xref: /openbmc/bmcweb/features/redfish/lib/trigger.hpp (revision d5736ef260c5534fb2fe2ee895d62e91bc9319c3)
107148cf2SLukasz Kazmierczak #pragma once
207148cf2SLukasz Kazmierczak 
33ccb3adbSEd Tanous #include "app.hpp"
4dd1c4a9cSSzymon Dompke #include "generated/enums/resource.hpp"
5dd1c4a9cSSzymon Dompke #include "generated/enums/triggers.hpp"
63ccb3adbSEd Tanous #include "query.hpp"
73ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
8dd1c4a9cSSzymon Dompke #include "sensors.hpp"
9dd1c4a9cSSzymon Dompke #include "utility.hpp"
1007148cf2SLukasz Kazmierczak #include "utils/collection.hpp"
113ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
1207148cf2SLukasz Kazmierczak #include "utils/telemetry_utils.hpp"
133ccb3adbSEd Tanous #include "utils/time_utils.hpp"
1407148cf2SLukasz Kazmierczak 
15ef4c65b7SEd Tanous #include <boost/url/format.hpp>
1689474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1789474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
1807148cf2SLukasz Kazmierczak 
197a1dbc48SGeorge Liu #include <array>
207a1dbc48SGeorge Liu #include <string_view>
211b7e696bSLukasz Kazmierczak #include <tuple>
221b7e696bSLukasz Kazmierczak #include <variant>
231b7e696bSLukasz Kazmierczak #include <vector>
241b7e696bSLukasz Kazmierczak 
2507148cf2SLukasz Kazmierczak namespace redfish
2607148cf2SLukasz Kazmierczak {
2707148cf2SLukasz Kazmierczak namespace telemetry
2807148cf2SLukasz Kazmierczak {
2907148cf2SLukasz Kazmierczak constexpr const char* triggerInterface =
3007148cf2SLukasz Kazmierczak     "xyz.openbmc_project.Telemetry.Trigger";
3107148cf2SLukasz Kazmierczak 
321b7e696bSLukasz Kazmierczak using NumericThresholdParams =
331b7e696bSLukasz Kazmierczak     std::tuple<std::string, uint64_t, std::string, double>;
341b7e696bSLukasz Kazmierczak 
351b7e696bSLukasz Kazmierczak using DiscreteThresholdParams =
361b7e696bSLukasz Kazmierczak     std::tuple<std::string, std::string, uint64_t, std::string>;
371b7e696bSLukasz Kazmierczak 
38dd1c4a9cSSzymon Dompke using TriggerThresholdParams =
39dd1c4a9cSSzymon Dompke     std::variant<std::vector<NumericThresholdParams>,
40dd1c4a9cSSzymon Dompke                  std::vector<DiscreteThresholdParams>>;
41dd1c4a9cSSzymon Dompke 
421b7e696bSLukasz Kazmierczak using TriggerThresholdParamsExt =
431b7e696bSLukasz Kazmierczak     std::variant<std::monostate, std::vector<NumericThresholdParams>,
441b7e696bSLukasz Kazmierczak                  std::vector<DiscreteThresholdParams>>;
451b7e696bSLukasz Kazmierczak 
461b7e696bSLukasz Kazmierczak using TriggerSensorsParams =
471b7e696bSLukasz Kazmierczak     std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
481b7e696bSLukasz Kazmierczak 
491b7e696bSLukasz Kazmierczak using TriggerGetParamsVariant =
501b7e696bSLukasz Kazmierczak     std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
513f215c92SSzymon Dompke                  TriggerSensorsParams, std::vector<std::string>,
523f215c92SSzymon Dompke                  std::vector<sdbusplus::message::object_path>>;
531b7e696bSLukasz Kazmierczak 
54dd1c4a9cSSzymon Dompke inline triggers::TriggerActionEnum
55dd1c4a9cSSzymon Dompke     toRedfishTriggerAction(std::string_view dbusValue)
561b7e696bSLukasz Kazmierczak {
57dd1c4a9cSSzymon Dompke     if (dbusValue ==
58dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
591b7e696bSLukasz Kazmierczak     {
60dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishMetricReport;
611b7e696bSLukasz Kazmierczak     }
62dd1c4a9cSSzymon Dompke     if (dbusValue ==
63dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
641b7e696bSLukasz Kazmierczak     {
65dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishEvent;
661b7e696bSLukasz Kazmierczak     }
67dd1c4a9cSSzymon Dompke     if (dbusValue ==
68dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
691b7e696bSLukasz Kazmierczak     {
70dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::LogToLogService;
711b7e696bSLukasz Kazmierczak     }
72dd1c4a9cSSzymon Dompke     return triggers::TriggerActionEnum::Invalid;
731b7e696bSLukasz Kazmierczak }
741b7e696bSLukasz Kazmierczak 
75dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue)
761b7e696bSLukasz Kazmierczak {
77dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishMetricReport")
781b7e696bSLukasz Kazmierczak     {
79dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
80dd1c4a9cSSzymon Dompke     }
81dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishEvent")
82dd1c4a9cSSzymon Dompke     {
83dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
84dd1c4a9cSSzymon Dompke     }
85dd1c4a9cSSzymon Dompke     if (redfishValue == "LogToLogService")
86dd1c4a9cSSzymon Dompke     {
87dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
88dd1c4a9cSSzymon Dompke     }
89dd1c4a9cSSzymon Dompke     return "";
90dd1c4a9cSSzymon Dompke }
911b7e696bSLukasz Kazmierczak 
92dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue)
93dd1c4a9cSSzymon Dompke {
94dd1c4a9cSSzymon Dompke     if (redfishValue == "OK")
95dd1c4a9cSSzymon Dompke     {
96dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
97dd1c4a9cSSzymon Dompke     }
98dd1c4a9cSSzymon Dompke     if (redfishValue == "Warning")
99dd1c4a9cSSzymon Dompke     {
100dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
101dd1c4a9cSSzymon Dompke     }
102dd1c4a9cSSzymon Dompke     if (redfishValue == "Critical")
103dd1c4a9cSSzymon Dompke     {
104dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
105dd1c4a9cSSzymon Dompke     }
106dd1c4a9cSSzymon Dompke     return "";
107dd1c4a9cSSzymon Dompke }
108dd1c4a9cSSzymon Dompke 
109dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue)
110dd1c4a9cSSzymon Dompke {
111dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
112dd1c4a9cSSzymon Dompke     {
113dd1c4a9cSSzymon Dompke         return resource::Health::OK;
114dd1c4a9cSSzymon Dompke     }
115dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
116dd1c4a9cSSzymon Dompke     {
117dd1c4a9cSSzymon Dompke         return resource::Health::Warning;
118dd1c4a9cSSzymon Dompke     }
119dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
120dd1c4a9cSSzymon Dompke     {
121dd1c4a9cSSzymon Dompke         return resource::Health::Critical;
122dd1c4a9cSSzymon Dompke     }
123dd1c4a9cSSzymon Dompke     return resource::Health::Invalid;
124dd1c4a9cSSzymon Dompke }
125dd1c4a9cSSzymon Dompke 
126dd1c4a9cSSzymon Dompke inline std::string toDbusThresholdName(std::string_view redfishValue)
127dd1c4a9cSSzymon Dompke {
128dd1c4a9cSSzymon Dompke     if (redfishValue == "UpperCritical")
129dd1c4a9cSSzymon Dompke     {
130dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical";
131dd1c4a9cSSzymon Dompke     }
132dd1c4a9cSSzymon Dompke 
133dd1c4a9cSSzymon Dompke     if (redfishValue == "LowerCritical")
134dd1c4a9cSSzymon Dompke     {
135dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical";
136dd1c4a9cSSzymon Dompke     }
137dd1c4a9cSSzymon Dompke 
138dd1c4a9cSSzymon Dompke     if (redfishValue == "UpperWarning")
139dd1c4a9cSSzymon Dompke     {
140dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning";
141dd1c4a9cSSzymon Dompke     }
142dd1c4a9cSSzymon Dompke 
143dd1c4a9cSSzymon Dompke     if (redfishValue == "LowerWarning")
144dd1c4a9cSSzymon Dompke     {
145dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning";
146dd1c4a9cSSzymon Dompke     }
147dd1c4a9cSSzymon Dompke 
148dd1c4a9cSSzymon Dompke     return "";
149dd1c4a9cSSzymon Dompke }
150dd1c4a9cSSzymon Dompke 
151dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue)
152dd1c4a9cSSzymon Dompke {
153dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
154dd1c4a9cSSzymon Dompke     {
155dd1c4a9cSSzymon Dompke         return "UpperCritical";
156dd1c4a9cSSzymon Dompke     }
157dd1c4a9cSSzymon Dompke 
158dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
159dd1c4a9cSSzymon Dompke     {
160dd1c4a9cSSzymon Dompke         return "LowerCritical";
161dd1c4a9cSSzymon Dompke     }
162dd1c4a9cSSzymon Dompke 
163dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
164dd1c4a9cSSzymon Dompke     {
165dd1c4a9cSSzymon Dompke         return "UpperWarning";
166dd1c4a9cSSzymon Dompke     }
167dd1c4a9cSSzymon Dompke 
168dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
169dd1c4a9cSSzymon Dompke     {
170dd1c4a9cSSzymon Dompke         return "LowerWarning";
171dd1c4a9cSSzymon Dompke     }
172dd1c4a9cSSzymon Dompke 
173dd1c4a9cSSzymon Dompke     return "";
174dd1c4a9cSSzymon Dompke }
175dd1c4a9cSSzymon Dompke 
176dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue)
177dd1c4a9cSSzymon Dompke {
178dd1c4a9cSSzymon Dompke     if (redfishValue == "Either")
179dd1c4a9cSSzymon Dompke     {
180dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
181dd1c4a9cSSzymon Dompke     }
182dd1c4a9cSSzymon Dompke 
183dd1c4a9cSSzymon Dompke     if (redfishValue == "Decreasing")
184dd1c4a9cSSzymon Dompke     {
185dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
186dd1c4a9cSSzymon Dompke     }
187dd1c4a9cSSzymon Dompke 
188dd1c4a9cSSzymon Dompke     if (redfishValue == "Increasing")
189dd1c4a9cSSzymon Dompke     {
190dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
191dd1c4a9cSSzymon Dompke     }
192dd1c4a9cSSzymon Dompke 
193dd1c4a9cSSzymon Dompke     return "";
194dd1c4a9cSSzymon Dompke }
195dd1c4a9cSSzymon Dompke 
196dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation
197dd1c4a9cSSzymon Dompke     toRedfishActivation(std::string_view dbusValue)
198dd1c4a9cSSzymon Dompke {
199dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
200dd1c4a9cSSzymon Dompke     {
201dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Either;
202dd1c4a9cSSzymon Dompke     }
203dd1c4a9cSSzymon Dompke 
204dd1c4a9cSSzymon Dompke     if (dbusValue ==
205dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
206dd1c4a9cSSzymon Dompke     {
207dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Decreasing;
208dd1c4a9cSSzymon Dompke     }
209dd1c4a9cSSzymon Dompke 
210dd1c4a9cSSzymon Dompke     if (dbusValue ==
211dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
212dd1c4a9cSSzymon Dompke     {
213dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Increasing;
214dd1c4a9cSSzymon Dompke     }
215dd1c4a9cSSzymon Dompke 
216dd1c4a9cSSzymon Dompke     return triggers::ThresholdActivation::Invalid;
217dd1c4a9cSSzymon Dompke }
218dd1c4a9cSSzymon Dompke 
219dd1c4a9cSSzymon Dompke enum class MetricType
220dd1c4a9cSSzymon Dompke {
221dd1c4a9cSSzymon Dompke     Discrete,
222dd1c4a9cSSzymon Dompke     Numeric
223dd1c4a9cSSzymon Dompke };
224dd1c4a9cSSzymon Dompke 
225dd1c4a9cSSzymon Dompke enum class DiscreteCondition
226dd1c4a9cSSzymon Dompke {
227dd1c4a9cSSzymon Dompke     Specified,
228dd1c4a9cSSzymon Dompke     Changed
229dd1c4a9cSSzymon Dompke };
230dd1c4a9cSSzymon Dompke 
231dd1c4a9cSSzymon Dompke struct Context
232dd1c4a9cSSzymon Dompke {
233dd1c4a9cSSzymon Dompke     std::string id;
234dd1c4a9cSSzymon Dompke     std::string name;
235dd1c4a9cSSzymon Dompke     std::vector<std::string> actions;
236dd1c4a9cSSzymon Dompke     std::vector<std::pair<sdbusplus::message::object_path, std::string>>
237dd1c4a9cSSzymon Dompke         sensors;
238dd1c4a9cSSzymon Dompke     std::vector<sdbusplus::message::object_path> reports;
239dd1c4a9cSSzymon Dompke     TriggerThresholdParams thresholds;
240dd1c4a9cSSzymon Dompke 
241dd1c4a9cSSzymon Dompke     std::optional<DiscreteCondition> discreteCondition;
242dd1c4a9cSSzymon Dompke     std::optional<MetricType> metricType;
243dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> metricProperties;
244dd1c4a9cSSzymon Dompke };
245dd1c4a9cSSzymon Dompke 
246dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path>
247dd1c4a9cSSzymon Dompke     getReportPathFromReportDefinitionUri(const std::string& uri)
248dd1c4a9cSSzymon Dompke {
249dd1c4a9cSSzymon Dompke     boost::urls::result<boost::urls::url_view> parsed =
250dd1c4a9cSSzymon Dompke         boost::urls::parse_relative_ref(uri);
251dd1c4a9cSSzymon Dompke 
252dd1c4a9cSSzymon Dompke     if (!parsed)
2531b7e696bSLukasz Kazmierczak     {
2541b7e696bSLukasz Kazmierczak         return std::nullopt;
2551b7e696bSLukasz Kazmierczak     }
2561b7e696bSLukasz Kazmierczak 
257dd1c4a9cSSzymon Dompke     std::string id;
258dd1c4a9cSSzymon Dompke     if (!crow::utility::readUrlSegments(
259dd1c4a9cSSzymon Dompke             *parsed, "redfish", "v1", "TelemetryService",
260dd1c4a9cSSzymon Dompke             "MetricReportDefinitions", std::ref(id)))
261dd1c4a9cSSzymon Dompke     {
262dd1c4a9cSSzymon Dompke         return std::nullopt;
2631b7e696bSLukasz Kazmierczak     }
2641b7e696bSLukasz Kazmierczak 
265dd1c4a9cSSzymon Dompke     return sdbusplus::message::object_path(
266dd1c4a9cSSzymon Dompke                "/xyz/openbmc_project/Telemetry/Reports") /
267dd1c4a9cSSzymon Dompke            "TelemetryService" / id;
268dd1c4a9cSSzymon Dompke }
269dd1c4a9cSSzymon Dompke 
270dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType)
271dd1c4a9cSSzymon Dompke {
272dd1c4a9cSSzymon Dompke     if (metricType == "Discrete")
273dd1c4a9cSSzymon Dompke     {
274dd1c4a9cSSzymon Dompke         return MetricType::Discrete;
275dd1c4a9cSSzymon Dompke     }
276dd1c4a9cSSzymon Dompke     if (metricType == "Numeric")
277dd1c4a9cSSzymon Dompke     {
278dd1c4a9cSSzymon Dompke         return MetricType::Numeric;
279dd1c4a9cSSzymon Dompke     }
280dd1c4a9cSSzymon Dompke     return std::nullopt;
281dd1c4a9cSSzymon Dompke }
282dd1c4a9cSSzymon Dompke 
283dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition>
284dd1c4a9cSSzymon Dompke     getDiscreteCondition(const std::string& discreteTriggerCondition)
285dd1c4a9cSSzymon Dompke {
286dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Specified")
287dd1c4a9cSSzymon Dompke     {
288dd1c4a9cSSzymon Dompke         return DiscreteCondition::Specified;
289dd1c4a9cSSzymon Dompke     }
290dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Changed")
291dd1c4a9cSSzymon Dompke     {
292dd1c4a9cSSzymon Dompke         return DiscreteCondition::Changed;
293dd1c4a9cSSzymon Dompke     }
294dd1c4a9cSSzymon Dompke     return std::nullopt;
295dd1c4a9cSSzymon Dompke }
296dd1c4a9cSSzymon Dompke 
297dd1c4a9cSSzymon Dompke inline bool parseNumericThresholds(crow::Response& res,
298dd1c4a9cSSzymon Dompke                                    nlohmann::json& numericThresholds,
299dd1c4a9cSSzymon Dompke                                    Context& ctx)
300dd1c4a9cSSzymon Dompke {
301dd1c4a9cSSzymon Dompke     nlohmann::json::object_t* obj =
302dd1c4a9cSSzymon Dompke         numericThresholds.get_ptr<nlohmann::json::object_t*>();
303dd1c4a9cSSzymon Dompke     if (obj == nullptr)
304dd1c4a9cSSzymon Dompke     {
305dd1c4a9cSSzymon Dompke         messages::propertyValueTypeError(res, numericThresholds.dump(),
306dd1c4a9cSSzymon Dompke                                          "NumericThresholds");
307dd1c4a9cSSzymon Dompke         return false;
308dd1c4a9cSSzymon Dompke     }
309dd1c4a9cSSzymon Dompke 
310dd1c4a9cSSzymon Dompke     std::vector<NumericThresholdParams> parsedParams;
311dd1c4a9cSSzymon Dompke     parsedParams.reserve(numericThresholds.size());
312dd1c4a9cSSzymon Dompke 
313dd1c4a9cSSzymon Dompke     for (auto& key : *obj)
314dd1c4a9cSSzymon Dompke     {
315dd1c4a9cSSzymon Dompke         std::string dbusThresholdName = toDbusThresholdName(key.first);
316dd1c4a9cSSzymon Dompke         if (dbusThresholdName.empty())
317dd1c4a9cSSzymon Dompke         {
318dd1c4a9cSSzymon Dompke             messages::propertyUnknown(res, key.first);
319dd1c4a9cSSzymon Dompke             return false;
320dd1c4a9cSSzymon Dompke         }
321dd1c4a9cSSzymon Dompke 
322dd1c4a9cSSzymon Dompke         double reading = 0.0;
323dd1c4a9cSSzymon Dompke         std::string activation;
324dd1c4a9cSSzymon Dompke         std::string dwellTimeStr;
325dd1c4a9cSSzymon Dompke 
326dd1c4a9cSSzymon Dompke         if (!json_util::readJson(key.second, res, "Reading", reading,
327dd1c4a9cSSzymon Dompke                                  "Activation", activation, "DwellTime",
328dd1c4a9cSSzymon Dompke                                  dwellTimeStr))
329dd1c4a9cSSzymon Dompke         {
330dd1c4a9cSSzymon Dompke             return false;
331dd1c4a9cSSzymon Dompke         }
332dd1c4a9cSSzymon Dompke 
333dd1c4a9cSSzymon Dompke         std::string dbusActivation = toDbusActivation(activation);
334dd1c4a9cSSzymon Dompke 
335dd1c4a9cSSzymon Dompke         if (dbusActivation.empty())
336dd1c4a9cSSzymon Dompke         {
337dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "Activation", activation);
338dd1c4a9cSSzymon Dompke             return false;
339dd1c4a9cSSzymon Dompke         }
340dd1c4a9cSSzymon Dompke 
341dd1c4a9cSSzymon Dompke         std::optional<std::chrono::milliseconds> dwellTime =
342dd1c4a9cSSzymon Dompke             time_utils::fromDurationString(dwellTimeStr);
343dd1c4a9cSSzymon Dompke         if (!dwellTime)
344dd1c4a9cSSzymon Dompke         {
345dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
346dd1c4a9cSSzymon Dompke             return false;
347dd1c4a9cSSzymon Dompke         }
348dd1c4a9cSSzymon Dompke 
349dd1c4a9cSSzymon Dompke         parsedParams.emplace_back(dbusThresholdName,
350dd1c4a9cSSzymon Dompke                                   static_cast<uint64_t>(dwellTime->count()),
351dd1c4a9cSSzymon Dompke                                   dbusActivation, reading);
352dd1c4a9cSSzymon Dompke     }
353dd1c4a9cSSzymon Dompke 
354dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
355dd1c4a9cSSzymon Dompke     return true;
356dd1c4a9cSSzymon Dompke }
357dd1c4a9cSSzymon Dompke 
358dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers(
359dd1c4a9cSSzymon Dompke     crow::Response& res,
360dd1c4a9cSSzymon Dompke     std::optional<std::vector<nlohmann::json>>& discreteTriggers, Context& ctx)
361dd1c4a9cSSzymon Dompke {
362dd1c4a9cSSzymon Dompke     std::vector<DiscreteThresholdParams> parsedParams;
363dd1c4a9cSSzymon Dompke     if (!discreteTriggers)
364dd1c4a9cSSzymon Dompke     {
365dd1c4a9cSSzymon Dompke         ctx.thresholds = std::move(parsedParams);
366dd1c4a9cSSzymon Dompke         return true;
367dd1c4a9cSSzymon Dompke     }
368dd1c4a9cSSzymon Dompke 
369dd1c4a9cSSzymon Dompke     parsedParams.reserve(discreteTriggers->size());
370dd1c4a9cSSzymon Dompke     for (nlohmann::json& thresholdInfo : *discreteTriggers)
371dd1c4a9cSSzymon Dompke     {
372dd1c4a9cSSzymon Dompke         std::optional<std::string> name = "";
373dd1c4a9cSSzymon Dompke         std::string value;
374dd1c4a9cSSzymon Dompke         std::string dwellTimeStr;
375dd1c4a9cSSzymon Dompke         std::string severity;
376dd1c4a9cSSzymon Dompke 
377dd1c4a9cSSzymon Dompke         if (!json_util::readJson(thresholdInfo, res, "Name", name, "Value",
378dd1c4a9cSSzymon Dompke                                  value, "DwellTime", dwellTimeStr, "Severity",
379dd1c4a9cSSzymon Dompke                                  severity))
380dd1c4a9cSSzymon Dompke         {
381dd1c4a9cSSzymon Dompke             return false;
382dd1c4a9cSSzymon Dompke         }
383dd1c4a9cSSzymon Dompke 
384dd1c4a9cSSzymon Dompke         std::optional<std::chrono::milliseconds> dwellTime =
385dd1c4a9cSSzymon Dompke             time_utils::fromDurationString(dwellTimeStr);
386dd1c4a9cSSzymon Dompke         if (!dwellTime)
387dd1c4a9cSSzymon Dompke         {
388dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
389dd1c4a9cSSzymon Dompke             return false;
390dd1c4a9cSSzymon Dompke         }
391dd1c4a9cSSzymon Dompke 
392dd1c4a9cSSzymon Dompke         std::string dbusSeverity = toDbusSeverity(severity);
393dd1c4a9cSSzymon Dompke         if (dbusSeverity.empty())
394dd1c4a9cSSzymon Dompke         {
395dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "Severity", severity);
396dd1c4a9cSSzymon Dompke             return false;
397dd1c4a9cSSzymon Dompke         }
398dd1c4a9cSSzymon Dompke 
399dd1c4a9cSSzymon Dompke         parsedParams.emplace_back(*name, dbusSeverity,
400dd1c4a9cSSzymon Dompke                                   static_cast<uint64_t>(dwellTime->count()),
401dd1c4a9cSSzymon Dompke                                   value);
402dd1c4a9cSSzymon Dompke     }
403dd1c4a9cSSzymon Dompke 
404dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
405dd1c4a9cSSzymon Dompke     return true;
406dd1c4a9cSSzymon Dompke }
407dd1c4a9cSSzymon Dompke 
408dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds(
409dd1c4a9cSSzymon Dompke     crow::Response& res,
410dd1c4a9cSSzymon Dompke     std::optional<std::vector<nlohmann::json>>& discreteTriggers,
411dd1c4a9cSSzymon Dompke     std::optional<nlohmann::json>& numericThresholds, Context& ctx)
412dd1c4a9cSSzymon Dompke {
413dd1c4a9cSSzymon Dompke     if (discreteTriggers && numericThresholds)
414dd1c4a9cSSzymon Dompke     {
415dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "DiscreteTriggers",
416dd1c4a9cSSzymon Dompke                                         "NumericThresholds");
417dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "NumericThresholds",
418dd1c4a9cSSzymon Dompke                                         "DiscreteTriggers");
419dd1c4a9cSSzymon Dompke         return false;
420dd1c4a9cSSzymon Dompke     }
421dd1c4a9cSSzymon Dompke 
422dd1c4a9cSSzymon Dompke     if (ctx.discreteCondition)
423dd1c4a9cSSzymon Dompke     {
424dd1c4a9cSSzymon Dompke         if (numericThresholds)
425dd1c4a9cSSzymon Dompke         {
426dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggerCondition",
427dd1c4a9cSSzymon Dompke                                             "NumericThresholds");
428dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
429dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
430dd1c4a9cSSzymon Dompke             return false;
431dd1c4a9cSSzymon Dompke         }
432dd1c4a9cSSzymon Dompke     }
433dd1c4a9cSSzymon Dompke 
434dd1c4a9cSSzymon Dompke     if (ctx.metricType)
435dd1c4a9cSSzymon Dompke     {
436dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Discrete && numericThresholds)
437dd1c4a9cSSzymon Dompke         {
438dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
439dd1c4a9cSSzymon Dompke                                             "MetricType");
440dd1c4a9cSSzymon Dompke             return false;
441dd1c4a9cSSzymon Dompke         }
442dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
443dd1c4a9cSSzymon Dompke         {
444dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
445dd1c4a9cSSzymon Dompke                                             "MetricType");
446dd1c4a9cSSzymon Dompke             return false;
447dd1c4a9cSSzymon Dompke         }
448dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
449dd1c4a9cSSzymon Dompke         {
450dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
451dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
452dd1c4a9cSSzymon Dompke             return false;
453dd1c4a9cSSzymon Dompke         }
454dd1c4a9cSSzymon Dompke     }
455dd1c4a9cSSzymon Dompke 
456dd1c4a9cSSzymon Dompke     if (discreteTriggers || ctx.discreteCondition ||
457dd1c4a9cSSzymon Dompke         (ctx.metricType && *ctx.metricType == MetricType::Discrete))
458dd1c4a9cSSzymon Dompke     {
459dd1c4a9cSSzymon Dompke         if (ctx.discreteCondition)
460dd1c4a9cSSzymon Dompke         {
461dd1c4a9cSSzymon Dompke             if (*ctx.discreteCondition == DiscreteCondition::Specified &&
462dd1c4a9cSSzymon Dompke                 !discreteTriggers)
463dd1c4a9cSSzymon Dompke             {
464dd1c4a9cSSzymon Dompke                 messages::createFailedMissingReqProperties(res,
465dd1c4a9cSSzymon Dompke                                                            "DiscreteTriggers");
466dd1c4a9cSSzymon Dompke                 return false;
467dd1c4a9cSSzymon Dompke             }
468dd1c4a9cSSzymon Dompke             if (discreteTriggers &&
469dd1c4a9cSSzymon Dompke                 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
470dd1c4a9cSSzymon Dompke                   discreteTriggers->empty()) ||
471dd1c4a9cSSzymon Dompke                  (*ctx.discreteCondition == DiscreteCondition::Changed &&
472dd1c4a9cSSzymon Dompke                   !discreteTriggers->empty())))
473dd1c4a9cSSzymon Dompke             {
474dd1c4a9cSSzymon Dompke                 messages::propertyValueConflict(res, "DiscreteTriggers",
475dd1c4a9cSSzymon Dompke                                                 "DiscreteTriggerCondition");
476dd1c4a9cSSzymon Dompke                 return false;
477dd1c4a9cSSzymon Dompke             }
478dd1c4a9cSSzymon Dompke         }
479dd1c4a9cSSzymon Dompke         if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
480dd1c4a9cSSzymon Dompke         {
481dd1c4a9cSSzymon Dompke             return false;
482dd1c4a9cSSzymon Dompke         }
483dd1c4a9cSSzymon Dompke     }
484dd1c4a9cSSzymon Dompke     else if (numericThresholds)
485dd1c4a9cSSzymon Dompke     {
486dd1c4a9cSSzymon Dompke         if (!parseNumericThresholds(res, *numericThresholds, ctx))
487dd1c4a9cSSzymon Dompke         {
488dd1c4a9cSSzymon Dompke             return false;
489dd1c4a9cSSzymon Dompke         }
490dd1c4a9cSSzymon Dompke     }
491dd1c4a9cSSzymon Dompke     else
492dd1c4a9cSSzymon Dompke     {
493dd1c4a9cSSzymon Dompke         messages::createFailedMissingReqProperties(
494dd1c4a9cSSzymon Dompke             res, "'DiscreteTriggers', 'NumericThresholds', "
495dd1c4a9cSSzymon Dompke                  "'DiscreteTriggerCondition' or 'MetricType'");
496dd1c4a9cSSzymon Dompke         return false;
497dd1c4a9cSSzymon Dompke     }
498dd1c4a9cSSzymon Dompke     return true;
499dd1c4a9cSSzymon Dompke }
500dd1c4a9cSSzymon Dompke 
501dd1c4a9cSSzymon Dompke inline bool parseLinks(crow::Response& res, nlohmann::json& links, Context& ctx)
502dd1c4a9cSSzymon Dompke {
503dd1c4a9cSSzymon Dompke     if (links.empty())
504dd1c4a9cSSzymon Dompke     {
505dd1c4a9cSSzymon Dompke         return true;
506dd1c4a9cSSzymon Dompke     }
507dd1c4a9cSSzymon Dompke 
508dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> metricReportDefinitions;
509dd1c4a9cSSzymon Dompke     if (!json_util::readJson(links, res, "MetricReportDefinitions",
510dd1c4a9cSSzymon Dompke                              metricReportDefinitions))
511dd1c4a9cSSzymon Dompke     {
512dd1c4a9cSSzymon Dompke         return false;
513dd1c4a9cSSzymon Dompke     }
514dd1c4a9cSSzymon Dompke 
515dd1c4a9cSSzymon Dompke     if (metricReportDefinitions)
516dd1c4a9cSSzymon Dompke     {
517dd1c4a9cSSzymon Dompke         ctx.reports.reserve(metricReportDefinitions->size());
518dd1c4a9cSSzymon Dompke         for (std::string& reportDefinionUri : *metricReportDefinitions)
519dd1c4a9cSSzymon Dompke         {
520dd1c4a9cSSzymon Dompke             std::optional<sdbusplus::message::object_path> reportPath =
521dd1c4a9cSSzymon Dompke                 getReportPathFromReportDefinitionUri(reportDefinionUri);
522dd1c4a9cSSzymon Dompke             if (!reportPath)
523dd1c4a9cSSzymon Dompke             {
524dd1c4a9cSSzymon Dompke                 messages::propertyValueIncorrect(res, "MetricReportDefinitions",
525dd1c4a9cSSzymon Dompke                                                  reportDefinionUri);
526dd1c4a9cSSzymon Dompke                 return false;
527dd1c4a9cSSzymon Dompke             }
528dd1c4a9cSSzymon Dompke             ctx.reports.emplace_back(*reportPath);
529dd1c4a9cSSzymon Dompke         }
530dd1c4a9cSSzymon Dompke     }
531dd1c4a9cSSzymon Dompke     return true;
532dd1c4a9cSSzymon Dompke }
533dd1c4a9cSSzymon Dompke 
534dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx)
535dd1c4a9cSSzymon Dompke {
536dd1c4a9cSSzymon Dompke     if (!ctx.metricProperties)
537dd1c4a9cSSzymon Dompke     {
538dd1c4a9cSSzymon Dompke         return true;
539dd1c4a9cSSzymon Dompke     }
540dd1c4a9cSSzymon Dompke 
541dd1c4a9cSSzymon Dompke     ctx.sensors.reserve(ctx.metricProperties->size());
542dd1c4a9cSSzymon Dompke 
543dd1c4a9cSSzymon Dompke     size_t uriIdx = 0;
544dd1c4a9cSSzymon Dompke     for (const std::string& uriStr : *ctx.metricProperties)
545dd1c4a9cSSzymon Dompke     {
546dd1c4a9cSSzymon Dompke         boost::urls::result<boost::urls::url_view> uri =
547dd1c4a9cSSzymon Dompke             boost::urls::parse_relative_ref(uriStr);
548dd1c4a9cSSzymon Dompke         if (!uri)
549dd1c4a9cSSzymon Dompke         {
550dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
551dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
552dd1c4a9cSSzymon Dompke             return false;
553dd1c4a9cSSzymon Dompke         }
554dd1c4a9cSSzymon Dompke         std::string chassisName;
555dd1c4a9cSSzymon Dompke         std::string sensorName;
556dd1c4a9cSSzymon Dompke         if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
557dd1c4a9cSSzymon Dompke                                             std::ref(chassisName), "Sensors",
558dd1c4a9cSSzymon Dompke                                             std::ref(sensorName)))
559dd1c4a9cSSzymon Dompke         {
560dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
561dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
562dd1c4a9cSSzymon Dompke             return false;
563dd1c4a9cSSzymon Dompke         }
564dd1c4a9cSSzymon Dompke 
565dd1c4a9cSSzymon Dompke         std::pair<std::string, std::string> split =
566dd1c4a9cSSzymon Dompke             splitSensorNameAndType(sensorName);
567dd1c4a9cSSzymon Dompke         if (split.first.empty() || split.second.empty())
568dd1c4a9cSSzymon Dompke         {
569dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
570dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
571dd1c4a9cSSzymon Dompke             return false;
572dd1c4a9cSSzymon Dompke         }
573dd1c4a9cSSzymon Dompke 
574dd1c4a9cSSzymon Dompke         std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
575dd1c4a9cSSzymon Dompke                                  '/' + split.second;
576dd1c4a9cSSzymon Dompke 
577dd1c4a9cSSzymon Dompke         ctx.sensors.emplace_back(sensorPath, uriStr);
578dd1c4a9cSSzymon Dompke         uriIdx++;
579dd1c4a9cSSzymon Dompke     }
580dd1c4a9cSSzymon Dompke     return true;
581dd1c4a9cSSzymon Dompke }
582dd1c4a9cSSzymon Dompke 
583dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res,
584dd1c4a9cSSzymon Dompke                                    const crow::Request& req, Context& ctx)
585dd1c4a9cSSzymon Dompke {
586dd1c4a9cSSzymon Dompke     std::optional<std::string> id = "";
587dd1c4a9cSSzymon Dompke     std::optional<std::string> name = "";
588dd1c4a9cSSzymon Dompke     std::optional<std::string> metricType;
589dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> triggerActions;
590dd1c4a9cSSzymon Dompke     std::optional<std::string> discreteTriggerCondition;
591dd1c4a9cSSzymon Dompke     std::optional<std::vector<nlohmann::json>> discreteTriggers;
592dd1c4a9cSSzymon Dompke     std::optional<nlohmann::json> numericThresholds;
593dd1c4a9cSSzymon Dompke     std::optional<nlohmann::json> links;
594dd1c4a9cSSzymon Dompke     if (!json_util::readJsonPatch(
595dd1c4a9cSSzymon Dompke             req, res, "Id", id, "Name", name, "MetricType", metricType,
596dd1c4a9cSSzymon Dompke             "TriggerActions", triggerActions, "DiscreteTriggerCondition",
597dd1c4a9cSSzymon Dompke             discreteTriggerCondition, "DiscreteTriggers", discreteTriggers,
598dd1c4a9cSSzymon Dompke             "NumericThresholds", numericThresholds, "MetricProperties",
599dd1c4a9cSSzymon Dompke             ctx.metricProperties, "Links", links))
600dd1c4a9cSSzymon Dompke     {
601dd1c4a9cSSzymon Dompke         return false;
602dd1c4a9cSSzymon Dompke     }
603dd1c4a9cSSzymon Dompke 
604dd1c4a9cSSzymon Dompke     ctx.id = *id;
605dd1c4a9cSSzymon Dompke     ctx.name = *name;
606dd1c4a9cSSzymon Dompke 
607dd1c4a9cSSzymon Dompke     if (metricType)
608dd1c4a9cSSzymon Dompke     {
609*d5736ef2SEd Tanous         ctx.metricType = getMetricType(*metricType);
610*d5736ef2SEd Tanous         if (!ctx.metricType)
611dd1c4a9cSSzymon Dompke         {
612dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricType", *metricType);
613dd1c4a9cSSzymon Dompke             return false;
614dd1c4a9cSSzymon Dompke         }
615dd1c4a9cSSzymon Dompke     }
616dd1c4a9cSSzymon Dompke 
617dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition)
618dd1c4a9cSSzymon Dompke     {
619*d5736ef2SEd Tanous         ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
620*d5736ef2SEd Tanous         if (!ctx.discreteCondition)
621dd1c4a9cSSzymon Dompke         {
622dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
623dd1c4a9cSSzymon Dompke                                              *discreteTriggerCondition);
624dd1c4a9cSSzymon Dompke             return false;
625dd1c4a9cSSzymon Dompke         }
626dd1c4a9cSSzymon Dompke     }
627dd1c4a9cSSzymon Dompke 
628dd1c4a9cSSzymon Dompke     if (triggerActions)
629dd1c4a9cSSzymon Dompke     {
630dd1c4a9cSSzymon Dompke         ctx.actions.reserve(triggerActions->size());
631dd1c4a9cSSzymon Dompke         for (const std::string& action : *triggerActions)
632dd1c4a9cSSzymon Dompke         {
633dd1c4a9cSSzymon Dompke             std::string dbusAction = toDbusTriggerAction(action);
634dd1c4a9cSSzymon Dompke 
635dd1c4a9cSSzymon Dompke             if (dbusAction.empty())
636dd1c4a9cSSzymon Dompke             {
637dd1c4a9cSSzymon Dompke                 messages::propertyValueNotInList(res, action, "TriggerActions");
638dd1c4a9cSSzymon Dompke                 return false;
639dd1c4a9cSSzymon Dompke             }
640dd1c4a9cSSzymon Dompke 
641dd1c4a9cSSzymon Dompke             ctx.actions.emplace_back(dbusAction);
642dd1c4a9cSSzymon Dompke         }
643dd1c4a9cSSzymon Dompke     }
644dd1c4a9cSSzymon Dompke     if (!parseMetricProperties(res, ctx))
645dd1c4a9cSSzymon Dompke     {
646dd1c4a9cSSzymon Dompke         return false;
647dd1c4a9cSSzymon Dompke     }
648dd1c4a9cSSzymon Dompke 
649dd1c4a9cSSzymon Dompke     if (!parseTriggerThresholds(res, discreteTriggers, numericThresholds, ctx))
650dd1c4a9cSSzymon Dompke     {
651dd1c4a9cSSzymon Dompke         return false;
652dd1c4a9cSSzymon Dompke     }
653dd1c4a9cSSzymon Dompke 
654dd1c4a9cSSzymon Dompke     if (links)
655dd1c4a9cSSzymon Dompke     {
656dd1c4a9cSSzymon Dompke         if (!parseLinks(res, *links, ctx))
657dd1c4a9cSSzymon Dompke         {
658dd1c4a9cSSzymon Dompke             return false;
659dd1c4a9cSSzymon Dompke         }
660dd1c4a9cSSzymon Dompke     }
661dd1c4a9cSSzymon Dompke     return true;
662dd1c4a9cSSzymon Dompke }
663dd1c4a9cSSzymon Dompke 
664dd1c4a9cSSzymon Dompke inline void afterCreateTrigger(
665dd1c4a9cSSzymon Dompke     const boost::system::error_code& ec, const std::string& dbusPath,
666dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
667dd1c4a9cSSzymon Dompke {
668dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::file_exists)
669dd1c4a9cSSzymon Dompke     {
670dd1c4a9cSSzymon Dompke         messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
671dd1c4a9cSSzymon Dompke         return;
672dd1c4a9cSSzymon Dompke     }
673dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::too_many_files_open)
674dd1c4a9cSSzymon Dompke     {
675dd1c4a9cSSzymon Dompke         messages::createLimitReachedForResource(asyncResp->res);
676dd1c4a9cSSzymon Dompke         return;
677dd1c4a9cSSzymon Dompke     }
678dd1c4a9cSSzymon Dompke     if (ec)
679dd1c4a9cSSzymon Dompke     {
680dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
681dd1c4a9cSSzymon Dompke         BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
682dd1c4a9cSSzymon Dompke         return;
683dd1c4a9cSSzymon Dompke     }
684dd1c4a9cSSzymon Dompke 
685dd1c4a9cSSzymon Dompke     const std::optional<std::string>& triggerId =
686dd1c4a9cSSzymon Dompke         getTriggerIdFromDbusPath(dbusPath);
687dd1c4a9cSSzymon Dompke     if (!triggerId)
688dd1c4a9cSSzymon Dompke     {
689dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
690dd1c4a9cSSzymon Dompke         BMCWEB_LOG_ERROR << "Unknown data returned by "
691dd1c4a9cSSzymon Dompke                             "AddTrigger DBus method";
692dd1c4a9cSSzymon Dompke         return;
693dd1c4a9cSSzymon Dompke     }
694dd1c4a9cSSzymon Dompke 
695dd1c4a9cSSzymon Dompke     messages::created(asyncResp->res);
696dd1c4a9cSSzymon Dompke     boost::urls::url locationUrl = boost::urls::format(
697dd1c4a9cSSzymon Dompke         "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
698dd1c4a9cSSzymon Dompke     asyncResp->res.addHeader("Location", locationUrl.buffer());
699dd1c4a9cSSzymon Dompke }
700dd1c4a9cSSzymon Dompke 
701dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t>
702dd1c4a9cSSzymon Dompke     getTriggerActions(const std::vector<std::string>& dbusActions)
703dd1c4a9cSSzymon Dompke {
704dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggerActions;
705dd1c4a9cSSzymon Dompke     for (const std::string& dbusAction : dbusActions)
706dd1c4a9cSSzymon Dompke     {
707dd1c4a9cSSzymon Dompke         triggers::TriggerActionEnum redfishAction =
708dd1c4a9cSSzymon Dompke             toRedfishTriggerAction(dbusAction);
709dd1c4a9cSSzymon Dompke 
710dd1c4a9cSSzymon Dompke         if (redfishAction == triggers::TriggerActionEnum::Invalid)
711dd1c4a9cSSzymon Dompke         {
712dd1c4a9cSSzymon Dompke             return std::nullopt;
713dd1c4a9cSSzymon Dompke         }
714dd1c4a9cSSzymon Dompke 
715dd1c4a9cSSzymon Dompke         triggerActions.emplace_back(redfishAction);
716dd1c4a9cSSzymon Dompke     }
717dd1c4a9cSSzymon Dompke 
718dd1c4a9cSSzymon Dompke     return triggerActions;
7191b7e696bSLukasz Kazmierczak }
7201b7e696bSLukasz Kazmierczak 
7213f215c92SSzymon Dompke inline std::optional<nlohmann::json::array_t>
7221b7e696bSLukasz Kazmierczak     getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
7231b7e696bSLukasz Kazmierczak {
724dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggers;
7251b7e696bSLukasz Kazmierczak     const std::vector<DiscreteThresholdParams>* discreteParams =
7261b7e696bSLukasz Kazmierczak         std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
7271b7e696bSLukasz Kazmierczak 
728e662eae8SEd Tanous     if (discreteParams == nullptr)
7291b7e696bSLukasz Kazmierczak     {
7301b7e696bSLukasz Kazmierczak         return std::nullopt;
7311b7e696bSLukasz Kazmierczak     }
7321b7e696bSLukasz Kazmierczak 
7331b7e696bSLukasz Kazmierczak     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 
7531b7e696bSLukasz Kazmierczak inline std::optional<nlohmann::json>
7541b7e696bSLukasz Kazmierczak     getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
7551b7e696bSLukasz Kazmierczak {
756dd1c4a9cSSzymon Dompke     nlohmann::json::object_t thresholds;
7571b7e696bSLukasz Kazmierczak     const std::vector<NumericThresholdParams>* numericParams =
7581b7e696bSLukasz Kazmierczak         std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
7591b7e696bSLukasz Kazmierczak 
760e662eae8SEd Tanous     if (numericParams == nullptr)
7611b7e696bSLukasz Kazmierczak     {
7621b7e696bSLukasz Kazmierczak         return std::nullopt;
7631b7e696bSLukasz Kazmierczak     }
7641b7e696bSLukasz Kazmierczak 
7651b7e696bSLukasz Kazmierczak     for (const auto& [type, dwellTime, activation, reading] : *numericParams)
7661b7e696bSLukasz Kazmierczak     {
7671b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7681b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7691b7e696bSLukasz Kazmierczak 
7701b7e696bSLukasz Kazmierczak         if (!duration)
7711b7e696bSLukasz Kazmierczak         {
7721b7e696bSLukasz Kazmierczak             return std::nullopt;
7731b7e696bSLukasz Kazmierczak         }
774dd1c4a9cSSzymon Dompke         nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
7751476687dSEd Tanous         threshold["Reading"] = reading;
776dd1c4a9cSSzymon Dompke         threshold["Activation"] = toRedfishActivation(activation);
7771476687dSEd Tanous         threshold["DwellTime"] = *duration;
7781b7e696bSLukasz Kazmierczak     }
7791b7e696bSLukasz Kazmierczak 
780dd1c4a9cSSzymon Dompke     return thresholds;
7811b7e696bSLukasz Kazmierczak }
7821b7e696bSLukasz Kazmierczak 
7833f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions(
7843f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>& reportPaths)
7851b7e696bSLukasz Kazmierczak {
7861b7e696bSLukasz Kazmierczak     nlohmann::json reports = nlohmann::json::array();
7873f215c92SSzymon Dompke 
7883f215c92SSzymon Dompke     for (const sdbusplus::message::object_path& path : reportPaths)
7891b7e696bSLukasz Kazmierczak     {
7903f215c92SSzymon Dompke         std::string reportId = path.filename();
7913f215c92SSzymon Dompke         if (reportId.empty())
7923f215c92SSzymon Dompke         {
7933f215c92SSzymon Dompke             {
7943f215c92SSzymon Dompke                 BMCWEB_LOG_ERROR << "Property Reports contains invalid value: "
7953f215c92SSzymon Dompke                                  << path.str;
7963f215c92SSzymon Dompke                 return std::nullopt;
7973f215c92SSzymon Dompke             }
7983f215c92SSzymon Dompke         }
7993f215c92SSzymon Dompke 
8001476687dSEd Tanous         nlohmann::json::object_t report;
801ef4c65b7SEd Tanous         report["@odata.id"] = boost::urls::format(
802ef4c65b7SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
803ef4c65b7SEd Tanous             reportId);
804b2ba3072SPatrick Williams         reports.emplace_back(std::move(report));
8051b7e696bSLukasz Kazmierczak     }
8061b7e696bSLukasz Kazmierczak 
8073f215c92SSzymon Dompke     return {std::move(reports)};
8081b7e696bSLukasz Kazmierczak }
8091b7e696bSLukasz Kazmierczak 
8101b7e696bSLukasz Kazmierczak inline std::vector<std::string>
8111b7e696bSLukasz Kazmierczak     getMetricProperties(const TriggerSensorsParams& sensors)
8121b7e696bSLukasz Kazmierczak {
8131b7e696bSLukasz Kazmierczak     std::vector<std::string> metricProperties;
8141b7e696bSLukasz Kazmierczak     metricProperties.reserve(sensors.size());
8151b7e696bSLukasz Kazmierczak     for (const auto& [_, metadata] : sensors)
8161b7e696bSLukasz Kazmierczak     {
8171b7e696bSLukasz Kazmierczak         metricProperties.emplace_back(metadata);
8181b7e696bSLukasz Kazmierczak     }
8191b7e696bSLukasz Kazmierczak 
8201b7e696bSLukasz Kazmierczak     return metricProperties;
8211b7e696bSLukasz Kazmierczak }
8221b7e696bSLukasz Kazmierczak 
8231b7e696bSLukasz Kazmierczak inline bool fillTrigger(
8241b7e696bSLukasz Kazmierczak     nlohmann::json& json, const std::string& id,
8251b7e696bSLukasz Kazmierczak     const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
8261b7e696bSLukasz Kazmierczak         properties)
8271b7e696bSLukasz Kazmierczak {
8281b7e696bSLukasz Kazmierczak     const std::string* name = nullptr;
8291b7e696bSLukasz Kazmierczak     const bool* discrete = nullptr;
8301b7e696bSLukasz Kazmierczak     const TriggerSensorsParams* sensors = nullptr;
8313f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>* reports = nullptr;
83289474494SKrzysztof Grobelny     const std::vector<std::string>* triggerActions = nullptr;
8331b7e696bSLukasz Kazmierczak     const TriggerThresholdParamsExt* thresholds = nullptr;
8341b7e696bSLukasz Kazmierczak 
83589474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
83689474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
83789474494SKrzysztof Grobelny         discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
83889474494SKrzysztof Grobelny         triggerActions, "Thresholds", thresholds);
83989474494SKrzysztof Grobelny 
84089474494SKrzysztof Grobelny     if (!success)
8411b7e696bSLukasz Kazmierczak     {
84289474494SKrzysztof Grobelny         return false;
8431b7e696bSLukasz Kazmierczak     }
8441b7e696bSLukasz Kazmierczak 
84589474494SKrzysztof Grobelny     if (triggerActions != nullptr)
84689474494SKrzysztof Grobelny     {
847dd1c4a9cSSzymon Dompke         std::optional<nlohmann::json::array_t> redfishTriggerActions =
84889474494SKrzysztof Grobelny             getTriggerActions(*triggerActions);
84989474494SKrzysztof Grobelny         if (!redfishTriggerActions)
8501b7e696bSLukasz Kazmierczak         {
8511b7e696bSLukasz Kazmierczak             BMCWEB_LOG_ERROR
85289474494SKrzysztof Grobelny                 << "Property TriggerActions is invalid in Trigger: " << id;
8531b7e696bSLukasz Kazmierczak             return false;
8541b7e696bSLukasz Kazmierczak         }
855dd1c4a9cSSzymon Dompke         json["TriggerActions"] = *redfishTriggerActions;
85689474494SKrzysztof Grobelny     }
8571b7e696bSLukasz Kazmierczak 
85889474494SKrzysztof Grobelny     if (reports != nullptr)
8593f215c92SSzymon Dompke     {
8603f215c92SSzymon Dompke         std::optional<nlohmann::json> linkedReports =
8613f215c92SSzymon Dompke             getMetricReportDefinitions(*reports);
8623f215c92SSzymon Dompke         if (!linkedReports)
8633f215c92SSzymon Dompke         {
86489474494SKrzysztof Grobelny             BMCWEB_LOG_ERROR << "Property Reports is invalid in Trigger: "
86589474494SKrzysztof Grobelny                              << id;
8663f215c92SSzymon Dompke             return false;
8673f215c92SSzymon Dompke         }
86889474494SKrzysztof Grobelny         json["Links"]["MetricReportDefinitions"] = *linkedReports;
86989474494SKrzysztof Grobelny     }
8701b7e696bSLukasz Kazmierczak 
87189474494SKrzysztof Grobelny     if (discrete != nullptr)
87289474494SKrzysztof Grobelny     {
8731b7e696bSLukasz Kazmierczak         if (*discrete)
8741b7e696bSLukasz Kazmierczak         {
8753f215c92SSzymon Dompke             std::optional<nlohmann::json::array_t> discreteTriggers =
8761b7e696bSLukasz Kazmierczak                 getDiscreteTriggers(*thresholds);
8771b7e696bSLukasz Kazmierczak 
8781b7e696bSLukasz Kazmierczak             if (!discreteTriggers)
8791b7e696bSLukasz Kazmierczak             {
88089474494SKrzysztof Grobelny                 BMCWEB_LOG_ERROR
88189474494SKrzysztof Grobelny                     << "Property Thresholds is invalid for discrete "
8821b7e696bSLukasz Kazmierczak                        "triggers in Trigger: "
8831b7e696bSLukasz Kazmierczak                     << id;
8841b7e696bSLukasz Kazmierczak                 return false;
8851b7e696bSLukasz Kazmierczak             }
8861b7e696bSLukasz Kazmierczak 
8871b7e696bSLukasz Kazmierczak             json["DiscreteTriggers"] = *discreteTriggers;
8881b7e696bSLukasz Kazmierczak             json["DiscreteTriggerCondition"] =
8891b7e696bSLukasz Kazmierczak                 discreteTriggers->empty() ? "Changed" : "Specified";
8901b7e696bSLukasz Kazmierczak             json["MetricType"] = "Discrete";
8911b7e696bSLukasz Kazmierczak         }
8921b7e696bSLukasz Kazmierczak         else
8931b7e696bSLukasz Kazmierczak         {
8941b7e696bSLukasz Kazmierczak             std::optional<nlohmann::json> numericThresholds =
8951b7e696bSLukasz Kazmierczak                 getNumericThresholds(*thresholds);
8961b7e696bSLukasz Kazmierczak 
8971b7e696bSLukasz Kazmierczak             if (!numericThresholds)
8981b7e696bSLukasz Kazmierczak             {
89989474494SKrzysztof Grobelny                 BMCWEB_LOG_ERROR
90089474494SKrzysztof Grobelny                     << "Property Thresholds is invalid for numeric "
9011b7e696bSLukasz Kazmierczak                        "thresholds in Trigger: "
9021b7e696bSLukasz Kazmierczak                     << id;
9031b7e696bSLukasz Kazmierczak                 return false;
9041b7e696bSLukasz Kazmierczak             }
9051b7e696bSLukasz Kazmierczak 
9061b7e696bSLukasz Kazmierczak             json["NumericThresholds"] = *numericThresholds;
9071b7e696bSLukasz Kazmierczak             json["MetricType"] = "Numeric";
9081b7e696bSLukasz Kazmierczak         }
90989474494SKrzysztof Grobelny     }
91089474494SKrzysztof Grobelny 
91189474494SKrzysztof Grobelny     if (name != nullptr)
91289474494SKrzysztof Grobelny     {
91389474494SKrzysztof Grobelny         json["Name"] = *name;
91489474494SKrzysztof Grobelny     }
91589474494SKrzysztof Grobelny 
91689474494SKrzysztof Grobelny     if (sensors != nullptr)
91789474494SKrzysztof Grobelny     {
91889474494SKrzysztof Grobelny         json["MetricProperties"] = getMetricProperties(*sensors);
91989474494SKrzysztof Grobelny     }
9201b7e696bSLukasz Kazmierczak 
9213f215c92SSzymon Dompke     json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
922ef4c65b7SEd Tanous     json["@odata.id"] =
923ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
9243f215c92SSzymon Dompke     json["Id"] = id;
9251b7e696bSLukasz Kazmierczak 
9261b7e696bSLukasz Kazmierczak     return true;
9271b7e696bSLukasz Kazmierczak }
9281b7e696bSLukasz Kazmierczak 
929dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost(
930dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
931dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
932dd1c4a9cSSzymon Dompke {
933dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
934dd1c4a9cSSzymon Dompke     {
935dd1c4a9cSSzymon Dompke         return;
936dd1c4a9cSSzymon Dompke     }
937dd1c4a9cSSzymon Dompke 
938dd1c4a9cSSzymon Dompke     telemetry::Context ctx;
939dd1c4a9cSSzymon Dompke     if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
940dd1c4a9cSSzymon Dompke     {
941dd1c4a9cSSzymon Dompke         return;
942dd1c4a9cSSzymon Dompke     }
943dd1c4a9cSSzymon Dompke 
944dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
945dd1c4a9cSSzymon Dompke         [asyncResp, id = ctx.id](const boost::system::error_code& ec,
946dd1c4a9cSSzymon Dompke                                  const std::string& dbusPath) {
947dd1c4a9cSSzymon Dompke         afterCreateTrigger(ec, dbusPath, asyncResp, id);
948dd1c4a9cSSzymon Dompke         },
949dd1c4a9cSSzymon Dompke         service, "/xyz/openbmc_project/Telemetry/Triggers",
950dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
951dd1c4a9cSSzymon Dompke         "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
952dd1c4a9cSSzymon Dompke         ctx.reports, ctx.thresholds);
953dd1c4a9cSSzymon Dompke }
954dd1c4a9cSSzymon Dompke 
95507148cf2SLukasz Kazmierczak } // namespace telemetry
95607148cf2SLukasz Kazmierczak 
95707148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app)
95807148cf2SLukasz Kazmierczak {
95907148cf2SLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
96007148cf2SLukasz Kazmierczak         .privileges(redfish::privileges::getTriggersCollection)
96107148cf2SLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
96245ca1b86SEd Tanous             [&app](const crow::Request& req,
96307148cf2SLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
9643ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
96545ca1b86SEd Tanous         {
96645ca1b86SEd Tanous             return;
96745ca1b86SEd Tanous         }
96807148cf2SLukasz Kazmierczak         asyncResp->res.jsonValue["@odata.type"] =
96907148cf2SLukasz Kazmierczak             "#TriggersCollection.TriggersCollection";
970ae9031f0SWilly Tu         asyncResp->res.jsonValue["@odata.id"] =
971ae9031f0SWilly Tu             "/redfish/v1/TelemetryService/Triggers";
97207148cf2SLukasz Kazmierczak         asyncResp->res.jsonValue["Name"] = "Triggers Collection";
9737a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
9747a1dbc48SGeorge Liu             telemetry::triggerInterface};
97507148cf2SLukasz Kazmierczak         collection_util::getCollectionMembers(
976ae9031f0SWilly Tu             asyncResp,
977ae9031f0SWilly Tu             boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
978ae9031f0SWilly Tu             interfaces,
97907148cf2SLukasz Kazmierczak             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
98007148cf2SLukasz Kazmierczak         });
981dd1c4a9cSSzymon Dompke 
982dd1c4a9cSSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
983dd1c4a9cSSzymon Dompke         .privileges(redfish::privileges::postTriggersCollection)
984dd1c4a9cSSzymon Dompke         .methods(boost::beast::http::verb::post)(std::bind_front(
985dd1c4a9cSSzymon Dompke             telemetry::handleTriggerCollectionPost, std::ref(app)));
98607148cf2SLukasz Kazmierczak }
98707148cf2SLukasz Kazmierczak 
9881b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app)
9891b7e696bSLukasz Kazmierczak {
9901b7e696bSLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
9911b7e696bSLukasz Kazmierczak         .privileges(redfish::privileges::getTriggers)
9921b7e696bSLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
99345ca1b86SEd Tanous             [&app](const crow::Request& req,
9941b7e696bSLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9951b7e696bSLukasz Kazmierczak                    const std::string& id) {
9963ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
99745ca1b86SEd Tanous         {
99845ca1b86SEd Tanous             return;
99945ca1b86SEd Tanous         }
100089474494SKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
100189474494SKrzysztof Grobelny             *crow::connections::systemBus, telemetry::service,
100289474494SKrzysztof Grobelny             telemetry::getDbusTriggerPath(id), telemetry::triggerInterface,
10031b7e696bSLukasz Kazmierczak             [asyncResp,
10045e7e2dc5SEd Tanous              id](const boost::system::error_code& ec,
10051b7e696bSLukasz Kazmierczak                  const std::vector<std::pair<
1006002d39b4SEd Tanous                      std::string, telemetry::TriggerGetParamsVariant>>& ret) {
10071b7e696bSLukasz Kazmierczak             if (ec.value() == EBADR ||
10081b7e696bSLukasz Kazmierczak                 ec == boost::system::errc::host_unreachable)
10091b7e696bSLukasz Kazmierczak             {
1010002d39b4SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Triggers", id);
10111b7e696bSLukasz Kazmierczak                 return;
10121b7e696bSLukasz Kazmierczak             }
10131b7e696bSLukasz Kazmierczak             if (ec)
10141b7e696bSLukasz Kazmierczak             {
10151b7e696bSLukasz Kazmierczak                 BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
10161b7e696bSLukasz Kazmierczak                 messages::internalError(asyncResp->res);
10171b7e696bSLukasz Kazmierczak                 return;
10181b7e696bSLukasz Kazmierczak             }
10191b7e696bSLukasz Kazmierczak 
1020002d39b4SEd Tanous             if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret))
10211b7e696bSLukasz Kazmierczak             {
10221b7e696bSLukasz Kazmierczak                 messages::internalError(asyncResp->res);
10231b7e696bSLukasz Kazmierczak             }
102489474494SKrzysztof Grobelny             });
10251b7e696bSLukasz Kazmierczak         });
1026163994a8SSzymon Dompke 
1027163994a8SSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1028163994a8SSzymon Dompke         .privileges(redfish::privileges::deleteTriggers)
1029163994a8SSzymon Dompke         .methods(boost::beast::http::verb::delete_)(
103045ca1b86SEd Tanous             [&app](const crow::Request& req,
1031163994a8SSzymon Dompke                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1032163994a8SSzymon Dompke                    const std::string& id) {
10333ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
103445ca1b86SEd Tanous         {
103545ca1b86SEd Tanous             return;
103645ca1b86SEd Tanous         }
1037002d39b4SEd Tanous         const std::string triggerPath = telemetry::getDbusTriggerPath(id);
1038163994a8SSzymon Dompke 
1039163994a8SSzymon Dompke         crow::connections::systemBus->async_method_call(
10405e7e2dc5SEd Tanous             [asyncResp, id](const boost::system::error_code& ec) {
1041163994a8SSzymon Dompke             if (ec.value() == EBADR)
1042163994a8SSzymon Dompke             {
1043002d39b4SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1044163994a8SSzymon Dompke                 return;
1045163994a8SSzymon Dompke             }
1046163994a8SSzymon Dompke 
1047163994a8SSzymon Dompke             if (ec)
1048163994a8SSzymon Dompke             {
1049163994a8SSzymon Dompke                 BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
1050163994a8SSzymon Dompke                 messages::internalError(asyncResp->res);
1051163994a8SSzymon Dompke                 return;
1052163994a8SSzymon Dompke             }
1053163994a8SSzymon Dompke 
1054002d39b4SEd Tanous             asyncResp->res.result(boost::beast::http::status::no_content);
1055163994a8SSzymon Dompke             },
1056163994a8SSzymon Dompke             telemetry::service, triggerPath,
1057163994a8SSzymon Dompke             "xyz.openbmc_project.Object.Delete", "Delete");
1058163994a8SSzymon Dompke         });
10591b7e696bSLukasz Kazmierczak }
10601b7e696bSLukasz Kazmierczak 
106107148cf2SLukasz Kazmierczak } // namespace redfish
1062