From 67327ddc580cb9a85219a534844832a1682780d4 Mon Sep 17 00:00:00 2001 From: "Jason M. Bills" Date: Thu, 29 Jul 2021 15:23:08 -0700 Subject: Update to internal 0.63 Signed-off-by: Jason M. Bills --- ...b-Add-BMC-Time-update-log-to-the-registry.patch | 77 ++++ ...-Add-generic-message-PropertySizeExceeded.patch | 118 +++++ .../0006-Add-EventService-SSE-filter-support.patch | 72 ++- ...ks-on-Event-Subscription-input-parameters.patch | 85 ++++ ...1-Add-support-for-MetricDefinition-scheme.patch | 491 +++++++++++++++++++++ ...2-Sync-Telmetry-service-with-EventService.patch | 294 ++++++++++++ ...3-Add-support-for-MetricDefinition-scheme.patch | 421 ------------------ ...t-Remove-LogService-from-TelemetryService.patch | 26 ++ ...4-Sync-Telmetry-service-with-EventService.patch | 295 ------------- ...rvice-fix-added-Context-field-to-response.patch | 29 ++ .../interfaces/bmcweb/telemetry/README | 9 +- .../recipes-phosphor/interfaces/bmcweb_%.bbappend | 11 +- 12 files changed, 1195 insertions(+), 733 deletions(-) create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0018-bmcweb-Add-BMC-Time-update-log-to-the-registry.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0019-Add-generic-message-PropertySizeExceeded.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0008-Add-checks-on-Event-Subscription-input-parameters.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Add-support-for-MetricDefinition-scheme.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch delete mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Sync-Telmetry-service-with-EventService.patch create mode 100644 meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces') diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0018-bmcweb-Add-BMC-Time-update-log-to-the-registry.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0018-bmcweb-Add-BMC-Time-update-log-to-the-registry.patch new file mode 100644 index 000000000..829384305 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0018-bmcweb-Add-BMC-Time-update-log-to-the-registry.patch @@ -0,0 +1,77 @@ +From 3ec1f79d1cb29724e345586f0baefca81d98d3ae Mon Sep 17 00:00:00 2001 +From: mansijos +Date: Wed, 26 May 2021 17:40:04 +0530 +Subject: [PATCH] [bmcweb] Add BMC Time update log to the registry + +Add message in registry to log an event that indicates BMC time +is set via NTP, Host or Manually. +During early stage of system boot if any critical events occur, +they are getting logged with 1970 timestamp till the time BMC +time update happens. This is expected behavior, but to call it out +explicitly it is good to log when BMC time is updated. + +Tested: +Built and validator passes. +Confirmed that the event is getting logged correctly in Redfish. + +Signed-off-by: mansijos +--- + .../registries/openbmc_message_registry.hpp | 35 ++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/redfish-core/include/registries/openbmc_message_registry.hpp b/redfish-core/include/registries/openbmc_message_registry.hpp +index 2f981db..a00d235 100644 +--- a/redfish-core/include/registries/openbmc_message_registry.hpp ++++ b/redfish-core/include/registries/openbmc_message_registry.hpp +@@ -29,7 +29,7 @@ const Header header = { + "0.2.0", + "OpenBMC", + }; +-constexpr std::array registry = { ++constexpr std::array registry = { + MessageEntry{ + "ADDDCCorrectable", + { +@@ -286,6 +286,39 @@ constexpr std::array registry = { + {}, + "None.", + }}, ++ MessageEntry{"BMCTimeUpdatedViaHost", ++ { ++ "Indicates that BMC time has been set via Host.", ++ "BMC time has been set via Host. " ++ "Date Time is set to %1 from %2.", ++ "OK", ++ "OK", ++ 2, ++ {"string", "string"}, ++ "None.", ++ }}, ++ MessageEntry{"BMCTimeUpdatedManually", ++ { ++ "Indicates that BMC time has been set Manually.", ++ "BMC time has been set Manually. " ++ "Date Time is set to %1 from %2.", ++ "OK", ++ "OK", ++ 2, ++ {"string", "string"}, ++ "None.", ++ }}, ++ MessageEntry{"BMCTimeUpdatedViaNTP", ++ { ++ "Indicates that BMC time has been set via NTP.", ++ "BMC time has been set via NTP. " ++ "Date Time is set to %1 from %2.", ++ "OK", ++ "OK", ++ 2, ++ {"string", "string"}, ++ "None.", ++ }}, + MessageEntry{"ChassisIntrusionDetected", + { + "Indicates that a physical security event " +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0019-Add-generic-message-PropertySizeExceeded.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0019-Add-generic-message-PropertySizeExceeded.patch new file mode 100644 index 000000000..756ea24d7 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0019-Add-generic-message-PropertySizeExceeded.patch @@ -0,0 +1,118 @@ +From da893566ec02aefe235685f1b6742269aab37909 Mon Sep 17 00:00:00 2001 +From: Nitin Wankhade +Date: Thu, 24 Jun 2021 15:29:24 +0000 +Subject: [PATCH] Add generic message - PropertySizeExceeded + +Adding a generic error message "PropertySizeExceeded" +to address properties which exceed there defined size limit. + +Tested: +No functional change. Build passed. +Verified by explicitly sending this message as a response. + +Change-Id: I0e9f85f82a69c598e169fc8e9a68c3f66c0084d8 +Signed-off-by: Nitin Wankhade +--- + redfish-core/include/error_messages.hpp | 12 +++++++++ + .../registries/base_message_registry.hpp | 17 +++++++++++- + redfish-core/src/error_messages.cpp | 27 +++++++++++++++++++ + 3 files changed, 55 insertions(+), 1 deletion(-) + +diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp +index 922dae9..586246c 100644 +--- a/redfish-core/include/error_messages.hpp ++++ b/redfish-core/include/error_messages.hpp +@@ -222,6 +222,18 @@ nlohmann::json propertyValueFormatError(const std::string& arg1, + void propertyValueFormatError(crow::Response& res, const std::string& arg1, + const std::string& arg2); + ++/** ++ * @brief Formats PropertySizeExceeded message into JSON ++ * Message body: "The property is too long. The value exceeds its size ++ * limit." ++ * ++ * @param[in] arg1 Parameter of message that will replace %1 in its body. ++ * ++ * @returns Message PropertySizeExceeded formatted to JSON */ ++nlohmann::json propertySizeExceeded(const std::string& arg1); ++ ++void propertySizeExceeded(crow::Response& res, const std::string& arg1); ++ + /** + * @brief Formats PropertyValueNotInList message into JSON + * Message body: "The value for the property is not in the list of +diff --git a/redfish-core/include/registries/base_message_registry.hpp b/redfish-core/include/registries/base_message_registry.hpp +index 7c385a0..79d324e 100644 +--- a/redfish-core/include/registries/base_message_registry.hpp ++++ b/redfish-core/include/registries/base_message_registry.hpp +@@ -36,7 +36,7 @@ const Header header = { + constexpr const char* url = + "https://redfish.dmtf.org/registries/Base.1.8.1.json"; + +-constexpr std::array registry = { ++constexpr std::array registry = { + MessageEntry{ + "AccessDenied", + { +@@ -592,6 +592,21 @@ constexpr std::array registry = { + "Remove the property from the request body and resubmit " + "the request if the operation failed.", + }}, ++ MessageEntry{"PropertySizeExceeded", ++ { ++ "Indicates that a given property exceeds the size " ++ "limit imposed.", ++ "The property %1 is too long. The value exceeds " ++ "its size limit.", ++ "Warning", ++ "Warning", ++ 1, ++ { ++ "string", ++ }, ++ "Correct the value for the property in the request body " ++ "and resubmit the request if the operation failed.", ++ }}, + MessageEntry{"PropertyUnknown", + { + "Indicates that an unknown property was included in the " +diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp +index 409adb1..11e59be 100644 +--- a/redfish-core/src/error_messages.cpp ++++ b/redfish-core/src/error_messages.cpp +@@ -514,6 +514,33 @@ void propertyValueFormatError(crow::Response& res, const std::string& arg1, + addMessageToJson(res.jsonValue, propertyValueFormatError(arg1, arg2), arg2); + } + ++/** ++ * @internal ++ * @brief Formats PropertySizeExceeded message into JSON for the specified ++ * property ++ * ++ * See header file for more information ++ * @endinternal ++ */ ++nlohmann::json propertySizeExceeded(const std::string& arg1) ++{ ++ return nlohmann::json{ ++ {"@odata.type", "#Message.v1_1_1.Message"}, ++ {"MessageId", "Base.1.8.1.PropertySizeExceeded"}, ++ {"Message", "The property " + arg1 + ++ " is too long. The value exceeds its size limit."}, ++ {"MessageArgs", {arg1}}, ++ {"MessageSeverity", "Warning"}, ++ {"Resolution", "Correct the value for the property in the request body " ++ "and resubmit the request if the operation failed."}}; ++} ++ ++void propertySizeExceeded(crow::Response& res, const std::string& arg1) ++{ ++ res.result(boost::beast::http::status::bad_request); ++ addMessageToJson(res.jsonValue, propertySizeExceeded(arg1), arg1); ++} ++ + /** + * @internal + * @brief Formats PropertyValueNotInList message into JSON for the specified +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch index 16e8affa5..c3e3acbca 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0006-Add-EventService-SSE-filter-support.patch @@ -1,4 +1,4 @@ -From dda3c7a46391ef88e7c6a6f61fba7fe9133336bf Mon Sep 17 00:00:00 2001 +From 3dc6f6d807060cf3b38486e4190fd1ba9c66c66b Mon Sep 17 00:00:00 2001 From: AppaRao Puli Date: Wed, 17 Mar 2021 01:16:50 +0000 Subject: [PATCH] Add EventService SSE filter support @@ -25,25 +25,26 @@ Tested: - To get all Redfish events, URI: /redfish/v1/EventService/Subscriptions/SSE?$filter=(EventFormatType%20eq%20Event) - To get Redfish events with RegistryPrefix "OpenBMC" - URi: /redfish/v1/EventService/Subscriptions/SSE?$filter=(RegistryPrefix%20eq%20OpenBMC) + URI: /redfish/v1/EventService/Subscriptions/SSE?$filter=(RegistryPrefix%20eq%20OpenBMC) - To get only DC power of Events, URI: /redfish/v1/EventService/Subscriptions/SSE?$filter=(EventFormatType%20eq%20Event)%20and%20(MessageId%20eq%20DCPowerOff) Signed-off-by: AppaRao Puli +Signed-off-by: P Dheeraj Srujan Kumar Change-Id: I55c6f53bb5e57aa1f2d1601f1a16525a33b13bd2 --- - include/eventservice_sse.hpp | 94 ++++++++++++++++++- - redfish-core/include/error_messages.hpp | 9 ++ - .../include/event_service_manager.hpp | 5 + - redfish-core/lib/event_service.hpp | 5 - - redfish-core/src/error_messages.cpp | 26 +++++ - 5 files changed, 130 insertions(+), 9 deletions(-) + include/eventservice_sse.hpp | 141 +++++++++++++++++- + redfish-core/include/error_messages.hpp | 9 ++ + .../include/event_service_manager.hpp | 5 + + redfish-core/lib/event_service.hpp | 5 - + redfish-core/src/error_messages.cpp | 26 ++++ + 5 files changed, 177 insertions(+), 9 deletions(-) diff --git a/include/eventservice_sse.hpp b/include/eventservice_sse.hpp -index 6c98e6e..ff72c4d 100644 +index 6c98e6e..01e4126 100644 --- a/include/eventservice_sse.hpp +++ b/include/eventservice_sse.hpp -@@ -23,16 +23,102 @@ static bool createSubscription(std::shared_ptr& conn, +@@ -23,16 +23,149 @@ static bool createSubscription(std::shared_ptr& conn, } BMCWEB_LOG_DEBUG << "Request query param size: " << req.urlParams.size(); @@ -130,6 +131,53 @@ index 6c98e6e..ff72c4d 100644 + } + } + } ++ ++ if (!msgIds.empty()) ++ { ++ std::vector registryPrefix; ++ ++ // If no registry prefixes are mentioned, consider all supported ++ // prefixes to validate message ID ++ if (regPrefixes.empty()) ++ { ++ registryPrefix.assign(supportedRegPrefixes.begin(), ++ supportedRegPrefixes.end()); ++ } ++ ++ for (const std::string& id : msgIds) ++ { ++ bool validId = false; ++ ++ // Check for Message ID in each of the selected Registry ++ for (const std::string& it : registryPrefix) ++ { ++ const boost::beast::span< ++ const redfish::message_registries::MessageEntry> ++ registry = ++ redfish::message_registries::getRegistryFromPrefix( ++ it); ++ ++ if (std::any_of( ++ registry.cbegin(), registry.cend(), ++ [&id]( ++ const redfish::message_registries::MessageEntry& ++ messageEntry) { ++ return !id.compare(messageEntry.first); ++ })) ++ { ++ validId = true; ++ break; ++ } ++ } ++ ++ if (!validId) ++ { ++ messages::propertyValueNotInList(res, id, "MessageId"); ++ res.end(); ++ return false; ++ } ++ } ++ } + } + std::shared_ptr subValue = @@ -171,7 +219,7 @@ index 7dfdc80..922dae9 100644 } // namespace redfish diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp -index ac644c1..3661fed 100644 +index e826207..f201134 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -55,6 +55,11 @@ static constexpr const char* eventServiceFile = @@ -203,7 +251,7 @@ index 7c9bb7a..297a4ea 100644 "TerminateAfterRetries", "SuspendRetries", "RetryForever"}; diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp -index 7059a38..1e3ef2f 100644 +index ad5f819..409adb1 100644 --- a/redfish-core/src/error_messages.cpp +++ b/redfish-core/src/error_messages.cpp @@ -2147,6 +2147,32 @@ void mutualExclusiveProperties(crow::Response& res, const std::string& arg1, diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0008-Add-checks-on-Event-Subscription-input-parameters.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0008-Add-checks-on-Event-Subscription-input-parameters.patch new file mode 100644 index 000000000..874c82e2f --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/eventservice/0008-Add-checks-on-Event-Subscription-input-parameters.patch @@ -0,0 +1,85 @@ +From b43da33c7bc9ad4d5eea35c9ba68efdd6ed6d34d Mon Sep 17 00:00:00 2001 +From: Nitin Wankhade +Date: Mon, 28 Jun 2021 19:59:57 +0000 +Subject: [PATCH] Add checks on Event Subscription input parameters + +There is no check on the size of input parameters(Context, +Destination and Header) during Event Subscription.This +creates out of memory situation. +This commit checks for the size of input parameters and +rejects if it is exceeding the input size limits. + +Tested + - Validated using POST on Event Subscription. + - When Context, Destination and Headers were too long, + received a error message denoting the same. + +Change-Id: Iec2cd766c0e137b72706fc2da468d4fefd8fbaae +Signed-off-by: Nitin Wankhade +--- + redfish-core/lib/event_service.hpp | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp +index ed4955e..0cb0f00 100644 +--- a/redfish-core/lib/event_service.hpp ++++ b/redfish-core/lib/event_service.hpp +@@ -16,6 +16,10 @@ + #pragma once + #include "event_service_manager.hpp" + ++#define MAX_CONTEXT_SIZE 256 ++#define MAX_DESTINATION_SIZE 1024 ++#define MAX_HEADER_SIZE 8096 ++ + namespace redfish + { + static constexpr const std::array supportedRetryPolicies = { +@@ -243,7 +247,11 @@ class EventDestinationCollection : public Node + { + return; + } +- ++ if (destUrl.size() > MAX_DESTINATION_SIZE) ++ { ++ messages::propertySizeExceeded(asyncResp->res, "Destination"); ++ return; ++ } + if (regPrefixes && msgIds) + { + if (regPrefixes->size() && msgIds->size()) +@@ -350,11 +358,31 @@ class EventDestinationCollection : public Node + + if (context) + { ++ if (context->size() > MAX_CONTEXT_SIZE) ++ { ++ messages::propertySizeExceeded(asyncResp->res, "Context"); ++ return; ++ } + subValue->customText = *context; + } + + if (headers) + { ++ size_t cumulativeLen = 0; ++ ++ for (nlohmann::json& itr : *headers) ++ { ++ std::string hdr{itr.dump( ++ -1, ' ', true, nlohmann::json::error_handler_t::replace)}; ++ cumulativeLen += hdr.length(); ++ ++ if (cumulativeLen > MAX_HEADER_SIZE) ++ { ++ messages::propertySizeExceeded(asyncResp->res, ++ "HttpHeaders"); ++ return; ++ } ++ } + subValue->httpHeaders = *headers; + } + +-- +2.17.1 + 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 new file mode 100644 index 000000000..f03e49223 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0001-Add-support-for-MetricDefinition-scheme.patch @@ -0,0 +1,491 @@ +From 6acffea563905c00f4b6d00c738fe7516e03c724 Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +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. + +Tested: + - MetricDefinitions response is filled with existing sensors, it works + with and without Telemetry service + - Validated a presence of MetricDefinition members and its attributes + - Successfully passed RedfishServiceValidator.py using witherspoon image + on QEMU + +Signed-off-by: Wludzik, Jozef +Signed-off-by: Krzysztof Grobelny +Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00 +--- + redfish-core/include/redfish.hpp | 3 + + .../include/utils/get_chassis_names.hpp | 58 ++++ + .../include/utils/telemetry_utils.hpp | 2 + + redfish-core/lib/metric_definition.hpp | 264 ++++++++++++++++++ + redfish-core/lib/sensors.hpp | 25 +- + redfish-core/lib/telemetry_service.hpp | 2 + + 6 files changed, 342 insertions(+), 12 deletions(-) + create mode 100644 redfish-core/include/utils/get_chassis_names.hpp + create mode 100644 redfish-core/lib/metric_definition.hpp + +diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp +index 4418c3d..594520d 100644 +--- a/redfish-core/include/redfish.hpp ++++ b/redfish-core/include/redfish.hpp +@@ -25,6 +25,7 @@ + #include "../lib/managers.hpp" + #include "../lib/memory.hpp" + #include "../lib/message_registries.hpp" ++#include "../lib/metric_definition.hpp" + #include "../lib/metric_report.hpp" + #include "../lib/metric_report_definition.hpp" + #include "../lib/network_protocol.hpp" +@@ -215,6 +216,8 @@ class RedfishService + nodes.emplace_back(std::make_unique(app)); + + nodes.emplace_back(std::make_unique(app)); ++ nodes.emplace_back(std::make_unique(app)); ++ nodes.emplace_back(std::make_unique(app)); + nodes.emplace_back( + std::make_unique(app)); + nodes.emplace_back(std::make_unique(app)); +diff --git a/redfish-core/include/utils/get_chassis_names.hpp b/redfish-core/include/utils/get_chassis_names.hpp +new file mode 100644 +index 0000000..0276b6f +--- /dev/null ++++ b/redfish-core/include/utils/get_chassis_names.hpp +@@ -0,0 +1,58 @@ ++#pragma once ++ ++#include ++ ++#include ++#include ++#include ++ ++namespace redfish ++{ ++ ++namespace utils ++{ ++ ++template ++inline void getChassisNames(F&& cb) ++{ ++ const std::array interfaces = { ++ "xyz.openbmc_project.Inventory.Item.Board", ++ "xyz.openbmc_project.Inventory.Item.Chassis"}; ++ ++ crow::connections::systemBus->async_method_call( ++ [callback = std::move(cb)](const boost::system::error_code ec, ++ const std::vector& chassis) { ++ std::vector chassisNames; ++ ++ if (ec) ++ { ++ callback(ec, chassisNames); ++ return; ++ } ++ ++ chassisNames.reserve(chassis.size()); ++ for (const std::string& path : chassis) ++ { ++ sdbusplus::message::object_path dbusPath = path; ++ std::string name = dbusPath.filename(); ++ if (name.empty()) ++ { ++ callback(boost::system::errc::make_error_code( ++ boost::system::errc::invalid_argument), ++ chassisNames); ++ return; ++ } ++ chassisNames.emplace_back(std::move(name)); ++ } ++ ++ callback(ec, chassisNames); ++ }, ++ "xyz.openbmc_project.ObjectMapper", ++ "/xyz/openbmc_project/object_mapper", ++ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", ++ "/xyz/openbmc_project/inventory", 0, interfaces); ++} ++ ++} // namespace utils ++ ++} // namespace redfish +diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp +index 5872350..1b4f75d 100644 +--- a/redfish-core/include/utils/telemetry_utils.hpp ++++ b/redfish-core/include/utils/telemetry_utils.hpp +@@ -10,6 +10,8 @@ namespace telemetry + + constexpr const char* service = "xyz.openbmc_project.Telemetry"; + constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report"; ++constexpr const char* metricDefinitionUri = ++ "/redfish/v1/TelemetryService/MetricDefinitions/"; + constexpr const char* metricReportDefinitionUri = + "/redfish/v1/TelemetryService/MetricReportDefinitions/"; + 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..072fe20 +--- /dev/null ++++ b/redfish-core/lib/metric_definition.hpp +@@ -0,0 +1,264 @@ ++#pragma once ++ ++#include "async_resp.hpp" ++#include "node.hpp" ++#include "sensors.hpp" ++#include "utils/get_chassis_names.hpp" ++#include "utils/telemetry_utils.hpp" ++ ++namespace redfish ++{ ++ ++namespace telemetry ++{ ++ ++void addMembers(crow::Response& res, ++ const boost::container::flat_map& el) ++{ ++ for (const auto& [_, dbusSensor] : el) ++ { ++ sdbusplus::message::object_path path(dbusSensor); ++ sdbusplus::message::object_path parentPath = path.parent_path(); ++ const std::string type = parentPath.filename(); ++ ++ if (type.empty()) ++ { ++ BMCWEB_LOG_ERROR << "Received invalid DBus Sensor Path = " ++ << dbusSensor; ++ continue; ++ } ++ ++ nlohmann::json& members = res.jsonValue["Members"]; ++ ++ const std::string odataId = ++ 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(); ++ if (!value) ++ { ++ return false; ++ } ++ return *value == odataId; ++ }); ++ ++ if (it == members.end()) ++ { ++ members.push_back({{"@odata.id", odataId}}); ++ } ++ ++ res.jsonValue["Members@odata.count"] = members.size(); ++ } ++} ++ ++} // namespace telemetry ++ ++class MetricDefinitionCollection : public Node ++{ ++ public: ++ MetricDefinitionCollection(App& app) : ++ Node(app, "/redfish/v1/TelemetryService/MetricDefinitions/") ++ { ++ entityPrivileges = { ++ {boost::beast::http::verb::get, {{"Login"}}}, ++ {boost::beast::http::verb::head, {{"Login"}}}, ++ {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, ++ {boost::beast::http::verb::put, {{"ConfigureManager"}}}, ++ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, ++ {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; ++ } ++ ++ private: ++ void doGet(const std::shared_ptr& asyncResp, ++ const crow::Request&, const std::vector&) override ++ { ++ asyncResp->res.jsonValue["@odata.type"] = "#MetricDefinitionCollection." ++ "MetricDefinitionCollection"; ++ asyncResp->res.jsonValue["@odata.id"] = ++ "/redfish/v1/TelemetryService/MetricDefinitions"; ++ asyncResp->res.jsonValue["Name"] = "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& 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(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); ++ } ++ } ++ }); ++ } ++}; ++ ++namespace telemetry ++{ ++ ++bool isSensorIdSupported(std::string_view readingType) ++{ ++ for (const std::pair>& ++ typeToPaths : sensors::dbus::paths) ++ { ++ for (const char* supportedPath : typeToPaths.second) ++ { ++ if (readingType == ++ sensors::toReadingType( ++ sdbusplus::message::object_path(supportedPath).filename())) ++ { ++ return true; ++ } ++ } ++ } ++ return false; ++} ++ ++void addMetricProperty( ++ bmcweb::AsyncResp& asyncResp, const std::string& readingType, ++ const boost::container::flat_map& el) ++{ ++ nlohmann::json& metricProperties = ++ asyncResp.res.jsonValue["MetricProperties"]; ++ ++ for (const auto& [redfishSensor, dbusSensor] : el) ++ { ++ std::string sensorId; ++ if (dbus::utility::getNthStringFromPath(dbusSensor, 3, sensorId)) ++ { ++ if (sensors::toReadingType(sensorId) == readingType) ++ { ++ metricProperties.push_back(redfishSensor); ++ } ++ } ++ } ++} ++ ++} // namespace telemetry ++ ++class MetricDefinition : public Node ++{ ++ public: ++ MetricDefinition(App& app) : ++ Node(app, "/redfish/v1/TelemetryService/MetricDefinitions//", ++ std::string()) ++ { ++ entityPrivileges = { ++ {boost::beast::http::verb::get, {{"Login"}}}, ++ {boost::beast::http::verb::head, {{"Login"}}}, ++ {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, ++ {boost::beast::http::verb::put, {{"ConfigureManager"}}}, ++ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, ++ {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; ++ } ++ ++ private: ++ void doGet(const std::shared_ptr& asyncResp, ++ const crow::Request&, ++ const std::vector& params) override ++ { ++ if (params.size() != 1) ++ { ++ messages::internalError(asyncResp->res); ++ return; ++ } ++ ++ const std::string& readingType = params[0]; ++ ++ if (!telemetry::isSensorIdSupported(readingType)) ++ { ++ messages::resourceNotFound(asyncResp->res, "MetricDefinition", ++ readingType); ++ 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& ++ chassisNames) { ++ if (ec) ++ { ++ messages::internalError(asyncResp->res); ++ BMCWEB_LOG_ERROR << "getChassisNames error: " << ec.value(); ++ return; ++ } ++ ++ auto handleRetrieveUriToDbusMap = ++ [asyncResp, readingType]( ++ 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); ++ 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); ++ } ++ } ++ }); ++ } ++}; ++ ++} // namespace redfish +diff --git a/redfish-core/lib/sensors.hpp b/redfish-core/lib/sensors.hpp +index e7f4cde..b16b014 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 9ec0737..de9c800 100644 +--- a/redfish-core/lib/telemetry_service.hpp ++++ b/redfish-core/lib/telemetry_service.hpp +@@ -32,6 +32,8 @@ class TelemetryService : public Node + asyncResp->res.jsonValue["Id"] = "TelemetryService"; + asyncResp->res.jsonValue["Name"] = "Telemetry Service"; + ++ asyncResp->res.jsonValue["MetricDefinitions"]["@odata.id"] = ++ "/redfish/v1/TelemetryService/MetricDefinitions"; + asyncResp->res.jsonValue["MetricReportDefinitions"]["@odata.id"] = + "/redfish/v1/TelemetryService/MetricReportDefinitions"; + asyncResp->res.jsonValue["MetricReports"]["@odata.id"] = +-- +2.17.1 + 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 new file mode 100644 index 000000000..9b77c29df --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0002-Sync-Telmetry-service-with-EventService.patch @@ -0,0 +1,294 @@ +From 206411b4c9b603e7b0edf63e03c0ef7bf10b09b2 Mon Sep 17 00:00:00 2001 +From: "Wludzik, Jozef" +Date: Tue, 15 Dec 2020 12:30:31 +0100 +Subject: [PATCH] Sync Telmetry service with EventService + +Synced the latest changes in Telemetry service with Event Service +code. Now assembling MetricReport is covered in single place in +code. Updated method of fetching Readings from Telemetry by +Event Service. Using ReportUpdate signal is no longer +supported. Now Event Service monitors for PropertiesChanged signal +from /xyz/openbmc_project/Telemetry/Reports path. + +Tested: + - Verified that EventListener received MetricReport response from + Event Service in insecure http push style eventing mode + +Change-Id: I2fc1841a6c9259a8bff30b34bddc0d4aabd41912 +Signed-off-by: Wludzik, Jozef +--- + .../include/event_service_manager.hpp | 156 ++++++------------ + redfish-core/lib/metric_report.hpp | 28 ++-- + 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 a1761bb..0e2ebfd 100644 +--- a/redfish-core/include/event_service_manager.hpp ++++ b/redfish-core/include/event_service_manager.hpp +@@ -14,6 +14,7 @@ + // limitations under the License. + */ + #pragma once ++#include "metric_report.hpp" + #include "node.hpp" + #include "registries.hpp" + #include "registries/base_message_registry.hpp" +@@ -523,47 +524,32 @@ class Subscription + } + #endif + +- void filterAndSendReports(const std::string& id2, +- const std::string& readingsTs, +- const ReadingsObjType& readings) ++ void filterAndSendReports( ++ const std::string& id, ++ const std::variant& var) + { +- std::string metricReportDef = +- "/redfish/v1/TelemetryService/MetricReportDefinitions/" + id2; ++ std::string mrdUri = telemetry::metricReportDefinitionUri + id; + + // Empty list means no filter. Send everything. + if (metricReportDefinitions.size()) + { + if (std::find(metricReportDefinitions.begin(), + metricReportDefinitions.end(), +- metricReportDef) == metricReportDefinitions.end()) ++ mrdUri) == metricReportDefinitions.end()) + { + return; + } + } + +- nlohmann::json metricValuesArray = nlohmann::json::array(); +- for (const auto& it : readings) ++ nlohmann::json msg; ++ if (!telemetry::fillReport(msg, id, var)) + { +- metricValuesArray.push_back({}); +- nlohmann::json& entry = metricValuesArray.back(); +- +- auto& [id, property, value, timestamp] = it; +- +- entry = {{"MetricId", id}, +- {"MetricProperty", property}, +- {"MetricValue", std::to_string(value)}, +- {"Timestamp", crow::utility::getDateTime(timestamp)}}; ++ BMCWEB_LOG_ERROR << "Failed to fill the MetricReport for DBus " ++ "Report with id " ++ << id; ++ return; + } + +- nlohmann::json msg = { +- {"@odata.id", "/redfish/v1/TelemetryService/MetricReports/" + id}, +- {"@odata.type", "#MetricReport.v1_3_0.MetricReport"}, +- {"Id", id2}, +- {"Name", id2}, +- {"Timestamp", readingsTs}, +- {"MetricReportDefinition", {{"@odata.id", metricReportDef}}}, +- {"MetricValues", metricValuesArray}}; +- + this->sendEvent( + msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); + } +@@ -1359,75 +1345,6 @@ class EventServiceManager + } + + #endif +- +- void getMetricReading(const std::string& service, +- const std::string& objPath, const std::string& intf) +- { +- std::size_t found = objPath.find_last_of('/'); +- if (found == std::string::npos) +- { +- BMCWEB_LOG_DEBUG << "Invalid objPath received"; +- return; +- } +- +- std::string idStr = objPath.substr(found + 1); +- if (idStr.empty()) +- { +- BMCWEB_LOG_DEBUG << "Invalid ID in objPath"; +- return; +- } +- +- crow::connections::systemBus->async_method_call( +- [idStr{std::move(idStr)}]( +- const boost::system::error_code ec, +- boost::container::flat_map< +- std::string, std::variant>& +- resp) { +- if (ec) +- { +- BMCWEB_LOG_DEBUG +- << "D-Bus call failed to GetAll metric readings."; +- return; +- } +- +- const int32_t* timestampPtr = +- std::get_if(&resp["Timestamp"]); +- if (!timestampPtr) +- { +- BMCWEB_LOG_DEBUG << "Failed to Get timestamp."; +- return; +- } +- +- ReadingsObjType* readingsPtr = +- std::get_if(&resp["Readings"]); +- if (!readingsPtr) +- { +- BMCWEB_LOG_DEBUG << "Failed to Get Readings property."; +- return; +- } +- +- if (!readingsPtr->size()) +- { +- BMCWEB_LOG_DEBUG << "No metrics report to be transferred"; +- return; +- } +- +- for (const auto& it : +- EventServiceManager::getInstance().subscriptionsMap) +- { +- std::shared_ptr entry = it.second; +- if (entry->eventFormatType == metricReportFormatType) +- { +- entry->filterAndSendReports( +- idStr, crow::utility::getDateTime(*timestampPtr), +- *readingsPtr); +- } +- } +- }, +- service, objPath, "org.freedesktop.DBus.Properties", "GetAll", +- intf); +- } +- + void unregisterMetricReportSignal() + { + if (matchTelemetryMonitor) +@@ -1447,9 +1364,11 @@ class EventServiceManager + } + + BMCWEB_LOG_DEBUG << "Metrics report signal - Register"; +- std::string matchStr( +- "type='signal',member='ReportUpdate', " +- "interface='xyz.openbmc_project.MonitoringService.Report'"); ++ std::string matchStr = "type='signal',member='PropertiesChanged'," ++ "interface='org.freedesktop.DBus.Properties'," ++ "path_namespace=/xyz/openbmc_project/Telemetry/" ++ "Reports/TelemetryService," ++ "arg0=xyz.openbmc_project.Telemetry.Report"; + + matchTelemetryMonitor = std::make_shared( + *crow::connections::systemBus, matchStr, +@@ -1460,10 +1379,43 @@ class EventServiceManager + return; + } + +- std::string service = msg.get_sender(); +- std::string objPath = msg.get_path(); +- std::string intf = msg.get_interface(); +- getMetricReading(service, objPath, intf); ++ sdbusplus::message::object_path path(msg.get_path()); ++ std::string id = path.filename(); ++ if (id.empty()) ++ { ++ BMCWEB_LOG_ERROR << "Failed to get Id from path"; ++ return; ++ } ++ ++ std::string intf; ++ std::vector>> ++ props; ++ std::vector invalidProps; ++ msg.read(intf, props, invalidProps); ++ ++ auto found = ++ std::find_if(props.begin(), props.end(), [](const auto& x) { ++ return x.first == "Readings"; ++ }); ++ if (found == props.end()) ++ { ++ BMCWEB_LOG_ERROR ++ << "Failed to get Readings from Report properties"; ++ return; ++ } ++ ++ std::variant& readings = ++ found->second; ++ for (const auto& it : ++ EventServiceManager::getInstance().subscriptionsMap) ++ { ++ Subscription& entry = *it.second.get(); ++ if (entry.eventFormatType == metricReportFormatType) ++ { ++ entry.filterAndSendReports(id, readings); ++ } ++ } + }); + } + +diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp +index ad15a05..18a6dcc 100644 +--- a/redfish-core/lib/metric_report.hpp ++++ b/redfish-core/lib/metric_report.hpp +@@ -31,16 +31,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) + return metricValues; + } + +-inline void fillReport(const std::shared_ptr& asyncResp, +- const std::string& id, ++inline bool fillReport(nlohmann::json& json, const std::string& id, + const std::variant& var) + { +- asyncResp->res.jsonValue["@odata.type"] = +- "#MetricReport.v1_3_0.MetricReport"; +- asyncResp->res.jsonValue["@odata.id"] = telemetry::metricReportUri + id; +- asyncResp->res.jsonValue["Id"] = id; +- asyncResp->res.jsonValue["Name"] = id; +- asyncResp->res.jsonValue["MetricReportDefinition"]["@odata.id"] = ++ json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport"; ++ json["@odata.id"] = telemetry::metricReportUri + id; ++ json["Id"] = id; ++ json["Name"] = id; ++ json["MetricReportDefinition"]["@odata.id"] = + telemetry::metricReportDefinitionUri + id; + + const TimestampReadings* timestampReadings = +@@ -48,14 +46,14 @@ inline void fillReport(const std::shared_ptr& asyncResp, + if (!timestampReadings) + { + BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; +- messages::internalError(asyncResp->res); +- return; ++ return false; + } + + const auto& [timestamp, readings] = *timestampReadings; +- asyncResp->res.jsonValue["Timestamp"] = ++ json["Timestamp"] = + crow::utility::getDateTime(static_cast(timestamp)); +- asyncResp->res.jsonValue["MetricValues"] = toMetricValues(readings); ++ json["MetricValues"] = toMetricValues(readings); ++ return true; + } + } // namespace telemetry + +@@ -145,7 +143,11 @@ class MetricReport : public Node + return; + } + +- telemetry::fillReport(asyncResp, id, ret); ++ if (!telemetry::fillReport(asyncResp->res.jsonValue, id, ++ ret)) ++ { ++ messages::internalError(asyncResp->res); ++ } + }, + telemetry::service, reportPath, + "org.freedesktop.DBus.Properties", "Get", +-- +2.25.1 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Add-support-for-MetricDefinition-scheme.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Add-support-for-MetricDefinition-scheme.patch deleted file mode 100644 index 8b08c6c5e..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Add-support-for-MetricDefinition-scheme.patch +++ /dev/null @@ -1,421 +0,0 @@ -From d664a145a96a642597c74819c183410d4a04fce0 Mon Sep 17 00:00:00 2001 -From: Krzysztof Grobelny -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. - -Tested: - - MetricDefinitions response is filled with existing sensors, - it works with and without Telemetry service - - Validated a presence of MetricDefinition members and it - attributes - - Succesfully passed RedfishServiceValidator.py using - witherspoon image on QEMU - -Signed-off-by: Wludzik, Jozef -Signed-off-by: Krzysztof Grobelny -Change-Id: I3086e1302e1ba2e5442d1367939fd5507a0cbc00 ---- - redfish-core/include/redfish.hpp | 3 + - .../include/utils/telemetry_utils.hpp | 2 + - redfish-core/lib/metric_definition.hpp | 335 ++++++++++++++++++ - redfish-core/lib/telemetry_service.hpp | 2 + - 4 files changed, 342 insertions(+) - create mode 100644 redfish-core/lib/metric_definition.hpp - -diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp -index 7a14969..d280a86 100644 ---- a/redfish-core/include/redfish.hpp -+++ b/redfish-core/include/redfish.hpp -@@ -26,6 +26,7 @@ - #include "../lib/managers.hpp" - #include "../lib/memory.hpp" - #include "../lib/message_registries.hpp" -+#include "../lib/metric_definition.hpp" - #include "../lib/metric_report.hpp" - #include "../lib/metric_report_definition.hpp" - #include "../lib/network_protocol.hpp" -@@ -219,6 +220,8 @@ class RedfishService - nodes.emplace_back(std::make_unique(app)); - - nodes.emplace_back(std::make_unique(app)); -+ nodes.emplace_back(std::make_unique(app)); -+ nodes.emplace_back(std::make_unique(app)); - nodes.emplace_back( - std::make_unique(app)); - nodes.emplace_back(std::make_unique(app)); -diff --git a/redfish-core/include/utils/telemetry_utils.hpp b/redfish-core/include/utils/telemetry_utils.hpp -index 5872350..1b4f75d 100644 ---- a/redfish-core/include/utils/telemetry_utils.hpp -+++ b/redfish-core/include/utils/telemetry_utils.hpp -@@ -10,6 +10,8 @@ namespace telemetry - - constexpr const char* service = "xyz.openbmc_project.Telemetry"; - constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report"; -+constexpr const char* metricDefinitionUri = -+ "/redfish/v1/TelemetryService/MetricDefinitions/"; - constexpr const char* metricReportDefinitionUri = - "/redfish/v1/TelemetryService/MetricReportDefinitions/"; - 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..515fe86 ---- /dev/null -+++ b/redfish-core/lib/metric_definition.hpp -@@ -0,0 +1,335 @@ -+#pragma once -+ -+#include "async_resp.hpp" -+#include "node.hpp" -+#include "sensors.hpp" -+#include "utils/telemetry_utils.hpp" -+ -+namespace redfish -+{ -+ -+namespace utils -+{ -+ -+class AsyncRespWithFinalizer -+{ -+ public: -+ AsyncRespWithFinalizer( -+ const std::shared_ptr& asyncResp) : -+ asyncResp(asyncResp) -+ {} -+ -+ AsyncRespWithFinalizer(const std::shared_ptr& asyncResp, -+ std::function finalizer) : -+ asyncResp(asyncResp), -+ finalizer(std::move(finalizer)) -+ {} -+ -+ AsyncRespWithFinalizer(const AsyncRespWithFinalizer&) = delete; -+ AsyncRespWithFinalizer(AsyncRespWithFinalizer&&) = delete; -+ -+ ~AsyncRespWithFinalizer() -+ { -+ if (finalizer) -+ { -+ try -+ { -+ finalizer(asyncResp->res); -+ } -+ catch (const std::exception& e) -+ { -+ BMCWEB_LOG_ERROR << "Executing finalizer failed: " << e.what(); -+ messages::internalError(asyncResp->res); -+ } -+ } -+ } -+ -+ void setFinalizer(std::function newFinalizer) -+ { -+ finalizer = std::move(newFinalizer); -+ } -+ -+ private: -+ std::shared_ptr asyncResp; -+ std::function finalizer; -+ -+ public: -+ crow::Response& res = asyncResp->res; -+}; -+ -+template -+inline void getChassisNames(F&& cb) -+{ -+ const std::array interfaces = { -+ "xyz.openbmc_project.Inventory.Item.Board", -+ "xyz.openbmc_project.Inventory.Item.Chassis"}; -+ -+ crow::connections::systemBus->async_method_call( -+ [callback = std::move(cb)](const boost::system::error_code ec, -+ const std::vector& chassis) { -+ std::vector chassisNames; -+ -+ if (ec) -+ { -+ callback(ec, chassisNames); -+ return; -+ } -+ -+ chassisNames.reserve(chassis.size()); -+ for (const std::string& path : chassis) -+ { -+ sdbusplus::message::object_path dbusPath = path; -+ std::string name = dbusPath.filename(); -+ if (name.empty()) -+ { -+ callback(boost::system::errc::make_error_code( -+ boost::system::errc::invalid_argument), -+ chassisNames); -+ return; -+ } -+ chassisNames.emplace_back(std::move(name)); -+ } -+ -+ callback(ec, chassisNames); -+ }, -+ "xyz.openbmc_project.ObjectMapper", -+ "/xyz/openbmc_project/object_mapper", -+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", -+ "/xyz/openbmc_project/inventory", 0, interfaces); -+} -+ -+} // namespace utils -+ -+namespace telemetry -+{ -+ -+void addMembers(crow::Response& res, -+ const boost::container::flat_map& el) -+{ -+ for (const auto& [_, dbusSensor] : el) -+ { -+ sdbusplus::message::object_path path(dbusSensor); -+ sdbusplus::message::object_path parentPath = path.parent_path(); -+ std::string type = parentPath.filename(); -+ if (type.empty()) -+ { -+ BMCWEB_LOG_ERROR << "Received invalid DBus Sensor Path = " -+ << dbusSensor; -+ continue; -+ } -+ -+ nlohmann::json& members = res.jsonValue["Members"]; -+ -+ const std::string odataId = -+ telemetry::metricDefinitionUri + std::move(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; -+ } -+ return kt->get() == odataId; -+ }); -+ -+ if (it == members.end()) -+ { -+ members.push_back({{"@odata.id", odataId}}); -+ } -+ -+ res.jsonValue["Members@odata.count"] = members.size(); -+ } -+} -+ -+} // namespace telemetry -+ -+class MetricDefinitionCollection : public Node -+{ -+ public: -+ MetricDefinitionCollection(App& app) : -+ Node(app, "/redfish/v1/TelemetryService/MetricDefinitions/") -+ { -+ entityPrivileges = { -+ {boost::beast::http::verb::get, {{"Login"}}}, -+ {boost::beast::http::verb::head, {{"Login"}}}, -+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, -+ {boost::beast::http::verb::put, {{"ConfigureManager"}}}, -+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, -+ {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; -+ } -+ -+ private: -+ void doGet(const std::shared_ptr& asyncResp, -+ const crow::Request&, const std::vector&) override -+ { -+ asyncResp->res.jsonValue["@odata.type"] = "#MetricDefinitionCollection." -+ "MetricDefinitionCollection"; -+ asyncResp->res.jsonValue["@odata.id"] = -+ "/redfish/v1/TelemetryService/MetricDefinitions"; -+ asyncResp->res.jsonValue["Name"] = "Metric Definition Collection"; -+ asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); -+ asyncResp->res.jsonValue["Members@odata.count"] = 0; -+ -+ auto handleRetrieveUriToDbusMap = -+ [asyncResp]( -+ 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); -+ messages::internalError(asyncResp->res); -+ return; -+ } -+ telemetry::addMembers(asyncResp->res, uriToDbus); -+ }; -+ -+ utils::getChassisNames( -+ [handleRetrieveUriToDbusMap = std::move(handleRetrieveUriToDbusMap), -+ asyncResp](boost::system::error_code ec, -+ const std::vector& chassisNames) { -+ if (ec) -+ { -+ messages::internalError(asyncResp->res); -+ BMCWEB_LOG_ERROR << "getChassisNames error: " << ec.value(); -+ return; -+ } -+ -+ 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); -+ } -+ } -+ }); -+ } -+}; -+ -+namespace telemetry -+{ -+ -+void addMetricProperty( -+ utils::AsyncRespWithFinalizer& asyncResp, const std::string& id, -+ const boost::container::flat_map& el) -+{ -+ nlohmann::json& metricProperties = -+ asyncResp.res.jsonValue["MetricProperties"]; -+ -+ for (const auto& [redfishSensor, dbusSensor] : el) -+ { -+ std::string sensorId; -+ if (dbus::utility::getNthStringFromPath(dbusSensor, 3, sensorId)) -+ { -+ if (sensorId == id) -+ { -+ metricProperties.push_back(redfishSensor); -+ } -+ } -+ } -+} -+ -+} // namespace telemetry -+ -+class MetricDefinition : public Node -+{ -+ public: -+ MetricDefinition(App& app) : -+ Node(app, "/redfish/v1/TelemetryService/MetricDefinitions//", -+ std::string()) -+ { -+ entityPrivileges = { -+ {boost::beast::http::verb::get, {{"Login"}}}, -+ {boost::beast::http::verb::head, {{"Login"}}}, -+ {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, -+ {boost::beast::http::verb::put, {{"ConfigureManager"}}}, -+ {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, -+ {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; -+ } -+ -+ private: -+ void doGet(const std::shared_ptr& asyncResp, -+ const crow::Request&, -+ const std::vector& params) override -+ { -+ auto telemetryAsyncResp = -+ std::make_shared(asyncResp); -+ -+ if (params.size() != 1) -+ { -+ messages::internalError(telemetryAsyncResp->res); -+ return; -+ } -+ -+ const std::string& id = params[0]; -+ telemetryAsyncResp->setFinalizer([id](crow::Response& res) { -+ if (res.jsonValue["MetricProperties"].empty()) -+ { -+ messages::resourceNotFound(res, "MetricDefinition", id); -+ } -+ }); -+ -+ telemetryAsyncResp->res.jsonValue["MetricProperties"] = -+ nlohmann::json::array(); -+ telemetryAsyncResp->res.jsonValue["Id"] = id; -+ telemetryAsyncResp->res.jsonValue["Name"] = id; -+ telemetryAsyncResp->res.jsonValue["@odata.id"] = -+ telemetry::metricDefinitionUri + id; -+ telemetryAsyncResp->res.jsonValue["@odata.type"] = -+ "#MetricDefinition.v1_0_3.MetricDefinition"; -+ telemetryAsyncResp->res.jsonValue["MetricDataType"] = "Decimal"; -+ telemetryAsyncResp->res.jsonValue["MetricType"] = "Numeric"; -+ telemetryAsyncResp->res.jsonValue["IsLinear"] = true; -+ telemetryAsyncResp->res.jsonValue["Units"] = -+ sensors::toReadingUnits(id); -+ -+ auto handleRetrieveUriToDbusMap = -+ [telemetryAsyncResp, -+ id](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); -+ messages::internalError(telemetryAsyncResp->res); -+ return; -+ } -+ telemetry::addMetricProperty(*telemetryAsyncResp, id, -+ uriToDbus); -+ }; -+ -+ utils::getChassisNames( -+ [handleRetrieveUriToDbusMap = std::move(handleRetrieveUriToDbusMap), -+ telemetryAsyncResp, -+ id](boost::system::error_code ec, -+ const std::vector& chassisNames) { -+ if (ec) -+ { -+ messages::internalError(telemetryAsyncResp->res); -+ BMCWEB_LOG_ERROR << "getChassisNames error: " << ec.value(); -+ return; -+ } -+ -+ for (const std::string& chassisName : chassisNames) -+ { -+ for (const auto& [sensorNode, dbusPaths] : -+ sensors::dbus::paths) -+ { -+ retrieveUriToDbusMap(chassisName, sensorNode.data(), -+ handleRetrieveUriToDbusMap); -+ } -+ } -+ }); -+ } -+}; -+ -+} // namespace redfish -diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp -index 9ec0737..de9c800 100644 ---- a/redfish-core/lib/telemetry_service.hpp -+++ b/redfish-core/lib/telemetry_service.hpp -@@ -32,6 +32,8 @@ class TelemetryService : public Node - asyncResp->res.jsonValue["Id"] = "TelemetryService"; - asyncResp->res.jsonValue["Name"] = "Telemetry Service"; - -+ asyncResp->res.jsonValue["MetricDefinitions"]["@odata.id"] = -+ "/redfish/v1/TelemetryService/MetricDefinitions"; - asyncResp->res.jsonValue["MetricReportDefinitions"]["@odata.id"] = - "/redfish/v1/TelemetryService/MetricReportDefinitions"; - asyncResp->res.jsonValue["MetricReports"]["@odata.id"] = --- -2.17.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/0003-Revert-Remove-LogService-from-TelemetryService.patch new file mode 100644 index 000000000..645351a51 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch @@ -0,0 +1,26 @@ +From dc7e43c70285596195efd9d328b303091794278c Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +Date: Mon, 31 May 2021 10:08:57 +0000 +Subject: [PATCH] Revert "Remove LogService from TelemetryService" + +This reverts commit 2b3da45876aac57a36d3093379a992d699e7e396. +--- + redfish-core/lib/telemetry_service.hpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/redfish-core/lib/telemetry_service.hpp b/redfish-core/lib/telemetry_service.hpp +index de9c800..f05bf6d 100644 +--- a/redfish-core/lib/telemetry_service.hpp ++++ b/redfish-core/lib/telemetry_service.hpp +@@ -38,6 +38,8 @@ class TelemetryService : public Node + "/redfish/v1/TelemetryService/MetricReportDefinitions"; + asyncResp->res.jsonValue["MetricReports"]["@odata.id"] = + "/redfish/v1/TelemetryService/MetricReports"; ++ asyncResp->res.jsonValue["LogService"]["@odata.id"] = ++ "/redfish/v1/Managers/bmc/LogServices/Journal"; + + crow::connections::systemBus->async_method_call( + [asyncResp]( +-- +2.25.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Sync-Telmetry-service-with-EventService.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Sync-Telmetry-service-with-EventService.patch deleted file mode 100644 index 4119045f1..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-Sync-Telmetry-service-with-EventService.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 0ed9ff4f37e7d3ea81073ad35acd530730104033 Mon Sep 17 00:00:00 2001 -From: "Wludzik, Jozef" -Date: Tue, 15 Dec 2020 12:30:31 +0100 -Subject: [PATCH] Sync Telmetry service with EventService - -Synced the latest changes in Telemetry service with Event Service -code. Now assembling MetricReport is covered in single place in -code. Updated method of fetching Readings from Telemetry by -Event Service. Using ReportUpdate signal is no longer -supported. Now Event Service monitors for PropertiesChanged signal -from /xyz/openbmc_project/Telemetry/Reports path. - -Tested: - - Verified that EventListener received MetricReport response from - Event Service in insecure http push style eventing mode - -Change-Id: I2fc1841a6c9259a8bff30b34bddc0d4aabd41912 -Signed-off-by: Wludzik, Jozef ---- - .../include/event_service_manager.hpp | 156 ++++++------------ - redfish-core/lib/metric_report.hpp | 28 ++-- - 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 c3c110a..dc99cda 100644 ---- a/redfish-core/include/event_service_manager.hpp -+++ b/redfish-core/include/event_service_manager.hpp -@@ -14,6 +14,7 @@ - // limitations under the License. - */ - #pragma once -+#include "metric_report.hpp" - #include "node.hpp" - #include "registries.hpp" - #include "registries/base_message_registry.hpp" -@@ -529,47 +530,32 @@ class Subscription - } - #endif - -- void filterAndSendReports(const std::string& id2, -- const std::string& readingsTs, -- const ReadingsObjType& readings) -+ void filterAndSendReports( -+ const std::string& id, -+ const std::variant& var) - { -- std::string metricReportDef = -- "/redfish/v1/TelemetryService/MetricReportDefinitions/" + id2; -+ std::string mrdUri = telemetry::metricReportDefinitionUri + id; - - // Empty list means no filter. Send everything. - if (metricReportDefinitions.size()) - { - if (std::find(metricReportDefinitions.begin(), - metricReportDefinitions.end(), -- metricReportDef) == metricReportDefinitions.end()) -+ mrdUri) == metricReportDefinitions.end()) - { - return; - } - } - -- nlohmann::json metricValuesArray = nlohmann::json::array(); -- for (const auto& it : readings) -+ nlohmann::json msg; -+ if (!telemetry::fillReport(msg, id, var)) - { -- metricValuesArray.push_back({}); -- nlohmann::json& entry = metricValuesArray.back(); -- -- auto& [id, property, value, timestamp] = it; -- -- entry = {{"MetricId", id}, -- {"MetricProperty", property}, -- {"MetricValue", std::to_string(value)}, -- {"Timestamp", crow::utility::getDateTime(timestamp)}}; -+ BMCWEB_LOG_ERROR << "Failed to fill the MetricReport for DBus " -+ "Report with id " -+ << id; -+ return; - } - -- nlohmann::json msg = { -- {"@odata.id", "/redfish/v1/TelemetryService/MetricReports/" + id}, -- {"@odata.type", "#MetricReport.v1_3_0.MetricReport"}, -- {"Id", id2}, -- {"Name", id2}, -- {"Timestamp", readingsTs}, -- {"MetricReportDefinition", {{"@odata.id", metricReportDef}}}, -- {"MetricValues", metricValuesArray}}; -- - this->sendEvent( - msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); - } -@@ -1421,75 +1407,6 @@ class EventServiceManager - } - - #endif -- -- void getMetricReading(const std::string& service, -- const std::string& objPath, const std::string& intf) -- { -- std::size_t found = objPath.find_last_of('/'); -- if (found == std::string::npos) -- { -- BMCWEB_LOG_DEBUG << "Invalid objPath received"; -- return; -- } -- -- std::string idStr = objPath.substr(found + 1); -- if (idStr.empty()) -- { -- BMCWEB_LOG_DEBUG << "Invalid ID in objPath"; -- return; -- } -- -- crow::connections::systemBus->async_method_call( -- [idStr{std::move(idStr)}]( -- const boost::system::error_code ec, -- boost::container::flat_map< -- std::string, std::variant>& -- resp) { -- if (ec) -- { -- BMCWEB_LOG_DEBUG -- << "D-Bus call failed to GetAll metric readings."; -- return; -- } -- -- const int32_t* timestampPtr = -- std::get_if(&resp["Timestamp"]); -- if (!timestampPtr) -- { -- BMCWEB_LOG_DEBUG << "Failed to Get timestamp."; -- return; -- } -- -- ReadingsObjType* readingsPtr = -- std::get_if(&resp["Readings"]); -- if (!readingsPtr) -- { -- BMCWEB_LOG_DEBUG << "Failed to Get Readings property."; -- return; -- } -- -- if (!readingsPtr->size()) -- { -- BMCWEB_LOG_DEBUG << "No metrics report to be transferred"; -- return; -- } -- -- for (const auto& it : -- EventServiceManager::getInstance().subscriptionsMap) -- { -- std::shared_ptr entry = it.second; -- if (entry->eventFormatType == metricReportFormatType) -- { -- entry->filterAndSendReports( -- idStr, crow::utility::getDateTime(*timestampPtr), -- *readingsPtr); -- } -- } -- }, -- service, objPath, "org.freedesktop.DBus.Properties", "GetAll", -- intf); -- } -- - void unregisterMetricReportSignal() - { - if (matchTelemetryMonitor) -@@ -1509,9 +1426,11 @@ class EventServiceManager - } - - BMCWEB_LOG_DEBUG << "Metrics report signal - Register"; -- std::string matchStr( -- "type='signal',member='ReportUpdate', " -- "interface='xyz.openbmc_project.MonitoringService.Report'"); -+ std::string matchStr = "type='signal',member='PropertiesChanged'," -+ "interface='org.freedesktop.DBus.Properties'," -+ "path_namespace=/xyz/openbmc_project/Telemetry/" -+ "Reports/TelemetryService," -+ "arg0=xyz.openbmc_project.Telemetry.Report"; - - matchTelemetryMonitor = std::make_shared( - *crow::connections::systemBus, matchStr, -@@ -1522,10 +1441,43 @@ class EventServiceManager - return; - } - -- std::string service = msg.get_sender(); -- std::string objPath = msg.get_path(); -- std::string intf = msg.get_interface(); -- getMetricReading(service, objPath, intf); -+ sdbusplus::message::object_path path(msg.get_path()); -+ std::string id = path.filename(); -+ if (id.empty()) -+ { -+ BMCWEB_LOG_ERROR << "Failed to get Id from path"; -+ return; -+ } -+ -+ std::string intf; -+ std::vector>> -+ props; -+ std::vector invalidProps; -+ msg.read(intf, props, invalidProps); -+ -+ auto found = -+ std::find_if(props.begin(), props.end(), [](const auto& x) { -+ return x.first == "Readings"; -+ }); -+ if (found == props.end()) -+ { -+ BMCWEB_LOG_ERROR -+ << "Failed to get Readings from Report properties"; -+ return; -+ } -+ -+ std::variant& readings = -+ found->second; -+ for (const auto& it : -+ EventServiceManager::getInstance().subscriptionsMap) -+ { -+ Subscription& entry = *it.second.get(); -+ if (entry.eventFormatType == metricReportFormatType) -+ { -+ entry.filterAndSendReports(id, readings); -+ } -+ } - }); - } - -diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp -index ad15a05..18a6dcc 100644 ---- a/redfish-core/lib/metric_report.hpp -+++ b/redfish-core/lib/metric_report.hpp -@@ -31,16 +31,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) - return metricValues; - } - --inline void fillReport(const std::shared_ptr& asyncResp, -- const std::string& id, -+inline bool fillReport(nlohmann::json& json, const std::string& id, - const std::variant& var) - { -- asyncResp->res.jsonValue["@odata.type"] = -- "#MetricReport.v1_3_0.MetricReport"; -- asyncResp->res.jsonValue["@odata.id"] = telemetry::metricReportUri + id; -- asyncResp->res.jsonValue["Id"] = id; -- asyncResp->res.jsonValue["Name"] = id; -- asyncResp->res.jsonValue["MetricReportDefinition"]["@odata.id"] = -+ json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport"; -+ json["@odata.id"] = telemetry::metricReportUri + id; -+ json["Id"] = id; -+ json["Name"] = id; -+ json["MetricReportDefinition"]["@odata.id"] = - telemetry::metricReportDefinitionUri + id; - - const TimestampReadings* timestampReadings = -@@ -48,14 +46,14 @@ inline void fillReport(const std::shared_ptr& asyncResp, - if (!timestampReadings) - { - BMCWEB_LOG_ERROR << "Property type mismatch or property is missing"; -- messages::internalError(asyncResp->res); -- return; -+ return false; - } - - const auto& [timestamp, readings] = *timestampReadings; -- asyncResp->res.jsonValue["Timestamp"] = -+ json["Timestamp"] = - crow::utility::getDateTime(static_cast(timestamp)); -- asyncResp->res.jsonValue["MetricValues"] = toMetricValues(readings); -+ json["MetricValues"] = toMetricValues(readings); -+ return true; - } - } // namespace telemetry - -@@ -145,7 +143,11 @@ class MetricReport : public Node - return; - } - -- telemetry::fillReport(asyncResp, id, ret); -+ if (!telemetry::fillReport(asyncResp->res.jsonValue, id, -+ ret)) -+ { -+ messages::internalError(asyncResp->res); -+ } - }, - telemetry::service, reportPath, - "org.freedesktop.DBus.Properties", "Get", --- -2.17.1 - 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/0004-event-service-fix-added-Context-field-to-response.patch new file mode 100644 index 000000000..ffab743f6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/telemetry/0004-event-service-fix-added-Context-field-to-response.patch @@ -0,0 +1,29 @@ +From 0ca8c383db8c9afbce63380955a20ada0acc20b7 Mon Sep 17 00:00:00 2001 +From: Krzysztof Grobelny +Date: Wed, 2 Jun 2021 12:44:43 +0000 +Subject: [PATCH] event service fix, added Context field to response + +Tested: + - Context field is present + - No regression detected + +Signed-off-by: Krzysztof Grobelny +--- + redfish-core/include/event_service_manager.hpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp +index 2b957ea..289886b 100644 +--- a/redfish-core/include/event_service_manager.hpp ++++ b/redfish-core/include/event_service_manager.hpp +@@ -556,6 +556,7 @@ class Subscription + << id; + return; + } ++ msg["Context"] = customText; + + this->sendEvent( + msg.dump(2, ' ', true, nlohmann::json::error_handler_t::replace)); +-- +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 20c93c08e..ea6ac73bd 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,8 +3,13 @@ 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/72 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/33363/80 - Sync Telmetry service with EventService - https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/38798/30 + https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/38798/31 +- 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 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend index 7e9d42228..2a7221b7b 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -1,5 +1,5 @@ SRC_URI = "git://github.com/openbmc/bmcweb.git" -SRCREV = "2ebb9683287cf6b1a2f2cc3c077bd99aceefa8dd" +SRCREV = "eb75770c6c4369984cb150ded4f5ace410ed24a9" DEPENDS += "boost-url" RDEPENDS_${PN} += "phosphor-nslcd-authority-cert-config" @@ -22,6 +22,8 @@ SRC_URI += "file://0001-Firmware-update-configuration-changes.patch \ file://0015-Add-state-sensor-messages-to-the-registry.patch \ file://0016-Fix-bmcweb-crashes-if-socket-directory-not-present.patch \ file://0017-Add-msg-registry-for-subscription-related-actions.patch \ + file://0018-bmcweb-Add-BMC-Time-update-log-to-the-registry.patch \ + file://0019-Add-generic-message-PropertySizeExceeded.patch \ " # OOB Bios Config: @@ -50,11 +52,14 @@ SRC_URI += "file://eventservice/0001-EventService-Fix-retry-handling-for-http-cl file://eventservice/0005-Add-SSE-style-subscription-support-to-eventservice.patch \ file://eventservice/0006-Add-EventService-SSE-filter-support.patch \ file://eventservice/0007-EventService-Log-events-for-subscription-actions.patch \ + file://eventservice/0008-Add-checks-on-Event-Subscription-input-parameters.patch \ " # Temporary downstream mirror of upstream patches, see telemetry\README for details -SRC_URI += " file://telemetry/0003-Add-support-for-MetricDefinition-scheme.patch \ - file://telemetry/0004-Sync-Telmetry-service-with-EventService.patch \ +SRC_URI += " file://telemetry/0001-Add-support-for-MetricDefinition-scheme.patch \ + file://telemetry/0002-Sync-Telmetry-service-with-EventService.patch \ + file://telemetry/0003-Revert-Remove-LogService-from-TelemetryService.patch \ + file://telemetry/0004-event-service-fix-added-Context-field-to-response.patch \ " # Temporary fix: Move it to service file -- cgit v1.2.3