blob: a6101a2a1d115d618113dca290284f207b60cc9d [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"
Szymon Dompkedd1c4a92022-03-04 13:11:38 +01004#include "generated/enums/resource.hpp"
5#include "generated/enums/triggers.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08006#include "query.hpp"
7#include "registries/privilege_registry.hpp"
Szymon Dompkedd1c4a92022-03-04 13:11:38 +01008#include "sensors.hpp"
9#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"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020013#include "utils/telemetry_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080014#include "utils/time_utils.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020015
Ed Tanousef4c65b2023-04-24 15:28:50 -070016#include <boost/url/format.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020017#include <sdbusplus/asio/property.hpp>
18#include <sdbusplus/unpack_properties.hpp>
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020019
George Liu7a1dbc42022-12-07 16:03:22 +080020#include <array>
21#include <string_view>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020022#include <tuple>
23#include <variant>
24#include <vector>
25
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020026namespace redfish
27{
28namespace telemetry
29{
30constexpr const char* triggerInterface =
31 "xyz.openbmc_project.Telemetry.Trigger";
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020032
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020033using NumericThresholdParams =
34 std::tuple<std::string, uint64_t, std::string, double>;
35
36using DiscreteThresholdParams =
37 std::tuple<std::string, std::string, uint64_t, std::string>;
38
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010039using TriggerThresholdParams =
40 std::variant<std::vector<NumericThresholdParams>,
41 std::vector<DiscreteThresholdParams>>;
42
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020043using TriggerThresholdParamsExt =
44 std::variant<std::monostate, std::vector<NumericThresholdParams>,
45 std::vector<DiscreteThresholdParams>>;
46
47using TriggerSensorsParams =
48 std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
49
50using TriggerGetParamsVariant =
51 std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
Szymon Dompke3f215c92022-02-22 13:58:00 +010052 TriggerSensorsParams, std::vector<std::string>,
53 std::vector<sdbusplus::message::object_path>>;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020054
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010055inline triggers::TriggerActionEnum
56 toRedfishTriggerAction(std::string_view dbusValue)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020057{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010058 if (dbusValue ==
59 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020060 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010061 return triggers::TriggerActionEnum::RedfishMetricReport;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020062 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010063 if (dbusValue ==
64 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020065 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010066 return triggers::TriggerActionEnum::RedfishEvent;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020067 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010068 if (dbusValue ==
69 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020070 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010071 return triggers::TriggerActionEnum::LogToLogService;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020072 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010073 return triggers::TriggerActionEnum::Invalid;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020074}
75
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010076inline std::string toDbusTriggerAction(std::string_view redfishValue)
77{
78 if (redfishValue == "RedfishMetricReport")
79 {
80 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
81 }
82 if (redfishValue == "RedfishEvent")
83 {
84 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
85 }
86 if (redfishValue == "LogToLogService")
87 {
88 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
89 }
90 return "";
91}
92
93inline std::string toDbusSeverity(std::string_view redfishValue)
94{
95 if (redfishValue == "OK")
96 {
97 return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
98 }
99 if (redfishValue == "Warning")
100 {
101 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
102 }
103 if (redfishValue == "Critical")
104 {
105 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
106 }
107 return "";
108}
109
110inline resource::Health toRedfishSeverity(std::string_view dbusValue)
111{
112 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
113 {
114 return resource::Health::OK;
115 }
116 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
117 {
118 return resource::Health::Warning;
119 }
120 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
121 {
122 return resource::Health::Critical;
123 }
124 return resource::Health::Invalid;
125}
126
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100127inline std::string toRedfishThresholdName(std::string_view dbusValue)
128{
129 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
130 {
131 return "UpperCritical";
132 }
133
134 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
135 {
136 return "LowerCritical";
137 }
138
139 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
140 {
141 return "UpperWarning";
142 }
143
144 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
145 {
146 return "LowerWarning";
147 }
148
149 return "";
150}
151
152inline std::string toDbusActivation(std::string_view redfishValue)
153{
154 if (redfishValue == "Either")
155 {
156 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
157 }
158
159 if (redfishValue == "Decreasing")
160 {
161 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
162 }
163
164 if (redfishValue == "Increasing")
165 {
166 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
167 }
168
169 return "";
170}
171
172inline triggers::ThresholdActivation
173 toRedfishActivation(std::string_view dbusValue)
174{
175 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
176 {
177 return triggers::ThresholdActivation::Either;
178 }
179
180 if (dbusValue ==
181 "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
182 {
183 return triggers::ThresholdActivation::Decreasing;
184 }
185
186 if (dbusValue ==
187 "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
188 {
189 return triggers::ThresholdActivation::Increasing;
190 }
191
192 return triggers::ThresholdActivation::Invalid;
193}
194
195enum class MetricType
196{
197 Discrete,
198 Numeric
199};
200
201enum class DiscreteCondition
202{
203 Specified,
204 Changed
205};
206
207struct Context
208{
209 std::string id;
210 std::string name;
211 std::vector<std::string> actions;
212 std::vector<std::pair<sdbusplus::message::object_path, std::string>>
213 sensors;
214 std::vector<sdbusplus::message::object_path> reports;
215 TriggerThresholdParams thresholds;
216
217 std::optional<DiscreteCondition> discreteCondition;
218 std::optional<MetricType> metricType;
219 std::optional<std::vector<std::string>> metricProperties;
220};
221
222inline std::optional<sdbusplus::message::object_path>
223 getReportPathFromReportDefinitionUri(const std::string& uri)
224{
Ed Tanous6fd29552023-10-04 09:40:14 -0700225 boost::system::result<boost::urls::url_view> parsed =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100226 boost::urls::parse_relative_ref(uri);
227
228 if (!parsed)
229 {
230 return std::nullopt;
231 }
232
233 std::string id;
234 if (!crow::utility::readUrlSegments(
235 *parsed, "redfish", "v1", "TelemetryService",
236 "MetricReportDefinitions", std::ref(id)))
237 {
238 return std::nullopt;
239 }
240
241 return sdbusplus::message::object_path(
242 "/xyz/openbmc_project/Telemetry/Reports") /
243 "TelemetryService" / id;
244}
245
246inline std::optional<MetricType> getMetricType(const std::string& metricType)
247{
248 if (metricType == "Discrete")
249 {
250 return MetricType::Discrete;
251 }
252 if (metricType == "Numeric")
253 {
254 return MetricType::Numeric;
255 }
256 return std::nullopt;
257}
258
259inline std::optional<DiscreteCondition>
260 getDiscreteCondition(const std::string& discreteTriggerCondition)
261{
262 if (discreteTriggerCondition == "Specified")
263 {
264 return DiscreteCondition::Specified;
265 }
266 if (discreteTriggerCondition == "Changed")
267 {
268 return DiscreteCondition::Changed;
269 }
270 return std::nullopt;
271}
272
Ed Tanous2932dcb2024-03-06 12:04:47 -0800273inline bool parseThreshold(crow::Response& res,
274 nlohmann::json::object_t& threshold,
275 std::string_view dbusThresholdName,
276 std::vector<NumericThresholdParams>& parsedParams)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100277{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800278 double reading = 0.0;
279 std::string activation;
280 std::string dwellTimeStr;
281
282 if (!json_util::readJsonObject(threshold, res, "Reading", reading,
283 "Activation", activation, "DwellTime",
284 dwellTimeStr))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100285 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100286 return false;
287 }
288
Ed Tanous2932dcb2024-03-06 12:04:47 -0800289 std::string dbusActivation = toDbusActivation(activation);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100290
Ed Tanous2932dcb2024-03-06 12:04:47 -0800291 if (dbusActivation.empty())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100292 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800293 messages::propertyValueIncorrect(res, "Activation", activation);
294 return false;
295 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100296
Ed Tanous2932dcb2024-03-06 12:04:47 -0800297 std::optional<std::chrono::milliseconds> dwellTime =
298 time_utils::fromDurationString(dwellTimeStr);
299 if (!dwellTime)
300 {
301 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
302 return false;
303 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100304
Ed Tanous2932dcb2024-03-06 12:04:47 -0800305 parsedParams.emplace_back(dbusThresholdName,
306 static_cast<uint64_t>(dwellTime->count()),
307 dbusActivation, reading);
308 return true;
309}
310
311struct NumericThresholds
312{
313 std::optional<nlohmann::json::object_t> upperCritical;
314 std::optional<nlohmann::json::object_t> upperWarning;
315 std::optional<nlohmann::json::object_t> lowerWarning;
316 std::optional<nlohmann::json::object_t> lowerCritical;
317
318 bool any() const
319 {
320 return upperCritical || upperWarning || lowerWarning || lowerCritical;
321 }
322};
323
324inline bool parseNumericThresholds(crow::Response& res,
325 NumericThresholds& numericThresholds,
326 Context& ctx)
327{
328 std::vector<NumericThresholdParams> parsedParams;
329 if (numericThresholds.upperCritical)
330 {
331 if (!parseThreshold(
332 res, *numericThresholds.upperCritical,
333 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
334 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100335 {
336 return false;
337 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800338 }
339 if (numericThresholds.upperWarning)
340 {
341 if (!parseThreshold(
342 res, *numericThresholds.upperWarning,
343 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
344 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100345 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100346 return false;
347 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800348 }
349 if (numericThresholds.lowerWarning)
350 {
351 if (!parseThreshold(
352 res, *numericThresholds.lowerWarning,
353 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
354 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100355 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100356 return false;
357 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800358 }
359 if (numericThresholds.lowerCritical)
360 {
361 if (!parseThreshold(
362 res, *numericThresholds.lowerCritical,
363 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
364 parsedParams))
365 {
366 return false;
367 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100368 }
369
370 ctx.thresholds = std::move(parsedParams);
371 return true;
372}
373
374inline bool parseDiscreteTriggers(
375 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800376 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
377 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100378{
379 std::vector<DiscreteThresholdParams> parsedParams;
380 if (!discreteTriggers)
381 {
382 ctx.thresholds = std::move(parsedParams);
383 return true;
384 }
385
386 parsedParams.reserve(discreteTriggers->size());
Ed Tanous2932dcb2024-03-06 12:04:47 -0800387 for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100388 {
389 std::optional<std::string> name = "";
390 std::string value;
391 std::string dwellTimeStr;
392 std::string severity;
393
Ed Tanous2932dcb2024-03-06 12:04:47 -0800394 if (!json_util::readJsonObject(thresholdInfo, res, "Name", name,
395 "Value", value, "DwellTime",
396 dwellTimeStr, "Severity", severity))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100397 {
398 return false;
399 }
400
401 std::optional<std::chrono::milliseconds> dwellTime =
402 time_utils::fromDurationString(dwellTimeStr);
403 if (!dwellTime)
404 {
405 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
406 return false;
407 }
408
409 std::string dbusSeverity = toDbusSeverity(severity);
410 if (dbusSeverity.empty())
411 {
412 messages::propertyValueIncorrect(res, "Severity", severity);
413 return false;
414 }
415
416 parsedParams.emplace_back(*name, dbusSeverity,
417 static_cast<uint64_t>(dwellTime->count()),
418 value);
419 }
420
421 ctx.thresholds = std::move(parsedParams);
422 return true;
423}
424
425inline bool parseTriggerThresholds(
426 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800427 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
428 NumericThresholds& numericThresholds, Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100429{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800430 if (discreteTriggers && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100431 {
432 messages::propertyValueConflict(res, "DiscreteTriggers",
433 "NumericThresholds");
434 messages::propertyValueConflict(res, "NumericThresholds",
435 "DiscreteTriggers");
436 return false;
437 }
438
439 if (ctx.discreteCondition)
440 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800441 if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100442 {
443 messages::propertyValueConflict(res, "DiscreteTriggerCondition",
444 "NumericThresholds");
445 messages::propertyValueConflict(res, "NumericThresholds",
446 "DiscreteTriggerCondition");
447 return false;
448 }
449 }
450
451 if (ctx.metricType)
452 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800453 if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100454 {
455 messages::propertyValueConflict(res, "NumericThresholds",
456 "MetricType");
457 return false;
458 }
459 if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
460 {
461 messages::propertyValueConflict(res, "DiscreteTriggers",
462 "MetricType");
463 return false;
464 }
465 if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
466 {
467 messages::propertyValueConflict(res, "DiscreteTriggers",
468 "DiscreteTriggerCondition");
469 return false;
470 }
471 }
472
473 if (discreteTriggers || ctx.discreteCondition ||
474 (ctx.metricType && *ctx.metricType == MetricType::Discrete))
475 {
476 if (ctx.discreteCondition)
477 {
478 if (*ctx.discreteCondition == DiscreteCondition::Specified &&
479 !discreteTriggers)
480 {
481 messages::createFailedMissingReqProperties(res,
482 "DiscreteTriggers");
483 return false;
484 }
485 if (discreteTriggers &&
486 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
487 discreteTriggers->empty()) ||
488 (*ctx.discreteCondition == DiscreteCondition::Changed &&
489 !discreteTriggers->empty())))
490 {
491 messages::propertyValueConflict(res, "DiscreteTriggers",
492 "DiscreteTriggerCondition");
493 return false;
494 }
495 }
496 if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
497 {
498 return false;
499 }
500 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800501 else if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100502 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800503 if (!parseNumericThresholds(res, numericThresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100504 {
505 return false;
506 }
507 }
508 else
509 {
510 messages::createFailedMissingReqProperties(
511 res, "'DiscreteTriggers', 'NumericThresholds', "
512 "'DiscreteTriggerCondition' or 'MetricType'");
513 return false;
514 }
515 return true;
516}
517
Ed Tanous2932dcb2024-03-06 12:04:47 -0800518inline bool parseLinks(crow::Response& res,
519 const std::vector<std::string>& metricReportDefinitions,
520 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100521{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800522 ctx.reports.reserve(metricReportDefinitions.size());
523 for (const std::string& reportDefinionUri : metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100524 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800525 std::optional<sdbusplus::message::object_path> reportPath =
526 getReportPathFromReportDefinitionUri(reportDefinionUri);
527 if (!reportPath)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100528 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800529 messages::propertyValueIncorrect(res, "MetricReportDefinitions",
530 reportDefinionUri);
531 return false;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100532 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800533 ctx.reports.emplace_back(*reportPath);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100534 }
535 return true;
536}
537
538inline bool parseMetricProperties(crow::Response& res, Context& ctx)
539{
540 if (!ctx.metricProperties)
541 {
542 return true;
543 }
544
545 ctx.sensors.reserve(ctx.metricProperties->size());
546
547 size_t uriIdx = 0;
548 for (const std::string& uriStr : *ctx.metricProperties)
549 {
Ed Tanous4a7fbef2024-04-06 16:03:49 -0700550 boost::system::result<boost::urls::url> uri =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100551 boost::urls::parse_relative_ref(uriStr);
552 if (!uri)
553 {
554 messages::propertyValueIncorrect(
555 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
556 return false;
557 }
558 std::string chassisName;
559 std::string sensorName;
560 if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
561 std::ref(chassisName), "Sensors",
562 std::ref(sensorName)))
563 {
564 messages::propertyValueIncorrect(
565 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
566 return false;
567 }
568
569 std::pair<std::string, std::string> split =
570 splitSensorNameAndType(sensorName);
571 if (split.first.empty() || split.second.empty())
572 {
573 messages::propertyValueIncorrect(
574 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
575 return false;
576 }
577
578 std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
579 '/' + split.second;
580
581 ctx.sensors.emplace_back(sensorPath, uriStr);
582 uriIdx++;
583 }
584 return true;
585}
586
587inline bool parsePostTriggerParams(crow::Response& res,
588 const crow::Request& req, Context& ctx)
589{
590 std::optional<std::string> id = "";
591 std::optional<std::string> name = "";
592 std::optional<std::string> metricType;
593 std::optional<std::vector<std::string>> triggerActions;
594 std::optional<std::string> discreteTriggerCondition;
Ed Tanous2932dcb2024-03-06 12:04:47 -0800595 std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
596 std::optional<std::vector<std::string>> metricReportDefinitions;
597 NumericThresholds thresholds;
598 // clang-format off
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100599 if (!json_util::readJsonPatch(
Ed Tanous2932dcb2024-03-06 12:04:47 -0800600 req, res,
601 "Id", id,
602 "Name", name,
603 "MetricType", metricType,
604 "TriggerActions", triggerActions,
605 "DiscreteTriggerCondition", discreteTriggerCondition,
606 "DiscreteTriggers", discreteTriggers,
607 "NumericThresholds/UpperCritical", thresholds.upperCritical,
608 "NumericThresholds/UpperWarning", thresholds.upperWarning,
609 "NumericThresholds/LowerWarning", thresholds.lowerWarning,
610 "NumericThresholds/LowerCritical", thresholds.lowerCritical,
611 "MetricProperties", ctx.metricProperties,
612 "Links/MetricReportDefinitions", metricReportDefinitions)
613 )
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100614 {
615 return false;
616 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800617 // clang-format on
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100618
619 ctx.id = *id;
620 ctx.name = *name;
621
622 if (metricType)
623 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700624 ctx.metricType = getMetricType(*metricType);
625 if (!ctx.metricType)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100626 {
627 messages::propertyValueIncorrect(res, "MetricType", *metricType);
628 return false;
629 }
630 }
631
632 if (discreteTriggerCondition)
633 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700634 ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
635 if (!ctx.discreteCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100636 {
637 messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
638 *discreteTriggerCondition);
639 return false;
640 }
641 }
642
643 if (triggerActions)
644 {
645 ctx.actions.reserve(triggerActions->size());
646 for (const std::string& action : *triggerActions)
647 {
648 std::string dbusAction = toDbusTriggerAction(action);
649
650 if (dbusAction.empty())
651 {
652 messages::propertyValueNotInList(res, action, "TriggerActions");
653 return false;
654 }
655
656 ctx.actions.emplace_back(dbusAction);
657 }
658 }
659 if (!parseMetricProperties(res, ctx))
660 {
661 return false;
662 }
663
Ed Tanous2932dcb2024-03-06 12:04:47 -0800664 if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100665 {
666 return false;
667 }
668
Ed Tanous2932dcb2024-03-06 12:04:47 -0800669 if (metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100670 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800671 if (!parseLinks(res, *metricReportDefinitions, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100672 {
673 return false;
674 }
675 }
676 return true;
677}
678
679inline void afterCreateTrigger(
680 const boost::system::error_code& ec, const std::string& dbusPath,
681 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
682{
683 if (ec == boost::system::errc::file_exists)
684 {
685 messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
686 return;
687 }
688 if (ec == boost::system::errc::too_many_files_open)
689 {
690 messages::createLimitReachedForResource(asyncResp->res);
691 return;
692 }
693 if (ec)
694 {
695 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700696 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100697 return;
698 }
699
700 const std::optional<std::string>& triggerId =
701 getTriggerIdFromDbusPath(dbusPath);
702 if (!triggerId)
703 {
704 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700705 BMCWEB_LOG_ERROR("Unknown data returned by "
706 "AddTrigger DBus method");
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100707 return;
708 }
709
710 messages::created(asyncResp->res);
711 boost::urls::url locationUrl = boost::urls::format(
712 "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
713 asyncResp->res.addHeader("Location", locationUrl.buffer());
714}
715
716inline std::optional<nlohmann::json::array_t>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200717 getTriggerActions(const std::vector<std::string>& dbusActions)
718{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100719 nlohmann::json::array_t triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200720 for (const std::string& dbusAction : dbusActions)
721 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100722 triggers::TriggerActionEnum redfishAction =
723 toRedfishTriggerAction(dbusAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200724
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100725 if (redfishAction == triggers::TriggerActionEnum::Invalid)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200726 {
727 return std::nullopt;
728 }
729
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100730 triggerActions.emplace_back(redfishAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200731 }
732
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100733 return triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200734}
735
Szymon Dompke3f215c92022-02-22 13:58:00 +0100736inline std::optional<nlohmann::json::array_t>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200737 getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
738{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100739 nlohmann::json::array_t triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200740 const std::vector<DiscreteThresholdParams>* discreteParams =
741 std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
742
Ed Tanouse662eae2022-01-25 10:39:19 -0800743 if (discreteParams == nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200744 {
745 return std::nullopt;
746 }
747
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200748 for (const auto& [name, severity, dwellTime, value] : *discreteParams)
749 {
750 std::optional<std::string> duration =
751 time_utils::toDurationStringFromUint(dwellTime);
752
753 if (!duration)
754 {
755 return std::nullopt;
756 }
Ed Tanous613dabe2022-07-09 11:17:36 -0700757 nlohmann::json::object_t trigger;
758 trigger["Name"] = name;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100759 trigger["Severity"] = toRedfishSeverity(severity);
Ed Tanous613dabe2022-07-09 11:17:36 -0700760 trigger["DwellTime"] = *duration;
761 trigger["Value"] = value;
Patrick Williamsad539542023-05-12 10:10:08 -0500762 triggers.emplace_back(std::move(trigger));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200763 }
764
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100765 return triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200766}
767
768inline std::optional<nlohmann::json>
769 getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
770{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100771 nlohmann::json::object_t thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200772 const std::vector<NumericThresholdParams>* numericParams =
773 std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
774
Ed Tanouse662eae2022-01-25 10:39:19 -0800775 if (numericParams == nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200776 {
777 return std::nullopt;
778 }
779
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200780 for (const auto& [type, dwellTime, activation, reading] : *numericParams)
781 {
782 std::optional<std::string> duration =
783 time_utils::toDurationStringFromUint(dwellTime);
784
785 if (!duration)
786 {
787 return std::nullopt;
788 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100789 nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
Ed Tanous14766872022-03-15 10:44:42 -0700790 threshold["Reading"] = reading;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100791 threshold["Activation"] = toRedfishActivation(activation);
Ed Tanous14766872022-03-15 10:44:42 -0700792 threshold["DwellTime"] = *duration;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200793 }
794
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100795 return thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200796}
797
Szymon Dompke3f215c92022-02-22 13:58:00 +0100798inline std::optional<nlohmann::json> getMetricReportDefinitions(
799 const std::vector<sdbusplus::message::object_path>& reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200800{
801 nlohmann::json reports = nlohmann::json::array();
Szymon Dompke3f215c92022-02-22 13:58:00 +0100802
803 for (const sdbusplus::message::object_path& path : reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200804 {
Szymon Dompke3f215c92022-02-22 13:58:00 +0100805 std::string reportId = path.filename();
806 if (reportId.empty())
807 {
808 {
Ed Tanous62598e32023-07-17 17:06:25 -0700809 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
810 path.str);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100811 return std::nullopt;
812 }
813 }
814
Ed Tanous14766872022-03-15 10:44:42 -0700815 nlohmann::json::object_t report;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700816 report["@odata.id"] = boost::urls::format(
817 "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
818 reportId);
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500819 reports.emplace_back(std::move(report));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200820 }
821
Szymon Dompke3f215c92022-02-22 13:58:00 +0100822 return {std::move(reports)};
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200823}
824
825inline std::vector<std::string>
826 getMetricProperties(const TriggerSensorsParams& sensors)
827{
828 std::vector<std::string> metricProperties;
829 metricProperties.reserve(sensors.size());
830 for (const auto& [_, metadata] : sensors)
831 {
832 metricProperties.emplace_back(metadata);
833 }
834
835 return metricProperties;
836}
837
838inline bool fillTrigger(
839 nlohmann::json& json, const std::string& id,
840 const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
841 properties)
842{
843 const std::string* name = nullptr;
844 const bool* discrete = nullptr;
845 const TriggerSensorsParams* sensors = nullptr;
Szymon Dompke3f215c92022-02-22 13:58:00 +0100846 const std::vector<sdbusplus::message::object_path>* reports = nullptr;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200847 const std::vector<std::string>* triggerActions = nullptr;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200848 const TriggerThresholdParamsExt* thresholds = nullptr;
849
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200850 const bool success = sdbusplus::unpackPropertiesNoThrow(
851 dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
852 discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
853 triggerActions, "Thresholds", thresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200854
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200855 if (!success)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200856 {
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200857 return false;
858 }
859
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200860 if (triggerActions != nullptr)
Szymon Dompke3f215c92022-02-22 13:58:00 +0100861 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100862 std::optional<nlohmann::json::array_t> redfishTriggerActions =
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200863 getTriggerActions(*triggerActions);
864 if (!redfishTriggerActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200865 {
Ed Tanous62598e32023-07-17 17:06:25 -0700866 BMCWEB_LOG_ERROR(
867 "Property TriggerActions is invalid in Trigger: {}", id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200868 return false;
869 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100870 json["TriggerActions"] = *redfishTriggerActions;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200871 }
872
873 if (reports != nullptr)
874 {
875 std::optional<nlohmann::json> linkedReports =
876 getMetricReportDefinitions(*reports);
877 if (!linkedReports)
878 {
Ed Tanous62598e32023-07-17 17:06:25 -0700879 BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200880 return false;
881 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200882 json["Links"]["MetricReportDefinitions"] = *linkedReports;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200883 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200884
885 if (discrete != nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200886 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200887 if (*discrete)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200888 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200889 std::optional<nlohmann::json::array_t> discreteTriggers =
890 getDiscreteTriggers(*thresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200891
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200892 if (!discreteTriggers)
893 {
Ed Tanous62598e32023-07-17 17:06:25 -0700894 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
895 "triggers in Trigger: {}",
896 id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200897 return false;
898 }
899
900 json["DiscreteTriggers"] = *discreteTriggers;
901 json["DiscreteTriggerCondition"] =
902 discreteTriggers->empty() ? "Changed" : "Specified";
903 json["MetricType"] = "Discrete";
904 }
905 else
906 {
907 std::optional<nlohmann::json> numericThresholds =
908 getNumericThresholds(*thresholds);
909
910 if (!numericThresholds)
911 {
Ed Tanous62598e32023-07-17 17:06:25 -0700912 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
913 "thresholds in Trigger: {}",
914 id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200915 return false;
916 }
917
918 json["NumericThresholds"] = *numericThresholds;
919 json["MetricType"] = "Numeric";
920 }
921 }
922
923 if (name != nullptr)
924 {
925 json["Name"] = *name;
926 }
927
928 if (sensors != nullptr)
929 {
930 json["MetricProperties"] = getMetricProperties(*sensors);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200931 }
932
Szymon Dompke3f215c92022-02-22 13:58:00 +0100933 json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700934 json["@odata.id"] =
935 boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100936 json["Id"] = id;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200937
938 return true;
939}
940
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100941inline void handleTriggerCollectionPost(
942 App& app, const crow::Request& req,
943 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
944{
945 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
946 {
947 return;
948 }
949
950 telemetry::Context ctx;
951 if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
952 {
953 return;
954 }
955
956 crow::connections::systemBus->async_method_call(
957 [asyncResp, id = ctx.id](const boost::system::error_code& ec,
958 const std::string& dbusPath) {
959 afterCreateTrigger(ec, dbusPath, asyncResp, id);
Patrick Williams5a39f772023-10-20 11:20:21 -0500960 },
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100961 service, "/xyz/openbmc_project/Telemetry/Triggers",
962 "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
963 "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
964 ctx.reports, ctx.thresholds);
965}
966
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200967} // namespace telemetry
968
969inline void requestRoutesTriggerCollection(App& app)
970{
971 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
972 .privileges(redfish::privileges::getTriggersCollection)
973 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700974 [&app](const crow::Request& req,
975 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000976 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700977 {
978 return;
979 }
980 asyncResp->res.jsonValue["@odata.type"] =
981 "#TriggersCollection.TriggersCollection";
Willy Tuae9031f2022-09-27 05:48:07 +0000982 asyncResp->res.jsonValue["@odata.id"] =
983 "/redfish/v1/TelemetryService/Triggers";
Ed Tanous002d39b2022-05-31 08:59:27 -0700984 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
George Liu7a1dbc42022-12-07 16:03:22 +0800985 constexpr std::array<std::string_view, 1> interfaces{
986 telemetry::triggerInterface};
Ed Tanous002d39b2022-05-31 08:59:27 -0700987 collection_util::getCollectionMembers(
Willy Tuae9031f2022-09-27 05:48:07 +0000988 asyncResp,
989 boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
990 interfaces,
Ed Tanous002d39b2022-05-31 08:59:27 -0700991 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
Patrick Williams5a39f772023-10-20 11:20:21 -0500992 });
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100993
994 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
995 .privileges(redfish::privileges::postTriggersCollection)
996 .methods(boost::beast::http::verb::post)(std::bind_front(
997 telemetry::handleTriggerCollectionPost, std::ref(app)));
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200998}
999
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001000inline void requestRoutesTrigger(App& app)
1001{
1002 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1003 .privileges(redfish::privileges::getTriggers)
1004 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001005 [&app](const crow::Request& req,
1006 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1007 const std::string& id) {
Carson Labrado3ba00072022-06-06 19:40:56 +00001008 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07001009 {
1010 return;
1011 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +02001012 sdbusplus::asio::getAllProperties(
1013 *crow::connections::systemBus, telemetry::service,
1014 telemetry::getDbusTriggerPath(id), telemetry::triggerInterface,
Ed Tanous002d39b2022-05-31 08:59:27 -07001015 [asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001016 id](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -07001017 const std::vector<std::pair<
1018 std::string, telemetry::TriggerGetParamsVariant>>& ret) {
1019 if (ec.value() == EBADR ||
1020 ec == boost::system::errc::host_unreachable)
1021 {
1022 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1023 return;
1024 }
1025 if (ec)
1026 {
Ed Tanous62598e32023-07-17 17:06:25 -07001027 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001028 messages::internalError(asyncResp->res);
1029 return;
1030 }
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001031
Ed Tanous002d39b2022-05-31 08:59:27 -07001032 if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret))
1033 {
1034 messages::internalError(asyncResp->res);
1035 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001036 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001037 });
Szymon Dompke163994a2021-08-12 17:30:23 +02001038
1039 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1040 .privileges(redfish::privileges::deleteTriggers)
1041 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001042 [&app](const crow::Request& req,
1043 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1044 const std::string& id) {
Carson Labrado3ba00072022-06-06 19:40:56 +00001045 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07001046 {
1047 return;
1048 }
1049 const std::string triggerPath = telemetry::getDbusTriggerPath(id);
Szymon Dompke163994a2021-08-12 17:30:23 +02001050
Ed Tanous002d39b2022-05-31 08:59:27 -07001051 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001052 [asyncResp, id](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001053 if (ec.value() == EBADR)
1054 {
1055 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1056 return;
1057 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001058
Ed Tanous002d39b2022-05-31 08:59:27 -07001059 if (ec)
1060 {
Ed Tanous62598e32023-07-17 17:06:25 -07001061 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001062 messages::internalError(asyncResp->res);
1063 return;
1064 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001065
Ed Tanous002d39b2022-05-31 08:59:27 -07001066 asyncResp->res.result(boost::beast::http::status::no_content);
Patrick Williams5a39f772023-10-20 11:20:21 -05001067 },
Ed Tanous002d39b2022-05-31 08:59:27 -07001068 telemetry::service, triggerPath,
1069 "xyz.openbmc_project.Object.Delete", "Delete");
Patrick Williams5a39f772023-10-20 11:20:21 -05001070 });
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001071}
1072
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001073} // namespace redfish