1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3 #pragma once 4 5 #include "dbus_utility.hpp" 6 #include "generated/enums/metric_report_definition.hpp" 7 #include "http/utility.hpp" 8 #include "logging.hpp" 9 #include "utility.hpp" 10 11 #include <boost/container/flat_map.hpp> 12 #include <boost/container/flat_set.hpp> 13 #include <sdbusplus/message/native_types.hpp> 14 15 #include <string> 16 17 namespace redfish 18 { 19 20 namespace telemetry 21 { 22 constexpr const char* service = "xyz.openbmc_project.Telemetry"; 23 constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report"; 24 25 inline std::string getDbusReportPath(std::string_view id) 26 { 27 sdbusplus::message::object_path reportsPath( 28 "/xyz/openbmc_project/Telemetry/Reports/TelemetryService"); 29 return {reportsPath / id}; 30 } 31 32 inline std::string getDbusTriggerPath(std::string_view id) 33 { 34 sdbusplus::message::object_path triggersPath( 35 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService"); 36 return {triggersPath / id}; 37 } 38 39 inline std::optional<std::string> 40 getTriggerIdFromDbusPath(const std::string& dbusPath) 41 { 42 sdbusplus::message::object_path converted(dbusPath); 43 44 if (converted.parent_path() != 45 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService") 46 { 47 return std::nullopt; 48 } 49 50 const std::string& id = converted.filename(); 51 if (id.empty()) 52 { 53 return std::nullopt; 54 } 55 return id; 56 } 57 58 struct IncorrectMetricUri 59 { 60 std::string uri; 61 size_t index; 62 }; 63 64 inline std::optional<IncorrectMetricUri> getChassisSensorNode( 65 std::span<const std::string> uris, 66 boost::container::flat_set<std::pair<std::string, std::string>>& matched) 67 { 68 size_t uriIdx = 0; 69 for (const std::string& uri : uris) 70 { 71 boost::system::result<boost::urls::url_view> parsed = 72 boost::urls::parse_relative_ref(uri); 73 74 if (!parsed) 75 { 76 BMCWEB_LOG_ERROR("Failed to get chassis and sensor Node " 77 "from {}", 78 uri); 79 return std::make_optional<IncorrectMetricUri>({uri, uriIdx}); 80 } 81 82 std::string chassis; 83 std::string node; 84 85 if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis", 86 std::ref(chassis), std::ref(node))) 87 { 88 matched.emplace(std::move(chassis), std::move(node)); 89 uriIdx++; 90 continue; 91 } 92 93 // Those 2 segments cannot be validated here, as we don't know which 94 // sensors exist at the moment of parsing. 95 std::string ignoredSenorId; 96 97 if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis", 98 std::ref(chassis), "Sensors", 99 std::ref(ignoredSenorId))) 100 { 101 matched.emplace(std::move(chassis), "Sensors"); 102 uriIdx++; 103 continue; 104 } 105 106 BMCWEB_LOG_ERROR("Failed to get chassis and sensor Node " 107 "from {}", 108 uri); 109 return std::make_optional<IncorrectMetricUri>({uri, uriIdx}); 110 } 111 return std::nullopt; 112 } 113 114 inline metric_report_definition::CalculationAlgorithmEnum 115 toRedfishCollectionFunction(std::string_view dbusValue) 116 { 117 if (dbusValue == 118 "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum") 119 { 120 return metric_report_definition::CalculationAlgorithmEnum::Maximum; 121 } 122 if (dbusValue == 123 "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum") 124 { 125 return metric_report_definition::CalculationAlgorithmEnum::Minimum; 126 } 127 if (dbusValue == 128 "xyz.openbmc_project.Telemetry.Report.OperationType.Average") 129 { 130 return metric_report_definition::CalculationAlgorithmEnum::Average; 131 } 132 if (dbusValue == 133 "xyz.openbmc_project.Telemetry.Report.OperationType.Summation") 134 { 135 return metric_report_definition::CalculationAlgorithmEnum::Summation; 136 } 137 return metric_report_definition::CalculationAlgorithmEnum::Invalid; 138 } 139 140 inline std::string toDbusCollectionFunction(std::string_view redfishValue) 141 { 142 if (redfishValue == "Maximum") 143 { 144 return "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum"; 145 } 146 if (redfishValue == "Minimum") 147 { 148 return "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum"; 149 } 150 if (redfishValue == "Average") 151 { 152 return "xyz.openbmc_project.Telemetry.Report.OperationType.Average"; 153 } 154 if (redfishValue == "Summation") 155 { 156 return "xyz.openbmc_project.Telemetry.Report.OperationType.Summation"; 157 } 158 return ""; 159 } 160 161 inline std::optional<nlohmann::json::array_t> 162 toRedfishCollectionFunctions(std::span<const std::string> dbusEnums) 163 { 164 nlohmann::json::array_t redfishEnums; 165 redfishEnums.reserve(dbusEnums.size()); 166 167 for (const auto& dbusValue : dbusEnums) 168 { 169 metric_report_definition::CalculationAlgorithmEnum redfishValue = 170 toRedfishCollectionFunction(dbusValue); 171 172 if (redfishValue == 173 metric_report_definition::CalculationAlgorithmEnum::Invalid) 174 { 175 return std::nullopt; 176 } 177 178 redfishEnums.emplace_back(redfishValue); 179 } 180 return redfishEnums; 181 } 182 183 } // namespace telemetry 184 } // namespace redfish 185