Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/envoy/router/scopes.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <memory>
4
5
#include "envoy/config/config_provider.h"
6
#include "envoy/router/router.h"
7
8
namespace Envoy {
9
namespace Router {
10
11
/**
12
 * Scope key fragment base class.
13
 */
14
class ScopeKeyFragmentBase {
15
public:
16
0
  bool operator!=(const ScopeKeyFragmentBase& other) const { return !(*this == other); }
17
18
0
  bool operator==(const ScopeKeyFragmentBase& other) const {
19
0
    if (typeid(*this) == typeid(other)) {
20
0
      return hash() == other.hash();
21
0
    }
22
0
    return false;
23
0
  }
24
1.79k
  virtual ~ScopeKeyFragmentBase() = default;
25
26
  // Hash of the fragment.
27
  virtual uint64_t hash() const PURE;
28
};
29
30
/**
31
 *  Scope Key is composed of non-null fragments.
32
 **/
33
class ScopeKey {
34
public:
35
1.00k
  ScopeKey() = default;
36
0
  ScopeKey(ScopeKey&& other) = default;
37
38
  // Scopekey is not copy-assignable and copy-constructible as it contains unique_ptr inside itself.
39
  ScopeKey(const ScopeKey&) = delete;
40
  ScopeKey operator=(const ScopeKey&) = delete;
41
42
  // Caller should guarantee the fragment is not nullptr.
43
1.79k
  void addFragment(std::unique_ptr<ScopeKeyFragmentBase>&& fragment) {
44
1.79k
    ASSERT(fragment != nullptr, "null fragment not allowed in ScopeKey.");
45
1.79k
    updateHash(*fragment);
46
1.79k
    fragments_.emplace_back(std::move(fragment));
47
1.79k
  }
48
49
1.10k
  uint64_t hash() const { return hash_; }
50
  bool operator!=(const ScopeKey& other) const;
51
  bool operator==(const ScopeKey& other) const;
52
53
private:
54
  // Update the key's hash with the new fragment hash.
55
1.79k
  void updateHash(const ScopeKeyFragmentBase& fragment) {
56
1.79k
    std::stringbuf buffer;
57
1.79k
    buffer.sputn(reinterpret_cast<const char*>(&hash_), sizeof(hash_));
58
1.79k
    const auto& fragment_hash = fragment.hash();
59
1.79k
    buffer.sputn(reinterpret_cast<const char*>(&fragment_hash), sizeof(fragment_hash));
60
1.79k
    hash_ = HashUtil::xxHash64(buffer.str());
61
1.79k
  }
62
63
  uint64_t hash_{0};
64
  std::vector<std::unique_ptr<ScopeKeyFragmentBase>> fragments_;
65
};
66
67
using ScopeKeyPtr = std::unique_ptr<ScopeKey>;
68
69
// String fragment.
70
class StringKeyFragment : public ScopeKeyFragmentBase {
71
public:
72
  explicit StringKeyFragment(absl::string_view value)
73
1.79k
      : value_(value), hash_(HashUtil::xxHash64(value_)) {}
74
75
1.79k
  uint64_t hash() const override { return hash_; }
76
77
private:
78
  const std::string value_;
79
  const uint64_t hash_;
80
};
81
82
/**
83
 * The scoped key builder.
84
 */
85
class ScopeKeyBuilder {
86
public:
87
9.54k
  virtual ~ScopeKeyBuilder() = default;
88
89
  /**
90
   * Based on the incoming HTTP request headers, returns the hash value of its scope key.
91
   * @param headers the request headers to match the scoped routing configuration against.
92
   * @return unique_ptr of the scope key computed from header.
93
   */
94
  virtual ScopeKeyPtr computeScopeKey(const Http::HeaderMap&) const PURE;
95
};
96
97
/**
98
 * The scoped routing configuration.
99
 */
100
class ScopedConfig : public Envoy::Config::ConfigProvider::Config {
101
public:
102
  ~ScopedConfig() override = default;
103
104
  /**
105
   * Based on the scope key, returns the configuration to use for selecting a target route.
106
   * The scope key can be got via ScopeKeyBuilder.
107
   *
108
   * @param scope_key the scope key. null config will be returned when null.
109
   * @return ConfigConstSharedPtr the router's Config matching the request headers.
110
   */
111
  virtual ConfigConstSharedPtr getRouteConfig(const ScopeKeyPtr& scope_key) const PURE;
112
};
113
114
using ScopedConfigConstSharedPtr = std::shared_ptr<const ScopedConfig>;
115
using ScopeKeyBuilderPtr = std::unique_ptr<const ScopeKeyBuilder>;
116
117
} // namespace Router
118
} // namespace Envoy