1 #include "trigger.hpp" 2 3 #include "interfaces/types.hpp" 4 #include "utils/transform.hpp" 5 6 #include <phosphor-logging/log.hpp> 7 8 template <class... Ts> 9 struct overloaded : Ts... 10 { 11 using Ts::operator()...; 12 }; 13 template <class... Ts> 14 overloaded(Ts...) -> overloaded<Ts...>; 15 16 Trigger::Trigger( 17 boost::asio::io_context& ioc, 18 const std::shared_ptr<sdbusplus::asio::object_server>& objServer, 19 const std::string& nameIn, const bool isDiscreteIn, 20 const bool logToJournalIn, const bool logToRedfishIn, 21 const bool updateReportIn, const TriggerSensors& sensorsIn, 22 const std::vector<std::string>& reportNamesIn, 23 const TriggerThresholdParams& thresholdParamsIn, 24 std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn, 25 interfaces::TriggerManager& triggerManager, 26 interfaces::JsonStorage& triggerStorageIn) : 27 name(nameIn), 28 isDiscrete(isDiscreteIn), logToJournal(logToJournalIn), 29 logToRedfish(logToRedfishIn), updateReport(updateReportIn), 30 path(triggerDir + name), sensors(sensorsIn), reportNames(reportNamesIn), 31 thresholdParams(thresholdParamsIn), thresholds(std::move(thresholdsIn)), 32 fileName(std::to_string(std::hash<std::string>{}(name))), 33 triggerStorage(triggerStorageIn) 34 { 35 deleteIface = objServer->add_unique_interface( 36 path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) { 37 dbusIface.register_method("Delete", [this, &ioc, &triggerManager] { 38 if (persistent) 39 { 40 triggerStorage.remove(fileName); 41 } 42 boost::asio::post(ioc, [this, &triggerManager] { 43 triggerManager.removeTrigger(this); 44 }); 45 }); 46 }); 47 48 triggerIface = objServer->add_unique_interface( 49 path, triggerIfaceName, 50 [this, isDiscreteIn, logToJournalIn, logToRedfishIn, 51 updateReportIn](auto& dbusIface) { 52 persistent = storeConfiguration(); 53 dbusIface.register_property_rw( 54 "Persistent", persistent, 55 sdbusplus::vtable::property_::emits_change, 56 [this](bool newVal, const auto&) { 57 if (newVal == persistent) 58 { 59 return true; 60 } 61 if (newVal) 62 { 63 persistent = storeConfiguration(); 64 } 65 else 66 { 67 triggerStorage.remove(fileName); 68 persistent = false; 69 } 70 return true; 71 }, 72 [this](const auto&) { return persistent; }); 73 74 dbusIface.register_property_r( 75 "Thresholds", thresholdParams, 76 sdbusplus::vtable::property_::emits_change, 77 [](const auto& x) { return x; }); 78 dbusIface.register_property_r( 79 "Sensors", sensors, sdbusplus::vtable::property_::emits_change, 80 [](const auto& x) { return x; }); 81 dbusIface.register_property_r( 82 "ReportNames", reportNames, 83 sdbusplus::vtable::property_::emits_change, 84 [](const auto& x) { return x; }); 85 dbusIface.register_property_r("Discrete", isDiscrete, 86 sdbusplus::vtable::property_::const_, 87 [](const auto& x) { return x; }); 88 dbusIface.register_property_r("LogToJournal", logToJournal, 89 sdbusplus::vtable::property_::const_, 90 [](const auto& x) { return x; }); 91 dbusIface.register_property_r("LogToRedfish", logToRedfish, 92 sdbusplus::vtable::property_::const_, 93 [](const auto& x) { return x; }); 94 dbusIface.register_property_r("UpdateReport", updateReport, 95 sdbusplus::vtable::property_::const_, 96 [](const auto& x) { return x; }); 97 }); 98 99 for (const auto& threshold : thresholds) 100 { 101 threshold->initialize(); 102 } 103 } 104 105 bool Trigger::storeConfiguration() const 106 { 107 try 108 { 109 nlohmann::json data; 110 111 data["Version"] = triggerVersion; 112 data["Name"] = name; 113 data["ThresholdParamsDiscriminator"] = thresholdParams.index(); 114 data["IsDiscrete"] = isDiscrete; 115 data["LogToJournal"] = logToJournal; 116 data["LogToRedfish"] = logToRedfish; 117 data["UpdateReport"] = updateReport; 118 119 std::visit( 120 overloaded{ 121 [&](const std::vector<numeric::ThresholdParam>& arg) { 122 data["ThresholdParams"] = 123 utils::transform(arg, [](const auto& thresholdParam) { 124 const auto& [type, dwellTime, direction, 125 thresholdValue] = thresholdParam; 126 return numeric::LabeledThresholdParam( 127 numeric::stringToType(type), dwellTime, 128 numeric::stringToDirection(direction), 129 thresholdValue); 130 }); 131 }, 132 [&](const std::vector<discrete::ThresholdParam>& arg) { 133 data["ThresholdParams"] = 134 utils::transform(arg, [](const auto& thresholdParam) { 135 const auto& [userId, severity, dwellTime, 136 thresholdValue] = thresholdParam; 137 return discrete::LabeledThresholdParam( 138 userId, discrete::stringToSeverity(severity), 139 dwellTime, thresholdValue); 140 }); 141 }, 142 }, 143 thresholdParams); 144 145 data["ReportNames"] = reportNames; 146 147 data["Sensors"] = utils::transform(sensors, [](const auto& sensor) { 148 const auto& [sensorPath, sensorMetadata] = sensor; 149 return LabeledTriggerSensor(sensorPath, sensorMetadata); 150 }); 151 152 triggerStorage.store(fileName, data); 153 } 154 catch (const std::exception& e) 155 { 156 phosphor::logging::log<phosphor::logging::level::ERR>( 157 "Failed to store a trigger in storage", 158 phosphor::logging::entry("EXCEPTION_MSG=%s", e.what())); 159 return false; 160 } 161 return true; 162 }