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