176833cb5SWludzik, Jozef #include "trigger_manager.hpp" 276833cb5SWludzik, Jozef 34416fce6SCezary Zwolak #include "trigger.hpp" 4dcc4e193SKrzysztof Grobelny #include "types/trigger_types.hpp" 54416fce6SCezary Zwolak #include "utils/conversion_trigger.hpp" 6b8cc78ddSKrzysztof Grobelny #include "utils/generate_id.hpp" 74416fce6SCezary Zwolak #include "utils/transform.hpp" 84416fce6SCezary Zwolak 94416fce6SCezary Zwolak #include <phosphor-logging/log.hpp> 104416fce6SCezary Zwolak 1176833cb5SWludzik, Jozef TriggerManager::TriggerManager( 1276833cb5SWludzik, Jozef std::unique_ptr<interfaces::TriggerFactory> triggerFactoryIn, 13a4e67616SCezary Zwolak std::unique_ptr<interfaces::JsonStorage> triggerStorageIn, 1476833cb5SWludzik, Jozef const std::shared_ptr<sdbusplus::asio::object_server>& objServer) : 15a4e67616SCezary Zwolak triggerFactory(std::move(triggerFactoryIn)), 16a4e67616SCezary Zwolak triggerStorage(std::move(triggerStorageIn)) 1776833cb5SWludzik, Jozef { 184416fce6SCezary Zwolak loadFromPersistent(); 194416fce6SCezary Zwolak 2076833cb5SWludzik, Jozef managerIface = objServer->add_unique_interface( 2176833cb5SWludzik, Jozef triggerManagerPath, triggerManagerIfaceName, [this](auto& iface) { 2276833cb5SWludzik, Jozef iface.register_method( 2376833cb5SWludzik, Jozef "AddTrigger", 24e28aa53dSSzymon Dompke [this](boost::asio::yield_context& yield, const std::string& id, 252001301aSSzymon Dompke const std::string& name, 262001301aSSzymon Dompke const std::vector<std::string>& triggerActions, 274416fce6SCezary Zwolak const SensorsInfo& sensors, 28b8cc78ddSKrzysztof Grobelny const std::vector<std::string>& reportIds, 294416fce6SCezary Zwolak const TriggerThresholdParamsExt& thresholds) { 304416fce6SCezary Zwolak LabeledTriggerThresholdParams 314416fce6SCezary Zwolak labeledTriggerThresholdParams = std::visit( 324416fce6SCezary Zwolak utils::ToLabeledThresholdParamConversion(), 334416fce6SCezary Zwolak thresholds); 3476833cb5SWludzik, Jozef 354416fce6SCezary Zwolak std::vector<LabeledSensorInfo> labeledSensorsInfo = 364416fce6SCezary Zwolak triggerFactory->getLabeledSensorsInfo(yield, sensors); 3776833cb5SWludzik, Jozef 38e28aa53dSSzymon Dompke return addTrigger(id, name, triggerActions, 39b8cc78ddSKrzysztof Grobelny labeledSensorsInfo, reportIds, 404416fce6SCezary Zwolak labeledTriggerThresholdParams) 414416fce6SCezary Zwolak .getPath(); 4276833cb5SWludzik, Jozef }); 4376833cb5SWludzik, Jozef }); 4476833cb5SWludzik, Jozef } 4576833cb5SWludzik, Jozef 4676833cb5SWludzik, Jozef void TriggerManager::removeTrigger(const interfaces::Trigger* trigger) 4776833cb5SWludzik, Jozef { 4876833cb5SWludzik, Jozef triggers.erase( 4976833cb5SWludzik, Jozef std::remove_if(triggers.begin(), triggers.end(), 5076833cb5SWludzik, Jozef [trigger](const auto& x) { return trigger == x.get(); }), 5176833cb5SWludzik, Jozef triggers.end()); 5276833cb5SWludzik, Jozef } 534416fce6SCezary Zwolak 54e28aa53dSSzymon Dompke void TriggerManager::verifyAddTrigger(const std::string& triggerId, 55e28aa53dSSzymon Dompke const std::string& triggerName) const 564416fce6SCezary Zwolak { 574416fce6SCezary Zwolak if (triggers.size() >= maxTriggers) 584416fce6SCezary Zwolak { 594416fce6SCezary Zwolak throw sdbusplus::exception::SdBusError( 604416fce6SCezary Zwolak static_cast<int>(std::errc::too_many_files_open), 614416fce6SCezary Zwolak "Reached maximal trigger count"); 624416fce6SCezary Zwolak } 634416fce6SCezary Zwolak 64b8cc78ddSKrzysztof Grobelny utils::verifyIdCharacters(triggerId); 65e28aa53dSSzymon Dompke 664416fce6SCezary Zwolak for (const auto& trigger : triggers) 674416fce6SCezary Zwolak { 68e28aa53dSSzymon Dompke if (trigger->getId() == triggerId) 694416fce6SCezary Zwolak { 704416fce6SCezary Zwolak throw sdbusplus::exception::SdBusError( 714416fce6SCezary Zwolak static_cast<int>(std::errc::file_exists), "Duplicate trigger"); 724416fce6SCezary Zwolak } 734416fce6SCezary Zwolak } 744416fce6SCezary Zwolak } 754416fce6SCezary Zwolak 764416fce6SCezary Zwolak interfaces::Trigger& TriggerManager::addTrigger( 77e28aa53dSSzymon Dompke const std::string& triggerIdIn, const std::string& triggerNameIn, 782001301aSSzymon Dompke const std::vector<std::string>& triggerActions, 794416fce6SCezary Zwolak const std::vector<LabeledSensorInfo>& labeledSensorsInfo, 80b8cc78ddSKrzysztof Grobelny const std::vector<std::string>& reportIds, 814416fce6SCezary Zwolak const LabeledTriggerThresholdParams& labeledThresholdParams) 824416fce6SCezary Zwolak { 83*a950e42bSKrzysztof Grobelny const auto existingTriggerIds = utils::transform( 84*a950e42bSKrzysztof Grobelny triggers, [](const auto& trigger) { return trigger->getId(); }); 85e28aa53dSSzymon Dompke 86*a950e42bSKrzysztof Grobelny auto [id, name] = 87*a950e42bSKrzysztof Grobelny utils::generateId(triggerIdIn, triggerNameIn, triggerNameDefault, 88*a950e42bSKrzysztof Grobelny existingTriggerIds, maxTriggerIdLength); 89e28aa53dSSzymon Dompke 90*a950e42bSKrzysztof Grobelny verifyAddTrigger(id, name); 914416fce6SCezary Zwolak 924416fce6SCezary Zwolak triggers.emplace_back(triggerFactory->make( 93*a950e42bSKrzysztof Grobelny id, name, triggerActions, reportIds, *this, *triggerStorage, 94*a950e42bSKrzysztof Grobelny labeledThresholdParams, labeledSensorsInfo)); 954416fce6SCezary Zwolak 964416fce6SCezary Zwolak return *triggers.back(); 974416fce6SCezary Zwolak } 984416fce6SCezary Zwolak 994416fce6SCezary Zwolak void TriggerManager::loadFromPersistent() 1004416fce6SCezary Zwolak { 1014416fce6SCezary Zwolak std::vector<interfaces::JsonStorage::FilePath> paths = 1024416fce6SCezary Zwolak triggerStorage->list(); 1034416fce6SCezary Zwolak 1044416fce6SCezary Zwolak for (const auto& path : paths) 1054416fce6SCezary Zwolak { 1064416fce6SCezary Zwolak std::optional<nlohmann::json> data = triggerStorage->load(path); 1074416fce6SCezary Zwolak try 1084416fce6SCezary Zwolak { 1094416fce6SCezary Zwolak if (!data.has_value()) 1104416fce6SCezary Zwolak { 1114416fce6SCezary Zwolak throw std::runtime_error("Empty storage"); 1124416fce6SCezary Zwolak } 1134416fce6SCezary Zwolak size_t version = data->at("Version").get<size_t>(); 1144416fce6SCezary Zwolak if (version != Trigger::triggerVersion) 1154416fce6SCezary Zwolak { 1164416fce6SCezary Zwolak throw std::runtime_error("Invalid version"); 1174416fce6SCezary Zwolak } 118e28aa53dSSzymon Dompke const std::string& id = data->at("Id").get_ref<std::string&>(); 1194416fce6SCezary Zwolak const std::string& name = data->at("Name").get_ref<std::string&>(); 1204416fce6SCezary Zwolak int thresholdParamsDiscriminator = 1214416fce6SCezary Zwolak data->at("ThresholdParamsDiscriminator").get<int>(); 1222001301aSSzymon Dompke const std::vector<std::string> triggerActions = 1232001301aSSzymon Dompke data->at("TriggerActions").get<std::vector<std::string>>(); 1244416fce6SCezary Zwolak 1254416fce6SCezary Zwolak LabeledTriggerThresholdParams labeledThresholdParams; 1264416fce6SCezary Zwolak if (0 == thresholdParamsDiscriminator) 1274416fce6SCezary Zwolak { 1284416fce6SCezary Zwolak labeledThresholdParams = 1294416fce6SCezary Zwolak data->at("ThresholdParams") 1304416fce6SCezary Zwolak .get<std::vector<numeric::LabeledThresholdParam>>(); 1314416fce6SCezary Zwolak } 1324416fce6SCezary Zwolak else 1334416fce6SCezary Zwolak { 1344416fce6SCezary Zwolak labeledThresholdParams = 1354416fce6SCezary Zwolak data->at("ThresholdParams") 1364416fce6SCezary Zwolak .get<std::vector<discrete::LabeledThresholdParam>>(); 1374416fce6SCezary Zwolak } 1384416fce6SCezary Zwolak 139b8cc78ddSKrzysztof Grobelny auto reportIds = 140b8cc78ddSKrzysztof Grobelny data->at("ReportIds").get<std::vector<std::string>>(); 1414416fce6SCezary Zwolak 1424416fce6SCezary Zwolak auto labeledSensorsInfo = 1434416fce6SCezary Zwolak data->at("Sensors").get<std::vector<LabeledSensorInfo>>(); 1444416fce6SCezary Zwolak 145b8cc78ddSKrzysztof Grobelny addTrigger(id, name, triggerActions, labeledSensorsInfo, reportIds, 146b8cc78ddSKrzysztof Grobelny labeledThresholdParams); 1474416fce6SCezary Zwolak } 1484416fce6SCezary Zwolak catch (const std::exception& e) 1494416fce6SCezary Zwolak { 1504416fce6SCezary Zwolak phosphor::logging::log<phosphor::logging::level::ERR>( 1514416fce6SCezary Zwolak "Failed to load trigger from storage", 1524416fce6SCezary Zwolak phosphor::logging::entry( 1534416fce6SCezary Zwolak "FILENAME=%s", 1544416fce6SCezary Zwolak static_cast<std::filesystem::path>(path).c_str()), 1554416fce6SCezary Zwolak phosphor::logging::entry("EXCEPTION_MSG=%s", e.what())); 1564416fce6SCezary Zwolak triggerStorage->remove(path); 1574416fce6SCezary Zwolak } 1584416fce6SCezary Zwolak } 1594416fce6SCezary Zwolak } 160