140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
307148cf2SLukasz Kazmierczak #pragma once
407148cf2SLukasz Kazmierczak
53ccb3adbSEd Tanous #include "app.hpp"
6d7857201SEd Tanous #include "async_resp.hpp"
7d7857201SEd Tanous #include "dbus_singleton.hpp"
8d7857201SEd Tanous #include "dbus_utility.hpp"
9d7857201SEd Tanous #include "error_messages.hpp"
10539d8c6bSEd Tanous #include "generated/enums/metric_definition.hpp"
11dd1c4a9cSSzymon Dompke #include "generated/enums/resource.hpp"
12dd1c4a9cSSzymon Dompke #include "generated/enums/triggers.hpp"
13d7857201SEd Tanous #include "http_request.hpp"
14d7857201SEd Tanous #include "http_response.hpp"
15d7857201SEd Tanous #include "logging.hpp"
163ccb3adbSEd Tanous #include "query.hpp"
173ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
18dd1c4a9cSSzymon Dompke #include "utility.hpp"
1907148cf2SLukasz Kazmierczak #include "utils/collection.hpp"
203ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
215b90429aSEd Tanous #include "utils/json_utils.hpp"
221516c21bSJanet Adkins #include "utils/sensor_utils.hpp"
2307148cf2SLukasz Kazmierczak #include "utils/telemetry_utils.hpp"
243ccb3adbSEd Tanous #include "utils/time_utils.hpp"
2507148cf2SLukasz Kazmierczak
26d7857201SEd Tanous #include <asm-generic/errno.h>
27d7857201SEd Tanous
28d7857201SEd Tanous #include <boost/beast/http/status.hpp>
29d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
30d7857201SEd Tanous #include <boost/system/result.hpp>
31ef4c65b7SEd Tanous #include <boost/url/format.hpp>
32d7857201SEd Tanous #include <boost/url/parse.hpp>
33d7857201SEd Tanous #include <boost/url/url.hpp>
34d7857201SEd Tanous #include <boost/url/url_view.hpp>
35d7857201SEd Tanous #include <nlohmann/json.hpp>
36d7857201SEd Tanous #include <sdbusplus/message/native_types.hpp>
3789474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
3807148cf2SLukasz Kazmierczak
397a1dbc48SGeorge Liu #include <array>
40d7857201SEd Tanous #include <chrono>
41d7857201SEd Tanous #include <cstddef>
42d7857201SEd Tanous #include <cstdint>
43d7857201SEd Tanous #include <functional>
44d7857201SEd Tanous #include <memory>
45d7857201SEd Tanous #include <optional>
46d7857201SEd Tanous #include <string>
477a1dbc48SGeorge Liu #include <string_view>
481b7e696bSLukasz Kazmierczak #include <tuple>
49d7857201SEd Tanous #include <utility>
501b7e696bSLukasz Kazmierczak #include <vector>
511b7e696bSLukasz Kazmierczak
5207148cf2SLukasz Kazmierczak namespace redfish
5307148cf2SLukasz Kazmierczak {
5407148cf2SLukasz Kazmierczak namespace telemetry
5507148cf2SLukasz Kazmierczak {
5607148cf2SLukasz Kazmierczak constexpr const char* triggerInterface =
5707148cf2SLukasz Kazmierczak "xyz.openbmc_project.Telemetry.Trigger";
5807148cf2SLukasz Kazmierczak
591b7e696bSLukasz Kazmierczak using NumericThresholdParams =
601b7e696bSLukasz Kazmierczak std::tuple<std::string, uint64_t, std::string, double>;
611b7e696bSLukasz Kazmierczak
621b7e696bSLukasz Kazmierczak using DiscreteThresholdParams =
631b7e696bSLukasz Kazmierczak std::tuple<std::string, std::string, uint64_t, std::string>;
641b7e696bSLukasz Kazmierczak
651b7e696bSLukasz Kazmierczak using TriggerSensorsParams =
661b7e696bSLukasz Kazmierczak std::vector<std::pair<sdbusplus::message::object_path, std::string>>;
671b7e696bSLukasz Kazmierczak
toRedfishTriggerAction(std::string_view dbusValue)68504af5a0SPatrick Williams inline triggers::TriggerActionEnum toRedfishTriggerAction(
69504af5a0SPatrick Williams std::string_view dbusValue)
701b7e696bSLukasz Kazmierczak {
71dd1c4a9cSSzymon Dompke if (dbusValue ==
72dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport")
731b7e696bSLukasz Kazmierczak {
74dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::RedfishMetricReport;
751b7e696bSLukasz Kazmierczak }
76dd1c4a9cSSzymon Dompke if (dbusValue ==
77dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog")
781b7e696bSLukasz Kazmierczak {
79dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::RedfishEvent;
801b7e696bSLukasz Kazmierczak }
81dd1c4a9cSSzymon Dompke if (dbusValue ==
82dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal")
831b7e696bSLukasz Kazmierczak {
84dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::LogToLogService;
851b7e696bSLukasz Kazmierczak }
86dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::Invalid;
871b7e696bSLukasz Kazmierczak }
881b7e696bSLukasz Kazmierczak
toDbusTriggerAction(std::string_view redfishValue)89dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue)
901b7e696bSLukasz Kazmierczak {
91dd1c4a9cSSzymon Dompke if (redfishValue == "RedfishMetricReport")
921b7e696bSLukasz Kazmierczak {
93dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport";
94dd1c4a9cSSzymon Dompke }
95dd1c4a9cSSzymon Dompke if (redfishValue == "RedfishEvent")
96dd1c4a9cSSzymon Dompke {
97dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog";
98dd1c4a9cSSzymon Dompke }
99dd1c4a9cSSzymon Dompke if (redfishValue == "LogToLogService")
100dd1c4a9cSSzymon Dompke {
101dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal";
102dd1c4a9cSSzymon Dompke }
103dd1c4a9cSSzymon Dompke return "";
104dd1c4a9cSSzymon Dompke }
1051b7e696bSLukasz Kazmierczak
toDbusSeverity(std::string_view redfishValue)106dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue)
107dd1c4a9cSSzymon Dompke {
108dd1c4a9cSSzymon Dompke if (redfishValue == "OK")
109dd1c4a9cSSzymon Dompke {
110dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK";
111dd1c4a9cSSzymon Dompke }
112dd1c4a9cSSzymon Dompke if (redfishValue == "Warning")
113dd1c4a9cSSzymon Dompke {
114dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning";
115dd1c4a9cSSzymon Dompke }
116dd1c4a9cSSzymon Dompke if (redfishValue == "Critical")
117dd1c4a9cSSzymon Dompke {
118dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical";
119dd1c4a9cSSzymon Dompke }
120dd1c4a9cSSzymon Dompke return "";
121dd1c4a9cSSzymon Dompke }
122dd1c4a9cSSzymon Dompke
toRedfishSeverity(std::string_view dbusValue)123dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue)
124dd1c4a9cSSzymon Dompke {
125dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK")
126dd1c4a9cSSzymon Dompke {
127dd1c4a9cSSzymon Dompke return resource::Health::OK;
128dd1c4a9cSSzymon Dompke }
129dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning")
130dd1c4a9cSSzymon Dompke {
131dd1c4a9cSSzymon Dompke return resource::Health::Warning;
132dd1c4a9cSSzymon Dompke }
133dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical")
134dd1c4a9cSSzymon Dompke {
135dd1c4a9cSSzymon Dompke return resource::Health::Critical;
136dd1c4a9cSSzymon Dompke }
137dd1c4a9cSSzymon Dompke return resource::Health::Invalid;
138dd1c4a9cSSzymon Dompke }
139dd1c4a9cSSzymon Dompke
toRedfishThresholdName(std::string_view dbusValue)140dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue)
141dd1c4a9cSSzymon Dompke {
142dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical")
143dd1c4a9cSSzymon Dompke {
144dd1c4a9cSSzymon Dompke return "UpperCritical";
145dd1c4a9cSSzymon Dompke }
146dd1c4a9cSSzymon Dompke
147dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical")
148dd1c4a9cSSzymon Dompke {
149dd1c4a9cSSzymon Dompke return "LowerCritical";
150dd1c4a9cSSzymon Dompke }
151dd1c4a9cSSzymon Dompke
152dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning")
153dd1c4a9cSSzymon Dompke {
154dd1c4a9cSSzymon Dompke return "UpperWarning";
155dd1c4a9cSSzymon Dompke }
156dd1c4a9cSSzymon Dompke
157dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning")
158dd1c4a9cSSzymon Dompke {
159dd1c4a9cSSzymon Dompke return "LowerWarning";
160dd1c4a9cSSzymon Dompke }
161dd1c4a9cSSzymon Dompke
162dd1c4a9cSSzymon Dompke return "";
163dd1c4a9cSSzymon Dompke }
164dd1c4a9cSSzymon Dompke
toDbusActivation(std::string_view redfishValue)165dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue)
166dd1c4a9cSSzymon Dompke {
167dd1c4a9cSSzymon Dompke if (redfishValue == "Either")
168dd1c4a9cSSzymon Dompke {
169dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either";
170dd1c4a9cSSzymon Dompke }
171dd1c4a9cSSzymon Dompke
172dd1c4a9cSSzymon Dompke if (redfishValue == "Decreasing")
173dd1c4a9cSSzymon Dompke {
174dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing";
175dd1c4a9cSSzymon Dompke }
176dd1c4a9cSSzymon Dompke
177dd1c4a9cSSzymon Dompke if (redfishValue == "Increasing")
178dd1c4a9cSSzymon Dompke {
179dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing";
180dd1c4a9cSSzymon Dompke }
181dd1c4a9cSSzymon Dompke
182dd1c4a9cSSzymon Dompke return "";
183dd1c4a9cSSzymon Dompke }
184dd1c4a9cSSzymon Dompke
toRedfishActivation(std::string_view dbusValue)185504af5a0SPatrick Williams inline triggers::ThresholdActivation toRedfishActivation(
186504af5a0SPatrick Williams std::string_view dbusValue)
187dd1c4a9cSSzymon Dompke {
188dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either")
189dd1c4a9cSSzymon Dompke {
190dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Either;
191dd1c4a9cSSzymon Dompke }
192dd1c4a9cSSzymon Dompke
193dd1c4a9cSSzymon Dompke if (dbusValue ==
194dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing")
195dd1c4a9cSSzymon Dompke {
196dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Decreasing;
197dd1c4a9cSSzymon Dompke }
198dd1c4a9cSSzymon Dompke
199dd1c4a9cSSzymon Dompke if (dbusValue ==
200dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing")
201dd1c4a9cSSzymon Dompke {
202dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Increasing;
203dd1c4a9cSSzymon Dompke }
204dd1c4a9cSSzymon Dompke
205dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Invalid;
206dd1c4a9cSSzymon Dompke }
207dd1c4a9cSSzymon Dompke
208dd1c4a9cSSzymon Dompke enum class MetricType
209dd1c4a9cSSzymon Dompke {
210dd1c4a9cSSzymon Dompke Discrete,
211dd1c4a9cSSzymon Dompke Numeric
212dd1c4a9cSSzymon Dompke };
213dd1c4a9cSSzymon Dompke
214dd1c4a9cSSzymon Dompke enum class DiscreteCondition
215dd1c4a9cSSzymon Dompke {
216dd1c4a9cSSzymon Dompke Specified,
217dd1c4a9cSSzymon Dompke Changed
218dd1c4a9cSSzymon Dompke };
219dd1c4a9cSSzymon Dompke
220dd1c4a9cSSzymon Dompke struct Context
221dd1c4a9cSSzymon Dompke {
222dd1c4a9cSSzymon Dompke std::string id;
223dd1c4a9cSSzymon Dompke std::string name;
224dd1c4a9cSSzymon Dompke std::vector<std::string> actions;
225dd1c4a9cSSzymon Dompke std::vector<std::pair<sdbusplus::message::object_path, std::string>>
226dd1c4a9cSSzymon Dompke sensors;
227dd1c4a9cSSzymon Dompke std::vector<sdbusplus::message::object_path> reports;
22858c71488SEd Tanous std::vector<NumericThresholdParams> numericThresholds;
22958c71488SEd Tanous std::vector<DiscreteThresholdParams> discreteThresholds;
230dd1c4a9cSSzymon Dompke std::optional<DiscreteCondition> discreteCondition;
231dd1c4a9cSSzymon Dompke std::optional<MetricType> metricType;
232dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> metricProperties;
233dd1c4a9cSSzymon Dompke };
234dd1c4a9cSSzymon Dompke
235dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path>
getReportPathFromReportDefinitionUri(const std::string & uri)236dd1c4a9cSSzymon Dompke getReportPathFromReportDefinitionUri(const std::string& uri)
237dd1c4a9cSSzymon Dompke {
2386fd29553SEd Tanous boost::system::result<boost::urls::url_view> parsed =
239dd1c4a9cSSzymon Dompke boost::urls::parse_relative_ref(uri);
240dd1c4a9cSSzymon Dompke
241dd1c4a9cSSzymon Dompke if (!parsed)
2421b7e696bSLukasz Kazmierczak {
2431b7e696bSLukasz Kazmierczak return std::nullopt;
2441b7e696bSLukasz Kazmierczak }
2451b7e696bSLukasz Kazmierczak
246dd1c4a9cSSzymon Dompke std::string id;
247dd1c4a9cSSzymon Dompke if (!crow::utility::readUrlSegments(
248dd1c4a9cSSzymon Dompke *parsed, "redfish", "v1", "TelemetryService",
249dd1c4a9cSSzymon Dompke "MetricReportDefinitions", std::ref(id)))
250dd1c4a9cSSzymon Dompke {
251dd1c4a9cSSzymon Dompke return std::nullopt;
2521b7e696bSLukasz Kazmierczak }
2531b7e696bSLukasz Kazmierczak
254dd1c4a9cSSzymon Dompke return sdbusplus::message::object_path(
255dd1c4a9cSSzymon Dompke "/xyz/openbmc_project/Telemetry/Reports") /
256dd1c4a9cSSzymon Dompke "TelemetryService" / id;
257dd1c4a9cSSzymon Dompke }
258dd1c4a9cSSzymon Dompke
getMetricType(const std::string & metricType)259dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType)
260dd1c4a9cSSzymon Dompke {
261dd1c4a9cSSzymon Dompke if (metricType == "Discrete")
262dd1c4a9cSSzymon Dompke {
263dd1c4a9cSSzymon Dompke return MetricType::Discrete;
264dd1c4a9cSSzymon Dompke }
265dd1c4a9cSSzymon Dompke if (metricType == "Numeric")
266dd1c4a9cSSzymon Dompke {
267dd1c4a9cSSzymon Dompke return MetricType::Numeric;
268dd1c4a9cSSzymon Dompke }
269dd1c4a9cSSzymon Dompke return std::nullopt;
270dd1c4a9cSSzymon Dompke }
271dd1c4a9cSSzymon Dompke
getDiscreteCondition(const std::string & discreteTriggerCondition)272504af5a0SPatrick Williams inline std::optional<DiscreteCondition> getDiscreteCondition(
273504af5a0SPatrick Williams const std::string& discreteTriggerCondition)
274dd1c4a9cSSzymon Dompke {
275dd1c4a9cSSzymon Dompke if (discreteTriggerCondition == "Specified")
276dd1c4a9cSSzymon Dompke {
277dd1c4a9cSSzymon Dompke return DiscreteCondition::Specified;
278dd1c4a9cSSzymon Dompke }
279dd1c4a9cSSzymon Dompke if (discreteTriggerCondition == "Changed")
280dd1c4a9cSSzymon Dompke {
281dd1c4a9cSSzymon Dompke return DiscreteCondition::Changed;
282dd1c4a9cSSzymon Dompke }
283dd1c4a9cSSzymon Dompke return std::nullopt;
284dd1c4a9cSSzymon Dompke }
285dd1c4a9cSSzymon Dompke
parseThreshold(crow::Response & res,nlohmann::json::object_t & threshold,std::string_view dbusThresholdName,std::vector<NumericThresholdParams> & parsedParams)2862932dcb6SEd Tanous inline bool parseThreshold(crow::Response& res,
2872932dcb6SEd Tanous nlohmann::json::object_t& threshold,
2882932dcb6SEd Tanous std::string_view dbusThresholdName,
2892932dcb6SEd Tanous std::vector<NumericThresholdParams>& parsedParams)
290dd1c4a9cSSzymon Dompke {
291dd1c4a9cSSzymon Dompke double reading = 0.0;
292dd1c4a9cSSzymon Dompke std::string activation;
293dd1c4a9cSSzymon Dompke std::string dwellTimeStr;
294dd1c4a9cSSzymon Dompke
295afc474aeSMyung Bae if (!json_util::readJsonObject( //
296afc474aeSMyung Bae threshold, res, //
297afc474aeSMyung Bae "Activation", activation, //
298afc474aeSMyung Bae "DwellTime", dwellTimeStr, //
299afc474aeSMyung Bae "Reading", reading //
300afc474aeSMyung Bae ))
301dd1c4a9cSSzymon Dompke {
302dd1c4a9cSSzymon Dompke return false;
303dd1c4a9cSSzymon Dompke }
304dd1c4a9cSSzymon Dompke
305dd1c4a9cSSzymon Dompke std::string dbusActivation = toDbusActivation(activation);
306dd1c4a9cSSzymon Dompke
307dd1c4a9cSSzymon Dompke if (dbusActivation.empty())
308dd1c4a9cSSzymon Dompke {
309dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "Activation", activation);
310dd1c4a9cSSzymon Dompke return false;
311dd1c4a9cSSzymon Dompke }
312dd1c4a9cSSzymon Dompke
313dd1c4a9cSSzymon Dompke std::optional<std::chrono::milliseconds> dwellTime =
314dd1c4a9cSSzymon Dompke time_utils::fromDurationString(dwellTimeStr);
315dd1c4a9cSSzymon Dompke if (!dwellTime)
316dd1c4a9cSSzymon Dompke {
317dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
318dd1c4a9cSSzymon Dompke return false;
319dd1c4a9cSSzymon Dompke }
320dd1c4a9cSSzymon Dompke
321dd1c4a9cSSzymon Dompke parsedParams.emplace_back(dbusThresholdName,
322dd1c4a9cSSzymon Dompke static_cast<uint64_t>(dwellTime->count()),
323dd1c4a9cSSzymon Dompke dbusActivation, reading);
3242932dcb6SEd Tanous return true;
3252932dcb6SEd Tanous }
3262932dcb6SEd Tanous
3272932dcb6SEd Tanous struct NumericThresholds
3282932dcb6SEd Tanous {
3292932dcb6SEd Tanous std::optional<nlohmann::json::object_t> upperCritical;
3302932dcb6SEd Tanous std::optional<nlohmann::json::object_t> upperWarning;
3312932dcb6SEd Tanous std::optional<nlohmann::json::object_t> lowerWarning;
3322932dcb6SEd Tanous std::optional<nlohmann::json::object_t> lowerCritical;
3332932dcb6SEd Tanous
anyredfish::telemetry::NumericThresholds3342932dcb6SEd Tanous bool any() const
3352932dcb6SEd Tanous {
3362932dcb6SEd Tanous return upperCritical || upperWarning || lowerWarning || lowerCritical;
3372932dcb6SEd Tanous }
3382932dcb6SEd Tanous };
3392932dcb6SEd Tanous
parseNumericThresholds(crow::Response & res,NumericThresholds & numericThresholds,Context & ctx)340bd79bce8SPatrick Williams inline bool parseNumericThresholds(
341bd79bce8SPatrick Williams crow::Response& res, NumericThresholds& numericThresholds, Context& ctx)
3422932dcb6SEd Tanous {
3432932dcb6SEd Tanous std::vector<NumericThresholdParams> parsedParams;
3442932dcb6SEd Tanous if (numericThresholds.upperCritical)
3452932dcb6SEd Tanous {
3462932dcb6SEd Tanous if (!parseThreshold(
3472932dcb6SEd Tanous res, *numericThresholds.upperCritical,
3482932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical",
3492932dcb6SEd Tanous parsedParams))
3502932dcb6SEd Tanous {
3512932dcb6SEd Tanous return false;
3522932dcb6SEd Tanous }
3532932dcb6SEd Tanous }
3542932dcb6SEd Tanous if (numericThresholds.upperWarning)
3552932dcb6SEd Tanous {
3562932dcb6SEd Tanous if (!parseThreshold(
3572932dcb6SEd Tanous res, *numericThresholds.upperWarning,
3582932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning",
3592932dcb6SEd Tanous parsedParams))
3602932dcb6SEd Tanous {
3612932dcb6SEd Tanous return false;
3622932dcb6SEd Tanous }
3632932dcb6SEd Tanous }
3642932dcb6SEd Tanous if (numericThresholds.lowerWarning)
3652932dcb6SEd Tanous {
3662932dcb6SEd Tanous if (!parseThreshold(
3672932dcb6SEd Tanous res, *numericThresholds.lowerWarning,
3682932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning",
3692932dcb6SEd Tanous parsedParams))
3702932dcb6SEd Tanous {
3712932dcb6SEd Tanous return false;
3722932dcb6SEd Tanous }
3732932dcb6SEd Tanous }
3742932dcb6SEd Tanous if (numericThresholds.lowerCritical)
3752932dcb6SEd Tanous {
3762932dcb6SEd Tanous if (!parseThreshold(
3772932dcb6SEd Tanous res, *numericThresholds.lowerCritical,
3782932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical",
3792932dcb6SEd Tanous parsedParams))
3802932dcb6SEd Tanous {
3812932dcb6SEd Tanous return false;
3822932dcb6SEd Tanous }
383dd1c4a9cSSzymon Dompke }
384dd1c4a9cSSzymon Dompke
38558c71488SEd Tanous ctx.numericThresholds = std::move(parsedParams);
386dd1c4a9cSSzymon Dompke return true;
387dd1c4a9cSSzymon Dompke }
388dd1c4a9cSSzymon Dompke
parseDiscreteTriggers(crow::Response & res,std::optional<std::vector<nlohmann::json::object_t>> & discreteTriggers,Context & ctx)389dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers(
390dd1c4a9cSSzymon Dompke crow::Response& res,
3912932dcb6SEd Tanous std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
3922932dcb6SEd Tanous Context& ctx)
393dd1c4a9cSSzymon Dompke {
394dd1c4a9cSSzymon Dompke std::vector<DiscreteThresholdParams> parsedParams;
395dd1c4a9cSSzymon Dompke if (!discreteTriggers)
396dd1c4a9cSSzymon Dompke {
39758c71488SEd Tanous ctx.discreteThresholds = std::move(parsedParams);
398dd1c4a9cSSzymon Dompke return true;
399dd1c4a9cSSzymon Dompke }
400dd1c4a9cSSzymon Dompke
401dd1c4a9cSSzymon Dompke parsedParams.reserve(discreteTriggers->size());
4022932dcb6SEd Tanous for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers)
403dd1c4a9cSSzymon Dompke {
404dd1c4a9cSSzymon Dompke std::optional<std::string> name = "";
405dd1c4a9cSSzymon Dompke std::string value;
406dd1c4a9cSSzymon Dompke std::string dwellTimeStr;
407dd1c4a9cSSzymon Dompke std::string severity;
408dd1c4a9cSSzymon Dompke
409afc474aeSMyung Bae if (!json_util::readJsonObject( //
410afc474aeSMyung Bae thresholdInfo, res, //
411afc474aeSMyung Bae "DwellTime", dwellTimeStr, //
412afc474aeSMyung Bae "Name", name, //
413afc474aeSMyung Bae "Severity", severity, //
414afc474aeSMyung Bae "Value", value //
415afc474aeSMyung Bae ))
416dd1c4a9cSSzymon Dompke {
417dd1c4a9cSSzymon Dompke return false;
418dd1c4a9cSSzymon Dompke }
419dd1c4a9cSSzymon Dompke
420dd1c4a9cSSzymon Dompke std::optional<std::chrono::milliseconds> dwellTime =
421dd1c4a9cSSzymon Dompke time_utils::fromDurationString(dwellTimeStr);
422dd1c4a9cSSzymon Dompke if (!dwellTime)
423dd1c4a9cSSzymon Dompke {
424dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr);
425dd1c4a9cSSzymon Dompke return false;
426dd1c4a9cSSzymon Dompke }
427dd1c4a9cSSzymon Dompke
428dd1c4a9cSSzymon Dompke std::string dbusSeverity = toDbusSeverity(severity);
429dd1c4a9cSSzymon Dompke if (dbusSeverity.empty())
430dd1c4a9cSSzymon Dompke {
431dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "Severity", severity);
432dd1c4a9cSSzymon Dompke return false;
433dd1c4a9cSSzymon Dompke }
434dd1c4a9cSSzymon Dompke
435dd1c4a9cSSzymon Dompke parsedParams.emplace_back(*name, dbusSeverity,
436dd1c4a9cSSzymon Dompke static_cast<uint64_t>(dwellTime->count()),
437dd1c4a9cSSzymon Dompke value);
438dd1c4a9cSSzymon Dompke }
439dd1c4a9cSSzymon Dompke
44058c71488SEd Tanous ctx.discreteThresholds = std::move(parsedParams);
441dd1c4a9cSSzymon Dompke return true;
442dd1c4a9cSSzymon Dompke }
443dd1c4a9cSSzymon Dompke
parseTriggerThresholds(crow::Response & res,std::optional<std::vector<nlohmann::json::object_t>> & discreteTriggers,NumericThresholds & numericThresholds,Context & ctx)444dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds(
445dd1c4a9cSSzymon Dompke crow::Response& res,
4462932dcb6SEd Tanous std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers,
4472932dcb6SEd Tanous NumericThresholds& numericThresholds, Context& ctx)
448dd1c4a9cSSzymon Dompke {
4492932dcb6SEd Tanous if (discreteTriggers && numericThresholds.any())
450dd1c4a9cSSzymon Dompke {
451dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers",
452dd1c4a9cSSzymon Dompke "NumericThresholds");
453dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds",
454dd1c4a9cSSzymon Dompke "DiscreteTriggers");
455dd1c4a9cSSzymon Dompke return false;
456dd1c4a9cSSzymon Dompke }
457dd1c4a9cSSzymon Dompke
458dd1c4a9cSSzymon Dompke if (ctx.discreteCondition)
459dd1c4a9cSSzymon Dompke {
4602932dcb6SEd Tanous if (numericThresholds.any())
461dd1c4a9cSSzymon Dompke {
462dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggerCondition",
463dd1c4a9cSSzymon Dompke "NumericThresholds");
464dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds",
465dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition");
466dd1c4a9cSSzymon Dompke return false;
467dd1c4a9cSSzymon Dompke }
468dd1c4a9cSSzymon Dompke }
469dd1c4a9cSSzymon Dompke
470dd1c4a9cSSzymon Dompke if (ctx.metricType)
471dd1c4a9cSSzymon Dompke {
4722932dcb6SEd Tanous if (*ctx.metricType == MetricType::Discrete && numericThresholds.any())
473dd1c4a9cSSzymon Dompke {
474dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds",
475dd1c4a9cSSzymon Dompke "MetricType");
476dd1c4a9cSSzymon Dompke return false;
477dd1c4a9cSSzymon Dompke }
478dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Numeric && discreteTriggers)
479dd1c4a9cSSzymon Dompke {
480dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers",
481dd1c4a9cSSzymon Dompke "MetricType");
482dd1c4a9cSSzymon Dompke return false;
483dd1c4a9cSSzymon Dompke }
484dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition)
485dd1c4a9cSSzymon Dompke {
486dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers",
487dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition");
488dd1c4a9cSSzymon Dompke return false;
489dd1c4a9cSSzymon Dompke }
490dd1c4a9cSSzymon Dompke }
491dd1c4a9cSSzymon Dompke
492dd1c4a9cSSzymon Dompke if (discreteTriggers || ctx.discreteCondition ||
493dd1c4a9cSSzymon Dompke (ctx.metricType && *ctx.metricType == MetricType::Discrete))
494dd1c4a9cSSzymon Dompke {
495dd1c4a9cSSzymon Dompke if (ctx.discreteCondition)
496dd1c4a9cSSzymon Dompke {
497dd1c4a9cSSzymon Dompke if (*ctx.discreteCondition == DiscreteCondition::Specified &&
498dd1c4a9cSSzymon Dompke !discreteTriggers)
499dd1c4a9cSSzymon Dompke {
500dd1c4a9cSSzymon Dompke messages::createFailedMissingReqProperties(res,
501dd1c4a9cSSzymon Dompke "DiscreteTriggers");
502dd1c4a9cSSzymon Dompke return false;
503dd1c4a9cSSzymon Dompke }
504dd1c4a9cSSzymon Dompke if (discreteTriggers &&
505dd1c4a9cSSzymon Dompke ((*ctx.discreteCondition == DiscreteCondition::Specified &&
506dd1c4a9cSSzymon Dompke discreteTriggers->empty()) ||
507dd1c4a9cSSzymon Dompke (*ctx.discreteCondition == DiscreteCondition::Changed &&
508dd1c4a9cSSzymon Dompke !discreteTriggers->empty())))
509dd1c4a9cSSzymon Dompke {
510dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers",
511dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition");
512dd1c4a9cSSzymon Dompke return false;
513dd1c4a9cSSzymon Dompke }
514dd1c4a9cSSzymon Dompke }
515dd1c4a9cSSzymon Dompke if (!parseDiscreteTriggers(res, discreteTriggers, ctx))
516dd1c4a9cSSzymon Dompke {
517dd1c4a9cSSzymon Dompke return false;
518dd1c4a9cSSzymon Dompke }
519dd1c4a9cSSzymon Dompke }
5202932dcb6SEd Tanous else if (numericThresholds.any())
521dd1c4a9cSSzymon Dompke {
5222932dcb6SEd Tanous if (!parseNumericThresholds(res, numericThresholds, ctx))
523dd1c4a9cSSzymon Dompke {
524dd1c4a9cSSzymon Dompke return false;
525dd1c4a9cSSzymon Dompke }
526dd1c4a9cSSzymon Dompke }
527dd1c4a9cSSzymon Dompke else
528dd1c4a9cSSzymon Dompke {
529dd1c4a9cSSzymon Dompke messages::createFailedMissingReqProperties(
530dd1c4a9cSSzymon Dompke res, "'DiscreteTriggers', 'NumericThresholds', "
531dd1c4a9cSSzymon Dompke "'DiscreteTriggerCondition' or 'MetricType'");
532dd1c4a9cSSzymon Dompke return false;
533dd1c4a9cSSzymon Dompke }
534dd1c4a9cSSzymon Dompke return true;
535dd1c4a9cSSzymon Dompke }
536dd1c4a9cSSzymon Dompke
parseLinks(crow::Response & res,const std::vector<std::string> & metricReportDefinitions,Context & ctx)5372932dcb6SEd Tanous inline bool parseLinks(crow::Response& res,
5382932dcb6SEd Tanous const std::vector<std::string>& metricReportDefinitions,
5392932dcb6SEd Tanous Context& ctx)
540dd1c4a9cSSzymon Dompke {
5412932dcb6SEd Tanous ctx.reports.reserve(metricReportDefinitions.size());
5422932dcb6SEd Tanous for (const std::string& reportDefinionUri : metricReportDefinitions)
543dd1c4a9cSSzymon Dompke {
544dd1c4a9cSSzymon Dompke std::optional<sdbusplus::message::object_path> reportPath =
545dd1c4a9cSSzymon Dompke getReportPathFromReportDefinitionUri(reportDefinionUri);
546dd1c4a9cSSzymon Dompke if (!reportPath)
547dd1c4a9cSSzymon Dompke {
548dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "MetricReportDefinitions",
549dd1c4a9cSSzymon Dompke reportDefinionUri);
550dd1c4a9cSSzymon Dompke return false;
551dd1c4a9cSSzymon Dompke }
552dd1c4a9cSSzymon Dompke ctx.reports.emplace_back(*reportPath);
553dd1c4a9cSSzymon Dompke }
554dd1c4a9cSSzymon Dompke return true;
555dd1c4a9cSSzymon Dompke }
556dd1c4a9cSSzymon Dompke
parseMetricProperties(crow::Response & res,Context & ctx)557dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx)
558dd1c4a9cSSzymon Dompke {
559dd1c4a9cSSzymon Dompke if (!ctx.metricProperties)
560dd1c4a9cSSzymon Dompke {
561dd1c4a9cSSzymon Dompke return true;
562dd1c4a9cSSzymon Dompke }
563dd1c4a9cSSzymon Dompke
564dd1c4a9cSSzymon Dompke ctx.sensors.reserve(ctx.metricProperties->size());
565dd1c4a9cSSzymon Dompke
566dd1c4a9cSSzymon Dompke size_t uriIdx = 0;
567dd1c4a9cSSzymon Dompke for (const std::string& uriStr : *ctx.metricProperties)
568dd1c4a9cSSzymon Dompke {
5694a7fbefdSEd Tanous boost::system::result<boost::urls::url> uri =
570dd1c4a9cSSzymon Dompke boost::urls::parse_relative_ref(uriStr);
571dd1c4a9cSSzymon Dompke if (!uri)
572dd1c4a9cSSzymon Dompke {
573dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(
574dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
575dd1c4a9cSSzymon Dompke return false;
576dd1c4a9cSSzymon Dompke }
577dd1c4a9cSSzymon Dompke std::string chassisName;
578dd1c4a9cSSzymon Dompke std::string sensorName;
579dd1c4a9cSSzymon Dompke if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis",
580dd1c4a9cSSzymon Dompke std::ref(chassisName), "Sensors",
581dd1c4a9cSSzymon Dompke std::ref(sensorName)))
582dd1c4a9cSSzymon Dompke {
583dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(
584dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
585dd1c4a9cSSzymon Dompke return false;
586dd1c4a9cSSzymon Dompke }
587dd1c4a9cSSzymon Dompke
588dd1c4a9cSSzymon Dompke std::pair<std::string, std::string> split =
5891516c21bSJanet Adkins redfish::sensor_utils::splitSensorNameAndType(sensorName);
590dd1c4a9cSSzymon Dompke if (split.first.empty() || split.second.empty())
591dd1c4a9cSSzymon Dompke {
592dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(
593dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr);
594dd1c4a9cSSzymon Dompke return false;
595dd1c4a9cSSzymon Dompke }
596dd1c4a9cSSzymon Dompke
597bd79bce8SPatrick Williams std::string sensorPath =
598bd79bce8SPatrick Williams "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second;
599dd1c4a9cSSzymon Dompke
600dd1c4a9cSSzymon Dompke ctx.sensors.emplace_back(sensorPath, uriStr);
601dd1c4a9cSSzymon Dompke uriIdx++;
602dd1c4a9cSSzymon Dompke }
603dd1c4a9cSSzymon Dompke return true;
604dd1c4a9cSSzymon Dompke }
605dd1c4a9cSSzymon Dompke
parsePostTriggerParams(crow::Response & res,const crow::Request & req,Context & ctx)606dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res,
607dd1c4a9cSSzymon Dompke const crow::Request& req, Context& ctx)
608dd1c4a9cSSzymon Dompke {
609dd1c4a9cSSzymon Dompke std::optional<std::string> id = "";
610dd1c4a9cSSzymon Dompke std::optional<std::string> name = "";
611dd1c4a9cSSzymon Dompke std::optional<std::string> metricType;
612dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> triggerActions;
613dd1c4a9cSSzymon Dompke std::optional<std::string> discreteTriggerCondition;
6142932dcb6SEd Tanous std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers;
6152932dcb6SEd Tanous std::optional<std::vector<std::string>> metricReportDefinitions;
6162932dcb6SEd Tanous NumericThresholds thresholds;
617afc474aeSMyung Bae
618afc474aeSMyung Bae if (!json_util::readJsonPatch( //
619afc474aeSMyung Bae req, res, //
620afc474aeSMyung Bae "Id", id, //
621afc474aeSMyung Bae "DiscreteTriggerCondition", discreteTriggerCondition, //
622afc474aeSMyung Bae "DiscreteTriggers", discreteTriggers, //
623afc474aeSMyung Bae "Links/MetricReportDefinitions", metricReportDefinitions, //
624afc474aeSMyung Bae "MetricProperties", ctx.metricProperties, //
625afc474aeSMyung Bae "MetricType", metricType, //
626afc474aeSMyung Bae "Name", name, //
627afc474aeSMyung Bae "NumericThresholds/LowerCritical", thresholds.lowerCritical, //
628afc474aeSMyung Bae "NumericThresholds/LowerWarning", thresholds.lowerWarning, //
629afc474aeSMyung Bae "NumericThresholds/UpperCritical", thresholds.upperCritical, //
630afc474aeSMyung Bae "NumericThresholds/UpperWarning", thresholds.upperWarning, //
631afc474aeSMyung Bae "TriggerActions", triggerActions //
632afc474aeSMyung Bae ))
633dd1c4a9cSSzymon Dompke {
634dd1c4a9cSSzymon Dompke return false;
635dd1c4a9cSSzymon Dompke }
636dd1c4a9cSSzymon Dompke
637dd1c4a9cSSzymon Dompke ctx.id = *id;
638dd1c4a9cSSzymon Dompke ctx.name = *name;
639dd1c4a9cSSzymon Dompke
640dd1c4a9cSSzymon Dompke if (metricType)
641dd1c4a9cSSzymon Dompke {
642d5736ef2SEd Tanous ctx.metricType = getMetricType(*metricType);
643d5736ef2SEd Tanous if (!ctx.metricType)
644dd1c4a9cSSzymon Dompke {
645dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "MetricType", *metricType);
646dd1c4a9cSSzymon Dompke return false;
647dd1c4a9cSSzymon Dompke }
648dd1c4a9cSSzymon Dompke }
649dd1c4a9cSSzymon Dompke
650dd1c4a9cSSzymon Dompke if (discreteTriggerCondition)
651dd1c4a9cSSzymon Dompke {
652d5736ef2SEd Tanous ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition);
653d5736ef2SEd Tanous if (!ctx.discreteCondition)
654dd1c4a9cSSzymon Dompke {
655dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DiscreteTriggerCondition",
656dd1c4a9cSSzymon Dompke *discreteTriggerCondition);
657dd1c4a9cSSzymon Dompke return false;
658dd1c4a9cSSzymon Dompke }
659dd1c4a9cSSzymon Dompke }
660dd1c4a9cSSzymon Dompke
661dd1c4a9cSSzymon Dompke if (triggerActions)
662dd1c4a9cSSzymon Dompke {
663dd1c4a9cSSzymon Dompke ctx.actions.reserve(triggerActions->size());
664dd1c4a9cSSzymon Dompke for (const std::string& action : *triggerActions)
665dd1c4a9cSSzymon Dompke {
666dd1c4a9cSSzymon Dompke std::string dbusAction = toDbusTriggerAction(action);
667dd1c4a9cSSzymon Dompke
668dd1c4a9cSSzymon Dompke if (dbusAction.empty())
669dd1c4a9cSSzymon Dompke {
670dd1c4a9cSSzymon Dompke messages::propertyValueNotInList(res, action, "TriggerActions");
671dd1c4a9cSSzymon Dompke return false;
672dd1c4a9cSSzymon Dompke }
673dd1c4a9cSSzymon Dompke
674dd1c4a9cSSzymon Dompke ctx.actions.emplace_back(dbusAction);
675dd1c4a9cSSzymon Dompke }
676dd1c4a9cSSzymon Dompke }
677dd1c4a9cSSzymon Dompke if (!parseMetricProperties(res, ctx))
678dd1c4a9cSSzymon Dompke {
679dd1c4a9cSSzymon Dompke return false;
680dd1c4a9cSSzymon Dompke }
681dd1c4a9cSSzymon Dompke
6822932dcb6SEd Tanous if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx))
683dd1c4a9cSSzymon Dompke {
684dd1c4a9cSSzymon Dompke return false;
685dd1c4a9cSSzymon Dompke }
686dd1c4a9cSSzymon Dompke
6872932dcb6SEd Tanous if (metricReportDefinitions)
688dd1c4a9cSSzymon Dompke {
6892932dcb6SEd Tanous if (!parseLinks(res, *metricReportDefinitions, ctx))
690dd1c4a9cSSzymon Dompke {
691dd1c4a9cSSzymon Dompke return false;
692dd1c4a9cSSzymon Dompke }
693dd1c4a9cSSzymon Dompke }
694dd1c4a9cSSzymon Dompke return true;
695dd1c4a9cSSzymon Dompke }
696dd1c4a9cSSzymon Dompke
afterCreateTrigger(const boost::system::error_code & ec,const std::string & dbusPath,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & id)697dd1c4a9cSSzymon Dompke inline void afterCreateTrigger(
698dd1c4a9cSSzymon Dompke const boost::system::error_code& ec, const std::string& dbusPath,
699dd1c4a9cSSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
700dd1c4a9cSSzymon Dompke {
701dd1c4a9cSSzymon Dompke if (ec == boost::system::errc::file_exists)
702dd1c4a9cSSzymon Dompke {
703dd1c4a9cSSzymon Dompke messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id);
704dd1c4a9cSSzymon Dompke return;
705dd1c4a9cSSzymon Dompke }
706dd1c4a9cSSzymon Dompke if (ec == boost::system::errc::too_many_files_open)
707dd1c4a9cSSzymon Dompke {
708dd1c4a9cSSzymon Dompke messages::createLimitReachedForResource(asyncResp->res);
709dd1c4a9cSSzymon Dompke return;
710dd1c4a9cSSzymon Dompke }
711dd1c4a9cSSzymon Dompke if (ec)
712dd1c4a9cSSzymon Dompke {
713dd1c4a9cSSzymon Dompke messages::internalError(asyncResp->res);
71462598e31SEd Tanous BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
715dd1c4a9cSSzymon Dompke return;
716dd1c4a9cSSzymon Dompke }
717dd1c4a9cSSzymon Dompke
718dd1c4a9cSSzymon Dompke const std::optional<std::string>& triggerId =
719dd1c4a9cSSzymon Dompke getTriggerIdFromDbusPath(dbusPath);
720dd1c4a9cSSzymon Dompke if (!triggerId)
721dd1c4a9cSSzymon Dompke {
722dd1c4a9cSSzymon Dompke messages::internalError(asyncResp->res);
72362598e31SEd Tanous BMCWEB_LOG_ERROR("Unknown data returned by "
72462598e31SEd Tanous "AddTrigger DBus method");
725dd1c4a9cSSzymon Dompke return;
726dd1c4a9cSSzymon Dompke }
727dd1c4a9cSSzymon Dompke
728dd1c4a9cSSzymon Dompke messages::created(asyncResp->res);
729dd1c4a9cSSzymon Dompke boost::urls::url locationUrl = boost::urls::format(
730dd1c4a9cSSzymon Dompke "/redfish/v1/TelemetryService/Triggers/{}", *triggerId);
731dd1c4a9cSSzymon Dompke asyncResp->res.addHeader("Location", locationUrl.buffer());
732dd1c4a9cSSzymon Dompke }
733dd1c4a9cSSzymon Dompke
getTriggerActions(const std::vector<std::string> & dbusActions)734504af5a0SPatrick Williams inline std::optional<nlohmann::json::array_t> getTriggerActions(
735504af5a0SPatrick Williams const std::vector<std::string>& dbusActions)
736dd1c4a9cSSzymon Dompke {
737dd1c4a9cSSzymon Dompke nlohmann::json::array_t triggerActions;
738dd1c4a9cSSzymon Dompke for (const std::string& dbusAction : dbusActions)
739dd1c4a9cSSzymon Dompke {
740dd1c4a9cSSzymon Dompke triggers::TriggerActionEnum redfishAction =
741dd1c4a9cSSzymon Dompke toRedfishTriggerAction(dbusAction);
742dd1c4a9cSSzymon Dompke
743dd1c4a9cSSzymon Dompke if (redfishAction == triggers::TriggerActionEnum::Invalid)
744dd1c4a9cSSzymon Dompke {
745dd1c4a9cSSzymon Dompke return std::nullopt;
746dd1c4a9cSSzymon Dompke }
747dd1c4a9cSSzymon Dompke
748dd1c4a9cSSzymon Dompke triggerActions.emplace_back(redfishAction);
749dd1c4a9cSSzymon Dompke }
750dd1c4a9cSSzymon Dompke
751dd1c4a9cSSzymon Dompke return triggerActions;
7521b7e696bSLukasz Kazmierczak }
7531b7e696bSLukasz Kazmierczak
getDiscreteTriggers(const std::vector<DiscreteThresholdParams> & discreteParams)75458c71488SEd Tanous inline std::optional<nlohmann::json::array_t> getDiscreteTriggers(
75558c71488SEd Tanous const std::vector<DiscreteThresholdParams>& discreteParams)
7561b7e696bSLukasz Kazmierczak {
757dd1c4a9cSSzymon Dompke nlohmann::json::array_t triggers;
75858c71488SEd Tanous for (const auto& [name, severity, dwellTime, value] : discreteParams)
7591b7e696bSLukasz Kazmierczak {
7601b7e696bSLukasz Kazmierczak std::optional<std::string> duration =
7611b7e696bSLukasz Kazmierczak time_utils::toDurationStringFromUint(dwellTime);
7621b7e696bSLukasz Kazmierczak
7631b7e696bSLukasz Kazmierczak if (!duration)
7641b7e696bSLukasz Kazmierczak {
7651b7e696bSLukasz Kazmierczak return std::nullopt;
7661b7e696bSLukasz Kazmierczak }
767613dabeaSEd Tanous nlohmann::json::object_t trigger;
768613dabeaSEd Tanous trigger["Name"] = name;
769dd1c4a9cSSzymon Dompke trigger["Severity"] = toRedfishSeverity(severity);
770613dabeaSEd Tanous trigger["DwellTime"] = *duration;
771613dabeaSEd Tanous trigger["Value"] = value;
772ad539545SPatrick Williams triggers.emplace_back(std::move(trigger));
7731b7e696bSLukasz Kazmierczak }
7741b7e696bSLukasz Kazmierczak
775dd1c4a9cSSzymon Dompke return triggers;
7761b7e696bSLukasz Kazmierczak }
7771b7e696bSLukasz Kazmierczak
getNumericThresholds(const std::vector<NumericThresholdParams> & numericParams)77858c71488SEd Tanous inline std::optional<nlohmann::json::object_t> getNumericThresholds(
77958c71488SEd Tanous const std::vector<NumericThresholdParams>& numericParams)
7801b7e696bSLukasz Kazmierczak {
781dd1c4a9cSSzymon Dompke nlohmann::json::object_t thresholds;
7821b7e696bSLukasz Kazmierczak
78358c71488SEd Tanous for (const auto& [type, dwellTime, activation, reading] : numericParams)
7841b7e696bSLukasz Kazmierczak {
7851b7e696bSLukasz Kazmierczak std::optional<std::string> duration =
7861b7e696bSLukasz Kazmierczak time_utils::toDurationStringFromUint(dwellTime);
7871b7e696bSLukasz Kazmierczak
7881b7e696bSLukasz Kazmierczak if (!duration)
7891b7e696bSLukasz Kazmierczak {
7901b7e696bSLukasz Kazmierczak return std::nullopt;
7911b7e696bSLukasz Kazmierczak }
792dd1c4a9cSSzymon Dompke nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)];
7931476687dSEd Tanous threshold["Reading"] = reading;
794dd1c4a9cSSzymon Dompke threshold["Activation"] = toRedfishActivation(activation);
7951476687dSEd Tanous threshold["DwellTime"] = *duration;
7961b7e696bSLukasz Kazmierczak }
7971b7e696bSLukasz Kazmierczak
798dd1c4a9cSSzymon Dompke return thresholds;
7991b7e696bSLukasz Kazmierczak }
8001b7e696bSLukasz Kazmierczak
getMetricReportDefinitions(const std::vector<sdbusplus::message::object_path> & reportPaths)8013f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions(
8023f215c92SSzymon Dompke const std::vector<sdbusplus::message::object_path>& reportPaths)
8031b7e696bSLukasz Kazmierczak {
8041b7e696bSLukasz Kazmierczak nlohmann::json reports = nlohmann::json::array();
8053f215c92SSzymon Dompke
8063f215c92SSzymon Dompke for (const sdbusplus::message::object_path& path : reportPaths)
8071b7e696bSLukasz Kazmierczak {
8083f215c92SSzymon Dompke std::string reportId = path.filename();
8093f215c92SSzymon Dompke if (reportId.empty())
8103f215c92SSzymon Dompke {
8113f215c92SSzymon Dompke {
81262598e31SEd Tanous BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}",
81362598e31SEd Tanous path.str);
8143f215c92SSzymon Dompke return std::nullopt;
8153f215c92SSzymon Dompke }
8163f215c92SSzymon Dompke }
8173f215c92SSzymon Dompke
8181476687dSEd Tanous nlohmann::json::object_t report;
819ef4c65b7SEd Tanous report["@odata.id"] = boost::urls::format(
820ef4c65b7SEd Tanous "/redfish/v1/TelemetryService/MetricReportDefinitions/{}",
821ef4c65b7SEd Tanous reportId);
822b2ba3072SPatrick Williams reports.emplace_back(std::move(report));
8231b7e696bSLukasz Kazmierczak }
8241b7e696bSLukasz Kazmierczak
8253f215c92SSzymon Dompke return {std::move(reports)};
8261b7e696bSLukasz Kazmierczak }
8271b7e696bSLukasz Kazmierczak
getMetricProperties(const TriggerSensorsParams & sensors)828504af5a0SPatrick Williams inline std::vector<std::string> getMetricProperties(
829504af5a0SPatrick Williams const TriggerSensorsParams& sensors)
8301b7e696bSLukasz Kazmierczak {
8311b7e696bSLukasz Kazmierczak std::vector<std::string> metricProperties;
8321b7e696bSLukasz Kazmierczak metricProperties.reserve(sensors.size());
8331b7e696bSLukasz Kazmierczak for (const auto& [_, metadata] : sensors)
8341b7e696bSLukasz Kazmierczak {
8351b7e696bSLukasz Kazmierczak metricProperties.emplace_back(metadata);
8361b7e696bSLukasz Kazmierczak }
8371b7e696bSLukasz Kazmierczak
8381b7e696bSLukasz Kazmierczak return metricProperties;
8391b7e696bSLukasz Kazmierczak }
8401b7e696bSLukasz Kazmierczak
fillTrigger(nlohmann::json & json,const std::string & id,const dbus::utility::DBusPropertiesMap & properties)841e3648032SEd Tanous inline bool fillTrigger(nlohmann::json& json, const std::string& id,
842e3648032SEd Tanous const dbus::utility::DBusPropertiesMap& properties)
8431b7e696bSLukasz Kazmierczak {
8441b7e696bSLukasz Kazmierczak const std::string* name = nullptr;
8451b7e696bSLukasz Kazmierczak const bool* discrete = nullptr;
8461b7e696bSLukasz Kazmierczak const TriggerSensorsParams* sensors = nullptr;
8473f215c92SSzymon Dompke const std::vector<sdbusplus::message::object_path>* reports = nullptr;
84889474494SKrzysztof Grobelny const std::vector<std::string>* triggerActions = nullptr;
84958c71488SEd Tanous
85058c71488SEd Tanous const std::vector<DiscreteThresholdParams>* discreteThresholds = nullptr;
85158c71488SEd Tanous const std::vector<NumericThresholdParams>* numericThresholds = nullptr;
8521b7e696bSLukasz Kazmierczak
85389474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow(
85489474494SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete",
85589474494SKrzysztof Grobelny discrete, "Sensors", sensors, "Reports", reports, "TriggerActions",
85658c71488SEd Tanous triggerActions, "DiscreteThresholds", discreteThresholds,
85758c71488SEd Tanous "NumericThresholds", numericThresholds);
85889474494SKrzysztof Grobelny
85989474494SKrzysztof Grobelny if (!success)
8601b7e696bSLukasz Kazmierczak {
86189474494SKrzysztof Grobelny return false;
8621b7e696bSLukasz Kazmierczak }
8631b7e696bSLukasz Kazmierczak
86489474494SKrzysztof Grobelny if (triggerActions != nullptr)
86589474494SKrzysztof Grobelny {
866dd1c4a9cSSzymon Dompke std::optional<nlohmann::json::array_t> redfishTriggerActions =
86789474494SKrzysztof Grobelny getTriggerActions(*triggerActions);
86889474494SKrzysztof Grobelny if (!redfishTriggerActions)
8691b7e696bSLukasz Kazmierczak {
87062598e31SEd Tanous BMCWEB_LOG_ERROR(
87162598e31SEd Tanous "Property TriggerActions is invalid in Trigger: {}", id);
8721b7e696bSLukasz Kazmierczak return false;
8731b7e696bSLukasz Kazmierczak }
874dd1c4a9cSSzymon Dompke json["TriggerActions"] = *redfishTriggerActions;
87589474494SKrzysztof Grobelny }
8761b7e696bSLukasz Kazmierczak
87789474494SKrzysztof Grobelny if (reports != nullptr)
8783f215c92SSzymon Dompke {
8793f215c92SSzymon Dompke std::optional<nlohmann::json> linkedReports =
8803f215c92SSzymon Dompke getMetricReportDefinitions(*reports);
8813f215c92SSzymon Dompke if (!linkedReports)
8823f215c92SSzymon Dompke {
88362598e31SEd Tanous BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id);
8843f215c92SSzymon Dompke return false;
8853f215c92SSzymon Dompke }
88689474494SKrzysztof Grobelny json["Links"]["MetricReportDefinitions"] = *linkedReports;
88789474494SKrzysztof Grobelny }
8881b7e696bSLukasz Kazmierczak
88958c71488SEd Tanous if (discreteThresholds != nullptr)
8901b7e696bSLukasz Kazmierczak {
8913f215c92SSzymon Dompke std::optional<nlohmann::json::array_t> discreteTriggers =
89258c71488SEd Tanous getDiscreteTriggers(*discreteThresholds);
8931b7e696bSLukasz Kazmierczak
8941b7e696bSLukasz Kazmierczak if (!discreteTriggers)
8951b7e696bSLukasz Kazmierczak {
89662598e31SEd Tanous BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete "
89762598e31SEd Tanous "triggers in Trigger: {}",
89862598e31SEd Tanous id);
8991b7e696bSLukasz Kazmierczak return false;
9001b7e696bSLukasz Kazmierczak }
9011b7e696bSLukasz Kazmierczak
9021b7e696bSLukasz Kazmierczak json["DiscreteTriggers"] = *discreteTriggers;
9031b7e696bSLukasz Kazmierczak json["DiscreteTriggerCondition"] =
9041b7e696bSLukasz Kazmierczak discreteTriggers->empty() ? "Changed" : "Specified";
905539d8c6bSEd Tanous json["MetricType"] = metric_definition::MetricType::Discrete;
9061b7e696bSLukasz Kazmierczak }
90758c71488SEd Tanous if (numericThresholds != nullptr)
9081b7e696bSLukasz Kazmierczak {
90958c71488SEd Tanous std::optional<nlohmann::json::object_t> jnumericThresholds =
91058c71488SEd Tanous getNumericThresholds(*numericThresholds);
9111b7e696bSLukasz Kazmierczak
91258c71488SEd Tanous if (!jnumericThresholds)
9131b7e696bSLukasz Kazmierczak {
91462598e31SEd Tanous BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric "
91562598e31SEd Tanous "thresholds in Trigger: {}",
91662598e31SEd Tanous id);
9171b7e696bSLukasz Kazmierczak return false;
9181b7e696bSLukasz Kazmierczak }
9191b7e696bSLukasz Kazmierczak
92058c71488SEd Tanous json["NumericThresholds"] = *jnumericThresholds;
921539d8c6bSEd Tanous json["MetricType"] = metric_definition::MetricType::Numeric;
9221b7e696bSLukasz Kazmierczak }
92389474494SKrzysztof Grobelny
92489474494SKrzysztof Grobelny if (name != nullptr)
92589474494SKrzysztof Grobelny {
92689474494SKrzysztof Grobelny json["Name"] = *name;
92789474494SKrzysztof Grobelny }
92889474494SKrzysztof Grobelny
92989474494SKrzysztof Grobelny if (sensors != nullptr)
93089474494SKrzysztof Grobelny {
93189474494SKrzysztof Grobelny json["MetricProperties"] = getMetricProperties(*sensors);
93289474494SKrzysztof Grobelny }
9331b7e696bSLukasz Kazmierczak
9343f215c92SSzymon Dompke json["@odata.type"] = "#Triggers.v1_2_0.Triggers";
935ef4c65b7SEd Tanous json["@odata.id"] =
936ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
9373f215c92SSzymon Dompke json["Id"] = id;
9381b7e696bSLukasz Kazmierczak
9391b7e696bSLukasz Kazmierczak return true;
9401b7e696bSLukasz Kazmierczak }
9411b7e696bSLukasz Kazmierczak
handleTriggerCollectionPost(App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)942dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost(
943dd1c4a9cSSzymon Dompke App& app, const crow::Request& req,
944dd1c4a9cSSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
945dd1c4a9cSSzymon Dompke {
946dd1c4a9cSSzymon Dompke if (!redfish::setUpRedfishRoute(app, req, asyncResp))
947dd1c4a9cSSzymon Dompke {
948dd1c4a9cSSzymon Dompke return;
949dd1c4a9cSSzymon Dompke }
950dd1c4a9cSSzymon Dompke
951dd1c4a9cSSzymon Dompke telemetry::Context ctx;
952dd1c4a9cSSzymon Dompke if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx))
953dd1c4a9cSSzymon Dompke {
954dd1c4a9cSSzymon Dompke return;
955dd1c4a9cSSzymon Dompke }
956dd1c4a9cSSzymon Dompke
957dd1c4a9cSSzymon Dompke crow::connections::systemBus->async_method_call(
958dd1c4a9cSSzymon Dompke [asyncResp, id = ctx.id](const boost::system::error_code& ec,
959dd1c4a9cSSzymon Dompke const std::string& dbusPath) {
960dd1c4a9cSSzymon Dompke afterCreateTrigger(ec, dbusPath, asyncResp, id);
961dd1c4a9cSSzymon Dompke },
962dd1c4a9cSSzymon Dompke service, "/xyz/openbmc_project/Telemetry/Triggers",
963dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger",
964dd1c4a9cSSzymon Dompke "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors,
96558c71488SEd Tanous ctx.reports, ctx.numericThresholds, ctx.discreteThresholds);
966dd1c4a9cSSzymon Dompke }
967dd1c4a9cSSzymon Dompke
96807148cf2SLukasz Kazmierczak } // namespace telemetry
96907148cf2SLukasz Kazmierczak
requestRoutesTriggerCollection(App & app)97007148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app)
97107148cf2SLukasz Kazmierczak {
97207148cf2SLukasz Kazmierczak BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
97307148cf2SLukasz Kazmierczak .privileges(redfish::privileges::getTriggersCollection)
97407148cf2SLukasz Kazmierczak .methods(boost::beast::http::verb::get)(
97545ca1b86SEd Tanous [&app](const crow::Request& req,
97607148cf2SLukasz Kazmierczak const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
9773ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
97845ca1b86SEd Tanous {
97945ca1b86SEd Tanous return;
98045ca1b86SEd Tanous }
98107148cf2SLukasz Kazmierczak asyncResp->res.jsonValue["@odata.type"] =
98207148cf2SLukasz Kazmierczak "#TriggersCollection.TriggersCollection";
983ae9031f0SWilly Tu asyncResp->res.jsonValue["@odata.id"] =
984ae9031f0SWilly Tu "/redfish/v1/TelemetryService/Triggers";
98507148cf2SLukasz Kazmierczak asyncResp->res.jsonValue["Name"] = "Triggers Collection";
9867a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{
9877a1dbc48SGeorge Liu telemetry::triggerInterface};
98807148cf2SLukasz Kazmierczak collection_util::getCollectionMembers(
989ae9031f0SWilly Tu asyncResp,
990ae9031f0SWilly Tu boost::urls::url("/redfish/v1/TelemetryService/Triggers"),
991ae9031f0SWilly Tu interfaces,
99207148cf2SLukasz Kazmierczak "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService");
99307148cf2SLukasz Kazmierczak });
994dd1c4a9cSSzymon Dompke
995dd1c4a9cSSzymon Dompke BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/")
996dd1c4a9cSSzymon Dompke .privileges(redfish::privileges::postTriggersCollection)
997dd1c4a9cSSzymon Dompke .methods(boost::beast::http::verb::post)(std::bind_front(
998dd1c4a9cSSzymon Dompke telemetry::handleTriggerCollectionPost, std::ref(app)));
99907148cf2SLukasz Kazmierczak }
100007148cf2SLukasz Kazmierczak
requestRoutesTrigger(App & app)10011b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app)
10021b7e696bSLukasz Kazmierczak {
10031b7e696bSLukasz Kazmierczak BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
10041b7e696bSLukasz Kazmierczak .privileges(redfish::privileges::getTriggers)
10051b7e696bSLukasz Kazmierczak .methods(boost::beast::http::verb::get)(
100645ca1b86SEd Tanous [&app](const crow::Request& req,
10071b7e696bSLukasz Kazmierczak const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10081b7e696bSLukasz Kazmierczak const std::string& id) {
10093ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
101045ca1b86SEd Tanous {
101145ca1b86SEd Tanous return;
101245ca1b86SEd Tanous }
1013*46f780f7SEd Tanous dbus::utility::getAllProperties(
101489474494SKrzysztof Grobelny *crow::connections::systemBus, telemetry::service,
1015bd79bce8SPatrick Williams telemetry::getDbusTriggerPath(id),
1016bd79bce8SPatrick Williams telemetry::triggerInterface,
10171b7e696bSLukasz Kazmierczak [asyncResp,
10185e7e2dc5SEd Tanous id](const boost::system::error_code& ec,
1019e3648032SEd Tanous const dbus::utility::DBusPropertiesMap& ret) {
10201b7e696bSLukasz Kazmierczak if (ec.value() == EBADR ||
10211b7e696bSLukasz Kazmierczak ec == boost::system::errc::host_unreachable)
10221b7e696bSLukasz Kazmierczak {
1023bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res,
1024bd79bce8SPatrick Williams "Triggers", id);
10251b7e696bSLukasz Kazmierczak return;
10261b7e696bSLukasz Kazmierczak }
10271b7e696bSLukasz Kazmierczak if (ec)
10281b7e696bSLukasz Kazmierczak {
102962598e31SEd Tanous BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
10301b7e696bSLukasz Kazmierczak messages::internalError(asyncResp->res);
10311b7e696bSLukasz Kazmierczak return;
10321b7e696bSLukasz Kazmierczak }
10331b7e696bSLukasz Kazmierczak
1034bd79bce8SPatrick Williams if (!telemetry::fillTrigger(asyncResp->res.jsonValue,
1035bd79bce8SPatrick Williams id, ret))
10361b7e696bSLukasz Kazmierczak {
10371b7e696bSLukasz Kazmierczak messages::internalError(asyncResp->res);
10381b7e696bSLukasz Kazmierczak }
103989474494SKrzysztof Grobelny });
10401b7e696bSLukasz Kazmierczak });
1041163994a8SSzymon Dompke
1042163994a8SSzymon Dompke BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/")
1043163994a8SSzymon Dompke .privileges(redfish::privileges::deleteTriggers)
1044163994a8SSzymon Dompke .methods(boost::beast::http::verb::delete_)(
104545ca1b86SEd Tanous [&app](const crow::Request& req,
1046163994a8SSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1047163994a8SSzymon Dompke const std::string& id) {
10483ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp))
104945ca1b86SEd Tanous {
105045ca1b86SEd Tanous return;
105145ca1b86SEd Tanous }
1052bd79bce8SPatrick Williams const std::string triggerPath =
1053bd79bce8SPatrick Williams telemetry::getDbusTriggerPath(id);
1054163994a8SSzymon Dompke
1055163994a8SSzymon Dompke crow::connections::systemBus->async_method_call(
10565e7e2dc5SEd Tanous [asyncResp, id](const boost::system::error_code& ec) {
1057163994a8SSzymon Dompke if (ec.value() == EBADR)
1058163994a8SSzymon Dompke {
1059bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res,
1060bd79bce8SPatrick Williams "Triggers", id);
1061163994a8SSzymon Dompke return;
1062163994a8SSzymon Dompke }
1063163994a8SSzymon Dompke
1064163994a8SSzymon Dompke if (ec)
1065163994a8SSzymon Dompke {
106662598e31SEd Tanous BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1067163994a8SSzymon Dompke messages::internalError(asyncResp->res);
1068163994a8SSzymon Dompke return;
1069163994a8SSzymon Dompke }
1070163994a8SSzymon Dompke
1071bd79bce8SPatrick Williams asyncResp->res.result(
1072bd79bce8SPatrick Williams boost::beast::http::status::no_content);
1073163994a8SSzymon Dompke },
1074163994a8SSzymon Dompke telemetry::service, triggerPath,
1075163994a8SSzymon Dompke "xyz.openbmc_project.Object.Delete", "Delete");
1076163994a8SSzymon Dompke });
10771b7e696bSLukasz Kazmierczak }
10781b7e696bSLukasz Kazmierczak
107907148cf2SLukasz Kazmierczak } // namespace redfish
1080