blob: 306742a5535064853fa43b6a32a56bb006710a7e [file] [log] [blame]
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001#pragma once
2
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "app.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -07004#include "generated/enums/metric_definition.hpp"
Szymon Dompkedd1c4a92022-03-04 13:11:38 +01005#include "generated/enums/resource.hpp"
6#include "generated/enums/triggers.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08007#include "query.hpp"
8#include "registries/privilege_registry.hpp"
Szymon Dompkedd1c4a92022-03-04 13:11:38 +01009#include "utility.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020010#include "utils/collection.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080011#include "utils/dbus_utils.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070012#include "utils/json_utils.hpp"
Janet Adkins1516c212024-08-14 13:22:41 -050013#include "utils/sensor_utils.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020014#include "utils/telemetry_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080015#include "utils/time_utils.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020016
Ed Tanousef4c65b2023-04-24 15:28:50 -070017#include <boost/url/format.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020018#include <sdbusplus/asio/property.hpp>
19#include <sdbusplus/unpack_properties.hpp>
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020020
George Liu7a1dbc42022-12-07 16:03:22 +080021#include <array>
22#include <string_view>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020023#include <tuple>
24#include <variant>
25#include <vector>
26
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020027namespace redfish
28{
29namespace telemetry
30{
31constexpr const char* triggerInterface =
32 "xyz.openbmc_project.Telemetry.Trigger";
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020033
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020034using NumericThresholdParams =
35 std::tuple<std::string, uint64_t, std::string, double>;
36
37using DiscreteThresholdParams =
38 std::tuple<std::string, std::string, uint64_t, std::string>;
39
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010040using TriggerThresholdParams =
41 std::variant<std::vector<NumericThresholdParams>,
42 std::vector<DiscreteThresholdParams>>;
43
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020044using TriggerThresholdParamsExt =
45 std::variant<std::monostate, std::vector<NumericThresholdParams>,
46 std::vector<DiscreteThresholdParams>>;
47
48using TriggerSensorsParams =
49 std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
50
51using TriggerGetParamsVariant =
52 std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
Szymon Dompke3f215c92022-02-22 13:58:00 +010053 TriggerSensorsParams, std::vector<std::string>,
54 std::vector<sdbusplus::message::object_path>>;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020055
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010056inline triggers::TriggerActionEnum
57 toRedfishTriggerAction(std::string_view dbusValue)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020058{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010059 if (dbusValue ==
60 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020061 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010062 return triggers::TriggerActionEnum::RedfishMetricReport;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020063 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010064 if (dbusValue ==
65 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020066 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010067 return triggers::TriggerActionEnum::RedfishEvent;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020068 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010069 if (dbusValue ==
70 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020071 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010072 return triggers::TriggerActionEnum::LogToLogService;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020073 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010074 return triggers::TriggerActionEnum::Invalid;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020075}
76
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010077inline std::string toDbusTriggerAction(std::string_view redfishValue)
78{
79 if (redfishValue == "RedfishMetricReport")
80 {
81 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
82 }
83 if (redfishValue == "RedfishEvent")
84 {
85 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
86 }
87 if (redfishValue == "LogToLogService")
88 {
89 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
90 }
91 return "";
92}
93
94inline std::string toDbusSeverity(std::string_view redfishValue)
95{
96 if (redfishValue == "OK")
97 {
98 return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
99 }
100 if (redfishValue == "Warning")
101 {
102 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
103 }
104 if (redfishValue == "Critical")
105 {
106 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
107 }
108 return "";
109}
110
111inline resource::Health toRedfishSeverity(std::string_view dbusValue)
112{
113 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
114 {
115 return resource::Health::OK;
116 }
117 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
118 {
119 return resource::Health::Warning;
120 }
121 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
122 {
123 return resource::Health::Critical;
124 }
125 return resource::Health::Invalid;
126}
127
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100128inline std::string toRedfishThresholdName(std::string_view dbusValue)
129{
130 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
131 {
132 return "UpperCritical";
133 }
134
135 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
136 {
137 return "LowerCritical";
138 }
139
140 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
141 {
142 return "UpperWarning";
143 }
144
145 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
146 {
147 return "LowerWarning";
148 }
149
150 return "";
151}
152
153inline std::string toDbusActivation(std::string_view redfishValue)
154{
155 if (redfishValue == "Either")
156 {
157 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
158 }
159
160 if (redfishValue == "Decreasing")
161 {
162 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
163 }
164
165 if (redfishValue == "Increasing")
166 {
167 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
168 }
169
170 return "";
171}
172
173inline triggers::ThresholdActivation
174 toRedfishActivation(std::string_view dbusValue)
175{
176 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
177 {
178 return triggers::ThresholdActivation::Either;
179 }
180
181 if (dbusValue ==
182 "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
183 {
184 return triggers::ThresholdActivation::Decreasing;
185 }
186
187 if (dbusValue ==
188 "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
189 {
190 return triggers::ThresholdActivation::Increasing;
191 }
192
193 return triggers::ThresholdActivation::Invalid;
194}
195
196enum class MetricType
197{
198 Discrete,
199 Numeric
200};
201
202enum class DiscreteCondition
203{
204 Specified,
205 Changed
206};
207
208struct Context
209{
210 std::string id;
211 std::string name;
212 std::vector<std::string> actions;
213 std::vector<std::pair<sdbusplus::message::object_path, std::string>>
214 sensors;
215 std::vector<sdbusplus::message::object_path> reports;
216 TriggerThresholdParams thresholds;
217
218 std::optional<DiscreteCondition> discreteCondition;
219 std::optional<MetricType> metricType;
220 std::optional<std::vector<std::string>> metricProperties;
221};
222
223inline std::optional<sdbusplus::message::object_path>
224 getReportPathFromReportDefinitionUri(const std::string& uri)
225{
Ed Tanous6fd29552023-10-04 09:40:14 -0700226 boost::system::result<boost::urls::url_view> parsed =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100227 boost::urls::parse_relative_ref(uri);
228
229 if (!parsed)
230 {
231 return std::nullopt;
232 }
233
234 std::string id;
235 if (!crow::utility::readUrlSegments(
236 *parsed, "redfish", "v1", "TelemetryService",
237 "MetricReportDefinitions", std::ref(id)))
238 {
239 return std::nullopt;
240 }
241
242 return sdbusplus::message::object_path(
243 "/xyz/openbmc_project/Telemetry/Reports") /
244 "TelemetryService" / id;
245}
246
247inline std::optional<MetricType> getMetricType(const std::string& metricType)
248{
249 if (metricType == "Discrete")
250 {
251 return MetricType::Discrete;
252 }
253 if (metricType == "Numeric")
254 {
255 return MetricType::Numeric;
256 }
257 return std::nullopt;
258}
259
260inline std::optional<DiscreteCondition>
261 getDiscreteCondition(const std::string& discreteTriggerCondition)
262{
263 if (discreteTriggerCondition == "Specified")
264 {
265 return DiscreteCondition::Specified;
266 }
267 if (discreteTriggerCondition == "Changed")
268 {
269 return DiscreteCondition::Changed;
270 }
271 return std::nullopt;
272}
273
Ed Tanous2932dcb2024-03-06 12:04:47 -0800274inline bool parseThreshold(crow::Response& res,
275 nlohmann::json::object_t& threshold,
276 std::string_view dbusThresholdName,
277 std::vector<NumericThresholdParams>& parsedParams)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100278{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800279 double reading = 0.0;
280 std::string activation;
281 std::string dwellTimeStr;
282
Myung Baeafc474a2024-10-09 00:53:29 -0700283 if (!json_util::readJsonObject( //
284 threshold, res, //
285 "Activation", activation, //
286 "DwellTime", dwellTimeStr, //
287 "Reading", reading //
288 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100289 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100290 return false;
291 }
292
Ed Tanous2932dcb2024-03-06 12:04:47 -0800293 std::string dbusActivation = toDbusActivation(activation);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100294
Ed Tanous2932dcb2024-03-06 12:04:47 -0800295 if (dbusActivation.empty())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100296 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800297 messages::propertyValueIncorrect(res, "Activation", activation);
298 return false;
299 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100300
Ed Tanous2932dcb2024-03-06 12:04:47 -0800301 std::optional<std::chrono::milliseconds> dwellTime =
302 time_utils::fromDurationString(dwellTimeStr);
303 if (!dwellTime)
304 {
305 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
306 return false;
307 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100308
Ed Tanous2932dcb2024-03-06 12:04:47 -0800309 parsedParams.emplace_back(dbusThresholdName,
310 static_cast<uint64_t>(dwellTime->count()),
311 dbusActivation, reading);
312 return true;
313}
314
315struct NumericThresholds
316{
317 std::optional<nlohmann::json::object_t> upperCritical;
318 std::optional<nlohmann::json::object_t> upperWarning;
319 std::optional<nlohmann::json::object_t> lowerWarning;
320 std::optional<nlohmann::json::object_t> lowerCritical;
321
322 bool any() const
323 {
324 return upperCritical || upperWarning || lowerWarning || lowerCritical;
325 }
326};
327
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400328inline bool parseNumericThresholds(
329 crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
Ed Tanous2932dcb2024-03-06 12:04:47 -0800330{
331 std::vector<NumericThresholdParams> parsedParams;
332 if (numericThresholds.upperCritical)
333 {
334 if (!parseThreshold(
335 res, *numericThresholds.upperCritical,
336 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
337 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100338 {
339 return false;
340 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800341 }
342 if (numericThresholds.upperWarning)
343 {
344 if (!parseThreshold(
345 res, *numericThresholds.upperWarning,
346 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
347 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100348 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100349 return false;
350 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800351 }
352 if (numericThresholds.lowerWarning)
353 {
354 if (!parseThreshold(
355 res, *numericThresholds.lowerWarning,
356 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
357 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100358 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100359 return false;
360 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800361 }
362 if (numericThresholds.lowerCritical)
363 {
364 if (!parseThreshold(
365 res, *numericThresholds.lowerCritical,
366 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
367 parsedParams))
368 {
369 return false;
370 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100371 }
372
373 ctx.thresholds = std::move(parsedParams);
374 return true;
375}
376
377inline bool parseDiscreteTriggers(
378 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800379 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
380 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100381{
382 std::vector<DiscreteThresholdParams> parsedParams;
383 if (!discreteTriggers)
384 {
385 ctx.thresholds = std::move(parsedParams);
386 return true;
387 }
388
389 parsedParams.reserve(discreteTriggers->size());
Ed Tanous2932dcb2024-03-06 12:04:47 -0800390 for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100391 {
392 std::optional<std::string> name = "";
393 std::string value;
394 std::string dwellTimeStr;
395 std::string severity;
396
Myung Baeafc474a2024-10-09 00:53:29 -0700397 if (!json_util::readJsonObject( //
398 thresholdInfo, res, //
399 "DwellTime", dwellTimeStr, //
400 "Name", name, //
401 "Severity", severity, //
402 "Value", value //
403 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100404 {
405 return false;
406 }
407
408 std::optional<std::chrono::milliseconds> dwellTime =
409 time_utils::fromDurationString(dwellTimeStr);
410 if (!dwellTime)
411 {
412 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
413 return false;
414 }
415
416 std::string dbusSeverity = toDbusSeverity(severity);
417 if (dbusSeverity.empty())
418 {
419 messages::propertyValueIncorrect(res, "Severity", severity);
420 return false;
421 }
422
423 parsedParams.emplace_back(*name, dbusSeverity,
424 static_cast<uint64_t>(dwellTime->count()),
425 value);
426 }
427
428 ctx.thresholds = std::move(parsedParams);
429 return true;
430}
431
432inline bool parseTriggerThresholds(
433 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800434 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
435 NumericThresholds& numericThresholds, Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100436{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800437 if (discreteTriggers && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100438 {
439 messages::propertyValueConflict(res, "DiscreteTriggers",
440 "NumericThresholds");
441 messages::propertyValueConflict(res, "NumericThresholds",
442 "DiscreteTriggers");
443 return false;
444 }
445
446 if (ctx.discreteCondition)
447 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800448 if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100449 {
450 messages::propertyValueConflict(res, "DiscreteTriggerCondition",
451 "NumericThresholds");
452 messages::propertyValueConflict(res, "NumericThresholds",
453 "DiscreteTriggerCondition");
454 return false;
455 }
456 }
457
458 if (ctx.metricType)
459 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800460 if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100461 {
462 messages::propertyValueConflict(res, "NumericThresholds",
463 "MetricType");
464 return false;
465 }
466 if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
467 {
468 messages::propertyValueConflict(res, "DiscreteTriggers",
469 "MetricType");
470 return false;
471 }
472 if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
473 {
474 messages::propertyValueConflict(res, "DiscreteTriggers",
475 "DiscreteTriggerCondition");
476 return false;
477 }
478 }
479
480 if (discreteTriggers || ctx.discreteCondition ||
481 (ctx.metricType && *ctx.metricType == MetricType::Discrete))
482 {
483 if (ctx.discreteCondition)
484 {
485 if (*ctx.discreteCondition == DiscreteCondition::Specified &&
486 !discreteTriggers)
487 {
488 messages::createFailedMissingReqProperties(res,
489 "DiscreteTriggers");
490 return false;
491 }
492 if (discreteTriggers &&
493 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
494 discreteTriggers->empty()) ||
495 (*ctx.discreteCondition == DiscreteCondition::Changed &&
496 !discreteTriggers->empty())))
497 {
498 messages::propertyValueConflict(res, "DiscreteTriggers",
499 "DiscreteTriggerCondition");
500 return false;
501 }
502 }
503 if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
504 {
505 return false;
506 }
507 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800508 else if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100509 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800510 if (!parseNumericThresholds(res, numericThresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100511 {
512 return false;
513 }
514 }
515 else
516 {
517 messages::createFailedMissingReqProperties(
518 res, "'DiscreteTriggers', 'NumericThresholds', "
519 "'DiscreteTriggerCondition' or 'MetricType'");
520 return false;
521 }
522 return true;
523}
524
Ed Tanous2932dcb2024-03-06 12:04:47 -0800525inline bool parseLinks(crow::Response& res,
526 const std::vector<std::string>& metricReportDefinitions,
527 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100528{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800529 ctx.reports.reserve(metricReportDefinitions.size());
530 for (const std::string& reportDefinionUri : metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100531 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800532 std::optional<sdbusplus::message::object_path> reportPath =
533 getReportPathFromReportDefinitionUri(reportDefinionUri);
534 if (!reportPath)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100535 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800536 messages::propertyValueIncorrect(res, "MetricReportDefinitions",
537 reportDefinionUri);
538 return false;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100539 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800540 ctx.reports.emplace_back(*reportPath);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100541 }
542 return true;
543}
544
545inline bool parseMetricProperties(crow::Response& res, Context& ctx)
546{
547 if (!ctx.metricProperties)
548 {
549 return true;
550 }
551
552 ctx.sensors.reserve(ctx.metricProperties->size());
553
554 size_t uriIdx = 0;
555 for (const std::string& uriStr : *ctx.metricProperties)
556 {
Ed Tanous4a7fbef2024-04-06 16:03:49 -0700557 boost::system::result<boost::urls::url> uri =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100558 boost::urls::parse_relative_ref(uriStr);
559 if (!uri)
560 {
561 messages::propertyValueIncorrect(
562 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
563 return false;
564 }
565 std::string chassisName;
566 std::string sensorName;
567 if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
568 std::ref(chassisName), "Sensors",
569 std::ref(sensorName)))
570 {
571 messages::propertyValueIncorrect(
572 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
573 return false;
574 }
575
576 std::pair<std::string, std::string> split =
Janet Adkins1516c212024-08-14 13:22:41 -0500577 redfish::sensor_utils::splitSensorNameAndType(sensorName);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100578 if (split.first.empty() || split.second.empty())
579 {
580 messages::propertyValueIncorrect(
581 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
582 return false;
583 }
584
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400585 std::string sensorPath =
586 "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100587
588 ctx.sensors.emplace_back(sensorPath, uriStr);
589 uriIdx++;
590 }
591 return true;
592}
593
594inline bool parsePostTriggerParams(crow::Response& res,
595 const crow::Request& req, Context& ctx)
596{
597 std::optional<std::string> id = "";
598 std::optional<std::string> name = "";
599 std::optional<std::string> metricType;
600 std::optional<std::vector<std::string>> triggerActions;
601 std::optional<std::string> discreteTriggerCondition;
Ed Tanous2932dcb2024-03-06 12:04:47 -0800602 std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
603 std::optional<std::vector<std::string>> metricReportDefinitions;
604 NumericThresholds thresholds;
Myung Baeafc474a2024-10-09 00:53:29 -0700605
606 if (!json_util::readJsonPatch( //
607 req, res, //
608 "Id", id, //
609 "DiscreteTriggerCondition", discreteTriggerCondition, //
610 "DiscreteTriggers", discreteTriggers, //
611 "Links/MetricReportDefinitions", metricReportDefinitions, //
612 "MetricProperties", ctx.metricProperties, //
613 "MetricType", metricType, //
614 "Name", name, //
615 "NumericThresholds/LowerCritical", thresholds.lowerCritical, //
616 "NumericThresholds/LowerWarning", thresholds.lowerWarning, //
617 "NumericThresholds/UpperCritical", thresholds.upperCritical, //
618 "NumericThresholds/UpperWarning", thresholds.upperWarning, //
619 "TriggerActions", triggerActions //
620 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100621 {
622 return false;
623 }
624
625 ctx.id = *id;
626 ctx.name = *name;
627
628 if (metricType)
629 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700630 ctx.metricType = getMetricType(*metricType);
631 if (!ctx.metricType)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100632 {
633 messages::propertyValueIncorrect(res, "MetricType", *metricType);
634 return false;
635 }
636 }
637
638 if (discreteTriggerCondition)
639 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700640 ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
641 if (!ctx.discreteCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100642 {
643 messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
644 *discreteTriggerCondition);
645 return false;
646 }
647 }
648
649 if (triggerActions)
650 {
651 ctx.actions.reserve(triggerActions->size());
652 for (const std::string& action : *triggerActions)
653 {
654 std::string dbusAction = toDbusTriggerAction(action);
655
656 if (dbusAction.empty())
657 {
658 messages::propertyValueNotInList(res, action, "TriggerActions");
659 return false;
660 }
661
662 ctx.actions.emplace_back(dbusAction);
663 }
664 }
665 if (!parseMetricProperties(res, ctx))
666 {
667 return false;
668 }
669
Ed Tanous2932dcb2024-03-06 12:04:47 -0800670 if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100671 {
672 return false;
673 }
674
Ed Tanous2932dcb2024-03-06 12:04:47 -0800675 if (metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100676 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800677 if (!parseLinks(res, *metricReportDefinitions, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100678 {
679 return false;
680 }
681 }
682 return true;
683}
684
685inline void afterCreateTrigger(
686 const boost::system::error_code& ec, const std::string& dbusPath,
687 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
688{
689 if (ec == boost::system::errc::file_exists)
690 {
691 messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
692 return;
693 }
694 if (ec == boost::system::errc::too_many_files_open)
695 {
696 messages::createLimitReachedForResource(asyncResp->res);
697 return;
698 }
699 if (ec)
700 {
701 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700702 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100703 return;
704 }
705
706 const std::optional<std::string>& triggerId =
707 getTriggerIdFromDbusPath(dbusPath);
708 if (!triggerId)
709 {
710 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700711 BMCWEB_LOG_ERROR("Unknown data returned by "
712 "AddTrigger DBus method");
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100713 return;
714 }
715
716 messages::created(asyncResp->res);
717 boost::urls::url locationUrl = boost::urls::format(
718 "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
719 asyncResp->res.addHeader("Location", locationUrl.buffer());
720}
721
722inline std::optional<nlohmann::json::array_t>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200723 getTriggerActions(const std::vector<std::string>& dbusActions)
724{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100725 nlohmann::json::array_t triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200726 for (const std::string& dbusAction : dbusActions)
727 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100728 triggers::TriggerActionEnum redfishAction =
729 toRedfishTriggerAction(dbusAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200730
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100731 if (redfishAction == triggers::TriggerActionEnum::Invalid)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200732 {
733 return std::nullopt;
734 }
735
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100736 triggerActions.emplace_back(redfishAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200737 }
738
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100739 return triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200740}
741
Szymon Dompke3f215c92022-02-22 13:58:00 +0100742inline std::optional<nlohmann::json::array_t>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200743 getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
744{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100745 nlohmann::json::array_t triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200746 const std::vector<DiscreteThresholdParams>* discreteParams =
747 std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
748
Ed Tanouse662eae2022-01-25 10:39:19 -0800749 if (discreteParams == nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200750 {
751 return std::nullopt;
752 }
753
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200754 for (const auto& [name, severity, dwellTime, value] : *discreteParams)
755 {
756 std::optional<std::string> duration =
757 time_utils::toDurationStringFromUint(dwellTime);
758
759 if (!duration)
760 {
761 return std::nullopt;
762 }
Ed Tanous613dabe2022-07-09 11:17:36 -0700763 nlohmann::json::object_t trigger;
764 trigger["Name"] = name;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100765 trigger["Severity"] = toRedfishSeverity(severity);
Ed Tanous613dabe2022-07-09 11:17:36 -0700766 trigger["DwellTime"] = *duration;
767 trigger["Value"] = value;
Patrick Williamsad539542023-05-12 10:10:08 -0500768 triggers.emplace_back(std::move(trigger));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200769 }
770
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100771 return triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200772}
773
774inline std::optional<nlohmann::json>
775 getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
776{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100777 nlohmann::json::object_t thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200778 const std::vector<NumericThresholdParams>* numericParams =
779 std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
780
Ed Tanouse662eae2022-01-25 10:39:19 -0800781 if (numericParams == nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200782 {
783 return std::nullopt;
784 }
785
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200786 for (const auto& [type, dwellTime, activation, reading] : *numericParams)
787 {
788 std::optional<std::string> duration =
789 time_utils::toDurationStringFromUint(dwellTime);
790
791 if (!duration)
792 {
793 return std::nullopt;
794 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100795 nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
Ed Tanous14766872022-03-15 10:44:42 -0700796 threshold["Reading"] = reading;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100797 threshold["Activation"] = toRedfishActivation(activation);
Ed Tanous14766872022-03-15 10:44:42 -0700798 threshold["DwellTime"] = *duration;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200799 }
800
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100801 return thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200802}
803
Szymon Dompke3f215c92022-02-22 13:58:00 +0100804inline std::optional<nlohmann::json> getMetricReportDefinitions(
805 const std::vector<sdbusplus::message::object_path>& reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200806{
807 nlohmann::json reports = nlohmann::json::array();
Szymon Dompke3f215c92022-02-22 13:58:00 +0100808
809 for (const sdbusplus::message::object_path& path : reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200810 {
Szymon Dompke3f215c92022-02-22 13:58:00 +0100811 std::string reportId = path.filename();
812 if (reportId.empty())
813 {
814 {
Ed Tanous62598e32023-07-17 17:06:25 -0700815 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
816 path.str);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100817 return std::nullopt;
818 }
819 }
820
Ed Tanous14766872022-03-15 10:44:42 -0700821 nlohmann::json::object_t report;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700822 report["@odata.id"] = boost::urls::format(
823 "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
824 reportId);
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500825 reports.emplace_back(std::move(report));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200826 }
827
Szymon Dompke3f215c92022-02-22 13:58:00 +0100828 return {std::move(reports)};
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200829}
830
831inline std::vector<std::string>
832 getMetricProperties(const TriggerSensorsParams& sensors)
833{
834 std::vector<std::string> metricProperties;
835 metricProperties.reserve(sensors.size());
836 for (const auto& [_, metadata] : sensors)
837 {
838 metricProperties.emplace_back(metadata);
839 }
840
841 return metricProperties;
842}
843
844inline bool fillTrigger(
845 nlohmann::json& json, const std::string& id,
846 const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
847 properties)
848{
849 const std::string* name = nullptr;
850 const bool* discrete = nullptr;
851 const TriggerSensorsParams* sensors = nullptr;
Szymon Dompke3f215c92022-02-22 13:58:00 +0100852 const std::vector<sdbusplus::message::object_path>* reports = nullptr;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200853 const std::vector<std::string>* triggerActions = nullptr;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200854 const TriggerThresholdParamsExt* thresholds = nullptr;
855
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200856 const bool success = sdbusplus::unpackPropertiesNoThrow(
857 dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
858 discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
859 triggerActions, "Thresholds", thresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200860
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200861 if (!success)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200862 {
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200863 return false;
864 }
865
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200866 if (triggerActions != nullptr)
Szymon Dompke3f215c92022-02-22 13:58:00 +0100867 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100868 std::optional<nlohmann::json::array_t> redfishTriggerActions =
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200869 getTriggerActions(*triggerActions);
870 if (!redfishTriggerActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200871 {
Ed Tanous62598e32023-07-17 17:06:25 -0700872 BMCWEB_LOG_ERROR(
873 "Property TriggerActions is invalid in Trigger: {}", id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200874 return false;
875 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100876 json["TriggerActions"] = *redfishTriggerActions;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200877 }
878
879 if (reports != nullptr)
880 {
881 std::optional<nlohmann::json> linkedReports =
882 getMetricReportDefinitions(*reports);
883 if (!linkedReports)
884 {
Ed Tanous62598e32023-07-17 17:06:25 -0700885 BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200886 return false;
887 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200888 json["Links"]["MetricReportDefinitions"] = *linkedReports;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200889 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200890
891 if (discrete != nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200892 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200893 if (*discrete)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200894 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200895 std::optional<nlohmann::json::array_t> discreteTriggers =
896 getDiscreteTriggers(*thresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200897
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200898 if (!discreteTriggers)
899 {
Ed Tanous62598e32023-07-17 17:06:25 -0700900 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
901 "triggers in Trigger: {}",
902 id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200903 return false;
904 }
905
906 json["DiscreteTriggers"] = *discreteTriggers;
907 json["DiscreteTriggerCondition"] =
908 discreteTriggers->empty() ? "Changed" : "Specified";
Ed Tanous539d8c62024-06-19 14:38:27 -0700909 json["MetricType"] = metric_definition::MetricType::Discrete;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200910 }
911 else
912 {
913 std::optional<nlohmann::json> numericThresholds =
914 getNumericThresholds(*thresholds);
915
916 if (!numericThresholds)
917 {
Ed Tanous62598e32023-07-17 17:06:25 -0700918 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
919 "thresholds in Trigger: {}",
920 id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200921 return false;
922 }
923
924 json["NumericThresholds"] = *numericThresholds;
Ed Tanous539d8c62024-06-19 14:38:27 -0700925 json["MetricType"] = metric_definition::MetricType::Numeric;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200926 }
927 }
928
929 if (name != nullptr)
930 {
931 json["Name"] = *name;
932 }
933
934 if (sensors != nullptr)
935 {
936 json["MetricProperties"] = getMetricProperties(*sensors);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200937 }
938
Szymon Dompke3f215c92022-02-22 13:58:00 +0100939 json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700940 json["@odata.id"] =
941 boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100942 json["Id"] = id;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200943
944 return true;
945}
946
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100947inline void handleTriggerCollectionPost(
948 App& app, const crow::Request& req,
949 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
950{
951 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
952 {
953 return;
954 }
955
956 telemetry::Context ctx;
957 if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
958 {
959 return;
960 }
961
962 crow::connections::systemBus->async_method_call(
963 [asyncResp, id = ctx.id](const boost::system::error_code& ec,
964 const std::string& dbusPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400965 afterCreateTrigger(ec, dbusPath, asyncResp, id);
966 },
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100967 service, "/xyz/openbmc_project/Telemetry/Triggers",
968 "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
969 "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
970 ctx.reports, ctx.thresholds);
971}
972
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200973} // namespace telemetry
974
975inline void requestRoutesTriggerCollection(App& app)
976{
977 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
978 .privileges(redfish::privileges::getTriggersCollection)
979 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700980 [&app](const crow::Request& req,
981 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400982 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
983 {
984 return;
985 }
986 asyncResp->res.jsonValue["@odata.type"] =
987 "#TriggersCollection.TriggersCollection";
988 asyncResp->res.jsonValue["@odata.id"] =
989 "/redfish/v1/TelemetryService/Triggers";
990 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
991 constexpr std::array<std::string_view, 1> interfaces{
992 telemetry::triggerInterface};
993 collection_util::getCollectionMembers(
994 asyncResp,
995 boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
996 interfaces,
997 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
998 });
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100999
1000 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
1001 .privileges(redfish::privileges::postTriggersCollection)
1002 .methods(boost::beast::http::verb::post)(std::bind_front(
1003 telemetry::handleTriggerCollectionPost, std::ref(app)));
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001004}
1005
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001006inline void requestRoutesTrigger(App& app)
1007{
1008 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1009 .privileges(redfish::privileges::getTriggers)
1010 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001011 [&app](const crow::Request& req,
1012 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1013 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001014 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1015 {
1016 return;
1017 }
1018 sdbusplus::asio::getAllProperties(
1019 *crow::connections::systemBus, telemetry::service,
1020 telemetry::getDbusTriggerPath(id),
1021 telemetry::triggerInterface,
1022 [asyncResp,
1023 id](const boost::system::error_code& ec,
1024 const std::vector<std::pair<
1025 std::string, telemetry::TriggerGetParamsVariant>>&
1026 ret) {
1027 if (ec.value() == EBADR ||
1028 ec == boost::system::errc::host_unreachable)
1029 {
1030 messages::resourceNotFound(asyncResp->res,
1031 "Triggers", id);
1032 return;
1033 }
1034 if (ec)
1035 {
1036 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1037 messages::internalError(asyncResp->res);
1038 return;
1039 }
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001040
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001041 if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
1042 id, ret))
1043 {
1044 messages::internalError(asyncResp->res);
1045 }
1046 });
1047 });
Szymon Dompke163994a2021-08-12 17:30:23 +02001048
1049 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1050 .privileges(redfish::privileges::deleteTriggers)
1051 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001052 [&app](const crow::Request& req,
1053 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1054 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001055 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1056 {
1057 return;
1058 }
1059 const std::string triggerPath =
1060 telemetry::getDbusTriggerPath(id);
Szymon Dompke163994a2021-08-12 17:30:23 +02001061
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001062 crow::connections::systemBus->async_method_call(
1063 [asyncResp, id](const boost::system::error_code& ec) {
1064 if (ec.value() == EBADR)
1065 {
1066 messages::resourceNotFound(asyncResp->res,
1067 "Triggers", id);
1068 return;
1069 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001070
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001071 if (ec)
1072 {
1073 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1074 messages::internalError(asyncResp->res);
1075 return;
1076 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001077
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001078 asyncResp->res.result(
1079 boost::beast::http::status::no_content);
1080 },
1081 telemetry::service, triggerPath,
1082 "xyz.openbmc_project.Object.Delete", "Delete");
1083 });
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001084}
1085
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001086} // namespace redfish