Add Links/Triggers to MetricReportDefinition

This change is adding Triggers property to Links when GET is called on
MetricReportDefinition. It contains array of @odata.id pointing to
Trigger resource if it is also linking to given MRD.

Testing done:
- Links/Trigger property is returned by GET request on
  /redfish/v1/TelemetryService/MetricReportDefinitions/<str>/

Signed-off-by: Szymon Dompke <szymon.dompke@intel.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I5accf4b50324437b0b185003200078ad2c7020b0
diff --git a/include/dbus_utility.hpp b/include/dbus_utility.hpp
index ee9aaab..c863c30 100644
--- a/include/dbus_utility.hpp
+++ b/include/dbus_utility.hpp
@@ -67,6 +67,7 @@
     std::vector<uint16_t>,
     sdbusplus::message::object_path,
     std::tuple<uint64_t, std::vector<std::tuple<std::string, double, uint64_t>>>,
+    std::vector<sdbusplus::message::object_path>,
     std::vector<std::tuple<std::string, std::string>>,
     std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>,
     std::vector<std::tuple<uint32_t, size_t>>,
diff --git a/redfish-core/lib/metric_report_definition.hpp b/redfish-core/lib/metric_report_definition.hpp
index 185c298..6a03b7f 100644
--- a/redfish-core/lib/metric_report_definition.hpp
+++ b/redfish-core/lib/metric_report_definition.hpp
@@ -18,9 +18,14 @@
 
 #include <array>
 #include <map>
+#include <optional>
+#include <span>
+#include <string>
 #include <string_view>
 #include <tuple>
+#include <utility>
 #include <variant>
+#include <vector>
 
 namespace redfish
 {
@@ -176,6 +181,37 @@
     return "";
 }
 
+inline std::optional<nlohmann::json::array_t> getLinkedTriggers(
+    std::span<const sdbusplus::message::object_path> triggerPaths)
+{
+    nlohmann::json::array_t triggers;
+
+    for (const sdbusplus::message::object_path& path : triggerPaths)
+    {
+        if (path.parent_path() !=
+            "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService")
+        {
+            BMCWEB_LOG_ERROR << "Property Triggers contains invalid value: "
+                             << path.str;
+            return std::nullopt;
+        }
+
+        std::string id = path.filename();
+        if (id.empty())
+        {
+            BMCWEB_LOG_ERROR << "Property Triggers contains invalid value: "
+                             << path.str;
+            return std::nullopt;
+        }
+        nlohmann::json::object_t trigger;
+        trigger["@odata.id"] =
+            boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
+        triggers.emplace_back(std::move(trigger));
+    }
+
+    return triggers;
+}
+
 inline void
     fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                          const std::string& id,
@@ -189,12 +225,14 @@
     uint64_t appendLimit = 0;
     uint64_t interval = 0;
     bool enabled = false;
+    std::vector<sdbusplus::message::object_path> triggers;
 
     const bool success = sdbusplus::unpackPropertiesNoThrow(
         dbus_utils::UnpackErrorPrinter(), properties, "ReportingType",
         reportingType, "Interval", interval, "ReportActions", reportActions,
         "ReportUpdates", reportUpdates, "AppendLimit", appendLimit,
-        "ReadingParameters", readingParams, "Name", name, "Enabled", enabled);
+        "ReadingParameters", readingParams, "Name", name, "Enabled", enabled,
+        "Triggers", triggers);
 
     if (!success)
     {
@@ -214,6 +252,16 @@
     asyncResp->res.jsonValue["MetricReportDefinitionType"] =
         redfishReportingType;
 
+    std::optional<nlohmann::json::array_t> linkedTriggers =
+        getLinkedTriggers(triggers);
+    if (!linkedTriggers)
+    {
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    asyncResp->res.jsonValue["Links"]["Triggers"] = std::move(*linkedTriggers);
+
     nlohmann::json::array_t redfishReportActions;
     for (const std::string& action : reportActions)
     {