blob: 43ec77daf8664220cb83ebd36e243cc90381ec96 [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"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020012#include "utils/telemetry_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080013#include "utils/time_utils.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020014
Ed Tanousef4c65b2023-04-24 15:28:50 -070015#include <boost/url/format.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020016#include <sdbusplus/asio/property.hpp>
17#include <sdbusplus/unpack_properties.hpp>
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020018
George Liu7a1dbc42022-12-07 16:03:22 +080019#include <array>
20#include <string_view>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020021#include <tuple>
22#include <variant>
23#include <vector>
24
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020025namespace redfish
26{
27namespace telemetry
28{
29constexpr const char* triggerInterface =
30 "xyz.openbmc_project.Telemetry.Trigger";
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020031
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020032using NumericThresholdParams =
33 std::tuple<std::string, uint64_t, std::string, double>;
34
35using DiscreteThresholdParams =
36 std::tuple<std::string, std::string, uint64_t, std::string>;
37
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010038using TriggerThresholdParams =
39 std::variant<std::vector<NumericThresholdParams>,
40 std::vector<DiscreteThresholdParams>>;
41
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020042using TriggerThresholdParamsExt =
43 std::variant<std::monostate, std::vector<NumericThresholdParams>,
44 std::vector<DiscreteThresholdParams>>;
45
46using TriggerSensorsParams =
47 std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
48
49using TriggerGetParamsVariant =
50 std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt,
Szymon Dompke3f215c92022-02-22 13:58:00 +010051 TriggerSensorsParams, std::vector<std::string>,
52 std::vector<sdbusplus::message::object_path>>;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020053
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010054inline triggers::TriggerActionEnum
55 toRedfishTriggerAction(std::string_view dbusValue)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020056{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010057 if (dbusValue ==
58 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020059 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010060 return triggers::TriggerActionEnum::RedfishMetricReport;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020061 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010062 if (dbusValue ==
63 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020064 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010065 return triggers::TriggerActionEnum::RedfishEvent;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020066 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010067 if (dbusValue ==
68 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020069 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010070 return triggers::TriggerActionEnum::LogToLogService;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020071 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010072 return triggers::TriggerActionEnum::Invalid;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020073}
74
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010075inline std::string toDbusTriggerAction(std::string_view redfishValue)
76{
77 if (redfishValue == "RedfishMetricReport")
78 {
79 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
80 }
81 if (redfishValue == "RedfishEvent")
82 {
83 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
84 }
85 if (redfishValue == "LogToLogService")
86 {
87 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
88 }
89 return "";
90}
91
92inline std::string toDbusSeverity(std::string_view redfishValue)
93{
94 if (redfishValue == "OK")
95 {
96 return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
97 }
98 if (redfishValue == "Warning")
99 {
100 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
101 }
102 if (redfishValue == "Critical")
103 {
104 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
105 }
106 return "";
107}
108
109inline resource::Health toRedfishSeverity(std::string_view dbusValue)
110{
111 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
112 {
113 return resource::Health::OK;
114 }
115 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
116 {
117 return resource::Health::Warning;
118 }
119 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
120 {
121 return resource::Health::Critical;
122 }
123 return resource::Health::Invalid;
124}
125
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100126inline std::string toRedfishThresholdName(std::string_view dbusValue)
127{
128 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
129 {
130 return "UpperCritical";
131 }
132
133 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
134 {
135 return "LowerCritical";
136 }
137
138 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
139 {
140 return "UpperWarning";
141 }
142
143 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
144 {
145 return "LowerWarning";
146 }
147
148 return "";
149}
150
151inline std::string toDbusActivation(std::string_view redfishValue)
152{
153 if (redfishValue == "Either")
154 {
155 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
156 }
157
158 if (redfishValue == "Decreasing")
159 {
160 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
161 }
162
163 if (redfishValue == "Increasing")
164 {
165 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
166 }
167
168 return "";
169}
170
171inline triggers::ThresholdActivation
172 toRedfishActivation(std::string_view dbusValue)
173{
174 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
175 {
176 return triggers::ThresholdActivation::Either;
177 }
178
179 if (dbusValue ==
180 "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
181 {
182 return triggers::ThresholdActivation::Decreasing;
183 }
184
185 if (dbusValue ==
186 "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
187 {
188 return triggers::ThresholdActivation::Increasing;
189 }
190
191 return triggers::ThresholdActivation::Invalid;
192}
193
194enum class MetricType
195{
196 Discrete,
197 Numeric
198};
199
200enum class DiscreteCondition
201{
202 Specified,
203 Changed
204};
205
206struct Context
207{
208 std::string id;
209 std::string name;
210 std::vector<std::string> actions;
211 std::vector<std::pair<sdbusplus::message::object_path, std::string>>
212 sensors;
213 std::vector<sdbusplus::message::object_path> reports;
214 TriggerThresholdParams thresholds;
215
216 std::optional<DiscreteCondition> discreteCondition;
217 std::optional<MetricType> metricType;
218 std::optional<std::vector<std::string>> metricProperties;
219};
220
221inline std::optional<sdbusplus::message::object_path>
222 getReportPathFromReportDefinitionUri(const std::string& uri)
223{
Ed Tanous6fd29552023-10-04 09:40:14 -0700224 boost::system::result<boost::urls::url_view> parsed =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100225 boost::urls::parse_relative_ref(uri);
226
227 if (!parsed)
228 {
229 return std::nullopt;
230 }
231
232 std::string id;
233 if (!crow::utility::readUrlSegments(
234 *parsed, "redfish", "v1", "TelemetryService",
235 "MetricReportDefinitions", std::ref(id)))
236 {
237 return std::nullopt;
238 }
239
240 return sdbusplus::message::object_path(
241 "/xyz/openbmc_project/Telemetry/Reports") /
242 "TelemetryService" / id;
243}
244
245inline std::optional<MetricType> getMetricType(const std::string& metricType)
246{
247 if (metricType == "Discrete")
248 {
249 return MetricType::Discrete;
250 }
251 if (metricType == "Numeric")
252 {
253 return MetricType::Numeric;
254 }
255 return std::nullopt;
256}
257
258inline std::optional<DiscreteCondition>
259 getDiscreteCondition(const std::string& discreteTriggerCondition)
260{
261 if (discreteTriggerCondition == "Specified")
262 {
263 return DiscreteCondition::Specified;
264 }
265 if (discreteTriggerCondition == "Changed")
266 {
267 return DiscreteCondition::Changed;
268 }
269 return std::nullopt;
270}
271
Ed Tanous2932dcb2024-03-06 12:04:47 -0800272inline bool parseThreshold(crow::Response& res,
273 nlohmann::json::object_t& threshold,
274 std::string_view dbusThresholdName,
275 std::vector<NumericThresholdParams>& parsedParams)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100276{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800277 double reading = 0.0;
278 std::string activation;
279 std::string dwellTimeStr;
280
281 if (!json_util::readJsonObject(threshold, res, "Reading", reading,
282 "Activation", activation, "DwellTime",
283 dwellTimeStr))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100284 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100285 return false;
286 }
287
Ed Tanous2932dcb2024-03-06 12:04:47 -0800288 std::string dbusActivation = toDbusActivation(activation);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100289
Ed Tanous2932dcb2024-03-06 12:04:47 -0800290 if (dbusActivation.empty())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100291 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800292 messages::propertyValueIncorrect(res, "Activation", activation);
293 return false;
294 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100295
Ed Tanous2932dcb2024-03-06 12:04:47 -0800296 std::optional<std::chrono::milliseconds> dwellTime =
297 time_utils::fromDurationString(dwellTimeStr);
298 if (!dwellTime)
299 {
300 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
301 return false;
302 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100303
Ed Tanous2932dcb2024-03-06 12:04:47 -0800304 parsedParams.emplace_back(dbusThresholdName,
305 static_cast<uint64_t>(dwellTime->count()),
306 dbusActivation, reading);
307 return true;
308}
309
310struct NumericThresholds
311{
312 std::optional<nlohmann::json::object_t> upperCritical;
313 std::optional<nlohmann::json::object_t> upperWarning;
314 std::optional<nlohmann::json::object_t> lowerWarning;
315 std::optional<nlohmann::json::object_t> lowerCritical;
316
317 bool any() const
318 {
319 return upperCritical || upperWarning || lowerWarning || lowerCritical;
320 }
321};
322
323inline bool parseNumericThresholds(crow::Response& res,
324 NumericThresholds& numericThresholds,
325 Context& ctx)
326{
327 std::vector<NumericThresholdParams> parsedParams;
328 if (numericThresholds.upperCritical)
329 {
330 if (!parseThreshold(
331 res, *numericThresholds.upperCritical,
332 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
333 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100334 {
335 return false;
336 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800337 }
338 if (numericThresholds.upperWarning)
339 {
340 if (!parseThreshold(
341 res, *numericThresholds.upperWarning,
342 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
343 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100344 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100345 return false;
346 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800347 }
348 if (numericThresholds.lowerWarning)
349 {
350 if (!parseThreshold(
351 res, *numericThresholds.lowerWarning,
352 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
353 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100354 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100355 return false;
356 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800357 }
358 if (numericThresholds.lowerCritical)
359 {
360 if (!parseThreshold(
361 res, *numericThresholds.lowerCritical,
362 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
363 parsedParams))
364 {
365 return false;
366 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100367 }
368
369 ctx.thresholds = std::move(parsedParams);
370 return true;
371}
372
373inline bool parseDiscreteTriggers(
374 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800375 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
376 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100377{
378 std::vector<DiscreteThresholdParams> parsedParams;
379 if (!discreteTriggers)
380 {
381 ctx.thresholds = std::move(parsedParams);
382 return true;
383 }
384
385 parsedParams.reserve(discreteTriggers->size());
Ed Tanous2932dcb2024-03-06 12:04:47 -0800386 for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100387 {
388 std::optional<std::string> name = "";
389 std::string value;
390 std::string dwellTimeStr;
391 std::string severity;
392
Ed Tanous2932dcb2024-03-06 12:04:47 -0800393 if (!json_util::readJsonObject(thresholdInfo, res, "Name", name,
394 "Value", value, "DwellTime",
395 dwellTimeStr, "Severity", severity))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100396 {
397 return false;
398 }
399
400 std::optional<std::chrono::milliseconds> dwellTime =
401 time_utils::fromDurationString(dwellTimeStr);
402 if (!dwellTime)
403 {
404 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
405 return false;
406 }
407
408 std::string dbusSeverity = toDbusSeverity(severity);
409 if (dbusSeverity.empty())
410 {
411 messages::propertyValueIncorrect(res, "Severity", severity);
412 return false;
413 }
414
415 parsedParams.emplace_back(*name, dbusSeverity,
416 static_cast<uint64_t>(dwellTime->count()),
417 value);
418 }
419
420 ctx.thresholds = std::move(parsedParams);
421 return true;
422}
423
424inline bool parseTriggerThresholds(
425 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800426 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
427 NumericThresholds& numericThresholds, Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100428{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800429 if (discreteTriggers && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100430 {
431 messages::propertyValueConflict(res, "DiscreteTriggers",
432 "NumericThresholds");
433 messages::propertyValueConflict(res, "NumericThresholds",
434 "DiscreteTriggers");
435 return false;
436 }
437
438 if (ctx.discreteCondition)
439 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800440 if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100441 {
442 messages::propertyValueConflict(res, "DiscreteTriggerCondition",
443 "NumericThresholds");
444 messages::propertyValueConflict(res, "NumericThresholds",
445 "DiscreteTriggerCondition");
446 return false;
447 }
448 }
449
450 if (ctx.metricType)
451 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800452 if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100453 {
454 messages::propertyValueConflict(res, "NumericThresholds",
455 "MetricType");
456 return false;
457 }
458 if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
459 {
460 messages::propertyValueConflict(res, "DiscreteTriggers",
461 "MetricType");
462 return false;
463 }
464 if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
465 {
466 messages::propertyValueConflict(res, "DiscreteTriggers",
467 "DiscreteTriggerCondition");
468 return false;
469 }
470 }
471
472 if (discreteTriggers || ctx.discreteCondition ||
473 (ctx.metricType && *ctx.metricType == MetricType::Discrete))
474 {
475 if (ctx.discreteCondition)
476 {
477 if (*ctx.discreteCondition == DiscreteCondition::Specified &&
478 !discreteTriggers)
479 {
480 messages::createFailedMissingReqProperties(res,
481 "DiscreteTriggers");
482 return false;
483 }
484 if (discreteTriggers &&
485 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
486 discreteTriggers->empty()) ||
487 (*ctx.discreteCondition == DiscreteCondition::Changed &&
488 !discreteTriggers->empty())))
489 {
490 messages::propertyValueConflict(res, "DiscreteTriggers",
491 "DiscreteTriggerCondition");
492 return false;
493 }
494 }
495 if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
496 {
497 return false;
498 }
499 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800500 else if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100501 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800502 if (!parseNumericThresholds(res, numericThresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100503 {
504 return false;
505 }
506 }
507 else
508 {
509 messages::createFailedMissingReqProperties(
510 res, "'DiscreteTriggers', 'NumericThresholds', "
511 "'DiscreteTriggerCondition' or 'MetricType'");
512 return false;
513 }
514 return true;
515}
516
Ed Tanous2932dcb2024-03-06 12:04:47 -0800517inline bool parseLinks(crow::Response& res,
518 const std::vector<std::string>& metricReportDefinitions,
519 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100520{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800521 ctx.reports.reserve(metricReportDefinitions.size());
522 for (const std::string& reportDefinionUri : metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100523 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800524 std::optional<sdbusplus::message::object_path> reportPath =
525 getReportPathFromReportDefinitionUri(reportDefinionUri);
526 if (!reportPath)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100527 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800528 messages::propertyValueIncorrect(res, "MetricReportDefinitions",
529 reportDefinionUri);
530 return false;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100531 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800532 ctx.reports.emplace_back(*reportPath);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100533 }
534 return true;
535}
536
537inline bool parseMetricProperties(crow::Response& res, Context& ctx)
538{
539 if (!ctx.metricProperties)
540 {
541 return true;
542 }
543
544 ctx.sensors.reserve(ctx.metricProperties->size());
545
546 size_t uriIdx = 0;
547 for (const std::string& uriStr : *ctx.metricProperties)
548 {
Ed Tanous6fd29552023-10-04 09:40:14 -0700549 boost::system::result<boost::urls::url_view> uri =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100550 boost::urls::parse_relative_ref(uriStr);
551 if (!uri)
552 {
553 messages::propertyValueIncorrect(
554 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
555 return false;
556 }
557 std::string chassisName;
558 std::string sensorName;
559 if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
560 std::ref(chassisName), "Sensors",
561 std::ref(sensorName)))
562 {
563 messages::propertyValueIncorrect(
564 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
565 return false;
566 }
567
568 std::pair<std::string, std::string> split =
569 splitSensorNameAndType(sensorName);
570 if (split.first.empty() || split.second.empty())
571 {
572 messages::propertyValueIncorrect(
573 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
574 return false;
575 }
576
577 std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first +
578 '/' + split.second;
579
580 ctx.sensors.emplace_back(sensorPath, uriStr);
581 uriIdx++;
582 }
583 return true;
584}
585
586inline bool parsePostTriggerParams(crow::Response& res,
587 const crow::Request& req, Context& ctx)
588{
589 std::optional<std::string> id = "";
590 std::optional<std::string> name = "";
591 std::optional<std::string> metricType;
592 std::optional<std::vector<std::string>> triggerActions;
593 std::optional<std::string> discreteTriggerCondition;
Ed Tanous2932dcb2024-03-06 12:04:47 -0800594 std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
595 std::optional<std::vector<std::string>> metricReportDefinitions;
596 NumericThresholds thresholds;
597 // clang-format off
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100598 if (!json_util::readJsonPatch(
Ed Tanous2932dcb2024-03-06 12:04:47 -0800599 req, res,
600 "Id", id,
601 "Name", name,
602 "MetricType", metricType,
603 "TriggerActions", triggerActions,
604 "DiscreteTriggerCondition", discreteTriggerCondition,
605 "DiscreteTriggers", discreteTriggers,
606 "NumericThresholds/UpperCritical", thresholds.upperCritical,
607 "NumericThresholds/UpperWarning", thresholds.upperWarning,
608 "NumericThresholds/LowerWarning", thresholds.lowerWarning,
609 "NumericThresholds/LowerCritical", thresholds.lowerCritical,
610 "MetricProperties", ctx.metricProperties,
611 "Links/MetricReportDefinitions", metricReportDefinitions)
612 )
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100613 {
614 return false;
615 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800616 // clang-format on
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100617
618 ctx.id = *id;
619 ctx.name = *name;
620
621 if (metricType)
622 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700623 ctx.metricType = getMetricType(*metricType);
624 if (!ctx.metricType)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100625 {
626 messages::propertyValueIncorrect(res, "MetricType", *metricType);
627 return false;
628 }
629 }
630
631 if (discreteTriggerCondition)
632 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700633 ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
634 if (!ctx.discreteCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100635 {
636 messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
637 *discreteTriggerCondition);
638 return false;
639 }
640 }
641
642 if (triggerActions)
643 {
644 ctx.actions.reserve(triggerActions->size());
645 for (const std::string& action : *triggerActions)
646 {
647 std::string dbusAction = toDbusTriggerAction(action);
648
649 if (dbusAction.empty())
650 {
651 messages::propertyValueNotInList(res, action, "TriggerActions");
652 return false;
653 }
654
655 ctx.actions.emplace_back(dbusAction);
656 }
657 }
658 if (!parseMetricProperties(res, ctx))
659 {
660 return false;
661 }
662
Ed Tanous2932dcb2024-03-06 12:04:47 -0800663 if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100664 {
665 return false;
666 }
667
Ed Tanous2932dcb2024-03-06 12:04:47 -0800668 if (metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100669 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800670 if (!parseLinks(res, *metricReportDefinitions, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100671 {
672 return false;
673 }
674 }
675 return true;
676}
677
678inline void afterCreateTrigger(
679 const boost::system::error_code& ec, const std::string& dbusPath,
680 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
681{
682 if (ec == boost::system::errc::file_exists)
683 {
684 messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
685 return;
686 }
687 if (ec == boost::system::errc::too_many_files_open)
688 {
689 messages::createLimitReachedForResource(asyncResp->res);
690 return;
691 }
692 if (ec)
693 {
694 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700695 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100696 return;
697 }
698
699 const std::optional<std::string>& triggerId =
700 getTriggerIdFromDbusPath(dbusPath);
701 if (!triggerId)
702 {
703 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700704 BMCWEB_LOG_ERROR("Unknown data returned by "
705 "AddTrigger DBus method");
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100706 return;
707 }
708
709 messages::created(asyncResp->res);
710 boost::urls::url locationUrl = boost::urls::format(
711 "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
712 asyncResp->res.addHeader("Location", locationUrl.buffer());
713}
714
715inline std::optional<nlohmann::json::array_t>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200716 getTriggerActions(const std::vector<std::string>& dbusActions)
717{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100718 nlohmann::json::array_t triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200719 for (const std::string& dbusAction : dbusActions)
720 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100721 triggers::TriggerActionEnum redfishAction =
722 toRedfishTriggerAction(dbusAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200723
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100724 if (redfishAction == triggers::TriggerActionEnum::Invalid)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200725 {
726 return std::nullopt;
727 }
728
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100729 triggerActions.emplace_back(redfishAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200730 }
731
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100732 return triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200733}
734
Szymon Dompke3f215c92022-02-22 13:58:00 +0100735inline std::optional<nlohmann::json::array_t>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200736 getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams)
737{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100738 nlohmann::json::array_t triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200739 const std::vector<DiscreteThresholdParams>* discreteParams =
740 std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams);
741
Ed Tanouse662eae2022-01-25 10:39:19 -0800742 if (discreteParams == nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200743 {
744 return std::nullopt;
745 }
746
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200747 for (const auto& [name, severity, dwellTime, value] : *discreteParams)
748 {
749 std::optional<std::string> duration =
750 time_utils::toDurationStringFromUint(dwellTime);
751
752 if (!duration)
753 {
754 return std::nullopt;
755 }
Ed Tanous613dabe2022-07-09 11:17:36 -0700756 nlohmann::json::object_t trigger;
757 trigger["Name"] = name;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100758 trigger["Severity"] = toRedfishSeverity(severity);
Ed Tanous613dabe2022-07-09 11:17:36 -0700759 trigger["DwellTime"] = *duration;
760 trigger["Value"] = value;
Patrick Williamsad539542023-05-12 10:10:08 -0500761 triggers.emplace_back(std::move(trigger));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200762 }
763
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100764 return triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200765}
766
767inline std::optional<nlohmann::json>
768 getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams)
769{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100770 nlohmann::json::object_t thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200771 const std::vector<NumericThresholdParams>* numericParams =
772 std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams);
773
Ed Tanouse662eae2022-01-25 10:39:19 -0800774 if (numericParams == nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200775 {
776 return std::nullopt;
777 }
778
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200779 for (const auto& [type, dwellTime, activation, reading] : *numericParams)
780 {
781 std::optional<std::string> duration =
782 time_utils::toDurationStringFromUint(dwellTime);
783
784 if (!duration)
785 {
786 return std::nullopt;
787 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100788 nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
Ed Tanous14766872022-03-15 10:44:42 -0700789 threshold["Reading"] = reading;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100790 threshold["Activation"] = toRedfishActivation(activation);
Ed Tanous14766872022-03-15 10:44:42 -0700791 threshold["DwellTime"] = *duration;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200792 }
793
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100794 return thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200795}
796
Szymon Dompke3f215c92022-02-22 13:58:00 +0100797inline std::optional<nlohmann::json> getMetricReportDefinitions(
798 const std::vector<sdbusplus::message::object_path>& reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200799{
800 nlohmann::json reports = nlohmann::json::array();
Szymon Dompke3f215c92022-02-22 13:58:00 +0100801
802 for (const sdbusplus::message::object_path& path : reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200803 {
Szymon Dompke3f215c92022-02-22 13:58:00 +0100804 std::string reportId = path.filename();
805 if (reportId.empty())
806 {
807 {
Ed Tanous62598e32023-07-17 17:06:25 -0700808 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
809 path.str);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100810 return std::nullopt;
811 }
812 }
813
Ed Tanous14766872022-03-15 10:44:42 -0700814 nlohmann::json::object_t report;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700815 report["@odata.id"] = boost::urls::format(
816 "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
817 reportId);
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500818 reports.emplace_back(std::move(report));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200819 }
820
Szymon Dompke3f215c92022-02-22 13:58:00 +0100821 return {std::move(reports)};
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200822}
823
824inline std::vector<std::string>
825 getMetricProperties(const TriggerSensorsParams& sensors)
826{
827 std::vector<std::string> metricProperties;
828 metricProperties.reserve(sensors.size());
829 for (const auto& [_, metadata] : sensors)
830 {
831 metricProperties.emplace_back(metadata);
832 }
833
834 return metricProperties;
835}
836
837inline bool fillTrigger(
838 nlohmann::json& json, const std::string& id,
839 const std::vector<std::pair<std::string, TriggerGetParamsVariant>>&
840 properties)
841{
842 const std::string* name = nullptr;
843 const bool* discrete = nullptr;
844 const TriggerSensorsParams* sensors = nullptr;
Szymon Dompke3f215c92022-02-22 13:58:00 +0100845 const std::vector<sdbusplus::message::object_path>* reports = nullptr;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200846 const std::vector<std::string>* triggerActions = nullptr;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200847 const TriggerThresholdParamsExt* thresholds = nullptr;
848
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200849 const bool success = sdbusplus::unpackPropertiesNoThrow(
850 dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
851 discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
852 triggerActions, "Thresholds", thresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200853
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200854 if (!success)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200855 {
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200856 return false;
857 }
858
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200859 if (triggerActions != nullptr)
Szymon Dompke3f215c92022-02-22 13:58:00 +0100860 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100861 std::optional<nlohmann::json::array_t> redfishTriggerActions =
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200862 getTriggerActions(*triggerActions);
863 if (!redfishTriggerActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200864 {
Ed Tanous62598e32023-07-17 17:06:25 -0700865 BMCWEB_LOG_ERROR(
866 "Property TriggerActions is invalid in Trigger: {}", id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200867 return false;
868 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100869 json["TriggerActions"] = *redfishTriggerActions;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200870 }
871
872 if (reports != nullptr)
873 {
874 std::optional<nlohmann::json> linkedReports =
875 getMetricReportDefinitions(*reports);
876 if (!linkedReports)
877 {
Ed Tanous62598e32023-07-17 17:06:25 -0700878 BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200879 return false;
880 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200881 json["Links"]["MetricReportDefinitions"] = *linkedReports;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200882 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200883
884 if (discrete != nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200885 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200886 if (*discrete)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200887 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200888 std::optional<nlohmann::json::array_t> discreteTriggers =
889 getDiscreteTriggers(*thresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200890
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200891 if (!discreteTriggers)
892 {
Ed Tanous62598e32023-07-17 17:06:25 -0700893 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
894 "triggers in Trigger: {}",
895 id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200896 return false;
897 }
898
899 json["DiscreteTriggers"] = *discreteTriggers;
900 json["DiscreteTriggerCondition"] =
901 discreteTriggers->empty() ? "Changed" : "Specified";
902 json["MetricType"] = "Discrete";
903 }
904 else
905 {
906 std::optional<nlohmann::json> numericThresholds =
907 getNumericThresholds(*thresholds);
908
909 if (!numericThresholds)
910 {
Ed Tanous62598e32023-07-17 17:06:25 -0700911 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
912 "thresholds in Trigger: {}",
913 id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200914 return false;
915 }
916
917 json["NumericThresholds"] = *numericThresholds;
918 json["MetricType"] = "Numeric";
919 }
920 }
921
922 if (name != nullptr)
923 {
924 json["Name"] = *name;
925 }
926
927 if (sensors != nullptr)
928 {
929 json["MetricProperties"] = getMetricProperties(*sensors);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200930 }
931
Szymon Dompke3f215c92022-02-22 13:58:00 +0100932 json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700933 json["@odata.id"] =
934 boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100935 json["Id"] = id;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200936
937 return true;
938}
939
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100940inline void handleTriggerCollectionPost(
941 App& app, const crow::Request& req,
942 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
943{
944 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
945 {
946 return;
947 }
948
949 telemetry::Context ctx;
950 if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
951 {
952 return;
953 }
954
955 crow::connections::systemBus->async_method_call(
956 [asyncResp, id = ctx.id](const boost::system::error_code& ec,
957 const std::string& dbusPath) {
958 afterCreateTrigger(ec, dbusPath, asyncResp, id);
Patrick Williams5a39f772023-10-20 11:20:21 -0500959 },
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100960 service, "/xyz/openbmc_project/Telemetry/Triggers",
961 "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
962 "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
963 ctx.reports, ctx.thresholds);
964}
965
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200966} // namespace telemetry
967
968inline void requestRoutesTriggerCollection(App& app)
969{
970 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
971 .privileges(redfish::privileges::getTriggersCollection)
972 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700973 [&app](const crow::Request& req,
974 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000975 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700976 {
977 return;
978 }
979 asyncResp->res.jsonValue["@odata.type"] =
980 "#TriggersCollection.TriggersCollection";
Willy Tuae9031f2022-09-27 05:48:07 +0000981 asyncResp->res.jsonValue["@odata.id"] =
982 "/redfish/v1/TelemetryService/Triggers";
Ed Tanous002d39b2022-05-31 08:59:27 -0700983 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
George Liu7a1dbc42022-12-07 16:03:22 +0800984 constexpr std::array<std::string_view, 1> interfaces{
985 telemetry::triggerInterface};
Ed Tanous002d39b2022-05-31 08:59:27 -0700986 collection_util::getCollectionMembers(
Willy Tuae9031f2022-09-27 05:48:07 +0000987 asyncResp,
988 boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
989 interfaces,
Ed Tanous002d39b2022-05-31 08:59:27 -0700990 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
Patrick Williams5a39f772023-10-20 11:20:21 -0500991 });
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100992
993 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
994 .privileges(redfish::privileges::postTriggersCollection)
995 .methods(boost::beast::http::verb::post)(std::bind_front(
996 telemetry::handleTriggerCollectionPost, std::ref(app)));
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200997}
998
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200999inline void requestRoutesTrigger(App& app)
1000{
1001 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1002 .privileges(redfish::privileges::getTriggers)
1003 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001004 [&app](const crow::Request& req,
1005 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1006 const std::string& id) {
Carson Labrado3ba00072022-06-06 19:40:56 +00001007 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07001008 {
1009 return;
1010 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +02001011 sdbusplus::asio::getAllProperties(
1012 *crow::connections::systemBus, telemetry::service,
1013 telemetry::getDbusTriggerPath(id), telemetry::triggerInterface,
Ed Tanous002d39b2022-05-31 08:59:27 -07001014 [asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001015 id](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -07001016 const std::vector<std::pair<
1017 std::string, telemetry::TriggerGetParamsVariant>>& ret) {
1018 if (ec.value() == EBADR ||
1019 ec == boost::system::errc::host_unreachable)
1020 {
1021 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1022 return;
1023 }
1024 if (ec)
1025 {
Ed Tanous62598e32023-07-17 17:06:25 -07001026 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001027 messages::internalError(asyncResp->res);
1028 return;
1029 }
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001030
Ed Tanous002d39b2022-05-31 08:59:27 -07001031 if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret))
1032 {
1033 messages::internalError(asyncResp->res);
1034 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001035 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001036 });
Szymon Dompke163994a2021-08-12 17:30:23 +02001037
1038 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1039 .privileges(redfish::privileges::deleteTriggers)
1040 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001041 [&app](const crow::Request& req,
1042 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1043 const std::string& id) {
Carson Labrado3ba00072022-06-06 19:40:56 +00001044 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07001045 {
1046 return;
1047 }
1048 const std::string triggerPath = telemetry::getDbusTriggerPath(id);
Szymon Dompke163994a2021-08-12 17:30:23 +02001049
Ed Tanous002d39b2022-05-31 08:59:27 -07001050 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001051 [asyncResp, id](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001052 if (ec.value() == EBADR)
1053 {
1054 messages::resourceNotFound(asyncResp->res, "Triggers", id);
1055 return;
1056 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001057
Ed Tanous002d39b2022-05-31 08:59:27 -07001058 if (ec)
1059 {
Ed Tanous62598e32023-07-17 17:06:25 -07001060 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001061 messages::internalError(asyncResp->res);
1062 return;
1063 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001064
Ed Tanous002d39b2022-05-31 08:59:27 -07001065 asyncResp->res.result(boost::beast::http::status::no_content);
Patrick Williams5a39f772023-10-20 11:20:21 -05001066 },
Ed Tanous002d39b2022-05-31 08:59:27 -07001067 telemetry::service, triggerPath,
1068 "xyz.openbmc_project.Object.Delete", "Delete");
Patrick Williams5a39f772023-10-20 11:20:21 -05001069 });
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001070}
1071
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001072} // namespace redfish