xref: /openbmc/bmcweb/features/redfish/lib/trigger.hpp (revision 2932dcb6139c6241bc7d56bf9cd495be4ddb3455)
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 toRedfishThresholdName(std::string_view dbusValue)
127dd1c4a9cSSzymon Dompke {
128dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
129dd1c4a9cSSzymon Dompke     {
130dd1c4a9cSSzymon Dompke         return "UpperCritical";
131dd1c4a9cSSzymon Dompke     }
132dd1c4a9cSSzymon Dompke 
133dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
134dd1c4a9cSSzymon Dompke     {
135dd1c4a9cSSzymon Dompke         return "LowerCritical";
136dd1c4a9cSSzymon Dompke     }
137dd1c4a9cSSzymon Dompke 
138dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
139dd1c4a9cSSzymon Dompke     {
140dd1c4a9cSSzymon Dompke         return "UpperWarning";
141dd1c4a9cSSzymon Dompke     }
142dd1c4a9cSSzymon Dompke 
143dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
144dd1c4a9cSSzymon Dompke     {
145dd1c4a9cSSzymon Dompke         return "LowerWarning";
146dd1c4a9cSSzymon Dompke     }
147dd1c4a9cSSzymon Dompke 
148dd1c4a9cSSzymon Dompke     return "";
149dd1c4a9cSSzymon Dompke }
150dd1c4a9cSSzymon Dompke 
151dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue)
152dd1c4a9cSSzymon Dompke {
153dd1c4a9cSSzymon Dompke     if (redfishValue == "Either")
154dd1c4a9cSSzymon Dompke     {
155dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
156dd1c4a9cSSzymon Dompke     }
157dd1c4a9cSSzymon Dompke 
158dd1c4a9cSSzymon Dompke     if (redfishValue == "Decreasing")
159dd1c4a9cSSzymon Dompke     {
160dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
161dd1c4a9cSSzymon Dompke     }
162dd1c4a9cSSzymon Dompke 
163dd1c4a9cSSzymon Dompke     if (redfishValue == "Increasing")
164dd1c4a9cSSzymon Dompke     {
165dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
166dd1c4a9cSSzymon Dompke     }
167dd1c4a9cSSzymon Dompke 
168dd1c4a9cSSzymon Dompke     return "";
169dd1c4a9cSSzymon Dompke }
170dd1c4a9cSSzymon Dompke 
171dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation
172dd1c4a9cSSzymon Dompke     toRedfishActivation(std::string_view dbusValue)
173dd1c4a9cSSzymon Dompke {
174dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
175dd1c4a9cSSzymon Dompke     {
176dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Either;
177dd1c4a9cSSzymon Dompke     }
178dd1c4a9cSSzymon Dompke 
179dd1c4a9cSSzymon Dompke     if (dbusValue ==
180dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
181dd1c4a9cSSzymon Dompke     {
182dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Decreasing;
183dd1c4a9cSSzymon Dompke     }
184dd1c4a9cSSzymon Dompke 
185dd1c4a9cSSzymon Dompke     if (dbusValue ==
186dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
187dd1c4a9cSSzymon Dompke     {
188dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Increasing;
189dd1c4a9cSSzymon Dompke     }
190dd1c4a9cSSzymon Dompke 
191dd1c4a9cSSzymon Dompke     return triggers::ThresholdActivation::Invalid;
192dd1c4a9cSSzymon Dompke }
193dd1c4a9cSSzymon Dompke 
194dd1c4a9cSSzymon Dompke enum class MetricType
195dd1c4a9cSSzymon Dompke {
196dd1c4a9cSSzymon Dompke     Discrete,
197dd1c4a9cSSzymon Dompke     Numeric
198dd1c4a9cSSzymon Dompke };
199dd1c4a9cSSzymon Dompke 
200dd1c4a9cSSzymon Dompke enum class DiscreteCondition
201dd1c4a9cSSzymon Dompke {
202dd1c4a9cSSzymon Dompke     Specified,
203dd1c4a9cSSzymon Dompke     Changed
204dd1c4a9cSSzymon Dompke };
205dd1c4a9cSSzymon Dompke 
206dd1c4a9cSSzymon Dompke struct Context
207dd1c4a9cSSzymon Dompke {
208dd1c4a9cSSzymon Dompke     std::string id;
209dd1c4a9cSSzymon Dompke     std::string name;
210dd1c4a9cSSzymon Dompke     std::vector<std::string> actions;
211dd1c4a9cSSzymon Dompke     std::vector<std::pair<sdbusplus::message::object_path, std::string>>
212dd1c4a9cSSzymon Dompke         sensors;
213dd1c4a9cSSzymon Dompke     std::vector<sdbusplus::message::object_path> reports;
214dd1c4a9cSSzymon Dompke     TriggerThresholdParams thresholds;
215dd1c4a9cSSzymon Dompke 
216dd1c4a9cSSzymon Dompke     std::optional<DiscreteCondition> discreteCondition;
217dd1c4a9cSSzymon Dompke     std::optional<MetricType> metricType;
218dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> metricProperties;
219dd1c4a9cSSzymon Dompke };
220dd1c4a9cSSzymon Dompke 
221dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path>
222dd1c4a9cSSzymon Dompke     getReportPathFromReportDefinitionUri(const std::string& uri)
223dd1c4a9cSSzymon Dompke {
2246fd29553SEd Tanous     boost::system::result<boost::urls::url_view> parsed =
225dd1c4a9cSSzymon Dompke         boost::urls::parse_relative_ref(uri);
226dd1c4a9cSSzymon Dompke 
227dd1c4a9cSSzymon Dompke     if (!parsed)
2281b7e696bSLukasz Kazmierczak     {
2291b7e696bSLukasz Kazmierczak         return std::nullopt;
2301b7e696bSLukasz Kazmierczak     }
2311b7e696bSLukasz Kazmierczak 
232dd1c4a9cSSzymon Dompke     std::string id;
233dd1c4a9cSSzymon Dompke     if (!crow::utility::readUrlSegments(
234dd1c4a9cSSzymon Dompke             *parsed, "redfish", "v1", "TelemetryService",
235dd1c4a9cSSzymon Dompke             "MetricReportDefinitions", std::ref(id)))
236dd1c4a9cSSzymon Dompke     {
237dd1c4a9cSSzymon Dompke         return std::nullopt;
2381b7e696bSLukasz Kazmierczak     }
2391b7e696bSLukasz Kazmierczak 
240dd1c4a9cSSzymon Dompke     return sdbusplus::message::object_path(
241dd1c4a9cSSzymon Dompke                "/xyz/openbmc_project/Telemetry/Reports") /
242dd1c4a9cSSzymon Dompke            "TelemetryService" / id;
243dd1c4a9cSSzymon Dompke }
244dd1c4a9cSSzymon Dompke 
245dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType)
246dd1c4a9cSSzymon Dompke {
247dd1c4a9cSSzymon Dompke     if (metricType == "Discrete")
248dd1c4a9cSSzymon Dompke     {
249dd1c4a9cSSzymon Dompke         return MetricType::Discrete;
250dd1c4a9cSSzymon Dompke     }
251dd1c4a9cSSzymon Dompke     if (metricType == "Numeric")
252dd1c4a9cSSzymon Dompke     {
253dd1c4a9cSSzymon Dompke         return MetricType::Numeric;
254dd1c4a9cSSzymon Dompke     }
255dd1c4a9cSSzymon Dompke     return std::nullopt;
256dd1c4a9cSSzymon Dompke }
257dd1c4a9cSSzymon Dompke 
258dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition>
259dd1c4a9cSSzymon Dompke     getDiscreteCondition(const std::string& discreteTriggerCondition)
260dd1c4a9cSSzymon Dompke {
261dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Specified")
262dd1c4a9cSSzymon Dompke     {
263dd1c4a9cSSzymon Dompke         return DiscreteCondition::Specified;
264dd1c4a9cSSzymon Dompke     }
265dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Changed")
266dd1c4a9cSSzymon Dompke     {
267dd1c4a9cSSzymon Dompke         return DiscreteCondition::Changed;
268dd1c4a9cSSzymon Dompke     }
269dd1c4a9cSSzymon Dompke     return std::nullopt;
270dd1c4a9cSSzymon Dompke }
271dd1c4a9cSSzymon Dompke 
272*2932dcb6SEd Tanous inline bool parseThreshold(crow::Response& res,
273*2932dcb6SEd Tanous                            nlohmann::json::object_t& threshold,
274*2932dcb6SEd Tanous                            std::string_view dbusThresholdName,
275*2932dcb6SEd Tanous                            std::vector<NumericThresholdParams>& parsedParams)
276dd1c4a9cSSzymon Dompke {
277dd1c4a9cSSzymon Dompke     double reading = 0.0;
278dd1c4a9cSSzymon Dompke     std::string activation;
279dd1c4a9cSSzymon Dompke     std::string dwellTimeStr;
280dd1c4a9cSSzymon Dompke 
281*2932dcb6SEd Tanous     if (!json_util::readJsonObject(threshold, res, "Reading", reading,
282dd1c4a9cSSzymon Dompke                                    "Activation", activation, "DwellTime",
283dd1c4a9cSSzymon Dompke                                    dwellTimeStr))
284dd1c4a9cSSzymon Dompke     {
285dd1c4a9cSSzymon Dompke         return false;
286dd1c4a9cSSzymon Dompke     }
287dd1c4a9cSSzymon Dompke 
288dd1c4a9cSSzymon Dompke     std::string dbusActivation = toDbusActivation(activation);
289dd1c4a9cSSzymon Dompke 
290dd1c4a9cSSzymon Dompke     if (dbusActivation.empty())
291dd1c4a9cSSzymon Dompke     {
292dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "Activation", activation);
293dd1c4a9cSSzymon Dompke         return false;
294dd1c4a9cSSzymon Dompke     }
295dd1c4a9cSSzymon Dompke 
296dd1c4a9cSSzymon Dompke     std::optional<std::chrono::milliseconds> dwellTime =
297dd1c4a9cSSzymon Dompke         time_utils::fromDurationString(dwellTimeStr);
298dd1c4a9cSSzymon Dompke     if (!dwellTime)
299dd1c4a9cSSzymon Dompke     {
300dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
301dd1c4a9cSSzymon Dompke         return false;
302dd1c4a9cSSzymon Dompke     }
303dd1c4a9cSSzymon Dompke 
304dd1c4a9cSSzymon Dompke     parsedParams.emplace_back(dbusThresholdName,
305dd1c4a9cSSzymon Dompke                               static_cast<uint64_t>(dwellTime->count()),
306dd1c4a9cSSzymon Dompke                               dbusActivation, reading);
307*2932dcb6SEd Tanous     return true;
308*2932dcb6SEd Tanous }
309*2932dcb6SEd Tanous 
310*2932dcb6SEd Tanous struct NumericThresholds
311*2932dcb6SEd Tanous {
312*2932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperCritical;
313*2932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperWarning;
314*2932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerWarning;
315*2932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerCritical;
316*2932dcb6SEd Tanous 
317*2932dcb6SEd Tanous     bool any() const
318*2932dcb6SEd Tanous     {
319*2932dcb6SEd Tanous         return upperCritical || upperWarning || lowerWarning || lowerCritical;
320*2932dcb6SEd Tanous     }
321*2932dcb6SEd Tanous };
322*2932dcb6SEd Tanous 
323*2932dcb6SEd Tanous inline bool parseNumericThresholds(crow::Response& res,
324*2932dcb6SEd Tanous                                    NumericThresholds& numericThresholds,
325*2932dcb6SEd Tanous                                    Context& ctx)
326*2932dcb6SEd Tanous {
327*2932dcb6SEd Tanous     std::vector<NumericThresholdParams> parsedParams;
328*2932dcb6SEd Tanous     if (numericThresholds.upperCritical)
329*2932dcb6SEd Tanous     {
330*2932dcb6SEd Tanous         if (!parseThreshold(
331*2932dcb6SEd Tanous                 res, *numericThresholds.upperCritical,
332*2932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
333*2932dcb6SEd Tanous                 parsedParams))
334*2932dcb6SEd Tanous         {
335*2932dcb6SEd Tanous             return false;
336*2932dcb6SEd Tanous         }
337*2932dcb6SEd Tanous     }
338*2932dcb6SEd Tanous     if (numericThresholds.upperWarning)
339*2932dcb6SEd Tanous     {
340*2932dcb6SEd Tanous         if (!parseThreshold(
341*2932dcb6SEd Tanous                 res, *numericThresholds.upperWarning,
342*2932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
343*2932dcb6SEd Tanous                 parsedParams))
344*2932dcb6SEd Tanous         {
345*2932dcb6SEd Tanous             return false;
346*2932dcb6SEd Tanous         }
347*2932dcb6SEd Tanous     }
348*2932dcb6SEd Tanous     if (numericThresholds.lowerWarning)
349*2932dcb6SEd Tanous     {
350*2932dcb6SEd Tanous         if (!parseThreshold(
351*2932dcb6SEd Tanous                 res, *numericThresholds.lowerWarning,
352*2932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
353*2932dcb6SEd Tanous                 parsedParams))
354*2932dcb6SEd Tanous         {
355*2932dcb6SEd Tanous             return false;
356*2932dcb6SEd Tanous         }
357*2932dcb6SEd Tanous     }
358*2932dcb6SEd Tanous     if (numericThresholds.lowerCritical)
359*2932dcb6SEd Tanous     {
360*2932dcb6SEd Tanous         if (!parseThreshold(
361*2932dcb6SEd Tanous                 res, *numericThresholds.lowerCritical,
362*2932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
363*2932dcb6SEd Tanous                 parsedParams))
364*2932dcb6SEd Tanous         {
365*2932dcb6SEd Tanous             return false;
366*2932dcb6SEd Tanous         }
367dd1c4a9cSSzymon Dompke     }
368dd1c4a9cSSzymon Dompke 
369dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
370dd1c4a9cSSzymon Dompke     return true;
371dd1c4a9cSSzymon Dompke }
372dd1c4a9cSSzymon Dompke 
373dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers(
374dd1c4a9cSSzymon Dompke     crow::Response& res,
375*2932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
376*2932dcb6SEd Tanous     Context& ctx)
377dd1c4a9cSSzymon Dompke {
378dd1c4a9cSSzymon Dompke     std::vector<DiscreteThresholdParams> parsedParams;
379dd1c4a9cSSzymon Dompke     if (!discreteTriggers)
380dd1c4a9cSSzymon Dompke     {
381dd1c4a9cSSzymon Dompke         ctx.thresholds = std::move(parsedParams);
382dd1c4a9cSSzymon Dompke         return true;
383dd1c4a9cSSzymon Dompke     }
384dd1c4a9cSSzymon Dompke 
385dd1c4a9cSSzymon Dompke     parsedParams.reserve(discreteTriggers->size());
386*2932dcb6SEd Tanous     for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
387dd1c4a9cSSzymon Dompke     {
388dd1c4a9cSSzymon Dompke         std::optional<std::string> name = "";
389dd1c4a9cSSzymon Dompke         std::string value;
390dd1c4a9cSSzymon Dompke         std::string dwellTimeStr;
391dd1c4a9cSSzymon Dompke         std::string severity;
392dd1c4a9cSSzymon Dompke 
393*2932dcb6SEd Tanous         if (!json_util::readJsonObject(thresholdInfo, res, "Name", name,
394*2932dcb6SEd Tanous                                        "Value", value, "DwellTime",
395*2932dcb6SEd Tanous                                        dwellTimeStr, "Severity", severity))
396dd1c4a9cSSzymon Dompke         {
397dd1c4a9cSSzymon Dompke             return false;
398dd1c4a9cSSzymon Dompke         }
399dd1c4a9cSSzymon Dompke 
400dd1c4a9cSSzymon Dompke         std::optional<std::chrono::milliseconds> dwellTime =
401dd1c4a9cSSzymon Dompke             time_utils::fromDurationString(dwellTimeStr);
402dd1c4a9cSSzymon Dompke         if (!dwellTime)
403dd1c4a9cSSzymon Dompke         {
404dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
405dd1c4a9cSSzymon Dompke             return false;
406dd1c4a9cSSzymon Dompke         }
407dd1c4a9cSSzymon Dompke 
408dd1c4a9cSSzymon Dompke         std::string dbusSeverity = toDbusSeverity(severity);
409dd1c4a9cSSzymon Dompke         if (dbusSeverity.empty())
410dd1c4a9cSSzymon Dompke         {
411dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "Severity", severity);
412dd1c4a9cSSzymon Dompke             return false;
413dd1c4a9cSSzymon Dompke         }
414dd1c4a9cSSzymon Dompke 
415dd1c4a9cSSzymon Dompke         parsedParams.emplace_back(*name, dbusSeverity,
416dd1c4a9cSSzymon Dompke                                   static_cast<uint64_t>(dwellTime->count()),
417dd1c4a9cSSzymon Dompke                                   value);
418dd1c4a9cSSzymon Dompke     }
419dd1c4a9cSSzymon Dompke 
420dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
421dd1c4a9cSSzymon Dompke     return true;
422dd1c4a9cSSzymon Dompke }
423dd1c4a9cSSzymon Dompke 
424dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds(
425dd1c4a9cSSzymon Dompke     crow::Response& res,
426*2932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
427*2932dcb6SEd Tanous     NumericThresholds& numericThresholds, Context& ctx)
428dd1c4a9cSSzymon Dompke {
429*2932dcb6SEd Tanous     if (discreteTriggers && numericThresholds.any())
430dd1c4a9cSSzymon Dompke     {
431dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "DiscreteTriggers",
432dd1c4a9cSSzymon Dompke                                         "NumericThresholds");
433dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "NumericThresholds",
434dd1c4a9cSSzymon Dompke                                         "DiscreteTriggers");
435dd1c4a9cSSzymon Dompke         return false;
436dd1c4a9cSSzymon Dompke     }
437dd1c4a9cSSzymon Dompke 
438dd1c4a9cSSzymon Dompke     if (ctx.discreteCondition)
439dd1c4a9cSSzymon Dompke     {
440*2932dcb6SEd Tanous         if (numericThresholds.any())
441dd1c4a9cSSzymon Dompke         {
442dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggerCondition",
443dd1c4a9cSSzymon Dompke                                             "NumericThresholds");
444dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
445dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
446dd1c4a9cSSzymon Dompke             return false;
447dd1c4a9cSSzymon Dompke         }
448dd1c4a9cSSzymon Dompke     }
449dd1c4a9cSSzymon Dompke 
450dd1c4a9cSSzymon Dompke     if (ctx.metricType)
451dd1c4a9cSSzymon Dompke     {
452*2932dcb6SEd Tanous         if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
453dd1c4a9cSSzymon Dompke         {
454dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
455dd1c4a9cSSzymon Dompke                                             "MetricType");
456dd1c4a9cSSzymon Dompke             return false;
457dd1c4a9cSSzymon Dompke         }
458dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
459dd1c4a9cSSzymon Dompke         {
460dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
461dd1c4a9cSSzymon Dompke                                             "MetricType");
462dd1c4a9cSSzymon Dompke             return false;
463dd1c4a9cSSzymon Dompke         }
464dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
465dd1c4a9cSSzymon Dompke         {
466dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
467dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
468dd1c4a9cSSzymon Dompke             return false;
469dd1c4a9cSSzymon Dompke         }
470dd1c4a9cSSzymon Dompke     }
471dd1c4a9cSSzymon Dompke 
472dd1c4a9cSSzymon Dompke     if (discreteTriggers || ctx.discreteCondition ||
473dd1c4a9cSSzymon Dompke         (ctx.metricType && *ctx.metricType == MetricType::Discrete))
474dd1c4a9cSSzymon Dompke     {
475dd1c4a9cSSzymon Dompke         if (ctx.discreteCondition)
476dd1c4a9cSSzymon Dompke         {
477dd1c4a9cSSzymon Dompke             if (*ctx.discreteCondition == DiscreteCondition::Specified &&
478dd1c4a9cSSzymon Dompke                 !discreteTriggers)
479dd1c4a9cSSzymon Dompke             {
480dd1c4a9cSSzymon Dompke                 messages::createFailedMissingReqProperties(res,
481dd1c4a9cSSzymon Dompke                                                            "DiscreteTriggers");
482dd1c4a9cSSzymon Dompke                 return false;
483dd1c4a9cSSzymon Dompke             }
484dd1c4a9cSSzymon Dompke             if (discreteTriggers &&
485dd1c4a9cSSzymon Dompke                 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
486dd1c4a9cSSzymon Dompke                   discreteTriggers->empty()) ||
487dd1c4a9cSSzymon Dompke                  (*ctx.discreteCondition == DiscreteCondition::Changed &&
488dd1c4a9cSSzymon Dompke                   !discreteTriggers->empty())))
489dd1c4a9cSSzymon Dompke             {
490dd1c4a9cSSzymon Dompke                 messages::propertyValueConflict(res, "DiscreteTriggers",
491dd1c4a9cSSzymon Dompke                                                 "DiscreteTriggerCondition");
492dd1c4a9cSSzymon Dompke                 return false;
493dd1c4a9cSSzymon Dompke             }
494dd1c4a9cSSzymon Dompke         }
495dd1c4a9cSSzymon Dompke         if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
496dd1c4a9cSSzymon Dompke         {
497dd1c4a9cSSzymon Dompke             return false;
498dd1c4a9cSSzymon Dompke         }
499dd1c4a9cSSzymon Dompke     }
500*2932dcb6SEd Tanous     else if (numericThresholds.any())
501dd1c4a9cSSzymon Dompke     {
502*2932dcb6SEd Tanous         if (!parseNumericThresholds(res, numericThresholds, ctx))
503dd1c4a9cSSzymon Dompke         {
504dd1c4a9cSSzymon Dompke             return false;
505dd1c4a9cSSzymon Dompke         }
506dd1c4a9cSSzymon Dompke     }
507dd1c4a9cSSzymon Dompke     else
508dd1c4a9cSSzymon Dompke     {
509dd1c4a9cSSzymon Dompke         messages::createFailedMissingReqProperties(
510dd1c4a9cSSzymon Dompke             res, "'DiscreteTriggers', 'NumericThresholds', "
511dd1c4a9cSSzymon Dompke                  "'DiscreteTriggerCondition' or 'MetricType'");
512dd1c4a9cSSzymon Dompke         return false;
513dd1c4a9cSSzymon Dompke     }
514dd1c4a9cSSzymon Dompke     return true;
515dd1c4a9cSSzymon Dompke }
516dd1c4a9cSSzymon Dompke 
517*2932dcb6SEd Tanous inline bool parseLinks(crow::Response& res,
518*2932dcb6SEd Tanous                        const std::vector<std::string>& metricReportDefinitions,
519*2932dcb6SEd Tanous                        Context& ctx)
520dd1c4a9cSSzymon Dompke {
521*2932dcb6SEd Tanous     ctx.reports.reserve(metricReportDefinitions.size());
522*2932dcb6SEd Tanous     for (const std::string& reportDefinionUri : metricReportDefinitions)
523dd1c4a9cSSzymon Dompke     {
524dd1c4a9cSSzymon Dompke         std::optional<sdbusplus::message::object_path> reportPath =
525dd1c4a9cSSzymon Dompke             getReportPathFromReportDefinitionUri(reportDefinionUri);
526dd1c4a9cSSzymon Dompke         if (!reportPath)
527dd1c4a9cSSzymon Dompke         {
528dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricReportDefinitions",
529dd1c4a9cSSzymon Dompke                                              reportDefinionUri);
530dd1c4a9cSSzymon Dompke             return false;
531dd1c4a9cSSzymon Dompke         }
532dd1c4a9cSSzymon Dompke         ctx.reports.emplace_back(*reportPath);
533dd1c4a9cSSzymon Dompke     }
534dd1c4a9cSSzymon Dompke     return true;
535dd1c4a9cSSzymon Dompke }
536dd1c4a9cSSzymon Dompke 
537dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx)
538dd1c4a9cSSzymon Dompke {
539dd1c4a9cSSzymon Dompke     if (!ctx.metricProperties)
540dd1c4a9cSSzymon Dompke     {
541dd1c4a9cSSzymon Dompke         return true;
542dd1c4a9cSSzymon Dompke     }
543dd1c4a9cSSzymon Dompke 
544dd1c4a9cSSzymon Dompke     ctx.sensors.reserve(ctx.metricProperties->size());
545dd1c4a9cSSzymon Dompke 
546dd1c4a9cSSzymon Dompke     size_t uriIdx = 0;
547dd1c4a9cSSzymon Dompke     for (const std::string& uriStr : *ctx.metricProperties)
548dd1c4a9cSSzymon Dompke     {
5496fd29553SEd Tanous         boost::system::result<boost::urls::url_view> uri =
550dd1c4a9cSSzymon Dompke             boost::urls::parse_relative_ref(uriStr);
551dd1c4a9cSSzymon Dompke         if (!uri)
552dd1c4a9cSSzymon Dompke         {
553dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
554dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
555dd1c4a9cSSzymon Dompke             return false;
556dd1c4a9cSSzymon Dompke         }
557dd1c4a9cSSzymon Dompke         std::string chassisName;
558dd1c4a9cSSzymon Dompke         std::string sensorName;
559dd1c4a9cSSzymon Dompke         if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
560dd1c4a9cSSzymon Dompke                                             std::ref(chassisName), "Sensors",
561dd1c4a9cSSzymon Dompke                                             std::ref(sensorName)))
562dd1c4a9cSSzymon Dompke         {
563dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
564dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
565dd1c4a9cSSzymon Dompke             return false;
566dd1c4a9cSSzymon Dompke         }
567dd1c4a9cSSzymon Dompke 
568dd1c4a9cSSzymon Dompke         std::pair<std::string, std::string> split =
569dd1c4a9cSSzymon Dompke             splitSensorNameAndType(sensorName);
570dd1c4a9cSSzymon Dompke         if (split.first.empty() || split.second.empty())
571dd1c4a9cSSzymon Dompke         {
572dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
573dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
574dd1c4a9cSSzymon Dompke             return false;
575dd1c4a9cSSzymon Dompke         }
576dd1c4a9cSSzymon Dompke 
577dd1c4a9cSSzymon Dompke         std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
578dd1c4a9cSSzymon Dompke                                  '/' + split.second;
579dd1c4a9cSSzymon Dompke 
580dd1c4a9cSSzymon Dompke         ctx.sensors.emplace_back(sensorPath, uriStr);
581dd1c4a9cSSzymon Dompke         uriIdx++;
582dd1c4a9cSSzymon Dompke     }
583dd1c4a9cSSzymon Dompke     return true;
584dd1c4a9cSSzymon Dompke }
585dd1c4a9cSSzymon Dompke 
586dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res,
587dd1c4a9cSSzymon Dompke                                    const crow::Request& req, Context& ctx)
588dd1c4a9cSSzymon Dompke {
589dd1c4a9cSSzymon Dompke     std::optional<std::string> id = "";
590dd1c4a9cSSzymon Dompke     std::optional<std::string> name = "";
591dd1c4a9cSSzymon Dompke     std::optional<std::string> metricType;
592dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> triggerActions;
593dd1c4a9cSSzymon Dompke     std::optional<std::string> discreteTriggerCondition;
594*2932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
595*2932dcb6SEd Tanous     std::optional<std::vector<std::string>> metricReportDefinitions;
596*2932dcb6SEd Tanous     NumericThresholds thresholds;
597*2932dcb6SEd Tanous     // clang-format off
598dd1c4a9cSSzymon Dompke     if (!json_util::readJsonPatch(
599*2932dcb6SEd Tanous             req, res,
600*2932dcb6SEd Tanous 	    "Id", id,
601*2932dcb6SEd Tanous             "Name", name,
602*2932dcb6SEd Tanous 	    "MetricType", metricType,
603*2932dcb6SEd Tanous             "TriggerActions", triggerActions,
604*2932dcb6SEd Tanous             "DiscreteTriggerCondition", discreteTriggerCondition,
605*2932dcb6SEd Tanous             "DiscreteTriggers", discreteTriggers,
606*2932dcb6SEd Tanous             "NumericThresholds/UpperCritical", thresholds.upperCritical,
607*2932dcb6SEd Tanous             "NumericThresholds/UpperWarning", thresholds.upperWarning,
608*2932dcb6SEd Tanous             "NumericThresholds/LowerWarning", thresholds.lowerWarning,
609*2932dcb6SEd Tanous             "NumericThresholds/LowerCritical", thresholds.lowerCritical,
610*2932dcb6SEd Tanous             "MetricProperties", ctx.metricProperties,
611*2932dcb6SEd Tanous             "Links/MetricReportDefinitions", metricReportDefinitions)
612*2932dcb6SEd Tanous     )
613dd1c4a9cSSzymon Dompke     {
614dd1c4a9cSSzymon Dompke         return false;
615dd1c4a9cSSzymon Dompke     }
616*2932dcb6SEd Tanous     // clang-format on
617dd1c4a9cSSzymon Dompke 
618dd1c4a9cSSzymon Dompke     ctx.id = *id;
619dd1c4a9cSSzymon Dompke     ctx.name = *name;
620dd1c4a9cSSzymon Dompke 
621dd1c4a9cSSzymon Dompke     if (metricType)
622dd1c4a9cSSzymon Dompke     {
623d5736ef2SEd Tanous         ctx.metricType = getMetricType(*metricType);
624d5736ef2SEd Tanous         if (!ctx.metricType)
625dd1c4a9cSSzymon Dompke         {
626dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricType", *metricType);
627dd1c4a9cSSzymon Dompke             return false;
628dd1c4a9cSSzymon Dompke         }
629dd1c4a9cSSzymon Dompke     }
630dd1c4a9cSSzymon Dompke 
631dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition)
632dd1c4a9cSSzymon Dompke     {
633d5736ef2SEd Tanous         ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
634d5736ef2SEd Tanous         if (!ctx.discreteCondition)
635dd1c4a9cSSzymon Dompke         {
636dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
637dd1c4a9cSSzymon Dompke                                              *discreteTriggerCondition);
638dd1c4a9cSSzymon Dompke             return false;
639dd1c4a9cSSzymon Dompke         }
640dd1c4a9cSSzymon Dompke     }
641dd1c4a9cSSzymon Dompke 
642dd1c4a9cSSzymon Dompke     if (triggerActions)
643dd1c4a9cSSzymon Dompke     {
644dd1c4a9cSSzymon Dompke         ctx.actions.reserve(triggerActions->size());
645dd1c4a9cSSzymon Dompke         for (const std::string& action : *triggerActions)
646dd1c4a9cSSzymon Dompke         {
647dd1c4a9cSSzymon Dompke             std::string dbusAction = toDbusTriggerAction(action);
648dd1c4a9cSSzymon Dompke 
649dd1c4a9cSSzymon Dompke             if (dbusAction.empty())
650dd1c4a9cSSzymon Dompke             {
651dd1c4a9cSSzymon Dompke                 messages::propertyValueNotInList(res, action, "TriggerActions");
652dd1c4a9cSSzymon Dompke                 return false;
653dd1c4a9cSSzymon Dompke             }
654dd1c4a9cSSzymon Dompke 
655dd1c4a9cSSzymon Dompke             ctx.actions.emplace_back(dbusAction);
656dd1c4a9cSSzymon Dompke         }
657dd1c4a9cSSzymon Dompke     }
658dd1c4a9cSSzymon Dompke     if (!parseMetricProperties(res, ctx))
659dd1c4a9cSSzymon Dompke     {
660dd1c4a9cSSzymon Dompke         return false;
661dd1c4a9cSSzymon Dompke     }
662dd1c4a9cSSzymon Dompke 
663*2932dcb6SEd Tanous     if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
664dd1c4a9cSSzymon Dompke     {
665dd1c4a9cSSzymon Dompke         return false;
666dd1c4a9cSSzymon Dompke     }
667dd1c4a9cSSzymon Dompke 
668*2932dcb6SEd Tanous     if (metricReportDefinitions)
669dd1c4a9cSSzymon Dompke     {
670*2932dcb6SEd Tanous         if (!parseLinks(res, *metricReportDefinitions, ctx))
671dd1c4a9cSSzymon Dompke         {
672dd1c4a9cSSzymon Dompke             return false;
673dd1c4a9cSSzymon Dompke         }
674dd1c4a9cSSzymon Dompke     }
675dd1c4a9cSSzymon Dompke     return true;
676dd1c4a9cSSzymon Dompke }
677dd1c4a9cSSzymon Dompke 
678dd1c4a9cSSzymon Dompke inline void afterCreateTrigger(
679dd1c4a9cSSzymon Dompke     const boost::system::error_code& ec, const std::string& dbusPath,
680dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
681dd1c4a9cSSzymon Dompke {
682dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::file_exists)
683dd1c4a9cSSzymon Dompke     {
684dd1c4a9cSSzymon Dompke         messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
685dd1c4a9cSSzymon Dompke         return;
686dd1c4a9cSSzymon Dompke     }
687dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::too_many_files_open)
688dd1c4a9cSSzymon Dompke     {
689dd1c4a9cSSzymon Dompke         messages::createLimitReachedForResource(asyncResp->res);
690dd1c4a9cSSzymon Dompke         return;
691dd1c4a9cSSzymon Dompke     }
692dd1c4a9cSSzymon Dompke     if (ec)
693dd1c4a9cSSzymon Dompke     {
694dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
69562598e31SEd Tanous         BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
696dd1c4a9cSSzymon Dompke         return;
697dd1c4a9cSSzymon Dompke     }
698dd1c4a9cSSzymon Dompke 
699dd1c4a9cSSzymon Dompke     const std::optional<std::string>& triggerId =
700dd1c4a9cSSzymon Dompke         getTriggerIdFromDbusPath(dbusPath);
701dd1c4a9cSSzymon Dompke     if (!triggerId)
702dd1c4a9cSSzymon Dompke     {
703dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
70462598e31SEd Tanous         BMCWEB_LOG_ERROR("Unknown data returned by "
70562598e31SEd Tanous                          "AddTrigger DBus method");
706dd1c4a9cSSzymon Dompke         return;
707dd1c4a9cSSzymon Dompke     }
708dd1c4a9cSSzymon Dompke 
709dd1c4a9cSSzymon Dompke     messages::created(asyncResp->res);
710dd1c4a9cSSzymon Dompke     boost::urls::url locationUrl = boost::urls::format(
711dd1c4a9cSSzymon Dompke         "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
712dd1c4a9cSSzymon Dompke     asyncResp->res.addHeader("Location", locationUrl.buffer());
713dd1c4a9cSSzymon Dompke }
714dd1c4a9cSSzymon Dompke 
715dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t>
716dd1c4a9cSSzymon Dompke     getTriggerActions(const std::vector<std::string>& dbusActions)
717dd1c4a9cSSzymon Dompke {
718dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggerActions;
719dd1c4a9cSSzymon Dompke     for (const std::string& dbusAction : dbusActions)
720dd1c4a9cSSzymon Dompke     {
721dd1c4a9cSSzymon Dompke         triggers::TriggerActionEnum redfishAction =
722dd1c4a9cSSzymon Dompke             toRedfishTriggerAction(dbusAction);
723dd1c4a9cSSzymon Dompke 
724dd1c4a9cSSzymon Dompke         if (redfishAction == triggers::TriggerActionEnum::Invalid)
725dd1c4a9cSSzymon Dompke         {
726dd1c4a9cSSzymon Dompke             return std::nullopt;
727dd1c4a9cSSzymon Dompke         }
728dd1c4a9cSSzymon Dompke 
729dd1c4a9cSSzymon Dompke         triggerActions.emplace_back(redfishAction);
730dd1c4a9cSSzymon Dompke     }
731dd1c4a9cSSzymon Dompke 
732dd1c4a9cSSzymon Dompke     return triggerActions;
7331b7e696bSLukasz Kazmierczak }
7341b7e696bSLukasz Kazmierczak 
7353f215c92SSzymon Dompke inline std::optional<nlohmann::json::array_t>
7361b7e696bSLukasz Kazmierczak     getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
7371b7e696bSLukasz Kazmierczak {
738dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggers;
7391b7e696bSLukasz Kazmierczak     const std::vector<DiscreteThresholdParams>* discreteParams =
7401b7e696bSLukasz Kazmierczak         std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
7411b7e696bSLukasz Kazmierczak 
742e662eae8SEd Tanous     if (discreteParams == nullptr)
7431b7e696bSLukasz Kazmierczak     {
7441b7e696bSLukasz Kazmierczak         return std::nullopt;
7451b7e696bSLukasz Kazmierczak     }
7461b7e696bSLukasz Kazmierczak 
7471b7e696bSLukasz Kazmierczak     for (const auto& [name, severity, dwellTime, value] : *discreteParams)
7481b7e696bSLukasz Kazmierczak     {
7491b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7501b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7511b7e696bSLukasz Kazmierczak 
7521b7e696bSLukasz Kazmierczak         if (!duration)
7531b7e696bSLukasz Kazmierczak         {
7541b7e696bSLukasz Kazmierczak             return std::nullopt;
7551b7e696bSLukasz Kazmierczak         }
756613dabeaSEd Tanous         nlohmann::json::object_t trigger;
757613dabeaSEd Tanous         trigger["Name"] = name;
758dd1c4a9cSSzymon Dompke         trigger["Severity"] = toRedfishSeverity(severity);
759613dabeaSEd Tanous         trigger["DwellTime"] = *duration;
760613dabeaSEd Tanous         trigger["Value"] = value;
761ad539545SPatrick Williams         triggers.emplace_back(std::move(trigger));
7621b7e696bSLukasz Kazmierczak     }
7631b7e696bSLukasz Kazmierczak 
764dd1c4a9cSSzymon Dompke     return triggers;
7651b7e696bSLukasz Kazmierczak }
7661b7e696bSLukasz Kazmierczak 
7671b7e696bSLukasz Kazmierczak inline std::optional<nlohmann::json>
7681b7e696bSLukasz Kazmierczak     getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
7691b7e696bSLukasz Kazmierczak {
770dd1c4a9cSSzymon Dompke     nlohmann::json::object_t thresholds;
7711b7e696bSLukasz Kazmierczak     const std::vector<NumericThresholdParams>* numericParams =
7721b7e696bSLukasz Kazmierczak         std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
7731b7e696bSLukasz Kazmierczak 
774e662eae8SEd Tanous     if (numericParams == nullptr)
7751b7e696bSLukasz Kazmierczak     {
7761b7e696bSLukasz Kazmierczak         return std::nullopt;
7771b7e696bSLukasz Kazmierczak     }
7781b7e696bSLukasz Kazmierczak 
7791b7e696bSLukasz Kazmierczak     for (const auto& [type, dwellTime, activation, reading] : *numericParams)
7801b7e696bSLukasz Kazmierczak     {
7811b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7821b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7831b7e696bSLukasz Kazmierczak 
7841b7e696bSLukasz Kazmierczak         if (!duration)
7851b7e696bSLukasz Kazmierczak         {
7861b7e696bSLukasz Kazmierczak             return std::nullopt;
7871b7e696bSLukasz Kazmierczak         }
788dd1c4a9cSSzymon Dompke         nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
7891476687dSEd Tanous         threshold["Reading"] = reading;
790dd1c4a9cSSzymon Dompke         threshold["Activation"] = toRedfishActivation(activation);
7911476687dSEd Tanous         threshold["DwellTime"] = *duration;
7921b7e696bSLukasz Kazmierczak     }
7931b7e696bSLukasz Kazmierczak 
794dd1c4a9cSSzymon Dompke     return thresholds;
7951b7e696bSLukasz Kazmierczak }
7961b7e696bSLukasz Kazmierczak 
7973f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions(
7983f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>& reportPaths)
7991b7e696bSLukasz Kazmierczak {
8001b7e696bSLukasz Kazmierczak     nlohmann::json reports = nlohmann::json::array();
8013f215c92SSzymon Dompke 
8023f215c92SSzymon Dompke     for (const sdbusplus::message::object_path& path : reportPaths)
8031b7e696bSLukasz Kazmierczak     {
8043f215c92SSzymon Dompke         std::string reportId = path.filename();
8053f215c92SSzymon Dompke         if (reportId.empty())
8063f215c92SSzymon Dompke         {
8073f215c92SSzymon Dompke             {
80862598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
80962598e31SEd Tanous                                  path.str);
8103f215c92SSzymon Dompke                 return std::nullopt;
8113f215c92SSzymon Dompke             }
8123f215c92SSzymon Dompke         }
8133f215c92SSzymon Dompke 
8141476687dSEd Tanous         nlohmann::json::object_t report;
815ef4c65b7SEd Tanous         report["@odata.id"] = boost::urls::format(
816ef4c65b7SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
817ef4c65b7SEd Tanous             reportId);
818b2ba3072SPatrick Williams         reports.emplace_back(std::move(report));
8191b7e696bSLukasz Kazmierczak     }
8201b7e696bSLukasz Kazmierczak 
8213f215c92SSzymon Dompke     return {std::move(reports)};
8221b7e696bSLukasz Kazmierczak }
8231b7e696bSLukasz Kazmierczak 
8241b7e696bSLukasz Kazmierczak inline std::vector<std::string>
8251b7e696bSLukasz Kazmierczak     getMetricProperties(const TriggerSensorsParams& sensors)
8261b7e696bSLukasz Kazmierczak {
8271b7e696bSLukasz Kazmierczak     std::vector<std::string> metricProperties;
8281b7e696bSLukasz Kazmierczak     metricProperties.reserve(sensors.size());
8291b7e696bSLukasz Kazmierczak     for (const auto& [_, metadata] : sensors)
8301b7e696bSLukasz Kazmierczak     {
8311b7e696bSLukasz Kazmierczak         metricProperties.emplace_back(metadata);
8321b7e696bSLukasz Kazmierczak     }
8331b7e696bSLukasz Kazmierczak 
8341b7e696bSLukasz Kazmierczak     return metricProperties;
8351b7e696bSLukasz Kazmierczak }
8361b7e696bSLukasz Kazmierczak 
8371b7e696bSLukasz Kazmierczak inline bool fillTrigger(
8381b7e696bSLukasz Kazmierczak     nlohmann::json& json, const std::string& id,
8391b7e696bSLukasz Kazmierczak     const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
8401b7e696bSLukasz Kazmierczak         properties)
8411b7e696bSLukasz Kazmierczak {
8421b7e696bSLukasz Kazmierczak     const std::string* name = nullptr;
8431b7e696bSLukasz Kazmierczak     const bool* discrete = nullptr;
8441b7e696bSLukasz Kazmierczak     const TriggerSensorsParams* sensors = nullptr;
8453f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>* reports = nullptr;
84689474494SKrzysztof Grobelny     const std::vector<std::string>* triggerActions = nullptr;
8471b7e696bSLukasz Kazmierczak     const TriggerThresholdParamsExt* thresholds = nullptr;
8481b7e696bSLukasz Kazmierczak 
84989474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
85089474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
85189474494SKrzysztof Grobelny         discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
85289474494SKrzysztof Grobelny         triggerActions, "Thresholds", thresholds);
85389474494SKrzysztof Grobelny 
85489474494SKrzysztof Grobelny     if (!success)
8551b7e696bSLukasz Kazmierczak     {
85689474494SKrzysztof Grobelny         return false;
8571b7e696bSLukasz Kazmierczak     }
8581b7e696bSLukasz Kazmierczak 
85989474494SKrzysztof Grobelny     if (triggerActions != nullptr)
86089474494SKrzysztof Grobelny     {
861dd1c4a9cSSzymon Dompke         std::optional<nlohmann::json::array_t> redfishTriggerActions =
86289474494SKrzysztof Grobelny             getTriggerActions(*triggerActions);
86389474494SKrzysztof Grobelny         if (!redfishTriggerActions)
8641b7e696bSLukasz Kazmierczak         {
86562598e31SEd Tanous             BMCWEB_LOG_ERROR(
86662598e31SEd Tanous                 "Property TriggerActions is invalid in Trigger: {}", id);
8671b7e696bSLukasz Kazmierczak             return false;
8681b7e696bSLukasz Kazmierczak         }
869dd1c4a9cSSzymon Dompke         json["TriggerActions"] = *redfishTriggerActions;
87089474494SKrzysztof Grobelny     }
8711b7e696bSLukasz Kazmierczak 
87289474494SKrzysztof Grobelny     if (reports != nullptr)
8733f215c92SSzymon Dompke     {
8743f215c92SSzymon Dompke         std::optional<nlohmann::json> linkedReports =
8753f215c92SSzymon Dompke             getMetricReportDefinitions(*reports);
8763f215c92SSzymon Dompke         if (!linkedReports)
8773f215c92SSzymon Dompke         {
87862598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
8793f215c92SSzymon Dompke             return false;
8803f215c92SSzymon Dompke         }
88189474494SKrzysztof Grobelny         json["Links"]["MetricReportDefinitions"] = *linkedReports;
88289474494SKrzysztof Grobelny     }
8831b7e696bSLukasz Kazmierczak 
88489474494SKrzysztof Grobelny     if (discrete != nullptr)
88589474494SKrzysztof Grobelny     {
8861b7e696bSLukasz Kazmierczak         if (*discrete)
8871b7e696bSLukasz Kazmierczak         {
8883f215c92SSzymon Dompke             std::optional<nlohmann::json::array_t> discreteTriggers =
8891b7e696bSLukasz Kazmierczak                 getDiscreteTriggers(*thresholds);
8901b7e696bSLukasz Kazmierczak 
8911b7e696bSLukasz Kazmierczak             if (!discreteTriggers)
8921b7e696bSLukasz Kazmierczak             {
89362598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
89462598e31SEd Tanous                                  "triggers in Trigger: {}",
89562598e31SEd Tanous                                  id);
8961b7e696bSLukasz Kazmierczak                 return false;
8971b7e696bSLukasz Kazmierczak             }
8981b7e696bSLukasz Kazmierczak 
8991b7e696bSLukasz Kazmierczak             json["DiscreteTriggers"] = *discreteTriggers;
9001b7e696bSLukasz Kazmierczak             json["DiscreteTriggerCondition"] =
9011b7e696bSLukasz Kazmierczak                 discreteTriggers->empty() ? "Changed" : "Specified";
9021b7e696bSLukasz Kazmierczak             json["MetricType"] = "Discrete";
9031b7e696bSLukasz Kazmierczak         }
9041b7e696bSLukasz Kazmierczak         else
9051b7e696bSLukasz Kazmierczak         {
9061b7e696bSLukasz Kazmierczak             std::optional<nlohmann::json> numericThresholds =
9071b7e696bSLukasz Kazmierczak                 getNumericThresholds(*thresholds);
9081b7e696bSLukasz Kazmierczak 
9091b7e696bSLukasz Kazmierczak             if (!numericThresholds)
9101b7e696bSLukasz Kazmierczak             {
91162598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
91262598e31SEd Tanous                                  "thresholds in Trigger: {}",
91362598e31SEd Tanous                                  id);
9141b7e696bSLukasz Kazmierczak                 return false;
9151b7e696bSLukasz Kazmierczak             }
9161b7e696bSLukasz Kazmierczak 
9171b7e696bSLukasz Kazmierczak             json["NumericThresholds"] = *numericThresholds;
9181b7e696bSLukasz Kazmierczak             json["MetricType"] = "Numeric";
9191b7e696bSLukasz Kazmierczak         }
92089474494SKrzysztof Grobelny     }
92189474494SKrzysztof Grobelny 
92289474494SKrzysztof Grobelny     if (name != nullptr)
92389474494SKrzysztof Grobelny     {
92489474494SKrzysztof Grobelny         json["Name"] = *name;
92589474494SKrzysztof Grobelny     }
92689474494SKrzysztof Grobelny 
92789474494SKrzysztof Grobelny     if (sensors != nullptr)
92889474494SKrzysztof Grobelny     {
92989474494SKrzysztof Grobelny         json["MetricProperties"] = getMetricProperties(*sensors);
93089474494SKrzysztof Grobelny     }
9311b7e696bSLukasz Kazmierczak 
9323f215c92SSzymon Dompke     json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
933ef4c65b7SEd Tanous     json["@odata.id"] =
934ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
9353f215c92SSzymon Dompke     json["Id"] = id;
9361b7e696bSLukasz Kazmierczak 
9371b7e696bSLukasz Kazmierczak     return true;
9381b7e696bSLukasz Kazmierczak }
9391b7e696bSLukasz Kazmierczak 
940dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost(
941dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
942dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
943dd1c4a9cSSzymon Dompke {
944dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
945dd1c4a9cSSzymon Dompke     {
946dd1c4a9cSSzymon Dompke         return;
947dd1c4a9cSSzymon Dompke     }
948dd1c4a9cSSzymon Dompke 
949dd1c4a9cSSzymon Dompke     telemetry::Context ctx;
950dd1c4a9cSSzymon Dompke     if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
951dd1c4a9cSSzymon Dompke     {
952dd1c4a9cSSzymon Dompke         return;
953dd1c4a9cSSzymon Dompke     }
954dd1c4a9cSSzymon Dompke 
955dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
956dd1c4a9cSSzymon Dompke         [asyncResp, id = ctx.id](const boost::system::error_code& ec,
957dd1c4a9cSSzymon Dompke                                  const std::string& dbusPath) {
958dd1c4a9cSSzymon Dompke         afterCreateTrigger(ec, dbusPath, asyncResp, id);
959dd1c4a9cSSzymon Dompke     },
960dd1c4a9cSSzymon Dompke         service, "/xyz/openbmc_project/Telemetry/Triggers",
961dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
962dd1c4a9cSSzymon Dompke         "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
963dd1c4a9cSSzymon Dompke         ctx.reports, ctx.thresholds);
964dd1c4a9cSSzymon Dompke }
965dd1c4a9cSSzymon Dompke 
96607148cf2SLukasz Kazmierczak } // namespace telemetry
96707148cf2SLukasz Kazmierczak 
96807148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app)
96907148cf2SLukasz Kazmierczak {
97007148cf2SLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
97107148cf2SLukasz Kazmierczak         .privileges(redfish::privileges::getTriggersCollection)
97207148cf2SLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
97345ca1b86SEd Tanous             [&app](const crow::Request& req,
97407148cf2SLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
9753ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
97645ca1b86SEd Tanous         {
97745ca1b86SEd Tanous             return;
97845ca1b86SEd Tanous         }
97907148cf2SLukasz Kazmierczak         asyncResp->res.jsonValue["@odata.type"] =
98007148cf2SLukasz Kazmierczak             "#TriggersCollection.TriggersCollection";
981ae9031f0SWilly Tu         asyncResp->res.jsonValue["@odata.id"] =
982ae9031f0SWilly Tu             "/redfish/v1/TelemetryService/Triggers";
98307148cf2SLukasz Kazmierczak         asyncResp->res.jsonValue["Name"] = "Triggers Collection";
9847a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
9857a1dbc48SGeorge Liu             telemetry::triggerInterface};
98607148cf2SLukasz Kazmierczak         collection_util::getCollectionMembers(
987ae9031f0SWilly Tu             asyncResp,
988ae9031f0SWilly Tu             boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
989ae9031f0SWilly Tu             interfaces,
99007148cf2SLukasz Kazmierczak             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
99107148cf2SLukasz Kazmierczak     });
992dd1c4a9cSSzymon Dompke 
993dd1c4a9cSSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
994dd1c4a9cSSzymon Dompke         .privileges(redfish::privileges::postTriggersCollection)
995dd1c4a9cSSzymon Dompke         .methods(boost::beast::http::verb::post)(std::bind_front(
996dd1c4a9cSSzymon Dompke             telemetry::handleTriggerCollectionPost, std::ref(app)));
99707148cf2SLukasz Kazmierczak }
99807148cf2SLukasz Kazmierczak 
9991b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app)
10001b7e696bSLukasz Kazmierczak {
10011b7e696bSLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
10021b7e696bSLukasz Kazmierczak         .privileges(redfish::privileges::getTriggers)
10031b7e696bSLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
100445ca1b86SEd Tanous             [&app](const crow::Request& req,
10051b7e696bSLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10061b7e696bSLukasz Kazmierczak                    const std::string& id) {
10073ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
100845ca1b86SEd Tanous         {
100945ca1b86SEd Tanous             return;
101045ca1b86SEd Tanous         }
101189474494SKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
101289474494SKrzysztof Grobelny             *crow::connections::systemBus, telemetry::service,
101389474494SKrzysztof Grobelny             telemetry::getDbusTriggerPath(id), telemetry::triggerInterface,
10141b7e696bSLukasz Kazmierczak             [asyncResp,
10155e7e2dc5SEd Tanous              id](const boost::system::error_code& ec,
10161b7e696bSLukasz Kazmierczak                  const std::vector<std::pair<
1017002d39b4SEd Tanous                      std::string, telemetry::TriggerGetParamsVariant>>& ret) {
10181b7e696bSLukasz Kazmierczak             if (ec.value() == EBADR ||
10191b7e696bSLukasz Kazmierczak                 ec == boost::system::errc::host_unreachable)
10201b7e696bSLukasz Kazmierczak             {
1021002d39b4SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Triggers", id);
10221b7e696bSLukasz Kazmierczak                 return;
10231b7e696bSLukasz Kazmierczak             }
10241b7e696bSLukasz Kazmierczak             if (ec)
10251b7e696bSLukasz Kazmierczak             {
102662598e31SEd Tanous                 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
10271b7e696bSLukasz Kazmierczak                 messages::internalError(asyncResp->res);
10281b7e696bSLukasz Kazmierczak                 return;
10291b7e696bSLukasz Kazmierczak             }
10301b7e696bSLukasz Kazmierczak 
1031002d39b4SEd Tanous             if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret))
10321b7e696bSLukasz Kazmierczak             {
10331b7e696bSLukasz Kazmierczak                 messages::internalError(asyncResp->res);
10341b7e696bSLukasz Kazmierczak             }
103589474494SKrzysztof Grobelny         });
10361b7e696bSLukasz Kazmierczak     });
1037163994a8SSzymon Dompke 
1038163994a8SSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1039163994a8SSzymon Dompke         .privileges(redfish::privileges::deleteTriggers)
1040163994a8SSzymon Dompke         .methods(boost::beast::http::verb::delete_)(
104145ca1b86SEd Tanous             [&app](const crow::Request& req,
1042163994a8SSzymon Dompke                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1043163994a8SSzymon Dompke                    const std::string& id) {
10443ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
104545ca1b86SEd Tanous         {
104645ca1b86SEd Tanous             return;
104745ca1b86SEd Tanous         }
1048002d39b4SEd Tanous         const std::string triggerPath = telemetry::getDbusTriggerPath(id);
1049163994a8SSzymon Dompke 
1050163994a8SSzymon Dompke         crow::connections::systemBus->async_method_call(
10515e7e2dc5SEd Tanous             [asyncResp, id](const boost::system::error_code& ec) {
1052163994a8SSzymon Dompke             if (ec.value() == EBADR)
1053163994a8SSzymon Dompke             {
1054002d39b4SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1055163994a8SSzymon Dompke                 return;
1056163994a8SSzymon Dompke             }
1057163994a8SSzymon Dompke 
1058163994a8SSzymon Dompke             if (ec)
1059163994a8SSzymon Dompke             {
106062598e31SEd Tanous                 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1061163994a8SSzymon Dompke                 messages::internalError(asyncResp->res);
1062163994a8SSzymon Dompke                 return;
1063163994a8SSzymon Dompke             }
1064163994a8SSzymon Dompke 
1065002d39b4SEd Tanous             asyncResp->res.result(boost::beast::http::status::no_content);
1066163994a8SSzymon Dompke         },
1067163994a8SSzymon Dompke             telemetry::service, triggerPath,
1068163994a8SSzymon Dompke             "xyz.openbmc_project.Object.Delete", "Delete");
1069163994a8SSzymon Dompke     });
10701b7e696bSLukasz Kazmierczak }
10711b7e696bSLukasz Kazmierczak 
107207148cf2SLukasz Kazmierczak } // namespace redfish
1073