diff options
-rw-r--r-- | redfish-core/include/event_service_manager.hpp | 135 | ||||
-rw-r--r-- | redfish-core/lib/metric_report.hpp | 29 |
2 files changed, 59 insertions, 105 deletions
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<telemetry::TimestampReadings>& 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<std::string, std::variant<telemetry::TimestampReadings>>> + props; + std::vector<std::string> 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<int32_t, ReadingsObjType>>& - resp) { - if (ec) - { - BMCWEB_LOG_DEBUG - << "D-Bus call failed to GetAll metric readings."; - return; - } - - const int32_t* timestampPtr = - std::get_if<int32_t>(&resp["Timestamp"]); - if (!timestampPtr) - { - BMCWEB_LOG_DEBUG << "Failed to Get timestamp."; - return; - } - - ReadingsObjType* readingsPtr = - std::get_if<ReadingsObjType>(&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<Subscription> 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<telemetry::TimestampReadings>& 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<sdbusplus::bus::match::match>( *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); }); } diff --git a/redfish-core/lib/metric_report.hpp b/redfish-core/lib/metric_report.hpp index 159968aaf5..c959495408 100644 --- a/redfish-core/lib/metric_report.hpp +++ b/redfish-core/lib/metric_report.hpp @@ -34,17 +34,14 @@ inline nlohmann::json toMetricValues(const Readings& readings) return metricValues; } -inline void fillReport(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, - const std::string& id, +inline bool fillReport(nlohmann::json& json, const std::string& id, const std::variant<TimestampReadings>& var) { - asyncResp->res.jsonValue["@odata.type"] = - "#MetricReport.v1_3_0.MetricReport"; - asyncResp->res.jsonValue["@odata.id"] = - telemetry::metricReportUri + std::string("/") + 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 + std::string("/") + id; + json["Id"] = id; + json["Name"] = id; + json["MetricReportDefinition"]["@odata.id"] = telemetry::metricReportDefinitionUri + std::string("/") + id; const TimestampReadings* timestampReadings = @@ -52,14 +49,14 @@ inline void fillReport(const std::shared_ptr<bmcweb::AsyncResp>& 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<time_t>(timestamp)); - asyncResp->res.jsonValue["MetricValues"] = toMetricValues(readings); + json["MetricValues"] = toMetricValues(readings); + return true; } } // namespace telemetry @@ -122,7 +119,11 @@ inline void requestRoutesMetricReport(App& app) 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", |