From c035324925c9c09855e0717ef7af5caae3c296ff Mon Sep 17 00:00:00 2001 From: "Wludzik, Jozef" Date: Tue, 15 Dec 2020 12:30:31 +0100 Subject: 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 Signed-off-by: Lukasz Kazmierczak --- redfish-core/include/event_service_manager.hpp | 135 ++++++++----------------- 1 file changed, 44 insertions(+), 91 deletions(-) (limited to 'redfish-core/include/event_service_manager.hpp') diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp index 010c991176..a20f36ac0e 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 "registries.hpp" #include "registries/base_message_registry.hpp" #include "registries/openbmc_message_registry.hpp" @@ -503,47 +504,32 @@ class Subscription : public persistent_data::UserSubscription } #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)); } @@ -1309,73 +1295,43 @@ class EventServiceManager } #endif - - void getMetricReading(const std::string& service, - const std::string& objPath, const std::string& intf) + void getReadingsForReport(sdbusplus::message::message& msg) { - std::size_t found = objPath.find_last_of('/'); - if (found == std::string::npos) + sdbusplus::message::object_path path(msg.get_path()); + std::string id = path.filename(); + if (id.empty()) { - BMCWEB_LOG_DEBUG << "Invalid objPath received"; + BMCWEB_LOG_ERROR << "Failed to get Id from path"; return; } - std::string idStr = objPath.substr(found + 1); - if (idStr.empty()) + std::string interface; + std::vector< + std::pair>> + props; + std::vector invalidProps; + msg.read(interface, props, invalidProps); + + auto found = + std::find_if(props.begin(), props.end(), + [](const auto& x) { return x.first == "Readings"; }); + if (found == props.end()) { - BMCWEB_LOG_DEBUG << "Invalid ID in objPath"; + BMCWEB_LOG_INFO << "Failed to get Readings from Report properties"; 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); + const 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); + } + } } void unregisterMetricReportSignal() @@ -1397,9 +1353,9 @@ 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'," + "arg0=xyz.openbmc_project.Telemetry.Report"; matchTelemetryMonitor = std::make_shared( *crow::connections::systemBus, matchStr, @@ -1410,10 +1366,7 @@ 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); + getReadingsForReport(msg); }); } -- cgit v1.2.3