1081ebf06SWludzik, Jozef #pragma once 2081ebf06SWludzik, Jozef 33ccb3adbSEd Tanous #include "app.hpp" 43ccb3adbSEd Tanous #include "dbus_utility.hpp" 5*479e899dSKrzysztof 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> 217a1dbc48SGeorge Liu #include <string_view> 22081ebf06SWludzik, Jozef #include <tuple> 23081ebf06SWludzik, Jozef #include <variant> 24081ebf06SWludzik, Jozef 25081ebf06SWludzik, Jozef namespace redfish 26081ebf06SWludzik, Jozef { 27081ebf06SWludzik, Jozef 28081ebf06SWludzik, Jozef namespace telemetry 29081ebf06SWludzik, Jozef { 30081ebf06SWludzik, Jozef 31*479e899dSKrzysztof Grobelny using ReadingParameters = std::vector<std::tuple< 32*479e899dSKrzysztof Grobelny std::vector<std::tuple<sdbusplus::message::object_path, std::string>>, 33*479e899dSKrzysztof Grobelny std::string, std::string, uint64_t>>; 34*479e899dSKrzysztof Grobelny 35*479e899dSKrzysztof Grobelny inline metric_report_definition::ReportActionsEnum 36*479e899dSKrzysztof Grobelny toRedfishReportAction(std::string_view dbusValue) 37*479e899dSKrzysztof Grobelny { 38*479e899dSKrzysztof Grobelny if (dbusValue == 39*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportActions.EmitsReadingsUpdate") 40*479e899dSKrzysztof Grobelny { 41*479e899dSKrzysztof Grobelny return metric_report_definition::ReportActionsEnum::RedfishEvent; 42*479e899dSKrzysztof Grobelny } 43*479e899dSKrzysztof Grobelny if (dbusValue == 44*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportActions.LogToMetricReportsCollection") 45*479e899dSKrzysztof Grobelny { 46*479e899dSKrzysztof Grobelny return metric_report_definition::ReportActionsEnum:: 47*479e899dSKrzysztof Grobelny LogToMetricReportsCollection; 48*479e899dSKrzysztof Grobelny } 49*479e899dSKrzysztof Grobelny return metric_report_definition::ReportActionsEnum::Invalid; 50*479e899dSKrzysztof Grobelny } 51*479e899dSKrzysztof Grobelny 52*479e899dSKrzysztof Grobelny inline std::string toDbusReportAction(std::string_view redfishValue) 53*479e899dSKrzysztof Grobelny { 54*479e899dSKrzysztof Grobelny if (redfishValue == "RedfishEvent") 55*479e899dSKrzysztof Grobelny { 56*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportActions.EmitsReadingsUpdate"; 57*479e899dSKrzysztof Grobelny } 58*479e899dSKrzysztof Grobelny if (redfishValue == "LogToMetricReportsCollection") 59*479e899dSKrzysztof Grobelny { 60*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportActions.LogToMetricReportsCollection"; 61*479e899dSKrzysztof Grobelny } 62*479e899dSKrzysztof Grobelny return ""; 63*479e899dSKrzysztof Grobelny } 64*479e899dSKrzysztof Grobelny 65*479e899dSKrzysztof Grobelny inline metric_report_definition::MetricReportDefinitionType 66*479e899dSKrzysztof Grobelny toRedfishReportingType(std::string_view dbusValue) 67*479e899dSKrzysztof Grobelny { 68*479e899dSKrzysztof Grobelny if (dbusValue == 69*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportingType.OnChange") 70*479e899dSKrzysztof Grobelny { 71*479e899dSKrzysztof Grobelny return metric_report_definition::MetricReportDefinitionType::OnChange; 72*479e899dSKrzysztof Grobelny } 73*479e899dSKrzysztof Grobelny if (dbusValue == 74*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportingType.OnRequest") 75*479e899dSKrzysztof Grobelny { 76*479e899dSKrzysztof Grobelny return metric_report_definition::MetricReportDefinitionType::OnRequest; 77*479e899dSKrzysztof Grobelny } 78*479e899dSKrzysztof Grobelny if (dbusValue == 79*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportingType.Periodic") 80*479e899dSKrzysztof Grobelny { 81*479e899dSKrzysztof Grobelny return metric_report_definition::MetricReportDefinitionType::Periodic; 82*479e899dSKrzysztof Grobelny } 83*479e899dSKrzysztof Grobelny return metric_report_definition::MetricReportDefinitionType::Invalid; 84*479e899dSKrzysztof Grobelny } 85*479e899dSKrzysztof Grobelny 86*479e899dSKrzysztof Grobelny inline std::string toDbusReportingType(std::string_view redfishValue) 87*479e899dSKrzysztof Grobelny { 88*479e899dSKrzysztof Grobelny if (redfishValue == "OnChange") 89*479e899dSKrzysztof Grobelny { 90*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportingType.OnChange"; 91*479e899dSKrzysztof Grobelny } 92*479e899dSKrzysztof Grobelny if (redfishValue == "OnRequest") 93*479e899dSKrzysztof Grobelny { 94*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportingType.OnRequest"; 95*479e899dSKrzysztof Grobelny } 96*479e899dSKrzysztof Grobelny if (redfishValue == "Periodic") 97*479e899dSKrzysztof Grobelny { 98*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportingType.Periodic"; 99*479e899dSKrzysztof Grobelny } 100*479e899dSKrzysztof Grobelny return ""; 101*479e899dSKrzysztof Grobelny } 102*479e899dSKrzysztof Grobelny 103*479e899dSKrzysztof Grobelny inline metric_report_definition::CollectionTimeScope 104*479e899dSKrzysztof Grobelny toRedfishCollectionTimeScope(std::string_view dbusValue) 105*479e899dSKrzysztof Grobelny { 106*479e899dSKrzysztof Grobelny if (dbusValue == 107*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Point") 108*479e899dSKrzysztof Grobelny { 109*479e899dSKrzysztof Grobelny return metric_report_definition::CollectionTimeScope::Point; 110*479e899dSKrzysztof Grobelny } 111*479e899dSKrzysztof Grobelny if (dbusValue == 112*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Interval") 113*479e899dSKrzysztof Grobelny { 114*479e899dSKrzysztof Grobelny return metric_report_definition::CollectionTimeScope::Interval; 115*479e899dSKrzysztof Grobelny } 116*479e899dSKrzysztof Grobelny if (dbusValue == 117*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.StartupInterval") 118*479e899dSKrzysztof Grobelny { 119*479e899dSKrzysztof Grobelny return metric_report_definition::CollectionTimeScope::StartupInterval; 120*479e899dSKrzysztof Grobelny } 121*479e899dSKrzysztof Grobelny return metric_report_definition::CollectionTimeScope::Invalid; 122*479e899dSKrzysztof Grobelny } 123*479e899dSKrzysztof Grobelny 124*479e899dSKrzysztof Grobelny inline std::string toDbusCollectionTimeScope(std::string_view redfishValue) 125*479e899dSKrzysztof Grobelny { 126*479e899dSKrzysztof Grobelny if (redfishValue == "Point") 127*479e899dSKrzysztof Grobelny { 128*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Point"; 129*479e899dSKrzysztof Grobelny } 130*479e899dSKrzysztof Grobelny if (redfishValue == "Interval") 131*479e899dSKrzysztof Grobelny { 132*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Interval"; 133*479e899dSKrzysztof Grobelny } 134*479e899dSKrzysztof Grobelny if (redfishValue == "StartupInterval") 135*479e899dSKrzysztof Grobelny { 136*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.StartupInterval"; 137*479e899dSKrzysztof Grobelny } 138*479e899dSKrzysztof Grobelny return ""; 139*479e899dSKrzysztof Grobelny } 140*479e899dSKrzysztof Grobelny 141*479e899dSKrzysztof Grobelny inline metric_report_definition::ReportUpdatesEnum 142*479e899dSKrzysztof Grobelny toRedfishReportUpdates(std::string_view dbusValue) 143*479e899dSKrzysztof Grobelny { 144*479e899dSKrzysztof Grobelny if (dbusValue == 145*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportUpdates.Overwrite") 146*479e899dSKrzysztof Grobelny { 147*479e899dSKrzysztof Grobelny return metric_report_definition::ReportUpdatesEnum::Overwrite; 148*479e899dSKrzysztof Grobelny } 149*479e899dSKrzysztof Grobelny if (dbusValue == 150*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendWrapsWhenFull") 151*479e899dSKrzysztof Grobelny { 152*479e899dSKrzysztof Grobelny return metric_report_definition::ReportUpdatesEnum::AppendWrapsWhenFull; 153*479e899dSKrzysztof Grobelny } 154*479e899dSKrzysztof Grobelny if (dbusValue == 155*479e899dSKrzysztof Grobelny "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendStopsWhenFull") 156*479e899dSKrzysztof Grobelny { 157*479e899dSKrzysztof Grobelny return metric_report_definition::ReportUpdatesEnum::AppendStopsWhenFull; 158*479e899dSKrzysztof Grobelny } 159*479e899dSKrzysztof Grobelny return metric_report_definition::ReportUpdatesEnum::Invalid; 160*479e899dSKrzysztof Grobelny } 161*479e899dSKrzysztof Grobelny 162*479e899dSKrzysztof Grobelny inline std::string toDbusReportUpdates(std::string_view redfishValue) 163*479e899dSKrzysztof Grobelny { 164*479e899dSKrzysztof Grobelny if (redfishValue == "Overwrite") 165*479e899dSKrzysztof Grobelny { 166*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.Overwrite"; 167*479e899dSKrzysztof Grobelny } 168*479e899dSKrzysztof Grobelny if (redfishValue == "AppendWrapsWhenFull") 169*479e899dSKrzysztof Grobelny { 170*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendWrapsWhenFull"; 171*479e899dSKrzysztof Grobelny } 172*479e899dSKrzysztof Grobelny if (redfishValue == "AppendStopsWhenFull") 173*479e899dSKrzysztof Grobelny { 174*479e899dSKrzysztof Grobelny return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendStopsWhenFull"; 175*479e899dSKrzysztof Grobelny } 176*479e899dSKrzysztof Grobelny return ""; 177*479e899dSKrzysztof Grobelny } 178081ebf06SWludzik, Jozef 179b9d36b47SEd Tanous inline void 180b9d36b47SEd Tanous fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 181b9d36b47SEd Tanous const std::string& id, 182*479e899dSKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties) 183081ebf06SWludzik, Jozef { 184*479e899dSKrzysztof Grobelny std::vector<std::string> reportActions; 185*479e899dSKrzysztof Grobelny ReadingParameters readingParams; 186*479e899dSKrzysztof Grobelny std::string reportingType; 187*479e899dSKrzysztof Grobelny std::string reportUpdates; 188*479e899dSKrzysztof Grobelny std::string name; 189*479e899dSKrzysztof Grobelny uint64_t appendLimit = 0; 190*479e899dSKrzysztof Grobelny uint64_t interval = 0; 191*479e899dSKrzysztof Grobelny bool enabled = false; 19289474494SKrzysztof Grobelny 19389474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 194*479e899dSKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "ReportingType", 195*479e899dSKrzysztof Grobelny reportingType, "Interval", interval, "ReportActions", reportActions, 196*479e899dSKrzysztof Grobelny "ReportUpdates", reportUpdates, "AppendLimit", appendLimit, 197*479e899dSKrzysztof Grobelny "ReadingParameters", readingParams, "Name", name, "Enabled", enabled); 19889474494SKrzysztof Grobelny 19989474494SKrzysztof Grobelny if (!success) 200081ebf06SWludzik, Jozef { 201081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 202081ebf06SWludzik, Jozef return; 203081ebf06SWludzik, Jozef } 204081ebf06SWludzik, Jozef 205*479e899dSKrzysztof Grobelny metric_report_definition::MetricReportDefinitionType redfishReportingType = 206*479e899dSKrzysztof Grobelny toRedfishReportingType(reportingType); 207*479e899dSKrzysztof Grobelny if (redfishReportingType == 208*479e899dSKrzysztof Grobelny metric_report_definition::MetricReportDefinitionType::Invalid) 209081ebf06SWludzik, Jozef { 210*479e899dSKrzysztof Grobelny messages::internalError(asyncResp->res); 211*479e899dSKrzysztof Grobelny return; 212081ebf06SWludzik, Jozef } 21389474494SKrzysztof Grobelny 214*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["MetricReportDefinitionType"] = 215*479e899dSKrzysztof Grobelny redfishReportingType; 216*479e899dSKrzysztof Grobelny 217*479e899dSKrzysztof Grobelny nlohmann::json::array_t redfishReportActions; 218*479e899dSKrzysztof Grobelny for (const std::string& action : reportActions) 219081ebf06SWludzik, Jozef { 220*479e899dSKrzysztof Grobelny metric_report_definition::ReportActionsEnum redfishAction = 221*479e899dSKrzysztof Grobelny toRedfishReportAction(action); 222*479e899dSKrzysztof Grobelny if (redfishAction == 223*479e899dSKrzysztof Grobelny metric_report_definition::ReportActionsEnum::Invalid) 224*479e899dSKrzysztof Grobelny { 225*479e899dSKrzysztof Grobelny messages::internalError(asyncResp->res); 226*479e899dSKrzysztof Grobelny return; 227081ebf06SWludzik, Jozef } 228081ebf06SWludzik, Jozef 229*479e899dSKrzysztof Grobelny redfishReportActions.emplace_back(redfishAction); 230*479e899dSKrzysztof Grobelny } 231*479e899dSKrzysztof Grobelny 232*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["ReportActions"] = std::move(redfishReportActions); 233*479e899dSKrzysztof Grobelny 234*479e899dSKrzysztof Grobelny nlohmann::json::array_t metrics = nlohmann::json::array(); 235*479e899dSKrzysztof Grobelny for (const auto& [sensorData, collectionFunction, collectionTimeScope, 236*479e899dSKrzysztof Grobelny collectionDuration] : readingParams) 23789474494SKrzysztof Grobelny { 238*479e899dSKrzysztof Grobelny nlohmann::json::array_t metricProperties; 239*479e899dSKrzysztof Grobelny 240*479e899dSKrzysztof Grobelny for (const auto& [sensorPath, sensorMetadata] : sensorData) 241081ebf06SWludzik, Jozef { 242*479e899dSKrzysztof Grobelny metricProperties.emplace_back(sensorMetadata); 243*479e899dSKrzysztof Grobelny } 244*479e899dSKrzysztof Grobelny 245613dabeaSEd Tanous nlohmann::json::object_t metric; 246*479e899dSKrzysztof Grobelny 247*479e899dSKrzysztof Grobelny metric_report_definition::CalculationAlgorithmEnum 248*479e899dSKrzysztof Grobelny redfishCollectionFunction = 249*479e899dSKrzysztof Grobelny telemetry::toRedfishCollectionFunction(collectionFunction); 250*479e899dSKrzysztof Grobelny if (redfishCollectionFunction == 251*479e899dSKrzysztof Grobelny metric_report_definition::CalculationAlgorithmEnum::Invalid) 252*479e899dSKrzysztof Grobelny { 253*479e899dSKrzysztof Grobelny messages::internalError(asyncResp->res); 254*479e899dSKrzysztof Grobelny return; 255*479e899dSKrzysztof Grobelny } 256*479e899dSKrzysztof Grobelny metric["CollectionFunction"] = redfishCollectionFunction; 257*479e899dSKrzysztof Grobelny 258*479e899dSKrzysztof Grobelny metric_report_definition::CollectionTimeScope 259*479e899dSKrzysztof Grobelny redfishCollectionTimeScope = 260*479e899dSKrzysztof Grobelny toRedfishCollectionTimeScope(collectionTimeScope); 261*479e899dSKrzysztof Grobelny if (redfishCollectionTimeScope == 262*479e899dSKrzysztof Grobelny metric_report_definition::CollectionTimeScope::Invalid) 263*479e899dSKrzysztof Grobelny { 264*479e899dSKrzysztof Grobelny messages::internalError(asyncResp->res); 265*479e899dSKrzysztof Grobelny return; 266*479e899dSKrzysztof Grobelny } 267*479e899dSKrzysztof Grobelny metric["CollectionTimeScope"] = redfishCollectionTimeScope; 268*479e899dSKrzysztof Grobelny 269*479e899dSKrzysztof Grobelny metric["MetricProperties"] = std::move(metricProperties); 270*479e899dSKrzysztof Grobelny metric["CollectionDuration"] = time_utils::toDurationString( 271*479e899dSKrzysztof Grobelny std::chrono::milliseconds(collectionDuration)); 272b2ba3072SPatrick Williams metrics.emplace_back(std::move(metric)); 273081ebf06SWludzik, Jozef } 274*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["Metrics"] = std::move(metrics); 275*479e899dSKrzysztof Grobelny 276*479e899dSKrzysztof Grobelny if (enabled) 277*479e899dSKrzysztof Grobelny { 278*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 279*479e899dSKrzysztof Grobelny } 280*479e899dSKrzysztof Grobelny else 281*479e899dSKrzysztof Grobelny { 282*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["Status"]["State"] = "Disabled"; 28389474494SKrzysztof Grobelny } 28489474494SKrzysztof Grobelny 285*479e899dSKrzysztof Grobelny metric_report_definition::ReportUpdatesEnum redfishReportUpdates = 286*479e899dSKrzysztof Grobelny toRedfishReportUpdates(reportUpdates); 287*479e899dSKrzysztof Grobelny if (redfishReportUpdates == 288*479e899dSKrzysztof Grobelny metric_report_definition::ReportUpdatesEnum::Invalid) 28989474494SKrzysztof Grobelny { 290*479e899dSKrzysztof Grobelny messages::internalError(asyncResp->res); 291*479e899dSKrzysztof Grobelny return; 29289474494SKrzysztof Grobelny } 293*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["ReportUpdates"] = redfishReportUpdates; 29489474494SKrzysztof Grobelny 295*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["MetricReportDefinitionEnabled"] = enabled; 296*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["AppendLimit"] = appendLimit; 297*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["Name"] = name; 298081ebf06SWludzik, Jozef asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = 299*479e899dSKrzysztof Grobelny time_utils::toDurationString(std::chrono::milliseconds(interval)); 300*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["@odata.type"] = 301*479e899dSKrzysztof Grobelny "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; 302*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 303*479e899dSKrzysztof Grobelny "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", id); 304*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["Id"] = id; 305*479e899dSKrzysztof Grobelny asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = boost::urls::format( 306*479e899dSKrzysztof Grobelny "/redfish/v1/TelemetryService/MetricReports/{}", id); 30789474494SKrzysztof Grobelny } 30889474494SKrzysztof Grobelny 3094dbb8aeaSWludzik, Jozef struct AddReportArgs 3104dbb8aeaSWludzik, Jozef { 311*479e899dSKrzysztof Grobelny struct MetricArgs 312*479e899dSKrzysztof Grobelny { 313*479e899dSKrzysztof Grobelny std::vector<std::string> uris; 314*479e899dSKrzysztof Grobelny std::string collectionFunction; 315*479e899dSKrzysztof Grobelny std::string collectionTimeScope; 316*479e899dSKrzysztof Grobelny uint64_t collectionDuration = 0; 317*479e899dSKrzysztof Grobelny }; 318*479e899dSKrzysztof Grobelny 319*479e899dSKrzysztof Grobelny std::string id; 3204dbb8aeaSWludzik, Jozef std::string name; 3214dbb8aeaSWludzik, Jozef std::string reportingType; 322*479e899dSKrzysztof Grobelny std::string reportUpdates; 323*479e899dSKrzysztof Grobelny uint64_t appendLimit = std::numeric_limits<uint64_t>::max(); 324*479e899dSKrzysztof Grobelny std::vector<std::string> reportActions; 325*479e899dSKrzysztof Grobelny uint64_t interval = std::numeric_limits<uint64_t>::max(); 326*479e899dSKrzysztof Grobelny std::vector<MetricArgs> metrics; 327*479e899dSKrzysztof Grobelny bool metricReportDefinitionEnabled = true; 3284dbb8aeaSWludzik, Jozef }; 3294dbb8aeaSWludzik, Jozef 3304dbb8aeaSWludzik, Jozef inline bool toDbusReportActions(crow::Response& res, 331*479e899dSKrzysztof Grobelny const std::vector<std::string>& actions, 3324dbb8aeaSWludzik, Jozef AddReportArgs& args) 3334dbb8aeaSWludzik, Jozef { 3344dbb8aeaSWludzik, Jozef size_t index = 0; 335*479e899dSKrzysztof Grobelny for (const std::string& action : actions) 3364dbb8aeaSWludzik, Jozef { 337*479e899dSKrzysztof Grobelny std::string dbusReportAction = toDbusReportAction(action); 338*479e899dSKrzysztof Grobelny if (dbusReportAction.empty()) 3394dbb8aeaSWludzik, Jozef { 340*479e899dSKrzysztof Grobelny messages::propertyValueNotInList(res, nlohmann::json(action).dump(), 341*479e899dSKrzysztof Grobelny "ReportActions/" + 342*479e899dSKrzysztof Grobelny std::to_string(index)); 3434dbb8aeaSWludzik, Jozef return false; 3444dbb8aeaSWludzik, Jozef } 345*479e899dSKrzysztof Grobelny 346*479e899dSKrzysztof Grobelny args.reportActions.emplace_back(std::move(dbusReportAction)); 3474dbb8aeaSWludzik, Jozef index++; 3484dbb8aeaSWludzik, Jozef } 3494dbb8aeaSWludzik, Jozef return true; 3504dbb8aeaSWludzik, Jozef } 3514dbb8aeaSWludzik, Jozef 352*479e899dSKrzysztof Grobelny inline bool getUserMetric(crow::Response& res, nlohmann::json& metric, 353*479e899dSKrzysztof Grobelny AddReportArgs::MetricArgs& metricArgs) 354*479e899dSKrzysztof Grobelny { 355*479e899dSKrzysztof Grobelny std::optional<std::vector<std::string>> uris; 356*479e899dSKrzysztof Grobelny std::optional<std::string> collectionDurationStr; 357*479e899dSKrzysztof Grobelny std::optional<std::string> collectionFunction; 358*479e899dSKrzysztof Grobelny std::optional<std::string> collectionTimeScopeStr; 359*479e899dSKrzysztof Grobelny 360*479e899dSKrzysztof Grobelny if (!json_util::readJson(metric, res, "MetricProperties", uris, 361*479e899dSKrzysztof Grobelny "CollectionFunction", collectionFunction, 362*479e899dSKrzysztof Grobelny "CollectionTimeScope", collectionTimeScopeStr, 363*479e899dSKrzysztof Grobelny "CollectionDuration", collectionDurationStr)) 364*479e899dSKrzysztof Grobelny { 365*479e899dSKrzysztof Grobelny return false; 366*479e899dSKrzysztof Grobelny } 367*479e899dSKrzysztof Grobelny 368*479e899dSKrzysztof Grobelny if (uris) 369*479e899dSKrzysztof Grobelny { 370*479e899dSKrzysztof Grobelny metricArgs.uris = std::move(*uris); 371*479e899dSKrzysztof Grobelny } 372*479e899dSKrzysztof Grobelny 373*479e899dSKrzysztof Grobelny if (collectionFunction) 374*479e899dSKrzysztof Grobelny { 375*479e899dSKrzysztof Grobelny std::string dbusCollectionFunction = 376*479e899dSKrzysztof Grobelny telemetry::toDbusCollectionFunction(*collectionFunction); 377*479e899dSKrzysztof Grobelny if (dbusCollectionFunction.empty()) 378*479e899dSKrzysztof Grobelny { 379*479e899dSKrzysztof Grobelny messages::propertyValueIncorrect(res, "CollectionFunction", 380*479e899dSKrzysztof Grobelny *collectionFunction); 381*479e899dSKrzysztof Grobelny return false; 382*479e899dSKrzysztof Grobelny } 383*479e899dSKrzysztof Grobelny metricArgs.collectionFunction = std::move(dbusCollectionFunction); 384*479e899dSKrzysztof Grobelny } 385*479e899dSKrzysztof Grobelny 386*479e899dSKrzysztof Grobelny if (collectionTimeScopeStr) 387*479e899dSKrzysztof Grobelny { 388*479e899dSKrzysztof Grobelny std::string dbusCollectionTimeScope = 389*479e899dSKrzysztof Grobelny toDbusCollectionTimeScope(*collectionTimeScopeStr); 390*479e899dSKrzysztof Grobelny if (dbusCollectionTimeScope.empty()) 391*479e899dSKrzysztof Grobelny { 392*479e899dSKrzysztof Grobelny messages::propertyValueIncorrect(res, "CollectionTimeScope", 393*479e899dSKrzysztof Grobelny *collectionTimeScopeStr); 394*479e899dSKrzysztof Grobelny return false; 395*479e899dSKrzysztof Grobelny } 396*479e899dSKrzysztof Grobelny metricArgs.collectionTimeScope = std::move(dbusCollectionTimeScope); 397*479e899dSKrzysztof Grobelny } 398*479e899dSKrzysztof Grobelny 399*479e899dSKrzysztof Grobelny if (collectionDurationStr) 400*479e899dSKrzysztof Grobelny { 401*479e899dSKrzysztof Grobelny std::optional<std::chrono::milliseconds> duration = 402*479e899dSKrzysztof Grobelny time_utils::fromDurationString(*collectionDurationStr); 403*479e899dSKrzysztof Grobelny 404*479e899dSKrzysztof Grobelny if (!duration || duration->count() < 0) 405*479e899dSKrzysztof Grobelny { 406*479e899dSKrzysztof Grobelny messages::propertyValueIncorrect(res, "CollectionDuration", 407*479e899dSKrzysztof Grobelny *collectionDurationStr); 408*479e899dSKrzysztof Grobelny return false; 409*479e899dSKrzysztof Grobelny } 410*479e899dSKrzysztof Grobelny 411*479e899dSKrzysztof Grobelny metricArgs.collectionDuration = 412*479e899dSKrzysztof Grobelny static_cast<uint64_t>(duration->count()); 413*479e899dSKrzysztof Grobelny } 414*479e899dSKrzysztof Grobelny 415*479e899dSKrzysztof Grobelny return true; 416*479e899dSKrzysztof Grobelny } 417*479e899dSKrzysztof Grobelny 418*479e899dSKrzysztof Grobelny inline bool getUserMetrics(crow::Response& res, 419*479e899dSKrzysztof Grobelny std::span<nlohmann::json> metrics, 420*479e899dSKrzysztof Grobelny std::vector<AddReportArgs::MetricArgs>& result) 421*479e899dSKrzysztof Grobelny { 422*479e899dSKrzysztof Grobelny result.reserve(metrics.size()); 423*479e899dSKrzysztof Grobelny 424*479e899dSKrzysztof Grobelny for (nlohmann::json& m : metrics) 425*479e899dSKrzysztof Grobelny { 426*479e899dSKrzysztof Grobelny AddReportArgs::MetricArgs metricArgs; 427*479e899dSKrzysztof Grobelny 428*479e899dSKrzysztof Grobelny if (!getUserMetric(res, m, metricArgs)) 429*479e899dSKrzysztof Grobelny { 430*479e899dSKrzysztof Grobelny return false; 431*479e899dSKrzysztof Grobelny } 432*479e899dSKrzysztof Grobelny 433*479e899dSKrzysztof Grobelny result.emplace_back(std::move(metricArgs)); 434*479e899dSKrzysztof Grobelny } 435*479e899dSKrzysztof Grobelny 436*479e899dSKrzysztof Grobelny return true; 437*479e899dSKrzysztof Grobelny } 438*479e899dSKrzysztof Grobelny 4394dbb8aeaSWludzik, Jozef inline bool getUserParameters(crow::Response& res, const crow::Request& req, 4404dbb8aeaSWludzik, Jozef AddReportArgs& args) 4414dbb8aeaSWludzik, Jozef { 442*479e899dSKrzysztof Grobelny std::optional<std::string> id; 443*479e899dSKrzysztof Grobelny std::optional<std::string> name; 444*479e899dSKrzysztof Grobelny std::optional<std::string> reportingTypeStr; 445*479e899dSKrzysztof Grobelny std::optional<std::string> reportUpdatesStr; 446*479e899dSKrzysztof Grobelny std::optional<uint64_t> appendLimit; 447*479e899dSKrzysztof Grobelny std::optional<bool> metricReportDefinitionEnabled; 448*479e899dSKrzysztof Grobelny std::optional<std::vector<nlohmann::json>> metrics; 449*479e899dSKrzysztof Grobelny std::optional<std::vector<std::string>> reportActionsStr; 4504dbb8aeaSWludzik, Jozef std::optional<nlohmann::json> schedule; 451*479e899dSKrzysztof Grobelny 452*479e899dSKrzysztof Grobelny if (!json_util::readJsonPatch( 453*479e899dSKrzysztof Grobelny req, res, "Id", id, "Name", name, "Metrics", metrics, 454*479e899dSKrzysztof Grobelny "MetricReportDefinitionType", reportingTypeStr, "ReportUpdates", 455*479e899dSKrzysztof Grobelny reportUpdatesStr, "AppendLimit", appendLimit, "ReportActions", 456*479e899dSKrzysztof Grobelny reportActionsStr, "Schedule", schedule, 457*479e899dSKrzysztof Grobelny "MetricReportDefinitionEnabled", metricReportDefinitionEnabled)) 4584dbb8aeaSWludzik, Jozef { 4594dbb8aeaSWludzik, Jozef return false; 4604dbb8aeaSWludzik, Jozef } 4614dbb8aeaSWludzik, Jozef 462*479e899dSKrzysztof Grobelny if (id) 463*479e899dSKrzysztof Grobelny { 464*479e899dSKrzysztof Grobelny constexpr const char* allowedCharactersInId = 4654dbb8aeaSWludzik, Jozef "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; 466*479e899dSKrzysztof Grobelny if (id->empty() || 467*479e899dSKrzysztof Grobelny id->find_first_not_of(allowedCharactersInId) != std::string::npos) 4684dbb8aeaSWludzik, Jozef { 469*479e899dSKrzysztof Grobelny messages::propertyValueIncorrect(res, "Id", *id); 4704dbb8aeaSWludzik, Jozef return false; 4714dbb8aeaSWludzik, Jozef } 472*479e899dSKrzysztof Grobelny args.id = *id; 473*479e899dSKrzysztof Grobelny } 4744dbb8aeaSWludzik, Jozef 475*479e899dSKrzysztof Grobelny if (name) 4764dbb8aeaSWludzik, Jozef { 477*479e899dSKrzysztof Grobelny args.name = *name; 478*479e899dSKrzysztof Grobelny } 479*479e899dSKrzysztof Grobelny 480*479e899dSKrzysztof Grobelny if (reportingTypeStr) 481*479e899dSKrzysztof Grobelny { 482*479e899dSKrzysztof Grobelny std::string dbusReportingType = toDbusReportingType(*reportingTypeStr); 483*479e899dSKrzysztof Grobelny if (dbusReportingType.empty()) 484*479e899dSKrzysztof Grobelny { 485*479e899dSKrzysztof Grobelny messages::propertyValueNotInList(res, *reportingTypeStr, 4864dbb8aeaSWludzik, Jozef "MetricReportDefinitionType"); 4874dbb8aeaSWludzik, Jozef return false; 4884dbb8aeaSWludzik, Jozef } 489*479e899dSKrzysztof Grobelny args.reportingType = dbusReportingType; 490*479e899dSKrzysztof Grobelny } 4914dbb8aeaSWludzik, Jozef 492*479e899dSKrzysztof Grobelny if (reportUpdatesStr) 493*479e899dSKrzysztof Grobelny { 494*479e899dSKrzysztof Grobelny std::string dbusReportUpdates = toDbusReportUpdates(*reportUpdatesStr); 495*479e899dSKrzysztof Grobelny if (dbusReportUpdates.empty()) 496*479e899dSKrzysztof Grobelny { 497*479e899dSKrzysztof Grobelny messages::propertyValueNotInList(res, *reportUpdatesStr, 498*479e899dSKrzysztof Grobelny "ReportUpdates"); 499*479e899dSKrzysztof Grobelny return false; 500*479e899dSKrzysztof Grobelny } 501*479e899dSKrzysztof Grobelny args.reportUpdates = dbusReportUpdates; 502*479e899dSKrzysztof Grobelny } 503*479e899dSKrzysztof Grobelny 504*479e899dSKrzysztof Grobelny if (appendLimit) 505*479e899dSKrzysztof Grobelny { 506*479e899dSKrzysztof Grobelny args.appendLimit = *appendLimit; 507*479e899dSKrzysztof Grobelny } 508*479e899dSKrzysztof Grobelny 509*479e899dSKrzysztof Grobelny if (metricReportDefinitionEnabled) 510*479e899dSKrzysztof Grobelny { 511*479e899dSKrzysztof Grobelny args.metricReportDefinitionEnabled = *metricReportDefinitionEnabled; 512*479e899dSKrzysztof Grobelny } 513*479e899dSKrzysztof Grobelny 514*479e899dSKrzysztof Grobelny if (reportActionsStr) 515*479e899dSKrzysztof Grobelny { 516*479e899dSKrzysztof Grobelny if (!toDbusReportActions(res, *reportActionsStr, args)) 5174dbb8aeaSWludzik, Jozef { 5184dbb8aeaSWludzik, Jozef return false; 5194dbb8aeaSWludzik, Jozef } 520*479e899dSKrzysztof Grobelny } 5214dbb8aeaSWludzik, Jozef 522*479e899dSKrzysztof Grobelny if (reportingTypeStr == "Periodic") 5234dbb8aeaSWludzik, Jozef { 5244dbb8aeaSWludzik, Jozef if (!schedule) 5254dbb8aeaSWludzik, Jozef { 5264dbb8aeaSWludzik, Jozef messages::createFailedMissingReqProperties(res, "Schedule"); 5274dbb8aeaSWludzik, Jozef return false; 5284dbb8aeaSWludzik, Jozef } 5294dbb8aeaSWludzik, Jozef 5304dbb8aeaSWludzik, Jozef std::string durationStr; 5314dbb8aeaSWludzik, Jozef if (!json_util::readJson(*schedule, res, "RecurrenceInterval", 5324dbb8aeaSWludzik, Jozef durationStr)) 5334dbb8aeaSWludzik, Jozef { 5344dbb8aeaSWludzik, Jozef return false; 5354dbb8aeaSWludzik, Jozef } 5364dbb8aeaSWludzik, Jozef 5374dbb8aeaSWludzik, Jozef std::optional<std::chrono::milliseconds> durationNum = 5384dbb8aeaSWludzik, Jozef time_utils::fromDurationString(durationStr); 539*479e899dSKrzysztof Grobelny if (!durationNum || durationNum->count() < 0) 5404dbb8aeaSWludzik, Jozef { 5414dbb8aeaSWludzik, Jozef messages::propertyValueIncorrect(res, "RecurrenceInterval", 5424dbb8aeaSWludzik, Jozef durationStr); 5434dbb8aeaSWludzik, Jozef return false; 5444dbb8aeaSWludzik, Jozef } 5454dbb8aeaSWludzik, Jozef args.interval = static_cast<uint64_t>(durationNum->count()); 5464dbb8aeaSWludzik, Jozef } 5474dbb8aeaSWludzik, Jozef 548*479e899dSKrzysztof Grobelny if (metrics) 5494dbb8aeaSWludzik, Jozef { 550*479e899dSKrzysztof Grobelny if (!getUserMetrics(res, *metrics, args.metrics)) 5514dbb8aeaSWludzik, Jozef { 5524dbb8aeaSWludzik, Jozef return false; 5534dbb8aeaSWludzik, Jozef } 5544dbb8aeaSWludzik, Jozef } 5554dbb8aeaSWludzik, Jozef 5564dbb8aeaSWludzik, Jozef return true; 5574dbb8aeaSWludzik, Jozef } 5584dbb8aeaSWludzik, Jozef 559ca1600c1SSzymon Dompke inline bool getChassisSensorNodeFromMetrics( 5608d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 561*479e899dSKrzysztof Grobelny std::span<const AddReportArgs::MetricArgs> metrics, 5624dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>>& matched) 5634dbb8aeaSWludzik, Jozef { 564ca1600c1SSzymon Dompke for (const auto& metric : metrics) 5654dbb8aeaSWludzik, Jozef { 566*479e899dSKrzysztof Grobelny std::optional<IncorrectMetricUri> error = 567*479e899dSKrzysztof Grobelny getChassisSensorNode(metric.uris, matched); 568ca1600c1SSzymon Dompke if (error) 5694dbb8aeaSWludzik, Jozef { 570ca1600c1SSzymon Dompke messages::propertyValueIncorrect(asyncResp->res, error->uri, 5714dbb8aeaSWludzik, Jozef "MetricProperties/" + 572ca1600c1SSzymon Dompke std::to_string(error->index)); 5734dbb8aeaSWludzik, Jozef return false; 5744dbb8aeaSWludzik, Jozef } 5754dbb8aeaSWludzik, Jozef } 5764dbb8aeaSWludzik, Jozef return true; 5774dbb8aeaSWludzik, Jozef } 5784dbb8aeaSWludzik, Jozef 5794dbb8aeaSWludzik, Jozef class AddReport 5804dbb8aeaSWludzik, Jozef { 5814dbb8aeaSWludzik, Jozef public: 5828d1b46d7Szhanghch05 AddReport(AddReportArgs argsIn, 5838a592810SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) : 5848a592810SEd Tanous asyncResp(asyncRespIn), 5858d1b46d7Szhanghch05 args{std::move(argsIn)} 5864dbb8aeaSWludzik, Jozef {} 587*479e899dSKrzysztof Grobelny 5884dbb8aeaSWludzik, Jozef ~AddReport() 5894dbb8aeaSWludzik, Jozef { 590*479e899dSKrzysztof Grobelny boost::asio::post(crow::connections::systemBus->get_io_context(), 591*479e899dSKrzysztof Grobelny std::bind_front(&performAddReport, asyncResp, args, 592*479e899dSKrzysztof Grobelny std::move(uriToDbus))); 593*479e899dSKrzysztof Grobelny } 594*479e899dSKrzysztof Grobelny 595*479e899dSKrzysztof Grobelny static void performAddReport( 596*479e899dSKrzysztof Grobelny const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 597*479e899dSKrzysztof Grobelny const AddReportArgs& args, 598*479e899dSKrzysztof Grobelny const boost::container::flat_map<std::string, std::string>& uriToDbus) 599*479e899dSKrzysztof Grobelny { 6004dbb8aeaSWludzik, Jozef if (asyncResp->res.result() != boost::beast::http::status::ok) 6014dbb8aeaSWludzik, Jozef { 6024dbb8aeaSWludzik, Jozef return; 6034dbb8aeaSWludzik, Jozef } 6044dbb8aeaSWludzik, Jozef 6054dbb8aeaSWludzik, Jozef telemetry::ReadingParameters readingParams; 6064dbb8aeaSWludzik, Jozef readingParams.reserve(args.metrics.size()); 6074dbb8aeaSWludzik, Jozef 608*479e899dSKrzysztof Grobelny for (const auto& metric : args.metrics) 6094dbb8aeaSWludzik, Jozef { 610*479e899dSKrzysztof Grobelny std::vector< 611*479e899dSKrzysztof Grobelny std::tuple<sdbusplus::message::object_path, std::string>> 612*479e899dSKrzysztof Grobelny sensorParams; 613*479e899dSKrzysztof Grobelny sensorParams.reserve(metric.uris.size()); 614*479e899dSKrzysztof Grobelny 615*479e899dSKrzysztof Grobelny for (size_t i = 0; i < metric.uris.size(); i++) 6164dbb8aeaSWludzik, Jozef { 617*479e899dSKrzysztof Grobelny const std::string& uri = metric.uris[i]; 6184dbb8aeaSWludzik, Jozef auto el = uriToDbus.find(uri); 6194dbb8aeaSWludzik, Jozef if (el == uriToDbus.end()) 6204dbb8aeaSWludzik, Jozef { 6210fda0f12SGeorge Liu BMCWEB_LOG_ERROR 6220fda0f12SGeorge Liu << "Failed to find DBus sensor corresponding to URI " 6234dbb8aeaSWludzik, Jozef << uri; 6244dbb8aeaSWludzik, Jozef messages::propertyValueNotInList(asyncResp->res, uri, 6254dbb8aeaSWludzik, Jozef "MetricProperties/" + 6264dbb8aeaSWludzik, Jozef std::to_string(i)); 6274dbb8aeaSWludzik, Jozef return; 6284dbb8aeaSWludzik, Jozef } 6294dbb8aeaSWludzik, Jozef 6304dbb8aeaSWludzik, Jozef const std::string& dbusPath = el->second; 631*479e899dSKrzysztof Grobelny sensorParams.emplace_back(dbusPath, uri); 6324dbb8aeaSWludzik, Jozef } 633*479e899dSKrzysztof Grobelny 634*479e899dSKrzysztof Grobelny readingParams.emplace_back( 635*479e899dSKrzysztof Grobelny std::move(sensorParams), metric.collectionFunction, 636*479e899dSKrzysztof Grobelny metric.collectionTimeScope, metric.collectionDuration); 6374dbb8aeaSWludzik, Jozef } 638*479e899dSKrzysztof Grobelny 6394dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 640*479e899dSKrzysztof Grobelny [asyncResp, id = args.id, uriToDbus]( 6415e7e2dc5SEd Tanous const boost::system::error_code& ec, const std::string&) { 6424dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::file_exists) 6434dbb8aeaSWludzik, Jozef { 6444dbb8aeaSWludzik, Jozef messages::resourceAlreadyExists( 645*479e899dSKrzysztof Grobelny asyncResp->res, "MetricReportDefinition", "Id", id); 6464dbb8aeaSWludzik, Jozef return; 6474dbb8aeaSWludzik, Jozef } 6484dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::too_many_files_open) 6494dbb8aeaSWludzik, Jozef { 650*479e899dSKrzysztof Grobelny messages::createLimitReachedForResource(asyncResp->res); 6514dbb8aeaSWludzik, Jozef return; 6524dbb8aeaSWludzik, Jozef } 6534dbb8aeaSWludzik, Jozef if (ec == boost::system::errc::argument_list_too_long) 6544dbb8aeaSWludzik, Jozef { 6554dbb8aeaSWludzik, Jozef nlohmann::json metricProperties = nlohmann::json::array(); 6564dbb8aeaSWludzik, Jozef for (const auto& [uri, _] : uriToDbus) 6574dbb8aeaSWludzik, Jozef { 6584dbb8aeaSWludzik, Jozef metricProperties.emplace_back(uri); 6594dbb8aeaSWludzik, Jozef } 660*479e899dSKrzysztof Grobelny messages::propertyValueIncorrect(asyncResp->res, 661*479e899dSKrzysztof Grobelny metricProperties.dump(), 662*479e899dSKrzysztof Grobelny "MetricProperties"); 6634dbb8aeaSWludzik, Jozef return; 6644dbb8aeaSWludzik, Jozef } 6654dbb8aeaSWludzik, Jozef if (ec) 6664dbb8aeaSWludzik, Jozef { 667*479e899dSKrzysztof Grobelny messages::internalError(asyncResp->res); 6684dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 6694dbb8aeaSWludzik, Jozef return; 6704dbb8aeaSWludzik, Jozef } 6714dbb8aeaSWludzik, Jozef 672*479e899dSKrzysztof Grobelny messages::created(asyncResp->res); 6734dbb8aeaSWludzik, Jozef }, 6744dbb8aeaSWludzik, Jozef telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", 6754dbb8aeaSWludzik, Jozef "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", 676*479e899dSKrzysztof Grobelny "TelemetryService/" + args.id, args.name, args.reportingType, 677*479e899dSKrzysztof Grobelny args.reportUpdates, args.appendLimit, args.reportActions, 678*479e899dSKrzysztof Grobelny args.interval, readingParams, args.metricReportDefinitionEnabled); 6794dbb8aeaSWludzik, Jozef } 6804dbb8aeaSWludzik, Jozef 681ecd6a3a2SEd Tanous AddReport(const AddReport&) = delete; 682ecd6a3a2SEd Tanous AddReport(AddReport&&) = delete; 683ecd6a3a2SEd Tanous AddReport& operator=(const AddReport&) = delete; 684ecd6a3a2SEd Tanous AddReport& operator=(AddReport&&) = delete; 685ecd6a3a2SEd Tanous 686fe04d49cSNan Zhou void insert(const std::map<std::string, std::string>& el) 6874dbb8aeaSWludzik, Jozef { 6884dbb8aeaSWludzik, Jozef uriToDbus.insert(el.begin(), el.end()); 6894dbb8aeaSWludzik, Jozef } 6904dbb8aeaSWludzik, Jozef 6914dbb8aeaSWludzik, Jozef private: 692*479e899dSKrzysztof Grobelny std::shared_ptr<bmcweb::AsyncResp> asyncResp; 6934dbb8aeaSWludzik, Jozef AddReportArgs args; 6944dbb8aeaSWludzik, Jozef boost::container::flat_map<std::string, std::string> uriToDbus{}; 6954dbb8aeaSWludzik, Jozef }; 696081ebf06SWludzik, Jozef } // namespace telemetry 697081ebf06SWludzik, Jozef 6987e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinitionCollection(App& app) 699081ebf06SWludzik, Jozef { 7007e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 701ed398213SEd Tanous .privileges(redfish::privileges::getMetricReportDefinitionCollection) 7027e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 70345ca1b86SEd Tanous [&app](const crow::Request& req, 7047e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 7053ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 70645ca1b86SEd Tanous { 70745ca1b86SEd Tanous return; 70845ca1b86SEd Tanous } 70945ca1b86SEd Tanous 7108d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.type"] = 7118d1b46d7Szhanghch05 "#MetricReportDefinitionCollection." 712081ebf06SWludzik, Jozef "MetricReportDefinitionCollection"; 7138d1b46d7Szhanghch05 asyncResp->res.jsonValue["@odata.id"] = 714ae9031f0SWilly Tu "/redfish/v1/TelemetryService/MetricReportDefinitions"; 715002d39b4SEd Tanous asyncResp->res.jsonValue["Name"] = "Metric Definition Collection"; 7167a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 7177a1dbc48SGeorge Liu telemetry::reportInterface}; 7184028ff77SEd Tanous collection_util::getCollectionMembers( 719ae9031f0SWilly Tu asyncResp, 720ae9031f0SWilly Tu boost::urls::url( 721ae9031f0SWilly Tu "/redfish/v1/TelemetryService/MetricReportDefinitions"), 722ae9031f0SWilly Tu interfaces, 7234028ff77SEd Tanous "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"); 7247e860f15SJohn Edward Broadbent }); 7254dbb8aeaSWludzik, Jozef 7267e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") 727ed398213SEd Tanous .privileges(redfish::privileges::postMetricReportDefinitionCollection) 728002d39b4SEd Tanous .methods(boost::beast::http::verb::post)( 729002d39b4SEd Tanous [&app](const crow::Request& req, 7307e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 7313ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 73245ca1b86SEd Tanous { 73345ca1b86SEd Tanous return; 73445ca1b86SEd Tanous } 73545ca1b86SEd Tanous 7364dbb8aeaSWludzik, Jozef telemetry::AddReportArgs args; 7378d1b46d7Szhanghch05 if (!telemetry::getUserParameters(asyncResp->res, req, args)) 7384dbb8aeaSWludzik, Jozef { 7394dbb8aeaSWludzik, Jozef return; 7404dbb8aeaSWludzik, Jozef } 7414dbb8aeaSWludzik, Jozef 7424dbb8aeaSWludzik, Jozef boost::container::flat_set<std::pair<std::string, std::string>> 7434dbb8aeaSWludzik, Jozef chassisSensors; 744002d39b4SEd Tanous if (!telemetry::getChassisSensorNodeFromMetrics(asyncResp, args.metrics, 745002d39b4SEd Tanous chassisSensors)) 7464dbb8aeaSWludzik, Jozef { 7474dbb8aeaSWludzik, Jozef return; 7484dbb8aeaSWludzik, Jozef } 7494dbb8aeaSWludzik, Jozef 750002d39b4SEd Tanous auto addReportReq = 751002d39b4SEd Tanous std::make_shared<telemetry::AddReport>(std::move(args), asyncResp); 7524dbb8aeaSWludzik, Jozef for (const auto& [chassis, sensorType] : chassisSensors) 7534dbb8aeaSWludzik, Jozef { 7544dbb8aeaSWludzik, Jozef retrieveUriToDbusMap( 755021d32cfSKrzysztof Grobelny chassis, sensorType, 756002d39b4SEd Tanous [asyncResp, addReportReq]( 757002d39b4SEd Tanous const boost::beast::http::status status, 758fe04d49cSNan Zhou const std::map<std::string, std::string>& uriToDbus) { 7594dbb8aeaSWludzik, Jozef if (status != boost::beast::http::status::ok) 7604dbb8aeaSWludzik, Jozef { 7617e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR 7620fda0f12SGeorge Liu << "Failed to retrieve URI to dbus sensors map with err " 7634dbb8aeaSWludzik, Jozef << static_cast<unsigned>(status); 7644dbb8aeaSWludzik, Jozef return; 7654dbb8aeaSWludzik, Jozef } 7664dbb8aeaSWludzik, Jozef addReportReq->insert(uriToDbus); 7674dbb8aeaSWludzik, Jozef }); 7684dbb8aeaSWludzik, Jozef } 7697e860f15SJohn Edward Broadbent }); 770081ebf06SWludzik, Jozef } 771081ebf06SWludzik, Jozef 7727e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinition(App& app) 773081ebf06SWludzik, Jozef { 7747e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 7757e860f15SJohn Edward Broadbent "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") 776ed398213SEd Tanous .privileges(redfish::privileges::getMetricReportDefinition) 7777e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 77845ca1b86SEd Tanous [&app](const crow::Request& req, 7797e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 7807e860f15SJohn Edward Broadbent const std::string& id) { 7813ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 78245ca1b86SEd Tanous { 78345ca1b86SEd Tanous return; 78445ca1b86SEd Tanous } 78545ca1b86SEd Tanous 78689474494SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 78789474494SKrzysztof Grobelny *crow::connections::systemBus, telemetry::service, 78889474494SKrzysztof Grobelny telemetry::getDbusReportPath(id), telemetry::reportInterface, 789168e20c1SEd Tanous [asyncResp, 7905e7e2dc5SEd Tanous id](const boost::system::error_code& ec, 791*479e899dSKrzysztof Grobelny const dbus::utility::DBusPropertiesMap& properties) { 792081ebf06SWludzik, Jozef if (ec.value() == EBADR || 793081ebf06SWludzik, Jozef ec == boost::system::errc::host_unreachable) 794081ebf06SWludzik, Jozef { 795002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, 796002d39b4SEd Tanous "MetricReportDefinition", id); 797081ebf06SWludzik, Jozef return; 798081ebf06SWludzik, Jozef } 799081ebf06SWludzik, Jozef if (ec) 800081ebf06SWludzik, Jozef { 801081ebf06SWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 802081ebf06SWludzik, Jozef messages::internalError(asyncResp->res); 803081ebf06SWludzik, Jozef return; 804081ebf06SWludzik, Jozef } 805081ebf06SWludzik, Jozef 806*479e899dSKrzysztof Grobelny telemetry::fillReportDefinition(asyncResp, id, properties); 80789474494SKrzysztof Grobelny }); 8087e860f15SJohn Edward Broadbent }); 809*479e899dSKrzysztof Grobelny 8107e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 8117e860f15SJohn Edward Broadbent "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") 812ed398213SEd Tanous .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) 8137e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::delete_)( 81445ca1b86SEd Tanous [&app](const crow::Request& req, 8157e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 8167e860f15SJohn Edward Broadbent const std::string& id) 8174dbb8aeaSWludzik, Jozef 8184dbb8aeaSWludzik, Jozef { 8193ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 82045ca1b86SEd Tanous { 82145ca1b86SEd Tanous return; 82245ca1b86SEd Tanous } 82345ca1b86SEd Tanous 8244dbb8aeaSWludzik, Jozef const std::string reportPath = telemetry::getDbusReportPath(id); 8254dbb8aeaSWludzik, Jozef 8264dbb8aeaSWludzik, Jozef crow::connections::systemBus->async_method_call( 8275e7e2dc5SEd Tanous [asyncResp, id](const boost::system::error_code& ec) { 8284dbb8aeaSWludzik, Jozef /* 8297e860f15SJohn Edward Broadbent * boost::system::errc and std::errc are missing value 8307e860f15SJohn Edward Broadbent * for EBADR error that is defined in Linux. 8314dbb8aeaSWludzik, Jozef */ 8324dbb8aeaSWludzik, Jozef if (ec.value() == EBADR) 8334dbb8aeaSWludzik, Jozef { 834002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, 835002d39b4SEd Tanous "MetricReportDefinition", id); 8364dbb8aeaSWludzik, Jozef return; 8374dbb8aeaSWludzik, Jozef } 8384dbb8aeaSWludzik, Jozef 8394dbb8aeaSWludzik, Jozef if (ec) 8404dbb8aeaSWludzik, Jozef { 8414dbb8aeaSWludzik, Jozef BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 8424dbb8aeaSWludzik, Jozef messages::internalError(asyncResp->res); 8434dbb8aeaSWludzik, Jozef return; 8444dbb8aeaSWludzik, Jozef } 8454dbb8aeaSWludzik, Jozef 846002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::no_content); 8474dbb8aeaSWludzik, Jozef }, 848002d39b4SEd Tanous telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete", 849002d39b4SEd Tanous "Delete"); 8507e860f15SJohn Edward Broadbent }); 8514dbb8aeaSWludzik, Jozef } 852081ebf06SWludzik, Jozef } // namespace redfish 853