xref: /openbmc/bmcweb/features/redfish/lib/trigger.hpp (revision afc474aef028555fc0a6deb425bdad86f0a34db6)
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 
40dd1c4a9cSSzymon Dompke using TriggerThresholdParams =
41dd1c4a9cSSzymon Dompke     std::variant<std::vector<NumericThresholdParams>,
42dd1c4a9cSSzymon Dompke                  std::vector<DiscreteThresholdParams>>;
43dd1c4a9cSSzymon Dompke 
441b7e696bSLukasz Kazmierczak using TriggerThresholdParamsExt =
451b7e696bSLukasz Kazmierczak     std::variant<std::monostate, std::vector<NumericThresholdParams>,
461b7e696bSLukasz Kazmierczak                  std::vector<DiscreteThresholdParams>>;
471b7e696bSLukasz Kazmierczak 
481b7e696bSLukasz Kazmierczak using TriggerSensorsParams =
491b7e696bSLukasz Kazmierczak     std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
501b7e696bSLukasz Kazmierczak 
511b7e696bSLukasz Kazmierczak using TriggerGetParamsVariant =
521b7e696bSLukasz Kazmierczak     std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
533f215c92SSzymon Dompke                  TriggerSensorsParams, std::vector<std::string>,
543f215c92SSzymon Dompke                  std::vector<sdbusplus::message::object_path>>;
551b7e696bSLukasz Kazmierczak 
56dd1c4a9cSSzymon Dompke inline triggers::TriggerActionEnum
57dd1c4a9cSSzymon Dompke     toRedfishTriggerAction(std::string_view dbusValue)
581b7e696bSLukasz Kazmierczak {
59dd1c4a9cSSzymon Dompke     if (dbusValue ==
60dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
611b7e696bSLukasz Kazmierczak     {
62dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishMetricReport;
631b7e696bSLukasz Kazmierczak     }
64dd1c4a9cSSzymon Dompke     if (dbusValue ==
65dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
661b7e696bSLukasz Kazmierczak     {
67dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishEvent;
681b7e696bSLukasz Kazmierczak     }
69dd1c4a9cSSzymon Dompke     if (dbusValue ==
70dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
711b7e696bSLukasz Kazmierczak     {
72dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::LogToLogService;
731b7e696bSLukasz Kazmierczak     }
74dd1c4a9cSSzymon Dompke     return triggers::TriggerActionEnum::Invalid;
751b7e696bSLukasz Kazmierczak }
761b7e696bSLukasz Kazmierczak 
77dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue)
781b7e696bSLukasz Kazmierczak {
79dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishMetricReport")
801b7e696bSLukasz Kazmierczak     {
81dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
82dd1c4a9cSSzymon Dompke     }
83dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishEvent")
84dd1c4a9cSSzymon Dompke     {
85dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
86dd1c4a9cSSzymon Dompke     }
87dd1c4a9cSSzymon Dompke     if (redfishValue == "LogToLogService")
88dd1c4a9cSSzymon Dompke     {
89dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
90dd1c4a9cSSzymon Dompke     }
91dd1c4a9cSSzymon Dompke     return "";
92dd1c4a9cSSzymon Dompke }
931b7e696bSLukasz Kazmierczak 
94dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue)
95dd1c4a9cSSzymon Dompke {
96dd1c4a9cSSzymon Dompke     if (redfishValue == "OK")
97dd1c4a9cSSzymon Dompke     {
98dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
99dd1c4a9cSSzymon Dompke     }
100dd1c4a9cSSzymon Dompke     if (redfishValue == "Warning")
101dd1c4a9cSSzymon Dompke     {
102dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
103dd1c4a9cSSzymon Dompke     }
104dd1c4a9cSSzymon Dompke     if (redfishValue == "Critical")
105dd1c4a9cSSzymon Dompke     {
106dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
107dd1c4a9cSSzymon Dompke     }
108dd1c4a9cSSzymon Dompke     return "";
109dd1c4a9cSSzymon Dompke }
110dd1c4a9cSSzymon Dompke 
111dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue)
112dd1c4a9cSSzymon Dompke {
113dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
114dd1c4a9cSSzymon Dompke     {
115dd1c4a9cSSzymon Dompke         return resource::Health::OK;
116dd1c4a9cSSzymon Dompke     }
117dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
118dd1c4a9cSSzymon Dompke     {
119dd1c4a9cSSzymon Dompke         return resource::Health::Warning;
120dd1c4a9cSSzymon Dompke     }
121dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
122dd1c4a9cSSzymon Dompke     {
123dd1c4a9cSSzymon Dompke         return resource::Health::Critical;
124dd1c4a9cSSzymon Dompke     }
125dd1c4a9cSSzymon Dompke     return resource::Health::Invalid;
126dd1c4a9cSSzymon Dompke }
127dd1c4a9cSSzymon Dompke 
128dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue)
129dd1c4a9cSSzymon Dompke {
130dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
131dd1c4a9cSSzymon Dompke     {
132dd1c4a9cSSzymon Dompke         return "UpperCritical";
133dd1c4a9cSSzymon Dompke     }
134dd1c4a9cSSzymon Dompke 
135dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
136dd1c4a9cSSzymon Dompke     {
137dd1c4a9cSSzymon Dompke         return "LowerCritical";
138dd1c4a9cSSzymon Dompke     }
139dd1c4a9cSSzymon Dompke 
140dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
141dd1c4a9cSSzymon Dompke     {
142dd1c4a9cSSzymon Dompke         return "UpperWarning";
143dd1c4a9cSSzymon Dompke     }
144dd1c4a9cSSzymon Dompke 
145dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
146dd1c4a9cSSzymon Dompke     {
147dd1c4a9cSSzymon Dompke         return "LowerWarning";
148dd1c4a9cSSzymon Dompke     }
149dd1c4a9cSSzymon Dompke 
150dd1c4a9cSSzymon Dompke     return "";
151dd1c4a9cSSzymon Dompke }
152dd1c4a9cSSzymon Dompke 
153dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue)
154dd1c4a9cSSzymon Dompke {
155dd1c4a9cSSzymon Dompke     if (redfishValue == "Either")
156dd1c4a9cSSzymon Dompke     {
157dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
158dd1c4a9cSSzymon Dompke     }
159dd1c4a9cSSzymon Dompke 
160dd1c4a9cSSzymon Dompke     if (redfishValue == "Decreasing")
161dd1c4a9cSSzymon Dompke     {
162dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
163dd1c4a9cSSzymon Dompke     }
164dd1c4a9cSSzymon Dompke 
165dd1c4a9cSSzymon Dompke     if (redfishValue == "Increasing")
166dd1c4a9cSSzymon Dompke     {
167dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
168dd1c4a9cSSzymon Dompke     }
169dd1c4a9cSSzymon Dompke 
170dd1c4a9cSSzymon Dompke     return "";
171dd1c4a9cSSzymon Dompke }
172dd1c4a9cSSzymon Dompke 
173dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation
174dd1c4a9cSSzymon Dompke     toRedfishActivation(std::string_view dbusValue)
175dd1c4a9cSSzymon Dompke {
176dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
177dd1c4a9cSSzymon Dompke     {
178dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Either;
179dd1c4a9cSSzymon Dompke     }
180dd1c4a9cSSzymon Dompke 
181dd1c4a9cSSzymon Dompke     if (dbusValue ==
182dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
183dd1c4a9cSSzymon Dompke     {
184dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Decreasing;
185dd1c4a9cSSzymon Dompke     }
186dd1c4a9cSSzymon Dompke 
187dd1c4a9cSSzymon Dompke     if (dbusValue ==
188dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
189dd1c4a9cSSzymon Dompke     {
190dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Increasing;
191dd1c4a9cSSzymon Dompke     }
192dd1c4a9cSSzymon Dompke 
193dd1c4a9cSSzymon Dompke     return triggers::ThresholdActivation::Invalid;
194dd1c4a9cSSzymon Dompke }
195dd1c4a9cSSzymon Dompke 
196dd1c4a9cSSzymon Dompke enum class MetricType
197dd1c4a9cSSzymon Dompke {
198dd1c4a9cSSzymon Dompke     Discrete,
199dd1c4a9cSSzymon Dompke     Numeric
200dd1c4a9cSSzymon Dompke };
201dd1c4a9cSSzymon Dompke 
202dd1c4a9cSSzymon Dompke enum class DiscreteCondition
203dd1c4a9cSSzymon Dompke {
204dd1c4a9cSSzymon Dompke     Specified,
205dd1c4a9cSSzymon Dompke     Changed
206dd1c4a9cSSzymon Dompke };
207dd1c4a9cSSzymon Dompke 
208dd1c4a9cSSzymon Dompke struct Context
209dd1c4a9cSSzymon Dompke {
210dd1c4a9cSSzymon Dompke     std::string id;
211dd1c4a9cSSzymon Dompke     std::string name;
212dd1c4a9cSSzymon Dompke     std::vector<std::string> actions;
213dd1c4a9cSSzymon Dompke     std::vector<std::pair<sdbusplus::message::object_path, std::string>>
214dd1c4a9cSSzymon Dompke         sensors;
215dd1c4a9cSSzymon Dompke     std::vector<sdbusplus::message::object_path> reports;
216dd1c4a9cSSzymon Dompke     TriggerThresholdParams thresholds;
217dd1c4a9cSSzymon Dompke 
218dd1c4a9cSSzymon Dompke     std::optional<DiscreteCondition> discreteCondition;
219dd1c4a9cSSzymon Dompke     std::optional<MetricType> metricType;
220dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> metricProperties;
221dd1c4a9cSSzymon Dompke };
222dd1c4a9cSSzymon Dompke 
223dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path>
224dd1c4a9cSSzymon Dompke     getReportPathFromReportDefinitionUri(const std::string& uri)
225dd1c4a9cSSzymon Dompke {
2266fd29553SEd Tanous     boost::system::result<boost::urls::url_view> parsed =
227dd1c4a9cSSzymon Dompke         boost::urls::parse_relative_ref(uri);
228dd1c4a9cSSzymon Dompke 
229dd1c4a9cSSzymon Dompke     if (!parsed)
2301b7e696bSLukasz Kazmierczak     {
2311b7e696bSLukasz Kazmierczak         return std::nullopt;
2321b7e696bSLukasz Kazmierczak     }
2331b7e696bSLukasz Kazmierczak 
234dd1c4a9cSSzymon Dompke     std::string id;
235dd1c4a9cSSzymon Dompke     if (!crow::utility::readUrlSegments(
236dd1c4a9cSSzymon Dompke             *parsed, "redfish", "v1", "TelemetryService",
237dd1c4a9cSSzymon Dompke             "MetricReportDefinitions", std::ref(id)))
238dd1c4a9cSSzymon Dompke     {
239dd1c4a9cSSzymon Dompke         return std::nullopt;
2401b7e696bSLukasz Kazmierczak     }
2411b7e696bSLukasz Kazmierczak 
242dd1c4a9cSSzymon Dompke     return sdbusplus::message::object_path(
243dd1c4a9cSSzymon Dompke                "/xyz/openbmc_project/Telemetry/Reports") /
244dd1c4a9cSSzymon Dompke            "TelemetryService" / id;
245dd1c4a9cSSzymon Dompke }
246dd1c4a9cSSzymon Dompke 
247dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType)
248dd1c4a9cSSzymon Dompke {
249dd1c4a9cSSzymon Dompke     if (metricType == "Discrete")
250dd1c4a9cSSzymon Dompke     {
251dd1c4a9cSSzymon Dompke         return MetricType::Discrete;
252dd1c4a9cSSzymon Dompke     }
253dd1c4a9cSSzymon Dompke     if (metricType == "Numeric")
254dd1c4a9cSSzymon Dompke     {
255dd1c4a9cSSzymon Dompke         return MetricType::Numeric;
256dd1c4a9cSSzymon Dompke     }
257dd1c4a9cSSzymon Dompke     return std::nullopt;
258dd1c4a9cSSzymon Dompke }
259dd1c4a9cSSzymon Dompke 
260dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition>
261dd1c4a9cSSzymon Dompke     getDiscreteCondition(const std::string& discreteTriggerCondition)
262dd1c4a9cSSzymon Dompke {
263dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Specified")
264dd1c4a9cSSzymon Dompke     {
265dd1c4a9cSSzymon Dompke         return DiscreteCondition::Specified;
266dd1c4a9cSSzymon Dompke     }
267dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Changed")
268dd1c4a9cSSzymon Dompke     {
269dd1c4a9cSSzymon Dompke         return DiscreteCondition::Changed;
270dd1c4a9cSSzymon Dompke     }
271dd1c4a9cSSzymon Dompke     return std::nullopt;
272dd1c4a9cSSzymon Dompke }
273dd1c4a9cSSzymon Dompke 
2742932dcb6SEd Tanous inline bool parseThreshold(crow::Response& res,
2752932dcb6SEd Tanous                            nlohmann::json::object_t& threshold,
2762932dcb6SEd Tanous                            std::string_view dbusThresholdName,
2772932dcb6SEd Tanous                            std::vector<NumericThresholdParams>& parsedParams)
278dd1c4a9cSSzymon Dompke {
279dd1c4a9cSSzymon Dompke     double reading = 0.0;
280dd1c4a9cSSzymon Dompke     std::string activation;
281dd1c4a9cSSzymon Dompke     std::string dwellTimeStr;
282dd1c4a9cSSzymon Dompke 
283*afc474aeSMyung Bae     if (!json_util::readJsonObject( //
284*afc474aeSMyung Bae             threshold, res, //
285*afc474aeSMyung Bae             "Activation", activation, //
286*afc474aeSMyung Bae             "DwellTime", dwellTimeStr, //
287*afc474aeSMyung Bae             "Reading", reading //
288*afc474aeSMyung Bae             ))
289dd1c4a9cSSzymon Dompke     {
290dd1c4a9cSSzymon Dompke         return false;
291dd1c4a9cSSzymon Dompke     }
292dd1c4a9cSSzymon Dompke 
293dd1c4a9cSSzymon Dompke     std::string dbusActivation = toDbusActivation(activation);
294dd1c4a9cSSzymon Dompke 
295dd1c4a9cSSzymon Dompke     if (dbusActivation.empty())
296dd1c4a9cSSzymon Dompke     {
297dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "Activation", activation);
298dd1c4a9cSSzymon Dompke         return false;
299dd1c4a9cSSzymon Dompke     }
300dd1c4a9cSSzymon Dompke 
301dd1c4a9cSSzymon Dompke     std::optional<std::chrono::milliseconds> dwellTime =
302dd1c4a9cSSzymon Dompke         time_utils::fromDurationString(dwellTimeStr);
303dd1c4a9cSSzymon Dompke     if (!dwellTime)
304dd1c4a9cSSzymon Dompke     {
305dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
306dd1c4a9cSSzymon Dompke         return false;
307dd1c4a9cSSzymon Dompke     }
308dd1c4a9cSSzymon Dompke 
309dd1c4a9cSSzymon Dompke     parsedParams.emplace_back(dbusThresholdName,
310dd1c4a9cSSzymon Dompke                               static_cast<uint64_t>(dwellTime->count()),
311dd1c4a9cSSzymon Dompke                               dbusActivation, reading);
3122932dcb6SEd Tanous     return true;
3132932dcb6SEd Tanous }
3142932dcb6SEd Tanous 
3152932dcb6SEd Tanous struct NumericThresholds
3162932dcb6SEd Tanous {
3172932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperCritical;
3182932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperWarning;
3192932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerWarning;
3202932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerCritical;
3212932dcb6SEd Tanous 
3222932dcb6SEd Tanous     bool any() const
3232932dcb6SEd Tanous     {
3242932dcb6SEd Tanous         return upperCritical || upperWarning || lowerWarning || lowerCritical;
3252932dcb6SEd Tanous     }
3262932dcb6SEd Tanous };
3272932dcb6SEd Tanous 
328bd79bce8SPatrick Williams inline bool parseNumericThresholds(
329bd79bce8SPatrick Williams     crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
3302932dcb6SEd Tanous {
3312932dcb6SEd Tanous     std::vector<NumericThresholdParams> parsedParams;
3322932dcb6SEd Tanous     if (numericThresholds.upperCritical)
3332932dcb6SEd Tanous     {
3342932dcb6SEd Tanous         if (!parseThreshold(
3352932dcb6SEd Tanous                 res, *numericThresholds.upperCritical,
3362932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
3372932dcb6SEd Tanous                 parsedParams))
3382932dcb6SEd Tanous         {
3392932dcb6SEd Tanous             return false;
3402932dcb6SEd Tanous         }
3412932dcb6SEd Tanous     }
3422932dcb6SEd Tanous     if (numericThresholds.upperWarning)
3432932dcb6SEd Tanous     {
3442932dcb6SEd Tanous         if (!parseThreshold(
3452932dcb6SEd Tanous                 res, *numericThresholds.upperWarning,
3462932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
3472932dcb6SEd Tanous                 parsedParams))
3482932dcb6SEd Tanous         {
3492932dcb6SEd Tanous             return false;
3502932dcb6SEd Tanous         }
3512932dcb6SEd Tanous     }
3522932dcb6SEd Tanous     if (numericThresholds.lowerWarning)
3532932dcb6SEd Tanous     {
3542932dcb6SEd Tanous         if (!parseThreshold(
3552932dcb6SEd Tanous                 res, *numericThresholds.lowerWarning,
3562932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
3572932dcb6SEd Tanous                 parsedParams))
3582932dcb6SEd Tanous         {
3592932dcb6SEd Tanous             return false;
3602932dcb6SEd Tanous         }
3612932dcb6SEd Tanous     }
3622932dcb6SEd Tanous     if (numericThresholds.lowerCritical)
3632932dcb6SEd Tanous     {
3642932dcb6SEd Tanous         if (!parseThreshold(
3652932dcb6SEd Tanous                 res, *numericThresholds.lowerCritical,
3662932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
3672932dcb6SEd Tanous                 parsedParams))
3682932dcb6SEd Tanous         {
3692932dcb6SEd Tanous             return false;
3702932dcb6SEd Tanous         }
371dd1c4a9cSSzymon Dompke     }
372dd1c4a9cSSzymon Dompke 
373dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
374dd1c4a9cSSzymon Dompke     return true;
375dd1c4a9cSSzymon Dompke }
376dd1c4a9cSSzymon Dompke 
377dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers(
378dd1c4a9cSSzymon Dompke     crow::Response& res,
3792932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
3802932dcb6SEd Tanous     Context& ctx)
381dd1c4a9cSSzymon Dompke {
382dd1c4a9cSSzymon Dompke     std::vector<DiscreteThresholdParams> parsedParams;
383dd1c4a9cSSzymon Dompke     if (!discreteTriggers)
384dd1c4a9cSSzymon Dompke     {
385dd1c4a9cSSzymon Dompke         ctx.thresholds = std::move(parsedParams);
386dd1c4a9cSSzymon Dompke         return true;
387dd1c4a9cSSzymon Dompke     }
388dd1c4a9cSSzymon Dompke 
389dd1c4a9cSSzymon Dompke     parsedParams.reserve(discreteTriggers->size());
3902932dcb6SEd Tanous     for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
391dd1c4a9cSSzymon Dompke     {
392dd1c4a9cSSzymon Dompke         std::optional<std::string> name = "";
393dd1c4a9cSSzymon Dompke         std::string value;
394dd1c4a9cSSzymon Dompke         std::string dwellTimeStr;
395dd1c4a9cSSzymon Dompke         std::string severity;
396dd1c4a9cSSzymon Dompke 
397*afc474aeSMyung Bae         if (!json_util::readJsonObject( //
398*afc474aeSMyung Bae                 thresholdInfo, res, //
399*afc474aeSMyung Bae                 "DwellTime", dwellTimeStr, //
400*afc474aeSMyung Bae                 "Name", name, //
401*afc474aeSMyung Bae                 "Severity", severity, //
402*afc474aeSMyung Bae                 "Value", value //
403*afc474aeSMyung Bae                 ))
404dd1c4a9cSSzymon Dompke         {
405dd1c4a9cSSzymon Dompke             return false;
406dd1c4a9cSSzymon Dompke         }
407dd1c4a9cSSzymon Dompke 
408dd1c4a9cSSzymon Dompke         std::optional<std::chrono::milliseconds> dwellTime =
409dd1c4a9cSSzymon Dompke             time_utils::fromDurationString(dwellTimeStr);
410dd1c4a9cSSzymon Dompke         if (!dwellTime)
411dd1c4a9cSSzymon Dompke         {
412dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
413dd1c4a9cSSzymon Dompke             return false;
414dd1c4a9cSSzymon Dompke         }
415dd1c4a9cSSzymon Dompke 
416dd1c4a9cSSzymon Dompke         std::string dbusSeverity = toDbusSeverity(severity);
417dd1c4a9cSSzymon Dompke         if (dbusSeverity.empty())
418dd1c4a9cSSzymon Dompke         {
419dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "Severity", severity);
420dd1c4a9cSSzymon Dompke             return false;
421dd1c4a9cSSzymon Dompke         }
422dd1c4a9cSSzymon Dompke 
423dd1c4a9cSSzymon Dompke         parsedParams.emplace_back(*name, dbusSeverity,
424dd1c4a9cSSzymon Dompke                                   static_cast<uint64_t>(dwellTime->count()),
425dd1c4a9cSSzymon Dompke                                   value);
426dd1c4a9cSSzymon Dompke     }
427dd1c4a9cSSzymon Dompke 
428dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
429dd1c4a9cSSzymon Dompke     return true;
430dd1c4a9cSSzymon Dompke }
431dd1c4a9cSSzymon Dompke 
432dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds(
433dd1c4a9cSSzymon Dompke     crow::Response& res,
4342932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
4352932dcb6SEd Tanous     NumericThresholds& numericThresholds, Context& ctx)
436dd1c4a9cSSzymon Dompke {
4372932dcb6SEd Tanous     if (discreteTriggers && numericThresholds.any())
438dd1c4a9cSSzymon Dompke     {
439dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "DiscreteTriggers",
440dd1c4a9cSSzymon Dompke                                         "NumericThresholds");
441dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "NumericThresholds",
442dd1c4a9cSSzymon Dompke                                         "DiscreteTriggers");
443dd1c4a9cSSzymon Dompke         return false;
444dd1c4a9cSSzymon Dompke     }
445dd1c4a9cSSzymon Dompke 
446dd1c4a9cSSzymon Dompke     if (ctx.discreteCondition)
447dd1c4a9cSSzymon Dompke     {
4482932dcb6SEd Tanous         if (numericThresholds.any())
449dd1c4a9cSSzymon Dompke         {
450dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggerCondition",
451dd1c4a9cSSzymon Dompke                                             "NumericThresholds");
452dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
453dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
454dd1c4a9cSSzymon Dompke             return false;
455dd1c4a9cSSzymon Dompke         }
456dd1c4a9cSSzymon Dompke     }
457dd1c4a9cSSzymon Dompke 
458dd1c4a9cSSzymon Dompke     if (ctx.metricType)
459dd1c4a9cSSzymon Dompke     {
4602932dcb6SEd Tanous         if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
461dd1c4a9cSSzymon Dompke         {
462dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
463dd1c4a9cSSzymon Dompke                                             "MetricType");
464dd1c4a9cSSzymon Dompke             return false;
465dd1c4a9cSSzymon Dompke         }
466dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
467dd1c4a9cSSzymon Dompke         {
468dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
469dd1c4a9cSSzymon Dompke                                             "MetricType");
470dd1c4a9cSSzymon Dompke             return false;
471dd1c4a9cSSzymon Dompke         }
472dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
473dd1c4a9cSSzymon Dompke         {
474dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
475dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
476dd1c4a9cSSzymon Dompke             return false;
477dd1c4a9cSSzymon Dompke         }
478dd1c4a9cSSzymon Dompke     }
479dd1c4a9cSSzymon Dompke 
480dd1c4a9cSSzymon Dompke     if (discreteTriggers || ctx.discreteCondition ||
481dd1c4a9cSSzymon Dompke         (ctx.metricType && *ctx.metricType == MetricType::Discrete))
482dd1c4a9cSSzymon Dompke     {
483dd1c4a9cSSzymon Dompke         if (ctx.discreteCondition)
484dd1c4a9cSSzymon Dompke         {
485dd1c4a9cSSzymon Dompke             if (*ctx.discreteCondition == DiscreteCondition::Specified &&
486dd1c4a9cSSzymon Dompke                 !discreteTriggers)
487dd1c4a9cSSzymon Dompke             {
488dd1c4a9cSSzymon Dompke                 messages::createFailedMissingReqProperties(res,
489dd1c4a9cSSzymon Dompke                                                            "DiscreteTriggers");
490dd1c4a9cSSzymon Dompke                 return false;
491dd1c4a9cSSzymon Dompke             }
492dd1c4a9cSSzymon Dompke             if (discreteTriggers &&
493dd1c4a9cSSzymon Dompke                 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
494dd1c4a9cSSzymon Dompke                   discreteTriggers->empty()) ||
495dd1c4a9cSSzymon Dompke                  (*ctx.discreteCondition == DiscreteCondition::Changed &&
496dd1c4a9cSSzymon Dompke                   !discreteTriggers->empty())))
497dd1c4a9cSSzymon Dompke             {
498dd1c4a9cSSzymon Dompke                 messages::propertyValueConflict(res, "DiscreteTriggers",
499dd1c4a9cSSzymon Dompke                                                 "DiscreteTriggerCondition");
500dd1c4a9cSSzymon Dompke                 return false;
501dd1c4a9cSSzymon Dompke             }
502dd1c4a9cSSzymon Dompke         }
503dd1c4a9cSSzymon Dompke         if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
504dd1c4a9cSSzymon Dompke         {
505dd1c4a9cSSzymon Dompke             return false;
506dd1c4a9cSSzymon Dompke         }
507dd1c4a9cSSzymon Dompke     }
5082932dcb6SEd Tanous     else if (numericThresholds.any())
509dd1c4a9cSSzymon Dompke     {
5102932dcb6SEd Tanous         if (!parseNumericThresholds(res, numericThresholds, ctx))
511dd1c4a9cSSzymon Dompke         {
512dd1c4a9cSSzymon Dompke             return false;
513dd1c4a9cSSzymon Dompke         }
514dd1c4a9cSSzymon Dompke     }
515dd1c4a9cSSzymon Dompke     else
516dd1c4a9cSSzymon Dompke     {
517dd1c4a9cSSzymon Dompke         messages::createFailedMissingReqProperties(
518dd1c4a9cSSzymon Dompke             res, "'DiscreteTriggers', 'NumericThresholds', "
519dd1c4a9cSSzymon Dompke                  "'DiscreteTriggerCondition' or 'MetricType'");
520dd1c4a9cSSzymon Dompke         return false;
521dd1c4a9cSSzymon Dompke     }
522dd1c4a9cSSzymon Dompke     return true;
523dd1c4a9cSSzymon Dompke }
524dd1c4a9cSSzymon Dompke 
5252932dcb6SEd Tanous inline bool parseLinks(crow::Response& res,
5262932dcb6SEd Tanous                        const std::vector<std::string>& metricReportDefinitions,
5272932dcb6SEd Tanous                        Context& ctx)
528dd1c4a9cSSzymon Dompke {
5292932dcb6SEd Tanous     ctx.reports.reserve(metricReportDefinitions.size());
5302932dcb6SEd Tanous     for (const std::string& reportDefinionUri : metricReportDefinitions)
531dd1c4a9cSSzymon Dompke     {
532dd1c4a9cSSzymon Dompke         std::optional<sdbusplus::message::object_path> reportPath =
533dd1c4a9cSSzymon Dompke             getReportPathFromReportDefinitionUri(reportDefinionUri);
534dd1c4a9cSSzymon Dompke         if (!reportPath)
535dd1c4a9cSSzymon Dompke         {
536dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricReportDefinitions",
537dd1c4a9cSSzymon Dompke                                              reportDefinionUri);
538dd1c4a9cSSzymon Dompke             return false;
539dd1c4a9cSSzymon Dompke         }
540dd1c4a9cSSzymon Dompke         ctx.reports.emplace_back(*reportPath);
541dd1c4a9cSSzymon Dompke     }
542dd1c4a9cSSzymon Dompke     return true;
543dd1c4a9cSSzymon Dompke }
544dd1c4a9cSSzymon Dompke 
545dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx)
546dd1c4a9cSSzymon Dompke {
547dd1c4a9cSSzymon Dompke     if (!ctx.metricProperties)
548dd1c4a9cSSzymon Dompke     {
549dd1c4a9cSSzymon Dompke         return true;
550dd1c4a9cSSzymon Dompke     }
551dd1c4a9cSSzymon Dompke 
552dd1c4a9cSSzymon Dompke     ctx.sensors.reserve(ctx.metricProperties->size());
553dd1c4a9cSSzymon Dompke 
554dd1c4a9cSSzymon Dompke     size_t uriIdx = 0;
555dd1c4a9cSSzymon Dompke     for (const std::string& uriStr : *ctx.metricProperties)
556dd1c4a9cSSzymon Dompke     {
5574a7fbefdSEd Tanous         boost::system::result<boost::urls::url> uri =
558dd1c4a9cSSzymon Dompke             boost::urls::parse_relative_ref(uriStr);
559dd1c4a9cSSzymon Dompke         if (!uri)
560dd1c4a9cSSzymon Dompke         {
561dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
562dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
563dd1c4a9cSSzymon Dompke             return false;
564dd1c4a9cSSzymon Dompke         }
565dd1c4a9cSSzymon Dompke         std::string chassisName;
566dd1c4a9cSSzymon Dompke         std::string sensorName;
567dd1c4a9cSSzymon Dompke         if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
568dd1c4a9cSSzymon Dompke                                             std::ref(chassisName), "Sensors",
569dd1c4a9cSSzymon Dompke                                             std::ref(sensorName)))
570dd1c4a9cSSzymon Dompke         {
571dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
572dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
573dd1c4a9cSSzymon Dompke             return false;
574dd1c4a9cSSzymon Dompke         }
575dd1c4a9cSSzymon Dompke 
576dd1c4a9cSSzymon Dompke         std::pair<std::string, std::string> split =
5771516c21bSJanet Adkins             redfish::sensor_utils::splitSensorNameAndType(sensorName);
578dd1c4a9cSSzymon Dompke         if (split.first.empty() || split.second.empty())
579dd1c4a9cSSzymon Dompke         {
580dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
581dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
582dd1c4a9cSSzymon Dompke             return false;
583dd1c4a9cSSzymon Dompke         }
584dd1c4a9cSSzymon Dompke 
585bd79bce8SPatrick Williams         std::string sensorPath =
586bd79bce8SPatrick Williams             "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
587dd1c4a9cSSzymon Dompke 
588dd1c4a9cSSzymon Dompke         ctx.sensors.emplace_back(sensorPath, uriStr);
589dd1c4a9cSSzymon Dompke         uriIdx++;
590dd1c4a9cSSzymon Dompke     }
591dd1c4a9cSSzymon Dompke     return true;
592dd1c4a9cSSzymon Dompke }
593dd1c4a9cSSzymon Dompke 
594dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res,
595dd1c4a9cSSzymon Dompke                                    const crow::Request& req, Context& ctx)
596dd1c4a9cSSzymon Dompke {
597dd1c4a9cSSzymon Dompke     std::optional<std::string> id = "";
598dd1c4a9cSSzymon Dompke     std::optional<std::string> name = "";
599dd1c4a9cSSzymon Dompke     std::optional<std::string> metricType;
600dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> triggerActions;
601dd1c4a9cSSzymon Dompke     std::optional<std::string> discreteTriggerCondition;
6022932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
6032932dcb6SEd Tanous     std::optional<std::vector<std::string>> metricReportDefinitions;
6042932dcb6SEd Tanous     NumericThresholds thresholds;
605*afc474aeSMyung Bae 
606*afc474aeSMyung Bae     if (!json_util::readJsonPatch( //
607*afc474aeSMyung Bae             req, res, //
608*afc474aeSMyung Bae             "Id", id, //
609*afc474aeSMyung Bae             "DiscreteTriggerCondition", discreteTriggerCondition, //
610*afc474aeSMyung Bae             "DiscreteTriggers", discreteTriggers, //
611*afc474aeSMyung Bae             "Links/MetricReportDefinitions", metricReportDefinitions, //
612*afc474aeSMyung Bae             "MetricProperties", ctx.metricProperties, //
613*afc474aeSMyung Bae             "MetricType", metricType, //
614*afc474aeSMyung Bae             "Name", name, //
615*afc474aeSMyung Bae             "NumericThresholds/LowerCritical", thresholds.lowerCritical, //
616*afc474aeSMyung Bae             "NumericThresholds/LowerWarning", thresholds.lowerWarning, //
617*afc474aeSMyung Bae             "NumericThresholds/UpperCritical", thresholds.upperCritical, //
618*afc474aeSMyung Bae             "NumericThresholds/UpperWarning", thresholds.upperWarning, //
619*afc474aeSMyung Bae             "TriggerActions", triggerActions //
620*afc474aeSMyung Bae             ))
621dd1c4a9cSSzymon Dompke     {
622dd1c4a9cSSzymon Dompke         return false;
623dd1c4a9cSSzymon Dompke     }
624dd1c4a9cSSzymon Dompke 
625dd1c4a9cSSzymon Dompke     ctx.id = *id;
626dd1c4a9cSSzymon Dompke     ctx.name = *name;
627dd1c4a9cSSzymon Dompke 
628dd1c4a9cSSzymon Dompke     if (metricType)
629dd1c4a9cSSzymon Dompke     {
630d5736ef2SEd Tanous         ctx.metricType = getMetricType(*metricType);
631d5736ef2SEd Tanous         if (!ctx.metricType)
632dd1c4a9cSSzymon Dompke         {
633dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricType", *metricType);
634dd1c4a9cSSzymon Dompke             return false;
635dd1c4a9cSSzymon Dompke         }
636dd1c4a9cSSzymon Dompke     }
637dd1c4a9cSSzymon Dompke 
638dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition)
639dd1c4a9cSSzymon Dompke     {
640d5736ef2SEd Tanous         ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
641d5736ef2SEd Tanous         if (!ctx.discreteCondition)
642dd1c4a9cSSzymon Dompke         {
643dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
644dd1c4a9cSSzymon Dompke                                              *discreteTriggerCondition);
645dd1c4a9cSSzymon Dompke             return false;
646dd1c4a9cSSzymon Dompke         }
647dd1c4a9cSSzymon Dompke     }
648dd1c4a9cSSzymon Dompke 
649dd1c4a9cSSzymon Dompke     if (triggerActions)
650dd1c4a9cSSzymon Dompke     {
651dd1c4a9cSSzymon Dompke         ctx.actions.reserve(triggerActions->size());
652dd1c4a9cSSzymon Dompke         for (const std::string& action : *triggerActions)
653dd1c4a9cSSzymon Dompke         {
654dd1c4a9cSSzymon Dompke             std::string dbusAction = toDbusTriggerAction(action);
655dd1c4a9cSSzymon Dompke 
656dd1c4a9cSSzymon Dompke             if (dbusAction.empty())
657dd1c4a9cSSzymon Dompke             {
658dd1c4a9cSSzymon Dompke                 messages::propertyValueNotInList(res, action, "TriggerActions");
659dd1c4a9cSSzymon Dompke                 return false;
660dd1c4a9cSSzymon Dompke             }
661dd1c4a9cSSzymon Dompke 
662dd1c4a9cSSzymon Dompke             ctx.actions.emplace_back(dbusAction);
663dd1c4a9cSSzymon Dompke         }
664dd1c4a9cSSzymon Dompke     }
665dd1c4a9cSSzymon Dompke     if (!parseMetricProperties(res, ctx))
666dd1c4a9cSSzymon Dompke     {
667dd1c4a9cSSzymon Dompke         return false;
668dd1c4a9cSSzymon Dompke     }
669dd1c4a9cSSzymon Dompke 
6702932dcb6SEd Tanous     if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
671dd1c4a9cSSzymon Dompke     {
672dd1c4a9cSSzymon Dompke         return false;
673dd1c4a9cSSzymon Dompke     }
674dd1c4a9cSSzymon Dompke 
6752932dcb6SEd Tanous     if (metricReportDefinitions)
676dd1c4a9cSSzymon Dompke     {
6772932dcb6SEd Tanous         if (!parseLinks(res, *metricReportDefinitions, ctx))
678dd1c4a9cSSzymon Dompke         {
679dd1c4a9cSSzymon Dompke             return false;
680dd1c4a9cSSzymon Dompke         }
681dd1c4a9cSSzymon Dompke     }
682dd1c4a9cSSzymon Dompke     return true;
683dd1c4a9cSSzymon Dompke }
684dd1c4a9cSSzymon Dompke 
685dd1c4a9cSSzymon Dompke inline void afterCreateTrigger(
686dd1c4a9cSSzymon Dompke     const boost::system::error_code& ec, const std::string& dbusPath,
687dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
688dd1c4a9cSSzymon Dompke {
689dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::file_exists)
690dd1c4a9cSSzymon Dompke     {
691dd1c4a9cSSzymon Dompke         messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
692dd1c4a9cSSzymon Dompke         return;
693dd1c4a9cSSzymon Dompke     }
694dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::too_many_files_open)
695dd1c4a9cSSzymon Dompke     {
696dd1c4a9cSSzymon Dompke         messages::createLimitReachedForResource(asyncResp->res);
697dd1c4a9cSSzymon Dompke         return;
698dd1c4a9cSSzymon Dompke     }
699dd1c4a9cSSzymon Dompke     if (ec)
700dd1c4a9cSSzymon Dompke     {
701dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
70262598e31SEd Tanous         BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
703dd1c4a9cSSzymon Dompke         return;
704dd1c4a9cSSzymon Dompke     }
705dd1c4a9cSSzymon Dompke 
706dd1c4a9cSSzymon Dompke     const std::optional<std::string>& triggerId =
707dd1c4a9cSSzymon Dompke         getTriggerIdFromDbusPath(dbusPath);
708dd1c4a9cSSzymon Dompke     if (!triggerId)
709dd1c4a9cSSzymon Dompke     {
710dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
71162598e31SEd Tanous         BMCWEB_LOG_ERROR("Unknown data returned by "
71262598e31SEd Tanous                          "AddTrigger DBus method");
713dd1c4a9cSSzymon Dompke         return;
714dd1c4a9cSSzymon Dompke     }
715dd1c4a9cSSzymon Dompke 
716dd1c4a9cSSzymon Dompke     messages::created(asyncResp->res);
717dd1c4a9cSSzymon Dompke     boost::urls::url locationUrl = boost::urls::format(
718dd1c4a9cSSzymon Dompke         "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
719dd1c4a9cSSzymon Dompke     asyncResp->res.addHeader("Location", locationUrl.buffer());
720dd1c4a9cSSzymon Dompke }
721dd1c4a9cSSzymon Dompke 
722dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t>
723dd1c4a9cSSzymon Dompke     getTriggerActions(const std::vector<std::string>& dbusActions)
724dd1c4a9cSSzymon Dompke {
725dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggerActions;
726dd1c4a9cSSzymon Dompke     for (const std::string& dbusAction : dbusActions)
727dd1c4a9cSSzymon Dompke     {
728dd1c4a9cSSzymon Dompke         triggers::TriggerActionEnum redfishAction =
729dd1c4a9cSSzymon Dompke             toRedfishTriggerAction(dbusAction);
730dd1c4a9cSSzymon Dompke 
731dd1c4a9cSSzymon Dompke         if (redfishAction == triggers::TriggerActionEnum::Invalid)
732dd1c4a9cSSzymon Dompke         {
733dd1c4a9cSSzymon Dompke             return std::nullopt;
734dd1c4a9cSSzymon Dompke         }
735dd1c4a9cSSzymon Dompke 
736dd1c4a9cSSzymon Dompke         triggerActions.emplace_back(redfishAction);
737dd1c4a9cSSzymon Dompke     }
738dd1c4a9cSSzymon Dompke 
739dd1c4a9cSSzymon Dompke     return triggerActions;
7401b7e696bSLukasz Kazmierczak }
7411b7e696bSLukasz Kazmierczak 
7423f215c92SSzymon Dompke inline std::optional<nlohmann::json::array_t>
7431b7e696bSLukasz Kazmierczak     getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
7441b7e696bSLukasz Kazmierczak {
745dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggers;
7461b7e696bSLukasz Kazmierczak     const std::vector<DiscreteThresholdParams>* discreteParams =
7471b7e696bSLukasz Kazmierczak         std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
7481b7e696bSLukasz Kazmierczak 
749e662eae8SEd Tanous     if (discreteParams == nullptr)
7501b7e696bSLukasz Kazmierczak     {
7511b7e696bSLukasz Kazmierczak         return std::nullopt;
7521b7e696bSLukasz Kazmierczak     }
7531b7e696bSLukasz Kazmierczak 
7541b7e696bSLukasz Kazmierczak     for (const auto& [name, severity, dwellTime, value] : *discreteParams)
7551b7e696bSLukasz Kazmierczak     {
7561b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7571b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7581b7e696bSLukasz Kazmierczak 
7591b7e696bSLukasz Kazmierczak         if (!duration)
7601b7e696bSLukasz Kazmierczak         {
7611b7e696bSLukasz Kazmierczak             return std::nullopt;
7621b7e696bSLukasz Kazmierczak         }
763613dabeaSEd Tanous         nlohmann::json::object_t trigger;
764613dabeaSEd Tanous         trigger["Name"] = name;
765dd1c4a9cSSzymon Dompke         trigger["Severity"] = toRedfishSeverity(severity);
766613dabeaSEd Tanous         trigger["DwellTime"] = *duration;
767613dabeaSEd Tanous         trigger["Value"] = value;
768ad539545SPatrick Williams         triggers.emplace_back(std::move(trigger));
7691b7e696bSLukasz Kazmierczak     }
7701b7e696bSLukasz Kazmierczak 
771dd1c4a9cSSzymon Dompke     return triggers;
7721b7e696bSLukasz Kazmierczak }
7731b7e696bSLukasz Kazmierczak 
7741b7e696bSLukasz Kazmierczak inline std::optional<nlohmann::json>
7751b7e696bSLukasz Kazmierczak     getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
7761b7e696bSLukasz Kazmierczak {
777dd1c4a9cSSzymon Dompke     nlohmann::json::object_t thresholds;
7781b7e696bSLukasz Kazmierczak     const std::vector<NumericThresholdParams>* numericParams =
7791b7e696bSLukasz Kazmierczak         std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
7801b7e696bSLukasz Kazmierczak 
781e662eae8SEd Tanous     if (numericParams == nullptr)
7821b7e696bSLukasz Kazmierczak     {
7831b7e696bSLukasz Kazmierczak         return std::nullopt;
7841b7e696bSLukasz Kazmierczak     }
7851b7e696bSLukasz Kazmierczak 
7861b7e696bSLukasz Kazmierczak     for (const auto& [type, dwellTime, activation, reading] : *numericParams)
7871b7e696bSLukasz Kazmierczak     {
7881b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7891b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7901b7e696bSLukasz Kazmierczak 
7911b7e696bSLukasz Kazmierczak         if (!duration)
7921b7e696bSLukasz Kazmierczak         {
7931b7e696bSLukasz Kazmierczak             return std::nullopt;
7941b7e696bSLukasz Kazmierczak         }
795dd1c4a9cSSzymon Dompke         nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
7961476687dSEd Tanous         threshold["Reading"] = reading;
797dd1c4a9cSSzymon Dompke         threshold["Activation"] = toRedfishActivation(activation);
7981476687dSEd Tanous         threshold["DwellTime"] = *duration;
7991b7e696bSLukasz Kazmierczak     }
8001b7e696bSLukasz Kazmierczak 
801dd1c4a9cSSzymon Dompke     return thresholds;
8021b7e696bSLukasz Kazmierczak }
8031b7e696bSLukasz Kazmierczak 
8043f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions(
8053f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>& reportPaths)
8061b7e696bSLukasz Kazmierczak {
8071b7e696bSLukasz Kazmierczak     nlohmann::json reports = nlohmann::json::array();
8083f215c92SSzymon Dompke 
8093f215c92SSzymon Dompke     for (const sdbusplus::message::object_path& path : reportPaths)
8101b7e696bSLukasz Kazmierczak     {
8113f215c92SSzymon Dompke         std::string reportId = path.filename();
8123f215c92SSzymon Dompke         if (reportId.empty())
8133f215c92SSzymon Dompke         {
8143f215c92SSzymon Dompke             {
81562598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
81662598e31SEd Tanous                                  path.str);
8173f215c92SSzymon Dompke                 return std::nullopt;
8183f215c92SSzymon Dompke             }
8193f215c92SSzymon Dompke         }
8203f215c92SSzymon Dompke 
8211476687dSEd Tanous         nlohmann::json::object_t report;
822ef4c65b7SEd Tanous         report["@odata.id"] = boost::urls::format(
823ef4c65b7SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
824ef4c65b7SEd Tanous             reportId);
825b2ba3072SPatrick Williams         reports.emplace_back(std::move(report));
8261b7e696bSLukasz Kazmierczak     }
8271b7e696bSLukasz Kazmierczak 
8283f215c92SSzymon Dompke     return {std::move(reports)};
8291b7e696bSLukasz Kazmierczak }
8301b7e696bSLukasz Kazmierczak 
8311b7e696bSLukasz Kazmierczak inline std::vector<std::string>
8321b7e696bSLukasz Kazmierczak     getMetricProperties(const TriggerSensorsParams& sensors)
8331b7e696bSLukasz Kazmierczak {
8341b7e696bSLukasz Kazmierczak     std::vector<std::string> metricProperties;
8351b7e696bSLukasz Kazmierczak     metricProperties.reserve(sensors.size());
8361b7e696bSLukasz Kazmierczak     for (const auto& [_, metadata] : sensors)
8371b7e696bSLukasz Kazmierczak     {
8381b7e696bSLukasz Kazmierczak         metricProperties.emplace_back(metadata);
8391b7e696bSLukasz Kazmierczak     }
8401b7e696bSLukasz Kazmierczak 
8411b7e696bSLukasz Kazmierczak     return metricProperties;
8421b7e696bSLukasz Kazmierczak }
8431b7e696bSLukasz Kazmierczak 
8441b7e696bSLukasz Kazmierczak inline bool fillTrigger(
8451b7e696bSLukasz Kazmierczak     nlohmann::json& json, const std::string& id,
8461b7e696bSLukasz Kazmierczak     const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
8471b7e696bSLukasz Kazmierczak         properties)
8481b7e696bSLukasz Kazmierczak {
8491b7e696bSLukasz Kazmierczak     const std::string* name = nullptr;
8501b7e696bSLukasz Kazmierczak     const bool* discrete = nullptr;
8511b7e696bSLukasz Kazmierczak     const TriggerSensorsParams* sensors = nullptr;
8523f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>* reports = nullptr;
85389474494SKrzysztof Grobelny     const std::vector<std::string>* triggerActions = nullptr;
8541b7e696bSLukasz Kazmierczak     const TriggerThresholdParamsExt* thresholds = nullptr;
8551b7e696bSLukasz Kazmierczak 
85689474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
85789474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
85889474494SKrzysztof Grobelny         discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
85989474494SKrzysztof Grobelny         triggerActions, "Thresholds", thresholds);
86089474494SKrzysztof Grobelny 
86189474494SKrzysztof Grobelny     if (!success)
8621b7e696bSLukasz Kazmierczak     {
86389474494SKrzysztof Grobelny         return false;
8641b7e696bSLukasz Kazmierczak     }
8651b7e696bSLukasz Kazmierczak 
86689474494SKrzysztof Grobelny     if (triggerActions != nullptr)
86789474494SKrzysztof Grobelny     {
868dd1c4a9cSSzymon Dompke         std::optional<nlohmann::json::array_t> redfishTriggerActions =
86989474494SKrzysztof Grobelny             getTriggerActions(*triggerActions);
87089474494SKrzysztof Grobelny         if (!redfishTriggerActions)
8711b7e696bSLukasz Kazmierczak         {
87262598e31SEd Tanous             BMCWEB_LOG_ERROR(
87362598e31SEd Tanous                 "Property TriggerActions is invalid in Trigger: {}", id);
8741b7e696bSLukasz Kazmierczak             return false;
8751b7e696bSLukasz Kazmierczak         }
876dd1c4a9cSSzymon Dompke         json["TriggerActions"] = *redfishTriggerActions;
87789474494SKrzysztof Grobelny     }
8781b7e696bSLukasz Kazmierczak 
87989474494SKrzysztof Grobelny     if (reports != nullptr)
8803f215c92SSzymon Dompke     {
8813f215c92SSzymon Dompke         std::optional<nlohmann::json> linkedReports =
8823f215c92SSzymon Dompke             getMetricReportDefinitions(*reports);
8833f215c92SSzymon Dompke         if (!linkedReports)
8843f215c92SSzymon Dompke         {
88562598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
8863f215c92SSzymon Dompke             return false;
8873f215c92SSzymon Dompke         }
88889474494SKrzysztof Grobelny         json["Links"]["MetricReportDefinitions"] = *linkedReports;
88989474494SKrzysztof Grobelny     }
8901b7e696bSLukasz Kazmierczak 
89189474494SKrzysztof Grobelny     if (discrete != nullptr)
89289474494SKrzysztof Grobelny     {
8931b7e696bSLukasz Kazmierczak         if (*discrete)
8941b7e696bSLukasz Kazmierczak         {
8953f215c92SSzymon Dompke             std::optional<nlohmann::json::array_t> discreteTriggers =
8961b7e696bSLukasz Kazmierczak                 getDiscreteTriggers(*thresholds);
8971b7e696bSLukasz Kazmierczak 
8981b7e696bSLukasz Kazmierczak             if (!discreteTriggers)
8991b7e696bSLukasz Kazmierczak             {
90062598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
90162598e31SEd Tanous                                  "triggers in Trigger: {}",
90262598e31SEd Tanous                                  id);
9031b7e696bSLukasz Kazmierczak                 return false;
9041b7e696bSLukasz Kazmierczak             }
9051b7e696bSLukasz Kazmierczak 
9061b7e696bSLukasz Kazmierczak             json["DiscreteTriggers"] = *discreteTriggers;
9071b7e696bSLukasz Kazmierczak             json["DiscreteTriggerCondition"] =
9081b7e696bSLukasz Kazmierczak                 discreteTriggers->empty() ? "Changed" : "Specified";
909539d8c6bSEd Tanous             json["MetricType"] = metric_definition::MetricType::Discrete;
9101b7e696bSLukasz Kazmierczak         }
9111b7e696bSLukasz Kazmierczak         else
9121b7e696bSLukasz Kazmierczak         {
9131b7e696bSLukasz Kazmierczak             std::optional<nlohmann::json> numericThresholds =
9141b7e696bSLukasz Kazmierczak                 getNumericThresholds(*thresholds);
9151b7e696bSLukasz Kazmierczak 
9161b7e696bSLukasz Kazmierczak             if (!numericThresholds)
9171b7e696bSLukasz Kazmierczak             {
91862598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
91962598e31SEd Tanous                                  "thresholds in Trigger: {}",
92062598e31SEd Tanous                                  id);
9211b7e696bSLukasz Kazmierczak                 return false;
9221b7e696bSLukasz Kazmierczak             }
9231b7e696bSLukasz Kazmierczak 
9241b7e696bSLukasz Kazmierczak             json["NumericThresholds"] = *numericThresholds;
925539d8c6bSEd Tanous             json["MetricType"] = metric_definition::MetricType::Numeric;
9261b7e696bSLukasz Kazmierczak         }
92789474494SKrzysztof Grobelny     }
92889474494SKrzysztof Grobelny 
92989474494SKrzysztof Grobelny     if (name != nullptr)
93089474494SKrzysztof Grobelny     {
93189474494SKrzysztof Grobelny         json["Name"] = *name;
93289474494SKrzysztof Grobelny     }
93389474494SKrzysztof Grobelny 
93489474494SKrzysztof Grobelny     if (sensors != nullptr)
93589474494SKrzysztof Grobelny     {
93689474494SKrzysztof Grobelny         json["MetricProperties"] = getMetricProperties(*sensors);
93789474494SKrzysztof Grobelny     }
9381b7e696bSLukasz Kazmierczak 
9393f215c92SSzymon Dompke     json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
940ef4c65b7SEd Tanous     json["@odata.id"] =
941ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
9423f215c92SSzymon Dompke     json["Id"] = id;
9431b7e696bSLukasz Kazmierczak 
9441b7e696bSLukasz Kazmierczak     return true;
9451b7e696bSLukasz Kazmierczak }
9461b7e696bSLukasz Kazmierczak 
947dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost(
948dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
949dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
950dd1c4a9cSSzymon Dompke {
951dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
952dd1c4a9cSSzymon Dompke     {
953dd1c4a9cSSzymon Dompke         return;
954dd1c4a9cSSzymon Dompke     }
955dd1c4a9cSSzymon Dompke 
956dd1c4a9cSSzymon Dompke     telemetry::Context ctx;
957dd1c4a9cSSzymon Dompke     if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
958dd1c4a9cSSzymon Dompke     {
959dd1c4a9cSSzymon Dompke         return;
960dd1c4a9cSSzymon Dompke     }
961dd1c4a9cSSzymon Dompke 
962dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
963dd1c4a9cSSzymon Dompke         [asyncResp, id = ctx.id](const boost::system::error_code& ec,
964dd1c4a9cSSzymon Dompke                                  const std::string& dbusPath) {
965dd1c4a9cSSzymon Dompke             afterCreateTrigger(ec, dbusPath, asyncResp, id);
966dd1c4a9cSSzymon Dompke         },
967dd1c4a9cSSzymon Dompke         service, "/xyz/openbmc_project/Telemetry/Triggers",
968dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
969dd1c4a9cSSzymon Dompke         "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
970dd1c4a9cSSzymon Dompke         ctx.reports, ctx.thresholds);
971dd1c4a9cSSzymon Dompke }
972dd1c4a9cSSzymon Dompke 
97307148cf2SLukasz Kazmierczak } // namespace telemetry
97407148cf2SLukasz Kazmierczak 
97507148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app)
97607148cf2SLukasz Kazmierczak {
97707148cf2SLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
97807148cf2SLukasz Kazmierczak         .privileges(redfish::privileges::getTriggersCollection)
97907148cf2SLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
98045ca1b86SEd Tanous             [&app](const crow::Request& req,
98107148cf2SLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
9823ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
98345ca1b86SEd Tanous                 {
98445ca1b86SEd Tanous                     return;
98545ca1b86SEd Tanous                 }
98607148cf2SLukasz Kazmierczak                 asyncResp->res.jsonValue["@odata.type"] =
98707148cf2SLukasz Kazmierczak                     "#TriggersCollection.TriggersCollection";
988ae9031f0SWilly Tu                 asyncResp->res.jsonValue["@odata.id"] =
989ae9031f0SWilly Tu                     "/redfish/v1/TelemetryService/Triggers";
99007148cf2SLukasz Kazmierczak                 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
9917a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
9927a1dbc48SGeorge Liu                     telemetry::triggerInterface};
99307148cf2SLukasz Kazmierczak                 collection_util::getCollectionMembers(
994ae9031f0SWilly Tu                     asyncResp,
995ae9031f0SWilly Tu                     boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
996ae9031f0SWilly Tu                     interfaces,
99707148cf2SLukasz Kazmierczak                     "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
99807148cf2SLukasz Kazmierczak             });
999dd1c4a9cSSzymon Dompke 
1000dd1c4a9cSSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
1001dd1c4a9cSSzymon Dompke         .privileges(redfish::privileges::postTriggersCollection)
1002dd1c4a9cSSzymon Dompke         .methods(boost::beast::http::verb::post)(std::bind_front(
1003dd1c4a9cSSzymon Dompke             telemetry::handleTriggerCollectionPost, std::ref(app)));
100407148cf2SLukasz Kazmierczak }
100507148cf2SLukasz Kazmierczak 
10061b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app)
10071b7e696bSLukasz Kazmierczak {
10081b7e696bSLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
10091b7e696bSLukasz Kazmierczak         .privileges(redfish::privileges::getTriggers)
10101b7e696bSLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
101145ca1b86SEd Tanous             [&app](const crow::Request& req,
10121b7e696bSLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10131b7e696bSLukasz Kazmierczak                    const std::string& id) {
10143ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
101545ca1b86SEd Tanous                 {
101645ca1b86SEd Tanous                     return;
101745ca1b86SEd Tanous                 }
101889474494SKrzysztof Grobelny                 sdbusplus::asio::getAllProperties(
101989474494SKrzysztof Grobelny                     *crow::connections::systemBus, telemetry::service,
1020bd79bce8SPatrick Williams                     telemetry::getDbusTriggerPath(id),
1021bd79bce8SPatrick Williams                     telemetry::triggerInterface,
10221b7e696bSLukasz Kazmierczak                     [asyncResp,
10235e7e2dc5SEd Tanous                      id](const boost::system::error_code& ec,
10241b7e696bSLukasz Kazmierczak                          const std::vector<std::pair<
1025bd79bce8SPatrick Williams                              std::string, telemetry::TriggerGetParamsVariant>>&
1026bd79bce8SPatrick Williams                              ret) {
10271b7e696bSLukasz Kazmierczak                         if (ec.value() == EBADR ||
10281b7e696bSLukasz Kazmierczak                             ec == boost::system::errc::host_unreachable)
10291b7e696bSLukasz Kazmierczak                         {
1030bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
1031bd79bce8SPatrick Williams                                                        "Triggers", id);
10321b7e696bSLukasz Kazmierczak                             return;
10331b7e696bSLukasz Kazmierczak                         }
10341b7e696bSLukasz Kazmierczak                         if (ec)
10351b7e696bSLukasz Kazmierczak                         {
103662598e31SEd Tanous                             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
10371b7e696bSLukasz Kazmierczak                             messages::internalError(asyncResp->res);
10381b7e696bSLukasz Kazmierczak                             return;
10391b7e696bSLukasz Kazmierczak                         }
10401b7e696bSLukasz Kazmierczak 
1041bd79bce8SPatrick Williams                         if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
1042bd79bce8SPatrick Williams                                                     id, ret))
10431b7e696bSLukasz Kazmierczak                         {
10441b7e696bSLukasz Kazmierczak                             messages::internalError(asyncResp->res);
10451b7e696bSLukasz Kazmierczak                         }
104689474494SKrzysztof Grobelny                     });
10471b7e696bSLukasz Kazmierczak             });
1048163994a8SSzymon Dompke 
1049163994a8SSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1050163994a8SSzymon Dompke         .privileges(redfish::privileges::deleteTriggers)
1051163994a8SSzymon Dompke         .methods(boost::beast::http::verb::delete_)(
105245ca1b86SEd Tanous             [&app](const crow::Request& req,
1053163994a8SSzymon Dompke                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1054163994a8SSzymon Dompke                    const std::string& id) {
10553ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
105645ca1b86SEd Tanous                 {
105745ca1b86SEd Tanous                     return;
105845ca1b86SEd Tanous                 }
1059bd79bce8SPatrick Williams                 const std::string triggerPath =
1060bd79bce8SPatrick Williams                     telemetry::getDbusTriggerPath(id);
1061163994a8SSzymon Dompke 
1062163994a8SSzymon Dompke                 crow::connections::systemBus->async_method_call(
10635e7e2dc5SEd Tanous                     [asyncResp, id](const boost::system::error_code& ec) {
1064163994a8SSzymon Dompke                         if (ec.value() == EBADR)
1065163994a8SSzymon Dompke                         {
1066bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
1067bd79bce8SPatrick Williams                                                        "Triggers", id);
1068163994a8SSzymon Dompke                             return;
1069163994a8SSzymon Dompke                         }
1070163994a8SSzymon Dompke 
1071163994a8SSzymon Dompke                         if (ec)
1072163994a8SSzymon Dompke                         {
107362598e31SEd Tanous                             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1074163994a8SSzymon Dompke                             messages::internalError(asyncResp->res);
1075163994a8SSzymon Dompke                             return;
1076163994a8SSzymon Dompke                         }
1077163994a8SSzymon Dompke 
1078bd79bce8SPatrick Williams                         asyncResp->res.result(
1079bd79bce8SPatrick Williams                             boost::beast::http::status::no_content);
1080163994a8SSzymon Dompke                     },
1081163994a8SSzymon Dompke                     telemetry::service, triggerPath,
1082163994a8SSzymon Dompke                     "xyz.openbmc_project.Object.Delete", "Delete");
1083163994a8SSzymon Dompke             });
10841b7e696bSLukasz Kazmierczak }
10851b7e696bSLukasz Kazmierczak 
108607148cf2SLukasz Kazmierczak } // namespace redfish
1087