blob: f37675222604e6c218c0bafd90d6c740681b4aef [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02003#pragma once
4
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08006#include "async_resp.hpp"
7#include "dbus_singleton.hpp"
8#include "dbus_utility.hpp"
9#include "error_messages.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070010#include "generated/enums/metric_definition.hpp"
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010011#include "generated/enums/resource.hpp"
12#include "generated/enums/triggers.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080013#include "http_request.hpp"
14#include "http_response.hpp"
15#include "logging.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080016#include "query.hpp"
17#include "registries/privilege_registry.hpp"
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010018#include "utility.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020019#include "utils/collection.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "utils/dbus_utils.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070021#include "utils/json_utils.hpp"
Janet Adkins1516c212024-08-14 13:22:41 -050022#include "utils/sensor_utils.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020023#include "utils/telemetry_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "utils/time_utils.hpp"
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020025
Ed Tanousd7857202025-01-28 15:32:26 -080026#include <asm-generic/errno.h>
27
28#include <boost/beast/http/status.hpp>
29#include <boost/beast/http/verb.hpp>
30#include <boost/system/result.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070031#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080032#include <boost/url/parse.hpp>
33#include <boost/url/url.hpp>
34#include <boost/url/url_view.hpp>
35#include <nlohmann/json.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080036#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020037#include <sdbusplus/unpack_properties.hpp>
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020038
George Liu7a1dbc42022-12-07 16:03:22 +080039#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080040#include <chrono>
41#include <cstddef>
42#include <cstdint>
43#include <functional>
44#include <memory>
45#include <optional>
46#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080047#include <string_view>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020048#include <tuple>
Ed Tanousd7857202025-01-28 15:32:26 -080049#include <utility>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020050#include <vector>
51
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020052namespace redfish
53{
54namespace telemetry
55{
56constexpr const char* triggerInterface =
57 "xyz.openbmc_project.Telemetry.Trigger";
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020058
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020059using NumericThresholdParams =
60 std::tuple<std::string, uint64_t, std::string, double>;
61
62using DiscreteThresholdParams =
63 std::tuple<std::string, std::string, uint64_t, std::string>;
64
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020065using TriggerSensorsParams =
66 std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
67
Patrick Williams504af5a2025-02-03 14:29:03 -050068inline triggers::TriggerActionEnum toRedfishTriggerAction(
69 std::string_view dbusValue)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020070{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010071 if (dbusValue ==
72 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020073 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010074 return triggers::TriggerActionEnum::RedfishMetricReport;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020075 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010076 if (dbusValue ==
77 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020078 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010079 return triggers::TriggerActionEnum::RedfishEvent;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020080 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010081 if (dbusValue ==
82 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020083 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010084 return triggers::TriggerActionEnum::LogToLogService;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020085 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010086 return triggers::TriggerActionEnum::Invalid;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020087}
88
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010089inline std::string toDbusTriggerAction(std::string_view redfishValue)
90{
91 if (redfishValue == "RedfishMetricReport")
92 {
93 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
94 }
95 if (redfishValue == "RedfishEvent")
96 {
97 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
98 }
99 if (redfishValue == "LogToLogService")
100 {
101 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
102 }
103 return "";
104}
105
106inline std::string toDbusSeverity(std::string_view redfishValue)
107{
108 if (redfishValue == "OK")
109 {
110 return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
111 }
112 if (redfishValue == "Warning")
113 {
114 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
115 }
116 if (redfishValue == "Critical")
117 {
118 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
119 }
120 return "";
121}
122
123inline resource::Health toRedfishSeverity(std::string_view dbusValue)
124{
125 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
126 {
127 return resource::Health::OK;
128 }
129 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
130 {
131 return resource::Health::Warning;
132 }
133 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
134 {
135 return resource::Health::Critical;
136 }
137 return resource::Health::Invalid;
138}
139
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100140inline std::string toRedfishThresholdName(std::string_view dbusValue)
141{
142 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
143 {
144 return "UpperCritical";
145 }
146
147 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
148 {
149 return "LowerCritical";
150 }
151
152 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
153 {
154 return "UpperWarning";
155 }
156
157 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
158 {
159 return "LowerWarning";
160 }
161
162 return "";
163}
164
165inline std::string toDbusActivation(std::string_view redfishValue)
166{
167 if (redfishValue == "Either")
168 {
169 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
170 }
171
172 if (redfishValue == "Decreasing")
173 {
174 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
175 }
176
177 if (redfishValue == "Increasing")
178 {
179 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
180 }
181
182 return "";
183}
184
Patrick Williams504af5a2025-02-03 14:29:03 -0500185inline triggers::ThresholdActivation toRedfishActivation(
186 std::string_view dbusValue)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100187{
188 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
189 {
190 return triggers::ThresholdActivation::Either;
191 }
192
193 if (dbusValue ==
194 "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
195 {
196 return triggers::ThresholdActivation::Decreasing;
197 }
198
199 if (dbusValue ==
200 "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
201 {
202 return triggers::ThresholdActivation::Increasing;
203 }
204
205 return triggers::ThresholdActivation::Invalid;
206}
207
208enum class MetricType
209{
210 Discrete,
211 Numeric
212};
213
214enum class DiscreteCondition
215{
216 Specified,
217 Changed
218};
219
220struct Context
221{
222 std::string id;
223 std::string name;
224 std::vector<std::string> actions;
225 std::vector<std::pair<sdbusplus::message::object_path, std::string>>
226 sensors;
227 std::vector<sdbusplus::message::object_path> reports;
Ed Tanous58c71482024-10-19 14:35:07 -0700228 std::vector<NumericThresholdParams> numericThresholds;
229 std::vector<DiscreteThresholdParams> discreteThresholds;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100230 std::optional<DiscreteCondition> discreteCondition;
231 std::optional<MetricType> metricType;
232 std::optional<std::vector<std::string>> metricProperties;
233};
234
235inline std::optional<sdbusplus::message::object_path>
236 getReportPathFromReportDefinitionUri(const std::string& uri)
237{
Ed Tanous6fd29552023-10-04 09:40:14 -0700238 boost::system::result<boost::urls::url_view> parsed =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100239 boost::urls::parse_relative_ref(uri);
240
241 if (!parsed)
242 {
243 return std::nullopt;
244 }
245
246 std::string id;
247 if (!crow::utility::readUrlSegments(
248 *parsed, "redfish", "v1", "TelemetryService",
249 "MetricReportDefinitions", std::ref(id)))
250 {
251 return std::nullopt;
252 }
253
254 return sdbusplus::message::object_path(
255 "/xyz/openbmc_project/Telemetry/Reports") /
256 "TelemetryService" / id;
257}
258
259inline std::optional<MetricType> getMetricType(const std::string& metricType)
260{
261 if (metricType == "Discrete")
262 {
263 return MetricType::Discrete;
264 }
265 if (metricType == "Numeric")
266 {
267 return MetricType::Numeric;
268 }
269 return std::nullopt;
270}
271
Patrick Williams504af5a2025-02-03 14:29:03 -0500272inline std::optional<DiscreteCondition> getDiscreteCondition(
273 const std::string& discreteTriggerCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100274{
275 if (discreteTriggerCondition == "Specified")
276 {
277 return DiscreteCondition::Specified;
278 }
279 if (discreteTriggerCondition == "Changed")
280 {
281 return DiscreteCondition::Changed;
282 }
283 return std::nullopt;
284}
285
Ed Tanous2932dcb2024-03-06 12:04:47 -0800286inline bool parseThreshold(crow::Response& res,
287 nlohmann::json::object_t& threshold,
288 std::string_view dbusThresholdName,
289 std::vector<NumericThresholdParams>& parsedParams)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100290{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800291 double reading = 0.0;
292 std::string activation;
293 std::string dwellTimeStr;
294
Patrick Williams504af5a2025-02-03 14:29:03 -0500295 if (!json_util::readJsonObject( //
296 threshold, res, //
297 "Activation", activation, //
Myung Baeafc474a2024-10-09 00:53:29 -0700298 "DwellTime", dwellTimeStr, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500299 "Reading", reading //
Myung Baeafc474a2024-10-09 00:53:29 -0700300 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100301 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100302 return false;
303 }
304
Ed Tanous2932dcb2024-03-06 12:04:47 -0800305 std::string dbusActivation = toDbusActivation(activation);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100306
Ed Tanous2932dcb2024-03-06 12:04:47 -0800307 if (dbusActivation.empty())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100308 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800309 messages::propertyValueIncorrect(res, "Activation", activation);
310 return false;
311 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100312
Ed Tanous2932dcb2024-03-06 12:04:47 -0800313 std::optional<std::chrono::milliseconds> dwellTime =
314 time_utils::fromDurationString(dwellTimeStr);
315 if (!dwellTime)
316 {
317 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
318 return false;
319 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100320
Ed Tanous2932dcb2024-03-06 12:04:47 -0800321 parsedParams.emplace_back(dbusThresholdName,
322 static_cast<uint64_t>(dwellTime->count()),
323 dbusActivation, reading);
324 return true;
325}
326
327struct NumericThresholds
328{
329 std::optional<nlohmann::json::object_t> upperCritical;
330 std::optional<nlohmann::json::object_t> upperWarning;
331 std::optional<nlohmann::json::object_t> lowerWarning;
332 std::optional<nlohmann::json::object_t> lowerCritical;
333
334 bool any() const
335 {
336 return upperCritical || upperWarning || lowerWarning || lowerCritical;
337 }
338};
339
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400340inline bool parseNumericThresholds(
341 crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
Ed Tanous2932dcb2024-03-06 12:04:47 -0800342{
343 std::vector<NumericThresholdParams> parsedParams;
344 if (numericThresholds.upperCritical)
345 {
346 if (!parseThreshold(
347 res, *numericThresholds.upperCritical,
348 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
349 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100350 {
351 return false;
352 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800353 }
354 if (numericThresholds.upperWarning)
355 {
356 if (!parseThreshold(
357 res, *numericThresholds.upperWarning,
358 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
359 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100360 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100361 return false;
362 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800363 }
364 if (numericThresholds.lowerWarning)
365 {
366 if (!parseThreshold(
367 res, *numericThresholds.lowerWarning,
368 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
369 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100370 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100371 return false;
372 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800373 }
374 if (numericThresholds.lowerCritical)
375 {
376 if (!parseThreshold(
377 res, *numericThresholds.lowerCritical,
378 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
379 parsedParams))
380 {
381 return false;
382 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100383 }
384
Ed Tanous58c71482024-10-19 14:35:07 -0700385 ctx.numericThresholds = std::move(parsedParams);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100386 return true;
387}
388
389inline bool parseDiscreteTriggers(
390 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800391 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
392 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100393{
394 std::vector<DiscreteThresholdParams> parsedParams;
395 if (!discreteTriggers)
396 {
Ed Tanous58c71482024-10-19 14:35:07 -0700397 ctx.discreteThresholds = std::move(parsedParams);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100398 return true;
399 }
400
401 parsedParams.reserve(discreteTriggers->size());
Ed Tanous2932dcb2024-03-06 12:04:47 -0800402 for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100403 {
404 std::optional<std::string> name = "";
405 std::string value;
406 std::string dwellTimeStr;
407 std::string severity;
408
Patrick Williams504af5a2025-02-03 14:29:03 -0500409 if (!json_util::readJsonObject( //
410 thresholdInfo, res, //
Myung Baeafc474a2024-10-09 00:53:29 -0700411 "DwellTime", dwellTimeStr, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500412 "Name", name, //
413 "Severity", severity, //
414 "Value", value //
Myung Baeafc474a2024-10-09 00:53:29 -0700415 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100416 {
417 return false;
418 }
419
420 std::optional<std::chrono::milliseconds> dwellTime =
421 time_utils::fromDurationString(dwellTimeStr);
422 if (!dwellTime)
423 {
424 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
425 return false;
426 }
427
428 std::string dbusSeverity = toDbusSeverity(severity);
429 if (dbusSeverity.empty())
430 {
431 messages::propertyValueIncorrect(res, "Severity", severity);
432 return false;
433 }
434
435 parsedParams.emplace_back(*name, dbusSeverity,
436 static_cast<uint64_t>(dwellTime->count()),
437 value);
438 }
439
Ed Tanous58c71482024-10-19 14:35:07 -0700440 ctx.discreteThresholds = std::move(parsedParams);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100441 return true;
442}
443
444inline bool parseTriggerThresholds(
445 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800446 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
447 NumericThresholds& numericThresholds, Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100448{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800449 if (discreteTriggers && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100450 {
451 messages::propertyValueConflict(res, "DiscreteTriggers",
452 "NumericThresholds");
453 messages::propertyValueConflict(res, "NumericThresholds",
454 "DiscreteTriggers");
455 return false;
456 }
457
458 if (ctx.discreteCondition)
459 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800460 if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100461 {
462 messages::propertyValueConflict(res, "DiscreteTriggerCondition",
463 "NumericThresholds");
464 messages::propertyValueConflict(res, "NumericThresholds",
465 "DiscreteTriggerCondition");
466 return false;
467 }
468 }
469
470 if (ctx.metricType)
471 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800472 if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100473 {
474 messages::propertyValueConflict(res, "NumericThresholds",
475 "MetricType");
476 return false;
477 }
478 if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
479 {
480 messages::propertyValueConflict(res, "DiscreteTriggers",
481 "MetricType");
482 return false;
483 }
484 if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
485 {
486 messages::propertyValueConflict(res, "DiscreteTriggers",
487 "DiscreteTriggerCondition");
488 return false;
489 }
490 }
491
492 if (discreteTriggers || ctx.discreteCondition ||
493 (ctx.metricType && *ctx.metricType == MetricType::Discrete))
494 {
495 if (ctx.discreteCondition)
496 {
497 if (*ctx.discreteCondition == DiscreteCondition::Specified &&
498 !discreteTriggers)
499 {
500 messages::createFailedMissingReqProperties(res,
501 "DiscreteTriggers");
502 return false;
503 }
504 if (discreteTriggers &&
505 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
506 discreteTriggers->empty()) ||
507 (*ctx.discreteCondition == DiscreteCondition::Changed &&
508 !discreteTriggers->empty())))
509 {
510 messages::propertyValueConflict(res, "DiscreteTriggers",
511 "DiscreteTriggerCondition");
512 return false;
513 }
514 }
515 if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
516 {
517 return false;
518 }
519 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800520 else if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100521 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800522 if (!parseNumericThresholds(res, numericThresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100523 {
524 return false;
525 }
526 }
527 else
528 {
529 messages::createFailedMissingReqProperties(
530 res, "'DiscreteTriggers', 'NumericThresholds', "
531 "'DiscreteTriggerCondition' or 'MetricType'");
532 return false;
533 }
534 return true;
535}
536
Ed Tanous2932dcb2024-03-06 12:04:47 -0800537inline bool parseLinks(crow::Response& res,
538 const std::vector<std::string>& metricReportDefinitions,
539 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100540{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800541 ctx.reports.reserve(metricReportDefinitions.size());
542 for (const std::string& reportDefinionUri : metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100543 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800544 std::optional<sdbusplus::message::object_path> reportPath =
545 getReportPathFromReportDefinitionUri(reportDefinionUri);
546 if (!reportPath)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100547 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800548 messages::propertyValueIncorrect(res, "MetricReportDefinitions",
549 reportDefinionUri);
550 return false;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100551 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800552 ctx.reports.emplace_back(*reportPath);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100553 }
554 return true;
555}
556
557inline bool parseMetricProperties(crow::Response& res, Context& ctx)
558{
559 if (!ctx.metricProperties)
560 {
561 return true;
562 }
563
564 ctx.sensors.reserve(ctx.metricProperties->size());
565
566 size_t uriIdx = 0;
567 for (const std::string& uriStr : *ctx.metricProperties)
568 {
Ed Tanous4a7fbef2024-04-06 16:03:49 -0700569 boost::system::result<boost::urls::url> uri =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100570 boost::urls::parse_relative_ref(uriStr);
571 if (!uri)
572 {
573 messages::propertyValueIncorrect(
574 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
575 return false;
576 }
577 std::string chassisName;
578 std::string sensorName;
579 if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
580 std::ref(chassisName), "Sensors",
581 std::ref(sensorName)))
582 {
583 messages::propertyValueIncorrect(
584 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
585 return false;
586 }
587
588 std::pair<std::string, std::string> split =
Janet Adkins1516c212024-08-14 13:22:41 -0500589 redfish::sensor_utils::splitSensorNameAndType(sensorName);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100590 if (split.first.empty() || split.second.empty())
591 {
592 messages::propertyValueIncorrect(
593 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
594 return false;
595 }
596
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400597 std::string sensorPath =
598 "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100599
600 ctx.sensors.emplace_back(sensorPath, uriStr);
601 uriIdx++;
602 }
603 return true;
604}
605
606inline bool parsePostTriggerParams(crow::Response& res,
607 const crow::Request& req, Context& ctx)
608{
609 std::optional<std::string> id = "";
610 std::optional<std::string> name = "";
611 std::optional<std::string> metricType;
612 std::optional<std::vector<std::string>> triggerActions;
613 std::optional<std::string> discreteTriggerCondition;
Ed Tanous2932dcb2024-03-06 12:04:47 -0800614 std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
615 std::optional<std::vector<std::string>> metricReportDefinitions;
616 NumericThresholds thresholds;
Myung Baeafc474a2024-10-09 00:53:29 -0700617
Patrick Williams504af5a2025-02-03 14:29:03 -0500618 if (!json_util::readJsonPatch( //
619 req, res, //
620 "Id", id, //
621 "DiscreteTriggerCondition", discreteTriggerCondition, //
622 "DiscreteTriggers", discreteTriggers, //
623 "Links/MetricReportDefinitions", metricReportDefinitions, //
624 "MetricProperties", ctx.metricProperties, //
625 "MetricType", metricType, //
626 "Name", name, //
Myung Baeafc474a2024-10-09 00:53:29 -0700627 "NumericThresholds/LowerCritical", thresholds.lowerCritical, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500628 "NumericThresholds/LowerWarning", thresholds.lowerWarning, //
Myung Baeafc474a2024-10-09 00:53:29 -0700629 "NumericThresholds/UpperCritical", thresholds.upperCritical, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500630 "NumericThresholds/UpperWarning", thresholds.upperWarning, //
631 "TriggerActions", triggerActions //
Myung Baeafc474a2024-10-09 00:53:29 -0700632 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100633 {
634 return false;
635 }
636
637 ctx.id = *id;
638 ctx.name = *name;
639
640 if (metricType)
641 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700642 ctx.metricType = getMetricType(*metricType);
643 if (!ctx.metricType)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100644 {
645 messages::propertyValueIncorrect(res, "MetricType", *metricType);
646 return false;
647 }
648 }
649
650 if (discreteTriggerCondition)
651 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700652 ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
653 if (!ctx.discreteCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100654 {
655 messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
656 *discreteTriggerCondition);
657 return false;
658 }
659 }
660
661 if (triggerActions)
662 {
663 ctx.actions.reserve(triggerActions->size());
664 for (const std::string& action : *triggerActions)
665 {
666 std::string dbusAction = toDbusTriggerAction(action);
667
668 if (dbusAction.empty())
669 {
670 messages::propertyValueNotInList(res, action, "TriggerActions");
671 return false;
672 }
673
674 ctx.actions.emplace_back(dbusAction);
675 }
676 }
677 if (!parseMetricProperties(res, ctx))
678 {
679 return false;
680 }
681
Ed Tanous2932dcb2024-03-06 12:04:47 -0800682 if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100683 {
684 return false;
685 }
686
Ed Tanous2932dcb2024-03-06 12:04:47 -0800687 if (metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100688 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800689 if (!parseLinks(res, *metricReportDefinitions, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100690 {
691 return false;
692 }
693 }
694 return true;
695}
696
697inline void afterCreateTrigger(
698 const boost::system::error_code& ec, const std::string& dbusPath,
699 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
700{
701 if (ec == boost::system::errc::file_exists)
702 {
703 messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
704 return;
705 }
706 if (ec == boost::system::errc::too_many_files_open)
707 {
708 messages::createLimitReachedForResource(asyncResp->res);
709 return;
710 }
711 if (ec)
712 {
713 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700714 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100715 return;
716 }
717
718 const std::optional<std::string>& triggerId =
719 getTriggerIdFromDbusPath(dbusPath);
720 if (!triggerId)
721 {
722 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700723 BMCWEB_LOG_ERROR("Unknown data returned by "
724 "AddTrigger DBus method");
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100725 return;
726 }
727
728 messages::created(asyncResp->res);
729 boost::urls::url locationUrl = boost::urls::format(
730 "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
731 asyncResp->res.addHeader("Location", locationUrl.buffer());
732}
733
Patrick Williams504af5a2025-02-03 14:29:03 -0500734inline std::optional<nlohmann::json::array_t> getTriggerActions(
735 const std::vector<std::string>& dbusActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200736{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100737 nlohmann::json::array_t triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200738 for (const std::string& dbusAction : dbusActions)
739 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100740 triggers::TriggerActionEnum redfishAction =
741 toRedfishTriggerAction(dbusAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200742
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100743 if (redfishAction == triggers::TriggerActionEnum::Invalid)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200744 {
745 return std::nullopt;
746 }
747
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100748 triggerActions.emplace_back(redfishAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200749 }
750
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100751 return triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200752}
753
Ed Tanous58c71482024-10-19 14:35:07 -0700754inline std::optional<nlohmann::json::array_t> getDiscreteTriggers(
755 const std::vector<DiscreteThresholdParams>& discreteParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200756{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100757 nlohmann::json::array_t triggers;
Ed Tanous58c71482024-10-19 14:35:07 -0700758 for (const auto& [name, severity, dwellTime, value] : discreteParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200759 {
760 std::optional<std::string> duration =
761 time_utils::toDurationStringFromUint(dwellTime);
762
763 if (!duration)
764 {
765 return std::nullopt;
766 }
Ed Tanous613dabe2022-07-09 11:17:36 -0700767 nlohmann::json::object_t trigger;
768 trigger["Name"] = name;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100769 trigger["Severity"] = toRedfishSeverity(severity);
Ed Tanous613dabe2022-07-09 11:17:36 -0700770 trigger["DwellTime"] = *duration;
771 trigger["Value"] = value;
Patrick Williamsad539542023-05-12 10:10:08 -0500772 triggers.emplace_back(std::move(trigger));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200773 }
774
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100775 return triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200776}
777
Ed Tanous58c71482024-10-19 14:35:07 -0700778inline std::optional<nlohmann::json::object_t> getNumericThresholds(
779 const std::vector<NumericThresholdParams>& numericParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200780{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100781 nlohmann::json::object_t thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200782
Ed Tanous58c71482024-10-19 14:35:07 -0700783 for (const auto& [type, dwellTime, activation, reading] : numericParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200784 {
785 std::optional<std::string> duration =
786 time_utils::toDurationStringFromUint(dwellTime);
787
788 if (!duration)
789 {
790 return std::nullopt;
791 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100792 nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
Ed Tanous14766872022-03-15 10:44:42 -0700793 threshold["Reading"] = reading;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100794 threshold["Activation"] = toRedfishActivation(activation);
Ed Tanous14766872022-03-15 10:44:42 -0700795 threshold["DwellTime"] = *duration;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200796 }
797
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100798 return thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200799}
800
Szymon Dompke3f215c92022-02-22 13:58:00 +0100801inline std::optional<nlohmann::json> getMetricReportDefinitions(
802 const std::vector<sdbusplus::message::object_path>& reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200803{
804 nlohmann::json reports = nlohmann::json::array();
Szymon Dompke3f215c92022-02-22 13:58:00 +0100805
806 for (const sdbusplus::message::object_path& path : reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200807 {
Szymon Dompke3f215c92022-02-22 13:58:00 +0100808 std::string reportId = path.filename();
809 if (reportId.empty())
810 {
811 {
Ed Tanous62598e32023-07-17 17:06:25 -0700812 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
813 path.str);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100814 return std::nullopt;
815 }
816 }
817
Ed Tanous14766872022-03-15 10:44:42 -0700818 nlohmann::json::object_t report;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700819 report["@odata.id"] = boost::urls::format(
820 "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
821 reportId);
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500822 reports.emplace_back(std::move(report));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200823 }
824
Szymon Dompke3f215c92022-02-22 13:58:00 +0100825 return {std::move(reports)};
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200826}
827
Patrick Williams504af5a2025-02-03 14:29:03 -0500828inline std::vector<std::string> getMetricProperties(
829 const TriggerSensorsParams& sensors)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200830{
831 std::vector<std::string> metricProperties;
832 metricProperties.reserve(sensors.size());
833 for (const auto& [_, metadata] : sensors)
834 {
835 metricProperties.emplace_back(metadata);
836 }
837
838 return metricProperties;
839}
840
Ed Tanouse3648032024-10-16 18:06:39 -0700841inline bool fillTrigger(nlohmann::json& json, const std::string& id,
842 const dbus::utility::DBusPropertiesMap& properties)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200843{
844 const std::string* name = nullptr;
845 const bool* discrete = nullptr;
846 const TriggerSensorsParams* sensors = nullptr;
Szymon Dompke3f215c92022-02-22 13:58:00 +0100847 const std::vector<sdbusplus::message::object_path>* reports = nullptr;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200848 const std::vector<std::string>* triggerActions = nullptr;
Ed Tanous58c71482024-10-19 14:35:07 -0700849
850 const std::vector<DiscreteThresholdParams>* discreteThresholds = nullptr;
851 const std::vector<NumericThresholdParams>* numericThresholds = nullptr;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200852
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200853 const bool success = sdbusplus::unpackPropertiesNoThrow(
854 dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
855 discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
Ed Tanous58c71482024-10-19 14:35:07 -0700856 triggerActions, "DiscreteThresholds", discreteThresholds,
857 "NumericThresholds", numericThresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200858
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200859 if (!success)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200860 {
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200861 return false;
862 }
863
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200864 if (triggerActions != nullptr)
Szymon Dompke3f215c92022-02-22 13:58:00 +0100865 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100866 std::optional<nlohmann::json::array_t> redfishTriggerActions =
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200867 getTriggerActions(*triggerActions);
868 if (!redfishTriggerActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200869 {
Ed Tanous62598e32023-07-17 17:06:25 -0700870 BMCWEB_LOG_ERROR(
871 "Property TriggerActions is invalid in Trigger: {}", id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200872 return false;
873 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100874 json["TriggerActions"] = *redfishTriggerActions;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200875 }
876
877 if (reports != nullptr)
878 {
879 std::optional<nlohmann::json> linkedReports =
880 getMetricReportDefinitions(*reports);
881 if (!linkedReports)
882 {
Ed Tanous62598e32023-07-17 17:06:25 -0700883 BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200884 return false;
885 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200886 json["Links"]["MetricReportDefinitions"] = *linkedReports;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200887 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200888
Ed Tanous58c71482024-10-19 14:35:07 -0700889 if (discreteThresholds != nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200890 {
Ed Tanous58c71482024-10-19 14:35:07 -0700891 std::optional<nlohmann::json::array_t> discreteTriggers =
892 getDiscreteTriggers(*discreteThresholds);
893
894 if (!discreteTriggers)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200895 {
Ed Tanous58c71482024-10-19 14:35:07 -0700896 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
897 "triggers in Trigger: {}",
898 id);
899 return false;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200900 }
Ed Tanous58c71482024-10-19 14:35:07 -0700901
902 json["DiscreteTriggers"] = *discreteTriggers;
903 json["DiscreteTriggerCondition"] =
904 discreteTriggers->empty() ? "Changed" : "Specified";
905 json["MetricType"] = metric_definition::MetricType::Discrete;
906 }
907 if (numericThresholds != nullptr)
908 {
909 std::optional<nlohmann::json::object_t> jnumericThresholds =
910 getNumericThresholds(*numericThresholds);
911
912 if (!jnumericThresholds)
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200913 {
Ed Tanous58c71482024-10-19 14:35:07 -0700914 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
915 "thresholds in Trigger: {}",
916 id);
917 return false;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200918 }
Ed Tanous58c71482024-10-19 14:35:07 -0700919
920 json["NumericThresholds"] = *jnumericThresholds;
921 json["MetricType"] = metric_definition::MetricType::Numeric;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200922 }
923
924 if (name != nullptr)
925 {
926 json["Name"] = *name;
927 }
928
929 if (sensors != nullptr)
930 {
931 json["MetricProperties"] = getMetricProperties(*sensors);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200932 }
933
Szymon Dompke3f215c92022-02-22 13:58:00 +0100934 json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700935 json["@odata.id"] =
936 boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100937 json["Id"] = id;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200938
939 return true;
940}
941
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100942inline void handleTriggerCollectionPost(
943 App& app, const crow::Request& req,
944 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
945{
946 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
947 {
948 return;
949 }
950
951 telemetry::Context ctx;
952 if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
953 {
954 return;
955 }
956
957 crow::connections::systemBus->async_method_call(
958 [asyncResp, id = ctx.id](const boost::system::error_code& ec,
959 const std::string& dbusPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400960 afterCreateTrigger(ec, dbusPath, asyncResp, id);
961 },
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100962 service, "/xyz/openbmc_project/Telemetry/Triggers",
963 "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
964 "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
Ed Tanous58c71482024-10-19 14:35:07 -0700965 ctx.reports, ctx.numericThresholds, ctx.discreteThresholds);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100966}
967
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200968} // namespace telemetry
969
970inline void requestRoutesTriggerCollection(App& app)
971{
972 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
973 .privileges(redfish::privileges::getTriggersCollection)
974 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700975 [&app](const crow::Request& req,
976 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400977 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
978 {
979 return;
980 }
981 asyncResp->res.jsonValue["@odata.type"] =
982 "#TriggersCollection.TriggersCollection";
983 asyncResp->res.jsonValue["@odata.id"] =
984 "/redfish/v1/TelemetryService/Triggers";
985 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
986 constexpr std::array<std::string_view, 1> interfaces{
987 telemetry::triggerInterface};
988 collection_util::getCollectionMembers(
989 asyncResp,
990 boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
991 interfaces,
992 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
993 });
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100994
995 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
996 .privileges(redfish::privileges::postTriggersCollection)
997 .methods(boost::beast::http::verb::post)(std::bind_front(
998 telemetry::handleTriggerCollectionPost, std::ref(app)));
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200999}
1000
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001001inline void requestRoutesTrigger(App& app)
1002{
1003 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1004 .privileges(redfish::privileges::getTriggers)
1005 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001006 [&app](const crow::Request& req,
1007 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1008 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001009 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1010 {
1011 return;
1012 }
Ed Tanous46f780f2025-02-09 09:35:23 -08001013 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001014 *crow::connections::systemBus, telemetry::service,
1015 telemetry::getDbusTriggerPath(id),
1016 telemetry::triggerInterface,
1017 [asyncResp,
1018 id](const boost::system::error_code& ec,
Ed Tanouse3648032024-10-16 18:06:39 -07001019 const dbus::utility::DBusPropertiesMap& ret) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001020 if (ec.value() == EBADR ||
1021 ec == boost::system::errc::host_unreachable)
1022 {
1023 messages::resourceNotFound(asyncResp->res,
1024 "Triggers", id);
1025 return;
1026 }
1027 if (ec)
1028 {
1029 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1030 messages::internalError(asyncResp->res);
1031 return;
1032 }
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001033
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001034 if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
1035 id, ret))
1036 {
1037 messages::internalError(asyncResp->res);
1038 }
1039 });
1040 });
Szymon Dompke163994a2021-08-12 17:30:23 +02001041
1042 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1043 .privileges(redfish::privileges::deleteTriggers)
1044 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001045 [&app](const crow::Request& req,
1046 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1047 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001048 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1049 {
1050 return;
1051 }
1052 const std::string triggerPath =
1053 telemetry::getDbusTriggerPath(id);
Szymon Dompke163994a2021-08-12 17:30:23 +02001054
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001055 crow::connections::systemBus->async_method_call(
1056 [asyncResp, id](const boost::system::error_code& ec) {
1057 if (ec.value() == EBADR)
1058 {
1059 messages::resourceNotFound(asyncResp->res,
1060 "Triggers", id);
1061 return;
1062 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001063
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001064 if (ec)
1065 {
1066 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1067 messages::internalError(asyncResp->res);
1068 return;
1069 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001070
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001071 asyncResp->res.result(
1072 boost::beast::http::status::no_content);
1073 },
1074 telemetry::service, triggerPath,
1075 "xyz.openbmc_project.Object.Delete", "Delete");
1076 });
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001077}
1078
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001079} // namespace redfish