107148cf2SLukasz Kazmierczak #pragma once 207148cf2SLukasz Kazmierczak 33ccb3adbSEd Tanous #include "app.hpp" 4*dd1c4a9cSSzymon Dompke #include "generated/enums/resource.hpp" 5*dd1c4a9cSSzymon Dompke #include "generated/enums/triggers.hpp" 63ccb3adbSEd Tanous #include "query.hpp" 73ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 8*dd1c4a9cSSzymon Dompke #include "sensors.hpp" 9*dd1c4a9cSSzymon Dompke #include "utility.hpp" 1007148cf2SLukasz Kazmierczak #include "utils/collection.hpp" 113ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 1207148cf2SLukasz Kazmierczak #include "utils/telemetry_utils.hpp" 133ccb3adbSEd Tanous #include "utils/time_utils.hpp" 1407148cf2SLukasz Kazmierczak 15ef4c65b7SEd Tanous #include <boost/url/format.hpp> 1689474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 1789474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 1807148cf2SLukasz Kazmierczak 197a1dbc48SGeorge Liu #include <array> 207a1dbc48SGeorge Liu #include <string_view> 211b7e696bSLukasz Kazmierczak #include <tuple> 221b7e696bSLukasz Kazmierczak #include <variant> 231b7e696bSLukasz Kazmierczak #include <vector> 241b7e696bSLukasz Kazmierczak 2507148cf2SLukasz Kazmierczak namespace redfish 2607148cf2SLukasz Kazmierczak { 2707148cf2SLukasz Kazmierczak namespace telemetry 2807148cf2SLukasz Kazmierczak { 2907148cf2SLukasz Kazmierczak constexpr const char* triggerInterface = 3007148cf2SLukasz Kazmierczak "xyz.openbmc_project.Telemetry.Trigger"; 3107148cf2SLukasz Kazmierczak 321b7e696bSLukasz Kazmierczak using NumericThresholdParams = 331b7e696bSLukasz Kazmierczak std::tuple<std::string, uint64_t, std::string, double>; 341b7e696bSLukasz Kazmierczak 351b7e696bSLukasz Kazmierczak using DiscreteThresholdParams = 361b7e696bSLukasz Kazmierczak std::tuple<std::string, std::string, uint64_t, std::string>; 371b7e696bSLukasz Kazmierczak 38*dd1c4a9cSSzymon Dompke using TriggerThresholdParams = 39*dd1c4a9cSSzymon Dompke std::variant<std::vector<NumericThresholdParams>, 40*dd1c4a9cSSzymon Dompke std::vector<DiscreteThresholdParams>>; 41*dd1c4a9cSSzymon Dompke 421b7e696bSLukasz Kazmierczak using TriggerThresholdParamsExt = 431b7e696bSLukasz Kazmierczak std::variant<std::monostate, std::vector<NumericThresholdParams>, 441b7e696bSLukasz Kazmierczak std::vector<DiscreteThresholdParams>>; 451b7e696bSLukasz Kazmierczak 461b7e696bSLukasz Kazmierczak using TriggerSensorsParams = 471b7e696bSLukasz Kazmierczak std::vector<std::pair<sdbusplus::message::object_path, std::string>>; 481b7e696bSLukasz Kazmierczak 491b7e696bSLukasz Kazmierczak using TriggerGetParamsVariant = 501b7e696bSLukasz Kazmierczak std::variant<std::monostate, bool, std::string, TriggerThresholdParamsExt, 513f215c92SSzymon Dompke TriggerSensorsParams, std::vector<std::string>, 523f215c92SSzymon Dompke std::vector<sdbusplus::message::object_path>>; 531b7e696bSLukasz Kazmierczak 54*dd1c4a9cSSzymon Dompke inline triggers::TriggerActionEnum 55*dd1c4a9cSSzymon Dompke toRedfishTriggerAction(std::string_view dbusValue) 561b7e696bSLukasz Kazmierczak { 57*dd1c4a9cSSzymon Dompke if (dbusValue == 58*dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport") 591b7e696bSLukasz Kazmierczak { 60*dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::RedfishMetricReport; 611b7e696bSLukasz Kazmierczak } 62*dd1c4a9cSSzymon Dompke if (dbusValue == 63*dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog") 641b7e696bSLukasz Kazmierczak { 65*dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::RedfishEvent; 661b7e696bSLukasz Kazmierczak } 67*dd1c4a9cSSzymon Dompke if (dbusValue == 68*dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal") 691b7e696bSLukasz Kazmierczak { 70*dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::LogToLogService; 711b7e696bSLukasz Kazmierczak } 72*dd1c4a9cSSzymon Dompke return triggers::TriggerActionEnum::Invalid; 731b7e696bSLukasz Kazmierczak } 741b7e696bSLukasz Kazmierczak 75*dd1c4a9cSSzymon Dompke inline std::string toDbusTriggerAction(std::string_view redfishValue) 761b7e696bSLukasz Kazmierczak { 77*dd1c4a9cSSzymon Dompke if (redfishValue == "RedfishMetricReport") 781b7e696bSLukasz Kazmierczak { 79*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.UpdateReport"; 80*dd1c4a9cSSzymon Dompke } 81*dd1c4a9cSSzymon Dompke if (redfishValue == "RedfishEvent") 82*dd1c4a9cSSzymon Dompke { 83*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToRedfishEventLog"; 84*dd1c4a9cSSzymon Dompke } 85*dd1c4a9cSSzymon Dompke if (redfishValue == "LogToLogService") 86*dd1c4a9cSSzymon Dompke { 87*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.TriggerAction.LogToJournal"; 88*dd1c4a9cSSzymon Dompke } 89*dd1c4a9cSSzymon Dompke return ""; 90*dd1c4a9cSSzymon Dompke } 911b7e696bSLukasz Kazmierczak 92*dd1c4a9cSSzymon Dompke inline std::string toDbusSeverity(std::string_view redfishValue) 93*dd1c4a9cSSzymon Dompke { 94*dd1c4a9cSSzymon Dompke if (redfishValue == "OK") 95*dd1c4a9cSSzymon Dompke { 96*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.OK"; 97*dd1c4a9cSSzymon Dompke } 98*dd1c4a9cSSzymon Dompke if (redfishValue == "Warning") 99*dd1c4a9cSSzymon Dompke { 100*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning"; 101*dd1c4a9cSSzymon Dompke } 102*dd1c4a9cSSzymon Dompke if (redfishValue == "Critical") 103*dd1c4a9cSSzymon Dompke { 104*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical"; 105*dd1c4a9cSSzymon Dompke } 106*dd1c4a9cSSzymon Dompke return ""; 107*dd1c4a9cSSzymon Dompke } 108*dd1c4a9cSSzymon Dompke 109*dd1c4a9cSSzymon Dompke inline resource::Health toRedfishSeverity(std::string_view dbusValue) 110*dd1c4a9cSSzymon Dompke { 111*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.OK") 112*dd1c4a9cSSzymon Dompke { 113*dd1c4a9cSSzymon Dompke return resource::Health::OK; 114*dd1c4a9cSSzymon Dompke } 115*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Warning") 116*dd1c4a9cSSzymon Dompke { 117*dd1c4a9cSSzymon Dompke return resource::Health::Warning; 118*dd1c4a9cSSzymon Dompke } 119*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Severity.Critical") 120*dd1c4a9cSSzymon Dompke { 121*dd1c4a9cSSzymon Dompke return resource::Health::Critical; 122*dd1c4a9cSSzymon Dompke } 123*dd1c4a9cSSzymon Dompke return resource::Health::Invalid; 124*dd1c4a9cSSzymon Dompke } 125*dd1c4a9cSSzymon Dompke 126*dd1c4a9cSSzymon Dompke inline std::string toDbusThresholdName(std::string_view redfishValue) 127*dd1c4a9cSSzymon Dompke { 128*dd1c4a9cSSzymon Dompke if (redfishValue == "UpperCritical") 129*dd1c4a9cSSzymon Dompke { 130*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical"; 131*dd1c4a9cSSzymon Dompke } 132*dd1c4a9cSSzymon Dompke 133*dd1c4a9cSSzymon Dompke if (redfishValue == "LowerCritical") 134*dd1c4a9cSSzymon Dompke { 135*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical"; 136*dd1c4a9cSSzymon Dompke } 137*dd1c4a9cSSzymon Dompke 138*dd1c4a9cSSzymon Dompke if (redfishValue == "UpperWarning") 139*dd1c4a9cSSzymon Dompke { 140*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning"; 141*dd1c4a9cSSzymon Dompke } 142*dd1c4a9cSSzymon Dompke 143*dd1c4a9cSSzymon Dompke if (redfishValue == "LowerWarning") 144*dd1c4a9cSSzymon Dompke { 145*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning"; 146*dd1c4a9cSSzymon Dompke } 147*dd1c4a9cSSzymon Dompke 148*dd1c4a9cSSzymon Dompke return ""; 149*dd1c4a9cSSzymon Dompke } 150*dd1c4a9cSSzymon Dompke 151*dd1c4a9cSSzymon Dompke inline std::string toRedfishThresholdName(std::string_view dbusValue) 152*dd1c4a9cSSzymon Dompke { 153*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperCritical") 154*dd1c4a9cSSzymon Dompke { 155*dd1c4a9cSSzymon Dompke return "UpperCritical"; 156*dd1c4a9cSSzymon Dompke } 157*dd1c4a9cSSzymon Dompke 158*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerCritical") 159*dd1c4a9cSSzymon Dompke { 160*dd1c4a9cSSzymon Dompke return "LowerCritical"; 161*dd1c4a9cSSzymon Dompke } 162*dd1c4a9cSSzymon Dompke 163*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.UpperWarning") 164*dd1c4a9cSSzymon Dompke { 165*dd1c4a9cSSzymon Dompke return "UpperWarning"; 166*dd1c4a9cSSzymon Dompke } 167*dd1c4a9cSSzymon Dompke 168*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Type.LowerWarning") 169*dd1c4a9cSSzymon Dompke { 170*dd1c4a9cSSzymon Dompke return "LowerWarning"; 171*dd1c4a9cSSzymon Dompke } 172*dd1c4a9cSSzymon Dompke 173*dd1c4a9cSSzymon Dompke return ""; 174*dd1c4a9cSSzymon Dompke } 175*dd1c4a9cSSzymon Dompke 176*dd1c4a9cSSzymon Dompke inline std::string toDbusActivation(std::string_view redfishValue) 177*dd1c4a9cSSzymon Dompke { 178*dd1c4a9cSSzymon Dompke if (redfishValue == "Either") 179*dd1c4a9cSSzymon Dompke { 180*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Either"; 181*dd1c4a9cSSzymon Dompke } 182*dd1c4a9cSSzymon Dompke 183*dd1c4a9cSSzymon Dompke if (redfishValue == "Decreasing") 184*dd1c4a9cSSzymon Dompke { 185*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing"; 186*dd1c4a9cSSzymon Dompke } 187*dd1c4a9cSSzymon Dompke 188*dd1c4a9cSSzymon Dompke if (redfishValue == "Increasing") 189*dd1c4a9cSSzymon Dompke { 190*dd1c4a9cSSzymon Dompke return "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing"; 191*dd1c4a9cSSzymon Dompke } 192*dd1c4a9cSSzymon Dompke 193*dd1c4a9cSSzymon Dompke return ""; 194*dd1c4a9cSSzymon Dompke } 195*dd1c4a9cSSzymon Dompke 196*dd1c4a9cSSzymon Dompke inline triggers::ThresholdActivation 197*dd1c4a9cSSzymon Dompke toRedfishActivation(std::string_view dbusValue) 198*dd1c4a9cSSzymon Dompke { 199*dd1c4a9cSSzymon Dompke if (dbusValue == "xyz.openbmc_project.Telemetry.Trigger.Direction.Either") 200*dd1c4a9cSSzymon Dompke { 201*dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Either; 202*dd1c4a9cSSzymon Dompke } 203*dd1c4a9cSSzymon Dompke 204*dd1c4a9cSSzymon Dompke if (dbusValue == 205*dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.Direction.Decreasing") 206*dd1c4a9cSSzymon Dompke { 207*dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Decreasing; 208*dd1c4a9cSSzymon Dompke } 209*dd1c4a9cSSzymon Dompke 210*dd1c4a9cSSzymon Dompke if (dbusValue == 211*dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.Trigger.Direction.Increasing") 212*dd1c4a9cSSzymon Dompke { 213*dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Increasing; 214*dd1c4a9cSSzymon Dompke } 215*dd1c4a9cSSzymon Dompke 216*dd1c4a9cSSzymon Dompke return triggers::ThresholdActivation::Invalid; 217*dd1c4a9cSSzymon Dompke } 218*dd1c4a9cSSzymon Dompke 219*dd1c4a9cSSzymon Dompke enum class MetricType 220*dd1c4a9cSSzymon Dompke { 221*dd1c4a9cSSzymon Dompke Discrete, 222*dd1c4a9cSSzymon Dompke Numeric 223*dd1c4a9cSSzymon Dompke }; 224*dd1c4a9cSSzymon Dompke 225*dd1c4a9cSSzymon Dompke enum class DiscreteCondition 226*dd1c4a9cSSzymon Dompke { 227*dd1c4a9cSSzymon Dompke Specified, 228*dd1c4a9cSSzymon Dompke Changed 229*dd1c4a9cSSzymon Dompke }; 230*dd1c4a9cSSzymon Dompke 231*dd1c4a9cSSzymon Dompke struct Context 232*dd1c4a9cSSzymon Dompke { 233*dd1c4a9cSSzymon Dompke std::string id; 234*dd1c4a9cSSzymon Dompke std::string name; 235*dd1c4a9cSSzymon Dompke std::vector<std::string> actions; 236*dd1c4a9cSSzymon Dompke std::vector<std::pair<sdbusplus::message::object_path, std::string>> 237*dd1c4a9cSSzymon Dompke sensors; 238*dd1c4a9cSSzymon Dompke std::vector<sdbusplus::message::object_path> reports; 239*dd1c4a9cSSzymon Dompke TriggerThresholdParams thresholds; 240*dd1c4a9cSSzymon Dompke 241*dd1c4a9cSSzymon Dompke std::optional<DiscreteCondition> discreteCondition; 242*dd1c4a9cSSzymon Dompke std::optional<MetricType> metricType; 243*dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> metricProperties; 244*dd1c4a9cSSzymon Dompke }; 245*dd1c4a9cSSzymon Dompke 246*dd1c4a9cSSzymon Dompke inline std::optional<sdbusplus::message::object_path> 247*dd1c4a9cSSzymon Dompke getReportPathFromReportDefinitionUri(const std::string& uri) 248*dd1c4a9cSSzymon Dompke { 249*dd1c4a9cSSzymon Dompke boost::urls::result<boost::urls::url_view> parsed = 250*dd1c4a9cSSzymon Dompke boost::urls::parse_relative_ref(uri); 251*dd1c4a9cSSzymon Dompke 252*dd1c4a9cSSzymon Dompke if (!parsed) 2531b7e696bSLukasz Kazmierczak { 2541b7e696bSLukasz Kazmierczak return std::nullopt; 2551b7e696bSLukasz Kazmierczak } 2561b7e696bSLukasz Kazmierczak 257*dd1c4a9cSSzymon Dompke std::string id; 258*dd1c4a9cSSzymon Dompke if (!crow::utility::readUrlSegments( 259*dd1c4a9cSSzymon Dompke *parsed, "redfish", "v1", "TelemetryService", 260*dd1c4a9cSSzymon Dompke "MetricReportDefinitions", std::ref(id))) 261*dd1c4a9cSSzymon Dompke { 262*dd1c4a9cSSzymon Dompke return std::nullopt; 2631b7e696bSLukasz Kazmierczak } 2641b7e696bSLukasz Kazmierczak 265*dd1c4a9cSSzymon Dompke return sdbusplus::message::object_path( 266*dd1c4a9cSSzymon Dompke "/xyz/openbmc_project/Telemetry/Reports") / 267*dd1c4a9cSSzymon Dompke "TelemetryService" / id; 268*dd1c4a9cSSzymon Dompke } 269*dd1c4a9cSSzymon Dompke 270*dd1c4a9cSSzymon Dompke inline std::optional<MetricType> getMetricType(const std::string& metricType) 271*dd1c4a9cSSzymon Dompke { 272*dd1c4a9cSSzymon Dompke if (metricType == "Discrete") 273*dd1c4a9cSSzymon Dompke { 274*dd1c4a9cSSzymon Dompke return MetricType::Discrete; 275*dd1c4a9cSSzymon Dompke } 276*dd1c4a9cSSzymon Dompke if (metricType == "Numeric") 277*dd1c4a9cSSzymon Dompke { 278*dd1c4a9cSSzymon Dompke return MetricType::Numeric; 279*dd1c4a9cSSzymon Dompke } 280*dd1c4a9cSSzymon Dompke return std::nullopt; 281*dd1c4a9cSSzymon Dompke } 282*dd1c4a9cSSzymon Dompke 283*dd1c4a9cSSzymon Dompke inline std::optional<DiscreteCondition> 284*dd1c4a9cSSzymon Dompke getDiscreteCondition(const std::string& discreteTriggerCondition) 285*dd1c4a9cSSzymon Dompke { 286*dd1c4a9cSSzymon Dompke if (discreteTriggerCondition == "Specified") 287*dd1c4a9cSSzymon Dompke { 288*dd1c4a9cSSzymon Dompke return DiscreteCondition::Specified; 289*dd1c4a9cSSzymon Dompke } 290*dd1c4a9cSSzymon Dompke if (discreteTriggerCondition == "Changed") 291*dd1c4a9cSSzymon Dompke { 292*dd1c4a9cSSzymon Dompke return DiscreteCondition::Changed; 293*dd1c4a9cSSzymon Dompke } 294*dd1c4a9cSSzymon Dompke return std::nullopt; 295*dd1c4a9cSSzymon Dompke } 296*dd1c4a9cSSzymon Dompke 297*dd1c4a9cSSzymon Dompke inline bool parseNumericThresholds(crow::Response& res, 298*dd1c4a9cSSzymon Dompke nlohmann::json& numericThresholds, 299*dd1c4a9cSSzymon Dompke Context& ctx) 300*dd1c4a9cSSzymon Dompke { 301*dd1c4a9cSSzymon Dompke nlohmann::json::object_t* obj = 302*dd1c4a9cSSzymon Dompke numericThresholds.get_ptr<nlohmann::json::object_t*>(); 303*dd1c4a9cSSzymon Dompke if (obj == nullptr) 304*dd1c4a9cSSzymon Dompke { 305*dd1c4a9cSSzymon Dompke messages::propertyValueTypeError(res, numericThresholds.dump(), 306*dd1c4a9cSSzymon Dompke "NumericThresholds"); 307*dd1c4a9cSSzymon Dompke return false; 308*dd1c4a9cSSzymon Dompke } 309*dd1c4a9cSSzymon Dompke 310*dd1c4a9cSSzymon Dompke std::vector<NumericThresholdParams> parsedParams; 311*dd1c4a9cSSzymon Dompke parsedParams.reserve(numericThresholds.size()); 312*dd1c4a9cSSzymon Dompke 313*dd1c4a9cSSzymon Dompke for (auto& key : *obj) 314*dd1c4a9cSSzymon Dompke { 315*dd1c4a9cSSzymon Dompke std::string dbusThresholdName = toDbusThresholdName(key.first); 316*dd1c4a9cSSzymon Dompke if (dbusThresholdName.empty()) 317*dd1c4a9cSSzymon Dompke { 318*dd1c4a9cSSzymon Dompke messages::propertyUnknown(res, key.first); 319*dd1c4a9cSSzymon Dompke return false; 320*dd1c4a9cSSzymon Dompke } 321*dd1c4a9cSSzymon Dompke 322*dd1c4a9cSSzymon Dompke double reading = 0.0; 323*dd1c4a9cSSzymon Dompke std::string activation; 324*dd1c4a9cSSzymon Dompke std::string dwellTimeStr; 325*dd1c4a9cSSzymon Dompke 326*dd1c4a9cSSzymon Dompke if (!json_util::readJson(key.second, res, "Reading", reading, 327*dd1c4a9cSSzymon Dompke "Activation", activation, "DwellTime", 328*dd1c4a9cSSzymon Dompke dwellTimeStr)) 329*dd1c4a9cSSzymon Dompke { 330*dd1c4a9cSSzymon Dompke return false; 331*dd1c4a9cSSzymon Dompke } 332*dd1c4a9cSSzymon Dompke 333*dd1c4a9cSSzymon Dompke std::string dbusActivation = toDbusActivation(activation); 334*dd1c4a9cSSzymon Dompke 335*dd1c4a9cSSzymon Dompke if (dbusActivation.empty()) 336*dd1c4a9cSSzymon Dompke { 337*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "Activation", activation); 338*dd1c4a9cSSzymon Dompke return false; 339*dd1c4a9cSSzymon Dompke } 340*dd1c4a9cSSzymon Dompke 341*dd1c4a9cSSzymon Dompke std::optional<std::chrono::milliseconds> dwellTime = 342*dd1c4a9cSSzymon Dompke time_utils::fromDurationString(dwellTimeStr); 343*dd1c4a9cSSzymon Dompke if (!dwellTime) 344*dd1c4a9cSSzymon Dompke { 345*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr); 346*dd1c4a9cSSzymon Dompke return false; 347*dd1c4a9cSSzymon Dompke } 348*dd1c4a9cSSzymon Dompke 349*dd1c4a9cSSzymon Dompke parsedParams.emplace_back(dbusThresholdName, 350*dd1c4a9cSSzymon Dompke static_cast<uint64_t>(dwellTime->count()), 351*dd1c4a9cSSzymon Dompke dbusActivation, reading); 352*dd1c4a9cSSzymon Dompke } 353*dd1c4a9cSSzymon Dompke 354*dd1c4a9cSSzymon Dompke ctx.thresholds = std::move(parsedParams); 355*dd1c4a9cSSzymon Dompke return true; 356*dd1c4a9cSSzymon Dompke } 357*dd1c4a9cSSzymon Dompke 358*dd1c4a9cSSzymon Dompke inline bool parseDiscreteTriggers( 359*dd1c4a9cSSzymon Dompke crow::Response& res, 360*dd1c4a9cSSzymon Dompke std::optional<std::vector<nlohmann::json>>& discreteTriggers, Context& ctx) 361*dd1c4a9cSSzymon Dompke { 362*dd1c4a9cSSzymon Dompke std::vector<DiscreteThresholdParams> parsedParams; 363*dd1c4a9cSSzymon Dompke if (!discreteTriggers) 364*dd1c4a9cSSzymon Dompke { 365*dd1c4a9cSSzymon Dompke ctx.thresholds = std::move(parsedParams); 366*dd1c4a9cSSzymon Dompke return true; 367*dd1c4a9cSSzymon Dompke } 368*dd1c4a9cSSzymon Dompke 369*dd1c4a9cSSzymon Dompke parsedParams.reserve(discreteTriggers->size()); 370*dd1c4a9cSSzymon Dompke for (nlohmann::json& thresholdInfo : *discreteTriggers) 371*dd1c4a9cSSzymon Dompke { 372*dd1c4a9cSSzymon Dompke std::optional<std::string> name = ""; 373*dd1c4a9cSSzymon Dompke std::string value; 374*dd1c4a9cSSzymon Dompke std::string dwellTimeStr; 375*dd1c4a9cSSzymon Dompke std::string severity; 376*dd1c4a9cSSzymon Dompke 377*dd1c4a9cSSzymon Dompke if (!json_util::readJson(thresholdInfo, res, "Name", name, "Value", 378*dd1c4a9cSSzymon Dompke value, "DwellTime", dwellTimeStr, "Severity", 379*dd1c4a9cSSzymon Dompke severity)) 380*dd1c4a9cSSzymon Dompke { 381*dd1c4a9cSSzymon Dompke return false; 382*dd1c4a9cSSzymon Dompke } 383*dd1c4a9cSSzymon Dompke 384*dd1c4a9cSSzymon Dompke std::optional<std::chrono::milliseconds> dwellTime = 385*dd1c4a9cSSzymon Dompke time_utils::fromDurationString(dwellTimeStr); 386*dd1c4a9cSSzymon Dompke if (!dwellTime) 387*dd1c4a9cSSzymon Dompke { 388*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DwellTime", dwellTimeStr); 389*dd1c4a9cSSzymon Dompke return false; 390*dd1c4a9cSSzymon Dompke } 391*dd1c4a9cSSzymon Dompke 392*dd1c4a9cSSzymon Dompke std::string dbusSeverity = toDbusSeverity(severity); 393*dd1c4a9cSSzymon Dompke if (dbusSeverity.empty()) 394*dd1c4a9cSSzymon Dompke { 395*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "Severity", severity); 396*dd1c4a9cSSzymon Dompke return false; 397*dd1c4a9cSSzymon Dompke } 398*dd1c4a9cSSzymon Dompke 399*dd1c4a9cSSzymon Dompke parsedParams.emplace_back(*name, dbusSeverity, 400*dd1c4a9cSSzymon Dompke static_cast<uint64_t>(dwellTime->count()), 401*dd1c4a9cSSzymon Dompke value); 402*dd1c4a9cSSzymon Dompke } 403*dd1c4a9cSSzymon Dompke 404*dd1c4a9cSSzymon Dompke ctx.thresholds = std::move(parsedParams); 405*dd1c4a9cSSzymon Dompke return true; 406*dd1c4a9cSSzymon Dompke } 407*dd1c4a9cSSzymon Dompke 408*dd1c4a9cSSzymon Dompke inline bool parseTriggerThresholds( 409*dd1c4a9cSSzymon Dompke crow::Response& res, 410*dd1c4a9cSSzymon Dompke std::optional<std::vector<nlohmann::json>>& discreteTriggers, 411*dd1c4a9cSSzymon Dompke std::optional<nlohmann::json>& numericThresholds, Context& ctx) 412*dd1c4a9cSSzymon Dompke { 413*dd1c4a9cSSzymon Dompke if (discreteTriggers && numericThresholds) 414*dd1c4a9cSSzymon Dompke { 415*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 416*dd1c4a9cSSzymon Dompke "NumericThresholds"); 417*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds", 418*dd1c4a9cSSzymon Dompke "DiscreteTriggers"); 419*dd1c4a9cSSzymon Dompke return false; 420*dd1c4a9cSSzymon Dompke } 421*dd1c4a9cSSzymon Dompke 422*dd1c4a9cSSzymon Dompke if (ctx.discreteCondition) 423*dd1c4a9cSSzymon Dompke { 424*dd1c4a9cSSzymon Dompke if (numericThresholds) 425*dd1c4a9cSSzymon Dompke { 426*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggerCondition", 427*dd1c4a9cSSzymon Dompke "NumericThresholds"); 428*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds", 429*dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition"); 430*dd1c4a9cSSzymon Dompke return false; 431*dd1c4a9cSSzymon Dompke } 432*dd1c4a9cSSzymon Dompke } 433*dd1c4a9cSSzymon Dompke 434*dd1c4a9cSSzymon Dompke if (ctx.metricType) 435*dd1c4a9cSSzymon Dompke { 436*dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Discrete && numericThresholds) 437*dd1c4a9cSSzymon Dompke { 438*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "NumericThresholds", 439*dd1c4a9cSSzymon Dompke "MetricType"); 440*dd1c4a9cSSzymon Dompke return false; 441*dd1c4a9cSSzymon Dompke } 442*dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Numeric && discreteTriggers) 443*dd1c4a9cSSzymon Dompke { 444*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 445*dd1c4a9cSSzymon Dompke "MetricType"); 446*dd1c4a9cSSzymon Dompke return false; 447*dd1c4a9cSSzymon Dompke } 448*dd1c4a9cSSzymon Dompke if (*ctx.metricType == MetricType::Numeric && ctx.discreteCondition) 449*dd1c4a9cSSzymon Dompke { 450*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 451*dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition"); 452*dd1c4a9cSSzymon Dompke return false; 453*dd1c4a9cSSzymon Dompke } 454*dd1c4a9cSSzymon Dompke } 455*dd1c4a9cSSzymon Dompke 456*dd1c4a9cSSzymon Dompke if (discreteTriggers || ctx.discreteCondition || 457*dd1c4a9cSSzymon Dompke (ctx.metricType && *ctx.metricType == MetricType::Discrete)) 458*dd1c4a9cSSzymon Dompke { 459*dd1c4a9cSSzymon Dompke if (ctx.discreteCondition) 460*dd1c4a9cSSzymon Dompke { 461*dd1c4a9cSSzymon Dompke if (*ctx.discreteCondition == DiscreteCondition::Specified && 462*dd1c4a9cSSzymon Dompke !discreteTriggers) 463*dd1c4a9cSSzymon Dompke { 464*dd1c4a9cSSzymon Dompke messages::createFailedMissingReqProperties(res, 465*dd1c4a9cSSzymon Dompke "DiscreteTriggers"); 466*dd1c4a9cSSzymon Dompke return false; 467*dd1c4a9cSSzymon Dompke } 468*dd1c4a9cSSzymon Dompke if (discreteTriggers && 469*dd1c4a9cSSzymon Dompke ((*ctx.discreteCondition == DiscreteCondition::Specified && 470*dd1c4a9cSSzymon Dompke discreteTriggers->empty()) || 471*dd1c4a9cSSzymon Dompke (*ctx.discreteCondition == DiscreteCondition::Changed && 472*dd1c4a9cSSzymon Dompke !discreteTriggers->empty()))) 473*dd1c4a9cSSzymon Dompke { 474*dd1c4a9cSSzymon Dompke messages::propertyValueConflict(res, "DiscreteTriggers", 475*dd1c4a9cSSzymon Dompke "DiscreteTriggerCondition"); 476*dd1c4a9cSSzymon Dompke return false; 477*dd1c4a9cSSzymon Dompke } 478*dd1c4a9cSSzymon Dompke } 479*dd1c4a9cSSzymon Dompke if (!parseDiscreteTriggers(res, discreteTriggers, ctx)) 480*dd1c4a9cSSzymon Dompke { 481*dd1c4a9cSSzymon Dompke return false; 482*dd1c4a9cSSzymon Dompke } 483*dd1c4a9cSSzymon Dompke } 484*dd1c4a9cSSzymon Dompke else if (numericThresholds) 485*dd1c4a9cSSzymon Dompke { 486*dd1c4a9cSSzymon Dompke if (!parseNumericThresholds(res, *numericThresholds, ctx)) 487*dd1c4a9cSSzymon Dompke { 488*dd1c4a9cSSzymon Dompke return false; 489*dd1c4a9cSSzymon Dompke } 490*dd1c4a9cSSzymon Dompke } 491*dd1c4a9cSSzymon Dompke else 492*dd1c4a9cSSzymon Dompke { 493*dd1c4a9cSSzymon Dompke messages::createFailedMissingReqProperties( 494*dd1c4a9cSSzymon Dompke res, "'DiscreteTriggers', 'NumericThresholds', " 495*dd1c4a9cSSzymon Dompke "'DiscreteTriggerCondition' or 'MetricType'"); 496*dd1c4a9cSSzymon Dompke return false; 497*dd1c4a9cSSzymon Dompke } 498*dd1c4a9cSSzymon Dompke return true; 499*dd1c4a9cSSzymon Dompke } 500*dd1c4a9cSSzymon Dompke 501*dd1c4a9cSSzymon Dompke inline bool parseLinks(crow::Response& res, nlohmann::json& links, Context& ctx) 502*dd1c4a9cSSzymon Dompke { 503*dd1c4a9cSSzymon Dompke if (links.empty()) 504*dd1c4a9cSSzymon Dompke { 505*dd1c4a9cSSzymon Dompke return true; 506*dd1c4a9cSSzymon Dompke } 507*dd1c4a9cSSzymon Dompke 508*dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> metricReportDefinitions; 509*dd1c4a9cSSzymon Dompke if (!json_util::readJson(links, res, "MetricReportDefinitions", 510*dd1c4a9cSSzymon Dompke metricReportDefinitions)) 511*dd1c4a9cSSzymon Dompke { 512*dd1c4a9cSSzymon Dompke return false; 513*dd1c4a9cSSzymon Dompke } 514*dd1c4a9cSSzymon Dompke 515*dd1c4a9cSSzymon Dompke if (metricReportDefinitions) 516*dd1c4a9cSSzymon Dompke { 517*dd1c4a9cSSzymon Dompke ctx.reports.reserve(metricReportDefinitions->size()); 518*dd1c4a9cSSzymon Dompke for (std::string& reportDefinionUri : *metricReportDefinitions) 519*dd1c4a9cSSzymon Dompke { 520*dd1c4a9cSSzymon Dompke std::optional<sdbusplus::message::object_path> reportPath = 521*dd1c4a9cSSzymon Dompke getReportPathFromReportDefinitionUri(reportDefinionUri); 522*dd1c4a9cSSzymon Dompke if (!reportPath) 523*dd1c4a9cSSzymon Dompke { 524*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "MetricReportDefinitions", 525*dd1c4a9cSSzymon Dompke reportDefinionUri); 526*dd1c4a9cSSzymon Dompke return false; 527*dd1c4a9cSSzymon Dompke } 528*dd1c4a9cSSzymon Dompke ctx.reports.emplace_back(*reportPath); 529*dd1c4a9cSSzymon Dompke } 530*dd1c4a9cSSzymon Dompke } 531*dd1c4a9cSSzymon Dompke return true; 532*dd1c4a9cSSzymon Dompke } 533*dd1c4a9cSSzymon Dompke 534*dd1c4a9cSSzymon Dompke inline bool parseMetricProperties(crow::Response& res, Context& ctx) 535*dd1c4a9cSSzymon Dompke { 536*dd1c4a9cSSzymon Dompke if (!ctx.metricProperties) 537*dd1c4a9cSSzymon Dompke { 538*dd1c4a9cSSzymon Dompke return true; 539*dd1c4a9cSSzymon Dompke } 540*dd1c4a9cSSzymon Dompke 541*dd1c4a9cSSzymon Dompke ctx.sensors.reserve(ctx.metricProperties->size()); 542*dd1c4a9cSSzymon Dompke 543*dd1c4a9cSSzymon Dompke size_t uriIdx = 0; 544*dd1c4a9cSSzymon Dompke for (const std::string& uriStr : *ctx.metricProperties) 545*dd1c4a9cSSzymon Dompke { 546*dd1c4a9cSSzymon Dompke boost::urls::result<boost::urls::url_view> uri = 547*dd1c4a9cSSzymon Dompke boost::urls::parse_relative_ref(uriStr); 548*dd1c4a9cSSzymon Dompke if (!uri) 549*dd1c4a9cSSzymon Dompke { 550*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect( 551*dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr); 552*dd1c4a9cSSzymon Dompke return false; 553*dd1c4a9cSSzymon Dompke } 554*dd1c4a9cSSzymon Dompke std::string chassisName; 555*dd1c4a9cSSzymon Dompke std::string sensorName; 556*dd1c4a9cSSzymon Dompke if (!crow::utility::readUrlSegments(*uri, "redfish", "v1", "Chassis", 557*dd1c4a9cSSzymon Dompke std::ref(chassisName), "Sensors", 558*dd1c4a9cSSzymon Dompke std::ref(sensorName))) 559*dd1c4a9cSSzymon Dompke { 560*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect( 561*dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr); 562*dd1c4a9cSSzymon Dompke return false; 563*dd1c4a9cSSzymon Dompke } 564*dd1c4a9cSSzymon Dompke 565*dd1c4a9cSSzymon Dompke std::pair<std::string, std::string> split = 566*dd1c4a9cSSzymon Dompke splitSensorNameAndType(sensorName); 567*dd1c4a9cSSzymon Dompke if (split.first.empty() || split.second.empty()) 568*dd1c4a9cSSzymon Dompke { 569*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect( 570*dd1c4a9cSSzymon Dompke res, "MetricProperties/" + std::to_string(uriIdx), uriStr); 571*dd1c4a9cSSzymon Dompke return false; 572*dd1c4a9cSSzymon Dompke } 573*dd1c4a9cSSzymon Dompke 574*dd1c4a9cSSzymon Dompke std::string sensorPath = "/xyz/openbmc_project/sensors/" + split.first + 575*dd1c4a9cSSzymon Dompke '/' + split.second; 576*dd1c4a9cSSzymon Dompke 577*dd1c4a9cSSzymon Dompke ctx.sensors.emplace_back(sensorPath, uriStr); 578*dd1c4a9cSSzymon Dompke uriIdx++; 579*dd1c4a9cSSzymon Dompke } 580*dd1c4a9cSSzymon Dompke return true; 581*dd1c4a9cSSzymon Dompke } 582*dd1c4a9cSSzymon Dompke 583*dd1c4a9cSSzymon Dompke inline bool parsePostTriggerParams(crow::Response& res, 584*dd1c4a9cSSzymon Dompke const crow::Request& req, Context& ctx) 585*dd1c4a9cSSzymon Dompke { 586*dd1c4a9cSSzymon Dompke std::optional<std::string> id = ""; 587*dd1c4a9cSSzymon Dompke std::optional<std::string> name = ""; 588*dd1c4a9cSSzymon Dompke std::optional<std::string> metricType; 589*dd1c4a9cSSzymon Dompke std::optional<std::vector<std::string>> triggerActions; 590*dd1c4a9cSSzymon Dompke std::optional<std::string> discreteTriggerCondition; 591*dd1c4a9cSSzymon Dompke std::optional<std::vector<nlohmann::json>> discreteTriggers; 592*dd1c4a9cSSzymon Dompke std::optional<nlohmann::json> numericThresholds; 593*dd1c4a9cSSzymon Dompke std::optional<nlohmann::json> links; 594*dd1c4a9cSSzymon Dompke if (!json_util::readJsonPatch( 595*dd1c4a9cSSzymon Dompke req, res, "Id", id, "Name", name, "MetricType", metricType, 596*dd1c4a9cSSzymon Dompke "TriggerActions", triggerActions, "DiscreteTriggerCondition", 597*dd1c4a9cSSzymon Dompke discreteTriggerCondition, "DiscreteTriggers", discreteTriggers, 598*dd1c4a9cSSzymon Dompke "NumericThresholds", numericThresholds, "MetricProperties", 599*dd1c4a9cSSzymon Dompke ctx.metricProperties, "Links", links)) 600*dd1c4a9cSSzymon Dompke { 601*dd1c4a9cSSzymon Dompke return false; 602*dd1c4a9cSSzymon Dompke } 603*dd1c4a9cSSzymon Dompke 604*dd1c4a9cSSzymon Dompke ctx.id = *id; 605*dd1c4a9cSSzymon Dompke ctx.name = *name; 606*dd1c4a9cSSzymon Dompke 607*dd1c4a9cSSzymon Dompke if (metricType) 608*dd1c4a9cSSzymon Dompke { 609*dd1c4a9cSSzymon Dompke if (!(ctx.metricType = getMetricType(*metricType))) 610*dd1c4a9cSSzymon Dompke { 611*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "MetricType", *metricType); 612*dd1c4a9cSSzymon Dompke return false; 613*dd1c4a9cSSzymon Dompke } 614*dd1c4a9cSSzymon Dompke } 615*dd1c4a9cSSzymon Dompke 616*dd1c4a9cSSzymon Dompke if (discreteTriggerCondition) 617*dd1c4a9cSSzymon Dompke { 618*dd1c4a9cSSzymon Dompke if (!(ctx.discreteCondition = 619*dd1c4a9cSSzymon Dompke getDiscreteCondition(*discreteTriggerCondition))) 620*dd1c4a9cSSzymon Dompke { 621*dd1c4a9cSSzymon Dompke messages::propertyValueIncorrect(res, "DiscreteTriggerCondition", 622*dd1c4a9cSSzymon Dompke *discreteTriggerCondition); 623*dd1c4a9cSSzymon Dompke return false; 624*dd1c4a9cSSzymon Dompke } 625*dd1c4a9cSSzymon Dompke } 626*dd1c4a9cSSzymon Dompke 627*dd1c4a9cSSzymon Dompke if (triggerActions) 628*dd1c4a9cSSzymon Dompke { 629*dd1c4a9cSSzymon Dompke ctx.actions.reserve(triggerActions->size()); 630*dd1c4a9cSSzymon Dompke for (const std::string& action : *triggerActions) 631*dd1c4a9cSSzymon Dompke { 632*dd1c4a9cSSzymon Dompke std::string dbusAction = toDbusTriggerAction(action); 633*dd1c4a9cSSzymon Dompke 634*dd1c4a9cSSzymon Dompke if (dbusAction.empty()) 635*dd1c4a9cSSzymon Dompke { 636*dd1c4a9cSSzymon Dompke messages::propertyValueNotInList(res, action, "TriggerActions"); 637*dd1c4a9cSSzymon Dompke return false; 638*dd1c4a9cSSzymon Dompke } 639*dd1c4a9cSSzymon Dompke 640*dd1c4a9cSSzymon Dompke ctx.actions.emplace_back(dbusAction); 641*dd1c4a9cSSzymon Dompke } 642*dd1c4a9cSSzymon Dompke } 643*dd1c4a9cSSzymon Dompke if (!parseMetricProperties(res, ctx)) 644*dd1c4a9cSSzymon Dompke { 645*dd1c4a9cSSzymon Dompke return false; 646*dd1c4a9cSSzymon Dompke } 647*dd1c4a9cSSzymon Dompke 648*dd1c4a9cSSzymon Dompke if (!parseTriggerThresholds(res, discreteTriggers, numericThresholds, ctx)) 649*dd1c4a9cSSzymon Dompke { 650*dd1c4a9cSSzymon Dompke return false; 651*dd1c4a9cSSzymon Dompke } 652*dd1c4a9cSSzymon Dompke 653*dd1c4a9cSSzymon Dompke if (links) 654*dd1c4a9cSSzymon Dompke { 655*dd1c4a9cSSzymon Dompke if (!parseLinks(res, *links, ctx)) 656*dd1c4a9cSSzymon Dompke { 657*dd1c4a9cSSzymon Dompke return false; 658*dd1c4a9cSSzymon Dompke } 659*dd1c4a9cSSzymon Dompke } 660*dd1c4a9cSSzymon Dompke return true; 661*dd1c4a9cSSzymon Dompke } 662*dd1c4a9cSSzymon Dompke 663*dd1c4a9cSSzymon Dompke inline void afterCreateTrigger( 664*dd1c4a9cSSzymon Dompke const boost::system::error_code& ec, const std::string& dbusPath, 665*dd1c4a9cSSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id) 666*dd1c4a9cSSzymon Dompke { 667*dd1c4a9cSSzymon Dompke if (ec == boost::system::errc::file_exists) 668*dd1c4a9cSSzymon Dompke { 669*dd1c4a9cSSzymon Dompke messages::resourceAlreadyExists(asyncResp->res, "Trigger", "Id", id); 670*dd1c4a9cSSzymon Dompke return; 671*dd1c4a9cSSzymon Dompke } 672*dd1c4a9cSSzymon Dompke if (ec == boost::system::errc::too_many_files_open) 673*dd1c4a9cSSzymon Dompke { 674*dd1c4a9cSSzymon Dompke messages::createLimitReachedForResource(asyncResp->res); 675*dd1c4a9cSSzymon Dompke return; 676*dd1c4a9cSSzymon Dompke } 677*dd1c4a9cSSzymon Dompke if (ec) 678*dd1c4a9cSSzymon Dompke { 679*dd1c4a9cSSzymon Dompke messages::internalError(asyncResp->res); 680*dd1c4a9cSSzymon Dompke BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 681*dd1c4a9cSSzymon Dompke return; 682*dd1c4a9cSSzymon Dompke } 683*dd1c4a9cSSzymon Dompke 684*dd1c4a9cSSzymon Dompke const std::optional<std::string>& triggerId = 685*dd1c4a9cSSzymon Dompke getTriggerIdFromDbusPath(dbusPath); 686*dd1c4a9cSSzymon Dompke if (!triggerId) 687*dd1c4a9cSSzymon Dompke { 688*dd1c4a9cSSzymon Dompke messages::internalError(asyncResp->res); 689*dd1c4a9cSSzymon Dompke BMCWEB_LOG_ERROR << "Unknown data returned by " 690*dd1c4a9cSSzymon Dompke "AddTrigger DBus method"; 691*dd1c4a9cSSzymon Dompke return; 692*dd1c4a9cSSzymon Dompke } 693*dd1c4a9cSSzymon Dompke 694*dd1c4a9cSSzymon Dompke messages::created(asyncResp->res); 695*dd1c4a9cSSzymon Dompke boost::urls::url locationUrl = boost::urls::format( 696*dd1c4a9cSSzymon Dompke "/redfish/v1/TelemetryService/Triggers/{}", *triggerId); 697*dd1c4a9cSSzymon Dompke asyncResp->res.addHeader("Location", locationUrl.buffer()); 698*dd1c4a9cSSzymon Dompke } 699*dd1c4a9cSSzymon Dompke 700*dd1c4a9cSSzymon Dompke inline std::optional<nlohmann::json::array_t> 701*dd1c4a9cSSzymon Dompke getTriggerActions(const std::vector<std::string>& dbusActions) 702*dd1c4a9cSSzymon Dompke { 703*dd1c4a9cSSzymon Dompke nlohmann::json::array_t triggerActions; 704*dd1c4a9cSSzymon Dompke for (const std::string& dbusAction : dbusActions) 705*dd1c4a9cSSzymon Dompke { 706*dd1c4a9cSSzymon Dompke triggers::TriggerActionEnum redfishAction = 707*dd1c4a9cSSzymon Dompke toRedfishTriggerAction(dbusAction); 708*dd1c4a9cSSzymon Dompke 709*dd1c4a9cSSzymon Dompke if (redfishAction == triggers::TriggerActionEnum::Invalid) 710*dd1c4a9cSSzymon Dompke { 711*dd1c4a9cSSzymon Dompke return std::nullopt; 712*dd1c4a9cSSzymon Dompke } 713*dd1c4a9cSSzymon Dompke 714*dd1c4a9cSSzymon Dompke triggerActions.emplace_back(redfishAction); 715*dd1c4a9cSSzymon Dompke } 716*dd1c4a9cSSzymon Dompke 717*dd1c4a9cSSzymon Dompke return triggerActions; 7181b7e696bSLukasz Kazmierczak } 7191b7e696bSLukasz Kazmierczak 7203f215c92SSzymon Dompke inline std::optional<nlohmann::json::array_t> 7211b7e696bSLukasz Kazmierczak getDiscreteTriggers(const TriggerThresholdParamsExt& thresholdParams) 7221b7e696bSLukasz Kazmierczak { 723*dd1c4a9cSSzymon Dompke nlohmann::json::array_t triggers; 7241b7e696bSLukasz Kazmierczak const std::vector<DiscreteThresholdParams>* discreteParams = 7251b7e696bSLukasz Kazmierczak std::get_if<std::vector<DiscreteThresholdParams>>(&thresholdParams); 7261b7e696bSLukasz Kazmierczak 727e662eae8SEd Tanous if (discreteParams == nullptr) 7281b7e696bSLukasz Kazmierczak { 7291b7e696bSLukasz Kazmierczak return std::nullopt; 7301b7e696bSLukasz Kazmierczak } 7311b7e696bSLukasz Kazmierczak 7321b7e696bSLukasz Kazmierczak for (const auto& [name, severity, dwellTime, value] : *discreteParams) 7331b7e696bSLukasz Kazmierczak { 7341b7e696bSLukasz Kazmierczak std::optional<std::string> duration = 7351b7e696bSLukasz Kazmierczak time_utils::toDurationStringFromUint(dwellTime); 7361b7e696bSLukasz Kazmierczak 7371b7e696bSLukasz Kazmierczak if (!duration) 7381b7e696bSLukasz Kazmierczak { 7391b7e696bSLukasz Kazmierczak return std::nullopt; 7401b7e696bSLukasz Kazmierczak } 741613dabeaSEd Tanous nlohmann::json::object_t trigger; 742613dabeaSEd Tanous trigger["Name"] = name; 743*dd1c4a9cSSzymon Dompke trigger["Severity"] = toRedfishSeverity(severity); 744613dabeaSEd Tanous trigger["DwellTime"] = *duration; 745613dabeaSEd Tanous trigger["Value"] = value; 746ad539545SPatrick Williams triggers.emplace_back(std::move(trigger)); 7471b7e696bSLukasz Kazmierczak } 7481b7e696bSLukasz Kazmierczak 749*dd1c4a9cSSzymon Dompke return triggers; 7501b7e696bSLukasz Kazmierczak } 7511b7e696bSLukasz Kazmierczak 7521b7e696bSLukasz Kazmierczak inline std::optional<nlohmann::json> 7531b7e696bSLukasz Kazmierczak getNumericThresholds(const TriggerThresholdParamsExt& thresholdParams) 7541b7e696bSLukasz Kazmierczak { 755*dd1c4a9cSSzymon Dompke nlohmann::json::object_t thresholds; 7561b7e696bSLukasz Kazmierczak const std::vector<NumericThresholdParams>* numericParams = 7571b7e696bSLukasz Kazmierczak std::get_if<std::vector<NumericThresholdParams>>(&thresholdParams); 7581b7e696bSLukasz Kazmierczak 759e662eae8SEd Tanous if (numericParams == nullptr) 7601b7e696bSLukasz Kazmierczak { 7611b7e696bSLukasz Kazmierczak return std::nullopt; 7621b7e696bSLukasz Kazmierczak } 7631b7e696bSLukasz Kazmierczak 7641b7e696bSLukasz Kazmierczak for (const auto& [type, dwellTime, activation, reading] : *numericParams) 7651b7e696bSLukasz Kazmierczak { 7661b7e696bSLukasz Kazmierczak std::optional<std::string> duration = 7671b7e696bSLukasz Kazmierczak time_utils::toDurationStringFromUint(dwellTime); 7681b7e696bSLukasz Kazmierczak 7691b7e696bSLukasz Kazmierczak if (!duration) 7701b7e696bSLukasz Kazmierczak { 7711b7e696bSLukasz Kazmierczak return std::nullopt; 7721b7e696bSLukasz Kazmierczak } 773*dd1c4a9cSSzymon Dompke nlohmann::json& threshold = thresholds[toRedfishThresholdName(type)]; 7741476687dSEd Tanous threshold["Reading"] = reading; 775*dd1c4a9cSSzymon Dompke threshold["Activation"] = toRedfishActivation(activation); 7761476687dSEd Tanous threshold["DwellTime"] = *duration; 7771b7e696bSLukasz Kazmierczak } 7781b7e696bSLukasz Kazmierczak 779*dd1c4a9cSSzymon Dompke return thresholds; 7801b7e696bSLukasz Kazmierczak } 7811b7e696bSLukasz Kazmierczak 7823f215c92SSzymon Dompke inline std::optional<nlohmann::json> getMetricReportDefinitions( 7833f215c92SSzymon Dompke const std::vector<sdbusplus::message::object_path>& reportPaths) 7841b7e696bSLukasz Kazmierczak { 7851b7e696bSLukasz Kazmierczak nlohmann::json reports = nlohmann::json::array(); 7863f215c92SSzymon Dompke 7873f215c92SSzymon Dompke for (const sdbusplus::message::object_path& path : reportPaths) 7881b7e696bSLukasz Kazmierczak { 7893f215c92SSzymon Dompke std::string reportId = path.filename(); 7903f215c92SSzymon Dompke if (reportId.empty()) 7913f215c92SSzymon Dompke { 7923f215c92SSzymon Dompke { 7933f215c92SSzymon Dompke BMCWEB_LOG_ERROR << "Property Reports contains invalid value: " 7943f215c92SSzymon Dompke << path.str; 7953f215c92SSzymon Dompke return std::nullopt; 7963f215c92SSzymon Dompke } 7973f215c92SSzymon Dompke } 7983f215c92SSzymon Dompke 7991476687dSEd Tanous nlohmann::json::object_t report; 800ef4c65b7SEd Tanous report["@odata.id"] = boost::urls::format( 801ef4c65b7SEd Tanous "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", 802ef4c65b7SEd Tanous reportId); 803b2ba3072SPatrick Williams reports.emplace_back(std::move(report)); 8041b7e696bSLukasz Kazmierczak } 8051b7e696bSLukasz Kazmierczak 8063f215c92SSzymon Dompke return {std::move(reports)}; 8071b7e696bSLukasz Kazmierczak } 8081b7e696bSLukasz Kazmierczak 8091b7e696bSLukasz Kazmierczak inline std::vector<std::string> 8101b7e696bSLukasz Kazmierczak getMetricProperties(const TriggerSensorsParams& sensors) 8111b7e696bSLukasz Kazmierczak { 8121b7e696bSLukasz Kazmierczak std::vector<std::string> metricProperties; 8131b7e696bSLukasz Kazmierczak metricProperties.reserve(sensors.size()); 8141b7e696bSLukasz Kazmierczak for (const auto& [_, metadata] : sensors) 8151b7e696bSLukasz Kazmierczak { 8161b7e696bSLukasz Kazmierczak metricProperties.emplace_back(metadata); 8171b7e696bSLukasz Kazmierczak } 8181b7e696bSLukasz Kazmierczak 8191b7e696bSLukasz Kazmierczak return metricProperties; 8201b7e696bSLukasz Kazmierczak } 8211b7e696bSLukasz Kazmierczak 8221b7e696bSLukasz Kazmierczak inline bool fillTrigger( 8231b7e696bSLukasz Kazmierczak nlohmann::json& json, const std::string& id, 8241b7e696bSLukasz Kazmierczak const std::vector<std::pair<std::string, TriggerGetParamsVariant>>& 8251b7e696bSLukasz Kazmierczak properties) 8261b7e696bSLukasz Kazmierczak { 8271b7e696bSLukasz Kazmierczak const std::string* name = nullptr; 8281b7e696bSLukasz Kazmierczak const bool* discrete = nullptr; 8291b7e696bSLukasz Kazmierczak const TriggerSensorsParams* sensors = nullptr; 8303f215c92SSzymon Dompke const std::vector<sdbusplus::message::object_path>* reports = nullptr; 83189474494SKrzysztof Grobelny const std::vector<std::string>* triggerActions = nullptr; 8321b7e696bSLukasz Kazmierczak const TriggerThresholdParamsExt* thresholds = nullptr; 8331b7e696bSLukasz Kazmierczak 83489474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 83589474494SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "Name", name, "Discrete", 83689474494SKrzysztof Grobelny discrete, "Sensors", sensors, "Reports", reports, "TriggerActions", 83789474494SKrzysztof Grobelny triggerActions, "Thresholds", thresholds); 83889474494SKrzysztof Grobelny 83989474494SKrzysztof Grobelny if (!success) 8401b7e696bSLukasz Kazmierczak { 84189474494SKrzysztof Grobelny return false; 8421b7e696bSLukasz Kazmierczak } 8431b7e696bSLukasz Kazmierczak 84489474494SKrzysztof Grobelny if (triggerActions != nullptr) 84589474494SKrzysztof Grobelny { 846*dd1c4a9cSSzymon Dompke std::optional<nlohmann::json::array_t> redfishTriggerActions = 84789474494SKrzysztof Grobelny getTriggerActions(*triggerActions); 84889474494SKrzysztof Grobelny if (!redfishTriggerActions) 8491b7e696bSLukasz Kazmierczak { 8501b7e696bSLukasz Kazmierczak BMCWEB_LOG_ERROR 85189474494SKrzysztof Grobelny << "Property TriggerActions is invalid in Trigger: " << id; 8521b7e696bSLukasz Kazmierczak return false; 8531b7e696bSLukasz Kazmierczak } 854*dd1c4a9cSSzymon Dompke json["TriggerActions"] = *redfishTriggerActions; 85589474494SKrzysztof Grobelny } 8561b7e696bSLukasz Kazmierczak 85789474494SKrzysztof Grobelny if (reports != nullptr) 8583f215c92SSzymon Dompke { 8593f215c92SSzymon Dompke std::optional<nlohmann::json> linkedReports = 8603f215c92SSzymon Dompke getMetricReportDefinitions(*reports); 8613f215c92SSzymon Dompke if (!linkedReports) 8623f215c92SSzymon Dompke { 86389474494SKrzysztof Grobelny BMCWEB_LOG_ERROR << "Property Reports is invalid in Trigger: " 86489474494SKrzysztof Grobelny << id; 8653f215c92SSzymon Dompke return false; 8663f215c92SSzymon Dompke } 86789474494SKrzysztof Grobelny json["Links"]["MetricReportDefinitions"] = *linkedReports; 86889474494SKrzysztof Grobelny } 8691b7e696bSLukasz Kazmierczak 87089474494SKrzysztof Grobelny if (discrete != nullptr) 87189474494SKrzysztof Grobelny { 8721b7e696bSLukasz Kazmierczak if (*discrete) 8731b7e696bSLukasz Kazmierczak { 8743f215c92SSzymon Dompke std::optional<nlohmann::json::array_t> discreteTriggers = 8751b7e696bSLukasz Kazmierczak getDiscreteTriggers(*thresholds); 8761b7e696bSLukasz Kazmierczak 8771b7e696bSLukasz Kazmierczak if (!discreteTriggers) 8781b7e696bSLukasz Kazmierczak { 87989474494SKrzysztof Grobelny BMCWEB_LOG_ERROR 88089474494SKrzysztof Grobelny << "Property Thresholds is invalid for discrete " 8811b7e696bSLukasz Kazmierczak "triggers in Trigger: " 8821b7e696bSLukasz Kazmierczak << id; 8831b7e696bSLukasz Kazmierczak return false; 8841b7e696bSLukasz Kazmierczak } 8851b7e696bSLukasz Kazmierczak 8861b7e696bSLukasz Kazmierczak json["DiscreteTriggers"] = *discreteTriggers; 8871b7e696bSLukasz Kazmierczak json["DiscreteTriggerCondition"] = 8881b7e696bSLukasz Kazmierczak discreteTriggers->empty() ? "Changed" : "Specified"; 8891b7e696bSLukasz Kazmierczak json["MetricType"] = "Discrete"; 8901b7e696bSLukasz Kazmierczak } 8911b7e696bSLukasz Kazmierczak else 8921b7e696bSLukasz Kazmierczak { 8931b7e696bSLukasz Kazmierczak std::optional<nlohmann::json> numericThresholds = 8941b7e696bSLukasz Kazmierczak getNumericThresholds(*thresholds); 8951b7e696bSLukasz Kazmierczak 8961b7e696bSLukasz Kazmierczak if (!numericThresholds) 8971b7e696bSLukasz Kazmierczak { 89889474494SKrzysztof Grobelny BMCWEB_LOG_ERROR 89989474494SKrzysztof Grobelny << "Property Thresholds is invalid for numeric " 9001b7e696bSLukasz Kazmierczak "thresholds in Trigger: " 9011b7e696bSLukasz Kazmierczak << id; 9021b7e696bSLukasz Kazmierczak return false; 9031b7e696bSLukasz Kazmierczak } 9041b7e696bSLukasz Kazmierczak 9051b7e696bSLukasz Kazmierczak json["NumericThresholds"] = *numericThresholds; 9061b7e696bSLukasz Kazmierczak json["MetricType"] = "Numeric"; 9071b7e696bSLukasz Kazmierczak } 90889474494SKrzysztof Grobelny } 90989474494SKrzysztof Grobelny 91089474494SKrzysztof Grobelny if (name != nullptr) 91189474494SKrzysztof Grobelny { 91289474494SKrzysztof Grobelny json["Name"] = *name; 91389474494SKrzysztof Grobelny } 91489474494SKrzysztof Grobelny 91589474494SKrzysztof Grobelny if (sensors != nullptr) 91689474494SKrzysztof Grobelny { 91789474494SKrzysztof Grobelny json["MetricProperties"] = getMetricProperties(*sensors); 91889474494SKrzysztof Grobelny } 9191b7e696bSLukasz Kazmierczak 9203f215c92SSzymon Dompke json["@odata.type"] = "#Triggers.v1_2_0.Triggers"; 921ef4c65b7SEd Tanous json["@odata.id"] = 922ef4c65b7SEd Tanous boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id); 9233f215c92SSzymon Dompke json["Id"] = id; 9241b7e696bSLukasz Kazmierczak 9251b7e696bSLukasz Kazmierczak return true; 9261b7e696bSLukasz Kazmierczak } 9271b7e696bSLukasz Kazmierczak 928*dd1c4a9cSSzymon Dompke inline void handleTriggerCollectionPost( 929*dd1c4a9cSSzymon Dompke App& app, const crow::Request& req, 930*dd1c4a9cSSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 931*dd1c4a9cSSzymon Dompke { 932*dd1c4a9cSSzymon Dompke if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 933*dd1c4a9cSSzymon Dompke { 934*dd1c4a9cSSzymon Dompke return; 935*dd1c4a9cSSzymon Dompke } 936*dd1c4a9cSSzymon Dompke 937*dd1c4a9cSSzymon Dompke telemetry::Context ctx; 938*dd1c4a9cSSzymon Dompke if (!telemetry::parsePostTriggerParams(asyncResp->res, req, ctx)) 939*dd1c4a9cSSzymon Dompke { 940*dd1c4a9cSSzymon Dompke return; 941*dd1c4a9cSSzymon Dompke } 942*dd1c4a9cSSzymon Dompke 943*dd1c4a9cSSzymon Dompke crow::connections::systemBus->async_method_call( 944*dd1c4a9cSSzymon Dompke [asyncResp, id = ctx.id](const boost::system::error_code& ec, 945*dd1c4a9cSSzymon Dompke const std::string& dbusPath) { 946*dd1c4a9cSSzymon Dompke afterCreateTrigger(ec, dbusPath, asyncResp, id); 947*dd1c4a9cSSzymon Dompke }, 948*dd1c4a9cSSzymon Dompke service, "/xyz/openbmc_project/Telemetry/Triggers", 949*dd1c4a9cSSzymon Dompke "xyz.openbmc_project.Telemetry.TriggerManager", "AddTrigger", 950*dd1c4a9cSSzymon Dompke "TelemetryService/" + ctx.id, ctx.name, ctx.actions, ctx.sensors, 951*dd1c4a9cSSzymon Dompke ctx.reports, ctx.thresholds); 952*dd1c4a9cSSzymon Dompke } 953*dd1c4a9cSSzymon Dompke 95407148cf2SLukasz Kazmierczak } // namespace telemetry 95507148cf2SLukasz Kazmierczak 95607148cf2SLukasz Kazmierczak inline void requestRoutesTriggerCollection(App& app) 95707148cf2SLukasz Kazmierczak { 95807148cf2SLukasz Kazmierczak BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/") 95907148cf2SLukasz Kazmierczak .privileges(redfish::privileges::getTriggersCollection) 96007148cf2SLukasz Kazmierczak .methods(boost::beast::http::verb::get)( 96145ca1b86SEd Tanous [&app](const crow::Request& req, 96207148cf2SLukasz Kazmierczak const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 9633ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 96445ca1b86SEd Tanous { 96545ca1b86SEd Tanous return; 96645ca1b86SEd Tanous } 96707148cf2SLukasz Kazmierczak asyncResp->res.jsonValue["@odata.type"] = 96807148cf2SLukasz Kazmierczak "#TriggersCollection.TriggersCollection"; 969ae9031f0SWilly Tu asyncResp->res.jsonValue["@odata.id"] = 970ae9031f0SWilly Tu "/redfish/v1/TelemetryService/Triggers"; 97107148cf2SLukasz Kazmierczak asyncResp->res.jsonValue["Name"] = "Triggers Collection"; 9727a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 9737a1dbc48SGeorge Liu telemetry::triggerInterface}; 97407148cf2SLukasz Kazmierczak collection_util::getCollectionMembers( 975ae9031f0SWilly Tu asyncResp, 976ae9031f0SWilly Tu boost::urls::url("/redfish/v1/TelemetryService/Triggers"), 977ae9031f0SWilly Tu interfaces, 97807148cf2SLukasz Kazmierczak "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService"); 97907148cf2SLukasz Kazmierczak }); 980*dd1c4a9cSSzymon Dompke 981*dd1c4a9cSSzymon Dompke BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/") 982*dd1c4a9cSSzymon Dompke .privileges(redfish::privileges::postTriggersCollection) 983*dd1c4a9cSSzymon Dompke .methods(boost::beast::http::verb::post)(std::bind_front( 984*dd1c4a9cSSzymon Dompke telemetry::handleTriggerCollectionPost, std::ref(app))); 98507148cf2SLukasz Kazmierczak } 98607148cf2SLukasz Kazmierczak 9871b7e696bSLukasz Kazmierczak inline void requestRoutesTrigger(App& app) 9881b7e696bSLukasz Kazmierczak { 9891b7e696bSLukasz Kazmierczak BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/") 9901b7e696bSLukasz Kazmierczak .privileges(redfish::privileges::getTriggers) 9911b7e696bSLukasz Kazmierczak .methods(boost::beast::http::verb::get)( 99245ca1b86SEd Tanous [&app](const crow::Request& req, 9931b7e696bSLukasz Kazmierczak const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 9941b7e696bSLukasz Kazmierczak const std::string& id) { 9953ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 99645ca1b86SEd Tanous { 99745ca1b86SEd Tanous return; 99845ca1b86SEd Tanous } 99989474494SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 100089474494SKrzysztof Grobelny *crow::connections::systemBus, telemetry::service, 100189474494SKrzysztof Grobelny telemetry::getDbusTriggerPath(id), telemetry::triggerInterface, 10021b7e696bSLukasz Kazmierczak [asyncResp, 10035e7e2dc5SEd Tanous id](const boost::system::error_code& ec, 10041b7e696bSLukasz Kazmierczak const std::vector<std::pair< 1005002d39b4SEd Tanous std::string, telemetry::TriggerGetParamsVariant>>& ret) { 10061b7e696bSLukasz Kazmierczak if (ec.value() == EBADR || 10071b7e696bSLukasz Kazmierczak ec == boost::system::errc::host_unreachable) 10081b7e696bSLukasz Kazmierczak { 1009002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "Triggers", id); 10101b7e696bSLukasz Kazmierczak return; 10111b7e696bSLukasz Kazmierczak } 10121b7e696bSLukasz Kazmierczak if (ec) 10131b7e696bSLukasz Kazmierczak { 10141b7e696bSLukasz Kazmierczak BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 10151b7e696bSLukasz Kazmierczak messages::internalError(asyncResp->res); 10161b7e696bSLukasz Kazmierczak return; 10171b7e696bSLukasz Kazmierczak } 10181b7e696bSLukasz Kazmierczak 1019002d39b4SEd Tanous if (!telemetry::fillTrigger(asyncResp->res.jsonValue, id, ret)) 10201b7e696bSLukasz Kazmierczak { 10211b7e696bSLukasz Kazmierczak messages::internalError(asyncResp->res); 10221b7e696bSLukasz Kazmierczak } 102389474494SKrzysztof Grobelny }); 10241b7e696bSLukasz Kazmierczak }); 1025163994a8SSzymon Dompke 1026163994a8SSzymon Dompke BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/Triggers/<str>/") 1027163994a8SSzymon Dompke .privileges(redfish::privileges::deleteTriggers) 1028163994a8SSzymon Dompke .methods(boost::beast::http::verb::delete_)( 102945ca1b86SEd Tanous [&app](const crow::Request& req, 1030163994a8SSzymon Dompke const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1031163994a8SSzymon Dompke const std::string& id) { 10323ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 103345ca1b86SEd Tanous { 103445ca1b86SEd Tanous return; 103545ca1b86SEd Tanous } 1036002d39b4SEd Tanous const std::string triggerPath = telemetry::getDbusTriggerPath(id); 1037163994a8SSzymon Dompke 1038163994a8SSzymon Dompke crow::connections::systemBus->async_method_call( 10395e7e2dc5SEd Tanous [asyncResp, id](const boost::system::error_code& ec) { 1040163994a8SSzymon Dompke if (ec.value() == EBADR) 1041163994a8SSzymon Dompke { 1042002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "Triggers", id); 1043163994a8SSzymon Dompke return; 1044163994a8SSzymon Dompke } 1045163994a8SSzymon Dompke 1046163994a8SSzymon Dompke if (ec) 1047163994a8SSzymon Dompke { 1048163994a8SSzymon Dompke BMCWEB_LOG_ERROR << "respHandler DBus error " << ec; 1049163994a8SSzymon Dompke messages::internalError(asyncResp->res); 1050163994a8SSzymon Dompke return; 1051163994a8SSzymon Dompke } 1052163994a8SSzymon Dompke 1053002d39b4SEd Tanous asyncResp->res.result(boost::beast::http::status::no_content); 1054163994a8SSzymon Dompke }, 1055163994a8SSzymon Dompke telemetry::service, triggerPath, 1056163994a8SSzymon Dompke "xyz.openbmc_project.Object.Delete", "Delete"); 1057163994a8SSzymon Dompke }); 10581b7e696bSLukasz Kazmierczak } 10591b7e696bSLukasz Kazmierczak 106007148cf2SLukasz Kazmierczak } // namespace redfish 1061