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