blob: 7f4a614c18ed68e6d63fdcc66d18bcfc697a05ec [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>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020036#include <sdbusplus/asio/property.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080037#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020038#include <sdbusplus/unpack_properties.hpp>
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020039
George Liu7a1dbc42022-12-07 16:03:22 +080040#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080041#include <chrono>
42#include <cstddef>
43#include <cstdint>
44#include <functional>
45#include <memory>
46#include <optional>
47#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080048#include <string_view>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020049#include <tuple>
Ed Tanousd7857202025-01-28 15:32:26 -080050#include <utility>
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020051#include <vector>
52
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020053namespace redfish
54{
55namespace telemetry
56{
57constexpr const char* triggerInterface =
58 "xyz.openbmc_project.Telemetry.Trigger";
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +020059
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020060using NumericThresholdParams =
61 std::tuple<std::string, uint64_t, std::string, double>;
62
63using DiscreteThresholdParams =
64 std::tuple<std::string, std::string, uint64_t, std::string>;
65
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020066using TriggerSensorsParams =
67 std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
68
Patrick Williams504af5a2025-02-03 14:29:03 -050069inline triggers::TriggerActionEnum toRedfishTriggerAction(
70 std::string_view dbusValue)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020071{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010072 if (dbusValue ==
73 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020074 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010075 return triggers::TriggerActionEnum::RedfishMetricReport;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020076 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010077 if (dbusValue ==
78 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020079 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010080 return triggers::TriggerActionEnum::RedfishEvent;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020081 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010082 if (dbusValue ==
83 "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020084 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010085 return triggers::TriggerActionEnum::LogToLogService;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020086 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010087 return triggers::TriggerActionEnum::Invalid;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +020088}
89
Szymon Dompkedd1c4a92022-03-04 13:11:38 +010090inline std::string toDbusTriggerAction(std::string_view redfishValue)
91{
92 if (redfishValue == "RedfishMetricReport")
93 {
94 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
95 }
96 if (redfishValue == "RedfishEvent")
97 {
98 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
99 }
100 if (redfishValue == "LogToLogService")
101 {
102 return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
103 }
104 return "";
105}
106
107inline std::string toDbusSeverity(std::string_view redfishValue)
108{
109 if (redfishValue == "OK")
110 {
111 return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
112 }
113 if (redfishValue == "Warning")
114 {
115 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
116 }
117 if (redfishValue == "Critical")
118 {
119 return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
120 }
121 return "";
122}
123
124inline resource::Health toRedfishSeverity(std::string_view dbusValue)
125{
126 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
127 {
128 return resource::Health::OK;
129 }
130 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
131 {
132 return resource::Health::Warning;
133 }
134 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
135 {
136 return resource::Health::Critical;
137 }
138 return resource::Health::Invalid;
139}
140
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100141inline std::string toRedfishThresholdName(std::string_view dbusValue)
142{
143 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
144 {
145 return "UpperCritical";
146 }
147
148 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
149 {
150 return "LowerCritical";
151 }
152
153 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
154 {
155 return "UpperWarning";
156 }
157
158 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
159 {
160 return "LowerWarning";
161 }
162
163 return "";
164}
165
166inline std::string toDbusActivation(std::string_view redfishValue)
167{
168 if (redfishValue == "Either")
169 {
170 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
171 }
172
173 if (redfishValue == "Decreasing")
174 {
175 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
176 }
177
178 if (redfishValue == "Increasing")
179 {
180 return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
181 }
182
183 return "";
184}
185
Patrick Williams504af5a2025-02-03 14:29:03 -0500186inline triggers::ThresholdActivation toRedfishActivation(
187 std::string_view dbusValue)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100188{
189 if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
190 {
191 return triggers::ThresholdActivation::Either;
192 }
193
194 if (dbusValue ==
195 "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
196 {
197 return triggers::ThresholdActivation::Decreasing;
198 }
199
200 if (dbusValue ==
201 "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
202 {
203 return triggers::ThresholdActivation::Increasing;
204 }
205
206 return triggers::ThresholdActivation::Invalid;
207}
208
209enum class MetricType
210{
211 Discrete,
212 Numeric
213};
214
215enum class DiscreteCondition
216{
217 Specified,
218 Changed
219};
220
221struct Context
222{
223 std::string id;
224 std::string name;
225 std::vector<std::string> actions;
226 std::vector<std::pair<sdbusplus::message::object_path, std::string>>
227 sensors;
228 std::vector<sdbusplus::message::object_path> reports;
Ed Tanous58c71482024-10-19 14:35:07 -0700229 std::vector<NumericThresholdParams> numericThresholds;
230 std::vector<DiscreteThresholdParams> discreteThresholds;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100231 std::optional<DiscreteCondition> discreteCondition;
232 std::optional<MetricType> metricType;
233 std::optional<std::vector<std::string>> metricProperties;
234};
235
236inline std::optional<sdbusplus::message::object_path>
237 getReportPathFromReportDefinitionUri(const std::string& uri)
238{
Ed Tanous6fd29552023-10-04 09:40:14 -0700239 boost::system::result<boost::urls::url_view> parsed =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100240 boost::urls::parse_relative_ref(uri);
241
242 if (!parsed)
243 {
244 return std::nullopt;
245 }
246
247 std::string id;
248 if (!crow::utility::readUrlSegments(
249 *parsed, "redfish", "v1", "TelemetryService",
250 "MetricReportDefinitions", std::ref(id)))
251 {
252 return std::nullopt;
253 }
254
255 return sdbusplus::message::object_path(
256 "/xyz/openbmc_project/Telemetry/Reports") /
257 "TelemetryService" / id;
258}
259
260inline std::optional<MetricType> getMetricType(const std::string& metricType)
261{
262 if (metricType == "Discrete")
263 {
264 return MetricType::Discrete;
265 }
266 if (metricType == "Numeric")
267 {
268 return MetricType::Numeric;
269 }
270 return std::nullopt;
271}
272
Patrick Williams504af5a2025-02-03 14:29:03 -0500273inline std::optional<DiscreteCondition> getDiscreteCondition(
274 const std::string& discreteTriggerCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100275{
276 if (discreteTriggerCondition == "Specified")
277 {
278 return DiscreteCondition::Specified;
279 }
280 if (discreteTriggerCondition == "Changed")
281 {
282 return DiscreteCondition::Changed;
283 }
284 return std::nullopt;
285}
286
Ed Tanous2932dcb2024-03-06 12:04:47 -0800287inline bool parseThreshold(crow::Response& res,
288 nlohmann::json::object_t& threshold,
289 std::string_view dbusThresholdName,
290 std::vector<NumericThresholdParams>& parsedParams)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100291{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800292 double reading = 0.0;
293 std::string activation;
294 std::string dwellTimeStr;
295
Patrick Williams504af5a2025-02-03 14:29:03 -0500296 if (!json_util::readJsonObject( //
297 threshold, res, //
298 "Activation", activation, //
Myung Baeafc474a2024-10-09 00:53:29 -0700299 "DwellTime", dwellTimeStr, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500300 "Reading", reading //
Myung Baeafc474a2024-10-09 00:53:29 -0700301 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100302 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100303 return false;
304 }
305
Ed Tanous2932dcb2024-03-06 12:04:47 -0800306 std::string dbusActivation = toDbusActivation(activation);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100307
Ed Tanous2932dcb2024-03-06 12:04:47 -0800308 if (dbusActivation.empty())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100309 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800310 messages::propertyValueIncorrect(res, "Activation", activation);
311 return false;
312 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100313
Ed Tanous2932dcb2024-03-06 12:04:47 -0800314 std::optional<std::chrono::milliseconds> dwellTime =
315 time_utils::fromDurationString(dwellTimeStr);
316 if (!dwellTime)
317 {
318 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
319 return false;
320 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100321
Ed Tanous2932dcb2024-03-06 12:04:47 -0800322 parsedParams.emplace_back(dbusThresholdName,
323 static_cast<uint64_t>(dwellTime->count()),
324 dbusActivation, reading);
325 return true;
326}
327
328struct NumericThresholds
329{
330 std::optional<nlohmann::json::object_t> upperCritical;
331 std::optional<nlohmann::json::object_t> upperWarning;
332 std::optional<nlohmann::json::object_t> lowerWarning;
333 std::optional<nlohmann::json::object_t> lowerCritical;
334
335 bool any() const
336 {
337 return upperCritical || upperWarning || lowerWarning || lowerCritical;
338 }
339};
340
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400341inline bool parseNumericThresholds(
342 crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
Ed Tanous2932dcb2024-03-06 12:04:47 -0800343{
344 std::vector<NumericThresholdParams> parsedParams;
345 if (numericThresholds.upperCritical)
346 {
347 if (!parseThreshold(
348 res, *numericThresholds.upperCritical,
349 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
350 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100351 {
352 return false;
353 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800354 }
355 if (numericThresholds.upperWarning)
356 {
357 if (!parseThreshold(
358 res, *numericThresholds.upperWarning,
359 "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
360 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100361 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100362 return false;
363 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800364 }
365 if (numericThresholds.lowerWarning)
366 {
367 if (!parseThreshold(
368 res, *numericThresholds.lowerWarning,
369 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
370 parsedParams))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100371 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100372 return false;
373 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800374 }
375 if (numericThresholds.lowerCritical)
376 {
377 if (!parseThreshold(
378 res, *numericThresholds.lowerCritical,
379 "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
380 parsedParams))
381 {
382 return false;
383 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100384 }
385
Ed Tanous58c71482024-10-19 14:35:07 -0700386 ctx.numericThresholds = std::move(parsedParams);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100387 return true;
388}
389
390inline bool parseDiscreteTriggers(
391 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800392 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
393 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100394{
395 std::vector<DiscreteThresholdParams> parsedParams;
396 if (!discreteTriggers)
397 {
Ed Tanous58c71482024-10-19 14:35:07 -0700398 ctx.discreteThresholds = std::move(parsedParams);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100399 return true;
400 }
401
402 parsedParams.reserve(discreteTriggers->size());
Ed Tanous2932dcb2024-03-06 12:04:47 -0800403 for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100404 {
405 std::optional<std::string> name = "";
406 std::string value;
407 std::string dwellTimeStr;
408 std::string severity;
409
Patrick Williams504af5a2025-02-03 14:29:03 -0500410 if (!json_util::readJsonObject( //
411 thresholdInfo, res, //
Myung Baeafc474a2024-10-09 00:53:29 -0700412 "DwellTime", dwellTimeStr, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500413 "Name", name, //
414 "Severity", severity, //
415 "Value", value //
Myung Baeafc474a2024-10-09 00:53:29 -0700416 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100417 {
418 return false;
419 }
420
421 std::optional<std::chrono::milliseconds> dwellTime =
422 time_utils::fromDurationString(dwellTimeStr);
423 if (!dwellTime)
424 {
425 messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
426 return false;
427 }
428
429 std::string dbusSeverity = toDbusSeverity(severity);
430 if (dbusSeverity.empty())
431 {
432 messages::propertyValueIncorrect(res, "Severity", severity);
433 return false;
434 }
435
436 parsedParams.emplace_back(*name, dbusSeverity,
437 static_cast<uint64_t>(dwellTime->count()),
438 value);
439 }
440
Ed Tanous58c71482024-10-19 14:35:07 -0700441 ctx.discreteThresholds = std::move(parsedParams);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100442 return true;
443}
444
445inline bool parseTriggerThresholds(
446 crow::Response& res,
Ed Tanous2932dcb2024-03-06 12:04:47 -0800447 std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
448 NumericThresholds& numericThresholds, Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100449{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800450 if (discreteTriggers && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100451 {
452 messages::propertyValueConflict(res, "DiscreteTriggers",
453 "NumericThresholds");
454 messages::propertyValueConflict(res, "NumericThresholds",
455 "DiscreteTriggers");
456 return false;
457 }
458
459 if (ctx.discreteCondition)
460 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800461 if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100462 {
463 messages::propertyValueConflict(res, "DiscreteTriggerCondition",
464 "NumericThresholds");
465 messages::propertyValueConflict(res, "NumericThresholds",
466 "DiscreteTriggerCondition");
467 return false;
468 }
469 }
470
471 if (ctx.metricType)
472 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800473 if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100474 {
475 messages::propertyValueConflict(res, "NumericThresholds",
476 "MetricType");
477 return false;
478 }
479 if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
480 {
481 messages::propertyValueConflict(res, "DiscreteTriggers",
482 "MetricType");
483 return false;
484 }
485 if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
486 {
487 messages::propertyValueConflict(res, "DiscreteTriggers",
488 "DiscreteTriggerCondition");
489 return false;
490 }
491 }
492
493 if (discreteTriggers || ctx.discreteCondition ||
494 (ctx.metricType && *ctx.metricType == MetricType::Discrete))
495 {
496 if (ctx.discreteCondition)
497 {
498 if (*ctx.discreteCondition == DiscreteCondition::Specified &&
499 !discreteTriggers)
500 {
501 messages::createFailedMissingReqProperties(res,
502 "DiscreteTriggers");
503 return false;
504 }
505 if (discreteTriggers &&
506 ((*ctx.discreteCondition == DiscreteCondition::Specified &&
507 discreteTriggers->empty()) ||
508 (*ctx.discreteCondition == DiscreteCondition::Changed &&
509 !discreteTriggers->empty())))
510 {
511 messages::propertyValueConflict(res, "DiscreteTriggers",
512 "DiscreteTriggerCondition");
513 return false;
514 }
515 }
516 if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
517 {
518 return false;
519 }
520 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800521 else if (numericThresholds.any())
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100522 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800523 if (!parseNumericThresholds(res, numericThresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100524 {
525 return false;
526 }
527 }
528 else
529 {
530 messages::createFailedMissingReqProperties(
531 res, "'DiscreteTriggers', 'NumericThresholds', "
532 "'DiscreteTriggerCondition' or 'MetricType'");
533 return false;
534 }
535 return true;
536}
537
Ed Tanous2932dcb2024-03-06 12:04:47 -0800538inline bool parseLinks(crow::Response& res,
539 const std::vector<std::string>& metricReportDefinitions,
540 Context& ctx)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100541{
Ed Tanous2932dcb2024-03-06 12:04:47 -0800542 ctx.reports.reserve(metricReportDefinitions.size());
543 for (const std::string& reportDefinionUri : metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100544 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800545 std::optional<sdbusplus::message::object_path> reportPath =
546 getReportPathFromReportDefinitionUri(reportDefinionUri);
547 if (!reportPath)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100548 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800549 messages::propertyValueIncorrect(res, "MetricReportDefinitions",
550 reportDefinionUri);
551 return false;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100552 }
Ed Tanous2932dcb2024-03-06 12:04:47 -0800553 ctx.reports.emplace_back(*reportPath);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100554 }
555 return true;
556}
557
558inline bool parseMetricProperties(crow::Response& res, Context& ctx)
559{
560 if (!ctx.metricProperties)
561 {
562 return true;
563 }
564
565 ctx.sensors.reserve(ctx.metricProperties->size());
566
567 size_t uriIdx = 0;
568 for (const std::string& uriStr : *ctx.metricProperties)
569 {
Ed Tanous4a7fbef2024-04-06 16:03:49 -0700570 boost::system::result<boost::urls::url> uri =
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100571 boost::urls::parse_relative_ref(uriStr);
572 if (!uri)
573 {
574 messages::propertyValueIncorrect(
575 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
576 return false;
577 }
578 std::string chassisName;
579 std::string sensorName;
580 if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
581 std::ref(chassisName), "Sensors",
582 std::ref(sensorName)))
583 {
584 messages::propertyValueIncorrect(
585 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
586 return false;
587 }
588
589 std::pair<std::string, std::string> split =
Janet Adkins1516c212024-08-14 13:22:41 -0500590 redfish::sensor_utils::splitSensorNameAndType(sensorName);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100591 if (split.first.empty() || split.second.empty())
592 {
593 messages::propertyValueIncorrect(
594 res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
595 return false;
596 }
597
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400598 std::string sensorPath =
599 "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100600
601 ctx.sensors.emplace_back(sensorPath, uriStr);
602 uriIdx++;
603 }
604 return true;
605}
606
607inline bool parsePostTriggerParams(crow::Response& res,
608 const crow::Request& req, Context& ctx)
609{
610 std::optional<std::string> id = "";
611 std::optional<std::string> name = "";
612 std::optional<std::string> metricType;
613 std::optional<std::vector<std::string>> triggerActions;
614 std::optional<std::string> discreteTriggerCondition;
Ed Tanous2932dcb2024-03-06 12:04:47 -0800615 std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
616 std::optional<std::vector<std::string>> metricReportDefinitions;
617 NumericThresholds thresholds;
Myung Baeafc474a2024-10-09 00:53:29 -0700618
Patrick Williams504af5a2025-02-03 14:29:03 -0500619 if (!json_util::readJsonPatch( //
620 req, res, //
621 "Id", id, //
622 "DiscreteTriggerCondition", discreteTriggerCondition, //
623 "DiscreteTriggers", discreteTriggers, //
624 "Links/MetricReportDefinitions", metricReportDefinitions, //
625 "MetricProperties", ctx.metricProperties, //
626 "MetricType", metricType, //
627 "Name", name, //
Myung Baeafc474a2024-10-09 00:53:29 -0700628 "NumericThresholds/LowerCritical", thresholds.lowerCritical, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500629 "NumericThresholds/LowerWarning", thresholds.lowerWarning, //
Myung Baeafc474a2024-10-09 00:53:29 -0700630 "NumericThresholds/UpperCritical", thresholds.upperCritical, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500631 "NumericThresholds/UpperWarning", thresholds.upperWarning, //
632 "TriggerActions", triggerActions //
Myung Baeafc474a2024-10-09 00:53:29 -0700633 ))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100634 {
635 return false;
636 }
637
638 ctx.id = *id;
639 ctx.name = *name;
640
641 if (metricType)
642 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700643 ctx.metricType = getMetricType(*metricType);
644 if (!ctx.metricType)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100645 {
646 messages::propertyValueIncorrect(res, "MetricType", *metricType);
647 return false;
648 }
649 }
650
651 if (discreteTriggerCondition)
652 {
Ed Tanousd5736ef2023-07-06 10:37:23 -0700653 ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
654 if (!ctx.discreteCondition)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100655 {
656 messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
657 *discreteTriggerCondition);
658 return false;
659 }
660 }
661
662 if (triggerActions)
663 {
664 ctx.actions.reserve(triggerActions->size());
665 for (const std::string& action : *triggerActions)
666 {
667 std::string dbusAction = toDbusTriggerAction(action);
668
669 if (dbusAction.empty())
670 {
671 messages::propertyValueNotInList(res, action, "TriggerActions");
672 return false;
673 }
674
675 ctx.actions.emplace_back(dbusAction);
676 }
677 }
678 if (!parseMetricProperties(res, ctx))
679 {
680 return false;
681 }
682
Ed Tanous2932dcb2024-03-06 12:04:47 -0800683 if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100684 {
685 return false;
686 }
687
Ed Tanous2932dcb2024-03-06 12:04:47 -0800688 if (metricReportDefinitions)
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100689 {
Ed Tanous2932dcb2024-03-06 12:04:47 -0800690 if (!parseLinks(res, *metricReportDefinitions, ctx))
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100691 {
692 return false;
693 }
694 }
695 return true;
696}
697
698inline void afterCreateTrigger(
699 const boost::system::error_code& ec, const std::string& dbusPath,
700 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
701{
702 if (ec == boost::system::errc::file_exists)
703 {
704 messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
705 return;
706 }
707 if (ec == boost::system::errc::too_many_files_open)
708 {
709 messages::createLimitReachedForResource(asyncResp->res);
710 return;
711 }
712 if (ec)
713 {
714 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700715 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100716 return;
717 }
718
719 const std::optional<std::string>& triggerId =
720 getTriggerIdFromDbusPath(dbusPath);
721 if (!triggerId)
722 {
723 messages::internalError(asyncResp->res);
Ed Tanous62598e32023-07-17 17:06:25 -0700724 BMCWEB_LOG_ERROR("Unknown data returned by "
725 "AddTrigger DBus method");
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100726 return;
727 }
728
729 messages::created(asyncResp->res);
730 boost::urls::url locationUrl = boost::urls::format(
731 "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
732 asyncResp->res.addHeader("Location", locationUrl.buffer());
733}
734
Patrick Williams504af5a2025-02-03 14:29:03 -0500735inline std::optional<nlohmann::json::array_t> getTriggerActions(
736 const std::vector<std::string>& dbusActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200737{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100738 nlohmann::json::array_t triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200739 for (const std::string& dbusAction : dbusActions)
740 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100741 triggers::TriggerActionEnum redfishAction =
742 toRedfishTriggerAction(dbusAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200743
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100744 if (redfishAction == triggers::TriggerActionEnum::Invalid)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200745 {
746 return std::nullopt;
747 }
748
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100749 triggerActions.emplace_back(redfishAction);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200750 }
751
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100752 return triggerActions;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200753}
754
Ed Tanous58c71482024-10-19 14:35:07 -0700755inline std::optional<nlohmann::json::array_t> getDiscreteTriggers(
756 const std::vector<DiscreteThresholdParams>& discreteParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200757{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100758 nlohmann::json::array_t triggers;
Ed Tanous58c71482024-10-19 14:35:07 -0700759 for (const auto& [name, severity, dwellTime, value] : discreteParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200760 {
761 std::optional<std::string> duration =
762 time_utils::toDurationStringFromUint(dwellTime);
763
764 if (!duration)
765 {
766 return std::nullopt;
767 }
Ed Tanous613dabe2022-07-09 11:17:36 -0700768 nlohmann::json::object_t trigger;
769 trigger["Name"] = name;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100770 trigger["Severity"] = toRedfishSeverity(severity);
Ed Tanous613dabe2022-07-09 11:17:36 -0700771 trigger["DwellTime"] = *duration;
772 trigger["Value"] = value;
Patrick Williamsad539542023-05-12 10:10:08 -0500773 triggers.emplace_back(std::move(trigger));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200774 }
775
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100776 return triggers;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200777}
778
Ed Tanous58c71482024-10-19 14:35:07 -0700779inline std::optional<nlohmann::json::object_t> getNumericThresholds(
780 const std::vector<NumericThresholdParams>& numericParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200781{
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100782 nlohmann::json::object_t thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200783
Ed Tanous58c71482024-10-19 14:35:07 -0700784 for (const auto& [type, dwellTime, activation, reading] : numericParams)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200785 {
786 std::optional<std::string> duration =
787 time_utils::toDurationStringFromUint(dwellTime);
788
789 if (!duration)
790 {
791 return std::nullopt;
792 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100793 nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
Ed Tanous14766872022-03-15 10:44:42 -0700794 threshold["Reading"] = reading;
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100795 threshold["Activation"] = toRedfishActivation(activation);
Ed Tanous14766872022-03-15 10:44:42 -0700796 threshold["DwellTime"] = *duration;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200797 }
798
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100799 return thresholds;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200800}
801
Szymon Dompke3f215c92022-02-22 13:58:00 +0100802inline std::optional<nlohmann::json> getMetricReportDefinitions(
803 const std::vector<sdbusplus::message::object_path>& reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200804{
805 nlohmann::json reports = nlohmann::json::array();
Szymon Dompke3f215c92022-02-22 13:58:00 +0100806
807 for (const sdbusplus::message::object_path& path : reportPaths)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200808 {
Szymon Dompke3f215c92022-02-22 13:58:00 +0100809 std::string reportId = path.filename();
810 if (reportId.empty())
811 {
812 {
Ed Tanous62598e32023-07-17 17:06:25 -0700813 BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
814 path.str);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100815 return std::nullopt;
816 }
817 }
818
Ed Tanous14766872022-03-15 10:44:42 -0700819 nlohmann::json::object_t report;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700820 report["@odata.id"] = boost::urls::format(
821 "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
822 reportId);
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500823 reports.emplace_back(std::move(report));
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200824 }
825
Szymon Dompke3f215c92022-02-22 13:58:00 +0100826 return {std::move(reports)};
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200827}
828
Patrick Williams504af5a2025-02-03 14:29:03 -0500829inline std::vector<std::string> getMetricProperties(
830 const TriggerSensorsParams& sensors)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200831{
832 std::vector<std::string> metricProperties;
833 metricProperties.reserve(sensors.size());
834 for (const auto& [_, metadata] : sensors)
835 {
836 metricProperties.emplace_back(metadata);
837 }
838
839 return metricProperties;
840}
841
Ed Tanouse3648032024-10-16 18:06:39 -0700842inline bool fillTrigger(nlohmann::json& json, const std::string& id,
843 const dbus::utility::DBusPropertiesMap& properties)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200844{
845 const std::string* name = nullptr;
846 const bool* discrete = nullptr;
847 const TriggerSensorsParams* sensors = nullptr;
Szymon Dompke3f215c92022-02-22 13:58:00 +0100848 const std::vector<sdbusplus::message::object_path>* reports = nullptr;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200849 const std::vector<std::string>* triggerActions = nullptr;
Ed Tanous58c71482024-10-19 14:35:07 -0700850
851 const std::vector<DiscreteThresholdParams>* discreteThresholds = nullptr;
852 const std::vector<NumericThresholdParams>* numericThresholds = nullptr;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200853
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200854 const bool success = sdbusplus::unpackPropertiesNoThrow(
855 dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
856 discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
Ed Tanous58c71482024-10-19 14:35:07 -0700857 triggerActions, "DiscreteThresholds", discreteThresholds,
858 "NumericThresholds", numericThresholds);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200859
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200860 if (!success)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200861 {
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200862 return false;
863 }
864
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200865 if (triggerActions != nullptr)
Szymon Dompke3f215c92022-02-22 13:58:00 +0100866 {
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100867 std::optional<nlohmann::json::array_t> redfishTriggerActions =
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200868 getTriggerActions(*triggerActions);
869 if (!redfishTriggerActions)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200870 {
Ed Tanous62598e32023-07-17 17:06:25 -0700871 BMCWEB_LOG_ERROR(
872 "Property TriggerActions is invalid in Trigger: {}", id);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200873 return false;
874 }
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100875 json["TriggerActions"] = *redfishTriggerActions;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200876 }
877
878 if (reports != nullptr)
879 {
880 std::optional<nlohmann::json> linkedReports =
881 getMetricReportDefinitions(*reports);
882 if (!linkedReports)
883 {
Ed Tanous62598e32023-07-17 17:06:25 -0700884 BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200885 return false;
886 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200887 json["Links"]["MetricReportDefinitions"] = *linkedReports;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200888 }
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200889
Ed Tanous58c71482024-10-19 14:35:07 -0700890 if (discreteThresholds != nullptr)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200891 {
Ed Tanous58c71482024-10-19 14:35:07 -0700892 std::optional<nlohmann::json::array_t> discreteTriggers =
893 getDiscreteTriggers(*discreteThresholds);
894
895 if (!discreteTriggers)
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200896 {
Ed Tanous58c71482024-10-19 14:35:07 -0700897 BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
898 "triggers in Trigger: {}",
899 id);
900 return false;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200901 }
Ed Tanous58c71482024-10-19 14:35:07 -0700902
903 json["DiscreteTriggers"] = *discreteTriggers;
904 json["DiscreteTriggerCondition"] =
905 discreteTriggers->empty() ? "Changed" : "Specified";
906 json["MetricType"] = metric_definition::MetricType::Discrete;
907 }
908 if (numericThresholds != nullptr)
909 {
910 std::optional<nlohmann::json::object_t> jnumericThresholds =
911 getNumericThresholds(*numericThresholds);
912
913 if (!jnumericThresholds)
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200914 {
Ed Tanous58c71482024-10-19 14:35:07 -0700915 BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
916 "thresholds in Trigger: {}",
917 id);
918 return false;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200919 }
Ed Tanous58c71482024-10-19 14:35:07 -0700920
921 json["NumericThresholds"] = *jnumericThresholds;
922 json["MetricType"] = metric_definition::MetricType::Numeric;
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200923 }
924
925 if (name != nullptr)
926 {
927 json["Name"] = *name;
928 }
929
930 if (sensors != nullptr)
931 {
932 json["MetricProperties"] = getMetricProperties(*sensors);
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200933 }
934
Szymon Dompke3f215c92022-02-22 13:58:00 +0100935 json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700936 json["@odata.id"] =
937 boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
Szymon Dompke3f215c92022-02-22 13:58:00 +0100938 json["Id"] = id;
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +0200939
940 return true;
941}
942
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100943inline void handleTriggerCollectionPost(
944 App& app, const crow::Request& req,
945 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
946{
947 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
948 {
949 return;
950 }
951
952 telemetry::Context ctx;
953 if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
954 {
955 return;
956 }
957
958 crow::connections::systemBus->async_method_call(
959 [asyncResp, id = ctx.id](const boost::system::error_code& ec,
960 const std::string& dbusPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400961 afterCreateTrigger(ec, dbusPath, asyncResp, id);
962 },
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100963 service, "/xyz/openbmc_project/Telemetry/Triggers",
964 "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
965 "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
Ed Tanous58c71482024-10-19 14:35:07 -0700966 ctx.reports, ctx.numericThresholds, ctx.discreteThresholds);
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100967}
968
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +0200969} // namespace telemetry
970
971inline void requestRoutesTriggerCollection(App& app)
972{
973 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
974 .privileges(redfish::privileges::getTriggersCollection)
975 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700976 [&app](const crow::Request& req,
977 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400978 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
979 {
980 return;
981 }
982 asyncResp->res.jsonValue["@odata.type"] =
983 "#TriggersCollection.TriggersCollection";
984 asyncResp->res.jsonValue["@odata.id"] =
985 "/redfish/v1/TelemetryService/Triggers";
986 asyncResp->res.jsonValue["Name"] = "Triggers Collection";
987 constexpr std::array<std::string_view, 1> interfaces{
988 telemetry::triggerInterface};
989 collection_util::getCollectionMembers(
990 asyncResp,
991 boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
992 interfaces,
993 "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
994 });
Szymon Dompkedd1c4a92022-03-04 13:11:38 +0100995
996 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
997 .privileges(redfish::privileges::postTriggersCollection)
998 .methods(boost::beast::http::verb::post)(std::bind_front(
999 telemetry::handleTriggerCollectionPost, std::ref(app)));
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001000}
1001
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001002inline void requestRoutesTrigger(App& app)
1003{
1004 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1005 .privileges(redfish::privileges::getTriggers)
1006 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001007 [&app](const crow::Request& req,
1008 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1009 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001010 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1011 {
1012 return;
1013 }
1014 sdbusplus::asio::getAllProperties(
1015 *crow::connections::systemBus, telemetry::service,
1016 telemetry::getDbusTriggerPath(id),
1017 telemetry::triggerInterface,
1018 [asyncResp,
1019 id](const boost::system::error_code& ec,
Ed Tanouse3648032024-10-16 18:06:39 -07001020 const dbus::utility::DBusPropertiesMap& ret) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001021 if (ec.value() == EBADR ||
1022 ec == boost::system::errc::host_unreachable)
1023 {
1024 messages::resourceNotFound(asyncResp->res,
1025 "Triggers", id);
1026 return;
1027 }
1028 if (ec)
1029 {
1030 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1031 messages::internalError(asyncResp->res);
1032 return;
1033 }
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001034
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001035 if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
1036 id, ret))
1037 {
1038 messages::internalError(asyncResp->res);
1039 }
1040 });
1041 });
Szymon Dompke163994a2021-08-12 17:30:23 +02001042
1043 BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1044 .privileges(redfish::privileges::deleteTriggers)
1045 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001046 [&app](const crow::Request& req,
1047 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1048 const std::string& id) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001049 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1050 {
1051 return;
1052 }
1053 const std::string triggerPath =
1054 telemetry::getDbusTriggerPath(id);
Szymon Dompke163994a2021-08-12 17:30:23 +02001055
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001056 crow::connections::systemBus->async_method_call(
1057 [asyncResp, id](const boost::system::error_code& ec) {
1058 if (ec.value() == EBADR)
1059 {
1060 messages::resourceNotFound(asyncResp->res,
1061 "Triggers", id);
1062 return;
1063 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001064
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001065 if (ec)
1066 {
1067 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1068 messages::internalError(asyncResp->res);
1069 return;
1070 }
Szymon Dompke163994a2021-08-12 17:30:23 +02001071
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001072 asyncResp->res.result(
1073 boost::beast::http::status::no_content);
1074 },
1075 telemetry::service, triggerPath,
1076 "xyz.openbmc_project.Object.Delete", "Delete");
1077 });
Lukasz Kazmierczak1b7e6962021-08-02 13:40:27 +02001078}
1079
Lukasz Kazmierczak07148cf2021-08-02 11:08:53 +02001080} // namespace redfish