Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Taggable.hpp
1#pragma once
2
3#include "util/Assert.hpp"
4#include "util/config/ConfigDefinition.hpp"
5
6#include <boost/algorithm/string/predicate.hpp>
7#include <boost/json.hpp>
8#include <boost/json/conversion.hpp>
9#include <boost/json/value.hpp>
10#include <boost/uuid/uuid.hpp>
11#include <boost/uuid/uuid_io.hpp>
12
13#include <atomic>
14#include <functional>
15#include <memory>
16#include <optional>
17#include <ostream>
18#include <string>
19#include <string_view>
20#include <utility>
21
22namespace util {
23namespace impl {
24
28struct NullTagGenerator final {};
29
33struct UIntTagGenerator final {
34 using TagType = std::atomic_uint64_t;
35
36 static TagType
37 next();
38};
39
43struct UUIDTagGenerator final {
44 using TagType = boost::uuids::uuid;
45
46 static TagType
47 next();
48};
49
50} // namespace impl
51
56public:
57 virtual ~BaseTagDecorator() = default;
58
64 virtual void
65 decorate(std::ostream& os) const = 0;
66
74 friend std::ostream&
75 operator<<(std::ostream& os, BaseTagDecorator const& decorator)
76 {
77 decorator.decorate(os);
78 return os;
79 }
80
86 std::string
87 toString() const
88 {
89 std::ostringstream oss;
90 decorate(oss);
91 return std::move(oss).str();
92 }
93};
94
100template <typename Generator>
101class TagDecorator final : public BaseTagDecorator {
102 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
103 using TagType = typename Generator::TagType;
104
105 ParentType parent_ = std::nullopt;
106 TagType tag_ = Generator::next();
107
108public:
120 explicit TagDecorator(ParentType parent = std::nullopt) : parent_{parent}
121 {
122 }
123
129 void
130 decorate(std::ostream& os) const override
131 {
132 os << "[";
133
134 if (parent_.has_value())
135 (*parent_).get().decorate(os);
136
137 os << tag_ << "] ";
138 }
139};
140
147template <>
148class TagDecorator<impl::NullTagGenerator> final : public BaseTagDecorator {
149public:
155 void
156 decorate([[maybe_unused]] std::ostream& os) const override
157 {
158 // nop
159 }
160};
161
166 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
167
171 enum class Type {
172 NONE,
173 UUID,
174 UINT
175 };
176
177 Type type_; /*< The type of TagDecorator this factory produces */
178 ParentType parent_ = std::nullopt; /*< The parent tag decorator to bind */
179
180 static Type
181 getLogTagType(std::string_view style)
182 {
183 if (boost::iequals(style, "int") || boost::iequals(style, "uint"))
184 return TagDecoratorFactory::Type::UINT;
185
186 if (boost::iequals(style, "null") || boost::iequals(style, "none"))
187 return TagDecoratorFactory::Type::NONE;
188
189 if (boost::iequals(style, "uuid"))
190 return TagDecoratorFactory::Type::UUID;
191
192 ASSERT(false, "log.tag_style does not have valid value");
193 std::unreachable();
194 }
195
196public:
197 ~TagDecoratorFactory() = default;
198
205 : type_{getLogTagType(config.get<std::string>("log.tag_style"))}
206 {
207 }
208
209private:
210 TagDecoratorFactory(Type type, ParentType parent) noexcept : type_{type}, parent_{parent}
211 {
212 }
213
214public:
220 std::unique_ptr<BaseTagDecorator>
221 make() const;
222
230 with(ParentType parent) const noexcept;
231};
232
236class Taggable {
237 using DecoratorType = std::unique_ptr<BaseTagDecorator>;
238 DecoratorType tagDecorator_;
239
240protected:
246 explicit Taggable(util::TagDecoratorFactory const& tagFactory)
247 : tagDecorator_{tagFactory.make()}
248 {
249 }
250
251public:
252 virtual ~Taggable() = default;
253 Taggable(Taggable&&) = default;
254
255 Taggable&
256 operator=(Taggable&&) = default;
257
263 BaseTagDecorator const&
264 tag() const
265 {
266 return *tagDecorator_;
267 }
268};
269
270} // namespace util
Represents any tag decorator.
Definition Taggable.hpp:55
virtual void decorate(std::ostream &os) const =0
Decorates a std::ostream.
friend std::ostream & operator<<(std::ostream &os, BaseTagDecorator const &decorator)
Support for decorating streams (boost log, cout, etc.).
Definition Taggable.hpp:75
std::string toString() const
Gets the string representation of the tag.
Definition Taggable.hpp:87
A factory for TagDecorator instantiation.
Definition Taggable.hpp:165
std::unique_ptr< BaseTagDecorator > make() const
Instantiates the TagDecorator specified by type_ with parent bound from parent_.
Definition Taggable.cpp:33
TagDecoratorFactory(util::config::ClioConfigDefinition const &config)
Instantiates a tag decorator factory from clio configuration.
Definition Taggable.hpp:204
TagDecoratorFactory with(ParentType parent) const noexcept
Creates a new tag decorator factory with a bound parent tag decorator.
Definition Taggable.cpp:47
void decorate(std::ostream &os) const override
Nop implementation for the decorator.
Definition Taggable.hpp:156
void decorate(std::ostream &os) const override
Implementation of the decoration. Chaining tags when parent is available.
Definition Taggable.hpp:130
TagDecorator(ParentType parent=std::nullopt)
Create a new tag decorator with an optional parent.
Definition Taggable.hpp:120
A base class that allows attaching a tag decorator to a subclass.
Definition Taggable.hpp:236
BaseTagDecorator const & tag() const
Getter for tag decorator.
Definition Taggable.hpp:264
Taggable(util::TagDecoratorFactory const &tagFactory)
New Taggable from a specified factory.
Definition Taggable.hpp:246
All the config data will be stored and extracted from this class.
Definition ConfigDefinition.hpp:31
This namespace contains various utilities.
Definition AccountUtils.hpp:11
A null tag generator - does nothing.
Definition Taggable.hpp:28
This strategy uses an atomic_uint64_t to remain lock free.
Definition Taggable.hpp:33
This strategy uses boost::uuids::uuid with a static random generator and a mutex.
Definition Taggable.hpp:43