xref: /openbmc/bmcweb/features/redfish/include/utils/telemetry_utils.hpp (revision 9e6c388a003d707136e26523dae84ba434695028)
1081ebf06SWludzik, Jozef #pragma once
2081ebf06SWludzik, Jozef 
34dbb8aeaSWludzik, Jozef #include "dbus_utility.hpp"
4479e899dSKrzysztof Grobelny #include "generated/enums/metric_report_definition.hpp"
53ccb3adbSEd Tanous #include "http/utility.hpp"
63ccb3adbSEd Tanous #include "logging.hpp"
7456cd875SSzymon Dompke #include "utility.hpp"
84dbb8aeaSWludzik, Jozef 
93ccb3adbSEd Tanous #include <boost/container/flat_map.hpp>
103ccb3adbSEd Tanous #include <boost/container/flat_set.hpp>
113ccb3adbSEd Tanous #include <sdbusplus/message/native_types.hpp>
123ccb3adbSEd Tanous 
133ccb3adbSEd Tanous #include <string>
143ccb3adbSEd Tanous 
15081ebf06SWludzik, Jozef namespace redfish
16081ebf06SWludzik, Jozef {
17081ebf06SWludzik, Jozef 
18081ebf06SWludzik, Jozef namespace telemetry
19081ebf06SWludzik, Jozef {
20081ebf06SWludzik, Jozef constexpr const char* service = "xyz.openbmc_project.Telemetry";
21081ebf06SWludzik, Jozef constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report";
22081ebf06SWludzik, Jozef 
23*9e6c388aSLukasz Kazmierczak inline std::string getDbusReportPath(std::string_view id)
24081ebf06SWludzik, Jozef {
25163994a8SSzymon Dompke     sdbusplus::message::object_path reportsPath(
26163994a8SSzymon Dompke         "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
27163994a8SSzymon Dompke     return {reportsPath / id};
28163994a8SSzymon Dompke }
29163994a8SSzymon Dompke 
30*9e6c388aSLukasz Kazmierczak inline std::string getDbusTriggerPath(std::string_view id)
31163994a8SSzymon Dompke {
32163994a8SSzymon Dompke     sdbusplus::message::object_path triggersPath(
33163994a8SSzymon Dompke         "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
34163994a8SSzymon Dompke     return {triggersPath / id};
35081ebf06SWludzik, Jozef }
36081ebf06SWludzik, Jozef 
37dd1c4a9cSSzymon Dompke inline std::optional<std::string>
38dd1c4a9cSSzymon Dompke     getTriggerIdFromDbusPath(const std::string& dbusPath)
39dd1c4a9cSSzymon Dompke {
40dd1c4a9cSSzymon Dompke     sdbusplus::message::object_path converted(dbusPath);
41dd1c4a9cSSzymon Dompke 
42dd1c4a9cSSzymon Dompke     if (converted.parent_path() !=
43dd1c4a9cSSzymon Dompke         "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService")
44dd1c4a9cSSzymon Dompke     {
45dd1c4a9cSSzymon Dompke         return std::nullopt;
46dd1c4a9cSSzymon Dompke     }
47dd1c4a9cSSzymon Dompke 
48dd1c4a9cSSzymon Dompke     const std::string& id = converted.filename();
49dd1c4a9cSSzymon Dompke     if (id.empty())
50dd1c4a9cSSzymon Dompke     {
51dd1c4a9cSSzymon Dompke         return std::nullopt;
52dd1c4a9cSSzymon Dompke     }
53dd1c4a9cSSzymon Dompke     return id;
54dd1c4a9cSSzymon Dompke }
55dd1c4a9cSSzymon Dompke 
56ca1600c1SSzymon Dompke struct IncorrectMetricUri
57ca1600c1SSzymon Dompke {
58ca1600c1SSzymon Dompke     std::string uri;
59ca1600c1SSzymon Dompke     size_t index;
60ca1600c1SSzymon Dompke };
61ca1600c1SSzymon Dompke 
62ca1600c1SSzymon Dompke inline std::optional<IncorrectMetricUri> getChassisSensorNode(
63479e899dSKrzysztof Grobelny     std::span<const std::string> uris,
64ca1600c1SSzymon Dompke     boost::container::flat_set<std::pair<std::string, std::string>>& matched)
65ca1600c1SSzymon Dompke {
66ca1600c1SSzymon Dompke     size_t uriIdx = 0;
67ca1600c1SSzymon Dompke     for (const std::string& uri : uris)
68ca1600c1SSzymon Dompke     {
69ca1600c1SSzymon Dompke         boost::urls::result<boost::urls::url_view> parsed =
70ca1600c1SSzymon Dompke             boost::urls::parse_relative_ref(uri);
71ca1600c1SSzymon Dompke 
72ca1600c1SSzymon Dompke         if (!parsed)
73ca1600c1SSzymon Dompke         {
7462598e31SEd Tanous             BMCWEB_LOG_ERROR("Failed to get chassis and sensor Node "
7562598e31SEd Tanous                              "from {}",
7662598e31SEd Tanous                              uri);
77ca1600c1SSzymon Dompke             return std::make_optional<IncorrectMetricUri>({uri, uriIdx});
78ca1600c1SSzymon Dompke         }
79ca1600c1SSzymon Dompke 
80ca1600c1SSzymon Dompke         std::string chassis;
81ca1600c1SSzymon Dompke         std::string node;
82ca1600c1SSzymon Dompke 
83ca1600c1SSzymon Dompke         if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis",
84ca1600c1SSzymon Dompke                                            std::ref(chassis), std::ref(node)))
85ca1600c1SSzymon Dompke         {
86ca1600c1SSzymon Dompke             matched.emplace(std::move(chassis), std::move(node));
87ca1600c1SSzymon Dompke             uriIdx++;
88ca1600c1SSzymon Dompke             continue;
89ca1600c1SSzymon Dompke         }
90ca1600c1SSzymon Dompke 
91ca1600c1SSzymon Dompke         // Those 2 segments cannot be validated here, as we don't know which
92ca1600c1SSzymon Dompke         // sensors exist at the moment of parsing.
93ca1600c1SSzymon Dompke         std::string ignoredSenorId;
94ca1600c1SSzymon Dompke 
95ca1600c1SSzymon Dompke         if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis",
96ca1600c1SSzymon Dompke                                            std::ref(chassis), "Sensors",
97c1d019a6SEd Tanous                                            std::ref(ignoredSenorId)))
98ca1600c1SSzymon Dompke         {
99ca1600c1SSzymon Dompke             matched.emplace(std::move(chassis), "Sensors");
100ca1600c1SSzymon Dompke             uriIdx++;
101ca1600c1SSzymon Dompke             continue;
102ca1600c1SSzymon Dompke         }
103ca1600c1SSzymon Dompke 
10462598e31SEd Tanous         BMCWEB_LOG_ERROR("Failed to get chassis and sensor Node "
10562598e31SEd Tanous                          "from {}",
10662598e31SEd Tanous                          uri);
107ca1600c1SSzymon Dompke         return std::make_optional<IncorrectMetricUri>({uri, uriIdx});
108ca1600c1SSzymon Dompke     }
109ca1600c1SSzymon Dompke     return std::nullopt;
110ca1600c1SSzymon Dompke }
111ca1600c1SSzymon Dompke 
112479e899dSKrzysztof Grobelny inline metric_report_definition::CalculationAlgorithmEnum
113479e899dSKrzysztof Grobelny     toRedfishCollectionFunction(std::string_view dbusValue)
114479e899dSKrzysztof Grobelny {
115479e899dSKrzysztof Grobelny     if (dbusValue ==
116479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum")
117479e899dSKrzysztof Grobelny     {
118479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Maximum;
119479e899dSKrzysztof Grobelny     }
120479e899dSKrzysztof Grobelny     if (dbusValue ==
121479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum")
122479e899dSKrzysztof Grobelny     {
123479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Minimum;
124479e899dSKrzysztof Grobelny     }
125479e899dSKrzysztof Grobelny     if (dbusValue ==
126479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Average")
127479e899dSKrzysztof Grobelny     {
128479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Average;
129479e899dSKrzysztof Grobelny     }
130479e899dSKrzysztof Grobelny     if (dbusValue ==
131479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Summation")
132479e899dSKrzysztof Grobelny     {
133479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Summation;
134479e899dSKrzysztof Grobelny     }
135479e899dSKrzysztof Grobelny     return metric_report_definition::CalculationAlgorithmEnum::Invalid;
136479e899dSKrzysztof Grobelny }
137479e899dSKrzysztof Grobelny 
138479e899dSKrzysztof Grobelny inline std::string toDbusCollectionFunction(std::string_view redfishValue)
139479e899dSKrzysztof Grobelny {
140479e899dSKrzysztof Grobelny     if (redfishValue == "Maximum")
141479e899dSKrzysztof Grobelny     {
142479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum";
143479e899dSKrzysztof Grobelny     }
144479e899dSKrzysztof Grobelny     if (redfishValue == "Minimum")
145479e899dSKrzysztof Grobelny     {
146479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum";
147479e899dSKrzysztof Grobelny     }
148479e899dSKrzysztof Grobelny     if (redfishValue == "Average")
149479e899dSKrzysztof Grobelny     {
150479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Average";
151479e899dSKrzysztof Grobelny     }
152479e899dSKrzysztof Grobelny     if (redfishValue == "Summation")
153479e899dSKrzysztof Grobelny     {
154479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Summation";
155479e899dSKrzysztof Grobelny     }
156479e899dSKrzysztof Grobelny     return "";
157479e899dSKrzysztof Grobelny }
158479e899dSKrzysztof Grobelny 
159479e899dSKrzysztof Grobelny inline std::optional<nlohmann::json::array_t>
160479e899dSKrzysztof Grobelny     toRedfishCollectionFunctions(std::span<const std::string> dbusEnums)
161479e899dSKrzysztof Grobelny {
162479e899dSKrzysztof Grobelny     nlohmann::json::array_t redfishEnums;
163479e899dSKrzysztof Grobelny     redfishEnums.reserve(dbusEnums.size());
164479e899dSKrzysztof Grobelny 
165479e899dSKrzysztof Grobelny     for (const auto& dbusValue : dbusEnums)
166479e899dSKrzysztof Grobelny     {
167479e899dSKrzysztof Grobelny         metric_report_definition::CalculationAlgorithmEnum redfishValue =
168479e899dSKrzysztof Grobelny             toRedfishCollectionFunction(dbusValue);
169479e899dSKrzysztof Grobelny 
170479e899dSKrzysztof Grobelny         if (redfishValue ==
171479e899dSKrzysztof Grobelny             metric_report_definition::CalculationAlgorithmEnum::Invalid)
172479e899dSKrzysztof Grobelny         {
173479e899dSKrzysztof Grobelny             return std::nullopt;
174479e899dSKrzysztof Grobelny         }
175479e899dSKrzysztof Grobelny 
176479e899dSKrzysztof Grobelny         redfishEnums.emplace_back(redfishValue);
177479e899dSKrzysztof Grobelny     }
178479e899dSKrzysztof Grobelny     return redfishEnums;
179479e899dSKrzysztof Grobelny }
180479e899dSKrzysztof Grobelny 
181081ebf06SWludzik, Jozef } // namespace telemetry
182081ebf06SWludzik, Jozef } // namespace redfish
183