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