xref: /openbmc/telemetry/src/trigger.cpp (revision b8cc78ddf9cc87c83176c7bda575ceef2678d00f)
1 #include "trigger.hpp"
2 
3 #include "trigger_manager.hpp"
4 #include "types/report_types.hpp"
5 #include "types/trigger_types.hpp"
6 #include "utils/conversion_trigger.hpp"
7 #include "utils/transform.hpp"
8 
9 #include <phosphor-logging/log.hpp>
10 
11 Trigger::Trigger(
12     boost::asio::io_context& ioc,
13     const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
14     const std::string& idIn, const std::string& nameIn,
15     const std::vector<std::string>& triggerActionsIn,
16     const std::vector<std::string>& reportIdsIn,
17     const std::vector<LabeledSensorInfo>& LabeledSensorsInfoIn,
18     const LabeledTriggerThresholdParams& labeledThresholdParamsIn,
19     std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
20     interfaces::TriggerManager& triggerManager,
21     interfaces::JsonStorage& triggerStorageIn) :
22     id(idIn),
23     name(nameIn), triggerActions(std::move(triggerActionsIn)),
24     path(triggerDir + id), reportIds(reportIdsIn),
25     labeledSensorsInfo(LabeledSensorsInfoIn),
26     labeledThresholdParams(labeledThresholdParamsIn),
27     thresholds(std::move(thresholdsIn)),
28     fileName(std::to_string(std::hash<std::string>{}(id))),
29     triggerStorage(triggerStorageIn)
30 {
31     deleteIface = objServer->add_unique_interface(
32         path, deleteIfaceName, [this, &ioc, &triggerManager](auto& dbusIface) {
33             dbusIface.register_method("Delete", [this, &ioc, &triggerManager] {
34                 if (persistent)
35                 {
36                     triggerStorage.remove(fileName);
37                 }
38                 boost::asio::post(ioc, [this, &triggerManager] {
39                     triggerManager.removeTrigger(this);
40                 });
41             });
42         });
43 
44     triggerIface = objServer->add_unique_interface(
45         path, triggerIfaceName, [this](auto& dbusIface) {
46             persistent = storeConfiguration();
47             dbusIface.register_property_rw(
48                 "Persistent", persistent,
49                 sdbusplus::vtable::property_::emits_change,
50                 [this](bool newVal, const auto&) {
51                     if (newVal == persistent)
52                     {
53                         return true;
54                     }
55                     if (newVal)
56                     {
57                         persistent = storeConfiguration();
58                     }
59                     else
60                     {
61                         triggerStorage.remove(fileName);
62                         persistent = false;
63                     }
64                     return true;
65                 },
66                 [this](const auto&) { return persistent; });
67 
68             dbusIface.register_property_r(
69                 "Thresholds", TriggerThresholdParams{},
70                 sdbusplus::vtable::property_::emits_change,
71                 [this](const auto&) {
72                     return std::visit(
73                         utils::FromLabeledThresholdParamConversion(),
74                         labeledThresholdParams);
75                 });
76 
77             dbusIface.register_property_r(
78                 "Sensors", SensorsInfo{},
79                 sdbusplus::vtable::property_::emits_change,
80                 [this](const auto&) {
81                     return utils::fromLabeledSensorsInfo(labeledSensorsInfo);
82                 });
83 
84             dbusIface.register_property_r(
85                 "ReportNames", reportIds,
86                 sdbusplus::vtable::property_::emits_change,
87                 [](const auto& x) { return x; });
88 
89             dbusIface.register_property_r(
90                 "Discrete", false, sdbusplus::vtable::property_::const_,
91                 [this](const auto& x) {
92                     return isTriggerThresholdDiscrete(labeledThresholdParams);
93                 });
94 
95             dbusIface.register_property_rw(
96                 "Name", std::string(),
97                 sdbusplus::vtable::property_::emits_change,
98                 [this](auto newVal, auto& oldVal) {
99                     name = oldVal = newVal;
100                     return true;
101                 },
102                 [this](const auto&) { return name; });
103 
104             dbusIface.register_property_r("TriggerActions", triggerActions,
105                                           sdbusplus::vtable::property_::const_,
106                                           [this](const auto& x) { return x; });
107         });
108 
109     for (const auto& threshold : thresholds)
110     {
111         threshold->initialize();
112     }
113 }
114 
115 bool Trigger::storeConfiguration() const
116 {
117     try
118     {
119         nlohmann::json data;
120 
121         data["Version"] = triggerVersion;
122         data["Id"] = id;
123         data["Name"] = name;
124         data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
125         data["TriggerActions"] = triggerActions;
126         data["ThresholdParams"] =
127             utils::labeledThresholdParamsToJson(labeledThresholdParams);
128         data["ReportIds"] = reportIds;
129         data["Sensors"] = labeledSensorsInfo;
130 
131         triggerStorage.store(fileName, data);
132     }
133     catch (const std::exception& e)
134     {
135         phosphor::logging::log<phosphor::logging::level::ERR>(
136             "Failed to store a trigger in storage",
137             phosphor::logging::entry("EXCEPTION_MSG=%s", e.what()));
138         return false;
139     }
140     return true;
141 }
142