xref: /openbmc/bmcweb/features/redfish/include/utils/telemetry_utils.hpp (revision 479e899d5f57a67647f83b7f615d2c8565290bcf)
1081ebf06SWludzik, Jozef #pragma once
2081ebf06SWludzik, Jozef 
34dbb8aeaSWludzik, Jozef #include "dbus_utility.hpp"
4*479e899dSKrzysztof 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 
23081ebf06SWludzik, Jozef inline std::string getDbusReportPath(const std::string& 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 
30163994a8SSzymon Dompke inline std::string getDbusTriggerPath(const std::string& 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 
37ca1600c1SSzymon Dompke struct IncorrectMetricUri
38ca1600c1SSzymon Dompke {
39ca1600c1SSzymon Dompke     std::string uri;
40ca1600c1SSzymon Dompke     size_t index;
41ca1600c1SSzymon Dompke };
42ca1600c1SSzymon Dompke 
43ca1600c1SSzymon Dompke inline std::optional<IncorrectMetricUri> getChassisSensorNode(
44*479e899dSKrzysztof Grobelny     std::span<const std::string> uris,
45ca1600c1SSzymon Dompke     boost::container::flat_set<std::pair<std::string, std::string>>& matched)
46ca1600c1SSzymon Dompke {
47ca1600c1SSzymon Dompke     size_t uriIdx = 0;
48ca1600c1SSzymon Dompke     for (const std::string& uri : uris)
49ca1600c1SSzymon Dompke     {
50ca1600c1SSzymon Dompke         boost::urls::result<boost::urls::url_view> parsed =
51ca1600c1SSzymon Dompke             boost::urls::parse_relative_ref(uri);
52ca1600c1SSzymon Dompke 
53ca1600c1SSzymon Dompke         if (!parsed)
54ca1600c1SSzymon Dompke         {
55ca1600c1SSzymon Dompke             BMCWEB_LOG_ERROR << "Failed to get chassis and sensor Node "
56ca1600c1SSzymon Dompke                                 "from "
57ca1600c1SSzymon Dompke                              << uri;
58ca1600c1SSzymon Dompke             return std::make_optional<IncorrectMetricUri>({uri, uriIdx});
59ca1600c1SSzymon Dompke         }
60ca1600c1SSzymon Dompke 
61ca1600c1SSzymon Dompke         std::string chassis;
62ca1600c1SSzymon Dompke         std::string node;
63ca1600c1SSzymon Dompke 
64ca1600c1SSzymon Dompke         if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis",
65ca1600c1SSzymon Dompke                                            std::ref(chassis), std::ref(node)))
66ca1600c1SSzymon Dompke         {
67ca1600c1SSzymon Dompke             matched.emplace(std::move(chassis), std::move(node));
68ca1600c1SSzymon Dompke             uriIdx++;
69ca1600c1SSzymon Dompke             continue;
70ca1600c1SSzymon Dompke         }
71ca1600c1SSzymon Dompke 
72ca1600c1SSzymon Dompke         // Those 2 segments cannot be validated here, as we don't know which
73ca1600c1SSzymon Dompke         // sensors exist at the moment of parsing.
74ca1600c1SSzymon Dompke         std::string ignoredSenorId;
75ca1600c1SSzymon Dompke 
76ca1600c1SSzymon Dompke         if (crow::utility::readUrlSegments(*parsed, "redfish", "v1", "Chassis",
77ca1600c1SSzymon Dompke                                            std::ref(chassis), "Sensors",
78c1d019a6SEd Tanous                                            std::ref(ignoredSenorId)))
79ca1600c1SSzymon Dompke         {
80ca1600c1SSzymon Dompke             matched.emplace(std::move(chassis), "Sensors");
81ca1600c1SSzymon Dompke             uriIdx++;
82ca1600c1SSzymon Dompke             continue;
83ca1600c1SSzymon Dompke         }
84ca1600c1SSzymon Dompke 
85ca1600c1SSzymon Dompke         BMCWEB_LOG_ERROR << "Failed to get chassis and sensor Node "
86ca1600c1SSzymon Dompke                             "from "
87ca1600c1SSzymon Dompke                          << uri;
88ca1600c1SSzymon Dompke         return std::make_optional<IncorrectMetricUri>({uri, uriIdx});
89ca1600c1SSzymon Dompke     }
90ca1600c1SSzymon Dompke     return std::nullopt;
91ca1600c1SSzymon Dompke }
92ca1600c1SSzymon Dompke 
93*479e899dSKrzysztof Grobelny inline metric_report_definition::CalculationAlgorithmEnum
94*479e899dSKrzysztof Grobelny     toRedfishCollectionFunction(std::string_view dbusValue)
95*479e899dSKrzysztof Grobelny {
96*479e899dSKrzysztof Grobelny     if (dbusValue ==
97*479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum")
98*479e899dSKrzysztof Grobelny     {
99*479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Maximum;
100*479e899dSKrzysztof Grobelny     }
101*479e899dSKrzysztof Grobelny     if (dbusValue ==
102*479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum")
103*479e899dSKrzysztof Grobelny     {
104*479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Minimum;
105*479e899dSKrzysztof Grobelny     }
106*479e899dSKrzysztof Grobelny     if (dbusValue ==
107*479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Average")
108*479e899dSKrzysztof Grobelny     {
109*479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Average;
110*479e899dSKrzysztof Grobelny     }
111*479e899dSKrzysztof Grobelny     if (dbusValue ==
112*479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.OperationType.Summation")
113*479e899dSKrzysztof Grobelny     {
114*479e899dSKrzysztof Grobelny         return metric_report_definition::CalculationAlgorithmEnum::Summation;
115*479e899dSKrzysztof Grobelny     }
116*479e899dSKrzysztof Grobelny     return metric_report_definition::CalculationAlgorithmEnum::Invalid;
117*479e899dSKrzysztof Grobelny }
118*479e899dSKrzysztof Grobelny 
119*479e899dSKrzysztof Grobelny inline std::string toDbusCollectionFunction(std::string_view redfishValue)
120*479e899dSKrzysztof Grobelny {
121*479e899dSKrzysztof Grobelny     if (redfishValue == "Maximum")
122*479e899dSKrzysztof Grobelny     {
123*479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Maximum";
124*479e899dSKrzysztof Grobelny     }
125*479e899dSKrzysztof Grobelny     if (redfishValue == "Minimum")
126*479e899dSKrzysztof Grobelny     {
127*479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Minimum";
128*479e899dSKrzysztof Grobelny     }
129*479e899dSKrzysztof Grobelny     if (redfishValue == "Average")
130*479e899dSKrzysztof Grobelny     {
131*479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Average";
132*479e899dSKrzysztof Grobelny     }
133*479e899dSKrzysztof Grobelny     if (redfishValue == "Summation")
134*479e899dSKrzysztof Grobelny     {
135*479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.OperationType.Summation";
136*479e899dSKrzysztof Grobelny     }
137*479e899dSKrzysztof Grobelny     return "";
138*479e899dSKrzysztof Grobelny }
139*479e899dSKrzysztof Grobelny 
140*479e899dSKrzysztof Grobelny inline std::optional<nlohmann::json::array_t>
141*479e899dSKrzysztof Grobelny     toRedfishCollectionFunctions(std::span<const std::string> dbusEnums)
142*479e899dSKrzysztof Grobelny {
143*479e899dSKrzysztof Grobelny     nlohmann::json::array_t redfishEnums;
144*479e899dSKrzysztof Grobelny     redfishEnums.reserve(dbusEnums.size());
145*479e899dSKrzysztof Grobelny 
146*479e899dSKrzysztof Grobelny     for (const auto& dbusValue : dbusEnums)
147*479e899dSKrzysztof Grobelny     {
148*479e899dSKrzysztof Grobelny         metric_report_definition::CalculationAlgorithmEnum redfishValue =
149*479e899dSKrzysztof Grobelny             toRedfishCollectionFunction(dbusValue);
150*479e899dSKrzysztof Grobelny 
151*479e899dSKrzysztof Grobelny         if (redfishValue ==
152*479e899dSKrzysztof Grobelny             metric_report_definition::CalculationAlgorithmEnum::Invalid)
153*479e899dSKrzysztof Grobelny         {
154*479e899dSKrzysztof Grobelny             return std::nullopt;
155*479e899dSKrzysztof Grobelny         }
156*479e899dSKrzysztof Grobelny 
157*479e899dSKrzysztof Grobelny         redfishEnums.emplace_back(redfishValue);
158*479e899dSKrzysztof Grobelny     }
159*479e899dSKrzysztof Grobelny     return redfishEnums;
160*479e899dSKrzysztof Grobelny }
161*479e899dSKrzysztof Grobelny 
162081ebf06SWludzik, Jozef } // namespace telemetry
163081ebf06SWludzik, Jozef } // namespace redfish
164