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