107148cf2SLukasz Kazmierczak #pragma once 207148cf2SLukasz Kazmierczak 33ccb3adbSEd Tanous #include "app.hpp" 4539d8c6bSEd Tanous #include "generated/enums/metric_definition.hpp" 5dd1c4a9cSSzymon Dompke #include "generated/enums/resource.hpp" 6dd1c4a9cSSzymon Dompke #include "generated/enums/triggers.hpp" 73ccb3adbSEd Tanous #include "query.hpp" 83ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 9dd1c4a9cSSzymon Dompke #include "utility.hpp" 1007148cf2SLukasz Kazmierczak #include "utils/collection.hpp" 113ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 125b90429aSEd Tanous #include "utils/json_utils.hpp" 131516c21bSJanet Adkins #include "utils/sensor_utils.hpp" 1407148cf2SLukasz Kazmierczak #include "utils/telemetry_utils.hpp" 153ccb3adbSEd Tanous #include "utils/time_utils.hpp" 1607148cf2SLukasz Kazmierczak 17ef4c65b7SEd Tanous #include <boost/url/format.hpp> 1889474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 1989474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 2007148cf2SLukasz Kazmierczak 217a1dbc48SGeorge Liu #include <array> 227a1dbc48SGeorge Liu #include <string_view> 231b7e696bSLukasz Kazmierczak #include <tuple> 241b7e696bSLukasz Kazmierczak #include <variant> 251b7e696bSLukasz Kazmierczak #include <vector> 261b7e696bSLukasz Kazmierczak 2707148cf2SLukasz Kazmierczak namespace redfish 2807148cf2SLukasz Kazmierczak { 2907148cf2SLukasz Kazmierczak namespace telemetry 3007148cf2SLukasz Kazmierczak { 3107148cf2SLukasz Kazmierczak constexpr const char* triggerInterface = 3207148cf2SLukasz Kazmierczak "xyz.openbmc_project.Telemetry.Trigger"; 3307148cf2SLukasz Kazmierczak 341b7e696bSLukasz Kazmierczak using NumericThresholdParams = 351b7e696bSLukasz Kazmierczak std::tuple<std::string, uint64_t, std::string, double>; 361b7e696bSLukasz Kazmierczak 371b7e696bSLukasz Kazmierczak using DiscreteThresholdParams = 381b7e696bSLukasz Kazmierczak std::tuple<std::string, std::string, uint64_t, std::string>; 391b7e696bSLukasz Kazmierczak 40dd1c4a9cSSzymon Dompke using TriggerThresholdParams = 41dd1c4a9cSSzymon Dompke std::variant<std::vector<NumericThresholdParams>, 42dd1c4a9cSSzymon Dompke std::vector<DiscreteThresholdParams>>; 43dd1c4a9cSSzymon Dompke 441b7e696bSLukasz Kazmierczak using TriggerThresholdParamsExt = 451b7e696bSLukasz Kazmierczak std::variant<std::monostate, std::vector<NumericThresholdParams>, 461b7e696bSLukasz Kazmierczak std::vector<DiscreteThresholdParams>>; 471b7e696bSLukasz Kazmierczak 481b7e696bSLukasz Kazmierczak using TriggerSensorsParams = 491b7e696bSLukasz Kazmierczak std::vector<std::pair<sdbusplus::message::object_path, std::string>>; 501b7e696bSLukasz Kazmierczak 511b7e696bSLukasz Kazmierczak using TriggerGetParamsVariant = 521b7e696bSLukasz Kazmierczak std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt, 533f215c92SSzymon Dompke TriggerSensorsParams, std::vector<std::string>, 543f215c92SSzymon Dompke std::vector<sdbusplus::message::object_path>>; 551b7e696bSLukasz Kazmierczak 56dd1c4a9cSSzymon Dompke inline triggers::TriggerActionEnum 57dd1c4a9cSSzymon Dompke toRedfishTriggerAction(std::string_view dbusValue) 581b7e696bSLukasz Kazmierczak { 59dd1c4a9cSSzymon Dompke if (dbusValue == 60dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport") 611b7e696bSLukasz Kazmierczak { 62dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::RedfishMetricReport; 631b7e696bSLukasz Kazmierczak } 64dd1c4a9cSSzymon Dompke if (dbusValue == 65dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog") 661b7e696bSLukasz Kazmierczak { 67dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::RedfishEvent; 681b7e696bSLukasz Kazmierczak } 69dd1c4a9cSSzymon Dompke if (dbusValue == 70dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal") 711b7e696bSLukasz Kazmierczak { 72dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::LogToLogService; 731b7e696bSLukasz Kazmierczak } 74dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::Invalid; 751b7e696bSLukasz Kazmierczak } 761b7e696bSLukasz Kazmierczak 77dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue) 781b7e696bSLukasz Kazmierczak { 79dd1c4a9cSSzymon Dompke if (redfishValue == "RedfishMetricReport") 801b7e696bSLukasz Kazmierczak { 81dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport"; 82dd1c4a9cSSzymon Dompke } 83dd1c4a9cSSzymon Dompke if (redfishValue == "RedfishEvent") 84dd1c4a9cSSzymon Dompke { 85dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog"; 86dd1c4a9cSSzymon Dompke } 87dd1c4a9cSSzymon Dompke if (redfishValue == "LogToLogService") 88dd1c4a9cSSzymon Dompke { 89dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal"; 90dd1c4a9cSSzymon Dompke } 91dd1c4a9cSSzymon Dompke return ""; 92dd1c4a9cSSzymon Dompke } 931b7e696bSLukasz Kazmierczak 94dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue) 95dd1c4a9cSSzymon Dompke { 96dd1c4a9cSSzymon Dompke if (redfishValue == "OK") 97dd1c4a9cSSzymon Dompke { 98dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK"; 99dd1c4a9cSSzymon Dompke } 100dd1c4a9cSSzymon Dompke if (redfishValue == "Warning") 101dd1c4a9cSSzymon Dompke { 102dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning"; 103dd1c4a9cSSzymon Dompke } 104dd1c4a9cSSzymon Dompke if (redfishValue == "Critical") 105dd1c4a9cSSzymon Dompke { 106dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical"; 107dd1c4a9cSSzymon Dompke } 108dd1c4a9cSSzymon Dompke return ""; 109dd1c4a9cSSzymon Dompke } 110dd1c4a9cSSzymon Dompke 111dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue) 112dd1c4a9cSSzymon Dompke { 113dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK") 114dd1c4a9cSSzymon Dompke { 115dd1c4a9cSSzymon Dompke return resource::Health::OK; 116dd1c4a9cSSzymon Dompke } 117dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning") 118dd1c4a9cSSzymon Dompke { 119dd1c4a9cSSzymon Dompke return resource::Health::Warning; 120dd1c4a9cSSzymon Dompke } 121dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical") 122dd1c4a9cSSzymon Dompke { 123dd1c4a9cSSzymon Dompke return resource::Health::Critical; 124dd1c4a9cSSzymon Dompke } 125dd1c4a9cSSzymon Dompke return resource::Health::Invalid; 126dd1c4a9cSSzymon Dompke } 127dd1c4a9cSSzymon Dompke 128dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue) 129dd1c4a9cSSzymon Dompke { 130dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical") 131dd1c4a9cSSzymon Dompke { 132dd1c4a9cSSzymon Dompke return "UpperCritical"; 133dd1c4a9cSSzymon Dompke } 134dd1c4a9cSSzymon Dompke 135dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical") 136dd1c4a9cSSzymon Dompke { 137dd1c4a9cSSzymon Dompke return "LowerCritical"; 138dd1c4a9cSSzymon Dompke } 139dd1c4a9cSSzymon Dompke 140dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning") 141dd1c4a9cSSzymon Dompke { 142dd1c4a9cSSzymon Dompke return "UpperWarning"; 143dd1c4a9cSSzymon Dompke } 144dd1c4a9cSSzymon Dompke 145dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning") 146dd1c4a9cSSzymon Dompke { 147dd1c4a9cSSzymon Dompke return "LowerWarning"; 148dd1c4a9cSSzymon Dompke } 149dd1c4a9cSSzymon Dompke 150dd1c4a9cSSzymon Dompke return ""; 151dd1c4a9cSSzymon Dompke } 152dd1c4a9cSSzymon Dompke 153dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue) 154dd1c4a9cSSzymon Dompke { 155dd1c4a9cSSzymon Dompke if (redfishValue == "Either") 156dd1c4a9cSSzymon Dompke { 157dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either"; 158dd1c4a9cSSzymon Dompke } 159dd1c4a9cSSzymon Dompke 160dd1c4a9cSSzymon Dompke if (redfishValue == "Decreasing") 161dd1c4a9cSSzymon Dompke { 162dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing"; 163dd1c4a9cSSzymon Dompke } 164dd1c4a9cSSzymon Dompke 165dd1c4a9cSSzymon Dompke if (redfishValue == "Increasing") 166dd1c4a9cSSzymon Dompke { 167dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing"; 168dd1c4a9cSSzymon Dompke } 169dd1c4a9cSSzymon Dompke 170dd1c4a9cSSzymon Dompke return ""; 171dd1c4a9cSSzymon Dompke } 172dd1c4a9cSSzymon Dompke 173dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation 174dd1c4a9cSSzymon Dompke toRedfishActivation(std::string_view dbusValue) 175dd1c4a9cSSzymon Dompke { 176dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either") 177dd1c4a9cSSzymon Dompke { 178dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Either; 179dd1c4a9cSSzymon Dompke } 180dd1c4a9cSSzymon Dompke 181dd1c4a9cSSzymon Dompke if (dbusValue == 182dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing") 183dd1c4a9cSSzymon Dompke { 184dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Decreasing; 185dd1c4a9cSSzymon Dompke } 186dd1c4a9cSSzymon Dompke 187dd1c4a9cSSzymon Dompke if (dbusValue == 188dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing") 189dd1c4a9cSSzymon Dompke { 190dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Increasing; 191dd1c4a9cSSzymon Dompke } 192dd1c4a9cSSzymon Dompke 193dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Invalid; 194dd1c4a9cSSzymon Dompke } 195dd1c4a9cSSzymon Dompke 196dd1c4a9cSSzymon Dompke enum class MetricType 197dd1c4a9cSSzymon Dompke { 198dd1c4a9cSSzymon Dompke Discrete, 199dd1c4a9cSSzymon Dompke Numeric 200dd1c4a9cSSzymon Dompke }; 201dd1c4a9cSSzymon Dompke 202dd1c4a9cSSzymon Dompke enum class DiscreteCondition 203dd1c4a9cSSzymon Dompke { 204dd1c4a9cSSzymon Dompke Specified, 205dd1c4a9cSSzymon Dompke Changed 206dd1c4a9cSSzymon Dompke }; 207dd1c4a9cSSzymon Dompke 208dd1c4a9cSSzymon Dompke struct Context 209dd1c4a9cSSzymon Dompke { 210dd1c4a9cSSzymon Dompke std::string id; 211dd1c4a9cSSzymon Dompke std::string name; 212dd1c4a9cSSzymon Dompke std::vector<std::string> actions; 213dd1c4a9cSSzymon Dompke std::vector<std::pair<sdbusplus::message::object_path, std::string>> 214dd1c4a9cSSzymon Dompke sensors; 215dd1c4a9cSSzymon Dompke std::vector<sdbusplus::message::object_path> reports; 216dd1c4a9cSSzymon Dompke TriggerThresholdParams thresholds; 217dd1c4a9cSSzymon Dompke 218dd1c4a9cSSzymon Dompke std::optional<DiscreteCondition> discreteCondition; 219dd1c4a9cSSzymon Dompke std::optional<MetricType> metricType; 220dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> metricProperties; 221dd1c4a9cSSzymon Dompke }; 222dd1c4a9cSSzymon Dompke 223dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path> 224dd1c4a9cSSzymon Dompke getReportPathFromReportDefinitionUri(const std::string& uri) 225dd1c4a9cSSzymon Dompke { 2266fd29553SEd Tanous boost::system::result<boost::urls::url_view> parsed = 227dd1c4a9cSSzymon Dompke boost::urls::parse_relative_ref(uri); 228dd1c4a9cSSzymon Dompke 229dd1c4a9cSSzymon Dompke if (!parsed) 2301b7e696bSLukasz Kazmierczak { 2311b7e696bSLukasz Kazmierczak return std::nullopt; 2321b7e696bSLukasz Kazmierczak } 2331b7e696bSLukasz Kazmierczak 234dd1c4a9cSSzymon Dompke std::string id; 235dd1c4a9cSSzymon Dompke if (!crow::utility::readUrlSegments( 236dd1c4a9cSSzymon Dompke *parsed, "redfish", "v1", "TelemetryService", 237dd1c4a9cSSzymon Dompke "MetricReportDefinitions", std::ref(id))) 238dd1c4a9cSSzymon Dompke { 239dd1c4a9cSSzymon Dompke return std::nullopt; 2401b7e696bSLukasz Kazmierczak } 2411b7e696bSLukasz Kazmierczak 242dd1c4a9cSSzymon Dompke return sdbusplus::message::object_path( 243dd1c4a9cSSzymon Dompke "/xyz/openbmc_project/Telemetry/Reports") / 244dd1c4a9cSSzymon Dompke "TelemetryService" / id; 245dd1c4a9cSSzymon Dompke } 246dd1c4a9cSSzymon Dompke 247dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType) 248dd1c4a9cSSzymon Dompke { 249dd1c4a9cSSzymon Dompke if (metricType == "Discrete") 250dd1c4a9cSSzymon Dompke { 251dd1c4a9cSSzymon Dompke return MetricType::Discrete; 252dd1c4a9cSSzymon Dompke } 253dd1c4a9cSSzymon Dompke if (metricType == "Numeric") 254dd1c4a9cSSzymon Dompke { 255dd1c4a9cSSzymon Dompke return MetricType::Numeric; 256dd1c4a9cSSzymon Dompke } 257dd1c4a9cSSzymon Dompke return std::nullopt; 258dd1c4a9cSSzymon Dompke } 259dd1c4a9cSSzymon Dompke 260dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition> 261dd1c4a9cSSzymon Dompke getDiscreteCondition(const std::string& discreteTriggerCondition) 262dd1c4a9cSSzymon Dompke { 263dd1c4a9cSSzymon Dompke if (discreteTriggerCondition == "Specified") 264dd1c4a9cSSzymon Dompke { 265dd1c4a9cSSzymon Dompke return DiscreteCondition::Specified; 266dd1c4a9cSSzymon Dompke } 267dd1c4a9cSSzymon Dompke if (discreteTriggerCondition == "Changed") 268dd1c4a9cSSzymon Dompke { 269dd1c4a9cSSzymon Dompke return DiscreteCondition::Changed; 270dd1c4a9cSSzymon Dompke } 271dd1c4a9cSSzymon Dompke return std::nullopt; 272dd1c4a9cSSzymon Dompke } 273dd1c4a9cSSzymon Dompke 2742932dcb6SEd Tanous inline bool parseThreshold(crow::Response& res, 2752932dcb6SEd Tanous nlohmann::json::object_t& threshold, 2762932dcb6SEd Tanous std::string_view dbusThresholdName, 2772932dcb6SEd Tanous std::vector<NumericThresholdParams>& parsedParams) 278dd1c4a9cSSzymon Dompke { 279dd1c4a9cSSzymon Dompke double reading = 0.0; 280dd1c4a9cSSzymon Dompke std::string activation; 281dd1c4a9cSSzymon Dompke std::string dwellTimeStr; 282dd1c4a9cSSzymon Dompke 283*afc474aeSMyung Bae if (!json_util::readJsonObject( // 284*afc474aeSMyung Bae threshold, res, // 285*afc474aeSMyung Bae "Activation", activation, // 286*afc474aeSMyung Bae "DwellTime", dwellTimeStr, // 287*afc474aeSMyung Bae "Reading", reading // 288*afc474aeSMyung Bae )) 289dd1c4a9cSSzymon Dompke { 290dd1c4a9cSSzymon Dompke return false; 291dd1c4a9cSSzymon Dompke } 292dd1c4a9cSSzymon Dompke 293dd1c4a9cSSzymon Dompke std::string dbusActivation = toDbusActivation(activation); 294dd1c4a9cSSzymon Dompke 295dd1c4a9cSSzymon Dompke if (dbusActivation.empty()) 296dd1c4a9cSSzymon Dompke { 297dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "Activation", activation); 298dd1c4a9cSSzymon Dompke return false; 299dd1c4a9cSSzymon Dompke } 300dd1c4a9cSSzymon Dompke 301dd1c4a9cSSzymon Dompke std::optional<std::chrono::milliseconds> dwellTime = 302dd1c4a9cSSzymon Dompke time_utils::fromDurationString(dwellTimeStr); 303dd1c4a9cSSzymon Dompke if (!dwellTime) 304dd1c4a9cSSzymon Dompke { 305dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr); 306dd1c4a9cSSzymon Dompke return false; 307dd1c4a9cSSzymon Dompke } 308dd1c4a9cSSzymon Dompke 309dd1c4a9cSSzymon Dompke parsedParams.emplace_back(dbusThresholdName, 310dd1c4a9cSSzymon Dompke static_cast<uint64_t>(dwellTime->count()), 311dd1c4a9cSSzymon Dompke dbusActivation, reading); 3122932dcb6SEd Tanous return true; 3132932dcb6SEd Tanous } 3142932dcb6SEd Tanous 3152932dcb6SEd Tanous struct NumericThresholds 3162932dcb6SEd Tanous { 3172932dcb6SEd Tanous std::optional<nlohmann::json::object_t> upperCritical; 3182932dcb6SEd Tanous std::optional<nlohmann::json::object_t> upperWarning; 3192932dcb6SEd Tanous std::optional<nlohmann::json::object_t> lowerWarning; 3202932dcb6SEd Tanous std::optional<nlohmann::json::object_t> lowerCritical; 3212932dcb6SEd Tanous 3222932dcb6SEd Tanous bool any() const 3232932dcb6SEd Tanous { 3242932dcb6SEd Tanous return upperCritical || upperWarning || lowerWarning || lowerCritical; 3252932dcb6SEd Tanous } 3262932dcb6SEd Tanous }; 3272932dcb6SEd Tanous 328bd79bce8SPatrick Williams inline bool parseNumericThresholds( 329bd79bce8SPatrick Williams crow::Response& res, NumericThresholds& numericThresholds, Context& ctx) 3302932dcb6SEd Tanous { 3312932dcb6SEd Tanous std::vector<NumericThresholdParams> parsedParams; 3322932dcb6SEd Tanous if (numericThresholds.upperCritical) 3332932dcb6SEd Tanous { 3342932dcb6SEd Tanous if (!parseThreshold( 3352932dcb6SEd Tanous res, *numericThresholds.upperCritical, 3362932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical", 3372932dcb6SEd Tanous parsedParams)) 3382932dcb6SEd Tanous { 3392932dcb6SEd Tanous return false; 3402932dcb6SEd Tanous } 3412932dcb6SEd Tanous } 3422932dcb6SEd Tanous if (numericThresholds.upperWarning) 3432932dcb6SEd Tanous { 3442932dcb6SEd Tanous if (!parseThreshold( 3452932dcb6SEd Tanous res, *numericThresholds.upperWarning, 3462932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning", 3472932dcb6SEd Tanous parsedParams)) 3482932dcb6SEd Tanous { 3492932dcb6SEd Tanous return false; 3502932dcb6SEd Tanous } 3512932dcb6SEd Tanous } 3522932dcb6SEd Tanous if (numericThresholds.lowerWarning) 3532932dcb6SEd Tanous { 3542932dcb6SEd Tanous if (!parseThreshold( 3552932dcb6SEd Tanous res, *numericThresholds.lowerWarning, 3562932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning", 3572932dcb6SEd Tanous parsedParams)) 3582932dcb6SEd Tanous { 3592932dcb6SEd Tanous return false; 3602932dcb6SEd Tanous } 3612932dcb6SEd Tanous } 3622932dcb6SEd Tanous if (numericThresholds.lowerCritical) 3632932dcb6SEd Tanous { 3642932dcb6SEd Tanous if (!parseThreshold( 3652932dcb6SEd Tanous res, *numericThresholds.lowerCritical, 3662932dcb6SEd Tanous "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical", 3672932dcb6SEd Tanous parsedParams)) 3682932dcb6SEd Tanous { 3692932dcb6SEd Tanous return false; 3702932dcb6SEd Tanous } 371dd1c4a9cSSzymon Dompke } 372dd1c4a9cSSzymon Dompke 373dd1c4a9cSSzymon Dompke ctx.thresholds = std::move(parsedParams); 374dd1c4a9cSSzymon Dompke return true; 375dd1c4a9cSSzymon Dompke } 376dd1c4a9cSSzymon Dompke 377dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers( 378dd1c4a9cSSzymon Dompke crow::Response& res, 3792932dcb6SEd Tanous std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers, 3802932dcb6SEd Tanous Context& ctx) 381dd1c4a9cSSzymon Dompke { 382dd1c4a9cSSzymon Dompke std::vector<DiscreteThresholdParams> parsedParams; 383dd1c4a9cSSzymon Dompke if (!discreteTriggers) 384dd1c4a9cSSzymon Dompke { 385dd1c4a9cSSzymon Dompke ctx.thresholds = std::move(parsedParams); 386dd1c4a9cSSzymon Dompke return true; 387dd1c4a9cSSzymon Dompke } 388dd1c4a9cSSzymon Dompke 389dd1c4a9cSSzymon Dompke parsedParams.reserve(discreteTriggers->size()); 3902932dcb6SEd Tanous for (nlohmann::json::object_t& thresholdInfo : *discreteTriggers) 391dd1c4a9cSSzymon Dompke { 392dd1c4a9cSSzymon Dompke std::optional<std::string> name = ""; 393dd1c4a9cSSzymon Dompke std::string value; 394dd1c4a9cSSzymon Dompke std::string dwellTimeStr; 395dd1c4a9cSSzymon Dompke std::string severity; 396dd1c4a9cSSzymon Dompke 397*afc474aeSMyung Bae if (!json_util::readJsonObject( // 398*afc474aeSMyung Bae thresholdInfo, res, // 399*afc474aeSMyung Bae "DwellTime", dwellTimeStr, // 400*afc474aeSMyung Bae "Name", name, // 401*afc474aeSMyung Bae "Severity", severity, // 402*afc474aeSMyung Bae "Value", value // 403*afc474aeSMyung Bae )) 404dd1c4a9cSSzymon Dompke { 405dd1c4a9cSSzymon Dompke return false; 406dd1c4a9cSSzymon Dompke } 407dd1c4a9cSSzymon Dompke 408dd1c4a9cSSzymon Dompke std::optional<std::chrono::milliseconds> dwellTime = 409dd1c4a9cSSzymon Dompke time_utils::fromDurationString(dwellTimeStr); 410dd1c4a9cSSzymon Dompke if (!dwellTime) 411dd1c4a9cSSzymon Dompke { 412dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr); 413dd1c4a9cSSzymon Dompke return false; 414dd1c4a9cSSzymon Dompke } 415dd1c4a9cSSzymon Dompke 416dd1c4a9cSSzymon Dompke std::string dbusSeverity = toDbusSeverity(severity); 417dd1c4a9cSSzymon Dompke if (dbusSeverity.empty()) 418dd1c4a9cSSzymon Dompke { 419dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "Severity", severity); 420dd1c4a9cSSzymon Dompke return false; 421dd1c4a9cSSzymon Dompke } 422dd1c4a9cSSzymon Dompke 423dd1c4a9cSSzymon Dompke parsedParams.emplace_back(*name, dbusSeverity, 424dd1c4a9cSSzymon Dompke static_cast<uint64_t>(dwellTime->count()), 425dd1c4a9cSSzymon Dompke value); 426dd1c4a9cSSzymon Dompke } 427dd1c4a9cSSzymon Dompke 428dd1c4a9cSSzymon Dompke ctx.thresholds = std::move(parsedParams); 429dd1c4a9cSSzymon Dompke return true; 430dd1c4a9cSSzymon Dompke } 431dd1c4a9cSSzymon Dompke 432dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds( 433dd1c4a9cSSzymon Dompke crow::Response& res, 4342932dcb6SEd Tanous std::optional<std::vector<nlohmann::json::object_t>>& discreteTriggers, 4352932dcb6SEd Tanous NumericThresholds& numericThresholds, Context& ctx) 436dd1c4a9cSSzymon Dompke { 4372932dcb6SEd Tanous if (discreteTriggers && numericThresholds.any()) 438dd1c4a9cSSzymon Dompke { 439dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 440dd1c4a9cSSzymon Dompke "NumericThresholds"); 441dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds", 442dd1c4a9cSSzymon Dompke "DiscreteTriggers"); 443dd1c4a9cSSzymon Dompke return false; 444dd1c4a9cSSzymon Dompke } 445dd1c4a9cSSzymon Dompke 446dd1c4a9cSSzymon Dompke if (ctx.discreteCondition) 447dd1c4a9cSSzymon Dompke { 4482932dcb6SEd Tanous if (numericThresholds.any()) 449dd1c4a9cSSzymon Dompke { 450dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggerCondition", 451dd1c4a9cSSzymon Dompke "NumericThresholds"); 452dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds", 453dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition"); 454dd1c4a9cSSzymon Dompke return false; 455dd1c4a9cSSzymon Dompke } 456dd1c4a9cSSzymon Dompke } 457dd1c4a9cSSzymon Dompke 458dd1c4a9cSSzymon Dompke if (ctx.metricType) 459dd1c4a9cSSzymon Dompke { 4602932dcb6SEd Tanous if (*ctx.metricType == MetricType::Discrete && numericThresholds.any()) 461dd1c4a9cSSzymon Dompke { 462dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds", 463dd1c4a9cSSzymon Dompke "MetricType"); 464dd1c4a9cSSzymon Dompke return false; 465dd1c4a9cSSzymon Dompke } 466dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Numeric && discreteTriggers) 467dd1c4a9cSSzymon Dompke { 468dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 469dd1c4a9cSSzymon Dompke "MetricType"); 470dd1c4a9cSSzymon Dompke return false; 471dd1c4a9cSSzymon Dompke } 472dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition) 473dd1c4a9cSSzymon Dompke { 474dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 475dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition"); 476dd1c4a9cSSzymon Dompke return false; 477dd1c4a9cSSzymon Dompke } 478dd1c4a9cSSzymon Dompke } 479dd1c4a9cSSzymon Dompke 480dd1c4a9cSSzymon Dompke if (discreteTriggers || ctx.discreteCondition || 481dd1c4a9cSSzymon Dompke (ctx.metricType && *ctx.metricType == MetricType::Discrete)) 482dd1c4a9cSSzymon Dompke { 483dd1c4a9cSSzymon Dompke if (ctx.discreteCondition) 484dd1c4a9cSSzymon Dompke { 485dd1c4a9cSSzymon Dompke if (*ctx.discreteCondition == DiscreteCondition::Specified && 486dd1c4a9cSSzymon Dompke !discreteTriggers) 487dd1c4a9cSSzymon Dompke { 488dd1c4a9cSSzymon Dompke messages::createFailedMissingReqProperties(res, 489dd1c4a9cSSzymon Dompke "DiscreteTriggers"); 490dd1c4a9cSSzymon Dompke return false; 491dd1c4a9cSSzymon Dompke } 492dd1c4a9cSSzymon Dompke if (discreteTriggers && 493dd1c4a9cSSzymon Dompke ((*ctx.discreteCondition == DiscreteCondition::Specified && 494dd1c4a9cSSzymon Dompke discreteTriggers->empty()) || 495dd1c4a9cSSzymon Dompke (*ctx.discreteCondition == DiscreteCondition::Changed && 496dd1c4a9cSSzymon Dompke !discreteTriggers->empty()))) 497dd1c4a9cSSzymon Dompke { 498dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 499dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition"); 500dd1c4a9cSSzymon Dompke return false; 501dd1c4a9cSSzymon Dompke } 502dd1c4a9cSSzymon Dompke } 503dd1c4a9cSSzymon Dompke if (!parseDiscreteTriggers(res, discreteTriggers, ctx)) 504dd1c4a9cSSzymon Dompke { 505dd1c4a9cSSzymon Dompke return false; 506dd1c4a9cSSzymon Dompke } 507dd1c4a9cSSzymon Dompke } 5082932dcb6SEd Tanous else if (numericThresholds.any()) 509dd1c4a9cSSzymon Dompke { 5102932dcb6SEd Tanous if (!parseNumericThresholds(res, numericThresholds, ctx)) 511dd1c4a9cSSzymon Dompke { 512dd1c4a9cSSzymon Dompke return false; 513dd1c4a9cSSzymon Dompke } 514dd1c4a9cSSzymon Dompke } 515dd1c4a9cSSzymon Dompke else 516dd1c4a9cSSzymon Dompke { 517dd1c4a9cSSzymon Dompke messages::createFailedMissingReqProperties( 518dd1c4a9cSSzymon Dompke res, "'DiscreteTriggers', 'NumericThresholds', " 519dd1c4a9cSSzymon Dompke "'DiscreteTriggerCondition' or 'MetricType'"); 520dd1c4a9cSSzymon Dompke return false; 521dd1c4a9cSSzymon Dompke } 522dd1c4a9cSSzymon Dompke return true; 523dd1c4a9cSSzymon Dompke } 524dd1c4a9cSSzymon Dompke 5252932dcb6SEd Tanous inline bool parseLinks(crow::Response& res, 5262932dcb6SEd Tanous const std::vector<std::string>& metricReportDefinitions, 5272932dcb6SEd Tanous Context& ctx) 528dd1c4a9cSSzymon Dompke { 5292932dcb6SEd Tanous ctx.reports.reserve(metricReportDefinitions.size()); 5302932dcb6SEd Tanous for (const std::string& reportDefinionUri : metricReportDefinitions) 531dd1c4a9cSSzymon Dompke { 532dd1c4a9cSSzymon Dompke std::optional<sdbusplus::message::object_path> reportPath = 533dd1c4a9cSSzymon Dompke getReportPathFromReportDefinitionUri(reportDefinionUri); 534dd1c4a9cSSzymon Dompke if (!reportPath) 535dd1c4a9cSSzymon Dompke { 536dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "MetricReportDefinitions", 537dd1c4a9cSSzymon Dompke reportDefinionUri); 538dd1c4a9cSSzymon Dompke return false; 539dd1c4a9cSSzymon Dompke } 540dd1c4a9cSSzymon Dompke ctx.reports.emplace_back(*reportPath); 541dd1c4a9cSSzymon Dompke } 542dd1c4a9cSSzymon Dompke return true; 543dd1c4a9cSSzymon Dompke } 544dd1c4a9cSSzymon Dompke 545dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx) 546dd1c4a9cSSzymon Dompke { 547dd1c4a9cSSzymon Dompke if (!ctx.metricProperties) 548dd1c4a9cSSzymon Dompke { 549dd1c4a9cSSzymon Dompke return true; 550dd1c4a9cSSzymon Dompke } 551dd1c4a9cSSzymon Dompke 552dd1c4a9cSSzymon Dompke ctx.sensors.reserve(ctx.metricProperties->size()); 553dd1c4a9cSSzymon Dompke 554dd1c4a9cSSzymon Dompke size_t uriIdx = 0; 555dd1c4a9cSSzymon Dompke for (const std::string& uriStr : *ctx.metricProperties) 556dd1c4a9cSSzymon Dompke { 5574a7fbefdSEd Tanous boost::system::result<boost::urls::url> uri = 558dd1c4a9cSSzymon Dompke boost::urls::parse_relative_ref(uriStr); 559dd1c4a9cSSzymon Dompke if (!uri) 560dd1c4a9cSSzymon Dompke { 561dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect( 562dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr); 563dd1c4a9cSSzymon Dompke return false; 564dd1c4a9cSSzymon Dompke } 565dd1c4a9cSSzymon Dompke std::string chassisName; 566dd1c4a9cSSzymon Dompke std::string sensorName; 567dd1c4a9cSSzymon Dompke if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis", 568dd1c4a9cSSzymon Dompke std::ref(chassisName), "Sensors", 569dd1c4a9cSSzymon Dompke std::ref(sensorName))) 570dd1c4a9cSSzymon Dompke { 571dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect( 572dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr); 573dd1c4a9cSSzymon Dompke return false; 574dd1c4a9cSSzymon Dompke } 575dd1c4a9cSSzymon Dompke 576dd1c4a9cSSzymon Dompke std::pair<std::string, std::string> split = 5771516c21bSJanet Adkins redfish::sensor_utils::splitSensorNameAndType(sensorName); 578dd1c4a9cSSzymon Dompke if (split.first.empty() || split.second.empty()) 579dd1c4a9cSSzymon Dompke { 580dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect( 581dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr); 582dd1c4a9cSSzymon Dompke return false; 583dd1c4a9cSSzymon Dompke } 584dd1c4a9cSSzymon Dompke 585bd79bce8SPatrick Williams std::string sensorPath = 586bd79bce8SPatrick Williams "/xyz/openbmc_project/sensors/" + split.first + '/' + split.second; 587dd1c4a9cSSzymon Dompke 588dd1c4a9cSSzymon Dompke ctx.sensors.emplace_back(sensorPath, uriStr); 589dd1c4a9cSSzymon Dompke uriIdx++; 590dd1c4a9cSSzymon Dompke } 591dd1c4a9cSSzymon Dompke return true; 592dd1c4a9cSSzymon Dompke } 593dd1c4a9cSSzymon Dompke 594dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res, 595dd1c4a9cSSzymon Dompke const crow::Request& req, Context& ctx) 596dd1c4a9cSSzymon Dompke { 597dd1c4a9cSSzymon Dompke std::optional<std::string> id = ""; 598dd1c4a9cSSzymon Dompke std::optional<std::string> name = ""; 599dd1c4a9cSSzymon Dompke std::optional<std::string> metricType; 600dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> triggerActions; 601dd1c4a9cSSzymon Dompke std::optional<std::string> discreteTriggerCondition; 6022932dcb6SEd Tanous std::optional<std::vector<nlohmann::json::object_t>> discreteTriggers; 6032932dcb6SEd Tanous std::optional<std::vector<std::string>> metricReportDefinitions; 6042932dcb6SEd Tanous NumericThresholds thresholds; 605*afc474aeSMyung Bae 606*afc474aeSMyung Bae if (!json_util::readJsonPatch( // 607*afc474aeSMyung Bae req, res, // 608*afc474aeSMyung Bae "Id", id, // 609*afc474aeSMyung Bae "DiscreteTriggerCondition", discreteTriggerCondition, // 610*afc474aeSMyung Bae "DiscreteTriggers", discreteTriggers, // 611*afc474aeSMyung Bae "Links/MetricReportDefinitions", metricReportDefinitions, // 612*afc474aeSMyung Bae "MetricProperties", ctx.metricProperties, // 613*afc474aeSMyung Bae "MetricType", metricType, // 614*afc474aeSMyung Bae "Name", name, // 615*afc474aeSMyung Bae "NumericThresholds/LowerCritical", thresholds.lowerCritical, // 616*afc474aeSMyung Bae "NumericThresholds/LowerWarning", thresholds.lowerWarning, // 617*afc474aeSMyung Bae "NumericThresholds/UpperCritical", thresholds.upperCritical, // 618*afc474aeSMyung Bae "NumericThresholds/UpperWarning", thresholds.upperWarning, // 619*afc474aeSMyung Bae "TriggerActions", triggerActions // 620*afc474aeSMyung Bae )) 621dd1c4a9cSSzymon Dompke { 622dd1c4a9cSSzymon Dompke return false; 623dd1c4a9cSSzymon Dompke } 624dd1c4a9cSSzymon Dompke 625dd1c4a9cSSzymon Dompke ctx.id = *id; 626dd1c4a9cSSzymon Dompke ctx.name = *name; 627dd1c4a9cSSzymon Dompke 628dd1c4a9cSSzymon Dompke if (metricType) 629dd1c4a9cSSzymon Dompke { 630d5736ef2SEd Tanous ctx.metricType = getMetricType(*metricType); 631d5736ef2SEd Tanous if (!ctx.metricType) 632dd1c4a9cSSzymon Dompke { 633dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "MetricType", *metricType); 634dd1c4a9cSSzymon Dompke return false; 635dd1c4a9cSSzymon Dompke } 636dd1c4a9cSSzymon Dompke } 637dd1c4a9cSSzymon Dompke 638dd1c4a9cSSzymon Dompke if (discreteTriggerCondition) 639dd1c4a9cSSzymon Dompke { 640d5736ef2SEd Tanous ctx.discreteCondition = getDiscreteCondition(*discreteTriggerCondition); 641d5736ef2SEd Tanous if (!ctx.discreteCondition) 642dd1c4a9cSSzymon Dompke { 643dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DiscreteTriggerCondition", 644dd1c4a9cSSzymon Dompke *discreteTriggerCondition); 645dd1c4a9cSSzymon Dompke return false; 646dd1c4a9cSSzymon Dompke } 647dd1c4a9cSSzymon Dompke } 648dd1c4a9cSSzymon Dompke 649dd1c4a9cSSzymon Dompke if (triggerActions) 650dd1c4a9cSSzymon Dompke { 651dd1c4a9cSSzymon Dompke ctx.actions.reserve(triggerActions->size()); 652dd1c4a9cSSzymon Dompke for (const std::string& action : *triggerActions) 653dd1c4a9cSSzymon Dompke { 654dd1c4a9cSSzymon Dompke std::string dbusAction = toDbusTriggerAction(action); 655dd1c4a9cSSzymon Dompke 656dd1c4a9cSSzymon Dompke if (dbusAction.empty()) 657dd1c4a9cSSzymon Dompke { 658dd1c4a9cSSzymon Dompke messages::propertyValueNotInList(res, action, "TriggerActions"); 659dd1c4a9cSSzymon Dompke return false; 660dd1c4a9cSSzymon Dompke } 661dd1c4a9cSSzymon Dompke 662dd1c4a9cSSzymon Dompke ctx.actions.emplace_back(dbusAction); 663dd1c4a9cSSzymon Dompke } 664dd1c4a9cSSzymon Dompke } 665dd1c4a9cSSzymon Dompke if (!parseMetricProperties(res, ctx)) 666dd1c4a9cSSzymon Dompke { 667dd1c4a9cSSzymon Dompke return false; 668dd1c4a9cSSzymon Dompke } 669dd1c4a9cSSzymon Dompke 6702932dcb6SEd Tanous if (!parseTriggerThresholds(res, discreteTriggers, thresholds, ctx)) 671dd1c4a9cSSzymon Dompke { 672dd1c4a9cSSzymon Dompke return false; 673dd1c4a9cSSzymon Dompke } 674dd1c4a9cSSzymon Dompke 6752932dcb6SEd Tanous if (metricReportDefinitions) 676dd1c4a9cSSzymon Dompke { 6772932dcb6SEd Tanous if (!parseLinks(res, *metricReportDefinitions, ctx)) 678dd1c4a9cSSzymon Dompke { 679dd1c4a9cSSzymon Dompke return false; 680dd1c4a9cSSzymon Dompke } 681dd1c4a9cSSzymon Dompke } 682dd1c4a9cSSzymon Dompke return true; 683dd1c4a9cSSzymon Dompke } 684dd1c4a9cSSzymon Dompke 685dd1c4a9cSSzymon Dompke inline void afterCreateTrigger( 686dd1c4a9cSSzymon Dompke const boost::system::error_code& ec, const std::string& dbusPath, 687dd1c4a9cSSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id) 688dd1c4a9cSSzymon Dompke { 689dd1c4a9cSSzymon Dompke if (ec == boost::system::errc::file_exists) 690dd1c4a9cSSzymon Dompke { 691dd1c4a9cSSzymon Dompke messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id); 692dd1c4a9cSSzymon Dompke return; 693dd1c4a9cSSzymon Dompke } 694dd1c4a9cSSzymon Dompke if (ec == boost::system::errc::too_many_files_open) 695dd1c4a9cSSzymon Dompke { 696dd1c4a9cSSzymon Dompke messages::createLimitReachedForResource(asyncResp->res); 697dd1c4a9cSSzymon Dompke return; 698dd1c4a9cSSzymon Dompke } 699dd1c4a9cSSzymon Dompke if (ec) 700dd1c4a9cSSzymon Dompke { 701dd1c4a9cSSzymon Dompke messages::internalError(asyncResp->res); 70262598e31SEd Tanous BMCWEB_LOG_ERROR("respHandler DBus error {}", ec); 703dd1c4a9cSSzymon Dompke return; 704dd1c4a9cSSzymon Dompke } 705dd1c4a9cSSzymon Dompke 706dd1c4a9cSSzymon Dompke const std::optional<std::string>& triggerId = 707dd1c4a9cSSzymon Dompke getTriggerIdFromDbusPath(dbusPath); 708dd1c4a9cSSzymon Dompke if (!triggerId) 709dd1c4a9cSSzymon Dompke { 710dd1c4a9cSSzymon Dompke messages::internalError(asyncResp->res); 71162598e31SEd Tanous BMCWEB_LOG_ERROR("Unknown data returned by " 71262598e31SEd Tanous "AddTrigger DBus method"); 713dd1c4a9cSSzymon Dompke return; 714dd1c4a9cSSzymon Dompke } 715dd1c4a9cSSzymon Dompke 716dd1c4a9cSSzymon Dompke messages::created(asyncResp->res); 717dd1c4a9cSSzymon Dompke boost::urls::url locationUrl = boost::urls::format( 718dd1c4a9cSSzymon Dompke "/redfish/v1/TelemetryService/Triggers/{}", *triggerId); 719dd1c4a9cSSzymon Dompke asyncResp->res.addHeader("Location", locationUrl.buffer()); 720dd1c4a9cSSzymon Dompke } 721dd1c4a9cSSzymon Dompke 722dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t> 723dd1c4a9cSSzymon Dompke getTriggerActions(const std::vector<std::string>& dbusActions) 724dd1c4a9cSSzymon Dompke { 725dd1c4a9cSSzymon Dompke nlohmann::json::array_t triggerActions; 726dd1c4a9cSSzymon Dompke for (const std::string& dbusAction : dbusActions) 727dd1c4a9cSSzymon Dompke { 728dd1c4a9cSSzymon Dompke triggers::TriggerActionEnum redfishAction = 729dd1c4a9cSSzymon Dompke toRedfishTriggerAction(dbusAction); 730dd1c4a9cSSzymon Dompke 731dd1c4a9cSSzymon Dompke if (redfishAction == triggers::TriggerActionEnum::Invalid) 732dd1c4a9cSSzymon Dompke { 733dd1c4a9cSSzymon Dompke return std::nullopt; 734dd1c4a9cSSzymon Dompke } 735dd1c4a9cSSzymon Dompke 736dd1c4a9cSSzymon Dompke triggerActions.emplace_back(redfishAction); 737dd1c4a9cSSzymon Dompke } 738dd1c4a9cSSzymon Dompke 739dd1c4a9cSSzymon Dompke return triggerActions; 7401b7e696bSLukasz Kazmierczak } 7411b7e696bSLukasz Kazmierczak 7423f215c92SSzymon Dompke inline std::optional<nlohmann::json::array_t> 7431b7e696bSLukasz Kazmierczak getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams) 7441b7e696bSLukasz Kazmierczak { 745dd1c4a9cSSzymon Dompke nlohmann::json::array_t triggers; 7461b7e696bSLukasz Kazmierczak const std::vector<DiscreteThresholdParams>* discreteParams = 7471b7e696bSLukasz Kazmierczak std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams); 7481b7e696bSLukasz Kazmierczak 749e662eae8SEd Tanous if (discreteParams == nullptr) 7501b7e696bSLukasz Kazmierczak { 7511b7e696bSLukasz Kazmierczak return std::nullopt; 7521b7e696bSLukasz Kazmierczak } 7531b7e696bSLukasz Kazmierczak 7541b7e696bSLukasz Kazmierczak for (const auto& [name, severity, dwellTime, value] : *discreteParams) 7551b7e696bSLukasz Kazmierczak { 7561b7e696bSLukasz Kazmierczak std::optional<std::string> duration = 7571b7e696bSLukasz Kazmierczak time_utils::toDurationStringFromUint(dwellTime); 7581b7e696bSLukasz Kazmierczak 7591b7e696bSLukasz Kazmierczak if (!duration) 7601b7e696bSLukasz Kazmierczak { 7611b7e696bSLukasz Kazmierczak return std::nullopt; 7621b7e696bSLukasz Kazmierczak } 763613dabeaSEd Tanous nlohmann::json::object_t trigger; 764613dabeaSEd Tanous trigger["Name"] = name; 765dd1c4a9cSSzymon Dompke trigger["Severity"] = toRedfishSeverity(severity); 766613dabeaSEd Tanous trigger["DwellTime"] = *duration; 767613dabeaSEd Tanous trigger["Value"] = value; 768ad539545SPatrick Williams triggers.emplace_back(std::move(trigger)); 7691b7e696bSLukasz Kazmierczak } 7701b7e696bSLukasz Kazmierczak 771dd1c4a9cSSzymon Dompke return triggers; 7721b7e696bSLukasz Kazmierczak } 7731b7e696bSLukasz Kazmierczak 7741b7e696bSLukasz Kazmierczak inline std::optional<nlohmann::json> 7751b7e696bSLukasz Kazmierczak getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams) 7761b7e696bSLukasz Kazmierczak { 777dd1c4a9cSSzymon Dompke nlohmann::json::object_t thresholds; 7781b7e696bSLukasz Kazmierczak const std::vector<NumericThresholdParams>* numericParams = 7791b7e696bSLukasz Kazmierczak std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams); 7801b7e696bSLukasz Kazmierczak 781e662eae8SEd Tanous if (numericParams == nullptr) 7821b7e696bSLukasz Kazmierczak { 7831b7e696bSLukasz Kazmierczak return std::nullopt; 7841b7e696bSLukasz Kazmierczak } 7851b7e696bSLukasz Kazmierczak 7861b7e696bSLukasz Kazmierczak for (const auto& [type, dwellTime, activation, reading] : *numericParams) 7871b7e696bSLukasz Kazmierczak { 7881b7e696bSLukasz Kazmierczak std::optional<std::string> duration = 7891b7e696bSLukasz Kazmierczak time_utils::toDurationStringFromUint(dwellTime); 7901b7e696bSLukasz Kazmierczak 7911b7e696bSLukasz Kazmierczak if (!duration) 7921b7e696bSLukasz Kazmierczak { 7931b7e696bSLukasz Kazmierczak return std::nullopt; 7941b7e696bSLukasz Kazmierczak } 795dd1c4a9cSSzymon Dompke nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)]; 7961476687dSEd Tanous threshold["Reading"] = reading; 797dd1c4a9cSSzymon Dompke threshold["Activation"] = toRedfishActivation(activation); 7981476687dSEd Tanous threshold["DwellTime"] = *duration; 7991b7e696bSLukasz Kazmierczak } 8001b7e696bSLukasz Kazmierczak 801dd1c4a9cSSzymon Dompke return thresholds; 8021b7e696bSLukasz Kazmierczak } 8031b7e696bSLukasz Kazmierczak 8043f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions( 8053f215c92SSzymon Dompke const std::vector<sdbusplus::message::object_path>& reportPaths) 8061b7e696bSLukasz Kazmierczak { 8071b7e696bSLukasz Kazmierczak nlohmann::json reports = nlohmann::json::array(); 8083f215c92SSzymon Dompke 8093f215c92SSzymon Dompke for (const sdbusplus::message::object_path& path : reportPaths) 8101b7e696bSLukasz Kazmierczak { 8113f215c92SSzymon Dompke std::string reportId = path.filename(); 8123f215c92SSzymon Dompke if (reportId.empty()) 8133f215c92SSzymon Dompke { 8143f215c92SSzymon Dompke { 81562598e31SEd Tanous BMCWEB_LOG_ERROR("Property Reports contains invalid value: {}", 81662598e31SEd Tanous path.str); 8173f215c92SSzymon Dompke return std::nullopt; 8183f215c92SSzymon Dompke } 8193f215c92SSzymon Dompke } 8203f215c92SSzymon Dompke 8211476687dSEd Tanous nlohmann::json::object_t report; 822ef4c65b7SEd Tanous report["@odata.id"] = boost::urls::format( 823ef4c65b7SEd Tanous "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", 824ef4c65b7SEd Tanous reportId); 825b2ba3072SPatrick Williams reports.emplace_back(std::move(report)); 8261b7e696bSLukasz Kazmierczak } 8271b7e696bSLukasz Kazmierczak 8283f215c92SSzymon Dompke return {std::move(reports)}; 8291b7e696bSLukasz Kazmierczak } 8301b7e696bSLukasz Kazmierczak 8311b7e696bSLukasz Kazmierczak inline std::vector<std::string> 8321b7e696bSLukasz Kazmierczak getMetricProperties(const TriggerSensorsParams& sensors) 8331b7e696bSLukasz Kazmierczak { 8341b7e696bSLukasz Kazmierczak std::vector<std::string> metricProperties; 8351b7e696bSLukasz Kazmierczak metricProperties.reserve(sensors.size()); 8361b7e696bSLukasz Kazmierczak for (const auto& [_, metadata] : sensors) 8371b7e696bSLukasz Kazmierczak { 8381b7e696bSLukasz Kazmierczak metricProperties.emplace_back(metadata); 8391b7e696bSLukasz Kazmierczak } 8401b7e696bSLukasz Kazmierczak 8411b7e696bSLukasz Kazmierczak return metricProperties; 8421b7e696bSLukasz Kazmierczak } 8431b7e696bSLukasz Kazmierczak 8441b7e696bSLukasz Kazmierczak inline bool fillTrigger( 8451b7e696bSLukasz Kazmierczak nlohmann::json& json, const std::string& id, 8461b7e696bSLukasz Kazmierczak const std::vector<std::pair<std::string, TriggerGetParamsVariant>>& 8471b7e696bSLukasz Kazmierczak properties) 8481b7e696bSLukasz Kazmierczak { 8491b7e696bSLukasz Kazmierczak const std::string* name = nullptr; 8501b7e696bSLukasz Kazmierczak const bool* discrete = nullptr; 8511b7e696bSLukasz Kazmierczak const TriggerSensorsParams* sensors = nullptr; 8523f215c92SSzymon Dompke const std::vector<sdbusplus::message::object_path>* reports = nullptr; 85389474494SKrzysztof Grobelny const std::vector<std::string>* triggerActions = nullptr; 8541b7e696bSLukasz Kazmierczak const TriggerThresholdParamsExt* thresholds = nullptr; 8551b7e696bSLukasz Kazmierczak 85689474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 85789474494SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete", 85889474494SKrzysztof Grobelny discrete, "Sensors", sensors, "Reports", reports, "TriggerActions", 85989474494SKrzysztof Grobelny triggerActions, "Thresholds", thresholds); 86089474494SKrzysztof Grobelny 86189474494SKrzysztof Grobelny if (!success) 8621b7e696bSLukasz Kazmierczak { 86389474494SKrzysztof Grobelny return false; 8641b7e696bSLukasz Kazmierczak } 8651b7e696bSLukasz Kazmierczak 86689474494SKrzysztof Grobelny if (triggerActions != nullptr) 86789474494SKrzysztof Grobelny { 868dd1c4a9cSSzymon Dompke std::optional<nlohmann::json::array_t> redfishTriggerActions = 86989474494SKrzysztof Grobelny getTriggerActions(*triggerActions); 87089474494SKrzysztof Grobelny if (!redfishTriggerActions) 8711b7e696bSLukasz Kazmierczak { 87262598e31SEd Tanous BMCWEB_LOG_ERROR( 87362598e31SEd Tanous "Property TriggerActions is invalid in Trigger: {}", id); 8741b7e696bSLukasz Kazmierczak return false; 8751b7e696bSLukasz Kazmierczak } 876dd1c4a9cSSzymon Dompke json["TriggerActions"] = *redfishTriggerActions; 87789474494SKrzysztof Grobelny } 8781b7e696bSLukasz Kazmierczak 87989474494SKrzysztof Grobelny if (reports != nullptr) 8803f215c92SSzymon Dompke { 8813f215c92SSzymon Dompke std::optional<nlohmann::json> linkedReports = 8823f215c92SSzymon Dompke getMetricReportDefinitions(*reports); 8833f215c92SSzymon Dompke if (!linkedReports) 8843f215c92SSzymon Dompke { 88562598e31SEd Tanous BMCWEB_LOG_ERROR("Property Reports is invalid in Trigger: {}", id); 8863f215c92SSzymon Dompke return false; 8873f215c92SSzymon Dompke } 88889474494SKrzysztof Grobelny json["Links"]["MetricReportDefinitions"] = *linkedReports; 88989474494SKrzysztof Grobelny } 8901b7e696bSLukasz Kazmierczak 89189474494SKrzysztof Grobelny if (discrete != nullptr) 89289474494SKrzysztof Grobelny { 8931b7e696bSLukasz Kazmierczak if (*discrete) 8941b7e696bSLukasz Kazmierczak { 8953f215c92SSzymon Dompke std::optional<nlohmann::json::array_t> discreteTriggers = 8961b7e696bSLukasz Kazmierczak getDiscreteTriggers(*thresholds); 8971b7e696bSLukasz Kazmierczak 8981b7e696bSLukasz Kazmierczak if (!discreteTriggers) 8991b7e696bSLukasz Kazmierczak { 90062598e31SEd Tanous BMCWEB_LOG_ERROR("Property Thresholds is invalid for discrete " 90162598e31SEd Tanous "triggers in Trigger: {}", 90262598e31SEd Tanous id); 9031b7e696bSLukasz Kazmierczak return false; 9041b7e696bSLukasz Kazmierczak } 9051b7e696bSLukasz Kazmierczak 9061b7e696bSLukasz Kazmierczak json["DiscreteTriggers"] = *discreteTriggers; 9071b7e696bSLukasz Kazmierczak json["DiscreteTriggerCondition"] = 9081b7e696bSLukasz Kazmierczak discreteTriggers->empty() ? "Changed" : "Specified"; 909539d8c6bSEd Tanous json["MetricType"] = metric_definition::MetricType::Discrete; 9101b7e696bSLukasz Kazmierczak } 9111b7e696bSLukasz Kazmierczak else 9121b7e696bSLukasz Kazmierczak { 9131b7e696bSLukasz Kazmierczak std::optional<nlohmann::json> numericThresholds = 9141b7e696bSLukasz Kazmierczak getNumericThresholds(*thresholds); 9151b7e696bSLukasz Kazmierczak 9161b7e696bSLukasz Kazmierczak if (!numericThresholds) 9171b7e696bSLukasz Kazmierczak { 91862598e31SEd Tanous BMCWEB_LOG_ERROR("Property Thresholds is invalid for numeric " 91962598e31SEd Tanous "thresholds in Trigger: {}", 92062598e31SEd Tanous id); 9211b7e696bSLukasz Kazmierczak return false; 9221b7e696bSLukasz Kazmierczak } 9231b7e696bSLukasz Kazmierczak 9241b7e696bSLukasz Kazmierczak json["NumericThresholds"] = *numericThresholds; 925539d8c6bSEd Tanous json["MetricType"] = metric_definition::MetricType::Numeric; 9261b7e696bSLukasz Kazmierczak } 92789474494SKrzysztof Grobelny } 92889474494SKrzysztof Grobelny 92989474494SKrzysztof Grobelny if (name != nullptr) 93089474494SKrzysztof Grobelny { 93189474494SKrzysztof Grobelny json["Name"] = *name; 93289474494SKrzysztof Grobelny } 93389474494SKrzysztof Grobelny 93489474494SKrzysztof Grobelny if (sensors != nullptr) 93589474494SKrzysztof Grobelny { 93689474494SKrzysztof Grobelny json["MetricProperties"] = getMetricProperties(*sensors); 93789474494SKrzysztof Grobelny } 9381b7e696bSLukasz Kazmierczak 9393f215c92SSzymon Dompke json["@odata.type"] = "#Triggers.v1_2_0.Triggers"; 940ef4c65b7SEd Tanous json["@odata.id"] = 941ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id); 9423f215c92SSzymon Dompke json["Id"] = id; 9431b7e696bSLukasz Kazmierczak 9441b7e696bSLukasz Kazmierczak return true; 9451b7e696bSLukasz Kazmierczak } 9461b7e696bSLukasz Kazmierczak 947dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost( 948dd1c4a9cSSzymon Dompke App& app, const crow::Request& req, 949dd1c4a9cSSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 950dd1c4a9cSSzymon Dompke { 951dd1c4a9cSSzymon Dompke if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 952dd1c4a9cSSzymon Dompke { 953dd1c4a9cSSzymon Dompke return; 954dd1c4a9cSSzymon Dompke } 955dd1c4a9cSSzymon Dompke 956dd1c4a9cSSzymon Dompke telemetry::Context ctx; 957dd1c4a9cSSzymon Dompke if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx)) 958dd1c4a9cSSzymon Dompke { 959dd1c4a9cSSzymon Dompke return; 960dd1c4a9cSSzymon Dompke } 961dd1c4a9cSSzymon Dompke 962dd1c4a9cSSzymon Dompke crow::connections::systemBus->async_method_call( 963dd1c4a9cSSzymon Dompke [asyncResp, id = ctx.id](const boost::system::error_code& ec, 964dd1c4a9cSSzymon Dompke const std::string& dbusPath) { 965dd1c4a9cSSzymon Dompke afterCreateTrigger(ec, dbusPath, asyncResp, id); 966dd1c4a9cSSzymon Dompke }, 967dd1c4a9cSSzymon Dompke service, "/xyz/openbmc_project/Telemetry/Triggers", 968dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger", 969dd1c4a9cSSzymon Dompke "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors, 970dd1c4a9cSSzymon Dompke ctx.reports, ctx.thresholds); 971dd1c4a9cSSzymon Dompke } 972dd1c4a9cSSzymon Dompke 97307148cf2SLukasz Kazmierczak } // namespace telemetry 97407148cf2SLukasz Kazmierczak 97507148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app) 97607148cf2SLukasz Kazmierczak { 97707148cf2SLukasz Kazmierczak BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/") 97807148cf2SLukasz Kazmierczak .privileges(redfish::privileges::getTriggersCollection) 97907148cf2SLukasz Kazmierczak .methods(boost::beast::http::verb::get)( 98045ca1b86SEd Tanous [&app](const crow::Request& req, 98107148cf2SLukasz Kazmierczak const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 9823ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 98345ca1b86SEd Tanous { 98445ca1b86SEd Tanous return; 98545ca1b86SEd Tanous } 98607148cf2SLukasz Kazmierczak asyncResp->res.jsonValue["@odata.type"] = 98707148cf2SLukasz Kazmierczak "#TriggersCollection.TriggersCollection"; 988ae9031f0SWilly Tu asyncResp->res.jsonValue["@odata.id"] = 989ae9031f0SWilly Tu "/redfish/v1/TelemetryService/Triggers"; 99007148cf2SLukasz Kazmierczak asyncResp->res.jsonValue["Name"] = "Triggers Collection"; 9917a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 9927a1dbc48SGeorge Liu telemetry::triggerInterface}; 99307148cf2SLukasz Kazmierczak collection_util::getCollectionMembers( 994ae9031f0SWilly Tu asyncResp, 995ae9031f0SWilly Tu boost::urls::url("/redfish/v1/TelemetryService/Triggers"), 996ae9031f0SWilly Tu interfaces, 99707148cf2SLukasz Kazmierczak "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService"); 99807148cf2SLukasz Kazmierczak }); 999dd1c4a9cSSzymon Dompke 1000dd1c4a9cSSzymon Dompke BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/") 1001dd1c4a9cSSzymon Dompke .privileges(redfish::privileges::postTriggersCollection) 1002dd1c4a9cSSzymon Dompke .methods(boost::beast::http::verb::post)(std::bind_front( 1003dd1c4a9cSSzymon Dompke telemetry::handleTriggerCollectionPost, std::ref(app))); 100407148cf2SLukasz Kazmierczak } 100507148cf2SLukasz Kazmierczak 10061b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app) 10071b7e696bSLukasz Kazmierczak { 10081b7e696bSLukasz Kazmierczak BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/") 10091b7e696bSLukasz Kazmierczak .privileges(redfish::privileges::getTriggers) 10101b7e696bSLukasz Kazmierczak .methods(boost::beast::http::verb::get)( 101145ca1b86SEd Tanous [&app](const crow::Request& req, 10121b7e696bSLukasz Kazmierczak const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 10131b7e696bSLukasz Kazmierczak const std::string& id) { 10143ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 101545ca1b86SEd Tanous { 101645ca1b86SEd Tanous return; 101745ca1b86SEd Tanous } 101889474494SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 101989474494SKrzysztof Grobelny *crow::connections::systemBus, telemetry::service, 1020bd79bce8SPatrick Williams telemetry::getDbusTriggerPath(id), 1021bd79bce8SPatrick Williams telemetry::triggerInterface, 10221b7e696bSLukasz Kazmierczak [asyncResp, 10235e7e2dc5SEd Tanous id](const boost::system::error_code& ec, 10241b7e696bSLukasz Kazmierczak const std::vector<std::pair< 1025bd79bce8SPatrick Williams std::string, telemetry::TriggerGetParamsVariant>>& 1026bd79bce8SPatrick Williams ret) { 10271b7e696bSLukasz Kazmierczak if (ec.value() == EBADR || 10281b7e696bSLukasz Kazmierczak ec == boost::system::errc::host_unreachable) 10291b7e696bSLukasz Kazmierczak { 1030bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, 1031bd79bce8SPatrick Williams "Triggers", id); 10321b7e696bSLukasz Kazmierczak return; 10331b7e696bSLukasz Kazmierczak } 10341b7e696bSLukasz Kazmierczak if (ec) 10351b7e696bSLukasz Kazmierczak { 103662598e31SEd Tanous BMCWEB_LOG_ERROR("respHandler DBus error {}", ec); 10371b7e696bSLukasz Kazmierczak messages::internalError(asyncResp->res); 10381b7e696bSLukasz Kazmierczak return; 10391b7e696bSLukasz Kazmierczak } 10401b7e696bSLukasz Kazmierczak 1041bd79bce8SPatrick Williams if (!telemetry::fillTrigger(asyncResp->res.jsonValue, 1042bd79bce8SPatrick Williams id, ret)) 10431b7e696bSLukasz Kazmierczak { 10441b7e696bSLukasz Kazmierczak messages::internalError(asyncResp->res); 10451b7e696bSLukasz Kazmierczak } 104689474494SKrzysztof Grobelny }); 10471b7e696bSLukasz Kazmierczak }); 1048163994a8SSzymon Dompke 1049163994a8SSzymon Dompke BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/") 1050163994a8SSzymon Dompke .privileges(redfish::privileges::deleteTriggers) 1051163994a8SSzymon Dompke .methods(boost::beast::http::verb::delete_)( 105245ca1b86SEd Tanous [&app](const crow::Request& req, 1053163994a8SSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1054163994a8SSzymon Dompke const std::string& id) { 10553ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 105645ca1b86SEd Tanous { 105745ca1b86SEd Tanous return; 105845ca1b86SEd Tanous } 1059bd79bce8SPatrick Williams const std::string triggerPath = 1060bd79bce8SPatrick Williams telemetry::getDbusTriggerPath(id); 1061163994a8SSzymon Dompke 1062163994a8SSzymon Dompke crow::connections::systemBus->async_method_call( 10635e7e2dc5SEd Tanous [asyncResp, id](const boost::system::error_code& ec) { 1064163994a8SSzymon Dompke if (ec.value() == EBADR) 1065163994a8SSzymon Dompke { 1066bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, 1067bd79bce8SPatrick Williams "Triggers", id); 1068163994a8SSzymon Dompke return; 1069163994a8SSzymon Dompke } 1070163994a8SSzymon Dompke 1071163994a8SSzymon Dompke if (ec) 1072163994a8SSzymon Dompke { 107362598e31SEd Tanous BMCWEB_LOG_ERROR("respHandler DBus error {}", ec); 1074163994a8SSzymon Dompke messages::internalError(asyncResp->res); 1075163994a8SSzymon Dompke return; 1076163994a8SSzymon Dompke } 1077163994a8SSzymon Dompke 1078bd79bce8SPatrick Williams asyncResp->res.result( 1079bd79bce8SPatrick Williams boost::beast::http::status::no_content); 1080163994a8SSzymon Dompke }, 1081163994a8SSzymon Dompke telemetry::service, triggerPath, 1082163994a8SSzymon Dompke "xyz.openbmc_project.Object.Delete", "Delete"); 1083163994a8SSzymon Dompke }); 10841b7e696bSLukasz Kazmierczak } 10851b7e696bSLukasz Kazmierczak 108607148cf2SLukasz Kazmierczak } // namespace redfish 1087