/proc/self/cwd/source/extensions/clusters/eds/leds.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "source/extensions/clusters/eds/leds.h" |
2 | | |
3 | | #include "envoy/common/exception.h" |
4 | | #include "envoy/config/core/v3/config_source.pb.h" |
5 | | |
6 | | #include "source/common/common/assert.h" |
7 | | #include "source/common/config/decoded_resource_impl.h" |
8 | | #include "source/common/config/xds_resource.h" |
9 | | |
10 | | namespace Envoy { |
11 | | namespace Upstream { |
12 | | |
13 | | LedsSubscription::LedsSubscription( |
14 | | const envoy::config::endpoint::v3::LedsClusterLocalityConfig& leds_config, |
15 | | const std::string& cluster_name, |
16 | | Server::Configuration::TransportSocketFactoryContext& factory_context, |
17 | | Stats::Scope& cluster_stats_scope, const UpdateCb& callback) |
18 | | : Envoy::Config::SubscriptionBase<envoy::config::endpoint::v3::LbEndpoint>( |
19 | | factory_context.messageValidationVisitor(), leds_config.leds_collection_name()), |
20 | | local_info_(factory_context.serverFactoryContext().localInfo()), cluster_name_(cluster_name), |
21 | | stats_scope_(cluster_stats_scope.createScope("leds.")), |
22 | 0 | stats_({ALL_LEDS_STATS(POOL_COUNTER(*stats_scope_))}), callback_(callback) { |
23 | 0 | const xds::core::v3::ResourceLocator leds_resource_locator = THROW_OR_RETURN_VALUE( |
24 | 0 | Config::XdsResourceIdentifier::decodeUrl(leds_config.leds_collection_name()), |
25 | 0 | xds::core::v3::ResourceLocator); |
26 | 0 | const auto resource_name = getResourceName(); |
27 | 0 | subscription_ = THROW_OR_RETURN_VALUE( |
28 | 0 | factory_context.clusterManager().subscriptionFactory().collectionSubscriptionFromUrl( |
29 | 0 | leds_resource_locator, leds_config.leds_config(), resource_name, *stats_scope_, *this, |
30 | 0 | resource_decoder_), |
31 | 0 | Config::SubscriptionPtr); |
32 | 0 | subscription_->start({}); |
33 | 0 | } |
34 | | |
35 | | absl::Status |
36 | | LedsSubscription::onConfigUpdate(const std::vector<Config::DecodedResourceRef>& added_resources, |
37 | | const Protobuf::RepeatedPtrField<std::string>& removed_resources, |
38 | 0 | const std::string&) { |
39 | | // At least one resource must be added or removed. |
40 | 0 | if (added_resources.empty() && removed_resources.empty()) { |
41 | 0 | ENVOY_LOG(debug, "No added or removed LbEndpoint entries for cluster {} in onConfigUpdate()", |
42 | 0 | cluster_name_); |
43 | 0 | stats_.update_empty_.inc(); |
44 | | // If it's the first update, and it has no resources, set the locality as active, |
45 | | // and update whoever is waiting for it, to allow the system to initialize. |
46 | 0 | if (!initial_update_attempt_complete_) { |
47 | 0 | initial_update_attempt_complete_ = true; |
48 | 0 | callback_(); |
49 | 0 | } |
50 | 0 | return absl::OkStatus(); |
51 | 0 | } |
52 | | |
53 | 0 | ENVOY_LOG(info, "{}: add {} endpoint(s), remove {} endpoints(s)", cluster_name_, |
54 | 0 | added_resources.size(), removed_resources.size()); |
55 | | |
56 | | // Update the internal host list with the removed hosts. |
57 | 0 | for (const auto& removed_resource_name : removed_resources) { |
58 | | // Remove the entry from the endpoints list. |
59 | 0 | ENVOY_LOG(debug, "Removing endpoint {} using LEDS update.", removed_resource_name); |
60 | 0 | endpoints_map_.erase(removed_resource_name); |
61 | 0 | } |
62 | | |
63 | | // Update the internal host list with the added hosts. |
64 | 0 | for (const auto& added_resource : added_resources) { |
65 | 0 | const auto& added_resource_name = added_resource.get().name(); |
66 | 0 | ENVOY_LOG(trace, "Adding/Updating endpoint {} using LEDS update.", added_resource_name); |
67 | 0 | envoy::config::endpoint::v3::LbEndpoint lb_endpoint = |
68 | 0 | dynamic_cast<const envoy::config::endpoint::v3::LbEndpoint&>( |
69 | 0 | added_resource.get().resource()); |
70 | 0 | endpoints_map_[added_resource_name] = std::move(lb_endpoint); |
71 | 0 | } |
72 | | |
73 | | // Notify the callbacks that the host list has been modified. |
74 | 0 | initial_update_attempt_complete_ = true; |
75 | 0 | callback_(); |
76 | 0 | return absl::OkStatus(); |
77 | 0 | } |
78 | | |
79 | | void LedsSubscription::onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason, |
80 | 0 | const EnvoyException*) { |
81 | 0 | ASSERT(Envoy::Config::ConfigUpdateFailureReason::ConnectionFailure != reason); |
82 | 0 | ENVOY_LOG(debug, "LEDS update failed"); |
83 | | |
84 | | // Similar to EDS, we need to let the system initialize. Set the locality as |
85 | | // active, and update whoever is waiting for it. |
86 | 0 | initial_update_attempt_complete_ = true; |
87 | 0 | callback_(); |
88 | 0 | } |
89 | | |
90 | | } // namespace Upstream |
91 | | } // namespace Envoy |