#pragma once #include "dbus_utility.hpp" #include "generated/enums/metric_report_definition.hpp" #include "http/utility.hpp" #include "logging.hpp" #include "utility.hpp" #include <boost/container/flat_map.hpp> #include <boost/container/flat_set.hpp> #include <sdbusplus/message/native_types.hpp> #include <string> namespace redfish { namespace telemetry { constexpr const char* service = "xyz.openbmc_project.Telemetry"; constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report"; inline std::string getDbusReportPath(const std::string& id) { sdbusplus::message::object_path reportsPath( "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"); return {reportsPath / id}; } inline std::string getDbusTriggerPath(const std::string& id) { sdbusplus::message::object_path triggersPath( "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService"); return {triggersPath / id}; } struct IncorrectMetricUri { std::string uri; size_t index; }; inline std::optional<IncorrectMetricUri> getChassisSensorNode( std::span<const std::string> uris, boost::container::flat_set<std::pair<std::string, std::string>>& matched) { size_t uriIdx = 0; for (const std::string& uri : uris) { boost::urls::result<boost::urls::url_view> parsed = boost::urls::parse_relative_ref(uri); if (!parsed) { BMCWEB_LOG_ERROR << "Failed to get chassis and sensor Node " "from " << uri; return std::make_optional<IncorrectMetricUri>({uri, uriIdx}); } std::string chassis; std::string node; if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis", std::ref(chassis), std::ref(node))) { matched.emplace(std::move(chassis), std::move(node)); uriIdx++; continue; } // Those 2 segments cannot be validated here, as we don't know which // sensors exist at the moment of parsing. std::string ignoredSenorId; if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis", std::ref(chassis), "Sensors", std::ref(ignoredSenorId))) { matched.emplace(std::move(chassis), "Sensors"); uriIdx++; continue; } BMCWEB_LOG_ERROR << "Failed to get chassis and sensor Node " "from " << uri; return std::make_optional<IncorrectMetricUri>({uri, uriIdx}); } return std::nullopt; } inline metric_report_definition::CalculationAlgorithmEnum toRedfishCollectionFunction(std::string_view dbusValue) { if (dbusValue == "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum") { return metric_report_definition::CalculationAlgorithmEnum::Maximum; } if (dbusValue == "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum") { return metric_report_definition::CalculationAlgorithmEnum::Minimum; } if (dbusValue == "xyz.openbmc_project.Telemetry.Report.OperationType.Average") { return metric_report_definition::CalculationAlgorithmEnum::Average; } if (dbusValue == "xyz.openbmc_project.Telemetry.Report.OperationType.Summation") { return metric_report_definition::CalculationAlgorithmEnum::Summation; } return metric_report_definition::CalculationAlgorithmEnum::Invalid; } inline std::string toDbusCollectionFunction(std::string_view redfishValue) { if (redfishValue == "Maximum") { return "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum"; } if (redfishValue == "Minimum") { return "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum"; } if (redfishValue == "Average") { return "xyz.openbmc_project.Telemetry.Report.OperationType.Average"; } if (redfishValue == "Summation") { return "xyz.openbmc_project.Telemetry.Report.OperationType.Summation"; } return ""; } inline std::optional<nlohmann::json::array_t> toRedfishCollectionFunctions(std::span<const std::string> dbusEnums) { nlohmann::json::array_t redfishEnums; redfishEnums.reserve(dbusEnums.size()); for (const auto& dbusValue : dbusEnums) { metric_report_definition::CalculationAlgorithmEnum redfishValue = toRedfishCollectionFunction(dbusValue); if (redfishValue == metric_report_definition::CalculationAlgorithmEnum::Invalid) { return std::nullopt; } redfishEnums.emplace_back(redfishValue); } return redfishEnums; } } // namespace telemetry } // namespace redfish