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 #include "utils/transform.hpp" 11 12 namespace ts = utils::tstring; 13 14 TriggerFactory::TriggerFactory( 15 std::shared_ptr<sdbusplus::asio::connection> bus, 16 std::shared_ptr<sdbusplus::asio::object_server> objServer, 17 SensorCache& sensorCache, interfaces::ReportManager& reportManager) : 18 bus(std::move(bus)), 19 objServer(std::move(objServer)), sensorCache(sensorCache), 20 reportManager(reportManager) 21 {} 22 23 std::unique_ptr<interfaces::Trigger> TriggerFactory::make( 24 const std::string& name, bool isDiscrete, bool logToJournal, 25 bool logToRedfish, bool updateReport, 26 const std::vector<std::string>& reportNames, 27 interfaces::TriggerManager& triggerManager, 28 interfaces::JsonStorage& triggerStorage, 29 const LabeledTriggerThresholdParams& labeledThresholdParams, 30 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const 31 { 32 const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo); 33 std::vector<std::shared_ptr<interfaces::Threshold>> thresholds; 34 35 if (isDiscrete) 36 { 37 const auto& labeledDiscreteThresholdParams = 38 std::get<std::vector<discrete::LabeledThresholdParam>>( 39 labeledThresholdParams); 40 for (const auto& labeledThresholdParam : labeledDiscreteThresholdParams) 41 { 42 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 43 44 std::string thresholdName = 45 labeledThresholdParam.at_label<ts::UserId>(); 46 discrete::Severity severity = 47 labeledThresholdParam.at_label<ts::Severity>(); 48 std::chrono::milliseconds dwellTime = std::chrono::milliseconds( 49 labeledThresholdParam.at_label<ts::DwellTime>()); 50 double thresholdValue = 51 labeledThresholdParam.at_label<ts::ThresholdValue>(); 52 53 if (logToJournal) 54 { 55 actions.emplace_back( 56 std::make_unique<action::discrete::LogToJournal>(severity)); 57 } 58 if (logToRedfish) 59 { 60 actions.emplace_back( 61 std::make_unique<action::discrete::LogToRedfish>(severity)); 62 } 63 if (updateReport) 64 { 65 actions.emplace_back(std::make_unique<action::UpdateReport>( 66 reportManager, reportNames)); 67 } 68 69 thresholds.emplace_back(std::make_shared<DiscreteThreshold>( 70 bus->get_io_context(), sensors, sensorNames, std::move(actions), 71 std::chrono::milliseconds(dwellTime), thresholdValue, 72 thresholdName)); 73 } 74 if (labeledDiscreteThresholdParams.empty()) 75 { 76 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 77 if (logToJournal) 78 { 79 actions.emplace_back( 80 std::make_unique< 81 action::discrete::onChange::LogToJournal>()); 82 } 83 if (logToRedfish) 84 { 85 actions.emplace_back( 86 std::make_unique< 87 action::discrete::onChange::LogToRedfish>()); 88 } 89 if (updateReport) 90 { 91 actions.emplace_back(std::make_unique<action::UpdateReport>( 92 reportManager, reportNames)); 93 } 94 95 thresholds.emplace_back(std::make_shared<OnChangeThreshold>( 96 sensors, sensorNames, std::move(actions))); 97 } 98 } 99 else 100 { 101 const auto& labeledNumericThresholdParams = 102 std::get<std::vector<numeric::LabeledThresholdParam>>( 103 labeledThresholdParams); 104 105 for (const auto& labeledThresholdParam : labeledNumericThresholdParams) 106 { 107 std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 108 auto type = labeledThresholdParam.at_label<ts::Type>(); 109 auto dwellTime = std::chrono::milliseconds( 110 labeledThresholdParam.at_label<ts::DwellTime>()); 111 auto direction = labeledThresholdParam.at_label<ts::Direction>(); 112 auto thresholdValue = 113 double{labeledThresholdParam.at_label<ts::ThresholdValue>()}; 114 115 if (logToJournal) 116 { 117 actions.emplace_back( 118 std::make_unique<action::numeric::LogToJournal>( 119 type, thresholdValue)); 120 } 121 122 if (logToRedfish) 123 { 124 actions.emplace_back( 125 std::make_unique<action::numeric::LogToRedfish>( 126 type, thresholdValue)); 127 } 128 129 if (updateReport) 130 { 131 actions.emplace_back(std::make_unique<action::UpdateReport>( 132 reportManager, reportNames)); 133 } 134 135 thresholds.emplace_back(std::make_shared<NumericThreshold>( 136 bus->get_io_context(), sensors, sensorNames, std::move(actions), 137 dwellTime, direction, thresholdValue)); 138 } 139 } 140 141 return std::make_unique<Trigger>( 142 bus->get_io_context(), objServer, name, isDiscrete, logToJournal, 143 logToRedfish, updateReport, reportNames, labeledSensorsInfo, 144 labeledThresholdParams, std::move(thresholds), triggerManager, 145 triggerStorage); 146 } 147 148 std::pair<std::vector<std::shared_ptr<interfaces::Sensor>>, 149 std::vector<std::string>> 150 TriggerFactory::getSensors( 151 const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const 152 { 153 std::vector<std::shared_ptr<interfaces::Sensor>> sensors; 154 std::vector<std::string> sensorNames; 155 156 for (const auto& labeledSensorInfo : labeledSensorsInfo) 157 { 158 const auto& service = labeledSensorInfo.at_label<ts::Service>(); 159 const auto& sensorPath = labeledSensorInfo.at_label<ts::SensorPath>(); 160 const auto& metadata = labeledSensorInfo.at_label<ts::SensorMetadata>(); 161 162 sensors.emplace_back(sensorCache.makeSensor<Sensor>( 163 service, sensorPath, bus->get_io_context(), bus)); 164 165 if (metadata.empty()) 166 { 167 sensorNames.emplace_back(sensorPath); 168 } 169 else 170 { 171 sensorNames.emplace_back(metadata); 172 } 173 } 174 175 return {sensors, sensorNames}; 176 } 177 178 std::vector<LabeledSensorInfo> 179 TriggerFactory::getLabeledSensorsInfo(boost::asio::yield_context& yield, 180 const SensorsInfo& sensorsInfo) const 181 { 182 auto tree = utils::getSubTreeSensors(yield, bus); 183 184 return utils::transform(sensorsInfo, [&tree](const auto& item) { 185 const auto& [sensorPath, metadata] = item; 186 auto found = std::find_if( 187 tree.begin(), tree.end(), 188 [&sensorPath](const auto& x) { return x.first == sensorPath; }); 189 190 if (tree.end() != found) 191 { 192 const auto& [service, ifaces] = found->second.front(); 193 return LabeledSensorInfo(service, sensorPath, metadata); 194 } 195 throw std::runtime_error("Not found"); 196 }); 197 } 198