1 #include "trigger_factory.hpp" 2 3 #include "discrete_threshold.hpp" 4 #include "numeric_threshold.hpp" 5 #include "on_change_threshold.hpp" 6 #include "sensor.hpp" 7 #include "trigger.hpp" 8 #include "trigger_actions.hpp" 9 #include "utils/dbus_mapper.hpp" 10 11 TriggerFactory::TriggerFactory( 12 std::shared_ptr<sdbusplus::asio::connection> bus, 13 std::shared_ptr<sdbusplus::asio::object_server> objServer, 14 SensorCache& sensorCache, interfaces::ReportManager& reportManager) : 15 bus(std::move(bus)), 16 objServer(std::move(objServer)), sensorCache(sensorCache), 17 reportManager(reportManager) 18 {} 19 20 std::unique_ptr<interfaces::Trigger> 21 TriggerFactory::make(boost::asio::yield_context& yield, 22 const std::string& name, bool isDiscrete, 23 bool logToJournal, bool logToRedfish, 24 bool updateReport, const TriggerSensors& sensorPaths, 25 const std::vector<std::string>& reportNames, 26 const TriggerThresholdParams& thresholdParams, 27 interfaces::TriggerManager& triggerManager, 28 interfaces::JsonStorage& triggerStorage) const 29 { 30 auto [sensors, sensorNames] = getSensors(yield, sensorPaths); 31 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds; 32 33 if (isDiscrete) 34 { 35 const auto& params = 36 std::get<std::vector<discrete::ThresholdParam>>(thresholdParams); 37 for (const auto& [thresholdName, severityStr, dwellTime, 38 thresholdValue] : params) 39 { 40 discrete::Severity severity = 41 discrete::stringToSeverity(severityStr); 42 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 43 if (logToJournal) 44 { 45 actions.emplace_back( 46 std::make_unique<action::discrete::LogToJournal>(severity)); 47 } 48 if (logToRedfish) 49 { 50 actions.emplace_back( 51 std::make_unique<action::discrete::LogToRedfish>(severity)); 52 } 53 if (updateReport) 54 { 55 actions.emplace_back(std::make_unique<action::UpdateReport>( 56 reportManager, reportNames)); 57 } 58 59 thresholds.emplace_back(std::make_shared<DiscreteThreshold>( 60 bus->get_io_context(), sensors, sensorNames, std::move(actions), 61 std::chrono::milliseconds(dwellTime), thresholdValue, 62 thresholdName)); 63 } 64 if (params.empty()) 65 { 66 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 67 if (logToJournal) 68 { 69 actions.emplace_back( 70 std::make_unique< 71 action::discrete::onChange::LogToJournal>()); 72 } 73 if (logToRedfish) 74 { 75 actions.emplace_back( 76 std::make_unique< 77 action::discrete::onChange::LogToRedfish>()); 78 } 79 if (updateReport) 80 { 81 actions.emplace_back(std::make_unique<action::UpdateReport>( 82 reportManager, reportNames)); 83 } 84 85 thresholds.emplace_back(std::make_shared<OnChangeThreshold>( 86 sensors, sensorNames, std::move(actions))); 87 } 88 } 89 else 90 { 91 const auto& params = 92 std::get<std::vector<numeric::ThresholdParam>>(thresholdParams); 93 for (const auto& [typeStr, dwellTime, directionStr, value] : params) 94 { 95 numeric::Type type = numeric::stringToType(typeStr); 96 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 97 if (logToJournal) 98 { 99 actions.emplace_back( 100 std::make_unique<action::numeric::LogToJournal>(type, 101 value)); 102 } 103 if (logToRedfish) 104 { 105 actions.emplace_back( 106 std::make_unique<action::numeric::LogToRedfish>(type, 107 value)); 108 } 109 if (updateReport) 110 { 111 actions.emplace_back(std::make_unique<action::UpdateReport>( 112 reportManager, reportNames)); 113 } 114 115 thresholds.emplace_back(std::make_shared<NumericThreshold>( 116 bus->get_io_context(), sensors, sensorNames, std::move(actions), 117 std::chrono::milliseconds(dwellTime), 118 numeric::stringToDirection(directionStr), value)); 119 } 120 } 121 122 return std::make_unique<Trigger>( 123 bus->get_io_context(), objServer, name, isDiscrete, logToJournal, 124 logToRedfish, updateReport, sensorPaths, reportNames, thresholdParams, 125 std::move(thresholds), triggerManager, triggerStorage); 126 } 127 128 std::pair<std::vector<std::shared_ptr<interfaces::Sensor>>, 129 std::vector<std::string>> 130 TriggerFactory::getSensors( 131 boost::asio::yield_context& yield, 132 const std::vector<std::pair<sdbusplus::message::object_path, 133 std::string>>& sensorPaths) const 134 { 135 auto tree = utils::getSubTreeSensors(yield, bus); 136 137 std::vector<std::shared_ptr<interfaces::Sensor>> sensors; 138 std::vector<std::string> sensorNames; 139 for (const auto& [sensorPath, metadata] : sensorPaths) 140 { 141 auto found = std::find_if( 142 tree.begin(), tree.end(), 143 [&sensorPath](const auto& x) { return x.first == sensorPath; }); 144 if (found == tree.end()) 145 { 146 throw std::runtime_error("Not found"); 147 } 148 149 const auto& service = found->second[0].first; 150 const auto& path = found->first; 151 sensors.emplace_back(sensorCache.makeSensor<Sensor>( 152 service, path, bus->get_io_context(), bus)); 153 if (metadata.empty()) 154 { 155 sensorNames.emplace_back(sensorPath); 156 } 157 else 158 { 159 sensorNames.emplace_back(metadata); 160 } 161 } 162 return {sensors, sensorNames}; 163 } 164