blob: 34609b32c9e4c46168e34284e8cb58f52dd850c3 [file] [log] [blame]
Wludzik, Jozef76833cb2020-12-21 14:42:41 +01001#include "trigger.hpp"
2
Szymon Dompkee28aa532021-10-27 12:33:12 +02003#include "trigger_manager.hpp"
Krzysztof Grobelnydcc4e192021-03-08 09:09:34 +00004#include "types/report_types.hpp"
5#include "types/trigger_types.hpp"
Cezary Zwolak4416fce2021-03-17 03:21:06 +01006#include "utils/conversion_trigger.hpp"
Cezary Zwolaka4e67612021-02-18 13:16:16 +01007#include "utils/transform.hpp"
8
9#include <phosphor-logging/log.hpp>
10
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010011Trigger::Trigger(
12 boost::asio::io_context& ioc,
13 const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
Szymon Dompkee28aa532021-10-27 12:33:12 +020014 const std::string& idIn, const std::string& nameIn,
Szymon Dompke94f71c52021-12-10 07:16:33 +010015 const std::vector<TriggerAction>& triggerActionsIn,
16 const std::shared_ptr<std::vector<std::string>> reportIdsIn,
Wludzik, Jozef1477fe62021-01-02 11:56:10 +010017 std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
Cezary Zwolaka4e67612021-02-18 13:16:16 +010018 interfaces::TriggerManager& triggerManager,
Szymon Dompke94f71c52021-12-10 07:16:33 +010019 interfaces::JsonStorage& triggerStorageIn,
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +010020 const interfaces::TriggerFactory& triggerFactory, Sensors sensorsIn,
21 interfaces::ReportManager& reportManagerIn) :
Szymon Dompkee28aa532021-10-27 12:33:12 +020022 id(idIn),
23 name(nameIn), triggerActions(std::move(triggerActionsIn)),
Szymon Dompke94f71c52021-12-10 07:16:33 +010024 path(triggerDir + id), reportIds(std::move(reportIdsIn)),
Cezary Zwolak4416fce2021-03-17 03:21:06 +010025 thresholds(std::move(thresholdsIn)),
Szymon Dompkee28aa532021-10-27 12:33:12 +020026 fileName(std::to_string(std::hash<std::string>{}(id))),
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +010027 triggerStorage(triggerStorageIn), sensors(std::move(sensorsIn)),
28 reportManager(reportManagerIn)
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010029{
30 deleteIface = objServer->add_unique_interface(
31 path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) {
32 dbusIface.register_method("Delete", [this, &ioc, &triggerManager] {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010033 if (persistent)
34 {
35 triggerStorage.remove(fileName);
36 }
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +010037 for (const auto& reportId : *reportIds)
38 {
39 reportManager.updateTriggerIds(reportId, id,
40 TriggerIdUpdate::Remove);
41 }
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010042 boost::asio::post(ioc, [this, &triggerManager] {
43 triggerManager.removeTrigger(this);
44 });
45 });
46 });
47
48 triggerIface = objServer->add_unique_interface(
Szymon Dompke94f71c52021-12-10 07:16:33 +010049 path, triggerIfaceName, [this, &triggerFactory](auto& dbusIface) {
Cezary Zwolaka4e67612021-02-18 13:16:16 +010050 persistent = storeConfiguration();
51 dbusIface.register_property_rw(
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010052 "Persistent", persistent,
53 sdbusplus::vtable::property_::emits_change,
Cezary Zwolaka4e67612021-02-18 13:16:16 +010054 [this](bool newVal, const auto&) {
55 if (newVal == persistent)
56 {
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +010057 return 1;
Cezary Zwolaka4e67612021-02-18 13:16:16 +010058 }
59 if (newVal)
60 {
61 persistent = storeConfiguration();
62 }
63 else
64 {
65 triggerStorage.remove(fileName);
66 persistent = false;
67 }
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +010068 return 1;
Cezary Zwolaka4e67612021-02-18 13:16:16 +010069 },
70 [this](const auto&) { return persistent; });
71
Szymon Dompke94f71c52021-12-10 07:16:33 +010072 dbusIface.register_property_rw(
Cezary Zwolak4416fce2021-03-17 03:21:06 +010073 "Thresholds", TriggerThresholdParams{},
Wludzik, Jozef76833cb2020-12-21 14:42:41 +010074 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +010075 [this, &triggerFactory](auto newVal, auto& oldVal) {
76 auto newThresholdParams = std::visit(
77 utils::ToLabeledThresholdParamConversion(), newVal);
78 triggerFactory.updateThresholds(thresholds, triggerActions,
79 reportIds, sensors,
80 newThresholdParams);
81 oldVal = std::move(newVal);
82 return 1;
83 },
Cezary Zwolak4416fce2021-03-17 03:21:06 +010084 [this](const auto&) {
Szymon Dompke94f71c52021-12-10 07:16:33 +010085 return fromLabeledThresholdParam(
86 utils::transform(thresholds, [](const auto& threshold) {
87 return threshold->getThresholdParam();
88 }));
Cezary Zwolak4416fce2021-03-17 03:21:06 +010089 });
90
Szymon Dompke94f71c52021-12-10 07:16:33 +010091 dbusIface.register_property_rw(
Cezary Zwolak4416fce2021-03-17 03:21:06 +010092 "Sensors", SensorsInfo{},
93 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +010094 [this, &triggerFactory](auto newVal, auto& oldVal) {
95 auto labeledSensorInfo =
96 triggerFactory.getLabeledSensorsInfo(newVal);
97 triggerFactory.updateSensors(sensors, labeledSensorInfo);
98 for (const auto& threshold : thresholds)
99 {
100 threshold->updateSensors(sensors);
101 }
102 oldVal = std::move(newVal);
103 return 1;
104 },
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100105 [this](const auto&) {
Szymon Dompke94f71c52021-12-10 07:16:33 +0100106 return utils::fromLabeledSensorsInfo(
107 utils::transform(sensors, [](const auto& sensor) {
108 return sensor->getLabeledSensorInfo();
109 }));
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100110 });
111
Szymon Dompke94f71c52021-12-10 07:16:33 +0100112 dbusIface.register_property_rw(
113 "ReportNames", std::vector<std::string>{},
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100114 sdbusplus::vtable::property_::emits_change,
Szymon Dompke94f71c52021-12-10 07:16:33 +0100115 [this](auto newVal, auto& oldVal) {
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100116 TriggerManager::verifyReportIds(newVal);
117 updateTriggerIdsInReports(newVal);
Szymon Dompke94f71c52021-12-10 07:16:33 +0100118 reportIds->clear();
119 std::copy(newVal.begin(), newVal.end(),
120 std::back_inserter(*reportIds));
121 oldVal = std::move(newVal);
122 return 1;
123 },
124 [this](const auto&) { return *reportIds; });
Szymon Dompke20013012021-07-23 09:54:20 +0200125
126 dbusIface.register_property_r(
127 "Discrete", false, sdbusplus::vtable::property_::const_,
128 [this](const auto& x) {
Szymon Dompke94f71c52021-12-10 07:16:33 +0100129 return !std::holds_alternative<
130 numeric::LabeledThresholdParam>(
131 thresholds.back()->getThresholdParam());
Szymon Dompke20013012021-07-23 09:54:20 +0200132 });
133
Szymon Dompkee28aa532021-10-27 12:33:12 +0200134 dbusIface.register_property_rw(
135 "Name", std::string(),
136 sdbusplus::vtable::property_::emits_change,
137 [this](auto newVal, auto& oldVal) {
138 name = oldVal = newVal;
Szymon Dompke3e2cc9d2021-12-14 12:00:52 +0100139 return 1;
Szymon Dompkee28aa532021-10-27 12:33:12 +0200140 },
141 [this](const auto&) { return name; });
142
Szymon Dompke94f71c52021-12-10 07:16:33 +0100143 dbusIface.register_property_r(
144 "TriggerActions", std::vector<std::string>(),
145 sdbusplus::vtable::property_::const_, [this](const auto&) {
146 return utils::transform(triggerActions,
147 [](const auto& action) {
148 return actionToString(action);
149 });
150 });
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100151 });
Wludzik, Jozef1477fe62021-01-02 11:56:10 +0100152
153 for (const auto& threshold : thresholds)
154 {
155 threshold->initialize();
156 }
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100157
158 for (const auto& reportId : *reportIds)
159 {
160 reportManager.updateTriggerIds(reportId, id, TriggerIdUpdate::Add);
161 }
Wludzik, Jozef76833cb2020-12-21 14:42:41 +0100162}
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100163
164bool Trigger::storeConfiguration() const
165{
166 try
167 {
168 nlohmann::json data;
169
Szymon Dompke94f71c52021-12-10 07:16:33 +0100170 auto labeledThresholdParams =
171 std::visit(utils::ToLabeledThresholdParamConversion(),
172 fromLabeledThresholdParam(utils::transform(
173 thresholds, [](const auto& threshold) {
174 return threshold->getThresholdParam();
175 })));
176
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100177 data["Version"] = triggerVersion;
Szymon Dompkee28aa532021-10-27 12:33:12 +0200178 data["Id"] = id;
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100179 data["Name"] = name;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100180 data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
Szymon Dompke94f71c52021-12-10 07:16:33 +0100181 data["TriggerActions"] =
182 utils::transform(triggerActions, [](const auto& action) {
183 return actionToString(action);
184 });
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100185 data["ThresholdParams"] =
186 utils::labeledThresholdParamsToJson(labeledThresholdParams);
Szymon Dompke94f71c52021-12-10 07:16:33 +0100187 data["ReportIds"] = *reportIds;
188 data["Sensors"] = utils::transform(sensors, [](const auto& sensor) {
189 return sensor->getLabeledSensorInfo();
190 });
Cezary Zwolaka4e67612021-02-18 13:16:16 +0100191
192 triggerStorage.store(fileName, data);
193 }
194 catch (const std::exception& e)
195 {
196 phosphor::logging::log<phosphor::logging::level::ERR>(
197 "Failed to store a trigger in storage",
198 phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
199 return false;
200 }
201 return true;
Cezary Zwolak4416fce2021-03-17 03:21:06 +0100202}
Szymon Dompkeb4ef22e2022-02-07 15:15:12 +0100203
204void Trigger::updateTriggerIdsInReports(
205 const std::vector<std::string>& newReportIds)
206{
207 std::vector<std::string> toBeRemoved, toBeAdded;
208 size_t maxSize = std::max(reportIds->size(), newReportIds.size());
209 toBeRemoved.reserve(maxSize);
210 toBeAdded.reserve(maxSize);
211 std::set_difference(reportIds->begin(), reportIds->end(),
212 newReportIds.begin(), newReportIds.end(),
213 std::back_inserter(toBeRemoved));
214 std::set_difference(newReportIds.begin(), newReportIds.end(),
215 reportIds->begin(), reportIds->end(),
216 std::back_inserter(toBeAdded));
217 for (auto& reportId : toBeRemoved)
218 {
219 reportManager.updateTriggerIds(reportId, id, TriggerIdUpdate::Remove);
220 }
221 for (auto& reportId : toBeAdded)
222 {
223 reportManager.updateTriggerIds(reportId, id, TriggerIdUpdate::Add);
224 }
225}