/proc/self/cwd/source/extensions/clusters/eds/eds.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <memory> |
4 | | |
5 | | #include "envoy/config/cluster/v3/cluster.pb.h" |
6 | | #include "envoy/config/core/v3/base.pb.h" |
7 | | #include "envoy/config/core/v3/config_source.pb.h" |
8 | | #include "envoy/config/eds_resources_cache.h" |
9 | | #include "envoy/config/endpoint/v3/endpoint.pb.h" |
10 | | #include "envoy/config/endpoint/v3/endpoint.pb.validate.h" |
11 | | #include "envoy/config/subscription.h" |
12 | | #include "envoy/config/subscription_factory.h" |
13 | | #include "envoy/local_info/local_info.h" |
14 | | #include "envoy/registry/registry.h" |
15 | | #include "envoy/secret/secret_manager.h" |
16 | | #include "envoy/service/discovery/v3/discovery.pb.h" |
17 | | #include "envoy/stats/scope.h" |
18 | | #include "envoy/upstream/locality.h" |
19 | | |
20 | | #include "source/common/config/subscription_base.h" |
21 | | #include "source/common/upstream/cluster_factory_impl.h" |
22 | | #include "source/common/upstream/upstream_impl.h" |
23 | | #include "source/extensions/clusters/eds/leds.h" |
24 | | |
25 | | namespace Envoy { |
26 | | namespace Upstream { |
27 | | |
28 | | /** |
29 | | * Cluster implementation that reads host information from the Endpoint Discovery Service. |
30 | | */ |
31 | | class EdsClusterImpl |
32 | | : public BaseDynamicClusterImpl, |
33 | | Envoy::Config::SubscriptionBase<envoy::config::endpoint::v3::ClusterLoadAssignment>, |
34 | | private Config::EdsResourceRemovalCallback { |
35 | | public: |
36 | | static absl::StatusOr<std::unique_ptr<EdsClusterImpl>> |
37 | | create(const envoy::config::cluster::v3::Cluster& cluster, |
38 | | ClusterFactoryContext& cluster_context); |
39 | | ~EdsClusterImpl() override; |
40 | | |
41 | | // Upstream::Cluster |
42 | 56 | InitializePhase initializePhase() const override { return initialize_phase_; } |
43 | | |
44 | | protected: |
45 | | EdsClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, |
46 | | ClusterFactoryContext& cluster_context, absl::Status& creation_status); |
47 | | |
48 | | private: |
49 | | // Config::SubscriptionCallbacks |
50 | | absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& resources, |
51 | | const std::string& version_info) override; |
52 | | absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& added_resources, |
53 | | const Protobuf::RepeatedPtrField<std::string>& removed_resources, |
54 | | const std::string& system_version_info) override; |
55 | | void onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason, |
56 | | const EnvoyException* e) override; |
57 | | using LocalityWeightsMap = absl::node_hash_map<envoy::config::core::v3::Locality, uint32_t, |
58 | | LocalityHash, LocalityEqualTo>; |
59 | | bool updateHostsPerLocality(const uint32_t priority, bool weighted_priority_health, |
60 | | const uint32_t overprovisioning_factor, const HostVector& new_hosts, |
61 | | LocalityWeightsMap& locality_weights_map, |
62 | | LocalityWeightsMap& new_locality_weights_map, |
63 | | PriorityStateManager& priority_state_manager, |
64 | | const HostMap& all_hosts, |
65 | | const absl::flat_hash_set<std::string>& all_new_hosts); |
66 | | bool validateUpdateSize(int num_resources); |
67 | 28 | const std::string& edsServiceName() const { |
68 | 28 | const std::string& name = info_->edsServiceName(); |
69 | 28 | return !name.empty() ? name : info_->name(); |
70 | 28 | } |
71 | | |
72 | | // Updates the internal data structures with a given cluster load assignment. |
73 | | void update(const envoy::config::endpoint::v3::ClusterLoadAssignment& cluster_load_assignment); |
74 | | |
75 | | // EdsResourceRemovalCallback |
76 | | void onCachedResourceRemoved(absl::string_view resource_name) override; |
77 | | |
78 | | // ClusterImplBase |
79 | | void reloadHealthyHostsHelper(const HostSharedPtr& host) override; |
80 | | void startPreInit() override; |
81 | | void onAssignmentTimeout(); |
82 | | |
83 | | // Returns true iff all the LEDS based localities were updated. |
84 | | bool validateAllLedsUpdated() const; |
85 | | |
86 | | class BatchUpdateHelper : public PrioritySet::BatchUpdateCb { |
87 | | public: |
88 | | BatchUpdateHelper( |
89 | | EdsClusterImpl& parent, |
90 | | const envoy::config::endpoint::v3::ClusterLoadAssignment& cluster_load_assignment) |
91 | 14 | : parent_(parent), cluster_load_assignment_(cluster_load_assignment) {} |
92 | | |
93 | | // Upstream::PrioritySet::BatchUpdateCb |
94 | | void batchUpdate(PrioritySet::HostUpdateCb& host_update_cb) override; |
95 | | |
96 | | private: |
97 | | void updateLocalityEndpoints( |
98 | | const envoy::config::endpoint::v3::LbEndpoint& lb_endpoint, |
99 | | const envoy::config::endpoint::v3::LocalityLbEndpoints& locality_lb_endpoint, |
100 | | PriorityStateManager& priority_state_manager, |
101 | | absl::flat_hash_set<std::string>& all_new_hosts); |
102 | | |
103 | | EdsClusterImpl& parent_; |
104 | | const envoy::config::endpoint::v3::ClusterLoadAssignment& cluster_load_assignment_; |
105 | | }; |
106 | | |
107 | | Config::SubscriptionPtr subscription_; |
108 | | const LocalInfo::LocalInfo& local_info_; |
109 | | std::vector<LocalityWeightsMap> locality_weights_map_; |
110 | | Event::TimerPtr assignment_timeout_; |
111 | | InitializePhase initialize_phase_; |
112 | | using LedsConfigSet = absl::flat_hash_set<envoy::config::endpoint::v3::LedsClusterLocalityConfig, |
113 | | MessageUtil, MessageUtil>; |
114 | | using LedsConfigMap = absl::flat_hash_map<envoy::config::endpoint::v3::LedsClusterLocalityConfig, |
115 | | LedsSubscriptionPtr, MessageUtil, MessageUtil>; |
116 | | // Maps between a LEDS configuration (ConfigSource + collection name) to the locality endpoints |
117 | | // data. |
118 | | LedsConfigMap leds_localities_; |
119 | | // TODO(adisuissa): Avoid saving the entire cluster load assignment, only the |
120 | | // relevant parts of the config for each locality. Note that this field must |
121 | | // be set when LEDS is used. |
122 | | std::unique_ptr<envoy::config::endpoint::v3::ClusterLoadAssignment> cluster_load_assignment_; |
123 | | |
124 | | // An optional cache for the EDS resources. |
125 | | // Upon a (warming) timeout, a cached resource will be used. |
126 | | Config::EdsResourcesCacheOptRef eds_resources_cache_; |
127 | | |
128 | | // Tracks whether a cached resource is used as the current EDS resource. |
129 | | bool using_cached_resource_{false}; |
130 | | }; |
131 | | |
132 | | using EdsClusterImplSharedPtr = std::shared_ptr<EdsClusterImpl>; |
133 | | |
134 | | class EdsClusterFactory : public ClusterFactoryImplBase { |
135 | | public: |
136 | 26 | EdsClusterFactory() : ClusterFactoryImplBase("envoy.cluster.eds") {} |
137 | | |
138 | | private: |
139 | | absl::StatusOr<std::pair<ClusterImplBaseSharedPtr, ThreadAwareLoadBalancerPtr>> |
140 | | createClusterImpl(const envoy::config::cluster::v3::Cluster& cluster, |
141 | | ClusterFactoryContext& context) override; |
142 | | }; |
143 | | |
144 | | DECLARE_FACTORY(EdsClusterFactory); |
145 | | |
146 | | } // namespace Upstream |
147 | | } // namespace Envoy |