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