Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/config/cluster/v3/cluster.pb.h" 4 : #include "envoy/extensions/load_balancing_policies/common/v3/common.pb.h" 5 : #include "envoy/extensions/load_balancing_policies/common/v3/common.pb.validate.h" 6 : #include "envoy/extensions/load_balancing_policies/subset/v3/subset.pb.h" 7 : #include "envoy/extensions/load_balancing_policies/subset/v3/subset.pb.validate.h" 8 : #include "envoy/upstream/load_balancer.h" 9 : 10 : namespace Envoy { 11 : namespace Upstream { 12 : 13 : /** 14 : * Implementation of SubsetSelector. This is part of subset load balancer config and is used to 15 : * store config of single selector. 16 : */ 17 : class SubsetSelectorImpl : public SubsetSelector { 18 : public: 19 : SubsetSelectorImpl(const Protobuf::RepeatedPtrField<std::string>& selector_keys, 20 : envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetSelector:: 21 : LbSubsetSelectorFallbackPolicy fallback_policy, 22 : const Protobuf::RepeatedPtrField<std::string>& fallback_keys_subset, 23 : bool single_host_per_subset); 24 : 25 : // SubsetSelector 26 0 : const std::set<std::string>& selectorKeys() const override { return selector_keys_; } 27 : envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetSelector:: 28 : LbSubsetSelectorFallbackPolicy 29 0 : fallbackPolicy() const override { 30 0 : return fallback_policy_; 31 0 : } 32 0 : const std::set<std::string>& fallbackKeysSubset() const override { return fallback_keys_subset_; } 33 0 : bool singleHostPerSubset() const override { return single_host_per_subset_; } 34 : 35 : private: 36 : const std::set<std::string> selector_keys_; 37 : const std::set<std::string> fallback_keys_subset_; 38 : // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. 39 : const envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetSelector:: 40 : LbSubsetSelectorFallbackPolicy fallback_policy_; 41 : const bool single_host_per_subset_ : 1; 42 : }; 43 : 44 : using SubsetLoadbalancingPolicyProto = 45 : envoy::extensions::load_balancing_policies::subset::v3::Subset; 46 : using LegacySubsetLoadbalancingPolicyProto = envoy::config::cluster::v3::Cluster::LbSubsetConfig; 47 : 48 : /** 49 : * Implementation of LoadBalancerSubsetInfo. Both the legacy and extension subset proto configs 50 : * are converted to this class. 51 : */ 52 : class LoadBalancerSubsetInfoImpl : public LoadBalancerSubsetInfo { 53 : public: 54 : using FallbackPolicy = 55 : envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetFallbackPolicy; 56 : using MetadataFallbackPolicy = 57 : envoy::config::cluster::v3::Cluster::LbSubsetConfig::LbSubsetMetadataFallbackPolicy; 58 : using SubsetFallbackPolicy = envoy::config::cluster::v3::Cluster::LbSubsetConfig:: 59 : LbSubsetSelector::LbSubsetSelectorFallbackPolicy; 60 : 61 : LoadBalancerSubsetInfoImpl(const SubsetLoadbalancingPolicyProto& subset_config) 62 : : default_subset_(subset_config.default_subset()), 63 : fallback_policy_(static_cast<FallbackPolicy>(subset_config.fallback_policy())), 64 : metadata_fallback_policy_( 65 : static_cast<MetadataFallbackPolicy>(subset_config.metadata_fallback_policy())), 66 : enabled_(!subset_config.subset_selectors().empty()), 67 : locality_weight_aware_(subset_config.locality_weight_aware()), 68 : scale_locality_weight_(subset_config.scale_locality_weight()), 69 : panic_mode_any_(subset_config.panic_mode_any()), list_as_any_(subset_config.list_as_any()), 70 0 : allow_redundant_keys_(subset_config.allow_redundant_keys()) { 71 0 : for (const auto& subset : subset_config.subset_selectors()) { 72 0 : if (!subset.keys().empty()) { 73 0 : subset_selectors_.emplace_back(std::make_shared<Upstream::SubsetSelectorImpl>( 74 0 : subset.keys(), static_cast<SubsetFallbackPolicy>(subset.fallback_policy()), 75 0 : subset.fallback_keys_subset(), subset.single_host_per_subset())); 76 0 : } 77 0 : } 78 0 : 79 0 : if (allow_redundant_keys_) { 80 0 : // Sort subset selectors by number of keys, descending. This will ensure that the longest 81 0 : // matching subset selector will be at the beginning of the list. 82 0 : std::stable_sort(subset_selectors_.begin(), subset_selectors_.end(), 83 0 : [](const SubsetSelectorPtr& a, const SubsetSelectorPtr& b) -> bool { 84 0 : return a->selectorKeys().size() > b->selectorKeys().size(); 85 0 : }); 86 0 : } 87 0 : } 88 : 89 : LoadBalancerSubsetInfoImpl(const LegacySubsetLoadbalancingPolicyProto& subset_config) 90 : : default_subset_(subset_config.default_subset()), 91 : fallback_policy_(subset_config.fallback_policy()), 92 : metadata_fallback_policy_(subset_config.metadata_fallback_policy()), 93 : enabled_(!subset_config.subset_selectors().empty()), 94 : locality_weight_aware_(subset_config.locality_weight_aware()), 95 : scale_locality_weight_(subset_config.scale_locality_weight()), 96 11 : panic_mode_any_(subset_config.panic_mode_any()), list_as_any_(subset_config.list_as_any()) { 97 11 : for (const auto& subset : subset_config.subset_selectors()) { 98 0 : if (!subset.keys().empty()) { 99 0 : subset_selectors_.emplace_back(std::make_shared<SubsetSelectorImpl>( 100 0 : subset.keys(), subset.fallback_policy(), subset.fallback_keys_subset(), 101 0 : subset.single_host_per_subset())); 102 0 : } 103 0 : } 104 11 : } 105 : LoadBalancerSubsetInfoImpl() 106 : : LoadBalancerSubsetInfoImpl( 107 11 : envoy::config::cluster::v3::Cluster::LbSubsetConfig::default_instance()) {} 108 : 109 : // Upstream::LoadBalancerSubsetInfo 110 306 : bool isEnabled() const override { return enabled_; } 111 0 : FallbackPolicy fallbackPolicy() const override { return fallback_policy_; } 112 0 : MetadataFallbackPolicy metadataFallbackPolicy() const override { 113 0 : return metadata_fallback_policy_; 114 0 : } 115 0 : const ProtobufWkt::Struct& defaultSubset() const override { return default_subset_; } 116 0 : const std::vector<Upstream::SubsetSelectorPtr>& subsetSelectors() const override { 117 0 : return subset_selectors_; 118 0 : } 119 0 : bool localityWeightAware() const override { return locality_weight_aware_; } 120 0 : bool scaleLocalityWeight() const override { return scale_locality_weight_; } 121 0 : bool panicModeAny() const override { return panic_mode_any_; } 122 0 : bool listAsAny() const override { return list_as_any_; } 123 0 : bool allowRedundantKeys() const override { return allow_redundant_keys_; } 124 : 125 : private: 126 : const ProtobufWkt::Struct default_subset_; 127 : std::vector<Upstream::SubsetSelectorPtr> subset_selectors_; 128 : // Keep small members (bools and enums) at the end of class, to reduce alignment overhead. 129 : const FallbackPolicy fallback_policy_; 130 : const MetadataFallbackPolicy metadata_fallback_policy_; 131 : const bool enabled_ : 1; 132 : const bool locality_weight_aware_ : 1; 133 : const bool scale_locality_weight_ : 1; 134 : const bool panic_mode_any_ : 1; 135 : const bool list_as_any_ : 1; 136 : const bool allow_redundant_keys_{}; 137 : }; 138 : using DefaultLoadBalancerSubsetInfoImpl = ConstSingleton<LoadBalancerSubsetInfoImpl>; 139 : 140 : } // namespace Upstream 141 : } // namespace Envoy