xref: /openbmc/bmcweb/features/redfish/include/utils/telemetry_utils.hpp (revision d78572018fc2022091ff8b8eb5a7fef2172ba3d6)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3081ebf06SWludzik, Jozef #pragma once
4081ebf06SWludzik, Jozef 
5479e899dSKrzysztof Grobelny #include "generated/enums/metric_report_definition.hpp"
63ccb3adbSEd Tanous #include "http/utility.hpp"
73ccb3adbSEd Tanous #include "logging.hpp"
8456cd875SSzymon Dompke #include "utility.hpp"
94dbb8aeaSWludzik, Jozef 
103ccb3adbSEd Tanous #include <boost/container/flat_set.hpp>
11*d7857201SEd Tanous #include <boost/system/result.hpp>
12*d7857201SEd Tanous #include <boost/url/parse.hpp>
13*d7857201SEd Tanous #include <boost/url/url_view.hpp>
14*d7857201SEd Tanous #include <nlohmann/json.hpp>
153ccb3adbSEd Tanous #include <sdbusplus/message/native_types.hpp>
163ccb3adbSEd Tanous 
17*d7857201SEd Tanous #include <cstddef>
18*d7857201SEd Tanous #include <functional>
19*d7857201SEd Tanous #include <optional>
20*d7857201SEd Tanous #include <span>
213ccb3adbSEd Tanous #include <string>
22*d7857201SEd Tanous #include <string_view>
23*d7857201SEd Tanous #include <utility>
243ccb3adbSEd Tanous 
25081ebf06SWludzik, Jozef namespace redfish
26081ebf06SWludzik, Jozef {
27081ebf06SWludzik, Jozef 
28081ebf06SWludzik, Jozef namespace telemetry
29081ebf06SWludzik, Jozef {
30081ebf06SWludzik, Jozef constexpr const char* service = "xyz.openbmc_project.Telemetry";
31081ebf06SWludzik, Jozef constexpr const char* reportInterface = "xyz.openbmc_project.Telemetry.Report";
32081ebf06SWludzik, Jozef 
339e6c388aSLukasz Kazmierczak inline std::string getDbusReportPath(std::string_view id)
34081ebf06SWludzik, Jozef {
35163994a8SSzymon Dompke     sdbusplus::message::object_path reportsPath(
36163994a8SSzymon Dompke         "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
37163994a8SSzymon Dompke     return {reportsPath / id};
38163994a8SSzymon Dompke }
39163994a8SSzymon Dompke 
409e6c388aSLukasz Kazmierczak inline std::string getDbusTriggerPath(std::string_view id)
41163994a8SSzymon Dompke {
42163994a8SSzymon Dompke     sdbusplus::message::object_path triggersPath(
43163994a8SSzymon Dompke         "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
44163994a8SSzymon Dompke     return {triggersPath / id};
45081ebf06SWludzik, Jozef }
46081ebf06SWludzik, Jozef 
47dd1c4a9cSSzymon Dompke inline std::optional<std::string>
48dd1c4a9cSSzymon Dompke     getTriggerIdFromDbusPath(const std::string& dbusPath)
49dd1c4a9cSSzymon Dompke {
50dd1c4a9cSSzymon Dompke     sdbusplus::message::object_path converted(dbusPath);
51dd1c4a9cSSzymon Dompke 
52dd1c4a9cSSzymon Dompke     if (converted.parent_path() !=
53dd1c4a9cSSzymon Dompke         "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService")
54dd1c4a9cSSzymon Dompke     {
55dd1c4a9cSSzymon Dompke         return std::nullopt;
56dd1c4a9cSSzymon Dompke     }
57dd1c4a9cSSzymon Dompke 
58dd1c4a9cSSzymon Dompke     const std::string& id = converted.filename();
59dd1c4a9cSSzymon Dompke     if (id.empty())
60dd1c4a9cSSzymon Dompke     {
61dd1c4a9cSSzymon Dompke         return std::nullopt;
62dd1c4a9cSSzymon Dompke     }
63dd1c4a9cSSzymon Dompke     return id;
64dd1c4a9cSSzymon Dompke }
65dd1c4a9cSSzymon Dompke 
66ca1600c1SSzymon Dompke struct IncorrectMetricUri
67ca1600c1SSzymon Dompke {
68ca1600c1SSzymon Dompke     std::string uri;
69ca1600c1SSzymon Dompke     size_t index;
70ca1600c1SSzymon Dompke };
71ca1600c1SSzymon Dompke 
72ca1600c1SSzymon Dompke inline std::optional<IncorrectMetricUri> getChassisSensorNode(
73479e899dSKrzysztof Grobelny     std::span<const std::string> uris,
74ca1600c1SSzymon Dompke     boost::container::flat_set<std::pair<std::string, std::string>>& matched)
75ca1600c1SSzymon Dompke {
76ca1600c1SSzymon Dompke     size_t uriIdx = 0;
77ca1600c1SSzymon Dompke     for (const std::string& uri : uris)
78ca1600c1SSzymon Dompke     {
796fd29553SEd Tanous         boost::system::result<boost::urls::url_view> parsed =
80ca1600c1SSzymon Dompke             boost::urls::parse_relative_ref(uri);
81ca1600c1SSzymon Dompke 
82ca1600c1SSzymon Dompke         if (!parsed)
83ca1600c1SSzymon Dompke         {
8462598e31SEd Tanous             BMCWEB_LOG_ERROR("Failed to get chassis and sensor Node "
8562598e31SEd Tanous                              "from {}",
8662598e31SEd Tanous                              uri);
87ca1600c1SSzymon Dompke             return std::make_optional<IncorrectMetricUri>({uri, uriIdx});
88ca1600c1SSzymon Dompke         }
89ca1600c1SSzymon Dompke 
90ca1600c1SSzymon Dompke         std::string chassis;
91ca1600c1SSzymon Dompke         std::string node;
92ca1600c1SSzymon Dompke 
93ca1600c1SSzymon Dompke         if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis",
94ca1600c1SSzymon Dompke                                            std::ref(chassis), std::ref(node)))
95ca1600c1SSzymon Dompke         {
96ca1600c1SSzymon Dompke             matched.emplace(std::move(chassis), std::move(node));
97ca1600c1SSzymon Dompke             uriIdx++;
98ca1600c1SSzymon Dompke             continue;
99ca1600c1SSzymon Dompke         }
100ca1600c1SSzymon Dompke 
101ca1600c1SSzymon Dompke         // Those 2 segments cannot be validated here, as we don't know which
102ca1600c1SSzymon Dompke         // sensors exist at the moment of parsing.
103ca1600c1SSzymon Dompke         std::string ignoredSenorId;
104ca1600c1SSzymon Dompke 
105ca1600c1SSzymon Dompke         if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis",
106ca1600c1SSzymon Dompke                                            std::ref(chassis), "Sensors",
107c1d019a6SEd Tanous                                            std::ref(ignoredSenorId)))
108ca1600c1SSzymon Dompke         {
109ca1600c1SSzymon Dompke             matched.emplace(std::move(chassis), "Sensors");
110ca1600c1SSzymon Dompke             uriIdx++;
111ca1600c1SSzymon Dompke             continue;
112ca1600c1SSzymon Dompke         }
113ca1600c1SSzymon Dompke 
11462598e31SEd Tanous         BMCWEB_LOG_ERROR("Failed to get chassis and sensor Node "
11562598e31SEd Tanous                          "from {}",
11662598e31SEd Tanous                          uri);
117ca1600c1SSzymon Dompke         return std::make_optional<IncorrectMetricUri>({uri, uriIdx});
118ca1600c1SSzymon Dompke     }
119ca1600c1SSzymon Dompke     return std::nullopt;
120ca1600c1SSzymon Dompke }
121ca1600c1SSzymon Dompke 
122479e899dSKrzysztof Grobelny inline metric_report_definition::CalculationAlgorithmEnum
123479e899dSKrzysztof Grobelny     toRedfishCollectionFunction(std::string_view dbusValue)
124479e899dSKrzysztof Grobelny {
125479e899dSKrzysztof Grobelny     if (dbusValue ==
126479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum")
127479e899dSKrzysztof Grobelny     {
128479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Maximum;
129479e899dSKrzysztof Grobelny     }
130479e899dSKrzysztof Grobelny     if (dbusValue ==
131479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum")
132479e899dSKrzysztof Grobelny     {
133479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Minimum;
134479e899dSKrzysztof Grobelny     }
135479e899dSKrzysztof Grobelny     if (dbusValue ==
136479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Average")
137479e899dSKrzysztof Grobelny     {
138479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Average;
139479e899dSKrzysztof Grobelny     }
140479e899dSKrzysztof Grobelny     if (dbusValue ==
141479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Summation")
142479e899dSKrzysztof Grobelny     {
143479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Summation;
144479e899dSKrzysztof Grobelny     }
145479e899dSKrzysztof Grobelny     return metric_report_definition::CalculationAlgorithmEnum::Invalid;
146479e899dSKrzysztof Grobelny }
147479e899dSKrzysztof Grobelny 
148479e899dSKrzysztof Grobelny inline std::string toDbusCollectionFunction(std::string_view redfishValue)
149479e899dSKrzysztof Grobelny {
150479e899dSKrzysztof Grobelny     if (redfishValue == "Maximum")
151479e899dSKrzysztof Grobelny     {
152479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum";
153479e899dSKrzysztof Grobelny     }
154479e899dSKrzysztof Grobelny     if (redfishValue == "Minimum")
155479e899dSKrzysztof Grobelny     {
156479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum";
157479e899dSKrzysztof Grobelny     }
158479e899dSKrzysztof Grobelny     if (redfishValue == "Average")
159479e899dSKrzysztof Grobelny     {
160479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Average";
161479e899dSKrzysztof Grobelny     }
162479e899dSKrzysztof Grobelny     if (redfishValue == "Summation")
163479e899dSKrzysztof Grobelny     {
164479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Summation";
165479e899dSKrzysztof Grobelny     }
166479e899dSKrzysztof Grobelny     return "";
167479e899dSKrzysztof Grobelny }
168479e899dSKrzysztof Grobelny 
169479e899dSKrzysztof Grobelny inline std::optional<nlohmann::json::array_t>
170479e899dSKrzysztof Grobelny     toRedfishCollectionFunctions(std::span<const std::string> dbusEnums)
171479e899dSKrzysztof Grobelny {
172479e899dSKrzysztof Grobelny     nlohmann::json::array_t redfishEnums;
173479e899dSKrzysztof Grobelny     redfishEnums.reserve(dbusEnums.size());
174479e899dSKrzysztof Grobelny 
175479e899dSKrzysztof Grobelny     for (const auto& dbusValue : dbusEnums)
176479e899dSKrzysztof Grobelny     {
177479e899dSKrzysztof Grobelny         metric_report_definition::CalculationAlgorithmEnum redfishValue =
178479e899dSKrzysztof Grobelny             toRedfishCollectionFunction(dbusValue);
179479e899dSKrzysztof Grobelny 
180479e899dSKrzysztof Grobelny         if (redfishValue ==
181479e899dSKrzysztof Grobelny             metric_report_definition::CalculationAlgorithmEnum::Invalid)
182479e899dSKrzysztof Grobelny         {
183479e899dSKrzysztof Grobelny             return std::nullopt;
184479e899dSKrzysztof Grobelny         }
185479e899dSKrzysztof Grobelny 
186479e899dSKrzysztof Grobelny         redfishEnums.emplace_back(redfishValue);
187479e899dSKrzysztof Grobelny     }
188479e899dSKrzysztof Grobelny     return redfishEnums;
189479e899dSKrzysztof Grobelny }
190479e899dSKrzysztof Grobelny 
191081ebf06SWludzik, Jozef } // namespace telemetry
192081ebf06SWludzik, Jozef } // namespace redfish
193