From 4c39922af8bf73b13150455166e7bd1fd8645a47 Mon Sep 17 00:00:00 2001 From: Lukasz Kazmierczak Date: Fri, 17 Dec 2021 13:02:23 +0100 Subject: [PATCH] Add PUT and PATCH for MetricReportDefinition Support for PUT and PATCH methods is added to Metric Report Definition, now Report can be replaced by PUT or selected read/write properties can be modified by PATCH method Tested: - Added new Report via PUT and extracted Report via GET checking if received data is appropriate - Added Report via POST, overwrite it via PUT and extracted Report via GET checking if received data is appropriate - Added Report via POST, overwrite editable properties via PATCH and fetched Report via GET checking if received data is properly modified Signed-off-by: Lukasz Kazmierczak Change-Id: If75110a92c55c9e4f2415f0ed4471baa802643ff --- redfish-core/lib/metric_report_definition.hpp | 774 ++++++++++++++++-- 1 file changed, 692 insertions(+), 82 deletions(-) diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp index 30d83b0..e726c8c 100644 --- a/redfish-core/lib/metric_report_definition.hpp +++ b/redfish-core/lib/metric_report_definition.hpp @@ -8,9 +8,9 @@ #include #include #include +#include #include -#include namespace redfish { @@ -22,6 +22,12 @@ using ReadingParameters = std::vector>, std::string, std::string, std::string, uint64_t>>; +enum class addReportType +{ + create, + replace +}; + std::string toReadfishReportAction(std::string_view action) { if (action == "EmitsReadingsUpdate") @@ -48,6 +54,38 @@ std::string toDbusReportAction(std::string_view action) return ""; } +inline bool verifyCommonErrors(crow::Response& res, const std::string& id, + const boost::system::error_code ec) +{ + if (ec.value() == EBADR || ec == boost::system::errc::host_unreachable) + { + messages::resourceNotFound(res, "MetricReportDefinition", id); + return false; + } + + if (ec == boost::system::errc::file_exists) + { + messages::resourceAlreadyExists(res, "MetricReportDefinition", "Id", + id); + return false; + } + + if (ec == boost::system::errc::too_many_files_open) + { + messages::createLimitReachedForResource(res); + return false; + } + + if (ec) + { + BMCWEB_LOG_ERROR << "DBUS response error " << ec; + messages::internalError(res); + return false; + } + + return true; +} + inline void fillReportDefinition( const std::shared_ptr& asyncResp, const std::string& id, const std::vector>& @@ -193,17 +231,17 @@ inline void fillReportDefinition( } } -struct AddReportArgs +struct MetricArgs { - struct MetricArgs - { - std::string id; - std::vector uris; - std::optional collectionFunction; - std::optional collectionTimeScope; - std::optional collectionDuration; - }; + std::string id; + std::vector uris; + std::optional collectionFunction; + std::optional collectionTimeScope; + std::optional collectionDuration; +}; +struct AddReportArgs +{ std::optional id; std::optional name; std::string reportingType; @@ -215,22 +253,22 @@ struct AddReportArgs }; inline bool toDbusReportActions(crow::Response& res, - const std::vector& actions, - AddReportArgs& args) + const std::vector& redfishActions, + std::vector& dbusActions) { size_t index = 0; - for (const auto& action : actions) + for (const auto& redfishAction : redfishActions) { - std::string dbusReportAction = toDbusReportAction(action); + std::string dbusAction = toDbusReportAction(redfishAction); - if (dbusReportAction.empty()) + if (dbusAction.empty()) { messages::propertyValueNotInList( - res, action, "ReportActions/" + std::to_string(index)); + res, redfishAction, "ReportActions/" + std::to_string(index)); return false; } - args.reportActions.emplace_back(std::move(dbusReportAction)); + dbusActions.emplace_back(std::move(dbusAction)); index++; } return true; @@ -259,7 +297,7 @@ inline bool getUserParameters(crow::Response& res, const crow::Request& req, return false; } - if (!toDbusReportActions(res, reportActions, args)) + if (!toDbusReportActions(res, reportActions, args.reportActions)) { return false; } @@ -294,7 +332,7 @@ inline bool getUserParameters(crow::Response& res, const crow::Request& req, for (auto& m : metrics) { std::optional collectionDurationStr; - AddReportArgs::MetricArgs metricArgs; + MetricArgs metricArgs; if (!json_util::readJson( m, res, "MetricId", metricArgs.id, "MetricProperties", metricArgs.uris, "CollectionFunction", @@ -329,7 +367,7 @@ inline bool getUserParameters(crow::Response& res, const crow::Request& req, inline bool getChassisSensorNode( const std::shared_ptr& asyncResp, - const std::vector& metrics, + const std::vector& metrics, boost::container::flat_set>& matched) { for (const auto& metric : metrics) @@ -363,13 +401,122 @@ inline bool getChassisSensorNode( return true; } +inline bool getReadingParametersFromMetrics( + crow::Response& res, const std::vector& metrics, + const boost::container::flat_map& uriToDbus, + ReadingParameters& readingParams) +{ + if (metrics.empty()) + { + return true; + } + + readingParams.reserve(metrics.size()); + for (const auto& metric : metrics) + { + std::vector> + sensorParams; + sensorParams.reserve(metric.uris.size()); + + for (size_t i = 0; i < metric.uris.size(); i++) + { + const std::string& uri = metric.uris[i]; + auto el = uriToDbus.find(uri); + if (el == uriToDbus.end()) + { + BMCWEB_LOG_ERROR + << "Failed to find DBus sensor corresponding to URI " + << uri; + messages::propertyValueNotInList( + res, uri, "MetricProperties/" + std::to_string(i)); + return false; + } + + const std::string& dbusPath = el->second; + sensorParams.emplace_back(dbusPath, uri); + } + + readingParams.emplace_back( + std::move(sensorParams), metric.collectionFunction.value_or(""), + metric.id, metric.collectionTimeScope.value_or(""), + metric.collectionDuration.value_or(0U)); + } + + return true; +} + +class UpdateMetrics +{ + public: + UpdateMetrics(const std::string& idIn, std::vector metricsIn, + const std::shared_ptr& asyncResp) : + asyncResp(asyncResp), + id(idIn), metrics{std::move(metricsIn)} + {} + + ~UpdateMetrics() + { + setReadingParams(); + } + + UpdateMetrics(const UpdateMetrics&) = delete; + UpdateMetrics(UpdateMetrics&&) = delete; + UpdateMetrics& operator=(const UpdateMetrics&) = delete; + UpdateMetrics& operator=(UpdateMetrics&&) = delete; + + void insert(const boost::container::flat_map& el) + { + uriToDbus.insert(el.begin(), el.end()); + } + + void setReadingParams() + { + if (asyncResp->res.result() != boost::beast::http::status::ok) + { + return; + } + + if (!getReadingParametersFromMetrics(asyncResp->res, metrics, uriToDbus, + readingParams)) + { + return; + } + + const std::shared_ptr aResp = asyncResp; + crow::connections::systemBus->async_method_call( + [aResp, id = id](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + messages::propertyValueModified(aResp->res, "Metrics", + "Updated"); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Telemetry.Report", + "ReadingParametersFutureVersion", + dbus::utility::DbusVariantType{readingParams}); + } + + private: + const std::shared_ptr asyncResp; + std::string id; + std::vector metrics; + boost::container::flat_map uriToDbus{}; + ReadingParameters readingParams{}; +}; + class AddReport { public: AddReport(AddReportArgs argsIn, - const std::shared_ptr& asyncResp) : + const std::shared_ptr& asyncResp, + addReportType type) : asyncResp(asyncResp), - args{std::move(argsIn)} + args{std::move(argsIn)}, type(type) {} ~AddReport() { @@ -378,7 +525,7 @@ class AddReport return; } - telemetry::ReadingParameters readingParams; + ReadingParameters readingParams; readingParams.reserve(args.metrics.size()); for (auto& metric : args.metrics) @@ -412,22 +559,12 @@ class AddReport std::move(metric.id), metric.collectionTimeScope.value_or(""), metric.collectionDuration.value_or(0U)); } + const std::shared_ptr aResp = asyncResp; crow::connections::systemBus->async_method_call( - [aResp, id = args.id.value_or(""), - uriToDbus = std::move(uriToDbus)]( - const boost::system::error_code ec, const std::string&) { - if (ec == boost::system::errc::file_exists) - { - messages::resourceAlreadyExists( - aResp->res, "MetricReportDefinition", "Id", id); - return; - } - if (ec == boost::system::errc::too_many_files_open) - { - messages::createLimitReachedForResource(aResp->res); - return; - } + [aResp, id = args.id.value_or(""), uriToDbus = std::move(uriToDbus), + type = type](const boost::system::error_code ec, + const std::string&) { if (ec == boost::system::errc::argument_list_too_long) { nlohmann::json metricProperties = nlohmann::json::array(); @@ -440,16 +577,22 @@ class AddReport "MetricProperties"); return; } - if (ec) + + if (!verifyCommonErrors(aResp->res, id, ec)) { - messages::internalError(aResp->res); - BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; return; } - messages::created(aResp->res); + if (type == addReportType::create) + { + messages::created(aResp->res); + } + else + { + messages::success(aResp->res); + } }, - telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", + service, "/xyz/openbmc_project/Telemetry/Reports", "xyz.openbmc_project.Telemetry.ReportManager", "AddReportFutureVersion", "TelemetryService/" + args.id.value_or(""), args.name.value_or(""), @@ -471,8 +614,491 @@ class AddReport private: const std::shared_ptr asyncResp; AddReportArgs args; + const addReportType type; boost::container::flat_map uriToDbus{}; }; + +inline void setReportEnabled(const std::shared_ptr& aResp, + const std::string& id, bool enabled) +{ + crow::connections::systemBus->async_method_call( + [aResp, id, + enabled](const boost::system::error_code ec, + const dbus::utility::DbusVariantType& currEnabledVar) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + const bool* currEnabled = std::get_if(&currEnabledVar); + if (currEnabled == nullptr || *currEnabled == enabled) + { + return; + } + + crow::connections::systemBus->async_method_call( + [aResp, id, enabled](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + messages::propertyValueModified( + aResp->res, "MetricReportDefinitionEnabled", + enabled ? "True" : "False"); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Telemetry.Report", "Enabled", + dbus::utility::DbusVariantType{enabled}); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Telemetry.Report", "Enabled"); +} + +inline void setReportType(const std::shared_ptr& aResp, + const std::string& id, const std::string& type) +{ + if (type != "Periodic" && type != "OnChange" && type != "OnRequest") + { + messages::propertyValueNotInList(aResp->res, type, + "MetricReportDefinitionType"); + return; + } + + crow::connections::systemBus->async_method_call( + [aResp, id, type](const boost::system::error_code ec, + const dbus::utility::DbusVariantType& currTypeVar) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + const std::string* currType = + std::get_if(&currTypeVar); + if (currType == nullptr || *currType == type) + { + return; + } + + crow::connections::systemBus->async_method_call( + [aResp, id, type](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + messages::propertyValueModified( + aResp->res, "MetricReportDefinitionType", type); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Telemetry.Report", "ReportingType", + dbus::utility::DbusVariantType{type}); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Telemetry.Report", "ReportingType"); +} + +inline void setReportUpdates(const std::shared_ptr& aResp, + const std::string& id, const std::string& updates) +{ + if (updates != "Overwrite" && updates != "AppendWrapsWhenFull" && + updates != "AppendStopsWhenFull") + { + messages::propertyValueNotInList(aResp->res, updates, "ReportUpdates"); + return; + } + + crow::connections::systemBus->async_method_call( + [aResp, id, + updates](const boost::system::error_code ec, + const dbus::utility::DbusVariantType& currUpdatesVar) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + const std::string* currUpdates = + std::get_if(&currUpdatesVar); + if (currUpdates == nullptr || *currUpdates == updates) + { + return; + } + + crow::connections::systemBus->async_method_call( + [aResp, id, updates](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + messages::propertyValueModified(aResp->res, "ReportUpdates", + updates); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Telemetry.Report", "ReportUpdates", + dbus::utility::DbusVariantType{updates}); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Telemetry.Report", "ReportUpdates"); +} + +inline void setReportActions(const std::shared_ptr& aResp, + const std::string& id, + std::vector& redfishActions) +{ + if (redfishActions.size() > 1) + { + stl_utils::removeDuplicate(redfishActions); + } + + std::vector newDbusActions; + if (!toDbusReportActions(aResp->res, redfishActions, newDbusActions)) + { + return; + } + + crow::connections::systemBus->async_method_call( + [aResp, id, redfishActions = std::move(redfishActions), + newDbusActions = std::move(newDbusActions)]( + const boost::system::error_code ec, + const dbus::utility::DbusVariantType& currDbusActionsVar) mutable { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + std::vector currDbusActions; + if (const std::vector* tmp = + std::get_if>(&currDbusActionsVar)) + { + currDbusActions = *tmp; + } + else + { + messages::internalError(aResp->res); + return; + } + + if (newDbusActions.size() == currDbusActions.size()) + { + std::sort(newDbusActions.begin(), newDbusActions.end()); + if (newDbusActions == currDbusActions) + { + return; + } + } + + crow::connections::systemBus->async_method_call( + [aResp, id, + redfishActions](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + std::string redfishActionsStr; + for (const auto& redfishAction : redfishActions) + { + redfishActionsStr += redfishAction + std::string(" "); + } + if (!redfishActionsStr.empty()) + { + redfishActionsStr.pop_back(); + } + messages::propertyValueModified(aResp->res, "ReportActions", + redfishActionsStr); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Telemetry.Report", "ReportActions", + dbus::utility::DbusVariantType{newDbusActions}); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Telemetry.Report", "ReportActions"); +} + +inline void setReportInterval(const std::shared_ptr& aResp, + const std::string& id, nlohmann::json& schedule) +{ + crow::connections::systemBus->async_method_call( + [aResp, schedule = std::move(schedule), + id](const boost::system::error_code ec, + const dbus::utility::DbusVariantType& typeVar) mutable { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + const std::string* reportingType = + std::get_if(&typeVar); + if (reportingType == nullptr || *reportingType != "Periodic") + { + return; + } + + std::string durationStr; + if (!json_util::readJson(schedule, aResp->res, "RecurrenceInterval", + durationStr)) + { + return; + } + + std::optional durationNum = + time_utils::fromDurationString(durationStr); + uint64_t interval = static_cast(durationNum->count()); + + crow::connections::systemBus->async_method_call( + [aResp, id, interval, durationStr]( + const boost::system::error_code ec, + const dbus::utility::DbusVariantType& currIntervalVar) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + const uint64_t* currInterval = + std::get_if(&currIntervalVar); + if (currInterval == nullptr || *currInterval == interval) + { + return; + } + crow::connections::systemBus->async_method_call( + [aResp, id, + durationStr](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + + messages::propertyValueModified( + aResp->res, "RecurrenceInterval", durationStr); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/" + "TelemetryService/" + + id, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Telemetry.Report", "Interval", + dbus::utility::DbusVariantType{interval}); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Telemetry.Report", "Interval"); + }, + "xyz.openbmc_project.Telemetry", + "/xyz/openbmc_project/Telemetry/Reports/TelemetryService/" + id, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Telemetry.Report", "ReportingType"); +} + +inline void setReportMetrics(const std::shared_ptr& aResp, + const std::string& id, + std::vector& metricJsons) +{ + std::vector metrics; + metrics.reserve(metricJsons.size()); + + for (auto& m : metricJsons) + { + MetricArgs metricArgs; + std::optional collectionDurationStr; + if (!json_util::readJson( + m, aResp->res, "MetricId", metricArgs.id, "MetricProperties", + metricArgs.uris, "CollectionFunction", + metricArgs.collectionFunction, "CollectionTimeScope", + metricArgs.collectionTimeScope, "CollectionDuration", + collectionDurationStr)) + { + return; + } + + if (collectionDurationStr) + { + std::optional duration = + time_utils::fromDurationString(*collectionDurationStr); + + if (!duration || duration->count() < 0) + { + messages::propertyValueIncorrect( + aResp->res, "CollectionDuration", *collectionDurationStr); + return; + } + + metricArgs.collectionDuration = + static_cast(duration->count()); + } + + metrics.emplace_back(std::move(metricArgs)); + } + + boost::container::flat_set> + chassisSensors; + if (!getChassisSensorNode(aResp, metrics, chassisSensors)) + { + return; + } + + auto updateMetricsReq = + std::make_shared(id, std::move(metrics), aResp); + + for (const auto& [chassis, sensorType] : chassisSensors) + { + retrieveUriToDbusMap( + chassis, sensorType, + [aResp, updateMetricsReq]( + const boost::beast::http::status status, + const boost::container::flat_map& + uriToDbus) { + if (status != boost::beast::http::status::ok) + { + BMCWEB_LOG_ERROR + << "Failed to retrieve URI to dbus sensors map with err " + << static_cast(status); + return; + } + updateMetricsReq->insert(uriToDbus); + }); + } +} + +inline void handleReportPatch(const crow::Request& req, + const std::shared_ptr& aResp, + const std::string& id) +{ + std::optional enabled; + std::optional type; + std::optional updates; + std::optional> actions; + std::optional schedule; + std::optional> metrics; + + if (!json_util::readJsonPatch( + req, aResp->res, "MetricReportDefinitionEnabled", enabled, + "Schedule", schedule, "ReportActions", actions, "Metrics", metrics, + "MetricReportDefinitionType", type, "ReportUpdates", updates)) + { + return; + } + + if (enabled) + { + setReportEnabled(aResp, id, *enabled); + } + if (type) + { + setReportType(aResp, id, *type); + } + if (updates) + { + setReportUpdates(aResp, id, *updates); + } + if (actions) + { + setReportActions(aResp, id, *actions); + } + if (schedule) + { + setReportInterval(aResp, id, *schedule); + } + if (metrics) + { + setReportMetrics(aResp, id, *metrics); + } +} + +inline void handleReportPut(const crow::Request& req, + const std::shared_ptr& aResp, + const std::string& id) +{ + AddReportArgs args; + if (!getUserParameters(aResp->res, req, args)) + { + return; + } + + boost::container::flat_set> + chassisSensors; + if (!getChassisSensorNode(aResp, args.metrics, chassisSensors)) + { + return; + } + + const std::string reportPath = getDbusReportPath(id); + + crow::connections::systemBus->async_method_call( + [aResp, id, args = std::move(args), + chassisSensors = + std::move(chassisSensors)](const boost::system::error_code ec) { + addReportType addReportMode = addReportType::replace; + if (ec) + { + if (ec.value() != EBADR) + { + BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; + messages::internalError(aResp->res); + return; + } + BMCWEB_LOG_INFO << "Report not found, creating new report: " + << id; + addReportMode = addReportType::create; + } + + auto addReportReq = + std::make_shared(args, aResp, addReportMode); + for (const auto& [chassis, sensorType] : chassisSensors) + { + retrieveUriToDbusMap( + chassis, sensorType, + [aResp, + addReportReq](const boost::beast::http::status status, + const boost::container::flat_map< + std::string, std::string>& uriToDbus) { + if (status != boost::beast::http::status::ok) + { + BMCWEB_LOG_ERROR + << "Failed to retrieve URI to dbus " + "sensors map with err " + << static_cast(status); + return; + } + addReportReq->insert(uriToDbus); + }); + } + }, + service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete"); +} + +inline void handleReportDelete(const std::shared_ptr& aResp, + const std::string& id) +{ + const std::string reportPath = getDbusReportPath(id); + + crow::connections::systemBus->async_method_call( + [aResp, id](const boost::system::error_code ec) { + if (!verifyCommonErrors(aResp->res, id, ec)) + { + return; + } + aResp->res.result(boost::beast::http::status::no_content); + }, + service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete"); +} } // namespace telemetry inline void requestRoutesMetricReportDefinitionCollection(App& app) @@ -517,7 +1143,7 @@ inline void requestRoutesMetricReportDefinitionCollection(App& app) } auto addReportReq = std::make_shared( - std::move(args), asyncResp); + std::move(args), asyncResp, telemetry::addReportType::create); for (const auto& [chassis, sensorType] : chassisSensors) { retrieveUriToDbusMap( @@ -554,17 +1180,9 @@ inline void requestRoutesMetricReportDefinition(App& app) const std::vector>& properties) { - if (ec.value() == EBADR || - ec == boost::system::errc::host_unreachable) + if (!redfish::telemetry::verifyCommonErrors( + asyncResp->res, id, ec)) { - messages::resourceNotFound( - asyncResp->res, "MetricReportDefinition", id); - return; - } - if (ec) - { - BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; - messages::internalError(asyncResp->res); return; } @@ -578,40 +1196,32 @@ inline void requestRoutesMetricReportDefinition(App& app) BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions//") - .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) + .privileges(redfish::privileges::deleteMetricReportDefinition) .methods(boost::beast::http::verb::delete_)( [](const crow::Request&, const std::shared_ptr& asyncResp, - const std::string& id) - - { - const std::string reportPath = telemetry::getDbusReportPath(id); - - crow::connections::systemBus->async_method_call( - [asyncResp, id](const boost::system::error_code ec) { - /* - * boost::system::errc and std::errc are missing value - * for EBADR error that is defined in Linux. - */ - if (ec.value() == EBADR) - { - messages::resourceNotFound( - asyncResp->res, "MetricReportDefinition", id); - return; - } + const std::string& id) { + telemetry::handleReportDelete(asyncResp, id); + }); - if (ec) - { - BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; - messages::internalError(asyncResp->res); - return; - } + BMCWEB_ROUTE(app, + "/redfish/v1/TelemetryService/MetricReportDefinitions//") + .privileges(redfish::privileges::putMetricReportDefinition) + .methods(boost::beast::http::verb::put)( + [](const crow::Request& req, + const std::shared_ptr& asyncResp, + const std::string& id) { + telemetry::handleReportPut(req, asyncResp, id); + }); - asyncResp->res.result( - boost::beast::http::status::no_content); - }, - telemetry::service, reportPath, - "xyz.openbmc_project.Object.Delete", "Delete"); + BMCWEB_ROUTE(app, + "/redfish/v1/TelemetryService/MetricReportDefinitions//") + .privileges(redfish::privileges::patchMetricReportDefinition) + .methods(boost::beast::http::verb::patch)( + [](const crow::Request& req, + const std::shared_ptr& asyncResp, + const std::string& id) { + telemetry::handleReportPatch(req, asyncResp, id); }); } } // namespace redfish -- 2.25.1