Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
Taggable.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2022, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "util/Assert.hpp"
23#include "util/config/ConfigDefinition.hpp"
24
25#include <boost/algorithm/string/predicate.hpp>
26#include <boost/json.hpp>
27#include <boost/json/conversion.hpp>
28#include <boost/json/value.hpp>
29#include <boost/uuid/uuid.hpp>
30#include <boost/uuid/uuid_io.hpp>
31
32#include <atomic>
33#include <functional>
34#include <memory>
35#include <optional>
36#include <ostream>
37#include <string>
38#include <string_view>
39#include <utility>
40
41namespace util {
42namespace impl {
43
47struct NullTagGenerator final {};
48
52struct UIntTagGenerator final {
53 using TagType = std::atomic_uint64_t;
54
55 static TagType
56 next();
57};
58
62struct UUIDTagGenerator final {
63 using TagType = boost::uuids::uuid;
64
65 static TagType
66 next();
67};
68
69} // namespace impl
70
75public:
76 virtual ~BaseTagDecorator() = default;
77
83 virtual void
84 decorate(std::ostream& os) const = 0;
85
93 friend std::ostream&
94 operator<<(std::ostream& os, BaseTagDecorator const& decorator)
95 {
96 decorator.decorate(os);
97 return os;
98 }
99
105 std::string
106 toString() const
107 {
108 std::ostringstream oss;
109 decorate(oss);
110 return std::move(oss).str();
111 }
112};
113
119template <typename Generator>
120class TagDecorator final : public BaseTagDecorator {
121 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
122 using TagType = typename Generator::TagType;
123
124 ParentType parent_ = std::nullopt;
125 TagType tag_ = Generator::next();
126
127public:
139 explicit TagDecorator(ParentType parent = std::nullopt) : parent_{parent}
140 {
141 }
142
148 void
149 decorate(std::ostream& os) const override
150 {
151 os << "[";
152
153 if (parent_.has_value())
154 (*parent_).get().decorate(os);
155
156 os << tag_ << "] ";
157 }
158};
159
166template <>
167class TagDecorator<impl::NullTagGenerator> final : public BaseTagDecorator {
168public:
174 void
175 decorate([[maybe_unused]] std::ostream& os) const override
176 {
177 // nop
178 }
179};
180
185 using ParentType = std::optional<std::reference_wrapper<BaseTagDecorator const>>;
186
190 enum class Type {
191 NONE,
192 UUID,
193 UINT
194 };
195
196 Type type_; /*< The type of TagDecorator this factory produces */
197 ParentType parent_ = std::nullopt; /*< The parent tag decorator to bind */
198
199 static Type
200 getLogTagType(std::string_view style)
201 {
202 if (boost::iequals(style, "int") || boost::iequals(style, "uint"))
203 return TagDecoratorFactory::Type::UINT;
204
205 if (boost::iequals(style, "null") || boost::iequals(style, "none"))
206 return TagDecoratorFactory::Type::NONE;
207
208 if (boost::iequals(style, "uuid"))
209 return TagDecoratorFactory::Type::UUID;
210
211 ASSERT(false, "log.tag_style does not have valid value");
212 std::unreachable();
213 }
214
215public:
216 ~TagDecoratorFactory() = default;
217
224 : type_{getLogTagType(config.get<std::string>("log.tag_style"))}
225 {
226 }
227
228private:
229 TagDecoratorFactory(Type type, ParentType parent) noexcept : type_{type}, parent_{parent}
230 {
231 }
232
233public:
239 std::unique_ptr<BaseTagDecorator>
240 make() const;
241
249 with(ParentType parent) const noexcept;
250};
251
255class Taggable {
256 using DecoratorType = std::unique_ptr<BaseTagDecorator>;
257 DecoratorType tagDecorator_;
258
259protected:
265 explicit Taggable(util::TagDecoratorFactory const& tagFactory)
266 : tagDecorator_{tagFactory.make()}
267 {
268 }
269
270public:
271 virtual ~Taggable() = default;
272 Taggable(Taggable&&) = default;
273
274 Taggable&
275 operator=(Taggable&&) = default;
276
282 BaseTagDecorator const&
283 tag() const
284 {
285 return *tagDecorator_;
286 }
287};
288
289} // namespace util
Represents any tag decorator.
Definition Taggable.hpp:74
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:94
std::string toString() const
Gets the string representation of the tag.
Definition Taggable.hpp:106
A factory for TagDecorator instantiation.
Definition Taggable.hpp:184
std::unique_ptr< BaseTagDecorator > make() const
Instantiates the TagDecorator specified by type_ with parent bound from parent_.
Definition Taggable.cpp:52
TagDecoratorFactory(util::config::ClioConfigDefinition const &config)
Instantiates a tag decorator factory from clio configuration.
Definition Taggable.hpp:223
TagDecoratorFactory with(ParentType parent) const noexcept
Creates a new tag decorator factory with a bound parent tag decorator.
Definition Taggable.cpp:66
void decorate(std::ostream &os) const override
Nop implementation for the decorator.
Definition Taggable.hpp:175
void decorate(std::ostream &os) const override
Implementation of the decoration. Chaining tags when parent is available.
Definition Taggable.hpp:149
TagDecorator(ParentType parent=std::nullopt)
Create a new tag decorator with an optional parent.
Definition Taggable.hpp:139
A base class that allows attaching a tag decorator to a subclass.
Definition Taggable.hpp:255
BaseTagDecorator const & tag() const
Getter for tag decorator.
Definition Taggable.hpp:283
Taggable(util::TagDecoratorFactory const &tagFactory)
New Taggable from a specified factory.
Definition Taggable.hpp:265
All the config data will be stored and extracted from this class.
Definition ConfigDefinition.hpp:50
This namespace contains various utilities.
Definition AccountUtils.hpp:30
A null tag generator - does nothing.
Definition Taggable.hpp:47
This strategy uses an atomic_uint64_t to remain lock free.
Definition Taggable.hpp:52
This strategy uses boost::uuids::uuid with a static random generator and a mutex.
Definition Taggable.hpp:62