Implement Report persistency
Now Report properties are stored in non-volatile memory. It allows
to restore Report after system restart. Persistency of a report is
controlled by Persistency property in Report interface.
Tested:
- Passed unit tests
- Verified that report is stored in /var/lib/telemetry dir
- Verified that report is restored from storage after telemetry
service start
Signed-off-by: Wludzik, Jozef <jozef.wludzik@intel.com>
Change-Id: Iccfe21603eecffc4e174a4403f699b03de320db9
diff --git a/src/utils/labeled_tuple.hpp b/src/utils/labeled_tuple.hpp
new file mode 100644
index 0000000..7e75322
--- /dev/null
+++ b/src/utils/labeled_tuple.hpp
@@ -0,0 +1,117 @@
+#pragma once
+
+#include <nlohmann/json.hpp>
+#include <sdbusplus/message/types.hpp>
+
+namespace utils
+{
+
+inline void from_json(const nlohmann::json& j,
+ sdbusplus::message::object_path& o)
+{
+ o = j.get<std::string>();
+}
+
+inline void from_json(const nlohmann::json& j,
+ std::vector<sdbusplus::message::object_path>& o)
+{
+ o.clear();
+ for (const nlohmann::json& item : j)
+ {
+ o.emplace_back(item.get<std::string>());
+ }
+}
+
+namespace detail
+{
+
+template <class T>
+struct has_utils_from_json
+{
+ template <class U>
+ static U& ref();
+
+ template <class U>
+ static std::true_type check(
+ decltype(utils::from_json(ref<const nlohmann::json>(), ref<U>()))*);
+
+ template <class>
+ static std::false_type check(...);
+
+ static constexpr bool value =
+ decltype(check<std::decay_t<T>>(nullptr))::value;
+};
+
+template <class T>
+constexpr bool has_utils_from_json_v = has_utils_from_json<T>::value;
+
+} // namespace detail
+
+template <class, class...>
+struct LabeledTuple;
+
+template <class... Args, class... Labels>
+struct LabeledTuple<std::tuple<Args...>, Labels...>
+{
+ LabeledTuple() = delete;
+
+ static_assert(sizeof...(Args) == sizeof...(Labels));
+
+ static nlohmann::json to_json(const std::tuple<Args...>& tuple)
+ {
+ nlohmann::json j;
+ to_json_all(j, tuple, std::make_index_sequence<sizeof...(Args)>());
+ return j;
+ }
+
+ static std::tuple<Args...> from_json(const nlohmann::json& j)
+ {
+ std::tuple<Args...> value;
+ from_json_all(j, value, std::make_index_sequence<sizeof...(Args)>());
+ return value;
+ }
+
+ private:
+ template <size_t... Idx>
+ static void to_json_all(nlohmann::json& j, const std::tuple<Args...>& tuple,
+ std::index_sequence<Idx...>)
+ {
+ (to_json_item<Idx>(j, tuple), ...);
+ }
+
+ template <size_t Idx>
+ static void to_json_item(nlohmann::json& j,
+ const std::tuple<Args...>& tuple)
+ {
+ using Label = std::tuple_element_t<Idx, std::tuple<Labels...>>;
+ j[Label::str()] = std::get<Idx>(tuple);
+ }
+
+ template <size_t... Idx>
+ static void from_json_all(const nlohmann::json& j,
+ std::tuple<Args...>& value,
+ std::index_sequence<Idx...>)
+ {
+ (from_json_item<Idx>(j, value), ...);
+ }
+
+ template <size_t Idx>
+ static void from_json_item(const nlohmann::json& j,
+ std::tuple<Args...>& value)
+ {
+ using Label = std::tuple_element_t<Idx, std::tuple<Labels...>>;
+ using T = std::tuple_element_t<Idx, std::tuple<Args...>>;
+ const nlohmann::json& item = j.at(Label::str());
+ if constexpr (detail::has_utils_from_json_v<T>)
+ {
+ T& v = std::get<Idx>(value);
+ utils::from_json(item, v);
+ }
+ else
+ {
+ std::get<Idx>(value) = item.get<T>();
+ }
+ }
+};
+
+} // namespace utils