1
#pragma once
2

            
3
#include "envoy/config/core/v3/base.pb.h"
4
#include "envoy/matcher/matcher.h"
5
#include "envoy/runtime/runtime.h"
6

            
7
#include "source/common/common/hash.h"
8
#include "source/common/matcher/matcher.h"
9

            
10
namespace Envoy {
11
namespace Extensions {
12
namespace Matching {
13
namespace InputMatchers {
14
namespace RuntimeFraction {
15

            
16
class Matcher : public Envoy::Matcher::InputMatcher {
17
public:
18
  Matcher(Runtime::Loader& runtime,
19
          envoy::config::core::v3::RuntimeFractionalPercent runtime_fraction, uint64_t seed)
20
13
      : runtime_(runtime), runtime_fraction_(runtime_fraction), seed_(seed) {}
21
11
  ::Envoy::Matcher::MatchResult match(const ::Envoy::Matcher::DataInputGetResult& input) override {
22
11
    auto data = input.stringData();
23
    // Only match if the value is present.
24
11
    if (!data) {
25
3
      return ::Envoy::Matcher::MatchResult::NoMatch;
26
3
    }
27

            
28
    // Otherwise, match if feature is enabled for hash(input).
29
8
    const auto hash_value = HashUtil::xxHash64(*data, seed_);
30
8
    return (runtime_.snapshot().featureEnabled(runtime_fraction_.runtime_key(),
31
8
                                               runtime_fraction_.default_value(), hash_value))
32
8
               ? ::Envoy::Matcher::MatchResult::Matched
33
8
               : ::Envoy::Matcher::MatchResult::NoMatch;
34
11
  }
35

            
36
private:
37
  Runtime::Loader& runtime_;
38
  const envoy::config::core::v3::RuntimeFractionalPercent runtime_fraction_;
39
  const uint64_t seed_;
40
};
41
} // namespace RuntimeFraction
42
} // namespace InputMatchers
43
} // namespace Matching
44
} // namespace Extensions
45
} // namespace Envoy