NVIDIA DeepStream SDK API Reference

9.2 Release
includes/opentelemetry/baggage/baggage.h
Go to the documentation of this file.
1 // Copyright The OpenTelemetry Authors
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include <cctype>
7 
8 #include "opentelemetry/common/kv_properties.h"
9 #include "opentelemetry/common/macros.h"
10 #include "opentelemetry/nostd/shared_ptr.h"
11 #include "opentelemetry/nostd/string_view.h"
12 #include "opentelemetry/version.h"
13 
15 
16 namespace baggage
17 {
18 
20 {
21 public:
22  static constexpr size_t kMaxKeyValuePairs = 180;
23  static constexpr size_t kMaxKeyValueSize = 4096;
24  static constexpr size_t kMaxSize = 8192;
25  static constexpr char kKeyValueSeparator = '=';
26  static constexpr char kMembersSeparator = ',';
27  static constexpr char kMetadataSeparator = ';';
28 
29  Baggage() noexcept : kv_properties_(new common::KeyValueProperties()) {}
30  Baggage(size_t size) noexcept : kv_properties_(new common::KeyValueProperties(size)) {}
31 
32  template <class T>
33  Baggage(const T &keys_and_values) noexcept
34  : kv_properties_(new common::KeyValueProperties(keys_and_values))
35  {}
36 
38  {
40  return baggage;
41  }
42 
43  /* Get value for key in the baggage
44  @returns true if key is found, false otherwise
45  */
46  bool GetValue(nostd::string_view key, std::string &value) const noexcept
47  {
48  return kv_properties_->GetValue(key, value);
49  }
50 
51  /* Returns shared_ptr of new baggage object which contains new key-value pair. If key or value is
52  invalid, copy of current baggage is returned
53  */
55  const nostd::string_view &value) noexcept
56  {
57 
58  nostd::shared_ptr<Baggage> baggage(new Baggage(kv_properties_->Size() + 1));
59  const bool valid_kv = IsValidKey(key) && IsValidValue(value);
60 
61  if (valid_kv)
62  {
63  baggage->kv_properties_->AddEntry(key, value);
64  }
65 
66  // add rest of the fields.
67  kv_properties_->GetAllEntries(
68  [&baggage, &key, &valid_kv](nostd::string_view e_key, nostd::string_view e_value) {
69  // if key or value was not valid, add all the entries. Add only remaining entries
70  // otherwise.
71  if (!valid_kv || key != e_key)
72  {
73  baggage->kv_properties_->AddEntry(e_key, e_value);
74  }
75 
76  return true;
77  });
78 
79  return baggage;
80  }
81 
82  // @return all key-values entries by repeatedly invoking the function reference passed as argument
83  // for each entry
85  nostd::function_ref<bool(nostd::string_view, nostd::string_view)> callback) const noexcept
86  {
87  return kv_properties_->GetAllEntries(callback);
88  }
89 
90  // delete key from the baggage if it exists. Returns shared_ptr of new baggage object.
91  // if key does not exist, copy of current baggage is returned.
92  // Validity of key is not checked as invalid keys should never be populated in baggage in the
93  // first place.
95  {
96  // keeping size of baggage same as key might not be found in it
97  nostd::shared_ptr<Baggage> baggage(new Baggage(kv_properties_->Size()));
98  kv_properties_->GetAllEntries(
99  [&baggage, &key](nostd::string_view e_key, nostd::string_view e_value) {
100  if (key != e_key)
101  baggage->kv_properties_->AddEntry(e_key, e_value);
102  return true;
103  });
104  return baggage;
105  }
106 
107  // Returns shared_ptr of baggage after extracting key-value pairs from header
109  {
110  if (header.size() > kMaxSize)
111  {
112  // header size exceeds maximum threshold, return empty baggage
113  return GetDefault();
114  }
115 
116  common::KeyValueStringTokenizer kv_str_tokenizer(header);
117  size_t cnt = kv_str_tokenizer.NumTokens(); // upper bound on number of kv pairs
118  if (cnt > kMaxKeyValuePairs)
119  {
120  cnt = kMaxKeyValuePairs;
121  }
122 
124  bool kv_valid;
125  nostd::string_view key, value;
126 
127  while (kv_str_tokenizer.next(kv_valid, key, value) && baggage->kv_properties_->Size() < cnt)
128  {
129  if (!kv_valid || (key.size() + value.size() > kMaxKeyValueSize))
130  {
131  // if kv pair is not valid, skip it
132  continue;
133  }
134 
135  // NOTE : metadata is kept as part of value only as it does not have any semantic meaning.
136  // but, we need to extract it (else Decode on value will return error)
137  nostd::string_view metadata;
138  auto metadata_separator = value.find(kMetadataSeparator);
139  if (metadata_separator != std::string::npos)
140  {
141  metadata = value.substr(metadata_separator);
142  value = value.substr(0, metadata_separator);
143  }
144 
145  bool err = 0;
146  auto key_str = UrlDecode(common::StringUtil::Trim(key), err);
147  auto value_str = UrlDecode(common::StringUtil::Trim(value), err);
148 
149  if (err == false && IsValidKey(key_str) && IsValidValue(value_str))
150  {
151  if (!metadata.empty())
152  {
153  value_str.append(metadata.data(), metadata.size());
154  }
155  baggage->kv_properties_->AddEntry(key_str, value_str);
156  }
157  }
158 
159  return baggage;
160  }
161 
162  // Creates string from baggage object.
163  std::string ToHeader() const noexcept
164  {
165  std::string header_s;
166  bool first = true;
167  kv_properties_->GetAllEntries([&](nostd::string_view key, nostd::string_view value) {
168  if (!first)
169  {
170  header_s.push_back(kMembersSeparator);
171  }
172  else
173  {
174  first = false;
175  }
176  header_s.append(UrlEncode(key));
177  header_s.push_back(kKeyValueSeparator);
178 
179  // extracting metadata from value. We do not encode metadata
180  auto metadata_separator = value.find(kMetadataSeparator);
181  if (metadata_separator != std::string::npos)
182  {
183  header_s.append(UrlEncode(value.substr(0, metadata_separator)));
184  auto metadata = value.substr(metadata_separator);
185  header_s.append(std::string(metadata.data(), metadata.size()));
186  }
187  else
188  {
189  header_s.append(UrlEncode(value));
190  }
191  return true;
192  });
193  return header_s;
194  }
195 
196 private:
197  static bool IsPrintableString(nostd::string_view str)
198  {
199  for (const auto ch : str)
200  {
201  if (ch < ' ' || ch > '~')
202  {
203  return false;
204  }
205  }
206 
207  return true;
208  }
209 
210  static bool IsValidKey(nostd::string_view key) { return key.size() && IsPrintableString(key); }
211 
212  static bool IsValidValue(nostd::string_view value) { return IsPrintableString(value); }
213 
214  // Uri encode key value pairs before injecting into header
215  // Implementation inspired from : https://golang.org/src/net/url/url.go?s=7851:7884#L264
216  static std::string UrlEncode(nostd::string_view str)
217  {
218  auto to_hex = [](char c) -> char {
219  static const char *hex = "0123456789ABCDEF";
220  return hex[c & 15];
221  };
222 
223  std::string ret;
224 
225  for (auto c : str)
226  {
227  if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
228  {
229  ret.push_back(c);
230  }
231  else if (c == ' ')
232  {
233  ret.push_back('+');
234  }
235  else
236  {
237  ret.push_back('%');
238  ret.push_back(to_hex(c >> 4));
239  ret.push_back(to_hex(c & 15));
240  }
241  }
242 
243  return ret;
244  }
245 
246  // Uri decode key value pairs after extracting from header
247  static std::string UrlDecode(nostd::string_view str, bool &err)
248  {
249  auto IsHex = [](char c) {
250  return std::isdigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
251  };
252 
253  auto from_hex = [](char c) -> char {
254  // c - '0' produces integer type which could trigger error/warning when casting to char,
255  // but the cast is safe here.
256  return static_cast<char>(std::isdigit(c) ? c - '0' : std::toupper(c) - 'A' + 10);
257  };
258 
259  std::string ret;
260 
261  for (size_t i = 0; i < str.size(); i++)
262  {
263  if (str[i] == '%')
264  {
265  if (i + 2 >= str.size() || !IsHex(str[i + 1]) || !IsHex(str[i + 2]))
266  {
267  err = 1;
268  return "";
269  }
270  ret.push_back(from_hex(str[i + 1]) << 4 | from_hex(str[i + 2]));
271  i += 2;
272  }
273  else if (str[i] == '+')
274  {
275  ret.push_back(' ');
276  }
277  else if (std::isalnum(str[i]) || str[i] == '-' || str[i] == '_' || str[i] == '.' ||
278  str[i] == '~')
279  {
280  ret.push_back(str[i]);
281  }
282  else
283  {
284  err = 1;
285  return "";
286  }
287  }
288 
289  return ret;
290  }
291 
292 private:
293  // Store entries in a C-style array to avoid using std::array or std::vector.
295 };
296 
297 } // namespace baggage
298 
baggage::Baggage::Set
nostd::shared_ptr< Baggage > Set(const nostd::string_view &key, const nostd::string_view &value) noexcept
Definition: includes/opentelemetry/baggage/baggage.h:54
nostd::function_ref
Definition: includes/opentelemetry/nostd/function_ref.h:17
OPENTELEMETRY_EXPORT
#define OPENTELEMETRY_EXPORT
Definition: includes/opentelemetry/common/macros.h:386
baggage::Baggage::Baggage
Baggage(const T &keys_and_values) noexcept
Definition: includes/opentelemetry/baggage/baggage.h:33
nostd::string_view::empty
bool empty() const noexcept
Definition: includes/opentelemetry/nostd/string_view.h:58
nostd::unique_ptr< common::KeyValueProperties >
common::KeyValueStringTokenizer
Definition: includes/opentelemetry/common/kv_properties.h:30
baggage
Definition: includes/opentelemetry/baggage/baggage.h:16
nostd::shared_ptr
Provide a type-erased version of std::shared_ptr that has ABI stability.
Definition: includes/opentelemetry/nostd/shared_ptr.h:28
OPENTELEMETRY_BEGIN_NAMESPACE
#define OPENTELEMETRY_BEGIN_NAMESPACE
Definition: includes/opentelemetry/version.h:21
baggage::Baggage::Baggage
Baggage() noexcept
Definition: includes/opentelemetry/baggage/baggage.h:29
nostd::string_view::substr
string_view substr(size_type pos, size_type n=npos) const
Definition: includes/opentelemetry/nostd/string_view.h:70
baggage::Baggage
Definition: includes/opentelemetry/baggage/baggage.h:19
baggage::Baggage::GetAllEntries
bool GetAllEntries(nostd::function_ref< bool(nostd::string_view, nostd::string_view)> callback) const noexcept
Definition: includes/opentelemetry/baggage/baggage.h:84
OPENTELEMETRY_END_NAMESPACE
#define OPENTELEMETRY_END_NAMESPACE
Definition: includes/opentelemetry/version.h:24
nostd::string_view::size
size_type size() const noexcept
Definition: includes/opentelemetry/nostd/string_view.h:62
baggage::Baggage::Delete
nostd::shared_ptr< Baggage > Delete(nostd::string_view key) noexcept
Definition: includes/opentelemetry/baggage/baggage.h:94
common::KeyValueStringTokenizer::next
bool next(bool &valid_kv, nostd::string_view &key, nostd::string_view &value) noexcept
Definition: includes/opentelemetry/common/kv_properties.h:50
pydeepstreamdoc::tensor::TensorDoc::size
constexpr const char * size
Definition: service-maker/sources/python/src/bindings/docstrings/tensordoc.h:46
baggage::Baggage::GetValue
bool GetValue(nostd::string_view key, std::string &value) const noexcept
Definition: includes/opentelemetry/baggage/baggage.h:46
baggage::Baggage::Baggage
Baggage(size_t size) noexcept
Definition: includes/opentelemetry/baggage/baggage.h:30
OPENTELEMETRY_API_SINGLETON
#define OPENTELEMETRY_API_SINGLETON
Definition: includes/opentelemetry/common/macros.h:335
baggage::Baggage::ToHeader
std::string ToHeader() const noexcept
Definition: includes/opentelemetry/baggage/baggage.h:163
baggage::Baggage::FromHeader
static nostd::shared_ptr< Baggage > FromHeader(nostd::string_view header) noexcept
Definition: includes/opentelemetry/baggage/baggage.h:108
common::StringUtil::Trim
static nostd::string_view Trim(nostd::string_view str, size_t left, size_t right) noexcept
Definition: includes/opentelemetry/common/string_util.h:18
nostd::string_view::data
const char * data() const noexcept
Definition: includes/opentelemetry/nostd/string_view.h:56
baggage::Baggage::GetDefault
static OPENTELEMETRY_API_SINGLETON nostd::shared_ptr< Baggage > GetDefault()
Definition: includes/opentelemetry/baggage/baggage.h:37
nostd::string_view::find
size_type find(char ch, size_type pos=0) const noexcept
Definition: includes/opentelemetry/nostd/string_view.h:119
common::KeyValueStringTokenizer::NumTokens
size_t NumTokens() const noexcept
Definition: includes/opentelemetry/common/kv_properties.h:108
common::KeyValueProperties
Definition: includes/opentelemetry/common/kv_properties.h:136
common
Definition: includes/opentelemetry/common/attribute_value.h:14
nostd::string_view
Back port of std::string_view to work with pre-cpp-17 compilers.
Definition: includes/opentelemetry/nostd/string_view.h:37