diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch | 301 |
1 files changed, 301 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch new file mode 100644 index 000000000..20bcbabfa --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Switched-bmcweb-to-use-new-telemetry-service-API.patch @@ -0,0 +1,301 @@ +From fca6f5b951a363916a83a25f6578f95a6cf32a3e Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny <krzysztof.grobelny@intel.com> +Date: Thu, 17 Jun 2021 13:37:57 +0000 +Subject: [PATCH] Switched bmcweb to use new telemetry service API + +Added support for multiple MetricProperties. Added support for new +parameters: CollectionTimeScope, CollectionDuration. + +Tested: + - It is possible to create MetricReportDefinitions with multiple + MetricProperties. + - Stub values for new parameters are correctly passed to telemetry + service. + - All existing telemetry service functionalities remain unchanged. + +Change-Id: I2cd17069e3ea015c8f5571c29278f1d50536272a +Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com> +--- + redfish-core/lib/metric_report_definition.hpp | 212 ++++++++++-------- + 1 file changed, 114 insertions(+), 98 deletions(-) + +diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp +index a0c4f1d..7c26787 100644 +--- a/redfish-core/lib/metric_report_definition.hpp ++++ b/redfish-core/lib/metric_report_definition.hpp +@@ -7,6 +7,8 @@ + #include <app.hpp> + #include <boost/container/flat_map.hpp> + #include <registries/privilege_registry.hpp> ++#include <sdbusplus/asio/property.hpp> ++#include <sdbusplus/unpack_properties.hpp> + + #include <tuple> + #include <variant> +@@ -17,87 +19,90 @@ namespace redfish + namespace telemetry + { + +-using ReadingParameters = +- std::vector<std::tuple<sdbusplus::message::object_path, std::string, +- std::string, std::string>>; ++using ReadingParameters = std::vector< ++ std::tuple<std::vector<sdbusplus::message::object_path>, std::string, ++ std::string, std::string, std::string, uint64_t>>; + + inline void fillReportDefinition( + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id, + const std::vector< +- std::pair<std::string, std::variant<std::string, bool, uint64_t, +- ReadingParameters>>>& ret) ++ std::pair<std::string, std::variant<std::monostate, std::string, bool, ++ uint64_t, ReadingParameters>>>& ++ properties) + { +- asyncResp->res.jsonValue["@odata.type"] = +- "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; +- asyncResp->res.jsonValue["@odata.id"] = +- telemetry::metricReportDefinitionUri + id; +- asyncResp->res.jsonValue["Id"] = id; +- asyncResp->res.jsonValue["Name"] = id; +- asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = +- telemetry::metricReportUri + id; +- asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; +- asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; +- +- const bool* emitsReadingsUpdate = nullptr; +- const bool* logToMetricReportsCollection = nullptr; +- const ReadingParameters* readingParams = nullptr; +- const std::string* reportingType = nullptr; +- const uint64_t* interval = nullptr; +- for (const auto& [key, var] : ret) ++ try + { +- if (key == "EmitsReadingsUpdate") ++ bool emitsReadingsUpdate = false; ++ bool logToMetricReportsCollection = false; ++ ReadingParameters readingParams; ++ std::string reportingType; ++ uint64_t interval = 0u; ++ ++ sdbusplus::unpackProperties( ++ properties, "EmitsReadingsUpdate", emitsReadingsUpdate, ++ "LogToMetricReportsCollection", logToMetricReportsCollection, ++ "ReadingParametersFutureVersion", readingParams, "ReportingType", ++ reportingType, "Interval", interval); ++ ++ std::vector<std::string> redfishReportActions; ++ redfishReportActions.reserve(2); ++ if (emitsReadingsUpdate) + { +- emitsReadingsUpdate = std::get_if<bool>(&var); ++ redfishReportActions.emplace_back("RedfishEvent"); + } +- else if (key == "LogToMetricReportsCollection") ++ if (logToMetricReportsCollection) + { +- logToMetricReportsCollection = std::get_if<bool>(&var); ++ redfishReportActions.emplace_back("LogToMetricReportsCollection"); + } +- else if (key == "ReadingParameters") +- { +- readingParams = std::get_if<ReadingParameters>(&var); +- } +- else if (key == "ReportingType") +- { +- reportingType = std::get_if<std::string>(&var); +- } +- else if (key == "Interval") ++ ++ nlohmann::json metrics = nlohmann::json::array(); ++ for (auto& [sensorPath, operationType, id, metadata, ++ collectionTimeScope, collectionDuration] : readingParams) + { +- interval = std::get_if<uint64_t>(&var); ++ std::vector<std::string> metricProperties; ++ ++ nlohmann::json parsedMetadata = nlohmann::json::parse(metadata); ++ if (!json_util::readJson(parsedMetadata, asyncResp->res, ++ "MetricProperties", metricProperties)) ++ { ++ BMCWEB_LOG_ERROR << "Failed to read metadata"; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ metrics.push_back({ ++ {"MetricId", id}, ++ {"MetricProperties", std::move(metricProperties)}, ++ }); + } +- } +- if (!emitsReadingsUpdate || !logToMetricReportsCollection || +- !readingParams || !reportingType || !interval) +- { +- BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; +- messages::internalError(asyncResp->res); +- return; +- } + +- std::vector<std::string> redfishReportActions; +- redfishReportActions.reserve(2); +- if (*emitsReadingsUpdate) +- { +- redfishReportActions.emplace_back("RedfishEvent"); ++ asyncResp->res.jsonValue["@odata.type"] = ++ "#MetricReportDefinition.v1_3_0.MetricReportDefinition"; ++ asyncResp->res.jsonValue["@odata.id"] = ++ telemetry::metricReportDefinitionUri + id; ++ asyncResp->res.jsonValue["Id"] = id; ++ asyncResp->res.jsonValue["Name"] = id; ++ asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = ++ telemetry::metricReportUri + id; ++ asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; ++ asyncResp->res.jsonValue["ReportUpdates"] = "Overwrite"; ++ asyncResp->res.jsonValue["Metrics"] = metrics; ++ asyncResp->res.jsonValue["MetricReportDefinitionType"] = reportingType; ++ asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; ++ asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = ++ time_utils::toDurationString(std::chrono::milliseconds(interval)); + } +- if (*logToMetricReportsCollection) ++ catch (const sdbusplus::exception::UnpackPropertyError& error) + { +- redfishReportActions.emplace_back("LogToMetricReportsCollection"); ++ BMCWEB_LOG_ERROR << error.what() << ", property: " ++ << error.propertyName + ", reason: " << error.reason; ++ messages::internalError(asyncResp->res); + } +- +- nlohmann::json metrics = nlohmann::json::array(); +- for (auto& [sensorPath, operationType, id, metadata] : *readingParams) ++ catch (const nlohmann::json::parse_error& e) + { +- metrics.push_back({ +- {"MetricId", id}, +- {"MetricProperties", {metadata}}, +- }); ++ BMCWEB_LOG_ERROR << "Failed to parse metadata: " << e.what(); ++ messages::internalError(asyncResp->res); + } +- asyncResp->res.jsonValue["Metrics"] = metrics; +- asyncResp->res.jsonValue["MetricReportDefinitionType"] = *reportingType; +- asyncResp->res.jsonValue["ReportActions"] = redfishReportActions; +- asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] = +- time_utils::toDurationString(std::chrono::milliseconds(*interval)); + } + + struct AddReportArgs +@@ -275,6 +280,11 @@ class AddReport + + for (const auto& [id, uris] : args.metrics) + { ++ std::vector<sdbusplus::message::object_path> dbusPaths; ++ dbusPaths.reserve(uris.size()); ++ nlohmann::json metadata; ++ metadata["MetricProperties"] = nlohmann::json::array(); ++ + for (size_t i = 0; i < uris.size(); i++) + { + const std::string& uri = uris[i]; +@@ -291,8 +301,12 @@ class AddReport + } + + const std::string& dbusPath = el->second; +- readingParams.emplace_back(dbusPath, "SINGLE", id, uri); ++ dbusPaths.emplace_back(dbusPath); ++ metadata["MetricProperties"].emplace_back(uri); + } ++ ++ readingParams.emplace_back(dbusPaths, "SINGLE", id, metadata.dump(), ++ "Point", 0u); + } + const std::shared_ptr<bmcweb::AsyncResp> aResp = asyncResp; + crow::connections::systemBus->async_method_call( +@@ -330,10 +344,10 @@ class AddReport + messages::created(aResp->res); + }, + telemetry::service, "/xyz/openbmc_project/Telemetry/Reports", +- "xyz.openbmc_project.Telemetry.ReportManager", "AddReport", +- "TelemetryService/" + args.name, args.reportingType, +- args.emitsReadingsUpdate, args.logToMetricReportsCollection, +- args.interval, readingParams); ++ "xyz.openbmc_project.Telemetry.ReportManager", ++ "AddReportFutureVersion", "TelemetryService/" + args.name, ++ args.reportingType, args.emitsReadingsUpdate, ++ args.logToMetricReportsCollection, args.interval, readingParams); + } + + void insert(const boost::container::flat_map<std::string, std::string>& el) +@@ -415,37 +429,39 @@ inline void requestRoutesMetricReportDefinition(App& app) + BMCWEB_ROUTE(app, + "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") + .privileges(redfish::privileges::getMetricReportDefinition) +- .methods(boost::beast::http::verb::get)( +- [](const crow::Request&, +- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, +- const std::string& id) { +- crow::connections::systemBus->async_method_call( +- [asyncResp, id]( +- const boost::system::error_code ec, +- const std::vector<std::pair< +- std::string, +- std::variant<std::string, bool, uint64_t, +- telemetry::ReadingParameters>>>& ret) { +- if (ec.value() == EBADR || +- ec == boost::system::errc::host_unreachable) +- { +- messages::resourceNotFound( +- asyncResp->res, "MetricReportDefinition", id); +- return; +- } +- if (ec) +- { +- BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; +- messages::internalError(asyncResp->res); +- return; +- } ++ .methods( ++ boost::beast::http::verb::get)([](const crow::Request&, ++ const std::shared_ptr< ++ bmcweb::AsyncResp>& asyncResp, ++ const std::string& id) { ++ sdbusplus::asio::getAllProperties( ++ *crow::connections::systemBus, telemetry::service, ++ telemetry::getDbusReportPath(id), telemetry::reportInterface, ++ [asyncResp, ++ id](boost::system::error_code ec, ++ const std::vector<std::pair< ++ std::string, ++ std::variant<std::monostate, std::string, bool, ++ uint64_t, telemetry::ReadingParameters>>>& ++ properties) { ++ if (ec.value() == EBADR || ++ ec == boost::system::errc::host_unreachable) ++ { ++ messages::resourceNotFound( ++ asyncResp->res, "MetricReportDefinition", id); ++ return; ++ } ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ telemetry::fillReportDefinition(asyncResp, id, properties); ++ }); ++ }); + +- telemetry::fillReportDefinition(asyncResp, id, ret); +- }, +- telemetry::service, telemetry::getDbusReportPath(id), +- "org.freedesktop.DBus.Properties", "GetAll", +- telemetry::reportInterface); +- }); + BMCWEB_ROUTE(app, + "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") + .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) +-- +2.25.1 |