Line data Source code
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 = 24 0 : Config::XdsResourceIdentifier::decodeUrl(leds_config.leds_collection_name()); 25 0 : const auto resource_name = getResourceName(); 26 0 : subscription_ = 27 0 : factory_context.clusterManager().subscriptionFactory().collectionSubscriptionFromUrl( 28 0 : leds_resource_locator, leds_config.leds_config(), resource_name, *stats_scope_, *this, 29 0 : resource_decoder_); 30 0 : subscription_->start({}); 31 0 : } 32 : 33 : absl::Status 34 : LedsSubscription::onConfigUpdate(const std::vector<Config::DecodedResourceRef>& added_resources, 35 : const Protobuf::RepeatedPtrField<std::string>& removed_resources, 36 0 : const std::string&) { 37 : // At least one resource must be added or removed. 38 0 : if (added_resources.empty() && removed_resources.empty()) { 39 0 : ENVOY_LOG(debug, "No added or removed LbEndpoint entries for cluster {} in onConfigUpdate()", 40 0 : cluster_name_); 41 0 : stats_.update_empty_.inc(); 42 : // If it's the first update, and it has no resources, set the locality as active, 43 : // and update whoever is waiting for it, to allow the system to initialize. 44 0 : if (!initial_update_attempt_complete_) { 45 0 : initial_update_attempt_complete_ = true; 46 0 : callback_(); 47 0 : } 48 0 : return absl::OkStatus(); 49 0 : } 50 : 51 0 : ENVOY_LOG(info, "{}: add {} endpoint(s), remove {} endpoints(s)", cluster_name_, 52 0 : added_resources.size(), removed_resources.size()); 53 : 54 : // Update the internal host list with the removed hosts. 55 0 : for (const auto& removed_resource_name : removed_resources) { 56 : // Remove the entry from the endpoints list. 57 0 : ENVOY_LOG(debug, "Removing endpoint {} using LEDS update.", removed_resource_name); 58 0 : endpoints_map_.erase(removed_resource_name); 59 0 : } 60 : 61 : // Update the internal host list with the added hosts. 62 0 : for (const auto& added_resource : added_resources) { 63 0 : const auto& added_resource_name = added_resource.get().name(); 64 0 : ENVOY_LOG(trace, "Adding/Updating endpoint {} using LEDS update.", added_resource_name); 65 0 : envoy::config::endpoint::v3::LbEndpoint lb_endpoint = 66 0 : dynamic_cast<const envoy::config::endpoint::v3::LbEndpoint&>( 67 0 : added_resource.get().resource()); 68 0 : endpoints_map_[added_resource_name] = std::move(lb_endpoint); 69 0 : } 70 : 71 : // Notify the callbacks that the host list has been modified. 72 0 : initial_update_attempt_complete_ = true; 73 0 : callback_(); 74 0 : return absl::OkStatus(); 75 0 : } 76 : 77 : void LedsSubscription::onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason, 78 0 : const EnvoyException*) { 79 0 : ASSERT(Envoy::Config::ConfigUpdateFailureReason::ConnectionFailure != reason); 80 0 : ENVOY_LOG(debug, "LEDS update failed"); 81 : 82 : // Similar to EDS, we need to let the system initialize. Set the locality as 83 : // active, and update whoever is waiting for it. 84 0 : initial_update_attempt_complete_ = true; 85 0 : callback_(); 86 0 : } 87 : 88 : } // namespace Upstream 89 : } // namespace Envoy