xref: /openbmc/bmcweb/features/redfish/lib/trigger.hpp (revision 5b90429a75c58797ec29ac9a8ed18c2dcd7d4950)
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"
12*5b90429aSEd Tanous #include "utils/json_utils.hpp"
1307148cf2SLukasz Kazmierczak #include "utils/telemetry_utils.hpp"
143ccb3adbSEd Tanous #include "utils/time_utils.hpp"
1507148cf2SLukasz Kazmierczak 
16ef4c65b7SEd Tanous #include <boost/url/format.hpp>
1789474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1889474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
1907148cf2SLukasz Kazmierczak 
207a1dbc48SGeorge Liu #include <array>
217a1dbc48SGeorge Liu #include <string_view>
221b7e696bSLukasz Kazmierczak #include <tuple>
231b7e696bSLukasz Kazmierczak #include <variant>
241b7e696bSLukasz Kazmierczak #include <vector>
251b7e696bSLukasz Kazmierczak 
2607148cf2SLukasz Kazmierczak namespace redfish
2707148cf2SLukasz Kazmierczak {
2807148cf2SLukasz Kazmierczak namespace telemetry
2907148cf2SLukasz Kazmierczak {
3007148cf2SLukasz Kazmierczak constexpr const char* triggerInterface =
3107148cf2SLukasz Kazmierczak     "xyz.openbmc_project.Telemetry.Trigger";
3207148cf2SLukasz Kazmierczak 
331b7e696bSLukasz Kazmierczak using NumericThresholdParams =
341b7e696bSLukasz Kazmierczak     std::tuple<std::string, uint64_t, std::string, double>;
351b7e696bSLukasz Kazmierczak 
361b7e696bSLukasz Kazmierczak using DiscreteThresholdParams =
371b7e696bSLukasz Kazmierczak     std::tuple<std::string, std::string, uint64_t, std::string>;
381b7e696bSLukasz Kazmierczak 
39dd1c4a9cSSzymon Dompke using TriggerThresholdParams =
40dd1c4a9cSSzymon Dompke     std::variant<std::vector<NumericThresholdParams>,
41dd1c4a9cSSzymon Dompke                  std::vector<DiscreteThresholdParams>>;
42dd1c4a9cSSzymon Dompke 
431b7e696bSLukasz Kazmierczak using TriggerThresholdParamsExt =
441b7e696bSLukasz Kazmierczak     std::variant<std::monostate, std::vector<NumericThresholdParams>,
451b7e696bSLukasz Kazmierczak                  std::vector<DiscreteThresholdParams>>;
461b7e696bSLukasz Kazmierczak 
471b7e696bSLukasz Kazmierczak using TriggerSensorsParams =
481b7e696bSLukasz Kazmierczak     std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
491b7e696bSLukasz Kazmierczak 
501b7e696bSLukasz Kazmierczak using TriggerGetParamsVariant =
511b7e696bSLukasz Kazmierczak     std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
523f215c92SSzymon Dompke                  TriggerSensorsParams, std::vector<std::string>,
533f215c92SSzymon Dompke                  std::vector<sdbusplus::message::object_path>>;
541b7e696bSLukasz Kazmierczak 
55dd1c4a9cSSzymon Dompke inline triggers::TriggerActionEnum
56dd1c4a9cSSzymon Dompke     toRedfishTriggerAction(std::string_view dbusValue)
571b7e696bSLukasz Kazmierczak {
58dd1c4a9cSSzymon Dompke     if (dbusValue ==
59dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
601b7e696bSLukasz Kazmierczak     {
61dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishMetricReport;
621b7e696bSLukasz Kazmierczak     }
63dd1c4a9cSSzymon Dompke     if (dbusValue ==
64dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
651b7e696bSLukasz Kazmierczak     {
66dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::RedfishEvent;
671b7e696bSLukasz Kazmierczak     }
68dd1c4a9cSSzymon Dompke     if (dbusValue ==
69dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
701b7e696bSLukasz Kazmierczak     {
71dd1c4a9cSSzymon Dompke         return triggers::TriggerActionEnum::LogToLogService;
721b7e696bSLukasz Kazmierczak     }
73dd1c4a9cSSzymon Dompke     return triggers::TriggerActionEnum::Invalid;
741b7e696bSLukasz Kazmierczak }
751b7e696bSLukasz Kazmierczak 
76dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue)
771b7e696bSLukasz Kazmierczak {
78dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishMetricReport")
791b7e696bSLukasz Kazmierczak     {
80dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
81dd1c4a9cSSzymon Dompke     }
82dd1c4a9cSSzymon Dompke     if (redfishValue == "RedfishEvent")
83dd1c4a9cSSzymon Dompke     {
84dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
85dd1c4a9cSSzymon Dompke     }
86dd1c4a9cSSzymon Dompke     if (redfishValue == "LogToLogService")
87dd1c4a9cSSzymon Dompke     {
88dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
89dd1c4a9cSSzymon Dompke     }
90dd1c4a9cSSzymon Dompke     return "";
91dd1c4a9cSSzymon Dompke }
921b7e696bSLukasz Kazmierczak 
93dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue)
94dd1c4a9cSSzymon Dompke {
95dd1c4a9cSSzymon Dompke     if (redfishValue == "OK")
96dd1c4a9cSSzymon Dompke     {
97dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
98dd1c4a9cSSzymon Dompke     }
99dd1c4a9cSSzymon Dompke     if (redfishValue == "Warning")
100dd1c4a9cSSzymon Dompke     {
101dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
102dd1c4a9cSSzymon Dompke     }
103dd1c4a9cSSzymon Dompke     if (redfishValue == "Critical")
104dd1c4a9cSSzymon Dompke     {
105dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
106dd1c4a9cSSzymon Dompke     }
107dd1c4a9cSSzymon Dompke     return "";
108dd1c4a9cSSzymon Dompke }
109dd1c4a9cSSzymon Dompke 
110dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue)
111dd1c4a9cSSzymon Dompke {
112dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
113dd1c4a9cSSzymon Dompke     {
114dd1c4a9cSSzymon Dompke         return resource::Health::OK;
115dd1c4a9cSSzymon Dompke     }
116dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
117dd1c4a9cSSzymon Dompke     {
118dd1c4a9cSSzymon Dompke         return resource::Health::Warning;
119dd1c4a9cSSzymon Dompke     }
120dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
121dd1c4a9cSSzymon Dompke     {
122dd1c4a9cSSzymon Dompke         return resource::Health::Critical;
123dd1c4a9cSSzymon Dompke     }
124dd1c4a9cSSzymon Dompke     return resource::Health::Invalid;
125dd1c4a9cSSzymon Dompke }
126dd1c4a9cSSzymon Dompke 
127dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue)
128dd1c4a9cSSzymon Dompke {
129dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
130dd1c4a9cSSzymon Dompke     {
131dd1c4a9cSSzymon Dompke         return "UpperCritical";
132dd1c4a9cSSzymon Dompke     }
133dd1c4a9cSSzymon Dompke 
134dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
135dd1c4a9cSSzymon Dompke     {
136dd1c4a9cSSzymon Dompke         return "LowerCritical";
137dd1c4a9cSSzymon Dompke     }
138dd1c4a9cSSzymon Dompke 
139dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
140dd1c4a9cSSzymon Dompke     {
141dd1c4a9cSSzymon Dompke         return "UpperWarning";
142dd1c4a9cSSzymon Dompke     }
143dd1c4a9cSSzymon Dompke 
144dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
145dd1c4a9cSSzymon Dompke     {
146dd1c4a9cSSzymon Dompke         return "LowerWarning";
147dd1c4a9cSSzymon Dompke     }
148dd1c4a9cSSzymon Dompke 
149dd1c4a9cSSzymon Dompke     return "";
150dd1c4a9cSSzymon Dompke }
151dd1c4a9cSSzymon Dompke 
152dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue)
153dd1c4a9cSSzymon Dompke {
154dd1c4a9cSSzymon Dompke     if (redfishValue == "Either")
155dd1c4a9cSSzymon Dompke     {
156dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
157dd1c4a9cSSzymon Dompke     }
158dd1c4a9cSSzymon Dompke 
159dd1c4a9cSSzymon Dompke     if (redfishValue == "Decreasing")
160dd1c4a9cSSzymon Dompke     {
161dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
162dd1c4a9cSSzymon Dompke     }
163dd1c4a9cSSzymon Dompke 
164dd1c4a9cSSzymon Dompke     if (redfishValue == "Increasing")
165dd1c4a9cSSzymon Dompke     {
166dd1c4a9cSSzymon Dompke         return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
167dd1c4a9cSSzymon Dompke     }
168dd1c4a9cSSzymon Dompke 
169dd1c4a9cSSzymon Dompke     return "";
170dd1c4a9cSSzymon Dompke }
171dd1c4a9cSSzymon Dompke 
172dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation
173dd1c4a9cSSzymon Dompke     toRedfishActivation(std::string_view dbusValue)
174dd1c4a9cSSzymon Dompke {
175dd1c4a9cSSzymon Dompke     if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
176dd1c4a9cSSzymon Dompke     {
177dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Either;
178dd1c4a9cSSzymon Dompke     }
179dd1c4a9cSSzymon Dompke 
180dd1c4a9cSSzymon Dompke     if (dbusValue ==
181dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
182dd1c4a9cSSzymon Dompke     {
183dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Decreasing;
184dd1c4a9cSSzymon Dompke     }
185dd1c4a9cSSzymon Dompke 
186dd1c4a9cSSzymon Dompke     if (dbusValue ==
187dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
188dd1c4a9cSSzymon Dompke     {
189dd1c4a9cSSzymon Dompke         return triggers::ThresholdActivation::Increasing;
190dd1c4a9cSSzymon Dompke     }
191dd1c4a9cSSzymon Dompke 
192dd1c4a9cSSzymon Dompke     return triggers::ThresholdActivation::Invalid;
193dd1c4a9cSSzymon Dompke }
194dd1c4a9cSSzymon Dompke 
195dd1c4a9cSSzymon Dompke enum class MetricType
196dd1c4a9cSSzymon Dompke {
197dd1c4a9cSSzymon Dompke     Discrete,
198dd1c4a9cSSzymon Dompke     Numeric
199dd1c4a9cSSzymon Dompke };
200dd1c4a9cSSzymon Dompke 
201dd1c4a9cSSzymon Dompke enum class DiscreteCondition
202dd1c4a9cSSzymon Dompke {
203dd1c4a9cSSzymon Dompke     Specified,
204dd1c4a9cSSzymon Dompke     Changed
205dd1c4a9cSSzymon Dompke };
206dd1c4a9cSSzymon Dompke 
207dd1c4a9cSSzymon Dompke struct Context
208dd1c4a9cSSzymon Dompke {
209dd1c4a9cSSzymon Dompke     std::string id;
210dd1c4a9cSSzymon Dompke     std::string name;
211dd1c4a9cSSzymon Dompke     std::vector<std::string> actions;
212dd1c4a9cSSzymon Dompke     std::vector<std::pair<sdbusplus::message::object_path, std::string>>
213dd1c4a9cSSzymon Dompke         sensors;
214dd1c4a9cSSzymon Dompke     std::vector<sdbusplus::message::object_path> reports;
215dd1c4a9cSSzymon Dompke     TriggerThresholdParams thresholds;
216dd1c4a9cSSzymon Dompke 
217dd1c4a9cSSzymon Dompke     std::optional<DiscreteCondition> discreteCondition;
218dd1c4a9cSSzymon Dompke     std::optional<MetricType> metricType;
219dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> metricProperties;
220dd1c4a9cSSzymon Dompke };
221dd1c4a9cSSzymon Dompke 
222dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path>
223dd1c4a9cSSzymon Dompke     getReportPathFromReportDefinitionUri(const std::string& uri)
224dd1c4a9cSSzymon Dompke {
2256fd29553SEd Tanous     boost::system::result<boost::urls::url_view> parsed =
226dd1c4a9cSSzymon Dompke         boost::urls::parse_relative_ref(uri);
227dd1c4a9cSSzymon Dompke 
228dd1c4a9cSSzymon Dompke     if (!parsed)
2291b7e696bSLukasz Kazmierczak     {
2301b7e696bSLukasz Kazmierczak         return std::nullopt;
2311b7e696bSLukasz Kazmierczak     }
2321b7e696bSLukasz Kazmierczak 
233dd1c4a9cSSzymon Dompke     std::string id;
234dd1c4a9cSSzymon Dompke     if (!crow::utility::readUrlSegments(
235dd1c4a9cSSzymon Dompke             *parsed, "redfish", "v1", "TelemetryService",
236dd1c4a9cSSzymon Dompke             "MetricReportDefinitions", std::ref(id)))
237dd1c4a9cSSzymon Dompke     {
238dd1c4a9cSSzymon Dompke         return std::nullopt;
2391b7e696bSLukasz Kazmierczak     }
2401b7e696bSLukasz Kazmierczak 
241dd1c4a9cSSzymon Dompke     return sdbusplus::message::object_path(
242dd1c4a9cSSzymon Dompke                "/xyz/openbmc_project/Telemetry/Reports") /
243dd1c4a9cSSzymon Dompke            "TelemetryService" / id;
244dd1c4a9cSSzymon Dompke }
245dd1c4a9cSSzymon Dompke 
246dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType)
247dd1c4a9cSSzymon Dompke {
248dd1c4a9cSSzymon Dompke     if (metricType == "Discrete")
249dd1c4a9cSSzymon Dompke     {
250dd1c4a9cSSzymon Dompke         return MetricType::Discrete;
251dd1c4a9cSSzymon Dompke     }
252dd1c4a9cSSzymon Dompke     if (metricType == "Numeric")
253dd1c4a9cSSzymon Dompke     {
254dd1c4a9cSSzymon Dompke         return MetricType::Numeric;
255dd1c4a9cSSzymon Dompke     }
256dd1c4a9cSSzymon Dompke     return std::nullopt;
257dd1c4a9cSSzymon Dompke }
258dd1c4a9cSSzymon Dompke 
259dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition>
260dd1c4a9cSSzymon Dompke     getDiscreteCondition(const std::string& discreteTriggerCondition)
261dd1c4a9cSSzymon Dompke {
262dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Specified")
263dd1c4a9cSSzymon Dompke     {
264dd1c4a9cSSzymon Dompke         return DiscreteCondition::Specified;
265dd1c4a9cSSzymon Dompke     }
266dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition == "Changed")
267dd1c4a9cSSzymon Dompke     {
268dd1c4a9cSSzymon Dompke         return DiscreteCondition::Changed;
269dd1c4a9cSSzymon Dompke     }
270dd1c4a9cSSzymon Dompke     return std::nullopt;
271dd1c4a9cSSzymon Dompke }
272dd1c4a9cSSzymon Dompke 
2732932dcb6SEd Tanous inline bool parseThreshold(crow::Response& res,
2742932dcb6SEd Tanous                            nlohmann::json::object_t& threshold,
2752932dcb6SEd Tanous                            std::string_view dbusThresholdName,
2762932dcb6SEd Tanous                            std::vector<NumericThresholdParams>& parsedParams)
277dd1c4a9cSSzymon Dompke {
278dd1c4a9cSSzymon Dompke     double reading = 0.0;
279dd1c4a9cSSzymon Dompke     std::string activation;
280dd1c4a9cSSzymon Dompke     std::string dwellTimeStr;
281dd1c4a9cSSzymon Dompke 
2822932dcb6SEd Tanous     if (!json_util::readJsonObject(threshold, res, "Reading", reading,
283dd1c4a9cSSzymon Dompke                                    "Activation", activation, "DwellTime",
284dd1c4a9cSSzymon Dompke                                    dwellTimeStr))
285dd1c4a9cSSzymon Dompke     {
286dd1c4a9cSSzymon Dompke         return false;
287dd1c4a9cSSzymon Dompke     }
288dd1c4a9cSSzymon Dompke 
289dd1c4a9cSSzymon Dompke     std::string dbusActivation = toDbusActivation(activation);
290dd1c4a9cSSzymon Dompke 
291dd1c4a9cSSzymon Dompke     if (dbusActivation.empty())
292dd1c4a9cSSzymon Dompke     {
293dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "Activation", activation);
294dd1c4a9cSSzymon Dompke         return false;
295dd1c4a9cSSzymon Dompke     }
296dd1c4a9cSSzymon Dompke 
297dd1c4a9cSSzymon Dompke     std::optional<std::chrono::milliseconds> dwellTime =
298dd1c4a9cSSzymon Dompke         time_utils::fromDurationString(dwellTimeStr);
299dd1c4a9cSSzymon Dompke     if (!dwellTime)
300dd1c4a9cSSzymon Dompke     {
301dd1c4a9cSSzymon Dompke         messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
302dd1c4a9cSSzymon Dompke         return false;
303dd1c4a9cSSzymon Dompke     }
304dd1c4a9cSSzymon Dompke 
305dd1c4a9cSSzymon Dompke     parsedParams.emplace_back(dbusThresholdName,
306dd1c4a9cSSzymon Dompke                               static_cast<uint64_t>(dwellTime->count()),
307dd1c4a9cSSzymon Dompke                               dbusActivation, reading);
3082932dcb6SEd Tanous     return true;
3092932dcb6SEd Tanous }
3102932dcb6SEd Tanous 
3112932dcb6SEd Tanous struct NumericThresholds
3122932dcb6SEd Tanous {
3132932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperCritical;
3142932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> upperWarning;
3152932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerWarning;
3162932dcb6SEd Tanous     std::optional<nlohmann::json::object_t> lowerCritical;
3172932dcb6SEd Tanous 
3182932dcb6SEd Tanous     bool any() const
3192932dcb6SEd Tanous     {
3202932dcb6SEd Tanous         return upperCritical || upperWarning || lowerWarning || lowerCritical;
3212932dcb6SEd Tanous     }
3222932dcb6SEd Tanous };
3232932dcb6SEd Tanous 
3242932dcb6SEd Tanous inline bool parseNumericThresholds(crow::Response& res,
3252932dcb6SEd Tanous                                    NumericThresholds& numericThresholds,
3262932dcb6SEd Tanous                                    Context& ctx)
3272932dcb6SEd Tanous {
3282932dcb6SEd Tanous     std::vector<NumericThresholdParams> parsedParams;
3292932dcb6SEd Tanous     if (numericThresholds.upperCritical)
3302932dcb6SEd Tanous     {
3312932dcb6SEd Tanous         if (!parseThreshold(
3322932dcb6SEd Tanous                 res, *numericThresholds.upperCritical,
3332932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
3342932dcb6SEd Tanous                 parsedParams))
3352932dcb6SEd Tanous         {
3362932dcb6SEd Tanous             return false;
3372932dcb6SEd Tanous         }
3382932dcb6SEd Tanous     }
3392932dcb6SEd Tanous     if (numericThresholds.upperWarning)
3402932dcb6SEd Tanous     {
3412932dcb6SEd Tanous         if (!parseThreshold(
3422932dcb6SEd Tanous                 res, *numericThresholds.upperWarning,
3432932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
3442932dcb6SEd Tanous                 parsedParams))
3452932dcb6SEd Tanous         {
3462932dcb6SEd Tanous             return false;
3472932dcb6SEd Tanous         }
3482932dcb6SEd Tanous     }
3492932dcb6SEd Tanous     if (numericThresholds.lowerWarning)
3502932dcb6SEd Tanous     {
3512932dcb6SEd Tanous         if (!parseThreshold(
3522932dcb6SEd Tanous                 res, *numericThresholds.lowerWarning,
3532932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
3542932dcb6SEd Tanous                 parsedParams))
3552932dcb6SEd Tanous         {
3562932dcb6SEd Tanous             return false;
3572932dcb6SEd Tanous         }
3582932dcb6SEd Tanous     }
3592932dcb6SEd Tanous     if (numericThresholds.lowerCritical)
3602932dcb6SEd Tanous     {
3612932dcb6SEd Tanous         if (!parseThreshold(
3622932dcb6SEd Tanous                 res, *numericThresholds.lowerCritical,
3632932dcb6SEd Tanous                 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
3642932dcb6SEd Tanous                 parsedParams))
3652932dcb6SEd Tanous         {
3662932dcb6SEd Tanous             return false;
3672932dcb6SEd Tanous         }
368dd1c4a9cSSzymon Dompke     }
369dd1c4a9cSSzymon Dompke 
370dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
371dd1c4a9cSSzymon Dompke     return true;
372dd1c4a9cSSzymon Dompke }
373dd1c4a9cSSzymon Dompke 
374dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers(
375dd1c4a9cSSzymon Dompke     crow::Response& res,
3762932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
3772932dcb6SEd Tanous     Context& ctx)
378dd1c4a9cSSzymon Dompke {
379dd1c4a9cSSzymon Dompke     std::vector<DiscreteThresholdParams> parsedParams;
380dd1c4a9cSSzymon Dompke     if (!discreteTriggers)
381dd1c4a9cSSzymon Dompke     {
382dd1c4a9cSSzymon Dompke         ctx.thresholds = std::move(parsedParams);
383dd1c4a9cSSzymon Dompke         return true;
384dd1c4a9cSSzymon Dompke     }
385dd1c4a9cSSzymon Dompke 
386dd1c4a9cSSzymon Dompke     parsedParams.reserve(discreteTriggers->size());
3872932dcb6SEd Tanous     for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
388dd1c4a9cSSzymon Dompke     {
389dd1c4a9cSSzymon Dompke         std::optional<std::string> name = "";
390dd1c4a9cSSzymon Dompke         std::string value;
391dd1c4a9cSSzymon Dompke         std::string dwellTimeStr;
392dd1c4a9cSSzymon Dompke         std::string severity;
393dd1c4a9cSSzymon Dompke 
3942932dcb6SEd Tanous         if (!json_util::readJsonObject(thresholdInfo, res, "Name", name,
3952932dcb6SEd Tanous                                        "Value", value, "DwellTime",
3962932dcb6SEd Tanous                                        dwellTimeStr, "Severity", severity))
397dd1c4a9cSSzymon Dompke         {
398dd1c4a9cSSzymon Dompke             return false;
399dd1c4a9cSSzymon Dompke         }
400dd1c4a9cSSzymon Dompke 
401dd1c4a9cSSzymon Dompke         std::optional<std::chrono::milliseconds> dwellTime =
402dd1c4a9cSSzymon Dompke             time_utils::fromDurationString(dwellTimeStr);
403dd1c4a9cSSzymon Dompke         if (!dwellTime)
404dd1c4a9cSSzymon Dompke         {
405dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
406dd1c4a9cSSzymon Dompke             return false;
407dd1c4a9cSSzymon Dompke         }
408dd1c4a9cSSzymon Dompke 
409dd1c4a9cSSzymon Dompke         std::string dbusSeverity = toDbusSeverity(severity);
410dd1c4a9cSSzymon Dompke         if (dbusSeverity.empty())
411dd1c4a9cSSzymon Dompke         {
412dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "Severity", severity);
413dd1c4a9cSSzymon Dompke             return false;
414dd1c4a9cSSzymon Dompke         }
415dd1c4a9cSSzymon Dompke 
416dd1c4a9cSSzymon Dompke         parsedParams.emplace_back(*name, dbusSeverity,
417dd1c4a9cSSzymon Dompke                                   static_cast<uint64_t>(dwellTime->count()),
418dd1c4a9cSSzymon Dompke                                   value);
419dd1c4a9cSSzymon Dompke     }
420dd1c4a9cSSzymon Dompke 
421dd1c4a9cSSzymon Dompke     ctx.thresholds = std::move(parsedParams);
422dd1c4a9cSSzymon Dompke     return true;
423dd1c4a9cSSzymon Dompke }
424dd1c4a9cSSzymon Dompke 
425dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds(
426dd1c4a9cSSzymon Dompke     crow::Response& res,
4272932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
4282932dcb6SEd Tanous     NumericThresholds& numericThresholds, Context& ctx)
429dd1c4a9cSSzymon Dompke {
4302932dcb6SEd Tanous     if (discreteTriggers && numericThresholds.any())
431dd1c4a9cSSzymon Dompke     {
432dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "DiscreteTriggers",
433dd1c4a9cSSzymon Dompke                                         "NumericThresholds");
434dd1c4a9cSSzymon Dompke         messages::propertyValueConflict(res, "NumericThresholds",
435dd1c4a9cSSzymon Dompke                                         "DiscreteTriggers");
436dd1c4a9cSSzymon Dompke         return false;
437dd1c4a9cSSzymon Dompke     }
438dd1c4a9cSSzymon Dompke 
439dd1c4a9cSSzymon Dompke     if (ctx.discreteCondition)
440dd1c4a9cSSzymon Dompke     {
4412932dcb6SEd Tanous         if (numericThresholds.any())
442dd1c4a9cSSzymon Dompke         {
443dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggerCondition",
444dd1c4a9cSSzymon Dompke                                             "NumericThresholds");
445dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
446dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
447dd1c4a9cSSzymon Dompke             return false;
448dd1c4a9cSSzymon Dompke         }
449dd1c4a9cSSzymon Dompke     }
450dd1c4a9cSSzymon Dompke 
451dd1c4a9cSSzymon Dompke     if (ctx.metricType)
452dd1c4a9cSSzymon Dompke     {
4532932dcb6SEd Tanous         if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
454dd1c4a9cSSzymon Dompke         {
455dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "NumericThresholds",
456dd1c4a9cSSzymon Dompke                                             "MetricType");
457dd1c4a9cSSzymon Dompke             return false;
458dd1c4a9cSSzymon Dompke         }
459dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
460dd1c4a9cSSzymon Dompke         {
461dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
462dd1c4a9cSSzymon Dompke                                             "MetricType");
463dd1c4a9cSSzymon Dompke             return false;
464dd1c4a9cSSzymon Dompke         }
465dd1c4a9cSSzymon Dompke         if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
466dd1c4a9cSSzymon Dompke         {
467dd1c4a9cSSzymon Dompke             messages::propertyValueConflict(res, "DiscreteTriggers",
468dd1c4a9cSSzymon Dompke                                             "DiscreteTriggerCondition");
469dd1c4a9cSSzymon Dompke             return false;
470dd1c4a9cSSzymon Dompke         }
471dd1c4a9cSSzymon Dompke     }
472dd1c4a9cSSzymon Dompke 
473dd1c4a9cSSzymon Dompke     if (discreteTriggers || ctx.discreteCondition ||
474dd1c4a9cSSzymon Dompke         (ctx.metricType && *ctx.metricType == MetricType::Discrete))
475dd1c4a9cSSzymon Dompke     {
476dd1c4a9cSSzymon Dompke         if (ctx.discreteCondition)
477dd1c4a9cSSzymon Dompke         {
478dd1c4a9cSSzymon Dompke             if (*ctx.discreteCondition == DiscreteCondition::Specified &&
479dd1c4a9cSSzymon Dompke                 !discreteTriggers)
480dd1c4a9cSSzymon Dompke             {
481dd1c4a9cSSzymon Dompke                 messages::createFailedMissingReqProperties(res,
482dd1c4a9cSSzymon Dompke                                                            "DiscreteTriggers");
483dd1c4a9cSSzymon Dompke                 return false;
484dd1c4a9cSSzymon Dompke             }
485dd1c4a9cSSzymon Dompke             if (discreteTriggers &&
486dd1c4a9cSSzymon Dompke                 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
487dd1c4a9cSSzymon Dompke                   discreteTriggers->empty()) ||
488dd1c4a9cSSzymon Dompke                  (*ctx.discreteCondition == DiscreteCondition::Changed &&
489dd1c4a9cSSzymon Dompke                   !discreteTriggers->empty())))
490dd1c4a9cSSzymon Dompke             {
491dd1c4a9cSSzymon Dompke                 messages::propertyValueConflict(res, "DiscreteTriggers",
492dd1c4a9cSSzymon Dompke                                                 "DiscreteTriggerCondition");
493dd1c4a9cSSzymon Dompke                 return false;
494dd1c4a9cSSzymon Dompke             }
495dd1c4a9cSSzymon Dompke         }
496dd1c4a9cSSzymon Dompke         if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
497dd1c4a9cSSzymon Dompke         {
498dd1c4a9cSSzymon Dompke             return false;
499dd1c4a9cSSzymon Dompke         }
500dd1c4a9cSSzymon Dompke     }
5012932dcb6SEd Tanous     else if (numericThresholds.any())
502dd1c4a9cSSzymon Dompke     {
5032932dcb6SEd Tanous         if (!parseNumericThresholds(res, numericThresholds, ctx))
504dd1c4a9cSSzymon Dompke         {
505dd1c4a9cSSzymon Dompke             return false;
506dd1c4a9cSSzymon Dompke         }
507dd1c4a9cSSzymon Dompke     }
508dd1c4a9cSSzymon Dompke     else
509dd1c4a9cSSzymon Dompke     {
510dd1c4a9cSSzymon Dompke         messages::createFailedMissingReqProperties(
511dd1c4a9cSSzymon Dompke             res, "'DiscreteTriggers', 'NumericThresholds', "
512dd1c4a9cSSzymon Dompke                  "'DiscreteTriggerCondition' or 'MetricType'");
513dd1c4a9cSSzymon Dompke         return false;
514dd1c4a9cSSzymon Dompke     }
515dd1c4a9cSSzymon Dompke     return true;
516dd1c4a9cSSzymon Dompke }
517dd1c4a9cSSzymon Dompke 
5182932dcb6SEd Tanous inline bool parseLinks(crow::Response& res,
5192932dcb6SEd Tanous                        const std::vector<std::string>& metricReportDefinitions,
5202932dcb6SEd Tanous                        Context& ctx)
521dd1c4a9cSSzymon Dompke {
5222932dcb6SEd Tanous     ctx.reports.reserve(metricReportDefinitions.size());
5232932dcb6SEd Tanous     for (const std::string& reportDefinionUri : metricReportDefinitions)
524dd1c4a9cSSzymon Dompke     {
525dd1c4a9cSSzymon Dompke         std::optional<sdbusplus::message::object_path> reportPath =
526dd1c4a9cSSzymon Dompke             getReportPathFromReportDefinitionUri(reportDefinionUri);
527dd1c4a9cSSzymon Dompke         if (!reportPath)
528dd1c4a9cSSzymon Dompke         {
529dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricReportDefinitions",
530dd1c4a9cSSzymon Dompke                                              reportDefinionUri);
531dd1c4a9cSSzymon Dompke             return false;
532dd1c4a9cSSzymon Dompke         }
533dd1c4a9cSSzymon Dompke         ctx.reports.emplace_back(*reportPath);
534dd1c4a9cSSzymon Dompke     }
535dd1c4a9cSSzymon Dompke     return true;
536dd1c4a9cSSzymon Dompke }
537dd1c4a9cSSzymon Dompke 
538dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx)
539dd1c4a9cSSzymon Dompke {
540dd1c4a9cSSzymon Dompke     if (!ctx.metricProperties)
541dd1c4a9cSSzymon Dompke     {
542dd1c4a9cSSzymon Dompke         return true;
543dd1c4a9cSSzymon Dompke     }
544dd1c4a9cSSzymon Dompke 
545dd1c4a9cSSzymon Dompke     ctx.sensors.reserve(ctx.metricProperties->size());
546dd1c4a9cSSzymon Dompke 
547dd1c4a9cSSzymon Dompke     size_t uriIdx = 0;
548dd1c4a9cSSzymon Dompke     for (const std::string& uriStr : *ctx.metricProperties)
549dd1c4a9cSSzymon Dompke     {
5504a7fbefdSEd Tanous         boost::system::result<boost::urls::url> uri =
551dd1c4a9cSSzymon Dompke             boost::urls::parse_relative_ref(uriStr);
552dd1c4a9cSSzymon Dompke         if (!uri)
553dd1c4a9cSSzymon Dompke         {
554dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
555dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
556dd1c4a9cSSzymon Dompke             return false;
557dd1c4a9cSSzymon Dompke         }
558dd1c4a9cSSzymon Dompke         std::string chassisName;
559dd1c4a9cSSzymon Dompke         std::string sensorName;
560dd1c4a9cSSzymon Dompke         if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
561dd1c4a9cSSzymon Dompke                                             std::ref(chassisName), "Sensors",
562dd1c4a9cSSzymon Dompke                                             std::ref(sensorName)))
563dd1c4a9cSSzymon Dompke         {
564dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
565dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
566dd1c4a9cSSzymon Dompke             return false;
567dd1c4a9cSSzymon Dompke         }
568dd1c4a9cSSzymon Dompke 
569dd1c4a9cSSzymon Dompke         std::pair<std::string, std::string> split =
570dd1c4a9cSSzymon Dompke             splitSensorNameAndType(sensorName);
571dd1c4a9cSSzymon Dompke         if (split.first.empty() || split.second.empty())
572dd1c4a9cSSzymon Dompke         {
573dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(
574dd1c4a9cSSzymon Dompke                 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
575dd1c4a9cSSzymon Dompke             return false;
576dd1c4a9cSSzymon Dompke         }
577dd1c4a9cSSzymon Dompke 
578dd1c4a9cSSzymon Dompke         std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
579dd1c4a9cSSzymon Dompke                                  '/' + split.second;
580dd1c4a9cSSzymon Dompke 
581dd1c4a9cSSzymon Dompke         ctx.sensors.emplace_back(sensorPath, uriStr);
582dd1c4a9cSSzymon Dompke         uriIdx++;
583dd1c4a9cSSzymon Dompke     }
584dd1c4a9cSSzymon Dompke     return true;
585dd1c4a9cSSzymon Dompke }
586dd1c4a9cSSzymon Dompke 
587dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res,
588dd1c4a9cSSzymon Dompke                                    const crow::Request& req, Context& ctx)
589dd1c4a9cSSzymon Dompke {
590dd1c4a9cSSzymon Dompke     std::optional<std::string> id = "";
591dd1c4a9cSSzymon Dompke     std::optional<std::string> name = "";
592dd1c4a9cSSzymon Dompke     std::optional<std::string> metricType;
593dd1c4a9cSSzymon Dompke     std::optional<std::vector<std::string>> triggerActions;
594dd1c4a9cSSzymon Dompke     std::optional<std::string> discreteTriggerCondition;
5952932dcb6SEd Tanous     std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
5962932dcb6SEd Tanous     std::optional<std::vector<std::string>> metricReportDefinitions;
5972932dcb6SEd Tanous     NumericThresholds thresholds;
5982932dcb6SEd Tanous     // clang-format off
599dd1c4a9cSSzymon Dompke     if (!json_util::readJsonPatch(
6002932dcb6SEd Tanous             req, res,
6012932dcb6SEd Tanous 	    "Id", id,
6022932dcb6SEd Tanous             "Name", name,
6032932dcb6SEd Tanous 	    "MetricType", metricType,
6042932dcb6SEd Tanous             "TriggerActions", triggerActions,
6052932dcb6SEd Tanous             "DiscreteTriggerCondition", discreteTriggerCondition,
6062932dcb6SEd Tanous             "DiscreteTriggers", discreteTriggers,
6072932dcb6SEd Tanous             "NumericThresholds/UpperCritical", thresholds.upperCritical,
6082932dcb6SEd Tanous             "NumericThresholds/UpperWarning", thresholds.upperWarning,
6092932dcb6SEd Tanous             "NumericThresholds/LowerWarning", thresholds.lowerWarning,
6102932dcb6SEd Tanous             "NumericThresholds/LowerCritical", thresholds.lowerCritical,
6112932dcb6SEd Tanous             "MetricProperties", ctx.metricProperties,
6122932dcb6SEd Tanous             "Links/MetricReportDefinitions", metricReportDefinitions)
6132932dcb6SEd Tanous     )
614dd1c4a9cSSzymon Dompke     {
615dd1c4a9cSSzymon Dompke         return false;
616dd1c4a9cSSzymon Dompke     }
6172932dcb6SEd Tanous     // clang-format on
618dd1c4a9cSSzymon Dompke 
619dd1c4a9cSSzymon Dompke     ctx.id = *id;
620dd1c4a9cSSzymon Dompke     ctx.name = *name;
621dd1c4a9cSSzymon Dompke 
622dd1c4a9cSSzymon Dompke     if (metricType)
623dd1c4a9cSSzymon Dompke     {
624d5736ef2SEd Tanous         ctx.metricType = getMetricType(*metricType);
625d5736ef2SEd Tanous         if (!ctx.metricType)
626dd1c4a9cSSzymon Dompke         {
627dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "MetricType", *metricType);
628dd1c4a9cSSzymon Dompke             return false;
629dd1c4a9cSSzymon Dompke         }
630dd1c4a9cSSzymon Dompke     }
631dd1c4a9cSSzymon Dompke 
632dd1c4a9cSSzymon Dompke     if (discreteTriggerCondition)
633dd1c4a9cSSzymon Dompke     {
634d5736ef2SEd Tanous         ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
635d5736ef2SEd Tanous         if (!ctx.discreteCondition)
636dd1c4a9cSSzymon Dompke         {
637dd1c4a9cSSzymon Dompke             messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
638dd1c4a9cSSzymon Dompke                                              *discreteTriggerCondition);
639dd1c4a9cSSzymon Dompke             return false;
640dd1c4a9cSSzymon Dompke         }
641dd1c4a9cSSzymon Dompke     }
642dd1c4a9cSSzymon Dompke 
643dd1c4a9cSSzymon Dompke     if (triggerActions)
644dd1c4a9cSSzymon Dompke     {
645dd1c4a9cSSzymon Dompke         ctx.actions.reserve(triggerActions->size());
646dd1c4a9cSSzymon Dompke         for (const std::string& action : *triggerActions)
647dd1c4a9cSSzymon Dompke         {
648dd1c4a9cSSzymon Dompke             std::string dbusAction = toDbusTriggerAction(action);
649dd1c4a9cSSzymon Dompke 
650dd1c4a9cSSzymon Dompke             if (dbusAction.empty())
651dd1c4a9cSSzymon Dompke             {
652dd1c4a9cSSzymon Dompke                 messages::propertyValueNotInList(res, action, "TriggerActions");
653dd1c4a9cSSzymon Dompke                 return false;
654dd1c4a9cSSzymon Dompke             }
655dd1c4a9cSSzymon Dompke 
656dd1c4a9cSSzymon Dompke             ctx.actions.emplace_back(dbusAction);
657dd1c4a9cSSzymon Dompke         }
658dd1c4a9cSSzymon Dompke     }
659dd1c4a9cSSzymon Dompke     if (!parseMetricProperties(res, ctx))
660dd1c4a9cSSzymon Dompke     {
661dd1c4a9cSSzymon Dompke         return false;
662dd1c4a9cSSzymon Dompke     }
663dd1c4a9cSSzymon Dompke 
6642932dcb6SEd Tanous     if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
665dd1c4a9cSSzymon Dompke     {
666dd1c4a9cSSzymon Dompke         return false;
667dd1c4a9cSSzymon Dompke     }
668dd1c4a9cSSzymon Dompke 
6692932dcb6SEd Tanous     if (metricReportDefinitions)
670dd1c4a9cSSzymon Dompke     {
6712932dcb6SEd Tanous         if (!parseLinks(res, *metricReportDefinitions, ctx))
672dd1c4a9cSSzymon Dompke         {
673dd1c4a9cSSzymon Dompke             return false;
674dd1c4a9cSSzymon Dompke         }
675dd1c4a9cSSzymon Dompke     }
676dd1c4a9cSSzymon Dompke     return true;
677dd1c4a9cSSzymon Dompke }
678dd1c4a9cSSzymon Dompke 
679dd1c4a9cSSzymon Dompke inline void afterCreateTrigger(
680dd1c4a9cSSzymon Dompke     const boost::system::error_code& ec, const std::string& dbusPath,
681dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
682dd1c4a9cSSzymon Dompke {
683dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::file_exists)
684dd1c4a9cSSzymon Dompke     {
685dd1c4a9cSSzymon Dompke         messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
686dd1c4a9cSSzymon Dompke         return;
687dd1c4a9cSSzymon Dompke     }
688dd1c4a9cSSzymon Dompke     if (ec == boost::system::errc::too_many_files_open)
689dd1c4a9cSSzymon Dompke     {
690dd1c4a9cSSzymon Dompke         messages::createLimitReachedForResource(asyncResp->res);
691dd1c4a9cSSzymon Dompke         return;
692dd1c4a9cSSzymon Dompke     }
693dd1c4a9cSSzymon Dompke     if (ec)
694dd1c4a9cSSzymon Dompke     {
695dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
69662598e31SEd Tanous         BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
697dd1c4a9cSSzymon Dompke         return;
698dd1c4a9cSSzymon Dompke     }
699dd1c4a9cSSzymon Dompke 
700dd1c4a9cSSzymon Dompke     const std::optional<std::string>& triggerId =
701dd1c4a9cSSzymon Dompke         getTriggerIdFromDbusPath(dbusPath);
702dd1c4a9cSSzymon Dompke     if (!triggerId)
703dd1c4a9cSSzymon Dompke     {
704dd1c4a9cSSzymon Dompke         messages::internalError(asyncResp->res);
70562598e31SEd Tanous         BMCWEB_LOG_ERROR("Unknown data returned by "
70662598e31SEd Tanous                          "AddTrigger DBus method");
707dd1c4a9cSSzymon Dompke         return;
708dd1c4a9cSSzymon Dompke     }
709dd1c4a9cSSzymon Dompke 
710dd1c4a9cSSzymon Dompke     messages::created(asyncResp->res);
711dd1c4a9cSSzymon Dompke     boost::urls::url locationUrl = boost::urls::format(
712dd1c4a9cSSzymon Dompke         "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
713dd1c4a9cSSzymon Dompke     asyncResp->res.addHeader("Location", locationUrl.buffer());
714dd1c4a9cSSzymon Dompke }
715dd1c4a9cSSzymon Dompke 
716dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t>
717dd1c4a9cSSzymon Dompke     getTriggerActions(const std::vector<std::string>& dbusActions)
718dd1c4a9cSSzymon Dompke {
719dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggerActions;
720dd1c4a9cSSzymon Dompke     for (const std::string& dbusAction : dbusActions)
721dd1c4a9cSSzymon Dompke     {
722dd1c4a9cSSzymon Dompke         triggers::TriggerActionEnum redfishAction =
723dd1c4a9cSSzymon Dompke             toRedfishTriggerAction(dbusAction);
724dd1c4a9cSSzymon Dompke 
725dd1c4a9cSSzymon Dompke         if (redfishAction == triggers::TriggerActionEnum::Invalid)
726dd1c4a9cSSzymon Dompke         {
727dd1c4a9cSSzymon Dompke             return std::nullopt;
728dd1c4a9cSSzymon Dompke         }
729dd1c4a9cSSzymon Dompke 
730dd1c4a9cSSzymon Dompke         triggerActions.emplace_back(redfishAction);
731dd1c4a9cSSzymon Dompke     }
732dd1c4a9cSSzymon Dompke 
733dd1c4a9cSSzymon Dompke     return triggerActions;
7341b7e696bSLukasz Kazmierczak }
7351b7e696bSLukasz Kazmierczak 
7363f215c92SSzymon Dompke inline std::optional<nlohmann::json::array_t>
7371b7e696bSLukasz Kazmierczak     getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
7381b7e696bSLukasz Kazmierczak {
739dd1c4a9cSSzymon Dompke     nlohmann::json::array_t triggers;
7401b7e696bSLukasz Kazmierczak     const std::vector<DiscreteThresholdParams>* discreteParams =
7411b7e696bSLukasz Kazmierczak         std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
7421b7e696bSLukasz Kazmierczak 
743e662eae8SEd Tanous     if (discreteParams == nullptr)
7441b7e696bSLukasz Kazmierczak     {
7451b7e696bSLukasz Kazmierczak         return std::nullopt;
7461b7e696bSLukasz Kazmierczak     }
7471b7e696bSLukasz Kazmierczak 
7481b7e696bSLukasz Kazmierczak     for (const auto& [name, severity, dwellTime, value] : *discreteParams)
7491b7e696bSLukasz Kazmierczak     {
7501b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7511b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7521b7e696bSLukasz Kazmierczak 
7531b7e696bSLukasz Kazmierczak         if (!duration)
7541b7e696bSLukasz Kazmierczak         {
7551b7e696bSLukasz Kazmierczak             return std::nullopt;
7561b7e696bSLukasz Kazmierczak         }
757613dabeaSEd Tanous         nlohmann::json::object_t trigger;
758613dabeaSEd Tanous         trigger["Name"] = name;
759dd1c4a9cSSzymon Dompke         trigger["Severity"] = toRedfishSeverity(severity);
760613dabeaSEd Tanous         trigger["DwellTime"] = *duration;
761613dabeaSEd Tanous         trigger["Value"] = value;
762ad539545SPatrick Williams         triggers.emplace_back(std::move(trigger));
7631b7e696bSLukasz Kazmierczak     }
7641b7e696bSLukasz Kazmierczak 
765dd1c4a9cSSzymon Dompke     return triggers;
7661b7e696bSLukasz Kazmierczak }
7671b7e696bSLukasz Kazmierczak 
7681b7e696bSLukasz Kazmierczak inline std::optional<nlohmann::json>
7691b7e696bSLukasz Kazmierczak     getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
7701b7e696bSLukasz Kazmierczak {
771dd1c4a9cSSzymon Dompke     nlohmann::json::object_t thresholds;
7721b7e696bSLukasz Kazmierczak     const std::vector<NumericThresholdParams>* numericParams =
7731b7e696bSLukasz Kazmierczak         std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
7741b7e696bSLukasz Kazmierczak 
775e662eae8SEd Tanous     if (numericParams == nullptr)
7761b7e696bSLukasz Kazmierczak     {
7771b7e696bSLukasz Kazmierczak         return std::nullopt;
7781b7e696bSLukasz Kazmierczak     }
7791b7e696bSLukasz Kazmierczak 
7801b7e696bSLukasz Kazmierczak     for (const auto& [type, dwellTime, activation, reading] : *numericParams)
7811b7e696bSLukasz Kazmierczak     {
7821b7e696bSLukasz Kazmierczak         std::optional<std::string> duration =
7831b7e696bSLukasz Kazmierczak             time_utils::toDurationStringFromUint(dwellTime);
7841b7e696bSLukasz Kazmierczak 
7851b7e696bSLukasz Kazmierczak         if (!duration)
7861b7e696bSLukasz Kazmierczak         {
7871b7e696bSLukasz Kazmierczak             return std::nullopt;
7881b7e696bSLukasz Kazmierczak         }
789dd1c4a9cSSzymon Dompke         nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
7901476687dSEd Tanous         threshold["Reading"] = reading;
791dd1c4a9cSSzymon Dompke         threshold["Activation"] = toRedfishActivation(activation);
7921476687dSEd Tanous         threshold["DwellTime"] = *duration;
7931b7e696bSLukasz Kazmierczak     }
7941b7e696bSLukasz Kazmierczak 
795dd1c4a9cSSzymon Dompke     return thresholds;
7961b7e696bSLukasz Kazmierczak }
7971b7e696bSLukasz Kazmierczak 
7983f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions(
7993f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>& reportPaths)
8001b7e696bSLukasz Kazmierczak {
8011b7e696bSLukasz Kazmierczak     nlohmann::json reports = nlohmann::json::array();
8023f215c92SSzymon Dompke 
8033f215c92SSzymon Dompke     for (const sdbusplus::message::object_path& path : reportPaths)
8041b7e696bSLukasz Kazmierczak     {
8053f215c92SSzymon Dompke         std::string reportId = path.filename();
8063f215c92SSzymon Dompke         if (reportId.empty())
8073f215c92SSzymon Dompke         {
8083f215c92SSzymon Dompke             {
80962598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
81062598e31SEd Tanous                                  path.str);
8113f215c92SSzymon Dompke                 return std::nullopt;
8123f215c92SSzymon Dompke             }
8133f215c92SSzymon Dompke         }
8143f215c92SSzymon Dompke 
8151476687dSEd Tanous         nlohmann::json::object_t report;
816ef4c65b7SEd Tanous         report["@odata.id"] = boost::urls::format(
817ef4c65b7SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
818ef4c65b7SEd Tanous             reportId);
819b2ba3072SPatrick Williams         reports.emplace_back(std::move(report));
8201b7e696bSLukasz Kazmierczak     }
8211b7e696bSLukasz Kazmierczak 
8223f215c92SSzymon Dompke     return {std::move(reports)};
8231b7e696bSLukasz Kazmierczak }
8241b7e696bSLukasz Kazmierczak 
8251b7e696bSLukasz Kazmierczak inline std::vector<std::string>
8261b7e696bSLukasz Kazmierczak     getMetricProperties(const TriggerSensorsParams& sensors)
8271b7e696bSLukasz Kazmierczak {
8281b7e696bSLukasz Kazmierczak     std::vector<std::string> metricProperties;
8291b7e696bSLukasz Kazmierczak     metricProperties.reserve(sensors.size());
8301b7e696bSLukasz Kazmierczak     for (const auto& [_, metadata] : sensors)
8311b7e696bSLukasz Kazmierczak     {
8321b7e696bSLukasz Kazmierczak         metricProperties.emplace_back(metadata);
8331b7e696bSLukasz Kazmierczak     }
8341b7e696bSLukasz Kazmierczak 
8351b7e696bSLukasz Kazmierczak     return metricProperties;
8361b7e696bSLukasz Kazmierczak }
8371b7e696bSLukasz Kazmierczak 
8381b7e696bSLukasz Kazmierczak inline bool fillTrigger(
8391b7e696bSLukasz Kazmierczak     nlohmann::json& json, const std::string& id,
8401b7e696bSLukasz Kazmierczak     const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
8411b7e696bSLukasz Kazmierczak         properties)
8421b7e696bSLukasz Kazmierczak {
8431b7e696bSLukasz Kazmierczak     const std::string* name = nullptr;
8441b7e696bSLukasz Kazmierczak     const bool* discrete = nullptr;
8451b7e696bSLukasz Kazmierczak     const TriggerSensorsParams* sensors = nullptr;
8463f215c92SSzymon Dompke     const std::vector<sdbusplus::message::object_path>* reports = nullptr;
84789474494SKrzysztof Grobelny     const std::vector<std::string>* triggerActions = nullptr;
8481b7e696bSLukasz Kazmierczak     const TriggerThresholdParamsExt* thresholds = nullptr;
8491b7e696bSLukasz Kazmierczak 
85089474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
85189474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
85289474494SKrzysztof Grobelny         discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
85389474494SKrzysztof Grobelny         triggerActions, "Thresholds", thresholds);
85489474494SKrzysztof Grobelny 
85589474494SKrzysztof Grobelny     if (!success)
8561b7e696bSLukasz Kazmierczak     {
85789474494SKrzysztof Grobelny         return false;
8581b7e696bSLukasz Kazmierczak     }
8591b7e696bSLukasz Kazmierczak 
86089474494SKrzysztof Grobelny     if (triggerActions != nullptr)
86189474494SKrzysztof Grobelny     {
862dd1c4a9cSSzymon Dompke         std::optional<nlohmann::json::array_t> redfishTriggerActions =
86389474494SKrzysztof Grobelny             getTriggerActions(*triggerActions);
86489474494SKrzysztof Grobelny         if (!redfishTriggerActions)
8651b7e696bSLukasz Kazmierczak         {
86662598e31SEd Tanous             BMCWEB_LOG_ERROR(
86762598e31SEd Tanous                 "Property TriggerActions is invalid in Trigger: {}", id);
8681b7e696bSLukasz Kazmierczak             return false;
8691b7e696bSLukasz Kazmierczak         }
870dd1c4a9cSSzymon Dompke         json["TriggerActions"] = *redfishTriggerActions;
87189474494SKrzysztof Grobelny     }
8721b7e696bSLukasz Kazmierczak 
87389474494SKrzysztof Grobelny     if (reports != nullptr)
8743f215c92SSzymon Dompke     {
8753f215c92SSzymon Dompke         std::optional<nlohmann::json> linkedReports =
8763f215c92SSzymon Dompke             getMetricReportDefinitions(*reports);
8773f215c92SSzymon Dompke         if (!linkedReports)
8783f215c92SSzymon Dompke         {
87962598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
8803f215c92SSzymon Dompke             return false;
8813f215c92SSzymon Dompke         }
88289474494SKrzysztof Grobelny         json["Links"]["MetricReportDefinitions"] = *linkedReports;
88389474494SKrzysztof Grobelny     }
8841b7e696bSLukasz Kazmierczak 
88589474494SKrzysztof Grobelny     if (discrete != nullptr)
88689474494SKrzysztof Grobelny     {
8871b7e696bSLukasz Kazmierczak         if (*discrete)
8881b7e696bSLukasz Kazmierczak         {
8893f215c92SSzymon Dompke             std::optional<nlohmann::json::array_t> discreteTriggers =
8901b7e696bSLukasz Kazmierczak                 getDiscreteTriggers(*thresholds);
8911b7e696bSLukasz Kazmierczak 
8921b7e696bSLukasz Kazmierczak             if (!discreteTriggers)
8931b7e696bSLukasz Kazmierczak             {
89462598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
89562598e31SEd Tanous                                  "triggers in Trigger: {}",
89662598e31SEd Tanous                                  id);
8971b7e696bSLukasz Kazmierczak                 return false;
8981b7e696bSLukasz Kazmierczak             }
8991b7e696bSLukasz Kazmierczak 
9001b7e696bSLukasz Kazmierczak             json["DiscreteTriggers"] = *discreteTriggers;
9011b7e696bSLukasz Kazmierczak             json["DiscreteTriggerCondition"] =
9021b7e696bSLukasz Kazmierczak                 discreteTriggers->empty() ? "Changed" : "Specified";
9031b7e696bSLukasz Kazmierczak             json["MetricType"] = "Discrete";
9041b7e696bSLukasz Kazmierczak         }
9051b7e696bSLukasz Kazmierczak         else
9061b7e696bSLukasz Kazmierczak         {
9071b7e696bSLukasz Kazmierczak             std::optional<nlohmann::json> numericThresholds =
9081b7e696bSLukasz Kazmierczak                 getNumericThresholds(*thresholds);
9091b7e696bSLukasz Kazmierczak 
9101b7e696bSLukasz Kazmierczak             if (!numericThresholds)
9111b7e696bSLukasz Kazmierczak             {
91262598e31SEd Tanous                 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
91362598e31SEd Tanous                                  "thresholds in Trigger: {}",
91462598e31SEd Tanous                                  id);
9151b7e696bSLukasz Kazmierczak                 return false;
9161b7e696bSLukasz Kazmierczak             }
9171b7e696bSLukasz Kazmierczak 
9181b7e696bSLukasz Kazmierczak             json["NumericThresholds"] = *numericThresholds;
9191b7e696bSLukasz Kazmierczak             json["MetricType"] = "Numeric";
9201b7e696bSLukasz Kazmierczak         }
92189474494SKrzysztof Grobelny     }
92289474494SKrzysztof Grobelny 
92389474494SKrzysztof Grobelny     if (name != nullptr)
92489474494SKrzysztof Grobelny     {
92589474494SKrzysztof Grobelny         json["Name"] = *name;
92689474494SKrzysztof Grobelny     }
92789474494SKrzysztof Grobelny 
92889474494SKrzysztof Grobelny     if (sensors != nullptr)
92989474494SKrzysztof Grobelny     {
93089474494SKrzysztof Grobelny         json["MetricProperties"] = getMetricProperties(*sensors);
93189474494SKrzysztof Grobelny     }
9321b7e696bSLukasz Kazmierczak 
9333f215c92SSzymon Dompke     json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
934ef4c65b7SEd Tanous     json["@odata.id"] =
935ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
9363f215c92SSzymon Dompke     json["Id"] = id;
9371b7e696bSLukasz Kazmierczak 
9381b7e696bSLukasz Kazmierczak     return true;
9391b7e696bSLukasz Kazmierczak }
9401b7e696bSLukasz Kazmierczak 
941dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost(
942dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
943dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
944dd1c4a9cSSzymon Dompke {
945dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
946dd1c4a9cSSzymon Dompke     {
947dd1c4a9cSSzymon Dompke         return;
948dd1c4a9cSSzymon Dompke     }
949dd1c4a9cSSzymon Dompke 
950dd1c4a9cSSzymon Dompke     telemetry::Context ctx;
951dd1c4a9cSSzymon Dompke     if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
952dd1c4a9cSSzymon Dompke     {
953dd1c4a9cSSzymon Dompke         return;
954dd1c4a9cSSzymon Dompke     }
955dd1c4a9cSSzymon Dompke 
956dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
957dd1c4a9cSSzymon Dompke         [asyncResp, id = ctx.id](const boost::system::error_code& ec,
958dd1c4a9cSSzymon Dompke                                  const std::string& dbusPath) {
959dd1c4a9cSSzymon Dompke         afterCreateTrigger(ec, dbusPath, asyncResp, id);
960dd1c4a9cSSzymon Dompke     },
961dd1c4a9cSSzymon Dompke         service, "/xyz/openbmc_project/Telemetry/Triggers",
962dd1c4a9cSSzymon Dompke         "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
963dd1c4a9cSSzymon Dompke         "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
964dd1c4a9cSSzymon Dompke         ctx.reports, ctx.thresholds);
965dd1c4a9cSSzymon Dompke }
966dd1c4a9cSSzymon Dompke 
96707148cf2SLukasz Kazmierczak } // namespace telemetry
96807148cf2SLukasz Kazmierczak 
96907148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app)
97007148cf2SLukasz Kazmierczak {
97107148cf2SLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
97207148cf2SLukasz Kazmierczak         .privileges(redfish::privileges::getTriggersCollection)
97307148cf2SLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
97445ca1b86SEd Tanous             [&app](const crow::Request& req,
97507148cf2SLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
9763ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
97745ca1b86SEd Tanous         {
97845ca1b86SEd Tanous             return;
97945ca1b86SEd Tanous         }
98007148cf2SLukasz Kazmierczak         asyncResp->res.jsonValue["@odata.type"] =
98107148cf2SLukasz Kazmierczak             "#TriggersCollection.TriggersCollection";
982ae9031f0SWilly Tu         asyncResp->res.jsonValue["@odata.id"] =
983ae9031f0SWilly Tu             "/redfish/v1/TelemetryService/Triggers";
98407148cf2SLukasz Kazmierczak         asyncResp->res.jsonValue["Name"] = "Triggers Collection";
9857a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
9867a1dbc48SGeorge Liu             telemetry::triggerInterface};
98707148cf2SLukasz Kazmierczak         collection_util::getCollectionMembers(
988ae9031f0SWilly Tu             asyncResp,
989ae9031f0SWilly Tu             boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
990ae9031f0SWilly Tu             interfaces,
99107148cf2SLukasz Kazmierczak             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
99207148cf2SLukasz Kazmierczak     });
993dd1c4a9cSSzymon Dompke 
994dd1c4a9cSSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
995dd1c4a9cSSzymon Dompke         .privileges(redfish::privileges::postTriggersCollection)
996dd1c4a9cSSzymon Dompke         .methods(boost::beast::http::verb::post)(std::bind_front(
997dd1c4a9cSSzymon Dompke             telemetry::handleTriggerCollectionPost, std::ref(app)));
99807148cf2SLukasz Kazmierczak }
99907148cf2SLukasz Kazmierczak 
10001b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app)
10011b7e696bSLukasz Kazmierczak {
10021b7e696bSLukasz Kazmierczak     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
10031b7e696bSLukasz Kazmierczak         .privileges(redfish::privileges::getTriggers)
10041b7e696bSLukasz Kazmierczak         .methods(boost::beast::http::verb::get)(
100545ca1b86SEd Tanous             [&app](const crow::Request& req,
10061b7e696bSLukasz Kazmierczak                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10071b7e696bSLukasz Kazmierczak                    const std::string& id) {
10083ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
100945ca1b86SEd Tanous         {
101045ca1b86SEd Tanous             return;
101145ca1b86SEd Tanous         }
101289474494SKrzysztof Grobelny         sdbusplus::asio::getAllProperties(
101389474494SKrzysztof Grobelny             *crow::connections::systemBus, telemetry::service,
101489474494SKrzysztof Grobelny             telemetry::getDbusTriggerPath(id), telemetry::triggerInterface,
10151b7e696bSLukasz Kazmierczak             [asyncResp,
10165e7e2dc5SEd Tanous              id](const boost::system::error_code& ec,
10171b7e696bSLukasz Kazmierczak                  const std::vector<std::pair<
1018002d39b4SEd Tanous                      std::string, telemetry::TriggerGetParamsVariant>>& ret) {
10191b7e696bSLukasz Kazmierczak             if (ec.value() == EBADR ||
10201b7e696bSLukasz Kazmierczak                 ec == boost::system::errc::host_unreachable)
10211b7e696bSLukasz Kazmierczak             {
1022002d39b4SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Triggers", id);
10231b7e696bSLukasz Kazmierczak                 return;
10241b7e696bSLukasz Kazmierczak             }
10251b7e696bSLukasz Kazmierczak             if (ec)
10261b7e696bSLukasz Kazmierczak             {
102762598e31SEd Tanous                 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
10281b7e696bSLukasz Kazmierczak                 messages::internalError(asyncResp->res);
10291b7e696bSLukasz Kazmierczak                 return;
10301b7e696bSLukasz Kazmierczak             }
10311b7e696bSLukasz Kazmierczak 
1032002d39b4SEd Tanous             if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret))
10331b7e696bSLukasz Kazmierczak             {
10341b7e696bSLukasz Kazmierczak                 messages::internalError(asyncResp->res);
10351b7e696bSLukasz Kazmierczak             }
103689474494SKrzysztof Grobelny         });
10371b7e696bSLukasz Kazmierczak     });
1038163994a8SSzymon Dompke 
1039163994a8SSzymon Dompke     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1040163994a8SSzymon Dompke         .privileges(redfish::privileges::deleteTriggers)
1041163994a8SSzymon Dompke         .methods(boost::beast::http::verb::delete_)(
104245ca1b86SEd Tanous             [&app](const crow::Request& req,
1043163994a8SSzymon Dompke                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1044163994a8SSzymon Dompke                    const std::string& id) {
10453ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
104645ca1b86SEd Tanous         {
104745ca1b86SEd Tanous             return;
104845ca1b86SEd Tanous         }
1049002d39b4SEd Tanous         const std::string triggerPath = telemetry::getDbusTriggerPath(id);
1050163994a8SSzymon Dompke 
1051163994a8SSzymon Dompke         crow::connections::systemBus->async_method_call(
10525e7e2dc5SEd Tanous             [asyncResp, id](const boost::system::error_code& ec) {
1053163994a8SSzymon Dompke             if (ec.value() == EBADR)
1054163994a8SSzymon Dompke             {
1055002d39b4SEd Tanous                 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1056163994a8SSzymon Dompke                 return;
1057163994a8SSzymon Dompke             }
1058163994a8SSzymon Dompke 
1059163994a8SSzymon Dompke             if (ec)
1060163994a8SSzymon Dompke             {
106162598e31SEd Tanous                 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1062163994a8SSzymon Dompke                 messages::internalError(asyncResp->res);
1063163994a8SSzymon Dompke                 return;
1064163994a8SSzymon Dompke             }
1065163994a8SSzymon Dompke 
1066002d39b4SEd Tanous             asyncResp->res.result(boost::beast::http::status::no_content);
1067163994a8SSzymon Dompke         },
1068163994a8SSzymon Dompke             telemetry::service, triggerPath,
1069163994a8SSzymon Dompke             "xyz.openbmc_project.Object.Delete", "Delete");
1070163994a8SSzymon Dompke     });
10711b7e696bSLukasz Kazmierczak }
10721b7e696bSLukasz Kazmierczak 
107307148cf2SLukasz Kazmierczak } // namespace redfish
1074