Using enum class instead of string in more places

ReportingType and ReportUpdates are now used as enum class in more
places than before. Changed how this two fields are stored in
persistent configuration. Increased Report::Version to break backward
compatibility. Updated unit tests to verify changed functionality.

Tested:
- All existing tests are passing

Change-Id: I55db205aefbe2b5a69fb7a31ccf11885aaecaaf2
Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
diff --git a/src/interfaces/report_factory.hpp b/src/interfaces/report_factory.hpp
index 36fc589..613c1d5 100644
--- a/src/interfaces/report_factory.hpp
+++ b/src/interfaces/report_factory.hpp
@@ -3,7 +3,10 @@
 #include "interfaces/json_storage.hpp"
 #include "interfaces/report.hpp"
 #include "interfaces/report_manager.hpp"
+#include "types/report_action.hpp"
 #include "types/report_types.hpp"
+#include "types/report_updates.hpp"
+#include "types/reporting_type.hpp"
 
 #include <boost/asio/spawn.hpp>
 
@@ -24,10 +27,10 @@
                             const ReadingParameters& metricParams) const = 0;
 
     virtual std::unique_ptr<interfaces::Report>
-        make(const std::string& name, const std::string& reportingType,
-             bool emitsReadingsSignal, bool logToMetricReportsCollection,
+        make(const std::string& name, const ReportingType reportingType,
+             const std::vector<ReportAction>& reportActions,
              Milliseconds period, uint64_t appendLimit,
-             const std::string& reportUpdates, ReportManager& reportManager,
+             const ReportUpdates reportUpdates, ReportManager& reportManager,
              JsonStorage& reportStorage,
              std::vector<LabeledMetricParameters> labeledMetricParams,
              bool enabled) const = 0;
diff --git a/src/report.cpp b/src/report.cpp
index 8c01cf2..cc981f1 100644
--- a/src/report.cpp
+++ b/src/report.cpp
@@ -1,6 +1,7 @@
 #include "report.hpp"
 
 #include "report_manager.hpp"
+#include "utils/contains.hpp"
 #include "utils/transform.hpp"
 
 #include <phosphor-logging/log.hpp>
@@ -13,8 +14,7 @@
                const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
                const std::string& reportName,
                const ReportingType reportingTypeIn,
-               const bool emitsReadingsUpdateIn,
-               const bool logToMetricReportsCollectionIn,
+               std::vector<ReportAction> reportActionsIn,
                const Milliseconds intervalIn, const uint64_t appendLimitIn,
                const ReportUpdates reportUpdatesIn,
                interfaces::ReportManager& reportManager,
@@ -23,8 +23,7 @@
                const bool enabledIn) :
     name(reportName),
     path(reportDir + name), reportingType(reportingTypeIn),
-    interval(intervalIn), emitsReadingsUpdate(emitsReadingsUpdateIn),
-    logToMetricReportsCollection(logToMetricReportsCollectionIn),
+    interval(intervalIn), reportActions(std::move(reportActionsIn)),
     sensorCount(getSensorCount(metricsIn)),
     appendLimit(deduceAppendLimit(appendLimitIn)),
     reportUpdates(reportUpdatesIn),
@@ -61,7 +60,7 @@
     persistency = storeConfiguration();
     reportIface = makeReportInterface();
 
-    if (reportingType == ReportingType::Periodic)
+    if (reportingType == ReportingType::periodic)
     {
         scheduleTimer(interval);
     }
@@ -101,8 +100,8 @@
 uint64_t Report::deduceBufferSize(const ReportUpdates reportUpdatesIn,
                                   const ReportingType reportingTypeIn) const
 {
-    if (reportUpdatesIn == ReportUpdates::Overwrite ||
-        reportingTypeIn == ReportingType::OnRequest)
+    if (reportUpdatesIn == ReportUpdates::overwrite ||
+        reportingTypeIn == ReportingType::onRequest)
     {
         return sensorCount;
     }
@@ -116,9 +115,9 @@
 {
     if (reportUpdates != newReportUpdates)
     {
-        if (reportingType != ReportingType::OnRequest &&
-            (reportUpdates == ReportUpdates::Overwrite ||
-             newReportUpdates == ReportUpdates::Overwrite))
+        if (reportingType != ReportingType::onRequest &&
+            (reportUpdates == ReportUpdates::overwrite ||
+             newReportUpdates == ReportUpdates::overwrite))
         {
             readingsBuffer.clearAndResize(
                 deduceBufferSize(newReportUpdates, reportingType));
@@ -135,7 +134,7 @@
         [this](bool newVal, const auto&) {
             if (newVal != enabled)
             {
-                if (true == newVal && ReportingType::Periodic == reportingType)
+                if (true == newVal && ReportingType::periodic == reportingType)
                 {
                     scheduleTimer(interval);
                 }
@@ -198,7 +197,7 @@
         [this](const auto&) { return persistency; });
 
     auto readingsFlag = sdbusplus::vtable::property_::none;
-    if (emitsReadingsUpdate)
+    if (utils::contains(reportActions, ReportAction::emitsReadingsUpdate))
     {
         readingsFlag = sdbusplus::vtable::property_::emits_change;
     }
@@ -206,7 +205,7 @@
                                    [this](const auto&) { return readings; });
     dbusIface->register_property_r(
         "ReportingType", std::string(), sdbusplus::vtable::property_::const_,
-        [this](const auto&) { return reportingTypeToString(reportingType); });
+        [this](const auto&) { return utils::enumToString(reportingType); });
     dbusIface->register_property_r(
         "ReadingParameters", readingParametersPastVersion,
         sdbusplus::vtable::property_::const_,
@@ -216,13 +215,24 @@
         sdbusplus::vtable::property_::const_,
         [this](const auto&) { return readingParameters; });
     dbusIface->register_property_r(
-        "EmitsReadingsUpdate", emitsReadingsUpdate,
-        sdbusplus::vtable::property_::const_,
-        [this](const auto&) { return emitsReadingsUpdate; });
+        "EmitsReadingsUpdate", bool{}, sdbusplus::vtable::property_::const_,
+        [this](const auto&) {
+            return utils::contains(reportActions,
+                                   ReportAction::emitsReadingsUpdate);
+        });
     dbusIface->register_property_r(
-        "LogToMetricReportsCollection", logToMetricReportsCollection,
-        sdbusplus::vtable::property_::const_,
-        [this](const auto&) { return logToMetricReportsCollection; });
+        "LogToMetricReportsCollection", bool{},
+        sdbusplus::vtable::property_::const_, [this](const auto&) {
+            return utils::contains(reportActions,
+                                   ReportAction::logToMetricReportsCollection);
+        });
+    dbusIface->register_property_r(
+        "ReportActions", std::vector<std::string>{},
+        sdbusplus::vtable::property_::const_, [this](const auto&) {
+            return utils::transform(reportActions, [](const auto reportAction) {
+                return utils::enumToString(reportAction);
+            });
+        });
     dbusIface->register_property_r("AppendLimit", appendLimit,
                                    sdbusplus::vtable::property_::emits_change,
                                    [this](const auto&) { return appendLimit; });
@@ -230,14 +240,14 @@
         "ReportUpdates", std::string(),
         sdbusplus::vtable::property_::emits_change,
         [this](auto newVal, auto& oldVal) {
-            ReportManager::verifyReportUpdates(newVal);
-            setReportUpdates(stringToReportUpdates(newVal));
+            ReportManager::verifyReportUpdates(utils::toReportUpdates(newVal));
+            setReportUpdates(utils::toReportUpdates(newVal));
             oldVal = newVal;
             return true;
         },
-        [this](const auto&) { return reportUpdatesToString(reportUpdates); });
+        [this](const auto&) { return utils::enumToString(reportUpdates); });
     dbusIface->register_method("Update", [this] {
-        if (reportingType == ReportingType::OnRequest)
+        if (reportingType == ReportingType::onRequest)
         {
             updateReadings();
         }
@@ -272,8 +282,8 @@
         return;
     }
 
-    if (reportUpdates == ReportUpdates::Overwrite ||
-        reportingType == ReportingType::OnRequest)
+    if (reportUpdates == ReportUpdates::overwrite ||
+        reportingType == ReportingType::onRequest)
     {
         readingsBuffer.clear();
     }
@@ -283,7 +293,7 @@
         for (const auto& [id, metadata, value, timestamp] :
              metric->getReadings())
         {
-            if (reportUpdates == ReportUpdates::AppendStopsWhenFull &&
+            if (reportUpdates == ReportUpdates::appendStopsWhenFull &&
                 readingsBuffer.isFull())
             {
                 enabled = false;
@@ -312,12 +322,14 @@
         data["Enabled"] = enabled;
         data["Version"] = reportVersion;
         data["Name"] = name;
-        data["ReportingType"] = reportingTypeToString(reportingType);
-        data["EmitsReadingsUpdate"] = emitsReadingsUpdate;
-        data["LogToMetricReportsCollection"] = logToMetricReportsCollection;
+        data["ReportingType"] = utils::toUnderlying(reportingType);
+        data["ReportActions"] =
+            utils::transform(reportActions, [](const auto reportAction) {
+                return utils::toUnderlying(reportAction);
+            });
         data["Interval"] = interval.count();
         data["AppendLimit"] = appendLimit;
-        data["ReportUpdates"] = reportUpdatesToString(reportUpdates);
+        data["ReportUpdates"] = utils::toUnderlying(reportUpdates);
         data["ReadingParameters"] =
             utils::transform(metrics, [](const auto& metric) {
                 return metric->dumpConfiguration();
diff --git a/src/report.hpp b/src/report.hpp
index c758988..5d675bf 100644
--- a/src/report.hpp
+++ b/src/report.hpp
@@ -4,7 +4,10 @@
 #include "interfaces/metric.hpp"
 #include "interfaces/report.hpp"
 #include "interfaces/report_manager.hpp"
+#include "types/report_action.hpp"
 #include "types/report_types.hpp"
+#include "types/report_updates.hpp"
+#include "types/reporting_type.hpp"
 #include "utils/circular_vector.hpp"
 
 #include <boost/asio/io_context.hpp>
@@ -20,8 +23,7 @@
     Report(boost::asio::io_context& ioc,
            const std::shared_ptr<sdbusplus::asio::object_server>& objServer,
            const std::string& reportName, const ReportingType reportingType,
-           const bool emitsReadingsSignal,
-           const bool logToMetricReportsCollection, const Milliseconds period,
+           std::vector<ReportAction> reportActions, const Milliseconds period,
            const uint64_t appendLimitIn, const ReportUpdates reportUpdatesIn,
            interfaces::ReportManager& reportManager,
            interfaces::JsonStorage& reportStorage,
@@ -62,8 +64,7 @@
     std::string path;
     ReportingType reportingType;
     Milliseconds interval;
-    bool emitsReadingsUpdate;
-    bool logToMetricReportsCollection;
+    std::vector<ReportAction> reportActions;
     ReadingParametersPastVersion readingParametersPastVersion;
     ReadingParameters readingParameters;
     bool persistency = false;
@@ -89,5 +90,5 @@
         "/xyz/openbmc_project/Telemetry/Reports/";
     static constexpr const char* deleteIfaceName =
         "xyz.openbmc_project.Object.Delete";
-    static constexpr size_t reportVersion = 4;
+    static constexpr size_t reportVersion = 6;
 };
diff --git a/src/report_factory.cpp b/src/report_factory.cpp
index 6c61cbe..57126b7 100644
--- a/src/report_factory.cpp
+++ b/src/report_factory.cpp
@@ -17,10 +17,9 @@
 {}
 
 std::unique_ptr<interfaces::Report> ReportFactory::make(
-    const std::string& name, const std::string& reportingTypeStr,
-    bool emitsReadingsSignal, bool logToMetricReportsCollection,
-    Milliseconds period, uint64_t appendLimit,
-    const std::string& reportUpdatesStr,
+    const std::string& name, const ReportingType reportingType,
+    const std::vector<ReportAction>& reportActions, Milliseconds period,
+    uint64_t appendLimit, const ReportUpdates reportUpdates,
     interfaces::ReportManager& reportManager,
     interfaces::JsonStorage& reportStorage,
     std::vector<LabeledMetricParameters> labeledMetricParams,
@@ -41,12 +40,8 @@
                 std::make_unique<Clock>());
         });
 
-    const ReportingType reportingType = stringToReportingType(reportingTypeStr);
-    const ReportUpdates reportUpdates = stringToReportUpdates(reportUpdatesStr);
-
     return std::make_unique<Report>(bus->get_io_context(), objServer, name,
-                                    reportingType, emitsReadingsSignal,
-                                    logToMetricReportsCollection, period,
+                                    reportingType, reportActions, period,
                                     appendLimit, reportUpdates, reportManager,
                                     reportStorage, std::move(metrics), enabled);
 }
@@ -99,9 +94,8 @@
         }
 
         return LabeledMetricParameters(
-            std::move(sensorParameters),
-            utils::stringToOperationType(operationType), id, metadata,
-            utils::stringToCollectionTimeScope(collectionTimeScope),
+            std::move(sensorParameters), utils::toOperationType(operationType),
+            id, metadata, utils::toCollectionTimeScope(collectionTimeScope),
             CollectionDuration(Milliseconds(collectionDuration)));
     });
 }
diff --git a/src/report_factory.hpp b/src/report_factory.hpp
index 9f68972..15f5898 100644
--- a/src/report_factory.hpp
+++ b/src/report_factory.hpp
@@ -20,10 +20,10 @@
         const ReadingParameters& metricParams) const override;
 
     std::unique_ptr<interfaces::Report>
-        make(const std::string& name, const std::string& reportingType,
-             bool emitsReadingsSignal, bool logToMetricReportsCollection,
+        make(const std::string& name, const ReportingType reportingType,
+             const std::vector<ReportAction>& reportActions,
              Milliseconds period, uint64_t appendLimitIn,
-             const std::string& reportUpdatesIn,
+             const ReportUpdates reportUpdatesIn,
              interfaces::ReportManager& reportManager,
              interfaces::JsonStorage& reportStorage,
              std::vector<LabeledMetricParameters> labeledMetricParams,
diff --git a/src/report_manager.cpp b/src/report_manager.cpp
index 21a9736..ab76a31 100644
--- a/src/report_manager.cpp
+++ b/src/report_manager.cpp
@@ -59,37 +59,53 @@
                     constexpr auto enabledDefault = true;
                     constexpr uint64_t appendLimitDefault = 0;
                     constexpr ReportUpdates reportUpdatesDefault =
-                        ReportUpdates::Overwrite;
-                    return addReport(
-                               yield, reportName, reportingType,
-                               emitsReadingsUpdate,
-                               logToMetricReportsCollection,
-                               Milliseconds(interval), appendLimitDefault,
-                               reportUpdatesToString(reportUpdatesDefault),
-                               convertToReadingParameters(
-                                   std::move(metricParams)),
-                               enabledDefault)
+                        ReportUpdates::overwrite;
+
+                    std::vector<ReportAction> reportActions;
+
+                    if (emitsReadingsUpdate)
+                    {
+                        reportActions.emplace_back(
+                            ReportAction::emitsReadingsUpdate);
+                    }
+                    if (logToMetricReportsCollection)
+                    {
+                        reportActions.emplace_back(
+                            ReportAction::logToMetricReportsCollection);
+                    }
+
+                    return addReport(yield, reportName,
+                                     utils::toReportingType(reportingType),
+                                     reportActions, Milliseconds(interval),
+                                     appendLimitDefault, reportUpdatesDefault,
+                                     convertToReadingParameters(
+                                         std::move(metricParams)),
+                                     enabledDefault)
                         .getPath();
                 });
 
             dbusIface.register_method(
                 "AddReportFutureVersion",
-
-                [this](
-                    boost::asio::yield_context& yield,
-                    const std::string& reportName,
-                    const std::string& reportingType,
-                    const std::string& reportUpdates,
-                    const uint64_t appendLimit, const bool emitsReadingsUpdate,
-                    const bool logToMetricReportsCollection,
-                    const uint64_t interval, ReadingParameters metricParams) {
+                [this](boost::asio::yield_context& yield,
+                       const std::string& reportName,
+                       const std::string& reportingType,
+                       const std::string& reportUpdates,
+                       const uint64_t appendLimit,
+                       const std::vector<std::string>& reportActions,
+                       const uint64_t interval,
+                       ReadingParameters metricParams) {
                     constexpr auto enabledDefault = true;
-                    return addReport(yield, reportName, reportingType,
-                                     emitsReadingsUpdate,
-                                     logToMetricReportsCollection,
+                    return addReport(yield, reportName,
+                                     utils::toReportingType(reportingType),
+                                     utils::transform(
+                                         reportActions,
+                                         [](const auto& reportAction) {
+                                             return utils::toReportAction(
+                                                 reportAction);
+                                         }),
                                      Milliseconds(interval), appendLimit,
-                                     reportUpdates, std::move(metricParams),
-                                     enabledDefault)
+                                     utils::toReportUpdates(reportUpdates),
+                                     std::move(metricParams), enabledDefault)
                         .getPath();
                 });
         });
@@ -114,10 +130,17 @@
 }
 
 void ReportManager::verifyAddReport(
-    const std::string& reportName, const std::string& reportingType,
-    Milliseconds interval, const std::string& reportUpdates,
+    const std::string& reportName, const ReportingType reportingType,
+    Milliseconds interval, const ReportUpdates reportUpdates,
     const std::vector<LabeledMetricParameters>& readingParams)
 {
+    if (reportingType == ReportingType::onChange)
+    {
+        throw sdbusplus::exception::SdBusError(
+            static_cast<int>(std::errc::invalid_argument),
+            "Invalid reportingType");
+    }
+
     if (reports.size() >= maxReports)
     {
         throw sdbusplus::exception::SdBusError(
@@ -136,17 +159,9 @@
         }
     }
 
-    if (std::find(supportedReportingType.begin(), supportedReportingType.end(),
-                  reportingType) == supportedReportingType.end())
-    {
-        throw sdbusplus::exception::SdBusError(
-            static_cast<int>(std::errc::invalid_argument),
-            "Invalid reportingType");
-    }
-
     verifyReportUpdates(reportUpdates);
 
-    if (reportingType == "Periodic" && interval < minInterval)
+    if (reportingType == ReportingType::periodic && interval < minInterval)
     {
         throw sdbusplus::exception::SdBusError(
             static_cast<int>(std::errc::invalid_argument), "Invalid interval");
@@ -179,24 +194,23 @@
 
 interfaces::Report& ReportManager::addReport(
     boost::asio::yield_context& yield, const std::string& reportName,
-    const std::string& reportingType, const bool emitsReadingsUpdate,
-    const bool logToMetricReportsCollection, Milliseconds interval,
-    const uint64_t appendLimit, const std::string& reportUpdates,
+    const ReportingType reportingType,
+    const std::vector<ReportAction>& reportActions, Milliseconds interval,
+    const uint64_t appendLimit, const ReportUpdates reportUpdates,
     ReadingParameters metricParams, const bool enabled)
 {
     auto labeledMetricParams =
         reportFactory->convertMetricParams(yield, metricParams);
 
-    return addReport(reportName, reportingType, emitsReadingsUpdate,
-                     logToMetricReportsCollection, interval, appendLimit,
-                     reportUpdates, std::move(labeledMetricParams), enabled);
+    return addReport(reportName, reportingType, reportActions, interval,
+                     appendLimit, reportUpdates, std::move(labeledMetricParams),
+                     enabled);
 }
 
 interfaces::Report& ReportManager::addReport(
-    const std::string& reportName, const std::string& reportingType,
-    const bool emitsReadingsUpdate, const bool logToMetricReportsCollection,
-    Milliseconds interval, const uint64_t appendLimit,
-    const std::string& reportUpdates,
+    const std::string& reportName, const ReportingType reportingType,
+    const std::vector<ReportAction>& reportActions, Milliseconds interval,
+    const uint64_t appendLimit, const ReportUpdates reportUpdates,
     std::vector<LabeledMetricParameters> labeledMetricParams,
     const bool enabled)
 {
@@ -204,9 +218,8 @@
                     labeledMetricParams);
 
     reports.emplace_back(reportFactory->make(
-        reportName, reportingType, emitsReadingsUpdate,
-        logToMetricReportsCollection, interval, appendLimit, reportUpdates,
-        *this, *reportStorage, labeledMetricParams, enabled));
+        reportName, reportingType, reportActions, interval, appendLimit,
+        reportUpdates, *this, *reportStorage, labeledMetricParams, enabled));
     return *reports.back();
 }
 
@@ -227,24 +240,24 @@
                 throw std::logic_error("Invalid version");
             }
             std::string& name = data->at("Name").get_ref<std::string&>();
-            std::string& reportingType =
-                data->at("ReportingType").get_ref<std::string&>();
-            bool emitsReadingsSignal =
-                data->at("EmitsReadingsUpdate").get<bool>();
-            bool logToMetricReportsCollection =
-                data->at("LogToMetricReportsCollection").get<bool>();
+
+            uint32_t reportingType = data->at("ReportingType").get<uint32_t>();
+            std::vector<ReportAction> reportActions = utils::transform(
+                data->at("ReportActions").get<std::vector<uint32_t>>(),
+                [](const auto reportAction) {
+                    return utils::toReportAction(reportAction);
+                });
             uint64_t interval = data->at("Interval").get<uint64_t>();
             uint64_t appendLimit = data->at("AppendLimit").get<uint64_t>();
-            std::string reportUpdates =
-                data->at("ReportUpdates").get<std::string>();
+            uint32_t reportUpdates = data->at("ReportUpdates").get<uint32_t>();
             auto readingParameters =
                 data->at("ReadingParameters")
                     .get<std::vector<LabeledMetricParameters>>();
 
-            addReport(name, reportingType, emitsReadingsSignal,
-                      logToMetricReportsCollection, Milliseconds(interval),
-                      appendLimit, reportUpdates, std::move(readingParameters),
-                      enabled);
+            addReport(name, utils::toReportingType(reportingType),
+                      reportActions, Milliseconds(interval), appendLimit,
+                      utils::toReportUpdates(reportUpdates),
+                      std::move(readingParameters), enabled);
         }
         catch (const std::exception& e)
         {
@@ -271,7 +284,7 @@
     }
 }
 
-void ReportManager::verifyReportUpdates(const std::string& reportUpdates)
+void ReportManager::verifyReportUpdates(const ReportUpdates reportUpdates)
 {
     if (std::find(supportedReportUpdates.begin(), supportedReportUpdates.end(),
                   reportUpdates) == supportedReportUpdates.end())
diff --git a/src/report_manager.hpp b/src/report_manager.hpp
index 32118c2..cc613e8 100644
--- a/src/report_manager.hpp
+++ b/src/report_manager.hpp
@@ -41,20 +41,19 @@
 
     void verifyReportNameLength(const std::string& reportName);
     void verifyAddReport(
-        const std::string& reportName, const std::string& reportingType,
-        Milliseconds interval, const std::string& reportUpdates,
+        const std::string& reportName, const ReportingType reportingType,
+        Milliseconds interval, const ReportUpdates reportUpdates,
         const std::vector<LabeledMetricParameters>& readingParams);
     interfaces::Report& addReport(
         boost::asio::yield_context& yield, const std::string& reportName,
-        const std::string& reportingType, const bool emitsReadingsUpdate,
-        const bool logToMetricReportsCollection, Milliseconds interval,
-        const uint64_t appendLimit, const std::string& reportUpdates,
+        const ReportingType reportingType,
+        const std::vector<ReportAction>& reportActions, Milliseconds interval,
+        const uint64_t appendLimit, const ReportUpdates reportUpdates,
         ReadingParameters metricParams, const bool enabled);
     interfaces::Report& addReport(
-        const std::string& reportName, const std::string& reportingType,
-        const bool emitsReadingsUpdate, const bool logToMetricReportsCollection,
-        Milliseconds interval, const uint64_t appendLimit,
-        const std::string& reportUpdates,
+        const std::string& reportName, const ReportingType reportingType,
+        const std::vector<ReportAction>& reportActions, Milliseconds interval,
+        const uint64_t appendLimit, const ReportUpdates reportUpdates,
         std::vector<LabeledMetricParameters> metricParams, const bool enabled);
     void loadFromPersistent();
 
@@ -69,10 +68,9 @@
         "xyz.openbmc_project.Telemetry.ReportManager";
     static constexpr const char* reportManagerPath =
         "/xyz/openbmc_project/Telemetry/Reports";
-    static constexpr std::array<std::string_view, 2> supportedReportingType = {
-        "Periodic", "OnRequest"};
-    static constexpr std::array<std::string_view, 3> supportedReportUpdates = {
-        "Overwrite", "AppendStopsWhenFull", "AppendWrapsWhenFull"};
+    static constexpr std::array<ReportUpdates, 3> supportedReportUpdates = {
+        ReportUpdates::overwrite, ReportUpdates::appendStopsWhenFull,
+        ReportUpdates::appendWrapsWhenFull};
 
-    static void verifyReportUpdates(const std::string& reportUpdates);
+    static void verifyReportUpdates(const ReportUpdates reportUpdates);
 };
diff --git a/src/sensor.cpp b/src/sensor.cpp
index 6e9eae8..644de2f 100644
--- a/src/sensor.cpp
+++ b/src/sensor.cpp
@@ -3,7 +3,6 @@
 #include <boost/container/flat_map.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/asio/property.hpp>
-#include <sdbusplus/bus/match.hpp>
 
 #include <functional>
 
diff --git a/src/trigger_factory.cpp b/src/trigger_factory.cpp
index 8980cc9..d5294c4 100644
--- a/src/trigger_factory.cpp
+++ b/src/trigger_factory.cpp
@@ -34,7 +34,7 @@
     std::transform(triggerActionsIn.begin(), triggerActionsIn.end(),
                    std::back_inserter(triggerActions),
                    [](auto& triggerActionStr) {
-                       return stringToTriggerAction(triggerActionStr);
+                       return toTriggerAction(triggerActionStr);
                    });
     std::vector<std::shared_ptr<interfaces::Threshold>> thresholds;
 
diff --git a/src/types/collection_time_scope.hpp b/src/types/collection_time_scope.hpp
index d2694d2..90c4fd3 100644
--- a/src/types/collection_time_scope.hpp
+++ b/src/types/collection_time_scope.hpp
@@ -29,13 +29,14 @@
 inline CollectionTimeScope
     toCollectionTimeScope(std::underlying_type_t<CollectionTimeScope> value)
 {
-    return toEnum<CollectionTimeScope, CollectionTimeScope::point,
-                  CollectionTimeScope::startup>(value);
+    return toEnum<CollectionTimeScope,
+                  minEnumValue(convDataCollectionTimeScope),
+                  maxEnumValue(convDataCollectionTimeScope)>(value);
 }
 
-inline CollectionTimeScope stringToCollectionTimeScope(const std::string& value)
+inline CollectionTimeScope toCollectionTimeScope(const std::string& value)
 {
-    return stringToEnum(convDataCollectionTimeScope, value);
+    return toEnum(convDataCollectionTimeScope, value);
 }
 
 inline std::string enumToString(CollectionTimeScope value)
@@ -43,4 +44,4 @@
     return std::string(enumToString(convDataCollectionTimeScope, value));
 }
 
-} // namespace utils
\ No newline at end of file
+} // namespace utils
diff --git a/src/types/operation_type.hpp b/src/types/operation_type.hpp
index a4f085c..5665e79 100644
--- a/src/types/operation_type.hpp
+++ b/src/types/operation_type.hpp
@@ -34,13 +34,13 @@
 inline OperationType
     toOperationType(std::underlying_type_t<OperationType> value)
 {
-    return toEnum<OperationType, OperationType::single, OperationType::sum>(
-        value);
+    return toEnum<OperationType, minEnumValue(convDataOperationType),
+                  maxEnumValue(convDataOperationType)>(value);
 }
 
-inline OperationType stringToOperationType(const std::string& value)
+inline OperationType toOperationType(const std::string& value)
 {
-    return stringToEnum(convDataOperationType, value);
+    return toEnum(convDataOperationType, value);
 }
 
 inline std::string enumToString(OperationType value)
diff --git a/src/types/report_action.hpp b/src/types/report_action.hpp
new file mode 100644
index 0000000..44348f2
--- /dev/null
+++ b/src/types/report_action.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "utils/conversion.hpp"
+
+#include <array>
+#include <cstdint>
+#include <string_view>
+#include <type_traits>
+
+enum class ReportAction : uint32_t
+{
+    emitsReadingsUpdate,
+    logToMetricReportsCollection
+};
+
+namespace utils
+{
+
+constexpr std::array<std::pair<std::string_view, ReportAction>, 2>
+    convDataReportAction = {
+        {std::make_pair<std::string_view, ReportAction>(
+             "EmitsReadingsUpdate", ReportAction::emitsReadingsUpdate),
+         std::make_pair<std::string_view, ReportAction>(
+             "LogToMetricReportsCollection",
+             ReportAction::logToMetricReportsCollection)}};
+
+inline ReportAction toReportAction(std::underlying_type_t<ReportAction> value)
+{
+    return toEnum<ReportAction, minEnumValue(convDataReportAction),
+                  maxEnumValue(convDataReportAction)>(value);
+}
+
+inline ReportAction toReportAction(const std::string& value)
+{
+    return toEnum(convDataReportAction, value);
+}
+
+inline std::string enumToString(ReportAction value)
+{
+    return std::string(enumToString(convDataReportAction, value));
+}
+
+} // namespace utils
\ No newline at end of file
diff --git a/src/types/report_types.hpp b/src/types/report_types.hpp
index b0b1a69..9d4a160 100644
--- a/src/types/report_types.hpp
+++ b/src/types/report_types.hpp
@@ -39,61 +39,3 @@
 
 ReadingParameters
     toReadingParameters(const std::vector<LabeledMetricParameters>& labeled);
-
-enum class ReportUpdates
-{
-    Overwrite = 0,
-    AppendStopsWhenFull,
-    AppendWrapsWhenFull,
-    NewReport
-};
-
-namespace details
-{
-constexpr std::array<std::pair<std::string_view, ReportUpdates>, 5>
-    convDataReportUpdates = {
-        std::make_pair("Overwrite", ReportUpdates::Overwrite),
-        std::make_pair("AppendStopsWhenFull",
-                       ReportUpdates::AppendStopsWhenFull),
-        std::make_pair("AppendWrapsWhenFull",
-                       ReportUpdates::AppendWrapsWhenFull),
-        std::make_pair("NewReport", ReportUpdates::NewReport)};
-
-} // namespace details
-
-inline ReportUpdates stringToReportUpdates(const std::string& str)
-{
-    return utils::stringToEnum(details::convDataReportUpdates, str);
-}
-
-inline std::string reportUpdatesToString(ReportUpdates v)
-{
-    return std::string(utils::enumToString(details::convDataReportUpdates, v));
-}
-
-enum class ReportingType
-{
-    OnChange = 0,
-    OnRequest,
-    Periodic
-};
-
-namespace details
-{
-constexpr std::array<std::pair<std::string_view, ReportingType>, 3>
-    convDataReportingType = {
-        std::make_pair("OnChange", ReportingType::OnChange),
-        std::make_pair("OnRequest", ReportingType::OnRequest),
-        std::make_pair("Periodic", ReportingType::Periodic)};
-
-} // namespace details
-
-inline ReportingType stringToReportingType(const std::string& str)
-{
-    return utils::stringToEnum(details::convDataReportingType, str);
-}
-
-inline std::string reportingTypeToString(ReportingType v)
-{
-    return std::string(utils::enumToString(details::convDataReportingType, v));
-}
diff --git a/src/types/report_updates.hpp b/src/types/report_updates.hpp
new file mode 100644
index 0000000..a47e8fb
--- /dev/null
+++ b/src/types/report_updates.hpp
@@ -0,0 +1,62 @@
+#pragma once
+
+#include "utils/conversion.hpp"
+
+#include <sdbusplus/exception.hpp>
+
+#include <array>
+#include <cstdint>
+#include <string_view>
+#include <type_traits>
+
+enum class ReportUpdates : uint32_t
+{
+    overwrite,
+    appendStopsWhenFull,
+    appendWrapsWhenFull,
+    newReport
+};
+
+namespace utils
+{
+
+template <>
+struct EnumTraits<ReportUpdates>
+{
+    [[noreturn]] static void throwConversionError()
+    {
+        throw sdbusplus::exception::SdBusError(
+            static_cast<int>(std::errc::invalid_argument),
+            "Invalid ReportUpdates");
+    }
+};
+
+constexpr std::array<std::pair<std::string_view, ReportUpdates>, 4>
+    convDataReportUpdates = {
+        {std::make_pair<std::string_view, ReportUpdates>(
+             "Overwrite", ReportUpdates::overwrite),
+         std::make_pair<std::string_view, ReportUpdates>(
+             "AppendStopsWhenFull", ReportUpdates::appendStopsWhenFull),
+         std::make_pair<std::string_view, ReportUpdates>(
+             "AppendWrapsWhenFull", ReportUpdates::appendWrapsWhenFull),
+         std::make_pair<std::string_view, ReportUpdates>(
+             "NewReport", ReportUpdates::newReport)}};
+
+inline ReportUpdates
+    toReportUpdates(std::underlying_type_t<ReportUpdates> value)
+{
+    return toEnum<ReportUpdates, minEnumValue(convDataReportUpdates),
+                  maxEnumValue(convDataReportUpdates)>(value);
+}
+
+inline ReportUpdates toReportUpdates(const std::string& value)
+{
+    return toEnum(convDataReportUpdates, value);
+}
+
+inline std::string enumToString(ReportUpdates value)
+{
+    return std::string(enumToString(convDataReportUpdates, value));
+}
+
+} // namespace utils
diff --git a/src/types/reporting_type.hpp b/src/types/reporting_type.hpp
new file mode 100644
index 0000000..ae0b60a
--- /dev/null
+++ b/src/types/reporting_type.hpp
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "utils/conversion.hpp"
+
+#include <sdbusplus/exception.hpp>
+
+#include <array>
+#include <cstdint>
+#include <string_view>
+#include <type_traits>
+
+enum class ReportingType : uint32_t
+{
+    periodic,
+    onRequest,
+    onChange
+};
+
+namespace utils
+{
+
+template <>
+struct EnumTraits<ReportingType>
+{
+    [[noreturn]] static void throwConversionError()
+    {
+        throw sdbusplus::exception::SdBusError(
+            static_cast<int>(std::errc::invalid_argument),
+            "Invalid reportingType");
+    }
+};
+
+constexpr std::array<std::pair<std::string_view, ReportingType>, 3>
+    convDataReportingType = {{std::make_pair<std::string_view, ReportingType>(
+                                  "Periodic", ReportingType::periodic),
+                              std::make_pair<std::string_view, ReportingType>(
+                                  "OnRequest", ReportingType::onRequest),
+                              std::make_pair<std::string_view, ReportingType>(
+                                  "OnChange", ReportingType::onChange)}};
+
+inline ReportingType
+    toReportingType(std::underlying_type_t<ReportingType> value)
+{
+    return toEnum<ReportingType, minEnumValue(convDataReportingType),
+                  maxEnumValue(convDataReportingType)>(value);
+}
+
+inline ReportingType toReportingType(const std::string& value)
+{
+    return toEnum(convDataReportingType, value);
+}
+
+inline std::string enumToString(ReportingType value)
+{
+    return std::string(enumToString(convDataReportingType, value));
+}
+
+} // namespace utils
diff --git a/src/types/trigger_types.hpp b/src/types/trigger_types.hpp
index a2a2e82..0ad9087 100644
--- a/src/types/trigger_types.hpp
+++ b/src/types/trigger_types.hpp
@@ -26,9 +26,9 @@
         std::make_pair("UpdateReport", TriggerAction::UpdateReport)};
 }
 
-inline TriggerAction stringToTriggerAction(const std::string& str)
+inline TriggerAction toTriggerAction(const std::string& str)
 {
-    return utils::stringToEnum(details::convDataTriggerAction, str);
+    return utils::toEnum(details::convDataTriggerAction, str);
 }
 
 namespace discrete
@@ -50,9 +50,9 @@
 
 } // namespace details
 
-inline Severity stringToSeverity(const std::string& str)
+inline Severity toSeverity(const std::string& str)
 {
-    return utils::stringToEnum(details::convDataSeverity, str);
+    return utils::toEnum(details::convDataSeverity, str);
 }
 
 inline std::string severityToString(Severity v)
@@ -103,9 +103,9 @@
 
 } // namespace details
 
-inline Type stringToType(const std::string& str)
+inline Type toType(const std::string& str)
 {
-    return utils::stringToEnum(details::convDataType, str);
+    return utils::toEnum(details::convDataType, str);
 }
 
 inline std::string typeToString(Type v)
@@ -113,9 +113,9 @@
     return std::string(utils::enumToString(details::convDataType, v));
 }
 
-inline Direction stringToDirection(const std::string& str)
+inline Direction toDirection(const std::string& str)
 {
-    return utils::stringToEnum(details::convDataDirection, str);
+    return utils::toEnum(details::convDataDirection, str);
 }
 
 inline std::string directionToString(Direction v)
diff --git a/src/utils/contains.hpp b/src/utils/contains.hpp
new file mode 100644
index 0000000..ea1dd16
--- /dev/null
+++ b/src/utils/contains.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <algorithm>
+
+namespace utils
+{
+namespace detail
+{
+
+template <class T>
+concept HasMemberFind = requires(T container)
+{
+    container.find(container.begin()->first);
+};
+
+} // namespace detail
+
+template <detail::HasMemberFind T>
+inline bool contains(const T& container,
+                     const typename T::value_type::first_type& key)
+{
+    return container.find(key) != container.end();
+}
+
+template <class T>
+inline bool contains(const T& container, const typename T::value_type& key)
+{
+    return std::find(container.begin(), container.end(), key) !=
+           container.end();
+}
+
+} // namespace utils
diff --git a/src/utils/conversion.hpp b/src/utils/conversion.hpp
index 5e8ef81..222b990 100644
--- a/src/utils/conversion.hpp
+++ b/src/utils/conversion.hpp
@@ -8,33 +8,72 @@
 namespace utils
 {
 
+template <class T>
+struct EnumTraits
+{
+    [[noreturn]] static void throwConversionError()
+    {
+        throw std::out_of_range("Value is not in range of enum");
+    }
+};
+
 template <class T, T first, T last>
 inline T toEnum(std::underlying_type_t<T> x)
 {
     if (x < static_cast<std::underlying_type_t<T>>(first) ||
         x > static_cast<std::underlying_type_t<T>>(last))
     {
-        throw std::out_of_range("Value is not in range of enum");
+        EnumTraits<T>::throwConversionError();
     }
     return static_cast<T>(x);
 }
 
 template <class T>
-inline std::underlying_type_t<T> toUnderlying(T value)
+constexpr inline std::underlying_type_t<T> toUnderlying(T value)
 {
     return static_cast<std::underlying_type_t<T>>(value);
 }
 
 template <class T, size_t N>
-inline T stringToEnum(const std::array<std::pair<std::string_view, T>, N>& data,
-                      const std::string& value)
+constexpr inline T
+    minEnumValue(std::array<std::pair<std::string_view, T>, N> data)
+{
+    auto min = data[0].second;
+    for (auto [key, value] : data)
+    {
+        if (toUnderlying(min) > toUnderlying(value))
+        {
+            min = value;
+        }
+    }
+    return min;
+}
+
+template <class T, size_t N>
+constexpr inline T
+    maxEnumValue(std::array<std::pair<std::string_view, T>, N> data)
+{
+    auto max = data[0].second;
+    for (auto [key, value] : data)
+    {
+        if (toUnderlying(max) < toUnderlying(value))
+        {
+            max = value;
+        }
+    }
+    return max;
+}
+
+template <class T, size_t N>
+inline T toEnum(const std::array<std::pair<std::string_view, T>, N>& data,
+                const std::string& value)
 {
     auto it = std::find_if(
         std::begin(data), std::end(data),
         [&value](const auto& item) { return item.first == value; });
     if (it == std::end(data))
     {
-        throw std::out_of_range("Value is not in range of enum");
+        EnumTraits<T>::throwConversionError();
     }
     return it->second;
 }
@@ -49,7 +88,7 @@
         [value](const auto& item) { return item.second == value; });
     if (it == std::end(data))
     {
-        throw std::out_of_range("Value is not in range of enum");
+        EnumTraits<T>::throwConversionError();
     }
     return it->first;
 }
diff --git a/src/utils/conversion_trigger.cpp b/src/utils/conversion_trigger.cpp
index 5aae0d5..aec0f28 100644
--- a/src/utils/conversion_trigger.cpp
+++ b/src/utils/conversion_trigger.cpp
@@ -22,9 +22,9 @@
     return utils::transform(arg, [](const auto& thresholdParam) {
         const auto& [type, dwellTime, direction, thresholdValue] =
             thresholdParam;
-        return numeric::LabeledThresholdParam(
-            numeric::stringToType(type), dwellTime,
-            numeric::stringToDirection(direction), thresholdValue);
+        return numeric::LabeledThresholdParam(numeric::toType(type), dwellTime,
+                                              numeric::toDirection(direction),
+                                              thresholdValue);
     });
 }
 
@@ -35,8 +35,7 @@
         const auto& [userId, severity, dwellTime, thresholdValue] =
             thresholdParam;
         return discrete::LabeledThresholdParam(
-            userId, discrete::stringToSeverity(severity), dwellTime,
-            thresholdValue);
+            userId, discrete::toSeverity(severity), dwellTime, thresholdValue);
     });
 }
 
diff --git a/tests/src/mocks/report_factory_mock.hpp b/tests/src/mocks/report_factory_mock.hpp
index f593883..cc0bc8e 100644
--- a/tests/src/mocks/report_factory_mock.hpp
+++ b/tests/src/mocks/report_factory_mock.hpp
@@ -19,9 +19,9 @@
                                      return LabeledSensorParameters("Service",
                                                                     sensorPath);
                                  }),
-                utils::stringToOperationType(std::get<1>(params)),
+                utils::toOperationType(std::get<1>(params)),
                 std::get<2>(params), std::get<3>(params),
-                utils::stringToCollectionTimeScope(std::get<4>(params)),
+                utils::toCollectionTimeScope(std::get<4>(params)),
                 CollectionDuration(Milliseconds(std::get<5>(params))));
         });
     }
@@ -35,8 +35,7 @@
             .WillByDefault(
                 WithArgs<1>(Invoke(&ReportFactoryMock::convertToLabeled)));
 
-        ON_CALL(*this,
-                make(A<const std::string&>(), _, _, _, _, _, _, _, _, _, _))
+        ON_CALL(*this, make(A<const std::string&>(), _, _, _, _, _, _, _, _, _))
             .WillByDefault(WithArgs<0>(Invoke([](const std::string& name) {
                 return std::make_unique<NiceMock<ReportMock>>(name);
             })));
@@ -47,10 +46,11 @@
                 (const, override));
 
     MOCK_METHOD(std::unique_ptr<interfaces::Report>, make,
-                (const std::string&, const std::string&, bool, bool,
-                 Milliseconds, uint64_t, const std::string&,
-                 interfaces::ReportManager&, interfaces::JsonStorage&,
-                 std::vector<LabeledMetricParameters>, bool),
+                (const std::string&, const ReportingType,
+                 const std::vector<ReportAction>&, Milliseconds, uint64_t,
+                 const ReportUpdates, interfaces::ReportManager&,
+                 interfaces::JsonStorage&, std::vector<LabeledMetricParameters>,
+                 bool),
                 (const, override));
 
     auto& expectMake(
@@ -62,17 +62,15 @@
         {
             const ReportParams& params = *paramsRef;
             return EXPECT_CALL(
-                *this,
-                make(params.reportName(), params.reportingType(),
-                     params.emitReadingUpdate(),
-                     params.logToMetricReportCollection(), params.interval(),
-                     params.appendLimit(), params.reportUpdates(), rm, js,
-                     params.metricParameters(), params.enabled()));
+                *this, make(params.reportName(), params.reportingType(),
+                            params.reportActions(), params.interval(),
+                            params.appendLimit(), params.reportUpdates(), rm,
+                            js, params.metricParameters(), params.enabled()));
         }
         else
         {
             using testing::_;
-            return EXPECT_CALL(*this, make(_, _, _, _, _, _, _, rm, js, _, _));
+            return EXPECT_CALL(*this, make(_, _, _, _, _, _, rm, js, _, _));
         }
     }
 };
diff --git a/tests/src/params/report_params.hpp b/tests/src/params/report_params.hpp
index d68f3fb..44ae901 100644
--- a/tests/src/params/report_params.hpp
+++ b/tests/src/params/report_params.hpp
@@ -20,37 +20,26 @@
         return reportNameProperty;
     }
 
-    ReportParams& reportingType(std::string val)
+    ReportParams& reportingType(const ReportingType val)
     {
-        reportingTypeProperty = std::move(val);
+        reportingTypeProperty = val;
         return *this;
     }
 
-    const std::string& reportingType() const
+    ReportingType reportingType() const
     {
         return reportingTypeProperty;
     }
 
-    ReportParams& emitReadingUpdate(bool val)
+    ReportParams& reportActions(std::vector<ReportAction> val)
     {
-        emitReadingUpdateProperty = val;
+        reportActionsProperty = std::move(val);
         return *this;
     }
 
-    bool emitReadingUpdate() const
+    std::vector<ReportAction> reportActions() const
     {
-        return emitReadingUpdateProperty;
-    }
-
-    ReportParams& logToMetricReportCollection(bool val)
-    {
-        logToMetricReportCollectionProperty = val;
-        return *this;
-    }
-
-    bool logToMetricReportCollection() const
-    {
-        return logToMetricReportCollectionProperty;
+        return reportActionsProperty;
     }
 
     ReportParams& interval(Milliseconds val)
@@ -86,13 +75,13 @@
         return appendLimitProperty;
     }
 
-    ReportParams& reportUpdates(std::string val)
+    ReportParams& reportUpdates(ReportUpdates val)
     {
         reportUpdatesProperty = val;
         return *this;
     }
 
-    std::string reportUpdates() const
+    ReportUpdates reportUpdates() const
     {
         return reportUpdatesProperty;
     }
@@ -110,12 +99,11 @@
 
   private:
     std::string reportNameProperty = "TestReport";
-    std::string reportingTypeProperty = "OnRequest";
-    bool emitReadingUpdateProperty = true;
-    bool logToMetricReportCollectionProperty = true;
+    ReportingType reportingTypeProperty = ReportingType::onRequest;
+    std::vector<ReportAction> reportActionsProperty;
     Milliseconds intervalProperty = ReportManager::minInterval;
     uint64_t appendLimitProperty = 123;
-    std::string reportUpdatesProperty = "Overwrite";
+    ReportUpdates reportUpdatesProperty = ReportUpdates::overwrite;
     std::vector<LabeledMetricParameters> metricParametersProperty{
         {LabeledMetricParameters{
              {LabeledSensorParameters{"Service",
diff --git a/tests/src/test_conversion.cpp b/tests/src/test_conversion.cpp
index f24592f..a61ff1b 100644
--- a/tests/src/test_conversion.cpp
+++ b/tests/src/test_conversion.cpp
@@ -16,12 +16,13 @@
 
     Enum toEnum(int x)
     {
-        return utils::toEnum<Enum, Enum::zero, Enum::two>(x);
+        return utils::toEnum<Enum, utils::minEnumValue(convDataEnum),
+                             utils::maxEnumValue(convDataEnum)>(x);
     }
 
-    Enum stringToEnum(const std::string& value)
+    Enum toEnum(const std::string& value)
     {
-        return utils::stringToEnum(convDataEnum, value);
+        return utils::toEnum(convDataEnum, value);
     }
 
     std::string enumToString(Enum value)
@@ -64,9 +65,9 @@
 
 TEST_F(TestConversion, convertsStringToEnum)
 {
-    EXPECT_THAT(stringToEnum("one"), Eq(Enum::one));
-    EXPECT_THAT(stringToEnum("two"), Eq(Enum::two));
-    EXPECT_THAT(stringToEnum("zero"), Eq(Enum::zero));
+    EXPECT_THAT(toEnum("one"), Eq(Enum::one));
+    EXPECT_THAT(toEnum("two"), Eq(Enum::two));
+    EXPECT_THAT(toEnum("zero"), Eq(Enum::zero));
 }
 
 TEST_F(TestConversion, enumToStringThrowsWhenUknownEnumPassed)
@@ -74,7 +75,7 @@
     EXPECT_THROW(enumToString(static_cast<Enum>(77)), std::out_of_range);
 }
 
-TEST_F(TestConversion, stringToEnumThrowsWhenUknownStringPassed)
+TEST_F(TestConversion, toEnumThrowsWhenUknownStringPassed)
 {
-    EXPECT_THROW(stringToEnum("four"), std::out_of_range);
+    EXPECT_THROW(toEnum("four"), std::out_of_range);
 }
diff --git a/tests/src/test_report.cpp b/tests/src/test_report.cpp
index f09ddef..7a56dac 100644
--- a/tests/src/test_report.cpp
+++ b/tests/src/test_report.cpp
@@ -6,7 +6,9 @@
 #include "params/report_params.hpp"
 #include "report.hpp"
 #include "report_manager.hpp"
+#include "utils/contains.hpp"
 #include "utils/conv_container.hpp"
+#include "utils/transform.hpp"
 #include "utils/tstring.hpp"
 
 #include <sdbusplus/exception.hpp>
@@ -68,11 +70,9 @@
 
         return std::make_unique<Report>(
             DbusEnvironment::getIoc(), DbusEnvironment::getObjServer(),
-            params.reportName(), stringToReportingType(params.reportingType()),
-            params.emitReadingUpdate(), params.logToMetricReportCollection(),
-            params.interval(), params.appendLimit(),
-            stringToReportUpdates(params.reportUpdates()), *reportManagerMock,
-            storageMock,
+            params.reportName(), params.reportingType(), params.reportActions(),
+            params.interval(), params.appendLimit(), params.reportUpdates(),
+            *reportManagerMock, storageMock,
             utils::convContainer<std::shared_ptr<interfaces::Metric>>(
                 metricMocks),
             params.enabled());
@@ -125,15 +125,24 @@
     EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "Interval"),
                 Eq(defaultParams.interval().count()));
     EXPECT_THAT(getProperty<bool>(sut->getPath(), "Persistency"), Eq(true));
+    EXPECT_THAT(
+        getProperty<std::vector<std::string>>(sut->getPath(), "ReportActions"),
+        Eq(utils::transform(defaultParams.reportActions(), [](const auto v) {
+            return utils::enumToString(v);
+        })));
     EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
-                Eq(defaultParams.emitReadingUpdate()));
+                Eq(utils::contains(defaultParams.reportActions(),
+                                   ReportAction::emitsReadingsUpdate)));
     EXPECT_THAT(getProperty<uint64_t>(sut->getPath(), "AppendLimit"),
                 Eq(defaultParams.appendLimit()));
+    EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
+                Eq(utils::enumToString(defaultParams.reportingType())));
     EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportUpdates"),
-                Eq(defaultParams.reportUpdates()));
+                Eq(utils::enumToString(defaultParams.reportUpdates())));
     EXPECT_THAT(
         getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
-        Eq(defaultParams.logToMetricReportCollection()));
+        Eq(utils::contains(defaultParams.reportActions(),
+                           ReportAction::logToMetricReportsCollection)));
     EXPECT_THAT(getProperty<ReadingParameters>(
                     sut->getPath(), "ReadingParametersFutureVersion"),
                 Eq(toReadingParameters(defaultParams.metricParameters())));
@@ -173,23 +182,24 @@
 
 TEST_F(TestReport, settingEmitsReadingsUpdateHaveNoEffect)
 {
-    EXPECT_THAT(setProperty(sut->getPath(), "EmitsReadingsUpdate",
-                            !defaultParams.emitReadingUpdate())
-                    .value(),
-                Eq(boost::system::errc::read_only_file_system));
+    EXPECT_THAT(
+        setProperty(sut->getPath(), "EmitsReadingsUpdate", true).value(),
+        Eq(boost::system::errc::read_only_file_system));
     EXPECT_THAT(getProperty<bool>(sut->getPath(), "EmitsReadingsUpdate"),
-                Eq(defaultParams.emitReadingUpdate()));
+                Eq(utils::contains(defaultParams.reportActions(),
+                                   ReportAction::emitsReadingsUpdate)));
 }
 
 TEST_F(TestReport, settingLogToMetricReportCollectionHaveNoEffect)
 {
-    EXPECT_THAT(setProperty(sut->getPath(), "LogToMetricReportsCollection",
-                            !defaultParams.logToMetricReportCollection())
-                    .value(),
-                Eq(boost::system::errc::read_only_file_system));
+    EXPECT_THAT(
+        setProperty(sut->getPath(), "LogToMetricReportsCollection", true)
+            .value(),
+        Eq(boost::system::errc::read_only_file_system));
     EXPECT_THAT(
         getProperty<bool>(sut->getPath(), "LogToMetricReportsCollection"),
-        Eq(defaultParams.logToMetricReportCollection()));
+        Eq(utils::contains(defaultParams.reportActions(),
+                           ReportAction::logToMetricReportsCollection)));
 }
 
 TEST_F(TestReport, settingPersistencyToFalseRemovesReportFromStorage)
@@ -237,15 +247,16 @@
 INSTANTIATE_TEST_SUITE_P(
     _, TestReportStore,
     Values(std::make_pair("Enabled"s, nlohmann::json(ReportParams().enabled())),
-           std::make_pair("Version"s, nlohmann::json(4)),
+           std::make_pair("Version"s, nlohmann::json(6)),
            std::make_pair("Name"s, nlohmann::json(ReportParams().reportName())),
            std::make_pair("ReportingType",
                           nlohmann::json(ReportParams().reportingType())),
-           std::make_pair("EmitsReadingsUpdate",
-                          nlohmann::json(ReportParams().emitReadingUpdate())),
-           std::make_pair(
-               "LogToMetricReportsCollection",
-               nlohmann::json(ReportParams().logToMetricReportCollection())),
+           std::make_pair("ReportActions", nlohmann::json(utils::transform(
+                                               ReportParams().reportActions(),
+                                               [](const auto v) {
+                                                   return utils::toUnderlying(
+                                                       v);
+                                               }))),
            std::make_pair("Interval",
                           nlohmann::json(ReportParams().interval().count())),
            std::make_pair(
@@ -365,14 +376,16 @@
     }
 };
 
-INSTANTIATE_TEST_SUITE_P(_, TestReportAllReportTypes,
-                         Values(ReportParams().reportingType("OnRequest"),
-                                ReportParams().reportingType("OnChange"),
-                                ReportParams().reportingType("Periodic")));
+INSTANTIATE_TEST_SUITE_P(
+    _, TestReportAllReportTypes,
+    Values(ReportParams().reportingType(ReportingType::onRequest),
+           ReportParams().reportingType(ReportingType::onChange),
+           ReportParams().reportingType(ReportingType::periodic)));
 
 TEST_P(TestReportAllReportTypes, returnPropertValueOfReportType)
 {
-    EXPECT_THAT(getProperty<std::string>(sut->getPath(), "ReportingType"),
+    EXPECT_THAT(utils::toReportingType(
+                    getProperty<std::string>(sut->getPath(), "ReportingType")),
                 Eq(GetParam().reportingType()));
 }
 
@@ -405,7 +418,8 @@
 {
     void SetUp() override
     {
-        sut = makeReport(ReportParams().reportingType("OnRequest"));
+        sut =
+            makeReport(ReportParams().reportingType(ReportingType::onRequest));
     }
 };
 
@@ -443,9 +457,10 @@
     }
 };
 
-INSTANTIATE_TEST_SUITE_P(_, TestReportNonOnRequestType,
-                         Values(ReportParams().reportingType("Periodic"),
-                                ReportParams().reportingType("OnChange")));
+INSTANTIATE_TEST_SUITE_P(
+    _, TestReportNonOnRequestType,
+    Values(ReportParams().reportingType(ReportingType::periodic),
+           ReportParams().reportingType(ReportingType::onChange)));
 
 TEST_P(TestReportNonOnRequestType, readingsAreNotUpdateOnUpdateCall)
 {
@@ -466,9 +481,10 @@
     }
 };
 
-INSTANTIATE_TEST_SUITE_P(_, TestReportNonPeriodicReport,
-                         Values(ReportParams().reportingType("OnRequest"),
-                                ReportParams().reportingType("OnChange")));
+INSTANTIATE_TEST_SUITE_P(
+    _, TestReportNonPeriodicReport,
+    Values(ReportParams().reportingType(ReportingType::onRequest),
+           ReportParams().reportingType(ReportingType::onChange)));
 
 TEST_P(TestReportNonPeriodicReport, readingsAreNotUpdatedAfterIntervalExpires)
 {
@@ -482,7 +498,7 @@
 {
     void SetUp() override
     {
-        sut = makeReport(ReportParams().reportingType("Periodic"));
+        sut = makeReport(ReportParams().reportingType(ReportingType::periodic));
     }
 };
 
@@ -523,7 +539,7 @@
     void SetUp() override
     {
         sut = makeReport(ReportParams(GetParam().reportParams)
-                             .reportingType("Periodic")
+                             .reportingType(ReportingType::periodic)
                              .interval(std::chrono::hours(1000)));
     }
 };
@@ -532,7 +548,9 @@
     _, TestReportWithReportUpdatesAndLimit,
     Values(
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendWrapsWhenFull").appendLimit(5),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendWrapsWhenFull)
+                .appendLimit(5),
             std::vector<ReadingData>{{std::make_tuple("aa"s, "bb"s, 42.0, 74u),
                                       std::make_tuple("a"s, "b"s, 17.1, 114u),
                                       std::make_tuple("aa"s, "bb"s, 42.0, 74u),
@@ -540,7 +558,9 @@
                                       std::make_tuple("a"s, "b"s, 17.1, 114u)}},
             true},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendWrapsWhenFull").appendLimit(4),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendWrapsWhenFull)
+                .appendLimit(4),
             std::vector<ReadingData>{
                 {std::make_tuple("a"s, "b"s, 17.1, 114u),
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u),
@@ -548,10 +568,14 @@
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
             true},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendWrapsWhenFull").appendLimit(0),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendWrapsWhenFull)
+                .appendLimit(0),
             std::vector<ReadingData>{}, true},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendStopsWhenFull").appendLimit(10),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendStopsWhenFull)
+                .appendLimit(10),
             std::vector<ReadingData>{
                 {std::make_tuple("a"s, "b"s, 17.1, 114u),
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u),
@@ -563,7 +587,9 @@
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
             true},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendStopsWhenFull").appendLimit(5),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendStopsWhenFull)
+                .appendLimit(5),
             std::vector<ReadingData>{{std::make_tuple("a"s, "b"s, 17.1, 114u),
                                       std::make_tuple("aa"s, "bb"s, 42.0, 74u),
                                       std::make_tuple("a"s, "b"s, 17.1, 114u),
@@ -571,7 +597,9 @@
                                       std::make_tuple("a"s, "b"s, 17.1, 114u)}},
             false},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendStopsWhenFull").appendLimit(4),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendStopsWhenFull)
+                .appendLimit(4),
             std::vector<ReadingData>{
                 {std::make_tuple("a"s, "b"s, 17.1, 114u),
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u),
@@ -579,22 +607,30 @@
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
             false},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("AppendStopsWhenFull").appendLimit(0),
+            ReportParams()
+                .reportUpdates(ReportUpdates::appendStopsWhenFull)
+                .appendLimit(0),
             std::vector<ReadingData>{}, false},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("Overwrite").appendLimit(500),
+            ReportParams()
+                .reportUpdates(ReportUpdates::overwrite)
+                .appendLimit(500),
             std::vector<ReadingData>{
                 {std::make_tuple("a"s, "b"s, 17.1, 114u),
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
             true},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("Overwrite").appendLimit(1),
+            ReportParams()
+                .reportUpdates(ReportUpdates::overwrite)
+                .appendLimit(1),
             std::vector<ReadingData>{
                 {std::make_tuple("a"s, "b"s, 17.1, 114u),
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
             true},
         ReportUpdatesReportParams{
-            ReportParams().reportUpdates("Overwrite").appendLimit(0),
+            ReportParams()
+                .reportUpdates(ReportUpdates::overwrite)
+                .appendLimit(0),
             std::vector<ReadingData>{
                 {std::make_tuple("a"s, "b"s, 17.1, 114u),
                  std::make_tuple("aa"s, "bb"s, 42.0, 74u)}},
@@ -686,8 +722,9 @@
             InvokeWithoutArgs(DbusEnvironment::setPromise("readingsUpdated")));
 
     const auto elapsed = DbusEnvironment::measureTime([this] {
-        sut = makeReport(
-            defaultParams.reportingType("Periodic").emitReadingUpdate(true));
+        sut =
+            makeReport(defaultParams.reportingType(ReportingType::periodic)
+                           .reportActions({ReportAction::emitsReadingsUpdate}));
         makeMonitor();
         EXPECT_TRUE(DbusEnvironment::waitForFuture("readingsUpdated"));
     });
@@ -702,7 +739,7 @@
     EXPECT_CALL(readingsUpdated, Call()).Times(0);
 
     sut = makeReport(
-        defaultParams.reportingType("Periodic").emitReadingUpdate(false));
+        defaultParams.reportingType(ReportingType::periodic).reportActions({}));
     makeMonitor();
     DbusEnvironment::sleepFor(defaultParams.interval() * 2);
 }
diff --git a/tests/src/test_report_manager.cpp b/tests/src/test_report_manager.cpp
index a740d95..1bf886c 100644
--- a/tests/src/test_report_manager.cpp
+++ b/tests/src/test_report_manager.cpp
@@ -48,8 +48,10 @@
         DbusEnvironment::synchronizeIoc();
     }
 
-    std::pair<boost::system::error_code, std::string>
-        addReport(const ReportParams& params)
+    template <class... Args>
+    requires(sizeof...(Args) > 1)
+        std::pair<boost::system::error_code, std::string> addReport(
+            Args&&... args)
     {
         std::promise<std::pair<boost::system::error_code, std::string>>
             addReportPromise;
@@ -60,13 +62,22 @@
             },
             DbusEnvironment::serviceName(), ReportManager::reportManagerPath,
             ReportManager::reportManagerIfaceName, "AddReportFutureVersion",
-            params.reportName(), params.reportingType(), params.reportUpdates(),
-            params.appendLimit(), params.emitReadingUpdate(),
-            params.logToMetricReportCollection(), params.interval().count(),
-            toReadingParameters(params.metricParameters()));
+            std::forward<Args>(args)...);
         return DbusEnvironment::waitForFuture(addReportPromise.get_future());
     }
 
+    auto addReport(const ReportParams& params)
+    {
+        return addReport(
+            params.reportName(), utils::enumToString(params.reportingType()),
+            utils::enumToString(params.reportUpdates()), params.appendLimit(),
+            utils::transform(
+                params.reportActions(),
+                [](const auto v) { return utils::enumToString(v); }),
+            params.interval().count(),
+            toReadingParameters(params.metricParameters()));
+    }
+
     template <class T>
     static T getProperty(const std::string& property)
     {
@@ -143,7 +154,7 @@
     reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
         .Times(0);
 
-    reportParams.reportingType("Periodic");
+    reportParams.reportingType(ReportingType::periodic);
     reportParams.interval(reportParams.interval() - 1ms);
 
     auto [ec, path] = addReport(reportParams);
@@ -157,9 +168,12 @@
     reportFactoryMock.expectMake(std::nullopt, Ref(*sut), Ref(storageMock))
         .Times(0);
 
-    reportParams.reportingType("Invalid");
-
-    auto [ec, path] = addReport(reportParams);
+    auto [ec, path] = addReport(
+        reportParams.reportName(), "InvalidReportingType",
+        utils::transform(reportParams.reportActions(),
+                         [](const auto v) { return utils::enumToString(v); }),
+        reportParams.interval().count(),
+        toReadingParameters(reportParams.metricParameters()));
 
     EXPECT_THAT(ec.value(), Eq(boost::system::errc::invalid_argument));
     EXPECT_THAT(path, Eq(std::string()));
@@ -331,12 +345,10 @@
         {"Enabled", reportParams.enabled()},
         {"Version", Report::reportVersion},
         {"Name", reportParams.reportName()},
-        {"ReportingType", reportParams.reportingType()},
-        {"EmitsReadingsUpdate", reportParams.emitReadingUpdate()},
-        {"LogToMetricReportsCollection",
-         reportParams.logToMetricReportCollection()},
+        {"ReportingType", utils::toUnderlying(reportParams.reportingType())},
+        {"ReportActions", reportParams.reportActions()},
         {"Interval", reportParams.interval().count()},
-        {"ReportUpdates", reportParams.reportUpdates()},
+        {"ReportUpdates", utils::toUnderlying(reportParams.reportUpdates())},
         {"AppendLimit", reportParams.appendLimit()},
         {"ReadingParameters", reportParams.metricParameters()}};
 };