Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/common/router/vhds.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/common/router/vhds.h"
2
3
#include <chrono>
4
#include <cstdint>
5
#include <memory>
6
#include <string>
7
8
#include "envoy/config/core/v3/config_source.pb.h"
9
#include "envoy/config/subscription.h"
10
#include "envoy/service/discovery/v3/discovery.pb.h"
11
12
#include "source/common/common/assert.h"
13
#include "source/common/common/fmt.h"
14
#include "source/common/config/api_version.h"
15
#include "source/common/config/utility.h"
16
#include "source/common/protobuf/utility.h"
17
#include "source/common/router/config_impl.h"
18
19
namespace Envoy {
20
namespace Router {
21
22
// Implements callbacks to handle DeltaDiscovery protocol for VirtualHostDiscoveryService
23
VhdsSubscription::VhdsSubscription(RouteConfigUpdatePtr& config_update_info,
24
                                   Server::Configuration::ServerFactoryContext& factory_context,
25
                                   const std::string& stat_prefix,
26
                                   Rds::RouteConfigProvider* route_config_provider)
27
    : Envoy::Config::SubscriptionBase<envoy::config::route::v3::VirtualHost>(
28
          factory_context.messageValidationContext().dynamicValidationVisitor(), "name"),
29
      config_update_info_(config_update_info),
30
      scope_(factory_context.scope().createScope(
31
          stat_prefix + "vhds." + config_update_info_->protobufConfigurationCast().name() + ".")),
32
      stats_({ALL_VHDS_STATS(POOL_COUNTER(*scope_))}),
33
      init_target_(fmt::format("VhdsConfigSubscription {}",
34
                               config_update_info_->protobufConfigurationCast().name()),
35
0
                   [this]() {
36
0
                     subscription_->start(
37
0
                         {config_update_info_->protobufConfigurationCast().name()});
38
0
                   }),
39
0
      route_config_provider_(route_config_provider) {
40
0
  const auto& config_source = config_update_info_->protobufConfigurationCast()
41
0
                                  .vhds()
42
0
                                  .config_source()
43
0
                                  .api_config_source()
44
0
                                  .api_type();
45
0
  if (config_source != envoy::config::core::v3::ApiConfigSource::DELTA_GRPC) {
46
0
    throwEnvoyExceptionOrPanic("vhds: only 'DELTA_GRPC' is supported as an api_type.");
47
0
  }
48
0
  const auto resource_name = getResourceName();
49
0
  Envoy::Config::SubscriptionOptions options;
50
0
  options.use_namespace_matching_ = true;
51
0
  subscription_ =
52
0
      factory_context.clusterManager().subscriptionFactory().subscriptionFromConfigSource(
53
0
          config_update_info_->protobufConfigurationCast().vhds().config_source(),
54
0
          Grpc::Common::typeUrl(resource_name), *scope_, *this, resource_decoder_, options);
55
0
}
56
57
0
void VhdsSubscription::updateOnDemand(const std::string& with_route_config_name_prefix) {
58
0
  subscription_->requestOnDemandUpdate({with_route_config_name_prefix});
59
0
}
60
61
void VhdsSubscription::onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason,
62
0
                                            const EnvoyException*) {
63
0
  ASSERT(Envoy::Config::ConfigUpdateFailureReason::ConnectionFailure != reason);
64
  // We need to allow server startup to continue, even if we have a bad
65
  // config.
66
0
  init_target_.ready();
67
0
}
68
69
absl::Status VhdsSubscription::onConfigUpdate(
70
    const std::vector<Envoy::Config::DecodedResourceRef>& added_resources,
71
    const Protobuf::RepeatedPtrField<std::string>& removed_resources,
72
0
    const std::string& version_info) {
73
0
  RouteConfigUpdateReceiver::VirtualHostRefVector added_vhosts;
74
0
  std::set<std::string> added_resource_ids;
75
0
  for (const auto& resource : added_resources) {
76
0
    added_resource_ids.emplace(resource.get().name());
77
0
    std::copy(resource.get().aliases().begin(), resource.get().aliases().end(),
78
0
              std::inserter(added_resource_ids, added_resource_ids.end()));
79
    // the management server returns empty resources (they contain no virtual hosts in this case)
80
    // for aliases that it couldn't resolve.
81
0
    if (!resource.get().hasResource()) {
82
0
      continue;
83
0
    }
84
0
    added_vhosts.emplace_back(
85
0
        dynamic_cast<const envoy::config::route::v3::VirtualHost&>(resource.get().resource()));
86
0
  }
87
0
  if (config_update_info_->onVhdsUpdate(added_vhosts, added_resource_ids, removed_resources,
88
0
                                        version_info)) {
89
0
    stats_.config_reload_.inc();
90
0
    ENVOY_LOG(debug, "vhds: loading new configuration: config_name={} hash={}",
91
0
              config_update_info_->protobufConfigurationCast().name(),
92
0
              config_update_info_->configHash());
93
0
    if (route_config_provider_ != nullptr) {
94
0
      THROW_IF_NOT_OK(route_config_provider_->onConfigUpdate());
95
0
    }
96
0
  }
97
98
0
  init_target_.ready();
99
0
  return absl::OkStatus();
100
0
}
101
102
} // namespace Router
103
} // namespace Envoy