diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry')
11 files changed, 795 insertions, 392 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch index f53b7013f..c19691cdc 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch @@ -1,12 +1,20 @@ -From e37e30943fcb1ba504658ed07d69f950ccf44585 Mon Sep 17 00:00:00 2001 +From 80608f0d72da62426bb00e03a42fbf5daed931c9 Mon Sep 17 00:00:00 2001 From: Krzysztof Grobelny <krzysztof.grobelny@intel.com> Date: Tue, 13 Apr 2021 13:00:18 +0000 Subject: [PATCH] Add support for MetricDefinition scheme Added MetricDefinition node to Redfish code. Now user is able to list all available metrics in OpenBMC that are supported by Telemetry -service. Metrics are grouped by following categories: temperature, -power, voltage, current, fan_tach, fan_pwm, utilization. +service. Metrics are grouped by reading type. + +MetricDefinitions contains all physical sensors supported by redfish, +algorithm iterates through all chassis and collects results for each +node available in that chassis (Power, Thermal, Sensors). + +When https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/40169 will +be merge it will be possible to optimize this algorithm to only get +sensors from Sensors node. Currently Sensors node doesn't contain all +available sensors. Tested: - MetricDefinitions response is filled with existing sensors, it works @@ -14,18 +22,98 @@ Tested: - Validated a presence of MetricDefinition members and its attributes - Successfully passed RedfishServiceValidator.py using witherspoon image on QEMU + - Tested using following GET,POST requests + +GET /redfish/v1/TelemetryService/MetricDefinitions +{ + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions", + "@odata.type": "#MetricDefinitionCollection.MetricDefinitionCollection", + "Members": [ + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Rotational" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Percent" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Temperature" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Power" + }, + { + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/AirFlow" + } + ], + "Members@odata.count": 5, + "Name": "Metric Definition Collection" +} + +GET /redfish/v1/TelemetryService/MetricDefinitions/Rotational +{ + "@odata.id": "/redfish/v1/TelemetryService/MetricDefinitions/Rotational", + "@odata.type": "#MetricDefinition.v1_0_3.MetricDefinition", + "Id": "Rotational", + "Implementation": "PhysicalSensor", + "IsLinear": true, + "MetricDataType": "Decimal", + "MetricProperties": [ + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/0/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/1/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/2/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/3/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/4/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/5/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/6/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/7/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/8/Reading", + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/9/Reading" + ], + "MetricType": "Numeric", + "Name": "Rotational", + "Units": "RPM" +} + +POST redfish/v1/TelemetryService/MetricReportDefinitions, body: +{ + "Id": "TestReport", + "Metrics": [ + { + "MetricId": "TestMetric", + "MetricProperties": [ + "/redfish/v1/Chassis/Chassis0/Thermal#/Fans/3/Reading", + ] + } + ], + "MetricReportDefinitionType": "OnRequest", + "ReportActions": [ + "RedfishEvent", + "LogToMetricReportsCollection" + ] +} +{ + "@Message.ExtendedInfo": [ + { + "@odata.type": "#Message.v1_1_1.Message", + "Message": "The resource has been created successfully", + "MessageArgs": [], + "MessageId": "Base.1.8.1.Created", + "MessageSeverity": "OK", + "Resolution": "None" + } + ] +} Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com> Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com> Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00 --- redfish-core/include/redfish.hpp | 3 + - .../include/utils/get_chassis_names.hpp | 58 +++++ + .../include/utils/get_chassis_names.hpp | 58 ++++ .../include/utils/telemetry_utils.hpp | 2 + - redfish-core/lib/metric_definition.hpp | 242 ++++++++++++++++++ - redfish-core/lib/sensors.hpp | 25 +- + redfish-core/lib/metric_definition.hpp | 258 ++++++++++++++++++ redfish-core/lib/telemetry_service.hpp | 2 + - 6 files changed, 320 insertions(+), 12 deletions(-) + 5 files changed, 323 insertions(+) create mode 100644 redfish-core/include/utils/get_chassis_names.hpp create mode 100644 redfish-core/lib/metric_definition.hpp @@ -129,10 +217,10 @@ index 5872350..1b4f75d 100644 constexpr const char* metricReportUri = diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp new file mode 100644 -index 0000000..2443996 +index 0000000..019168b --- /dev/null +++ b/redfish-core/lib/metric_definition.hpp -@@ -0,0 +1,242 @@ +@@ -0,0 +1,258 @@ +#pragma once + +#include "async_resp.hpp" @@ -140,12 +228,34 @@ index 0000000..2443996 +#include "utils/get_chassis_names.hpp" +#include "utils/telemetry_utils.hpp" + ++#include <registries/privilege_registry.hpp> ++ +namespace redfish +{ + +namespace telemetry +{ + ++bool containsOdata(const nlohmann::json& json, const std::string& odataId) ++{ ++ const auto it = std::find_if( ++ json.begin(), json.end(), [&odataId](const nlohmann::json& item) { ++ auto kt = item.find("@odata.id"); ++ if (kt == item.end()) ++ { ++ return false; ++ } ++ const std::string* value = kt->get_ptr<const std::string*>(); ++ if (!value) ++ { ++ return false; ++ } ++ return *value == odataId; ++ }); ++ ++ return it != json.end(); ++} ++ +void addMembers(crow::Response& res, + const boost::container::flat_map<std::string, std::string>& el) +{ @@ -168,23 +278,7 @@ index 0000000..2443996 + std::string(telemetry::metricDefinitionUri) + + sensors::toReadingType(type); + -+ const auto it = std::find_if(members.begin(), members.end(), -+ [&odataId](const nlohmann::json& item) { -+ auto kt = item.find("@odata.id"); -+ if (kt == item.end()) -+ { -+ return false; -+ } -+ const std::string* value = -+ kt->get_ptr<const std::string*>(); -+ if (!value) -+ { -+ return false; -+ } -+ return *value == odataId; -+ }); -+ -+ if (it == members.end()) ++ if (!containsOdata(members, odataId)) + { + members.push_back({{"@odata.id", odataId}}); + } @@ -193,15 +287,76 @@ index 0000000..2443996 + } +} + ++template <class Callback> ++inline void mapRedfishUriToDbusPath(Callback&& callback) ++{ ++ utils::getChassisNames([callback = std::move(callback)]( ++ boost::system::error_code ec, ++ const std::vector<std::string>& chassisNames) { ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR << "getChassisNames error: " << ec.value(); ++ callback(ec, {}); ++ return; ++ } ++ ++ auto handleRetrieveUriToDbusMap = ++ [callback = std::move(callback)]( ++ 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<unsigned>(status); ++ callback(boost::system::errc::make_error_code( ++ boost::system::errc::io_error), ++ {}); ++ return; ++ } ++ ++ callback(boost::system::errc::make_error_code( ++ boost::system::errc::success), ++ uriToDbus); ++ }; ++ ++ for (const std::string& chassisName : chassisNames) ++ { ++ for (const auto& [sensorNode, dbusPaths] : sensors::dbus::paths) ++ { ++ retrieveUriToDbusMap(chassisName, sensorNode.data(), ++ handleRetrieveUriToDbusMap); ++ } ++ } ++ }); ++} ++ +} // namespace telemetry + +inline void requestRoutesMetricDefinitionCollection(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricDefinitions/") -+ .privileges({{"Login"}}) ++ .privileges(privileges::getTelemetryService) + .methods(boost::beast::http::verb::get)( + [](const crow::Request&, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { ++ telemetry::mapRedfishUriToDbusPath( ++ [asyncResp](boost::system::error_code ec, ++ const boost::container::flat_map< ++ std::string, std::string>& uriToDbus) { ++ if (ec) ++ { ++ messages::internalError(asyncResp->res); ++ BMCWEB_LOG_ERROR ++ << "mapRedfishUriToDbusPath error: " ++ << ec.value(); ++ return; ++ } ++ ++ telemetry::addMembers(asyncResp->res, uriToDbus); ++ }); ++ + asyncResp->res.jsonValue["@odata.type"] = + "#MetricDefinitionCollection." + "MetricDefinitionCollection"; @@ -211,49 +366,6 @@ index 0000000..2443996 + "Metric Definition Collection"; + asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); + asyncResp->res.jsonValue["Members@odata.count"] = 0; -+ -+ utils::getChassisNames( -+ [asyncResp](boost::system::error_code ec, -+ const std::vector<std::string>& chassisNames) { -+ if (ec) -+ { -+ messages::internalError(asyncResp->res); -+ BMCWEB_LOG_ERROR << "getChassisNames error: " -+ << ec.value(); -+ return; -+ } -+ -+ auto handleRetrieveUriToDbusMap = -+ [asyncResp]( -+ 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<unsigned>(status); -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ telemetry::addMembers(asyncResp->res, -+ uriToDbus); -+ }; -+ -+ for (const std::string& chassisName : chassisNames) -+ { -+ for (const auto& [sensorNode, _] : -+ sensors::dbus::paths) -+ { -+ BMCWEB_LOG_DEBUG << "Chassis: " << chassisName -+ << " sensor: " << sensorNode; -+ retrieveUriToDbusMap( -+ chassisName, sensorNode.data(), -+ handleRetrieveUriToDbusMap); -+ } -+ } -+ }); + }); +} + @@ -298,12 +410,29 @@ index 0000000..2443996 + } +} + ++inline const char* readingTypeToReadingUnits(const std::string& readingType) ++{ ++ for (const auto& [node, paths] : sensors::dbus::paths) ++ { ++ for (const char* path : paths) ++ { ++ const sdbusplus::message::object_path sensorPath = ++ sdbusplus::message::object_path(path); ++ if (sensors::toReadingType(sensorPath.filename()) == readingType) ++ { ++ return sensors::toReadingUnits(sensorPath.filename()); ++ } ++ } ++ } ++ return ""; ++} ++ +} // namespace telemetry + +inline void requestRoutesMetricDefinition(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricDefinitions/<str>/") -+ .privileges({{"Login"}}) ++ .privileges(privileges::getTelemetryService) + .methods(boost::beast::http::verb::get)( + [](const crow::Request&, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, @@ -315,142 +444,41 @@ index 0000000..2443996 + return; + } + -+ asyncResp->res.jsonValue["MetricProperties"] = -+ nlohmann::json::array(); -+ asyncResp->res.jsonValue["Id"] = readingType; -+ asyncResp->res.jsonValue["Name"] = readingType; -+ asyncResp->res.jsonValue["@odata.id"] = -+ telemetry::metricDefinitionUri + readingType; -+ asyncResp->res.jsonValue["@odata.type"] = -+ "#MetricDefinition.v1_0_3.MetricDefinition"; -+ asyncResp->res.jsonValue["MetricDataType"] = "Decimal"; -+ asyncResp->res.jsonValue["MetricType"] = "Numeric"; -+ asyncResp->res.jsonValue["IsLinear"] = true; -+ asyncResp->res.jsonValue["Implementation"] = "PhysicalSensor"; -+ asyncResp->res.jsonValue["Units"] = -+ sensors::toReadingUnits(readingType); -+ -+ utils::getChassisNames( -+ [asyncResp, readingType]( -+ boost::system::error_code ec, -+ const std::vector<std::string>& chassisNames) { ++ telemetry::mapRedfishUriToDbusPath( ++ [asyncResp, ++ readingType](boost::system::error_code ec, ++ const boost::container::flat_map< ++ std::string, std::string>& uriToDbus) { + if (ec) + { + messages::internalError(asyncResp->res); -+ BMCWEB_LOG_ERROR << "getChassisNames error: " -+ << ec.value(); ++ BMCWEB_LOG_ERROR ++ << "mapRedfishUriToDbusPath error: " ++ << ec.value(); + return; + } + -+ auto handleRetrieveUriToDbusMap = -+ [asyncResp, readingType]( -+ 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<unsigned>(status); -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ telemetry::addMetricProperty( -+ *asyncResp, readingType, uriToDbus); -+ }; -+ -+ for (const std::string& chassisName : chassisNames) -+ { -+ for (const auto& [sensorNode, dbusPaths] : -+ sensors::dbus::paths) -+ { -+ retrieveUriToDbusMap( -+ chassisName, sensorNode.data(), -+ handleRetrieveUriToDbusMap); -+ } -+ } ++ asyncResp->res.jsonValue["Id"] = readingType; ++ asyncResp->res.jsonValue["Name"] = readingType; ++ asyncResp->res.jsonValue["@odata.id"] = ++ telemetry::metricDefinitionUri + readingType; ++ asyncResp->res.jsonValue["@odata.type"] = ++ "#MetricDefinition.v1_0_3.MetricDefinition"; ++ asyncResp->res.jsonValue["MetricDataType"] = "Decimal"; ++ asyncResp->res.jsonValue["MetricType"] = "Numeric"; ++ asyncResp->res.jsonValue["IsLinear"] = true; ++ asyncResp->res.jsonValue["Implementation"] = ++ "PhysicalSensor"; ++ asyncResp->res.jsonValue["Units"] = ++ telemetry::readingTypeToReadingUnits(readingType); ++ ++ telemetry::addMetricProperty(*asyncResp, readingType, ++ uriToDbus); + }); + }); +} + +} // namespace redfish -diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp -index d986565..bccbb94 100644 ---- a/redfish-core/lib/sensors.hpp -+++ b/redfish-core/lib/sensors.hpp -@@ -111,46 +111,47 @@ inline const char* toReadingType(const std::string& sensorType) - return ""; - } - --inline const char* toReadingUnits(const std::string& sensorType) -+inline const char* toReadingUnits(const std::string& readingType) - { -- if (sensorType == "voltage") -+ if (readingType == "Voltage") - { - return "V"; - } -- if (sensorType == "power") -+ if (readingType == "Power") - { - return "W"; - } -- if (sensorType == "current") -+ if (readingType == "Current") - { - return "A"; - } -- if (sensorType == "fan_tach") -+ if (readingType == "Rotational") - { - return "RPM"; - } -- if (sensorType == "temperature") -+ if (readingType == "Temperature") - { - return "Cel"; - } -- if (sensorType == "fan_pwm" || sensorType == "utilization") -+ if (readingType == "Percent") - { - return "%"; - } -- if (sensorType == "altitude") -+ if (readingType == "Altitude") - { - return "m"; - } -- if (sensorType == "airflow") -+ if (readingType == "AirFlow") - { - return "cft_i/min"; - } -- if (sensorType == "energy") -+ if (readingType == "EnergyJoules") - { - return "J"; - } - return ""; - } -+ - } // namespace sensors - - /** -@@ -953,11 +954,11 @@ inline void objectInterfacesToJson( - sensorJson["ReadingType"] = readingType; - } - -- const std::string& readingUnits = sensors::toReadingUnits(sensorType); -+ const std::string& readingUnits = sensors::toReadingUnits(readingType); - if (readingUnits.empty()) - { - BMCWEB_LOG_ERROR << "Redfish cannot map reading unit for " -- << sensorType; -+ << readingType; - } - else - { diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp index ad86d5c..c4962e9 100644 --- a/redfish-core/lib/telemetry_service.hpp diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch index 0ca58a114..d32c85356 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch @@ -1,4 +1,4 @@ -From 277d261ef3b1723c9d198baf4b84d2e01a7460b8 Mon Sep 17 00:00:00 2001 +From 77e8a0b5037a555b1520823b667595ac8780c675 Mon Sep 17 00:00:00 2001 From: "Wludzik, Jozef" <jozef.wludzik@intel.com> Date: Tue, 15 Dec 2020 12:30:31 +0100 Subject: [PATCH] Sync Telmetry service with EventService @@ -22,7 +22,7 @@ Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com> 2 files changed, 69 insertions(+), 115 deletions(-) diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index 11190ef..ffe9435 100644 +index d89b789..4faaddd 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -14,6 +14,7 @@ @@ -33,7 +33,7 @@ index 11190ef..ffe9435 100644 #include "registries.hpp" #include "registries/base_message_registry.hpp" #include "registries/openbmc_message_registry.hpp" -@@ -522,47 +523,32 @@ class Subscription +@@ -511,47 +512,32 @@ class Subscription : public persistent_data::UserSubscription } #endif @@ -92,7 +92,7 @@ index 11190ef..ffe9435 100644 this->sendEvent( msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); } -@@ -1358,75 +1344,6 @@ class EventServiceManager +@@ -1317,75 +1303,6 @@ class EventServiceManager } #endif @@ -168,7 +168,7 @@ index 11190ef..ffe9435 100644 void unregisterMetricReportSignal() { if (matchTelemetryMonitor) -@@ -1446,9 +1363,11 @@ class EventServiceManager +@@ -1405,9 +1322,11 @@ class EventServiceManager } BMCWEB_LOG_DEBUG << "Metrics report signal - Register"; @@ -183,7 +183,7 @@ index 11190ef..ffe9435 100644 matchTelemetryMonitor = std::make_shared<sdbusplus::bus::match::match>( *crow::connections::systemBus, matchStr, -@@ -1459,10 +1378,43 @@ class EventServiceManager +@@ -1418,10 +1337,43 @@ class EventServiceManager return; } @@ -232,10 +232,10 @@ index 11190ef..ffe9435 100644 } diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp -index 66f4f93..a43f6a6 100644 +index 63c8c19..7fe281d 100644 --- a/redfish-core/lib/metric_report.hpp +++ b/redfish-core/lib/metric_report.hpp -@@ -32,16 +32,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) +@@ -33,16 +33,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) return metricValues; } @@ -258,7 +258,7 @@ index 66f4f93..a43f6a6 100644 telemetry::metricReportDefinitionUri + id; const TimestampReadings* timestampReadings = -@@ -49,14 +47,14 @@ inline void fillReport(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, +@@ -50,14 +48,14 @@ inline void fillReport(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, if (!timestampReadings) { BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; @@ -277,7 +277,7 @@ index 66f4f93..a43f6a6 100644 } } // namespace telemetry -@@ -117,7 +115,11 @@ inline void requestRoutesMetricReport(App& app) +@@ -118,7 +116,11 @@ inline void requestRoutesMetricReport(App& app) return; } diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-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 index 4e326ff88..20bcbabfa 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-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 @@ -1,4 +1,4 @@ -From 51869fd549cd826981ad30c6cdea4c4e94a972db Mon Sep 17 00:00:00 2001 +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 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch index d3a7c0a35..3d60ae293 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-support-for-MetricDefinition-property-in-MetricReport.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Add-support-for-MetricDefinition-property-in-MetricReport.patch @@ -1,4 +1,4 @@ -From d37ba16f837380ea5fbd7fae2d0f2e229c601754 Mon Sep 17 00:00:00 2001 +From 79b3d35b864a2b545b4c9b2ac9390ea5dec169f5 Mon Sep 17 00:00:00 2001 From: Szymon Dompke <szymon.dompke@intel.com> Date: Mon, 28 Jun 2021 11:10:23 +0200 Subject: [PATCH] Add support for MetricDefinition property in MetricReport @@ -73,10 +73,10 @@ Signed-off-by: Szymon Dompke <szymon.dompke@intel.com> 4 files changed, 95 insertions(+), 15 deletions(-) diff --git a/meson.build b/meson.build -index bdc514b..aadfd7d 100644 +index f6a66f1..6b5d9af 100644 --- a/meson.build +++ b/meson.build -@@ -354,6 +354,8 @@ srcfiles_unittest = ['include/ut/dbus_utility_test.cpp', +@@ -355,6 +355,8 @@ srcfiles_unittest = ['include/ut/dbus_utility_test.cpp', 'redfish-core/ut/time_utils_test.cpp', 'http/ut/utility_test.cpp'] @@ -85,7 +85,7 @@ index bdc514b..aadfd7d 100644 # Gather the Configuration data conf_data = configuration_data() -@@ -411,7 +413,7 @@ executable('bmcweb',srcfiles_bmcweb, +@@ -412,7 +414,7 @@ executable('bmcweb',srcfiles_bmcweb, if(get_option('tests').enabled()) foreach src_test : srcfiles_unittest testname = src_test.split('/')[-1].split('.')[0] @@ -251,7 +251,7 @@ index 7fe281d..13bf792 100644 } } // namespace telemetry diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp -index bccbb94..3e1d003 100644 +index cb7ea15..44c2129 100644 --- a/redfish-core/lib/sensors.hpp +++ b/redfish-core/lib/sensors.hpp @@ -21,6 +21,8 @@ @@ -265,4 +265,3 @@ index bccbb94..3e1d003 100644 -- 2.25.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch new file mode 100644 index 000000000..aabe500f5 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0005-Add-DELETE-method-for-MetricReport.patch @@ -0,0 +1,132 @@ +From 4cf883dba6e16c56d04dbd092d30c9a13d5a5eb4 Mon Sep 17 00:00:00 2001 +From: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com> +Date: Fri, 6 Aug 2021 15:15:17 +0200 +Subject: [PATCH] Add DELETE method for MetricReport + +Added DELETE method for removing Reports by using MetricReports uri; +metric_report.hpp and metric_report_definition.hpp files are sharing +now common lambda function for DELETE operations + +Tested on QEMU: +- Added Reports and requested from bmcweb to delete them via + /redfish/v1/TelemetryService/MetricReports/<reportname> or via + /redfish/v1/TelemetryService/MetricReportDefinitions/<reportname> +- Added two different reports via POST, deleted first of them via + MetricReports DELETE, checked by MetricReports GET if list of reports + contain only second report, deleted second report via MetricReports + DELETE and checked by MetricReports GET if list of reports is empty +- Same as one above but using MetricReportDefinitions DELETE and GET + +Signed-off-by: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com> +Change-Id: I151bad363dcabd57246eb10b501abd24107b937e +--- + .../include/utils/telemetry_utils.hpp | 35 +++++++++++++++++++ + redfish-core/lib/metric_report.hpp | 4 +++ + redfish-core/lib/metric_report_definition.hpp | 34 +----------------- + 3 files changed, 40 insertions(+), 33 deletions(-) + +diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp +index 5872350..743585f 100644 +--- a/redfish-core/include/utils/telemetry_utils.hpp ++++ b/redfish-core/include/utils/telemetry_utils.hpp +@@ -70,5 +70,40 @@ inline std::string getDbusReportPath(const std::string& id) + return path; + } + ++inline std::function<void(const crow::Request&, ++ const std::shared_ptr<bmcweb::AsyncResp>&, ++ const std::string&)> ++ getMetricReportDeleteHandler(const std::string& type) ++{ ++ return [type](const crow::Request&, ++ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, ++ const std::string& id) { ++ const std::string reportPath = getDbusReportPath(id); ++ ++ crow::connections::systemBus->async_method_call( ++ [asyncResp, type, 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, type, id); ++ return; ++ } ++ ++ if (ec) ++ { ++ BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ asyncResp->res.result(boost::beast::http::status::no_content); ++ }, ++ service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete"); ++ }; ++} ++ + } // namespace telemetry + } // namespace redfish +diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp +index 63c8c19..60ce74e 100644 +--- a/redfish-core/lib/metric_report.hpp ++++ b/redfish-core/lib/metric_report.hpp +@@ -127,5 +127,9 @@ inline void requestRoutesMetricReport(App& app) + telemetry::service, reportPath, telemetry::reportInterface, + "Update"); + }); ++ BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/") ++ .privileges(redfish::privileges::deleteMetricReport) ++ .methods(boost::beast::http::verb::delete_)( ++ telemetry::getMetricReportDeleteHandler("MetricReports")); + } + } // namespace redfish +diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp +index a0c4f1d..e0505e5 100644 +--- a/redfish-core/lib/metric_report_definition.hpp ++++ b/redfish-core/lib/metric_report_definition.hpp +@@ -450,38 +450,6 @@ inline void requestRoutesMetricReportDefinition(App& app) + "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/") + .privileges(redfish::privileges::deleteMetricReportDefinitionCollection) + .methods(boost::beast::http::verb::delete_)( +- [](const crow::Request&, +- const std::shared_ptr<bmcweb::AsyncResp>& 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; +- } +- +- if (ec) +- { +- BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; +- messages::internalError(asyncResp->res); +- return; +- } +- +- asyncResp->res.result( +- boost::beast::http::status::no_content); +- }, +- telemetry::service, reportPath, +- "xyz.openbmc_project.Object.Delete", "Delete"); +- }); ++ telemetry::getMetricReportDeleteHandler("MetricReportDefinition")); + } + } // namespace redfish +-- +2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch new file mode 100644 index 000000000..0646aba5c --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0006-Add-GET-method-for-TriggerCollection.patch @@ -0,0 +1,313 @@ +From a1e89d356ba5ed594a1494efe8257946e1062396 Mon Sep 17 00:00:00 2001 +From: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com> +Date: Tue, 31 Aug 2021 14:35:31 +0200 +Subject: [PATCH] Add GET method for TriggerCollection + +Added GET method for retrieving list of Triggers from Telemetry service + +Tested: +- Added single Trigger and requested result from bmcweb via + /redfish/v1/TelemetryService/Triggers +- Added multiple Triggers numeric and discrete, and requested results + from bmcweb via /redfish/v1/TelemetryService/Triggers +- Verified uri /redfish/v1/TelemetryService/Triggers by using + Redfish-Service-Validator (all passed) + +Signed-off-by: Lukasz Kazmierczak <lukasz.kazmierczak@intel.com> +Change-Id: Ide00eb44901ea1b97b80fc5c5ddfd97e393d4a04 +--- + redfish-core/include/redfish.hpp | 2 + + .../include/utils/telemetry_utils.hpp | 40 ++++++++--- + redfish-core/lib/metric_report.hpp | 6 +- + redfish-core/lib/metric_report_definition.hpp | 6 +- + redfish-core/lib/trigger.hpp | 31 ++++++++ + scripts/update_schemas.py | 1 + + static/redfish/v1/$metadata/index.xml | 3 + + .../v1/schema/TriggersCollection_v1.xml | 70 +++++++++++++++++++ + 8 files changed, 144 insertions(+), 15 deletions(-) + create mode 100644 redfish-core/lib/trigger.hpp + create mode 100644 static/redfish/v1/schema/TriggersCollection_v1.xml + +diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp +index 9fb0ffe..99b3fe6 100644 +--- a/redfish-core/include/redfish.hpp ++++ b/redfish-core/include/redfish.hpp +@@ -42,6 +42,7 @@ + #include "../lib/task.hpp" + #include "../lib/telemetry_service.hpp" + #include "../lib/thermal.hpp" ++#include "../lib/trigger.hpp" + #include "../lib/update_service.hpp" + #include "../lib/virtual_media.hpp" + +@@ -197,6 +198,7 @@ class RedfishService + + hypervisor::requestRoutesHypervisorSystems(app); + ++ requestRoutesTriggerCollection(app); + requestRoutesTelemetryService(app); + requestRoutesMetricReportDefinitionCollection(app); + requestRoutesMetricReportDefinition(app); +diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp +index c0c5ba3..df1aa68 100644 +--- a/redfish-core/include/utils/telemetry_utils.hpp ++++ b/redfish-core/include/utils/telemetry_utils.hpp +@@ -9,6 +9,8 @@ namespace telemetry + { + + constexpr const char* service = "xyz.openbmc_project.Telemetry"; ++constexpr const char* reportSubtree = ++ "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"; + constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report"; + constexpr const char* metricDefinitionUri = + "/redfish/v1/TelemetryService/MetricDefinitions/"; +@@ -16,6 +18,11 @@ constexpr const char* metricReportDefinitionUri = + "/redfish/v1/TelemetryService/MetricReportDefinitions/"; + constexpr const char* metricReportUri = + "/redfish/v1/TelemetryService/MetricReports/"; ++constexpr const char* triggerSubtree = ++ "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService"; ++constexpr const char* triggerInterface = ++ "xyz.openbmc_project.Telemetry.Trigger"; ++constexpr const char* triggerUri = "/redfish/v1/TelemetryService/Triggers/"; + + inline std::optional<nlohmann::json> + getMetadataJson(const std::string& metadataStr) +@@ -57,15 +64,27 @@ inline std::optional<std::string> + return res; + } + +-inline void +- getReportCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, +- const std::string& uri) ++struct CollectionParams + { +- const std::array<const char*, 1> interfaces = {reportInterface}; ++ const char* subtree; ++ int depth; ++ std::array<const char*, 1> interfaces; + ++ CollectionParams() = delete; ++ CollectionParams(const char* st, int dp, ++ const std::array<const char*, 1>& ifaces) : ++ subtree{st}, ++ depth{dp}, interfaces{ifaces} ++ {} ++}; ++ ++inline void getCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, ++ const std::string& uri, ++ const CollectionParams& params) ++{ + crow::connections::systemBus->async_method_call( + [asyncResp, uri](const boost::system::error_code ec, +- const std::vector<std::string>& reports) { ++ const std::vector<std::string>& items) { + if (ec == boost::system::errc::io_error) + { + asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); +@@ -82,13 +101,13 @@ inline void + nlohmann::json& members = asyncResp->res.jsonValue["Members"]; + members = nlohmann::json::array(); + +- for (const std::string& report : reports) ++ for (const std::string& item : items) + { +- sdbusplus::message::object_path path(report); ++ sdbusplus::message::object_path path(item); + std::string name = path.filename(); + if (name.empty()) + { +- BMCWEB_LOG_ERROR << "Received invalid path: " << report; ++ BMCWEB_LOG_ERROR << "Received invalid path: " << item; + messages::internalError(asyncResp->res); + return; + } +@@ -99,9 +118,8 @@ inline void + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", +- "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", +- "/xyz/openbmc_project/Telemetry/Reports/TelemetryService", 1, +- interfaces); ++ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", params.subtree, ++ params.depth, params.interfaces); + } + + inline std::string getDbusReportPath(const std::string& id) +diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp +index 13bf792..ea4cd62 100644 +--- a/redfish-core/lib/metric_report.hpp ++++ b/redfish-core/lib/metric_report.hpp +@@ -108,8 +108,10 @@ inline void requestRoutesMetricReportCollection(App& app) + "/redfish/v1/TelemetryService/MetricReports"; + asyncResp->res.jsonValue["Name"] = "Metric Report Collection"; + +- telemetry::getReportCollection(asyncResp, +- telemetry::metricReportUri); ++ telemetry::getCollection( ++ asyncResp, telemetry::metricReportUri, ++ telemetry::CollectionParams(telemetry::reportSubtree, 1, ++ {telemetry::reportInterface})); + }); + } + +diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp +index 7c26787..c97a1df 100644 +--- a/redfish-core/lib/metric_report_definition.hpp ++++ b/redfish-core/lib/metric_report_definition.hpp +@@ -377,8 +377,10 @@ inline void requestRoutesMetricReportDefinitionCollection(App& app) + asyncResp->res.jsonValue["Name"] = + "Metric Definition Collection"; + +- telemetry::getReportCollection( +- asyncResp, telemetry::metricReportDefinitionUri); ++ telemetry::getCollection( ++ asyncResp, telemetry::metricReportDefinitionUri, ++ telemetry::CollectionParams(telemetry::reportSubtree, 1, ++ {telemetry::reportInterface})); + }); + + BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/") +diff --git a/redfish-core/lib/trigger.hpp b/redfish-core/lib/trigger.hpp +new file mode 100644 +index 0000000..681b3b4 +--- /dev/null ++++ b/redfish-core/lib/trigger.hpp +@@ -0,0 +1,31 @@ ++#pragma once ++ ++#include "utils/telemetry_utils.hpp" ++ ++#include <app.hpp> ++#include <registries/privilege_registry.hpp> ++ ++namespace redfish ++{ ++ ++inline void requestRoutesTriggerCollection(App& app) ++{ ++ BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/") ++ .privileges(redfish::privileges::getTriggersCollection) ++ .methods(boost::beast::http::verb::get)( ++ [](const crow::Request&, ++ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { ++ asyncResp->res.jsonValue["@odata.type"] = ++ "#TriggersCollection.TriggersCollection"; ++ asyncResp->res.jsonValue["@odata.id"] = ++ "/redfish/v1/TelemetryService/Triggers"; ++ asyncResp->res.jsonValue["Name"] = "Triggers Collection"; ++ ++ telemetry::getCollection( ++ asyncResp, telemetry::triggerUri, ++ telemetry::CollectionParams(telemetry::triggerSubtree, 1, ++ {telemetry::triggerInterface})); ++ }); ++} ++ ++} // namespace redfish +diff --git a/scripts/update_schemas.py b/scripts/update_schemas.py +index dd39278..d66a59a 100755 +--- a/scripts/update_schemas.py ++++ b/scripts/update_schemas.py +@@ -93,6 +93,7 @@ include_list = [ + 'TaskService', + 'TelemetryService', + 'Thermal', ++ 'TriggersCollection', + 'UpdateService', + 'VLanNetworkInterfaceCollection', + 'VLanNetworkInterface', +diff --git a/static/redfish/v1/$metadata/index.xml b/static/redfish/v1/$metadata/index.xml +index 876ebfb..75e3dd4 100644 +--- a/static/redfish/v1/$metadata/index.xml ++++ b/static/redfish/v1/$metadata/index.xml +@@ -2215,6 +2215,9 @@ + <edmx:Include Namespace="Thermal.v1_7_0"/> + <edmx:Include Namespace="Thermal.v1_7_1"/> + </edmx:Reference> ++ <edmx:Reference Uri="/redfish/v1/schema/TriggersCollection_v1.xml"> ++ <edmx:Include Namespace="TriggersCollection"/> ++ </edmx:Reference> + <edmx:Reference Uri="/redfish/v1/schema/UpdateService_v1.xml"> + <edmx:Include Namespace="UpdateService"/> + <edmx:Include Namespace="UpdateService.v1_0_0"/> +diff --git a/static/redfish/v1/schema/TriggersCollection_v1.xml b/static/redfish/v1/schema/TriggersCollection_v1.xml +new file mode 100644 +index 0000000..399bebd +--- /dev/null ++++ b/static/redfish/v1/schema/TriggersCollection_v1.xml +@@ -0,0 +1,70 @@ ++<?xml version="1.0" encoding="UTF-8"?> ++<!----> ++<!--################################################################################ --> ++<!--# Redfish Schema: TriggerSetCollection --> ++<!--# --> ++<!--# For a detailed change log, see the README file contained in the DSP8010 bundle, --> ++<!--# available at http://www.dmtf.org/standards/redfish --> ++<!--# Copyright 2014-2021 DMTF. --> ++<!--# For the full DMTF copyright policy, see http://www.dmtf.org/about/policies/copyright --> ++<!--################################################################################ --> ++<!----> ++<edmx:Edmx xmlns:edmx="http://docs.oasis-open.org/odata/ns/edmx" Version="4.0"> ++ ++ <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Core.V1.xml"> ++ <edmx:Include Namespace="Org.OData.Core.V1" Alias="OData"/> ++ </edmx:Reference> ++ <edmx:Reference Uri="http://docs.oasis-open.org/odata/odata/v4.0/errata03/csd01/complete/vocabularies/Org.OData.Capabilities.V1.xml"> ++ <edmx:Include Namespace="Org.OData.Capabilities.V1" Alias="Capabilities"/> ++ </edmx:Reference> ++ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Resource_v1.xml"> ++ <edmx:Include Namespace="Resource.v1_0_0"/> ++ </edmx:Reference> ++ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/RedfishExtensions_v1.xml"> ++ <edmx:Include Namespace="RedfishExtensions.v1_0_0" Alias="Redfish"/> ++ </edmx:Reference> ++ <edmx:Reference Uri="http://redfish.dmtf.org/schemas/v1/Triggers_v1.xml"> ++ <edmx:Include Namespace="Triggers"/> ++ </edmx:Reference> ++ ++ <edmx:DataServices> ++ ++ <Schema xmlns="http://docs.oasis-open.org/odata/ns/edm" Namespace="TriggersCollection"> ++ <Annotation Term="Redfish.OwningEntity" String="DMTF"/> ++ ++ <EntityType Name="TriggersCollection" BaseType="Resource.v1_0_0.ResourceCollection"> ++ <Annotation Term="OData.Description" String="The collection of Triggers resource instances."/> ++ <Annotation Term="OData.LongDescription" String="This resource shall represent a resource collection of Triggers instances for a Redfish implementation."/> ++ <Annotation Term="Capabilities.InsertRestrictions"> ++ <Record> ++ <PropertyValue Property="Insertable" Bool="true"/> ++ <Annotation Term="OData.Description" String="Create triggers through a POST to the trigger collection."/> ++ </Record> ++ </Annotation> ++ <Annotation Term="Capabilities.UpdateRestrictions"> ++ <Record> ++ <PropertyValue Property="Updatable" Bool="false"/> ++ </Record> ++ </Annotation> ++ <Annotation Term="Capabilities.DeleteRestrictions"> ++ <Record> ++ <PropertyValue Property="Deletable" Bool="false"/> ++ </Record> ++ </Annotation> ++ <Annotation Term="Redfish.Uris"> ++ <Collection> ++ <String>/redfish/v1/TelemetryService/Triggers</String> ++ </Collection> ++ </Annotation> ++ <NavigationProperty Name="Members" Type="Collection(Triggers.Triggers)"> ++ <Annotation Term="OData.Permissions" EnumMember="OData.Permission/Read"/> ++ <Annotation Term="OData.Description" String="The members of this collection."/> ++ <Annotation Term="OData.LongDescription" String="This property shall contain an array of links to the members of this collection."/> ++ <Annotation Term="OData.AutoExpandReferences"/> ++ <Annotation Term="Redfish.Required"/> ++ </NavigationProperty> ++ </EntityType> ++ ++ </Schema> ++ </edmx:DataServices> ++</edmx:Edmx> +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch deleted file mode 100644 index 1cdd59d4b..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 872a7bdb9c272944914d7c5babc751e6bb33afec Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Adrian=20Ambro=C5=BCewicz?= <adrian.ambrozewicz@intel.com> -Date: Tue, 3 Aug 2021 13:59:31 +0200 -Subject: [PATCH] Generalize ReadingType in MetricDefinition - -Recent addition of PMT required adding new type of sensor 'count', which -doesnt comply with any of Redfish-defined Sensor.ReadingType values. - -To support property of this kind MetricDefinition implementation was -altered to support sensor types not covered by Redfish types by -a 'fallback' to direct usage of sensor type. Populating 'Units' was also -modified, so it won't be shown if value does not have any units mapped. - -Testing: -- PMT counters are shown properly in MetricDefinitions/Count -- Redfish Validator passes ---- - redfish-core/lib/metric_definition.hpp | 63 ++++++++++++++++---------- - 1 file changed, 39 insertions(+), 24 deletions(-) - -diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp -index 2443996..fcab44d 100644 ---- a/redfish-core/lib/metric_definition.hpp -+++ b/redfish-core/lib/metric_definition.hpp -@@ -11,6 +11,18 @@ namespace redfish - namespace telemetry - { - -+std::string groupName(const std::string& sensorType) -+{ -+ std::string group = sensors::toReadingType(sensorType); -+ if (group.empty()) -+ { -+ // Fallback for types not covered by standard Redfish Sensor.ReadingType -+ group = sensorType; -+ group[0] = static_cast<char>(std::toupper(group[0])); -+ } -+ return group; -+} -+ - void addMembers(crow::Response& res, - const boost::container::flat_map<std::string, std::string>& el) - { -@@ -30,8 +42,7 @@ void addMembers(crow::Response& res, - nlohmann::json& members = res.jsonValue["Members"]; - - const std::string odataId = -- std::string(telemetry::metricDefinitionUri) + -- sensors::toReadingType(type); -+ std::string(telemetry::metricDefinitionUri) + groupName(type); - - const auto it = std::find_if(members.begin(), members.end(), - [&odataId](const nlohmann::json& item) { -@@ -125,15 +136,15 @@ inline void requestRoutesMetricDefinitionCollection(App& app) - namespace telemetry - { - --bool isSensorIdSupported(std::string_view readingType) -+bool isSensorIdSupported(std::string_view group) - { - for (const std::pair<std::string_view, std::vector<const char*>>& - typeToPaths : sensors::dbus::paths) - { - for (const char* supportedPath : typeToPaths.second) - { -- if (readingType == -- sensors::toReadingType( -+ if (group == -+ groupName( - sdbusplus::message::object_path(supportedPath).filename())) - { - return true; -@@ -144,7 +155,7 @@ bool isSensorIdSupported(std::string_view readingType) - } - - void addMetricProperty( -- bmcweb::AsyncResp& asyncResp, const std::string& readingType, -+ bmcweb::AsyncResp& asyncResp, const std::string& group, - const boost::container::flat_map<std::string, std::string>& el) - { - nlohmann::json& metricProperties = -@@ -155,7 +166,7 @@ void addMetricProperty( - std::string sensorId; - if (dbus::utility::getNthStringFromPath(dbusSensor, 3, sensorId)) - { -- if (sensors::toReadingType(sensorId) == readingType) -+ if (groupName(sensorId) == group) - { - metricProperties.push_back(redfishSensor); - } -@@ -172,33 +183,37 @@ inline void requestRoutesMetricDefinition(App& app) - .methods(boost::beast::http::verb::get)( - [](const crow::Request&, - const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, -- const std::string& readingType) { -- if (!telemetry::isSensorIdSupported(readingType)) -+ const std::string& group) { -+ if (!telemetry::isSensorIdSupported(group)) - { - messages::resourceNotFound(asyncResp->res, -- "MetricDefinition", readingType); -+ "MetricDefinition", group); - return; - } - - asyncResp->res.jsonValue["MetricProperties"] = - nlohmann::json::array(); -- asyncResp->res.jsonValue["Id"] = readingType; -- asyncResp->res.jsonValue["Name"] = readingType; -+ asyncResp->res.jsonValue["Id"] = group; -+ asyncResp->res.jsonValue["Name"] = group; - asyncResp->res.jsonValue["@odata.id"] = -- telemetry::metricDefinitionUri + readingType; -+ telemetry::metricDefinitionUri + group; - asyncResp->res.jsonValue["@odata.type"] = - "#MetricDefinition.v1_0_3.MetricDefinition"; - asyncResp->res.jsonValue["MetricDataType"] = "Decimal"; - asyncResp->res.jsonValue["MetricType"] = "Numeric"; - asyncResp->res.jsonValue["IsLinear"] = true; - asyncResp->res.jsonValue["Implementation"] = "PhysicalSensor"; -- asyncResp->res.jsonValue["Units"] = -- sensors::toReadingUnits(readingType); -+ -+ std::string readingUnits = sensors::toReadingUnits(group); -+ if (!readingUnits.empty()) -+ { -+ asyncResp->res.jsonValue["Units"] = readingUnits; -+ } - - utils::getChassisNames( -- [asyncResp, readingType]( -- boost::system::error_code ec, -- const std::vector<std::string>& chassisNames) { -+ [asyncResp, -+ group](boost::system::error_code ec, -+ const std::vector<std::string>& chassisNames) { - if (ec) - { - messages::internalError(asyncResp->res); -@@ -208,10 +223,10 @@ inline void requestRoutesMetricDefinition(App& app) - } - - auto handleRetrieveUriToDbusMap = -- [asyncResp, readingType]( -- const boost::beast::http::status status, -- const boost::container::flat_map< -- std::string, std::string>& uriToDbus) { -+ [asyncResp, -+ group](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 -@@ -221,8 +236,8 @@ inline void requestRoutesMetricDefinition(App& app) - messages::internalError(asyncResp->res); - return; - } -- telemetry::addMetricProperty( -- *asyncResp, readingType, uriToDbus); -+ telemetry::addMetricProperty(*asyncResp, group, -+ uriToDbus); - }; - - for (const std::string& chassisName : chassisNames) --- -2.25.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch index 987a43b4c..987a43b4c 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch index ffab743f6..ffab743f6 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0008-event-service-fix-added-Context-field-to-response.patch diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch new file mode 100644 index 000000000..bd6e64346 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch @@ -0,0 +1,93 @@ +From d9baec3ccdff5ed4d1620f374a252c769de5b45b Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny <krzysztof.grobelny@intel.com> +Date: Thu, 19 Aug 2021 10:55:38 +0000 +Subject: [PATCH] Generalize ReadingType in MetricDefinition + +Recent addition of PMT required adding new type of sensor 'count', which +doesnt comply with any of Redfish-defined Sensor.ReadingType values. + +To support property of this kind MetricDefinition implementation was +altered to support sensor types not covered by Redfish types by +a 'fallback' to direct usage of sensor type. Populating 'Units' was also +modified, so it won't be shown if value does not have any units mapped. + +Testing: +- PMT counters are shown properly in MetricDefinitions/Count +- Redfish Validator passes +--- + redfish-core/lib/metric_definition.hpp | 25 ++++++++++++++++++------- + 1 file changed, 18 insertions(+), 7 deletions(-) + +diff --git a/redfish-core/lib/metric_definition.hpp b/redfish-core/lib/metric_definition.hpp +index 019168b..df29b65 100644 +--- a/redfish-core/lib/metric_definition.hpp ++++ b/redfish-core/lib/metric_definition.hpp +@@ -33,6 +33,18 @@ bool containsOdata(const nlohmann::json& json, const std::string& odataId) + return it != json.end(); + } + ++std::string groupName(const std::string& sensorType) ++{ ++ std::string group = sensors::toReadingType(sensorType); ++ if (group.empty()) ++ { ++ // Fallback for types not covered by standard Redfish Sensor.ReadingType ++ group = sensorType; ++ group[0] = static_cast<char>(std::toupper(group[0])); ++ } ++ return group; ++} ++ + void addMembers(crow::Response& res, + const boost::container::flat_map<std::string, std::string>& el) + { +@@ -52,8 +64,7 @@ void addMembers(crow::Response& res, + nlohmann::json& members = res.jsonValue["Members"]; + + const std::string odataId = +- std::string(telemetry::metricDefinitionUri) + +- sensors::toReadingType(type); ++ std::string(telemetry::metricDefinitionUri) + groupName(type); + + if (!containsOdata(members, odataId)) + { +@@ -149,15 +160,15 @@ inline void requestRoutesMetricDefinitionCollection(App& app) + namespace telemetry + { + +-bool isSensorIdSupported(std::string_view readingType) ++bool isSensorIdSupported(std::string_view group) + { + for (const std::pair<std::string_view, std::vector<const char*>>& + typeToPaths : sensors::dbus::paths) + { + for (const char* supportedPath : typeToPaths.second) + { +- if (readingType == +- sensors::toReadingType( ++ if (group == ++ groupName( + sdbusplus::message::object_path(supportedPath).filename())) + { + return true; +@@ -168,7 +179,7 @@ bool isSensorIdSupported(std::string_view readingType) + } + + void addMetricProperty( +- bmcweb::AsyncResp& asyncResp, const std::string& readingType, ++ bmcweb::AsyncResp& asyncResp, const std::string& group, + const boost::container::flat_map<std::string, std::string>& el) + { + nlohmann::json& metricProperties = +@@ -179,7 +190,7 @@ void addMetricProperty( + std::string sensorId; + if (dbus::utility::getNthStringFromPath(dbusSensor, 3, sensorId)) + { +- if (sensors::toReadingType(sensorId) == readingType) ++ if (groupName(sensorId) == group) + { + metricProperties.push_back(redfishSensor); + } +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README index cd15a815c..8dab07e2b 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/README @@ -3,22 +3,28 @@ Until change is integrated they will be manually merged here to enable feature i Current revisions: - Add support for MetricDefinition scheme - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/33363/89 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/33363/93 - Sync Telmetry service with EventService - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/38798/36 - -- LogService field, actual implementation will be upstreamed with triggers feature - file://telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch - -- Event service fix for Context field - file://telemetry/0004-event-service-fix-added-Context-field-to-response.patch + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/38798/40 - Switched bmcweb to use new telemetry service API - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44270/4 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44270/5 - Add support for MetricDefinition property in MetricReport - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44512/8 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/44512/9 + +- Add DELETE method for MetricReport + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/45688/5 + +- Add GET method for TriggerCollection + file://telemetry/0006-Add-GET-method-for-TriggerCollection.patch + +- LogService field, actual implementation will be upstreamed with triggers feature + file://telemetry/0007-Revert-Remove-LogService-from-TelemetryService.patch + +- Event service fix for Context field + file://telemetry/0008-event-service-fix-added-Context-field-to-response.patch - Generalize ReadingType in MetricDefinition - file://telemetry/0007-Generalize-ReadingType-in-MetricDefinition.patch
\ No newline at end of file + file://telemetry/0009-Generalize-ReadingType-in-MetricDefinition.patch |