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