xref: /openbmc/bmcweb/features/redfish/lib/trigger.hpp (revision 58c71488f1db00f81b8242938f75c27062e8487d)
107148cf2SLukasz Kazmierczak #pragma once
207148cf2SLukasz Kazmierczak 
33ccb3adbSEd Tanous #include "app.hpp"
4539d8c6bSEd Tanous #include "generated/enums/metric_definition.hpp"
5dd1c4a9cSSzymon Dompke #include "generated/enums/resource.hpp"
6dd1c4a9cSSzymon Dompke #include "generated/enums/triggers.hpp"
73ccb3adbSEd Tanous #include "query.hpp"
83ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
9dd1c4a9cSSzymon Dompke #include "utility.hpp"
1007148cf2SLukasz Kazmierczak #include "utils/collection.hpp"
113ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
125b90429aSEd Tanous #include "utils/json_utils.hpp"
131516c21bSJanet Adkins #include "utils/sensor_utils.hpp"
1407148cf2SLukasz Kazmierczak #include "utils/telemetry_utils.hpp"
153ccb3adbSEd Tanous #include "utils/time_utils.hpp"
1607148cf2SLukasz Kazmierczak 
17ef4c65b7SEd Tanous #include <boost/url/format.hpp>
1889474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1989474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
2007148cf2SLukasz Kazmierczak 
217a1dbc48SGeorge Liu #include <array>
227a1dbc48SGeorge Liu #include <string_view>
231b7e696bSLukasz Kazmierczak #include <tuple>
241b7e696bSLukasz Kazmierczak #include <variant>
251b7e696bSLukasz Kazmierczak #include <vector>
261b7e696bSLukasz Kazmierczak 
2707148cf2SLukasz Kazmierczak namespace redfish
2807148cf2SLukasz Kazmierczak {
2907148cf2SLukasz Kazmierczak namespace telemetry
3007148cf2SLukasz Kazmierczak {
3107148cf2SLukasz Kazmierczak constexpr const char* triggerInterface =
3207148cf2SLukasz Kazmierczak     "xyz.openbmc_project.Telemetry.Trigger";
3307148cf2SLukasz Kazmierczak 
341b7e696bSLukasz Kazmierczak using NumericThresholdParams =
351b7e696bSLukasz Kazmierczak     std::tuple<std::string, uint64_t, std::string, double>;
361b7e696bSLukasz Kazmierczak 
371b7e696bSLukasz Kazmierczak using DiscreteThresholdParams =
381b7e696bSLukasz Kazmierczak     std::tuple<std::string, std::string, uint64_t, std::string>;
391b7e696bSLukasz Kazmierczak 
401b7e696bSLukasz Kazmierczak using TriggerSensorsParams =
411b7e696bSLukasz Kazmierczak     std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
421b7e696bSLukasz Kazmierczak 
43dd1c4a9cSSzymon Dompke inline triggers::TriggerActionEnum
44dd1c4a9cSSzymon Dompke     toRedfishTriggerAction(std::string_view dbusValue)
451b7e696bSLukasz Kazmierczak {
46dd1c4a9cSSzymon Dompke     if (dbusValue ==
47dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
481b7e696bSLukasz Kazmierczak     {
49dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishMetricReport;
501b7e696bSLukasz Kazmierczak     }
51dd1c4a9cSSzymon Dompke     if (dbusValue ==
52dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
531b7e696bSLukasz Kazmierczak     {
54dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishEvent;
551b7e696bSLukasz Kazmierczak     }
56dd1c4a9cSSzymon Dompke     if (dbusValue ==
57dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
581b7e696bSLukasz Kazmierczak     {
59dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::LogToLogService;
601b7e696bSLukasz Kazmierczak     }
61dd1c4a9cSSzymon Dompke     return triggers::TriggerActionEnum::Invalid;
621b7e696bSLukasz Kazmierczak }
631b7e696bSLukasz Kazmierczak 
64dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue)
651b7e696bSLukasz Kazmierczak {
66dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishMetricReport")
671b7e696bSLukasz Kazmierczak     {
68dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
69dd1c4a9cSSzymon Dompke     }
70dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishEvent")
71dd1c4a9cSSzymon Dompke     {
72dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
73dd1c4a9cSSzymon Dompke     }
74dd1c4a9cSSzymon Dompke     if (redfishValue == "LogToLogService")
75dd1c4a9cSSzymon Dompke     {
76dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
77dd1c4a9cSSzymon Dompke     }
78dd1c4a9cSSzymon Dompke     return "";
79dd1c4a9cSSzymon Dompke }
801b7e696bSLukasz Kazmierczak 
81dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue)
82dd1c4a9cSSzymon Dompke {
83dd1c4a9cSSzymon Dompke     if (redfishValue == "OK")
84dd1c4a9cSSzymon Dompke     {
85dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
86dd1c4a9cSSzymon Dompke     }
87dd1c4a9cSSzymon Dompke     if (redfishValue == "Warning")
88dd1c4a9cSSzymon Dompke     {
89dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
90dd1c4a9cSSzymon Dompke     }
91dd1c4a9cSSzymon Dompke     if (redfishValue == "Critical")
92dd1c4a9cSSzymon Dompke     {
93dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
94dd1c4a9cSSzymon Dompke     }
95dd1c4a9cSSzymon Dompke     return "";
96dd1c4a9cSSzymon Dompke }
97dd1c4a9cSSzymon Dompke 
98dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue)
99dd1c4a9cSSzymon Dompke {
100dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
101dd1c4a9cSSzymon Dompke     {
102dd1c4a9cSSzymon Dompke         return resource::Health::OK;
103dd1c4a9cSSzymon Dompke     }
104dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
105dd1c4a9cSSzymon Dompke     {
106dd1c4a9cSSzymon Dompke         return resource::Health::Warning;
107dd1c4a9cSSzymon Dompke     }
108dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
109dd1c4a9cSSzymon Dompke     {
110dd1c4a9cSSzymon Dompke         return resource::Health::Critical;
111dd1c4a9cSSzymon Dompke     }
112dd1c4a9cSSzymon Dompke     return resource::Health::Invalid;
113dd1c4a9cSSzymon Dompke }
114dd1c4a9cSSzymon Dompke 
115dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue)
116dd1c4a9cSSzymon Dompke {
117dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
118dd1c4a9cSSzymon Dompke     {
119dd1c4a9cSSzymon Dompke         return "UpperCritical";
120dd1c4a9cSSzymon Dompke     }
121dd1c4a9cSSzymon Dompke 
122dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
123dd1c4a9cSSzymon Dompke     {
124dd1c4a9cSSzymon Dompke         return "LowerCritical";
125dd1c4a9cSSzymon Dompke     }
126dd1c4a9cSSzymon Dompke 
127dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
128dd1c4a9cSSzymon Dompke     {
129dd1c4a9cSSzymon Dompke         return "UpperWarning";
130dd1c4a9cSSzymon Dompke     }
131dd1c4a9cSSzymon Dompke 
132dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
133dd1c4a9cSSzymon Dompke     {
134dd1c4a9cSSzymon Dompke         return "LowerWarning";
135dd1c4a9cSSzymon Dompke     }
136dd1c4a9cSSzymon Dompke 
137dd1c4a9cSSzymon Dompke     return "";
138dd1c4a9cSSzymon Dompke }
139dd1c4a9cSSzymon Dompke 
140dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue)
141dd1c4a9cSSzymon Dompke {
142dd1c4a9cSSzymon Dompke     if (redfishValue == "Either")
143dd1c4a9cSSzymon Dompke     {
144dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
145dd1c4a9cSSzymon Dompke     }
146dd1c4a9cSSzymon Dompke 
147dd1c4a9cSSzymon Dompke     if (redfishValue == "Decreasing")
148dd1c4a9cSSzymon Dompke     {
149dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
150dd1c4a9cSSzymon Dompke     }
151dd1c4a9cSSzymon Dompke 
152dd1c4a9cSSzymon Dompke     if (redfishValue == "Increasing")
153dd1c4a9cSSzymon Dompke     {
154dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
155dd1c4a9cSSzymon Dompke     }
156dd1c4a9cSSzymon Dompke 
157dd1c4a9cSSzymon Dompke     return "";
158dd1c4a9cSSzymon Dompke }
159dd1c4a9cSSzymon Dompke 
160dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation
161dd1c4a9cSSzymon Dompke     toRedfishActivation(std::string_view dbusValue)
162dd1c4a9cSSzymon Dompke {
163dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
164dd1c4a9cSSzymon Dompke     {
165dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Either;
166dd1c4a9cSSzymon Dompke     }
167dd1c4a9cSSzymon Dompke 
168dd1c4a9cSSzymon Dompke     if (dbusValue ==
169dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
170dd1c4a9cSSzymon Dompke     {
171dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Decreasing;
172dd1c4a9cSSzymon Dompke     }
173dd1c4a9cSSzymon Dompke 
174dd1c4a9cSSzymon Dompke     if (dbusValue ==
175dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
176dd1c4a9cSSzymon Dompke     {
177dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Increasing;
178dd1c4a9cSSzymon Dompke     }
179dd1c4a9cSSzymon Dompke 
180dd1c4a9cSSzymon Dompke     return triggers::ThresholdActivation::Invalid;
181dd1c4a9cSSzymon Dompke }
182dd1c4a9cSSzymon Dompke 
183dd1c4a9cSSzymon Dompke enum class MetricType
184dd1c4a9cSSzymon Dompke {
185dd1c4a9cSSzymon Dompke     Discrete,
186dd1c4a9cSSzymon Dompke     Numeric
187dd1c4a9cSSzymon Dompke };
188dd1c4a9cSSzymon Dompke 
189dd1c4a9cSSzymon Dompke enum class DiscreteCondition
190dd1c4a9cSSzymon Dompke {
191dd1c4a9cSSzymon Dompke     Specified,
192dd1c4a9cSSzymon Dompke     Changed
193dd1c4a9cSSzymon Dompke };
194dd1c4a9cSSzymon Dompke 
195dd1c4a9cSSzymon Dompke struct Context
196dd1c4a9cSSzymon Dompke {
197dd1c4a9cSSzymon Dompke     std::string id;
198dd1c4a9cSSzymon Dompke     std::string name;
199dd1c4a9cSSzymon Dompke     std::vector<std::string> actions;
200dd1c4a9cSSzymon Dompke     std::vector<std::pair<sdbusplus::message::object_path, std::string>>
201dd1c4a9cSSzymon Dompke         sensors;
202dd1c4a9cSSzymon Dompke     std::vector<sdbusplus::message::object_path> reports;
203*58c71488SEd Tanous     std::vector<NumericThresholdParams> numericThresholds;
204*58c71488SEd Tanous     std::vector<DiscreteThresholdParams> discreteThresholds;
205dd1c4a9cSSzymon Dompke     std::optional<DiscreteCondition> discreteCondition;
206dd1c4a9cSSzymon Dompke     std::optional<MetricType> metricType;
207dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> metricProperties;
208dd1c4a9cSSzymon Dompke };
209dd1c4a9cSSzymon Dompke 
210dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path>
211dd1c4a9cSSzymon Dompke     getReportPathFromReportDefinitionUri(const std::string& uri)
212dd1c4a9cSSzymon Dompke {
2136fd29553SEd Tanous     boost::system::result<boost::urls::url_view> parsed =
214dd1c4a9cSSzymon Dompke         boost::urls::parse_relative_ref(uri);
215dd1c4a9cSSzymon Dompke 
216dd1c4a9cSSzymon Dompke     if (!parsed)
2171b7e696bSLukasz Kazmierczak     {
2181b7e696bSLukasz Kazmierczak         return std::nullopt;
2191b7e696bSLukasz Kazmierczak     }
2201b7e696bSLukasz Kazmierczak 
221dd1c4a9cSSzymon Dompke     std::string id;
222dd1c4a9cSSzymon Dompke     if (!crow::utility::readUrlSegments(
223dd1c4a9cSSzymon Dompke             *parsed, "redfish", "v1", "TelemetryService",
224dd1c4a9cSSzymon Dompke             "MetricReportDefinitions", std::ref(id)))
225dd1c4a9cSSzymon Dompke     {
226dd1c4a9cSSzymon Dompke         return std::nullopt;
2271b7e696bSLukasz Kazmierczak     }
2281b7e696bSLukasz Kazmierczak 
229dd1c4a9cSSzymon Dompke     return sdbusplus::message::object_path(
230dd1c4a9cSSzymon Dompke                "/xyz/openbmc_project/Telemetry/Reports") /
231dd1c4a9cSSzymon Dompke            "TelemetryService" / id;
232dd1c4a9cSSzymon Dompke }
233dd1c4a9cSSzymon Dompke 
234dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType)
235dd1c4a9cSSzymon Dompke {
236dd1c4a9cSSzymon Dompke     if (metricType == "Discrete")
237dd1c4a9cSSzymon Dompke     {
238dd1c4a9cSSzymon Dompke         return MetricType::Discrete;
239dd1c4a9cSSzymon Dompke     }
240dd1c4a9cSSzymon Dompke     if (metricType == "Numeric")
241dd1c4a9cSSzymon Dompke     {
242dd1c4a9cSSzymon Dompke         return MetricType::Numeric;
243dd1c4a9cSSzymon Dompke     }
244dd1c4a9cSSzymon Dompke     return std::nullopt;
245dd1c4a9cSSzymon Dompke }
246dd1c4a9cSSzymon Dompke 
247dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition>
248dd1c4a9cSSzymon Dompke     getDiscreteCondition(const std::string& discreteTriggerCondition)
249dd1c4a9cSSzymon Dompke {
250dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Specified")
251dd1c4a9cSSzymon Dompke     {
252dd1c4a9cSSzymon Dompke         return DiscreteCondition::Specified;
253dd1c4a9cSSzymon Dompke     }
254dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Changed")
255dd1c4a9cSSzymon Dompke     {
256dd1c4a9cSSzymon Dompke         return DiscreteCondition::Changed;
257dd1c4a9cSSzymon Dompke     }
258dd1c4a9cSSzymon Dompke     return std::nullopt;
259dd1c4a9cSSzymon Dompke }
260dd1c4a9cSSzymon Dompke 
2612932dcb6SEd Tanous inline bool parseThreshold(crow::Response& res,
2622932dcb6SEd Tanous                            nlohmann::json::object_t& threshold,
2632932dcb6SEd Tanous                            std::string_view dbusThresholdName,
2642932dcb6SEd Tanous                            std::vector<NumericThresholdParams>& parsedParams)
265dd1c4a9cSSzymon Dompke {
266dd1c4a9cSSzymon Dompke     double reading = 0.0;
267dd1c4a9cSSzymon Dompke     std::string activation;
268dd1c4a9cSSzymon Dompke     std::string dwellTimeStr;
269dd1c4a9cSSzymon Dompke 
270afc474aeSMyung Bae     if (!json_util::readJsonObject( //
271afc474aeSMyung Bae             threshold, res, //
272afc474aeSMyung Bae             "Activation", activation, //
273afc474aeSMyung Bae             "DwellTime", dwellTimeStr, //
274afc474aeSMyung Bae             "Reading", reading //
275afc474aeSMyung Bae             ))
276dd1c4a9cSSzymon Dompke     {
277dd1c4a9cSSzymon Dompke         return false;
278dd1c4a9cSSzymon Dompke     }
279dd1c4a9cSSzymon Dompke 
280dd1c4a9cSSzymon Dompke     std::string dbusActivation = toDbusActivation(activation);
281dd1c4a9cSSzymon Dompke 
282dd1c4a9cSSzymon Dompke     if (dbusActivation.empty())
283dd1c4a9cSSzymon Dompke     {
284dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "Activation", activation);
285dd1c4a9cSSzymon Dompke         return false;
286dd1c4a9cSSzymon Dompke     }
287dd1c4a9cSSzymon Dompke 
288dd1c4a9cSSzymon Dompke     std::optional<std::chrono::milliseconds> dwellTime =
289dd1c4a9cSSzymon Dompke         time_utils::fromDurationString(dwellTimeStr);
290dd1c4a9cSSzymon Dompke     if (!dwellTime)
291dd1c4a9cSSzymon Dompke     {
292dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
293dd1c4a9cSSzymon Dompke         return false;
294dd1c4a9cSSzymon Dompke     }
295dd1c4a9cSSzymon Dompke 
296dd1c4a9cSSzymon Dompke     parsedParams.emplace_back(dbusThresholdName,
297dd1c4a9cSSzymon Dompke                               static_cast<uint64_t>(dwellTime->count()),
298dd1c4a9cSSzymon Dompke                               dbusActivation, reading);
2992932dcb6SEd Tanous     return true;
3002932dcb6SEd Tanous }
3012932dcb6SEd Tanous 
3022932dcb6SEd Tanous struct NumericThresholds
3032932dcb6SEd Tanous {
3042932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperCritical;
3052932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperWarning;
3062932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerWarning;
3072932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerCritical;
3082932dcb6SEd Tanous 
3092932dcb6SEd Tanous     bool any() const
3102932dcb6SEd Tanous     {
3112932dcb6SEd Tanous         return upperCritical || upperWarning || lowerWarning || lowerCritical;
3122932dcb6SEd Tanous     }
3132932dcb6SEd Tanous };
3142932dcb6SEd Tanous 
315bd79bce8SPatrick Williams inline bool parseNumericThresholds(
316bd79bce8SPatrick Williams     crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
3172932dcb6SEd Tanous {
3182932dcb6SEd Tanous     std::vector<NumericThresholdParams> parsedParams;
3192932dcb6SEd Tanous     if (numericThresholds.upperCritical)
3202932dcb6SEd Tanous     {
3212932dcb6SEd Tanous         if (!parseThreshold(
3222932dcb6SEd Tanous                 res, *numericThresholds.upperCritical,
3232932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
3242932dcb6SEd Tanous                 parsedParams))
3252932dcb6SEd Tanous         {
3262932dcb6SEd Tanous             return false;
3272932dcb6SEd Tanous         }
3282932dcb6SEd Tanous     }
3292932dcb6SEd Tanous     if (numericThresholds.upperWarning)
3302932dcb6SEd Tanous     {
3312932dcb6SEd Tanous         if (!parseThreshold(
3322932dcb6SEd Tanous                 res, *numericThresholds.upperWarning,
3332932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
3342932dcb6SEd Tanous                 parsedParams))
3352932dcb6SEd Tanous         {
3362932dcb6SEd Tanous             return false;
3372932dcb6SEd Tanous         }
3382932dcb6SEd Tanous     }
3392932dcb6SEd Tanous     if (numericThresholds.lowerWarning)
3402932dcb6SEd Tanous     {
3412932dcb6SEd Tanous         if (!parseThreshold(
3422932dcb6SEd Tanous                 res, *numericThresholds.lowerWarning,
3432932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
3442932dcb6SEd Tanous                 parsedParams))
3452932dcb6SEd Tanous         {
3462932dcb6SEd Tanous             return false;
3472932dcb6SEd Tanous         }
3482932dcb6SEd Tanous     }
3492932dcb6SEd Tanous     if (numericThresholds.lowerCritical)
3502932dcb6SEd Tanous     {
3512932dcb6SEd Tanous         if (!parseThreshold(
3522932dcb6SEd Tanous                 res, *numericThresholds.lowerCritical,
3532932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
3542932dcb6SEd Tanous                 parsedParams))
3552932dcb6SEd Tanous         {
3562932dcb6SEd Tanous             return false;
3572932dcb6SEd Tanous         }
358dd1c4a9cSSzymon Dompke     }
359dd1c4a9cSSzymon Dompke 
360*58c71488SEd Tanous     ctx.numericThresholds = std::move(parsedParams);
361dd1c4a9cSSzymon Dompke     return true;
362dd1c4a9cSSzymon Dompke }
363dd1c4a9cSSzymon Dompke 
364dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers(
365dd1c4a9cSSzymon Dompke     crow::Response& res,
3662932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
3672932dcb6SEd Tanous     Context& ctx)
368dd1c4a9cSSzymon Dompke {
369dd1c4a9cSSzymon Dompke     std::vector<DiscreteThresholdParams> parsedParams;
370dd1c4a9cSSzymon Dompke     if (!discreteTriggers)
371dd1c4a9cSSzymon Dompke     {
372*58c71488SEd Tanous         ctx.discreteThresholds = std::move(parsedParams);
373dd1c4a9cSSzymon Dompke         return true;
374dd1c4a9cSSzymon Dompke     }
375dd1c4a9cSSzymon Dompke 
376dd1c4a9cSSzymon Dompke     parsedParams.reserve(discreteTriggers->size());
3772932dcb6SEd Tanous     for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
378dd1c4a9cSSzymon Dompke     {
379dd1c4a9cSSzymon Dompke         std::optional<std::string> name = "";
380dd1c4a9cSSzymon Dompke         std::string value;
381dd1c4a9cSSzymon Dompke         std::string dwellTimeStr;
382dd1c4a9cSSzymon Dompke         std::string severity;
383dd1c4a9cSSzymon Dompke 
384afc474aeSMyung Bae         if (!json_util::readJsonObject( //
385afc474aeSMyung Bae                 thresholdInfo, res, //
386afc474aeSMyung Bae                 "DwellTime", dwellTimeStr, //
387afc474aeSMyung Bae                 "Name", name, //
388afc474aeSMyung Bae                 "Severity", severity, //
389afc474aeSMyung Bae                 "Value", value //
390afc474aeSMyung Bae                 ))
391dd1c4a9cSSzymon Dompke         {
392dd1c4a9cSSzymon Dompke             return false;
393dd1c4a9cSSzymon Dompke         }
394dd1c4a9cSSzymon Dompke 
395dd1c4a9cSSzymon Dompke         std::optional<std::chrono::milliseconds> dwellTime =
396dd1c4a9cSSzymon Dompke             time_utils::fromDurationString(dwellTimeStr);
397dd1c4a9cSSzymon Dompke         if (!dwellTime)
398dd1c4a9cSSzymon Dompke         {
399dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
400dd1c4a9cSSzymon Dompke             return false;
401dd1c4a9cSSzymon Dompke         }
402dd1c4a9cSSzymon Dompke 
403dd1c4a9cSSzymon Dompke         std::string dbusSeverity = toDbusSeverity(severity);
404dd1c4a9cSSzymon Dompke         if (dbusSeverity.empty())
405dd1c4a9cSSzymon Dompke         {
406dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "Severity", severity);
407dd1c4a9cSSzymon Dompke             return false;
408dd1c4a9cSSzymon Dompke         }
409dd1c4a9cSSzymon Dompke 
410dd1c4a9cSSzymon Dompke         parsedParams.emplace_back(*name, dbusSeverity,
411dd1c4a9cSSzymon Dompke                                   static_cast<uint64_t>(dwellTime->count()),
412dd1c4a9cSSzymon Dompke                                   value);
413dd1c4a9cSSzymon Dompke     }
414dd1c4a9cSSzymon Dompke 
415*58c71488SEd Tanous     ctx.discreteThresholds = std::move(parsedParams);
416dd1c4a9cSSzymon Dompke     return true;
417dd1c4a9cSSzymon Dompke }
418dd1c4a9cSSzymon Dompke 
419dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds(
420dd1c4a9cSSzymon Dompke     crow::Response& res,
4212932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
4222932dcb6SEd Tanous     NumericThresholds& numericThresholds, Context& ctx)
423dd1c4a9cSSzymon Dompke {
4242932dcb6SEd Tanous     if (discreteTriggers && numericThresholds.any())
425dd1c4a9cSSzymon Dompke     {
426dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "DiscreteTriggers",
427dd1c4a9cSSzymon Dompke                                         "NumericThresholds");
428dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "NumericThresholds",
429dd1c4a9cSSzymon Dompke                                         "DiscreteTriggers");
430dd1c4a9cSSzymon Dompke         return false;
431dd1c4a9cSSzymon Dompke     }
432dd1c4a9cSSzymon Dompke 
433dd1c4a9cSSzymon Dompke     if (ctx.discreteCondition)
434dd1c4a9cSSzymon Dompke     {
4352932dcb6SEd Tanous         if (numericThresholds.any())
436dd1c4a9cSSzymon Dompke         {
437dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggerCondition",
438dd1c4a9cSSzymon Dompke                                             "NumericThresholds");
439dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
440dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
441dd1c4a9cSSzymon Dompke             return false;
442dd1c4a9cSSzymon Dompke         }
443dd1c4a9cSSzymon Dompke     }
444dd1c4a9cSSzymon Dompke 
445dd1c4a9cSSzymon Dompke     if (ctx.metricType)
446dd1c4a9cSSzymon Dompke     {
4472932dcb6SEd Tanous         if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
448dd1c4a9cSSzymon Dompke         {
449dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
450dd1c4a9cSSzymon Dompke                                             "MetricType");
451dd1c4a9cSSzymon Dompke             return false;
452dd1c4a9cSSzymon Dompke         }
453dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
454dd1c4a9cSSzymon Dompke         {
455dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
456dd1c4a9cSSzymon Dompke                                             "MetricType");
457dd1c4a9cSSzymon Dompke             return false;
458dd1c4a9cSSzymon Dompke         }
459dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
460dd1c4a9cSSzymon Dompke         {
461dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
462dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
463dd1c4a9cSSzymon Dompke             return false;
464dd1c4a9cSSzymon Dompke         }
465dd1c4a9cSSzymon Dompke     }
466dd1c4a9cSSzymon Dompke 
467dd1c4a9cSSzymon Dompke     if (discreteTriggers || ctx.discreteCondition ||
468dd1c4a9cSSzymon Dompke         (ctx.metricType && *ctx.metricType == MetricType::Discrete))
469dd1c4a9cSSzymon Dompke     {
470dd1c4a9cSSzymon Dompke         if (ctx.discreteCondition)
471dd1c4a9cSSzymon Dompke         {
472dd1c4a9cSSzymon Dompke             if (*ctx.discreteCondition == DiscreteCondition::Specified &&
473dd1c4a9cSSzymon Dompke                 !discreteTriggers)
474dd1c4a9cSSzymon Dompke             {
475dd1c4a9cSSzymon Dompke                 messages::createFailedMissingReqProperties(res,
476dd1c4a9cSSzymon Dompke                                                            "DiscreteTriggers");
477dd1c4a9cSSzymon Dompke                 return false;
478dd1c4a9cSSzymon Dompke             }
479dd1c4a9cSSzymon Dompke             if (discreteTriggers &&
480dd1c4a9cSSzymon Dompke                 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
481dd1c4a9cSSzymon Dompke                   discreteTriggers->empty()) ||
482dd1c4a9cSSzymon Dompke                  (*ctx.discreteCondition == DiscreteCondition::Changed &&
483dd1c4a9cSSzymon Dompke                   !discreteTriggers->empty())))
484dd1c4a9cSSzymon Dompke             {
485dd1c4a9cSSzymon Dompke                 messages::propertyValueConflict(res, "DiscreteTriggers",
486dd1c4a9cSSzymon Dompke                                                 "DiscreteTriggerCondition");
487dd1c4a9cSSzymon Dompke                 return false;
488dd1c4a9cSSzymon Dompke             }
489dd1c4a9cSSzymon Dompke         }
490dd1c4a9cSSzymon Dompke         if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
491dd1c4a9cSSzymon Dompke         {
492dd1c4a9cSSzymon Dompke             return false;
493dd1c4a9cSSzymon Dompke         }
494dd1c4a9cSSzymon Dompke     }
4952932dcb6SEd Tanous     else if (numericThresholds.any())
496dd1c4a9cSSzymon Dompke     {
4972932dcb6SEd Tanous         if (!parseNumericThresholds(res, numericThresholds, ctx))
498dd1c4a9cSSzymon Dompke         {
499dd1c4a9cSSzymon Dompke             return false;
500dd1c4a9cSSzymon Dompke         }
501dd1c4a9cSSzymon Dompke     }
502dd1c4a9cSSzymon Dompke     else
503dd1c4a9cSSzymon Dompke     {
504dd1c4a9cSSzymon Dompke         messages::createFailedMissingReqProperties(
505dd1c4a9cSSzymon Dompke             res, "'DiscreteTriggers', 'NumericThresholds', "
506dd1c4a9cSSzymon Dompke                  "'DiscreteTriggerCondition' or 'MetricType'");
507dd1c4a9cSSzymon Dompke         return false;
508dd1c4a9cSSzymon Dompke     }
509dd1c4a9cSSzymon Dompke     return true;
510dd1c4a9cSSzymon Dompke }
511dd1c4a9cSSzymon Dompke 
5122932dcb6SEd Tanous inline bool parseLinks(crow::Response& res,
5132932dcb6SEd Tanous                        const std::vector<std::string>& metricReportDefinitions,
5142932dcb6SEd Tanous                        Context& ctx)
515dd1c4a9cSSzymon Dompke {
5162932dcb6SEd Tanous     ctx.reports.reserve(metricReportDefinitions.size());
5172932dcb6SEd Tanous     for (const std::string& reportDefinionUri : metricReportDefinitions)
518dd1c4a9cSSzymon Dompke     {
519dd1c4a9cSSzymon Dompke         std::optional<sdbusplus::message::object_path> reportPath =
520dd1c4a9cSSzymon Dompke             getReportPathFromReportDefinitionUri(reportDefinionUri);
521dd1c4a9cSSzymon Dompke         if (!reportPath)
522dd1c4a9cSSzymon Dompke         {
523dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricReportDefinitions",
524dd1c4a9cSSzymon Dompke                                              reportDefinionUri);
525dd1c4a9cSSzymon Dompke             return false;
526dd1c4a9cSSzymon Dompke         }
527dd1c4a9cSSzymon Dompke         ctx.reports.emplace_back(*reportPath);
528dd1c4a9cSSzymon Dompke     }
529dd1c4a9cSSzymon Dompke     return true;
530dd1c4a9cSSzymon Dompke }
531dd1c4a9cSSzymon Dompke 
532dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx)
533dd1c4a9cSSzymon Dompke {
534dd1c4a9cSSzymon Dompke     if (!ctx.metricProperties)
535dd1c4a9cSSzymon Dompke     {
536dd1c4a9cSSzymon Dompke         return true;
537dd1c4a9cSSzymon Dompke     }
538dd1c4a9cSSzymon Dompke 
539dd1c4a9cSSzymon Dompke     ctx.sensors.reserve(ctx.metricProperties->size());
540dd1c4a9cSSzymon Dompke 
541dd1c4a9cSSzymon Dompke     size_t uriIdx = 0;
542dd1c4a9cSSzymon Dompke     for (const std::string& uriStr : *ctx.metricProperties)
543dd1c4a9cSSzymon Dompke     {
5444a7fbefdSEd Tanous         boost::system::result<boost::urls::url> uri =
545dd1c4a9cSSzymon Dompke             boost::urls::parse_relative_ref(uriStr);
546dd1c4a9cSSzymon Dompke         if (!uri)
547dd1c4a9cSSzymon Dompke         {
548dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
549dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
550dd1c4a9cSSzymon Dompke             return false;
551dd1c4a9cSSzymon Dompke         }
552dd1c4a9cSSzymon Dompke         std::string chassisName;
553dd1c4a9cSSzymon Dompke         std::string sensorName;
554dd1c4a9cSSzymon Dompke         if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
555dd1c4a9cSSzymon Dompke                                             std::ref(chassisName), "Sensors",
556dd1c4a9cSSzymon Dompke                                             std::ref(sensorName)))
557dd1c4a9cSSzymon Dompke         {
558dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
559dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
560dd1c4a9cSSzymon Dompke             return false;
561dd1c4a9cSSzymon Dompke         }
562dd1c4a9cSSzymon Dompke 
563dd1c4a9cSSzymon Dompke         std::pair<std::string, std::string> split =
5641516c21bSJanet Adkins             redfish::sensor_utils::splitSensorNameAndType(sensorName);
565dd1c4a9cSSzymon Dompke         if (split.first.empty() || split.second.empty())
566dd1c4a9cSSzymon Dompke         {
567dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
568dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
569dd1c4a9cSSzymon Dompke             return false;
570dd1c4a9cSSzymon Dompke         }
571dd1c4a9cSSzymon Dompke 
572bd79bce8SPatrick Williams         std::string sensorPath =
573bd79bce8SPatrick Williams             "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
574dd1c4a9cSSzymon Dompke 
575dd1c4a9cSSzymon Dompke         ctx.sensors.emplace_back(sensorPath, uriStr);
576dd1c4a9cSSzymon Dompke         uriIdx++;
577dd1c4a9cSSzymon Dompke     }
578dd1c4a9cSSzymon Dompke     return true;
579dd1c4a9cSSzymon Dompke }
580dd1c4a9cSSzymon Dompke 
581dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res,
582dd1c4a9cSSzymon Dompke                                    const crow::Request& req, Context& ctx)
583dd1c4a9cSSzymon Dompke {
584dd1c4a9cSSzymon Dompke     std::optional<std::string> id = "";
585dd1c4a9cSSzymon Dompke     std::optional<std::string> name = "";
586dd1c4a9cSSzymon Dompke     std::optional<std::string> metricType;
587dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> triggerActions;
588dd1c4a9cSSzymon Dompke     std::optional<std::string> discreteTriggerCondition;
5892932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
5902932dcb6SEd Tanous     std::optional<std::vector<std::string>> metricReportDefinitions;
5912932dcb6SEd Tanous     NumericThresholds thresholds;
592afc474aeSMyung Bae 
593afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
594afc474aeSMyung Bae             req, res, //
595afc474aeSMyung Bae             "Id", id, //
596afc474aeSMyung Bae             "DiscreteTriggerCondition", discreteTriggerCondition, //
597afc474aeSMyung Bae             "DiscreteTriggers", discreteTriggers, //
598afc474aeSMyung Bae             "Links/MetricReportDefinitions", metricReportDefinitions, //
599afc474aeSMyung Bae             "MetricProperties", ctx.metricProperties, //
600afc474aeSMyung Bae             "MetricType", metricType, //
601afc474aeSMyung Bae             "Name", name, //
602afc474aeSMyung Bae             "NumericThresholds/LowerCritical", thresholds.lowerCritical, //
603afc474aeSMyung Bae             "NumericThresholds/LowerWarning", thresholds.lowerWarning, //
604afc474aeSMyung Bae             "NumericThresholds/UpperCritical", thresholds.upperCritical, //
605afc474aeSMyung Bae             "NumericThresholds/UpperWarning", thresholds.upperWarning, //
606afc474aeSMyung Bae             "TriggerActions", triggerActions //
607afc474aeSMyung Bae             ))
608dd1c4a9cSSzymon Dompke     {
609dd1c4a9cSSzymon Dompke         return false;
610dd1c4a9cSSzymon Dompke     }
611dd1c4a9cSSzymon Dompke 
612dd1c4a9cSSzymon Dompke     ctx.id = *id;
613dd1c4a9cSSzymon Dompke     ctx.name = *name;
614dd1c4a9cSSzymon Dompke 
615dd1c4a9cSSzymon Dompke     if (metricType)
616dd1c4a9cSSzymon Dompke     {
617d5736ef2SEd Tanous         ctx.metricType = getMetricType(*metricType);
618d5736ef2SEd Tanous         if (!ctx.metricType)
619dd1c4a9cSSzymon Dompke         {
620dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricType", *metricType);
621dd1c4a9cSSzymon Dompke             return false;
622dd1c4a9cSSzymon Dompke         }
623dd1c4a9cSSzymon Dompke     }
624dd1c4a9cSSzymon Dompke 
625dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition)
626dd1c4a9cSSzymon Dompke     {
627d5736ef2SEd Tanous         ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
628d5736ef2SEd Tanous         if (!ctx.discreteCondition)
629dd1c4a9cSSzymon Dompke         {
630dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
631dd1c4a9cSSzymon Dompke                                              *discreteTriggerCondition);
632dd1c4a9cSSzymon Dompke             return false;
633dd1c4a9cSSzymon Dompke         }
634dd1c4a9cSSzymon Dompke     }
635dd1c4a9cSSzymon Dompke 
636dd1c4a9cSSzymon Dompke     if (triggerActions)
637dd1c4a9cSSzymon Dompke     {
638dd1c4a9cSSzymon Dompke         ctx.actions.reserve(triggerActions->size());
639dd1c4a9cSSzymon Dompke         for (const std::string& action : *triggerActions)
640dd1c4a9cSSzymon Dompke         {
641dd1c4a9cSSzymon Dompke             std::string dbusAction = toDbusTriggerAction(action);
642dd1c4a9cSSzymon Dompke 
643dd1c4a9cSSzymon Dompke             if (dbusAction.empty())
644dd1c4a9cSSzymon Dompke             {
645dd1c4a9cSSzymon Dompke                 messages::propertyValueNotInList(res, action, "TriggerActions");
646dd1c4a9cSSzymon Dompke                 return false;
647dd1c4a9cSSzymon Dompke             }
648dd1c4a9cSSzymon Dompke 
649dd1c4a9cSSzymon Dompke             ctx.actions.emplace_back(dbusAction);
650dd1c4a9cSSzymon Dompke         }
651dd1c4a9cSSzymon Dompke     }
652dd1c4a9cSSzymon Dompke     if (!parseMetricProperties(res, ctx))
653dd1c4a9cSSzymon Dompke     {
654dd1c4a9cSSzymon Dompke         return false;
655dd1c4a9cSSzymon Dompke     }
656dd1c4a9cSSzymon Dompke 
6572932dcb6SEd Tanous     if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
658dd1c4a9cSSzymon Dompke     {
659dd1c4a9cSSzymon Dompke         return false;
660dd1c4a9cSSzymon Dompke     }
661dd1c4a9cSSzymon Dompke 
6622932dcb6SEd Tanous     if (metricReportDefinitions)
663dd1c4a9cSSzymon Dompke     {
6642932dcb6SEd Tanous         if (!parseLinks(res, *metricReportDefinitions, ctx))
665dd1c4a9cSSzymon Dompke         {
666dd1c4a9cSSzymon Dompke             return false;
667dd1c4a9cSSzymon Dompke         }
668dd1c4a9cSSzymon Dompke     }
669dd1c4a9cSSzymon Dompke     return true;
670dd1c4a9cSSzymon Dompke }
671dd1c4a9cSSzymon Dompke 
672dd1c4a9cSSzymon Dompke inline void afterCreateTrigger(
673dd1c4a9cSSzymon Dompke     const boost::system::error_code& ec, const std::string& dbusPath,
674dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
675dd1c4a9cSSzymon Dompke {
676dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::file_exists)
677dd1c4a9cSSzymon Dompke     {
678dd1c4a9cSSzymon Dompke         messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
679dd1c4a9cSSzymon Dompke         return;
680dd1c4a9cSSzymon Dompke     }
681dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::too_many_files_open)
682dd1c4a9cSSzymon Dompke     {
683dd1c4a9cSSzymon Dompke         messages::createLimitReachedForResource(asyncResp->res);
684dd1c4a9cSSzymon Dompke         return;
685dd1c4a9cSSzymon Dompke     }
686dd1c4a9cSSzymon Dompke     if (ec)
687dd1c4a9cSSzymon Dompke     {
688dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
68962598e31SEd Tanous         BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
690dd1c4a9cSSzymon Dompke         return;
691dd1c4a9cSSzymon Dompke     }
692dd1c4a9cSSzymon Dompke 
693dd1c4a9cSSzymon Dompke     const std::optional<std::string>& triggerId =
694dd1c4a9cSSzymon Dompke         getTriggerIdFromDbusPath(dbusPath);
695dd1c4a9cSSzymon Dompke     if (!triggerId)
696dd1c4a9cSSzymon Dompke     {
697dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
69862598e31SEd Tanous         BMCWEB_LOG_ERROR("Unknown data returned by "
69962598e31SEd Tanous                          "AddTrigger DBus method");
700dd1c4a9cSSzymon Dompke         return;
701dd1c4a9cSSzymon Dompke     }
702dd1c4a9cSSzymon Dompke 
703dd1c4a9cSSzymon Dompke     messages::created(asyncResp->res);
704dd1c4a9cSSzymon Dompke     boost::urls::url locationUrl = boost::urls::format(
705dd1c4a9cSSzymon Dompke         "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
706dd1c4a9cSSzymon Dompke     asyncResp->res.addHeader("Location", locationUrl.buffer());
707dd1c4a9cSSzymon Dompke }
708dd1c4a9cSSzymon Dompke 
709dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t>
710dd1c4a9cSSzymon Dompke     getTriggerActions(const std::vector<std::string>& dbusActions)
711dd1c4a9cSSzymon Dompke {
712dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggerActions;
713dd1c4a9cSSzymon Dompke     for (const std::string& dbusAction : dbusActions)
714dd1c4a9cSSzymon Dompke     {
715dd1c4a9cSSzymon Dompke         triggers::TriggerActionEnum redfishAction =
716dd1c4a9cSSzymon Dompke             toRedfishTriggerAction(dbusAction);
717dd1c4a9cSSzymon Dompke 
718dd1c4a9cSSzymon Dompke         if (redfishAction == triggers::TriggerActionEnum::Invalid)
719dd1c4a9cSSzymon Dompke         {
720dd1c4a9cSSzymon Dompke             return std::nullopt;
721dd1c4a9cSSzymon Dompke         }
722dd1c4a9cSSzymon Dompke 
723dd1c4a9cSSzymon Dompke         triggerActions.emplace_back(redfishAction);
724dd1c4a9cSSzymon Dompke     }
725dd1c4a9cSSzymon Dompke 
726dd1c4a9cSSzymon Dompke     return triggerActions;
7271b7e696bSLukasz Kazmierczak }
7281b7e696bSLukasz Kazmierczak 
729*58c71488SEd Tanous inline std::optional<nlohmann::json::array_t> getDiscreteTriggers(
730*58c71488SEd Tanous     const std::vector<DiscreteThresholdParams>& discreteParams)
7311b7e696bSLukasz Kazmierczak {
732dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggers;
733*58c71488SEd Tanous     for (const auto& [name, severity, dwellTime, value] : discreteParams)
7341b7e696bSLukasz Kazmierczak     {
7351b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7361b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7371b7e696bSLukasz Kazmierczak 
7381b7e696bSLukasz Kazmierczak         if (!duration)
7391b7e696bSLukasz Kazmierczak         {
7401b7e696bSLukasz Kazmierczak             return std::nullopt;
7411b7e696bSLukasz Kazmierczak         }
742613dabeaSEd Tanous         nlohmann::json::object_t trigger;
743613dabeaSEd Tanous         trigger["Name"] = name;
744dd1c4a9cSSzymon Dompke         trigger["Severity"] = toRedfishSeverity(severity);
745613dabeaSEd Tanous         trigger["DwellTime"] = *duration;
746613dabeaSEd Tanous         trigger["Value"] = value;
747ad539545SPatrick Williams         triggers.emplace_back(std::move(trigger));
7481b7e696bSLukasz Kazmierczak     }
7491b7e696bSLukasz Kazmierczak 
750dd1c4a9cSSzymon Dompke     return triggers;
7511b7e696bSLukasz Kazmierczak }
7521b7e696bSLukasz Kazmierczak 
753*58c71488SEd Tanous inline std::optional<nlohmann::json::object_t> getNumericThresholds(
754*58c71488SEd Tanous     const std::vector<NumericThresholdParams>& numericParams)
7551b7e696bSLukasz Kazmierczak {
756dd1c4a9cSSzymon Dompke     nlohmann::json::object_t thresholds;
7571b7e696bSLukasz Kazmierczak 
758*58c71488SEd Tanous     for (const auto& [type, dwellTime, activation, reading] : numericParams)
7591b7e696bSLukasz Kazmierczak     {
7601b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7611b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7621b7e696bSLukasz Kazmierczak 
7631b7e696bSLukasz Kazmierczak         if (!duration)
7641b7e696bSLukasz Kazmierczak         {
7651b7e696bSLukasz Kazmierczak             return std::nullopt;
7661b7e696bSLukasz Kazmierczak         }
767dd1c4a9cSSzymon Dompke         nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
7681476687dSEd Tanous         threshold["Reading"] = reading;
769dd1c4a9cSSzymon Dompke         threshold["Activation"] = toRedfishActivation(activation);
7701476687dSEd Tanous         threshold["DwellTime"] = *duration;
7711b7e696bSLukasz Kazmierczak     }
7721b7e696bSLukasz Kazmierczak 
773dd1c4a9cSSzymon Dompke     return thresholds;
7741b7e696bSLukasz Kazmierczak }
7751b7e696bSLukasz Kazmierczak 
7763f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions(
7773f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>& reportPaths)
7781b7e696bSLukasz Kazmierczak {
7791b7e696bSLukasz Kazmierczak     nlohmann::json reports = nlohmann::json::array();
7803f215c92SSzymon Dompke 
7813f215c92SSzymon Dompke     for (const sdbusplus::message::object_path& path : reportPaths)
7821b7e696bSLukasz Kazmierczak     {
7833f215c92SSzymon Dompke         std::string reportId = path.filename();
7843f215c92SSzymon Dompke         if (reportId.empty())
7853f215c92SSzymon Dompke         {
7863f215c92SSzymon Dompke             {
78762598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
78862598e31SEd Tanous                                  path.str);
7893f215c92SSzymon Dompke                 return std::nullopt;
7903f215c92SSzymon Dompke             }
7913f215c92SSzymon Dompke         }
7923f215c92SSzymon Dompke 
7931476687dSEd Tanous         nlohmann::json::object_t report;
794ef4c65b7SEd Tanous         report["@odata.id"] = boost::urls::format(
795ef4c65b7SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
796ef4c65b7SEd Tanous             reportId);
797b2ba3072SPatrick Williams         reports.emplace_back(std::move(report));
7981b7e696bSLukasz Kazmierczak     }
7991b7e696bSLukasz Kazmierczak 
8003f215c92SSzymon Dompke     return {std::move(reports)};
8011b7e696bSLukasz Kazmierczak }
8021b7e696bSLukasz Kazmierczak 
8031b7e696bSLukasz Kazmierczak inline std::vector<std::string>
8041b7e696bSLukasz Kazmierczak     getMetricProperties(const TriggerSensorsParams& sensors)
8051b7e696bSLukasz Kazmierczak {
8061b7e696bSLukasz Kazmierczak     std::vector<std::string> metricProperties;
8071b7e696bSLukasz Kazmierczak     metricProperties.reserve(sensors.size());
8081b7e696bSLukasz Kazmierczak     for (const auto& [_, metadata] : sensors)
8091b7e696bSLukasz Kazmierczak     {
8101b7e696bSLukasz Kazmierczak         metricProperties.emplace_back(metadata);
8111b7e696bSLukasz Kazmierczak     }
8121b7e696bSLukasz Kazmierczak 
8131b7e696bSLukasz Kazmierczak     return metricProperties;
8141b7e696bSLukasz Kazmierczak }
8151b7e696bSLukasz Kazmierczak 
816e3648032SEd Tanous inline bool fillTrigger(nlohmann::json& json, const std::string& id,
817e3648032SEd Tanous                         const dbus::utility::DBusPropertiesMap& properties)
8181b7e696bSLukasz Kazmierczak {
8191b7e696bSLukasz Kazmierczak     const std::string* name = nullptr;
8201b7e696bSLukasz Kazmierczak     const bool* discrete = nullptr;
8211b7e696bSLukasz Kazmierczak     const TriggerSensorsParams* sensors = nullptr;
8223f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>* reports = nullptr;
82389474494SKrzysztof Grobelny     const std::vector<std::string>* triggerActions = nullptr;
824*58c71488SEd Tanous 
825*58c71488SEd Tanous     const std::vector<DiscreteThresholdParams>* discreteThresholds = nullptr;
826*58c71488SEd Tanous     const std::vector<NumericThresholdParams>* numericThresholds = nullptr;
8271b7e696bSLukasz Kazmierczak 
82889474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
82989474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
83089474494SKrzysztof Grobelny         discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
831*58c71488SEd Tanous         triggerActions, "DiscreteThresholds", discreteThresholds,
832*58c71488SEd Tanous         "NumericThresholds", numericThresholds);
83389474494SKrzysztof Grobelny 
83489474494SKrzysztof Grobelny     if (!success)
8351b7e696bSLukasz Kazmierczak     {
83689474494SKrzysztof Grobelny         return false;
8371b7e696bSLukasz Kazmierczak     }
8381b7e696bSLukasz Kazmierczak 
83989474494SKrzysztof Grobelny     if (triggerActions != nullptr)
84089474494SKrzysztof Grobelny     {
841dd1c4a9cSSzymon Dompke         std::optional<nlohmann::json::array_t> redfishTriggerActions =
84289474494SKrzysztof Grobelny             getTriggerActions(*triggerActions);
84389474494SKrzysztof Grobelny         if (!redfishTriggerActions)
8441b7e696bSLukasz Kazmierczak         {
84562598e31SEd Tanous             BMCWEB_LOG_ERROR(
84662598e31SEd Tanous                 "Property TriggerActions is invalid in Trigger: {}", id);
8471b7e696bSLukasz Kazmierczak             return false;
8481b7e696bSLukasz Kazmierczak         }
849dd1c4a9cSSzymon Dompke         json["TriggerActions"] = *redfishTriggerActions;
85089474494SKrzysztof Grobelny     }
8511b7e696bSLukasz Kazmierczak 
85289474494SKrzysztof Grobelny     if (reports != nullptr)
8533f215c92SSzymon Dompke     {
8543f215c92SSzymon Dompke         std::optional<nlohmann::json> linkedReports =
8553f215c92SSzymon Dompke             getMetricReportDefinitions(*reports);
8563f215c92SSzymon Dompke         if (!linkedReports)
8573f215c92SSzymon Dompke         {
85862598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
8593f215c92SSzymon Dompke             return false;
8603f215c92SSzymon Dompke         }
86189474494SKrzysztof Grobelny         json["Links"]["MetricReportDefinitions"] = *linkedReports;
86289474494SKrzysztof Grobelny     }
8631b7e696bSLukasz Kazmierczak 
864*58c71488SEd Tanous     if (discreteThresholds != nullptr)
8651b7e696bSLukasz Kazmierczak     {
8663f215c92SSzymon Dompke         std::optional<nlohmann::json::array_t> discreteTriggers =
867*58c71488SEd Tanous             getDiscreteTriggers(*discreteThresholds);
8681b7e696bSLukasz Kazmierczak 
8691b7e696bSLukasz Kazmierczak         if (!discreteTriggers)
8701b7e696bSLukasz Kazmierczak         {
87162598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
87262598e31SEd Tanous                              "triggers in Trigger: {}",
87362598e31SEd Tanous                              id);
8741b7e696bSLukasz Kazmierczak             return false;
8751b7e696bSLukasz Kazmierczak         }
8761b7e696bSLukasz Kazmierczak 
8771b7e696bSLukasz Kazmierczak         json["DiscreteTriggers"] = *discreteTriggers;
8781b7e696bSLukasz Kazmierczak         json["DiscreteTriggerCondition"] =
8791b7e696bSLukasz Kazmierczak             discreteTriggers->empty() ? "Changed" : "Specified";
880539d8c6bSEd Tanous         json["MetricType"] = metric_definition::MetricType::Discrete;
8811b7e696bSLukasz Kazmierczak     }
882*58c71488SEd Tanous     if (numericThresholds != nullptr)
8831b7e696bSLukasz Kazmierczak     {
884*58c71488SEd Tanous         std::optional<nlohmann::json::object_t> jnumericThresholds =
885*58c71488SEd Tanous             getNumericThresholds(*numericThresholds);
8861b7e696bSLukasz Kazmierczak 
887*58c71488SEd Tanous         if (!jnumericThresholds)
8881b7e696bSLukasz Kazmierczak         {
88962598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
89062598e31SEd Tanous                              "thresholds in Trigger: {}",
89162598e31SEd Tanous                              id);
8921b7e696bSLukasz Kazmierczak             return false;
8931b7e696bSLukasz Kazmierczak         }
8941b7e696bSLukasz Kazmierczak 
895*58c71488SEd Tanous         json["NumericThresholds"] = *jnumericThresholds;
896539d8c6bSEd Tanous         json["MetricType"] = metric_definition::MetricType::Numeric;
8971b7e696bSLukasz Kazmierczak     }
89889474494SKrzysztof Grobelny 
89989474494SKrzysztof Grobelny     if (name != nullptr)
90089474494SKrzysztof Grobelny     {
90189474494SKrzysztof Grobelny         json["Name"] = *name;
90289474494SKrzysztof Grobelny     }
90389474494SKrzysztof Grobelny 
90489474494SKrzysztof Grobelny     if (sensors != nullptr)
90589474494SKrzysztof Grobelny     {
90689474494SKrzysztof Grobelny         json["MetricProperties"] = getMetricProperties(*sensors);
90789474494SKrzysztof Grobelny     }
9081b7e696bSLukasz Kazmierczak 
9093f215c92SSzymon Dompke     json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
910ef4c65b7SEd Tanous     json["@odata.id"] =
911ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
9123f215c92SSzymon Dompke     json["Id"] = id;
9131b7e696bSLukasz Kazmierczak 
9141b7e696bSLukasz Kazmierczak     return true;
9151b7e696bSLukasz Kazmierczak }
9161b7e696bSLukasz Kazmierczak 
917dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost(
918dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
919dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
920dd1c4a9cSSzymon Dompke {
921dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
922dd1c4a9cSSzymon Dompke     {
923dd1c4a9cSSzymon Dompke         return;
924dd1c4a9cSSzymon Dompke     }
925dd1c4a9cSSzymon Dompke 
926dd1c4a9cSSzymon Dompke     telemetry::Context ctx;
927dd1c4a9cSSzymon Dompke     if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
928dd1c4a9cSSzymon Dompke     {
929dd1c4a9cSSzymon Dompke         return;
930dd1c4a9cSSzymon Dompke     }
931dd1c4a9cSSzymon Dompke 
932dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
933dd1c4a9cSSzymon Dompke         [asyncResp, id = ctx.id](const boost::system::error_code& ec,
934dd1c4a9cSSzymon Dompke                                  const std::string& dbusPath) {
935dd1c4a9cSSzymon Dompke             afterCreateTrigger(ec, dbusPath, asyncResp, id);
936dd1c4a9cSSzymon Dompke         },
937dd1c4a9cSSzymon Dompke         service, "/xyz/openbmc_project/Telemetry/Triggers",
938dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
939dd1c4a9cSSzymon Dompke         "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
940*58c71488SEd Tanous         ctx.reports, ctx.numericThresholds, ctx.discreteThresholds);
941dd1c4a9cSSzymon Dompke }
942dd1c4a9cSSzymon Dompke 
94307148cf2SLukasz Kazmierczak } // namespace telemetry
94407148cf2SLukasz Kazmierczak 
94507148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app)
94607148cf2SLukasz Kazmierczak {
94707148cf2SLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
94807148cf2SLukasz Kazmierczak         .privileges(redfish::privileges::getTriggersCollection)
94907148cf2SLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
95045ca1b86SEd Tanous             [&app](const crow::Request& req,
95107148cf2SLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
9523ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
95345ca1b86SEd Tanous                 {
95445ca1b86SEd Tanous                     return;
95545ca1b86SEd Tanous                 }
95607148cf2SLukasz Kazmierczak                 asyncResp->res.jsonValue["@odata.type"] =
95707148cf2SLukasz Kazmierczak                     "#TriggersCollection.TriggersCollection";
958ae9031f0SWilly Tu                 asyncResp->res.jsonValue["@odata.id"] =
959ae9031f0SWilly Tu                     "/redfish/v1/TelemetryService/Triggers";
96007148cf2SLukasz Kazmierczak                 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
9617a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
9627a1dbc48SGeorge Liu                     telemetry::triggerInterface};
96307148cf2SLukasz Kazmierczak                 collection_util::getCollectionMembers(
964ae9031f0SWilly Tu                     asyncResp,
965ae9031f0SWilly Tu                     boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
966ae9031f0SWilly Tu                     interfaces,
96707148cf2SLukasz Kazmierczak                     "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
96807148cf2SLukasz Kazmierczak             });
969dd1c4a9cSSzymon Dompke 
970dd1c4a9cSSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
971dd1c4a9cSSzymon Dompke         .privileges(redfish::privileges::postTriggersCollection)
972dd1c4a9cSSzymon Dompke         .methods(boost::beast::http::verb::post)(std::bind_front(
973dd1c4a9cSSzymon Dompke             telemetry::handleTriggerCollectionPost, std::ref(app)));
97407148cf2SLukasz Kazmierczak }
97507148cf2SLukasz Kazmierczak 
9761b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app)
9771b7e696bSLukasz Kazmierczak {
9781b7e696bSLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
9791b7e696bSLukasz Kazmierczak         .privileges(redfish::privileges::getTriggers)
9801b7e696bSLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
98145ca1b86SEd Tanous             [&app](const crow::Request& req,
9821b7e696bSLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9831b7e696bSLukasz Kazmierczak                    const std::string& id) {
9843ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
98545ca1b86SEd Tanous                 {
98645ca1b86SEd Tanous                     return;
98745ca1b86SEd Tanous                 }
98889474494SKrzysztof Grobelny                 sdbusplus::asio::getAllProperties(
98989474494SKrzysztof Grobelny                     *crow::connections::systemBus, telemetry::service,
990bd79bce8SPatrick Williams                     telemetry::getDbusTriggerPath(id),
991bd79bce8SPatrick Williams                     telemetry::triggerInterface,
9921b7e696bSLukasz Kazmierczak                     [asyncResp,
9935e7e2dc5SEd Tanous                      id](const boost::system::error_code& ec,
994e3648032SEd Tanous                          const dbus::utility::DBusPropertiesMap& ret) {
9951b7e696bSLukasz Kazmierczak                         if (ec.value() == EBADR ||
9961b7e696bSLukasz Kazmierczak                             ec == boost::system::errc::host_unreachable)
9971b7e696bSLukasz Kazmierczak                         {
998bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
999bd79bce8SPatrick Williams                                                        "Triggers", id);
10001b7e696bSLukasz Kazmierczak                             return;
10011b7e696bSLukasz Kazmierczak                         }
10021b7e696bSLukasz Kazmierczak                         if (ec)
10031b7e696bSLukasz Kazmierczak                         {
100462598e31SEd Tanous                             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
10051b7e696bSLukasz Kazmierczak                             messages::internalError(asyncResp->res);
10061b7e696bSLukasz Kazmierczak                             return;
10071b7e696bSLukasz Kazmierczak                         }
10081b7e696bSLukasz Kazmierczak 
1009bd79bce8SPatrick Williams                         if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
1010bd79bce8SPatrick Williams                                                     id, ret))
10111b7e696bSLukasz Kazmierczak                         {
10121b7e696bSLukasz Kazmierczak                             messages::internalError(asyncResp->res);
10131b7e696bSLukasz Kazmierczak                         }
101489474494SKrzysztof Grobelny                     });
10151b7e696bSLukasz Kazmierczak             });
1016163994a8SSzymon Dompke 
1017163994a8SSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1018163994a8SSzymon Dompke         .privileges(redfish::privileges::deleteTriggers)
1019163994a8SSzymon Dompke         .methods(boost::beast::http::verb::delete_)(
102045ca1b86SEd Tanous             [&app](const crow::Request& req,
1021163994a8SSzymon Dompke                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1022163994a8SSzymon Dompke                    const std::string& id) {
10233ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
102445ca1b86SEd Tanous                 {
102545ca1b86SEd Tanous                     return;
102645ca1b86SEd Tanous                 }
1027bd79bce8SPatrick Williams                 const std::string triggerPath =
1028bd79bce8SPatrick Williams                     telemetry::getDbusTriggerPath(id);
1029163994a8SSzymon Dompke 
1030163994a8SSzymon Dompke                 crow::connections::systemBus->async_method_call(
10315e7e2dc5SEd Tanous                     [asyncResp, id](const boost::system::error_code& ec) {
1032163994a8SSzymon Dompke                         if (ec.value() == EBADR)
1033163994a8SSzymon Dompke                         {
1034bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
1035bd79bce8SPatrick Williams                                                        "Triggers", id);
1036163994a8SSzymon Dompke                             return;
1037163994a8SSzymon Dompke                         }
1038163994a8SSzymon Dompke 
1039163994a8SSzymon Dompke                         if (ec)
1040163994a8SSzymon Dompke                         {
104162598e31SEd Tanous                             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1042163994a8SSzymon Dompke                             messages::internalError(asyncResp->res);
1043163994a8SSzymon Dompke                             return;
1044163994a8SSzymon Dompke                         }
1045163994a8SSzymon Dompke 
1046bd79bce8SPatrick Williams                         asyncResp->res.result(
1047bd79bce8SPatrick Williams                             boost::beast::http::status::no_content);
1048163994a8SSzymon Dompke                     },
1049163994a8SSzymon Dompke                     telemetry::service, triggerPath,
1050163994a8SSzymon Dompke                     "xyz.openbmc_project.Object.Delete", "Delete");
1051163994a8SSzymon Dompke             });
10521b7e696bSLukasz Kazmierczak }
10531b7e696bSLukasz Kazmierczak 
105407148cf2SLukasz Kazmierczak } // namespace redfish
1055