1
#pragma once
2

            
3
#include "envoy/router/cluster_specifier_plugin.h"
4

            
5
#include "source/common/router/delegating_route_impl.h"
6
#include "source/common/router/header_parser.h"
7
#include "source/common/router/metadatamatchcriteria_impl.h"
8
#include "source/common/router/per_filter_config.h"
9

            
10
namespace Envoy {
11
namespace Router {
12

            
13
using WeightedClusterProto = envoy::config::route::v3::WeightedCluster;
14
using ClusterWeightProto = envoy::config::route::v3::WeightedCluster::ClusterWeight;
15

            
16
class WeightedClusterEntry;
17
class WeightedClusterSpecifierPlugin;
18

            
19
struct WeightedClustersConfigEntry {
20
public:
21
  static absl::StatusOr<std::shared_ptr<WeightedClustersConfigEntry>>
22
  create(const ClusterWeightProto& cluster, const MetadataMatchCriteria* parent_metadata_match,
23
         std::string&& runtime_key, Server::Configuration::ServerFactoryContext& context);
24

            
25
427
  uint64_t clusterWeight(Runtime::Loader& loader) const {
26
427
    return loader.snapshot().getInteger(runtime_key_, cluster_weight_);
27
427
  }
28

            
29
private:
30
  friend class WeightedClusterEntry;
31
  friend class WeightedClusterSpecifierPlugin;
32

            
33
  WeightedClustersConfigEntry(const ClusterWeightProto& cluster,
34
                              const MetadataMatchCriteria* parent_metadata_match,
35
                              std::string&& runtime_key,
36
                              Server::Configuration::ServerFactoryContext& context);
37

            
38
  const std::string runtime_key_;
39
  const uint64_t cluster_weight_;
40
  MetadataMatchCriteriaConstPtr cluster_metadata_match_criteria_;
41
  HeaderParserPtr request_headers_parser_;
42
  HeaderParserPtr response_headers_parser_;
43
  std::unique_ptr<PerFilterConfigs> per_filter_configs_;
44
  const std::string host_rewrite_;
45
  const std::string cluster_name_;
46
  const Http::LowerCaseString cluster_header_name_;
47
};
48

            
49
using WeightedClustersConfigEntryConstSharedPtr =
50
    std::shared_ptr<const WeightedClustersConfigEntry>;
51

            
52
class WeightedClusterSpecifierPlugin : public ClusterSpecifierPlugin,
53
                                       public Logger::Loggable<Logger::Id::router> {
54
public:
55
  WeightedClusterSpecifierPlugin(const WeightedClusterProto& weighted_clusters,
56
                                 const MetadataMatchCriteria* parent_metadata_match,
57
                                 absl::string_view route_name,
58
                                 Server::Configuration::ServerFactoryContext& context,
59
                                 absl::Status& creation_status);
60

            
61
  RouteConstSharedPtr route(RouteEntryAndRouteConstSharedPtr parent,
62
                            const Http::RequestHeaderMap& headers, const StreamInfo::StreamInfo&,
63
                            uint64_t random) const override;
64

            
65
  absl::Status validateClusters(const Upstream::ClusterManager& cm) const override;
66

            
67
private:
68
  RouteConstSharedPtr pickWeightedCluster(RouteEntryAndRouteConstSharedPtr parent,
69
                                          const Http::RequestHeaderMap& headers,
70
                                          const StreamInfo::StreamInfo& stream_info,
71
                                          uint64_t random_value) const;
72

            
73
  Runtime::Loader& loader_;
74
  const Http::LowerCaseString random_value_header_;
75
  const std::string runtime_key_prefix_;
76
  const bool use_hash_policy_{};
77
  std::vector<WeightedClustersConfigEntryConstSharedPtr> weighted_clusters_;
78
  uint64_t total_cluster_weight_{0};
79
};
80

            
81
} // namespace Router
82
} // namespace Envoy