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