created AddReportFutureVersion dbus method

New method will support CollectionTimeScope, CollectionDuration

In order to make not breaking interface changes bmcweb will switch to
AddReportFutureVersion, then AddReport will be changed to match
AddReportFutureVersion, then redfish will switch back to use AddReport,
then AddReportFutureVersion will be removed.

Tested:
  - Verified that current version of bmcweb works fine with old API

Signed-off-by: Krzysztof Grobelny <krzysztof.grobelny@intel.com>
Change-Id: I51a9b7fb2f4da5b8d2f688ccd5e93710352b1ac7
diff --git a/src/utils/conversion_trigger.hpp b/src/utils/conversion_trigger.hpp
index 7ed660f..5229e5e 100644
--- a/src/utils/conversion_trigger.hpp
+++ b/src/utils/conversion_trigger.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
 #include "interfaces/json_storage.hpp"
-#include "interfaces/trigger_types.hpp"
+#include "types/trigger_types.hpp"
 
 namespace utils
 {
diff --git a/src/utils/detached_timer.hpp b/src/utils/detached_timer.hpp
index 224e5a1..636949c 100644
--- a/src/utils/detached_timer.hpp
+++ b/src/utils/detached_timer.hpp
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "types/milliseconds.hpp"
+
 #include <boost/asio/io_context.hpp>
 #include <boost/asio/steady_timer.hpp>
 
@@ -9,8 +11,8 @@
 {
 
 template <class F>
-void makeDetachedTimer(boost::asio::io_context& ioc,
-                       std::chrono::milliseconds delay, F&& fun)
+void makeDetachedTimer(boost::asio::io_context& ioc, Milliseconds delay,
+                       F&& fun)
 {
     auto timer = std::make_unique<boost::asio::steady_timer>(ioc);
     timer->expires_after(delay);
diff --git a/src/utils/json.hpp b/src/utils/json.hpp
new file mode 100644
index 0000000..2ae606f
--- /dev/null
+++ b/src/utils/json.hpp
@@ -0,0 +1,63 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+
+#include <string_view>
+
+namespace utils
+{
+
+template <class T>
+struct is_vector : std::false_type
+{};
+
+template <class T>
+struct is_vector<std::vector<T>> : std::true_type
+{};
+
+template <class T>
+constexpr bool is_vector_v = is_vector<T>::value;
+
+template <class T>
+std::optional<T> readJson(const nlohmann::json& json)
+{
+    if constexpr (is_vector_v<T>)
+    {
+        if (json.is_array())
+        {
+            auto result = T{};
+            for (const auto& item : json.items())
+            {
+                if (auto val = readJson<typename T::value_type>(item.value()))
+                {
+                    result.emplace_back(*val);
+                }
+            }
+            return result;
+        }
+    }
+    else
+    {
+        if (const T* val = json.get_ptr<const T*>())
+        {
+            return *val;
+        }
+    }
+
+    return std::nullopt;
+}
+
+template <class T>
+std::optional<T> readJson(const nlohmann::json& json, std::string_view key)
+{
+    auto it = json.find(key);
+    if (it != json.end())
+    {
+        const nlohmann::json& subJson = *it;
+        return readJson<T>(subJson);
+    }
+
+    return std::nullopt;
+}
+
+} // namespace utils
diff --git a/src/utils/labeled_tuple.hpp b/src/utils/labeled_tuple.hpp
index 795f37f..a224141 100644
--- a/src/utils/labeled_tuple.hpp
+++ b/src/utils/labeled_tuple.hpp
@@ -170,15 +170,15 @@
 };
 
 template <class... Args, class... Labels>
-void to_json(nlohmann::json& json,
-             const LabeledTuple<std::tuple<Args...>, Labels...>& tuple)
+inline void to_json(nlohmann::json& json,
+                    const LabeledTuple<std::tuple<Args...>, Labels...>& tuple)
 {
     json = tuple.to_json();
 }
 
 template <class... Args, class... Labels>
-void from_json(const nlohmann::json& json,
-               LabeledTuple<std::tuple<Args...>, Labels...>& tuple)
+inline void from_json(const nlohmann::json& json,
+                      LabeledTuple<std::tuple<Args...>, Labels...>& tuple)
 {
     tuple.from_json(json);
 }
diff --git a/src/utils/tstring.hpp b/src/utils/tstring.hpp
index 5b17d98..8f9701a 100644
--- a/src/utils/tstring.hpp
+++ b/src/utils/tstring.hpp
@@ -112,5 +112,21 @@
     }
 };
 
+struct CollectionTimeScope
+{
+    static std::string str()
+    {
+        return "collectionTimeScope";
+    }
+};
+
+struct CollectionDuration
+{
+    static std::string str()
+    {
+        return "collectionDuration";
+    }
+};
+
 } // namespace tstring
 } // namespace utils