Coverage Report

Created: 2023-11-12 09:30

/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 =
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