Modify Trigger dbus api

'AddTrigger' method is now using array of strings for actions instead
of boolean flags. The action names are following:
- 'UpdateReport' (same as old flag)
- 'LogToLogService' (old 'LogToJournal' flag)
- 'RedfishEvent' (old 'LogToRedfish' flag)
Additionally, isDiscrete flag was removed from 'AddTrigger' call, as
this value can be extracted depending on threshold.

As a result new 'AddTrigger" signature is: "sasa{os}asv"
Example call parameters:
- TestTrigger 1 UpdateReport 0 0 "a(stsd)" 1 LowerWarning 1000
  Either 42.7'
- TestTrigger 2 UpdateReport RedfishEvent 0 0 "a(ssts)" 1 userId_1
  Warning 10 15.2'

'Trigger' properties were also modified. Instead of action bool
properties (same as mentioned above), new property was introduced
'TriggerActions' - which has same values as those used in 'AddTrigger'
method. This also affects persistence: store/load functionality was
modified accordingly.

As a side change - isDiscrete is no longer stored, as this can be easily
recreated in the runtime.

Tested:
- Trigger was successfully created using dbus.
- busctl introspect was called on test trigger and properties are
  modified and working as intended.
- persistency mechanic is working propetly.

Signed-off-by: Szymon Dompke <szymon.dompke@intel.com>
Change-Id: Icd64d4032fd6d446d9b6ad248e28e9031af1fed7
diff --git a/src/interfaces/trigger_factory.hpp b/src/interfaces/trigger_factory.hpp
index a9eb55b..7a39aeb 100644
--- a/src/interfaces/trigger_factory.hpp
+++ b/src/interfaces/trigger_factory.hpp
@@ -20,8 +20,7 @@
     virtual ~TriggerFactory() = default;
 
     virtual std::unique_ptr<interfaces::Trigger> make(
-        const std::string& name, bool isDiscrete, bool logToJournal,
-        bool logToRedfish, bool updateReport,
+        const std::string& name, const std::vector<std::string>& triggerActions,
         const std::vector<std::string>& reportNames,
         interfaces::TriggerManager& triggerManager,
         interfaces::JsonStorage& triggerStorage,
diff --git a/src/trigger.cpp b/src/trigger.cpp
index d6ee3be..92e1472 100644
--- a/src/trigger.cpp
+++ b/src/trigger.cpp
@@ -10,19 +10,16 @@
 Trigger::Trigger(
     boost::asio::io_context& ioc,
     const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
-    const std::string& nameIn, const bool isDiscreteIn,
-    const bool logToJournalIn, const bool logToRedfishIn,
-    const bool updateReportIn, const std::vector<std::string>& reportNamesIn,
+    const std::string& nameIn, const std::vector<std::string>& triggerActionsIn,
+    const std::vector<std::string>& reportNamesIn,
     const std::vector<LabeledSensorInfo>& LabeledSensorsInfoIn,
     const LabeledTriggerThresholdParams& labeledThresholdParamsIn,
     std::vector<std::shared_ptr<interfaces::Threshold>>&& thresholdsIn,
     interfaces::TriggerManager& triggerManager,
     interfaces::JsonStorage& triggerStorageIn) :
     name(nameIn),
-    isDiscrete(isDiscreteIn), logToJournal(logToJournalIn),
-    logToRedfish(logToRedfishIn), updateReport(updateReportIn),
-    path(triggerDir + name), reportNames(reportNamesIn),
-    labeledSensorsInfo(LabeledSensorsInfoIn),
+    triggerActions(std::move(triggerActionsIn)), path(triggerDir + name),
+    reportNames(reportNamesIn), labeledSensorsInfo(LabeledSensorsInfoIn),
     labeledThresholdParams(labeledThresholdParamsIn),
     thresholds(std::move(thresholdsIn)),
     fileName(std::to_string(std::hash<std::string>{}(name))),
@@ -42,9 +39,7 @@
         });
 
     triggerIface = objServer->add_unique_interface(
-        path, triggerIfaceName,
-        [this, isDiscreteIn, logToJournalIn, logToRedfishIn,
-         updateReportIn](auto& dbusIface) {
+        path, triggerIfaceName, [this](auto& dbusIface) {
             persistent = storeConfiguration();
             dbusIface.register_property_rw(
                 "Persistent", persistent,
@@ -84,22 +79,19 @@
                 });
 
             dbusIface.register_property_r(
-
                 "ReportNames", reportNames,
                 sdbusplus::vtable::property_::emits_change,
                 [](const auto& x) { return x; });
-            dbusIface.register_property_r("Discrete", isDiscrete,
+
+            dbusIface.register_property_r(
+                "Discrete", false, sdbusplus::vtable::property_::const_,
+                [this](const auto& x) {
+                    return isTriggerThresholdDiscrete(labeledThresholdParams);
+                });
+
+            dbusIface.register_property_r("TriggerActions", triggerActions,
                                           sdbusplus::vtable::property_::const_,
-                                          [](const auto& x) { return x; });
-            dbusIface.register_property_r("LogToJournal", logToJournal,
-                                          sdbusplus::vtable::property_::const_,
-                                          [](const auto& x) { return x; });
-            dbusIface.register_property_r("LogToRedfish", logToRedfish,
-                                          sdbusplus::vtable::property_::const_,
-                                          [](const auto& x) { return x; });
-            dbusIface.register_property_r("UpdateReport", updateReport,
-                                          sdbusplus::vtable::property_::const_,
-                                          [](const auto& x) { return x; });
+                                          [this](const auto& x) { return x; });
         });
 
     for (const auto& threshold : thresholds)
@@ -117,10 +109,7 @@
         data["Version"] = triggerVersion;
         data["Name"] = name;
         data["ThresholdParamsDiscriminator"] = labeledThresholdParams.index();
-        data["IsDiscrete"] = labeledThresholdParams.index() == 1;
-        data["LogToJournal"] = logToJournal;
-        data["LogToRedfish"] = logToRedfish;
-        data["UpdateReport"] = updateReport;
+        data["TriggerActions"] = triggerActions;
         data["ThresholdParams"] =
             utils::labeledThresholdParamsToJson(labeledThresholdParams);
         data["ReportNames"] = reportNames;
diff --git a/src/trigger.hpp b/src/trigger.hpp
index 09b5dc8..904f520 100644
--- a/src/trigger.hpp
+++ b/src/trigger.hpp
@@ -16,9 +16,8 @@
   public:
     Trigger(boost::asio::io_context& ioc,
             const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
-            const std::string& name, const bool isDiscrete,
-            const bool logToJournal, const bool logToRedfish,
-            const bool updateReport,
+            const std::string& name,
+            const std::vector<std::string>& triggerActions,
             const std::vector<std::string>& reportNames,
             const std::vector<LabeledSensorInfo>& LabeledSensorsInfoIn,
             const LabeledTriggerThresholdParams& labeledThresholdParamsIn,
@@ -45,10 +44,7 @@
 
   private:
     const std::string name;
-    bool isDiscrete;
-    bool logToJournal;
-    bool logToRedfish;
-    bool updateReport;
+    std::vector<std::string> triggerActions;
     const std::string path;
     bool persistent = false;
     std::vector<std::string> reportNames;
diff --git a/src/trigger_actions.cpp b/src/trigger_actions.cpp
index 8f2cf82..e89bd84 100644
--- a/src/trigger_actions.cpp
+++ b/src/trigger_actions.cpp
@@ -95,6 +95,39 @@
                                  getDirection(value, threshold)));
 }
 
+void fillActions(
+    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
+    const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
+    double thresholdValue, interfaces::ReportManager& reportManager,
+    const std::vector<std::string>& reportNames)
+{
+    actionsIf.reserve(ActionsEnum.size());
+    for (auto actionType : ActionsEnum)
+    {
+        switch (actionType)
+        {
+            case TriggerAction::LogToLogService:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<LogToJournal>(type, thresholdValue));
+                break;
+            }
+            case TriggerAction::RedfishEvent:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<LogToRedfish>(type, thresholdValue));
+                break;
+            }
+            case TriggerAction::UpdateReport:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<UpdateReport>(reportManager, reportNames));
+                break;
+            }
+        }
+    }
+}
+
 } // namespace numeric
 
 namespace discrete
@@ -148,6 +181,39 @@
                                  sensorName.c_str(), value, timestamp));
 }
 
+void fillActions(
+    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
+    const std::vector<TriggerAction>& ActionsEnum,
+    ::discrete::Severity severity, interfaces::ReportManager& reportManager,
+    const std::vector<std::string>& reportNames)
+{
+    actionsIf.reserve(ActionsEnum.size());
+    for (auto actionType : ActionsEnum)
+    {
+        switch (actionType)
+        {
+            case TriggerAction::LogToLogService:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<LogToJournal>(severity));
+                break;
+            }
+            case TriggerAction::RedfishEvent:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<LogToRedfish>(severity));
+                break;
+            }
+            case TriggerAction::UpdateReport:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<UpdateReport>(reportManager, reportNames));
+                break;
+            }
+        }
+    }
+}
+
 namespace onChange
 {
 void LogToJournal::commit(const std::string& sensorName, uint64_t timestamp,
@@ -170,6 +236,37 @@
         phosphor::logging::entry("REDFISH_MESSAGE_ARGS=%s,%f,%llu",
                                  sensorName.c_str(), value, timestamp));
 }
+
+void fillActions(
+    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
+    const std::vector<TriggerAction>& ActionsEnum,
+    interfaces::ReportManager& reportManager,
+    const std::vector<std::string>& reportNames)
+{
+    actionsIf.reserve(ActionsEnum.size());
+    for (auto actionType : ActionsEnum)
+    {
+        switch (actionType)
+        {
+            case TriggerAction::LogToLogService:
+            {
+                actionsIf.emplace_back(std::make_unique<LogToJournal>());
+                break;
+            }
+            case TriggerAction::RedfishEvent:
+            {
+                actionsIf.emplace_back(std::make_unique<LogToRedfish>());
+                break;
+            }
+            case TriggerAction::UpdateReport:
+            {
+                actionsIf.emplace_back(
+                    std::make_unique<UpdateReport>(reportManager, reportNames));
+                break;
+            }
+        }
+    }
+}
 } // namespace onChange
 } // namespace discrete
 
diff --git a/src/trigger_actions.hpp b/src/trigger_actions.hpp
index 2b126e0..c180c3d 100644
--- a/src/trigger_actions.hpp
+++ b/src/trigger_actions.hpp
@@ -40,6 +40,12 @@
 
     const char* getMessageId() const;
 };
+
+void fillActions(
+    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
+    const std::vector<TriggerAction>& ActionsEnum, ::numeric::Type type,
+    double thresholdValue, interfaces::ReportManager& reportManager,
+    const std::vector<std::string>& reportNames);
 } // namespace numeric
 
 namespace discrete
@@ -74,6 +80,12 @@
     const char* getMessageId() const;
 };
 
+void fillActions(
+    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
+    const std::vector<TriggerAction>& ActionsEnum,
+    ::discrete::Severity severity, interfaces::ReportManager& reportManager,
+    const std::vector<std::string>& reportNames);
+
 namespace onChange
 {
 class LogToJournal : public interfaces::TriggerAction
@@ -95,6 +107,12 @@
     void commit(const std::string& id, uint64_t timestamp,
                 double value) override;
 };
+
+void fillActions(
+    std::vector<std::unique_ptr<interfaces::TriggerAction>>& actionsIf,
+    const std::vector<TriggerAction>& ActionsEnum,
+    interfaces::ReportManager& reportManager,
+    const std::vector<std::string>& reportNames);
 } // namespace onChange
 
 } // namespace discrete
diff --git a/src/trigger_factory.cpp b/src/trigger_factory.cpp
index bdfc163..98cfefe 100644
--- a/src/trigger_factory.cpp
+++ b/src/trigger_factory.cpp
@@ -21,8 +21,7 @@
 {}
 
 std::unique_ptr<interfaces::Trigger> TriggerFactory::make(
-    const std::string& name, bool isDiscrete, bool logToJournal,
-    bool logToRedfish, bool updateReport,
+    const std::string& name, const std::vector<std::string>& triggerActionsIn,
     const std::vector<std::string>& reportNames,
     interfaces::TriggerManager& triggerManager,
     interfaces::JsonStorage& triggerStorage,
@@ -30,9 +29,15 @@
     const std::vector<LabeledSensorInfo>& labeledSensorsInfo) const
 {
     const auto& [sensors, sensorNames] = getSensors(labeledSensorsInfo);
+    std::vector<TriggerAction> triggerActions;
+    std::transform(triggerActionsIn.begin(), triggerActionsIn.end(),
+                   std::back_inserter(triggerActions),
+                   [](auto& triggerActionStr) {
+                       return stringToTriggerAction(triggerActionStr);
+                   });
     std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
 
-    if (isDiscrete)
+    if (isTriggerThresholdDiscrete(labeledThresholdParams))
     {
         const auto& labeledDiscreteThresholdParams =
             std::get<std::vector<discrete::LabeledThresholdParam>>(
@@ -50,21 +55,8 @@
             std::string thresholdValue =
                 labeledThresholdParam.at_label<ts::ThresholdValue>();
 
-            if (logToJournal)
-            {
-                actions.emplace_back(
-                    std::make_unique<action::discrete::LogToJournal>(severity));
-            }
-            if (logToRedfish)
-            {
-                actions.emplace_back(
-                    std::make_unique<action::discrete::LogToRedfish>(severity));
-            }
-            if (updateReport)
-            {
-                actions.emplace_back(std::make_unique<action::UpdateReport>(
-                    reportManager, reportNames));
-            }
+            action::discrete::fillActions(actions, triggerActions, severity,
+                                          reportManager, reportNames);
 
             thresholds.emplace_back(std::make_shared<DiscreteThreshold>(
                 bus->get_io_context(), sensors, sensorNames, std::move(actions),
@@ -74,23 +66,8 @@
         if (labeledDiscreteThresholdParams.empty())
         {
             std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
-            if (logToJournal)
-            {
-                actions.emplace_back(
-                    std::make_unique<
-                        action::discrete::onChange::LogToJournal>());
-            }
-            if (logToRedfish)
-            {
-                actions.emplace_back(
-                    std::make_unique<
-                        action::discrete::onChange::LogToRedfish>());
-            }
-            if (updateReport)
-            {
-                actions.emplace_back(std::make_unique<action::UpdateReport>(
-                    reportManager, reportNames));
-            }
+            action::discrete::onChange::fillActions(actions, triggerActions,
+                                                    reportManager, reportNames);
 
             thresholds.emplace_back(std::make_shared<OnChangeThreshold>(
                 sensors, sensorNames, std::move(actions)));
@@ -112,25 +89,9 @@
             auto thresholdValue =
                 double{labeledThresholdParam.at_label<ts::ThresholdValue>()};
 
-            if (logToJournal)
-            {
-                actions.emplace_back(
-                    std::make_unique<action::numeric::LogToJournal>(
-                        type, thresholdValue));
-            }
-
-            if (logToRedfish)
-            {
-                actions.emplace_back(
-                    std::make_unique<action::numeric::LogToRedfish>(
-                        type, thresholdValue));
-            }
-
-            if (updateReport)
-            {
-                actions.emplace_back(std::make_unique<action::UpdateReport>(
-                    reportManager, reportNames));
-            }
+            action::numeric::fillActions(actions, triggerActions, type,
+                                         thresholdValue, reportManager,
+                                         reportNames);
 
             thresholds.emplace_back(std::make_shared<NumericThreshold>(
                 bus->get_io_context(), sensors, sensorNames, std::move(actions),
@@ -139,10 +100,9 @@
     }
 
     return std::make_unique<Trigger>(
-        bus->get_io_context(), objServer, name, isDiscrete, logToJournal,
-        logToRedfish, updateReport, reportNames, labeledSensorsInfo,
-        labeledThresholdParams, std::move(thresholds), triggerManager,
-        triggerStorage);
+        bus->get_io_context(), objServer, name, triggerActionsIn, reportNames,
+        labeledSensorsInfo, labeledThresholdParams, std::move(thresholds),
+        triggerManager, triggerStorage);
 }
 
 std::pair<Sensors, std::vector<std::string>> TriggerFactory::getSensors(
diff --git a/src/trigger_factory.hpp b/src/trigger_factory.hpp
index 4ec273a..e7f8fb0 100644
--- a/src/trigger_factory.hpp
+++ b/src/trigger_factory.hpp
@@ -16,8 +16,8 @@
                    interfaces::ReportManager& reportManager);
 
     std::unique_ptr<interfaces::Trigger>
-        make(const std::string& name, bool isDiscrete, bool logToJournal,
-             bool logToRedfish, bool updateReport,
+        make(const std::string& name,
+             const std::vector<std::string>& triggerActions,
              const std::vector<std::string>& reportNames,
              interfaces::TriggerManager& triggerManager,
              interfaces::JsonStorage& triggerStorage,
diff --git a/src/trigger_manager.cpp b/src/trigger_manager.cpp
index 81a0398..da4797f 100644
--- a/src/trigger_manager.cpp
+++ b/src/trigger_manager.cpp
@@ -21,8 +21,8 @@
             iface.register_method(
                 "AddTrigger",
                 [this](boost::asio::yield_context& yield,
-                       const std::string& name, bool isDiscrete,
-                       bool logToJournal, bool logToRedfish, bool updateReport,
+                       const std::string& name,
+                       const std::vector<std::string>& triggerActions,
                        const SensorsInfo& sensors,
                        const std::vector<std::string>& reportNames,
                        const TriggerThresholdParamsExt& thresholds) {
@@ -34,9 +34,8 @@
                     std::vector<LabeledSensorInfo> labeledSensorsInfo =
                         triggerFactory->getLabeledSensorsInfo(yield, sensors);
 
-                    return addTrigger(name, isDiscrete, logToJournal,
-                                      logToRedfish, updateReport,
-                                      labeledSensorsInfo, reportNames,
+                    return addTrigger(name, triggerActions, labeledSensorsInfo,
+                                      reportNames,
                                       labeledTriggerThresholdParams)
                         .getPath();
                 });
@@ -51,9 +50,7 @@
         triggers.end());
 }
 
-void TriggerManager::verifyAddTrigger(
-    const std::string& triggerName, bool isDiscrete,
-    const LabeledTriggerThresholdParams& thresholdParams)
+void TriggerManager::verifyAddTrigger(const std::string& triggerName)
 {
     if (triggers.size() >= maxTriggers)
     {
@@ -73,18 +70,17 @@
 }
 
 interfaces::Trigger& TriggerManager::addTrigger(
-    const std::string& triggerName, bool isDiscrete, bool logToJournal,
-    bool logToRedfish, bool updateReport,
+    const std::string& triggerName,
+    const std::vector<std::string>& triggerActions,
     const std::vector<LabeledSensorInfo>& labeledSensorsInfo,
     const std::vector<std::string>& reportNames,
     const LabeledTriggerThresholdParams& labeledThresholdParams)
 {
-    verifyAddTrigger(triggerName, isDiscrete, labeledThresholdParams);
+    verifyAddTrigger(triggerName);
 
     triggers.emplace_back(triggerFactory->make(
-        triggerName, isDiscrete, logToJournal, logToRedfish, updateReport,
-        reportNames, *this, *triggerStorage, labeledThresholdParams,
-        labeledSensorsInfo));
+        triggerName, triggerActions, reportNames, *this, *triggerStorage,
+        labeledThresholdParams, labeledSensorsInfo));
 
     return *triggers.back();
 }
@@ -111,10 +107,8 @@
             const std::string& name = data->at("Name").get_ref<std::string&>();
             int thresholdParamsDiscriminator =
                 data->at("ThresholdParamsDiscriminator").get<int>();
-            bool isDiscrete = data->at("IsDiscrete").get<bool>();
-            bool logToJournal = data->at("LogToJournal").get<bool>();
-            bool logToRedfish = data->at("LogToRedfish").get<bool>();
-            bool updateReport = data->at("UpdateReport").get<bool>();
+            const std::vector<std::string> triggerActions =
+                data->at("TriggerActions").get<std::vector<std::string>>();
 
             LabeledTriggerThresholdParams labeledThresholdParams;
             if (0 == thresholdParamsDiscriminator)
@@ -136,8 +130,7 @@
             auto labeledSensorsInfo =
                 data->at("Sensors").get<std::vector<LabeledSensorInfo>>();
 
-            addTrigger(name, isDiscrete, logToJournal, logToRedfish,
-                       updateReport, labeledSensorsInfo, reportNames,
+            addTrigger(name, triggerActions, labeledSensorsInfo, reportNames,
                        labeledThresholdParams);
         }
         catch (const std::exception& e)
diff --git a/src/trigger_manager.hpp b/src/trigger_manager.hpp
index ec26bdc..c3acd36 100644
--- a/src/trigger_manager.hpp
+++ b/src/trigger_manager.hpp
@@ -30,12 +30,11 @@
     std::unique_ptr<sdbusplus::asio::dbus_interface> managerIface;
     std::vector<std::unique_ptr<interfaces::Trigger>> triggers;
 
-    void verifyAddTrigger(const std::string& triggerName, bool isDiscrete,
-                          const LabeledTriggerThresholdParams& thresholdParams);
+    void verifyAddTrigger(const std::string& triggerName);
 
     interfaces::Trigger&
-        addTrigger(const std::string& triggerName, bool isDiscrete,
-                   bool logToJournal, bool logToRedfish, bool updateReport,
+        addTrigger(const std::string& triggerName,
+                   const std::vector<std::string>& triggerActions,
                    const std::vector<LabeledSensorInfo>& labeledSensors,
                    const std::vector<std::string>& reportNames,
                    const LabeledTriggerThresholdParams& labeledThresholdParams);
diff --git a/src/types/trigger_types.hpp b/src/types/trigger_types.hpp
index 4b6e150..a2a2e82 100644
--- a/src/types/trigger_types.hpp
+++ b/src/types/trigger_types.hpp
@@ -10,6 +10,27 @@
 #include <variant>
 #include <vector>
 
+enum class TriggerAction
+{
+    LogToLogService = 0,
+    RedfishEvent,
+    UpdateReport,
+};
+
+namespace details
+{
+constexpr std::array<std::pair<std::string_view, TriggerAction>, 3>
+    convDataTriggerAction = {
+        std::make_pair("LogToLogService", TriggerAction::LogToLogService),
+        std::make_pair("RedfishEvent", TriggerAction::RedfishEvent),
+        std::make_pair("UpdateReport", TriggerAction::UpdateReport)};
+}
+
+inline TriggerAction stringToTriggerAction(const std::string& str)
+{
+    return utils::stringToEnum(details::convDataTriggerAction, str);
+}
+
 namespace discrete
 {
 
@@ -130,3 +151,10 @@
 using LabeledTriggerThresholdParams =
     std::variant<std::vector<numeric::LabeledThresholdParam>,
                  std::vector<discrete::LabeledThresholdParam>>;
+
+inline bool
+    isTriggerThresholdDiscrete(const LabeledTriggerThresholdParams& params)
+{
+    return std::holds_alternative<std::vector<discrete::LabeledThresholdParam>>(
+        params);
+}