C++ Server-Side SDK
LaunchDarkly SDK
Loading...
Searching...
No Matches
json_deserializer.hpp
1#pragma once
2
3#include "../../../include/launchdarkly/server_side/integrations/data_reader/kinds.hpp"
4#include "../../data_interfaces/source/idata_reader.hpp"
5
6#include <launchdarkly/logging/logger.hpp>
7#include <launchdarkly/serialization/value_mapping.hpp>
8#include <launchdarkly/server_side/integrations/data_reader/iserialized_data_reader.hpp>
9
10#include <memory>
11
12namespace launchdarkly {
13
14tl::expected<std::optional<data_model::Tombstone>, JsonError> tag_invoke(
15 boost::json::value_to_tag<tl::expected<std::optional<data_model::Tombstone>,
16 JsonError>> const& unused,
17 boost::json::value const& json_value);
18} // namespace launchdarkly
19
20namespace launchdarkly::server_side::data_components {
21
23 public:
24 explicit JsonDeserializer(
25 Logger const& logger,
26 std::shared_ptr<integrations::ISerializedDataReader> reader);
27
28 [[nodiscard]] SingleResult<data_model::Flag> GetFlag(
29 std::string const& key) const override;
30
31 [[nodiscard]] SingleResult<data_model::Segment> GetSegment(
32 std::string const& key) const override;
33
34 [[nodiscard]] CollectionResult<data_model::Flag> AllFlags() const override;
35
36 [[nodiscard]] CollectionResult<data_model::Segment> AllSegments()
37 const override;
38
39 [[nodiscard]] std::string const& Identity() const override;
40
41 [[nodiscard]] bool Initialized() const override;
42
43 private:
44 template <typename Item>
45 static tl::expected<data_model::ItemDescriptor<Item>,
46 data_interfaces::IDataReader::Error>
47 DeserializeJsonDescriptor(
49 if (descriptor.deleted) {
50 return data_model::ItemDescriptor<Item>(
51 data_model::Tombstone(descriptor.version));
52 }
53
54 auto const json_val = boost::json::parse(descriptor.serializedItem);
55
56 if (auto item_result = boost::json::value_to<
57 tl::expected<std::optional<Item>, JsonError>>(json_val)) {
58 auto item = *item_result;
59 if (!item) {
60 return tl::make_unexpected("item invalid: value is null");
61 }
62 return data_model::ItemDescriptor<Item>(std::move(*item));
63 }
64
65 auto tombstone = boost::json::value_to<
66 tl::expected<std::optional<data_model::Tombstone>, JsonError>>(
67 json_val);
68 if (!tombstone) {
69 return tl::make_unexpected(ErrorToString(tombstone.error()));
70 }
71 auto tombstone_result = *tombstone;
72 if (!tombstone_result) {
73 return tl::make_unexpected("tombstone invalid: value is null");
74 }
75 return data_model::ItemDescriptor<Item>(*tombstone_result);
76 }
77
78 template <typename DataModel, typename DataKind>
79 SingleResult<DataModel> DeserializeSingle(DataKind const& kind,
80 std::string const& key) const {
81 auto result = source_->Get(kind, key);
82
83 if (!result) {
84 /* error in fetching the item */
85 return tl::make_unexpected(result.error().message);
86 }
87
88 auto serialized_item = *result;
89
90 if (!serialized_item) {
91 return std::nullopt;
92 }
93
94 return DeserializeJsonDescriptor<DataModel>(*serialized_item);
95 }
96
97 template <typename DataModel, typename DataKind>
98 CollectionResult<DataModel> DeserializeCollection(
99 DataKind const& kind) const {
100 auto result = source_->All(kind);
101
102 if (!result) {
103 /* error in fetching the items */
104 return tl::make_unexpected(result.error().message);
105 }
106
107 Collection<DataModel> items;
108
109 for (auto const& [key, descriptor] : *result) {
110 auto item = DeserializeJsonDescriptor<DataModel>(descriptor);
111
112 if (!item) {
113 LD_LOG(logger_, LogLevel::kError)
114 << "failed to deserialize " << key << " while fetching all "
115 << kind.Namespace() << ": " << item.error();
116 continue;
117 }
118
119 items.emplace(key, *item);
120 }
121 return items;
122 }
123
124 Logger const& logger_;
125 integrations::FlagKind const flag_kind_;
126 integrations::SegmentKind const segment_kind_;
127 std::shared_ptr<integrations::ISerializedDataReader> source_;
128 std::string const identity_;
129};
130
131} // namespace launchdarkly::server_side::data_components
SingleResult< data_model::Segment > GetSegment(std::string const &key) const override
Attempts to get a segment named by key.
Definition json_deserializer.cpp:52
CollectionResult< data_model::Segment > AllSegments() const override
Attempts to get a collection of all segments.
Definition json_deserializer.cpp:62
bool Initialized() const override
Definition json_deserializer.cpp:70
std::string const & Identity() const override
Definition json_deserializer.cpp:66
SingleResult< data_model::Flag > GetFlag(std::string const &key) const override
Attempts to get a flag named by key.
Definition json_deserializer.cpp:47
CollectionResult< data_model::Flag > AllFlags() const override
Attempts to get a collection of all flags.
Definition json_deserializer.cpp:57
IDataReader obtains data on-demand. Calls to obtain data may fail, so the getter methods use tl::expe...
Definition idata_reader.hpp:21
Definition serialized_item_descriptor.hpp:12
bool deleted
Definition serialized_item_descriptor.hpp:21