1
#include "source/common/rds/route_config_provider_manager.h"
2

            
3
#include "source/common/rds/util.h"
4

            
5
namespace Envoy {
6
namespace Rds {
7

            
8
RouteConfigProviderManager::RouteConfigProviderManager(OptRef<Server::Admin> admin,
9
                                                       const std::string& config_tracker_key,
10
                                                       ProtoTraits& proto_traits)
11
10085
    : proto_traits_(proto_traits) {
12
10085
  if (!admin.has_value()) {
13
    return;
14
  }
15
10085
  config_tracker_entry_ = admin->getConfigTracker().add(
16
10085
      config_tracker_key,
17
10087
      [this](const Matchers::StringMatcher& matcher) { return dumpRouteConfigs(matcher); });
18
  // ConfigTracker keys must be unique. We are asserting that no one has stolen the "routes" key
19
  // from us, since the returned entry will be nullptr if the key already exists.
20
10085
  RELEASE_ASSERT(config_tracker_entry_, "");
21
10085
}
22

            
23
19300
void RouteConfigProviderManager::eraseStaticProvider(RouteConfigProvider* provider) {
24
19300
  static_route_config_providers_.erase(provider);
25
19300
}
26

            
27
380
void RouteConfigProviderManager::eraseDynamicProvider(uint64_t manager_identifier) {
28
380
  dynamic_route_config_providers_.erase(manager_identifier);
29
380
}
30

            
31
std::unique_ptr<envoy::admin::v3::RoutesConfigDump>
32
64
RouteConfigProviderManager::dumpRouteConfigs(const Matchers::StringMatcher& name_matcher) const {
33
64
  auto config_dump = std::make_unique<envoy::admin::v3::RoutesConfigDump>();
34

            
35
72
  for (const auto& element : dynamic_route_config_providers_) {
36
49
    const auto provider = element.second.first.lock();
37
    // Because the RouteConfigProviderManager's weak_ptrs only get cleaned up
38
    // in the RdsRouteConfigSubscription destructor, and the single threaded nature
39
    // of this code, locking the weak_ptr will not fail.
40
49
    ASSERT(provider);
41

            
42
49
    if (provider->configInfo()) {
43
48
      if (!name_matcher.match(
44
48
              resourceName(proto_traits_, provider->configInfo().value().config_))) {
45
1
        continue;
46
1
      }
47
47
      auto* dynamic_config = config_dump->mutable_dynamic_route_configs()->Add();
48
47
      dynamic_config->set_version_info(provider->configInfo().value().version_);
49
47
      MessageUtil::packFrom(*dynamic_config->mutable_route_config(),
50
47
                            provider->configInfo().value().config_);
51
47
      TimestampUtil::systemClockToTimestamp(provider->lastUpdated(),
52
47
                                            *dynamic_config->mutable_last_updated());
53
47
    }
54
49
  }
55

            
56
65
  for (const auto& provider : static_route_config_providers_) {
57
24
    ASSERT(provider->configInfo());
58
24
    if (!name_matcher.match(resourceName(proto_traits_, provider->configInfo().value().config_))) {
59
1
      continue;
60
1
    }
61
23
    auto* static_config = config_dump->mutable_static_route_configs()->Add();
62
23
    MessageUtil::packFrom(*static_config->mutable_route_config(),
63
23
                          provider->configInfo().value().config_);
64
23
    TimestampUtil::systemClockToTimestamp(provider->lastUpdated(),
65
23
                                          *static_config->mutable_last_updated());
66
23
  }
67

            
68
64
  return config_dump;
69
64
}
70

            
71
RouteConfigProviderPtr RouteConfigProviderManager::addStaticProvider(
72
9868
    std::function<RouteConfigProviderPtr()> create_static_provider) {
73
9868
  auto provider = create_static_provider();
74
9868
  static_route_config_providers_.insert(provider.get());
75
9868
  return provider;
76
9868
}
77

            
78
RouteConfigProviderSharedPtr
79
RouteConfigProviderManager::reuseDynamicProvider(uint64_t manager_identifier,
80
                                                 Init::Manager& init_manager,
81
486
                                                 const std::string& route_config_name) {
82
486
  auto it = dynamic_route_config_providers_.find(manager_identifier);
83
486
  if (it == dynamic_route_config_providers_.end()) {
84
380
    return nullptr;
85
380
  }
86
  // Because the RouteConfigProviderManager's weak_ptrs only get cleaned up
87
  // in the RdsRouteConfigSubscription destructor, and the single threaded nature
88
  // of this code, locking the weak_ptr will not fail.
89
106
  auto existing_provider = it->second.first.lock();
90
106
  RELEASE_ASSERT(existing_provider != nullptr,
91
106
                 absl::StrCat("cannot find subscribed rds resource ", route_config_name));
92
106
  init_manager.add(*it->second.second);
93
106
  return existing_provider;
94
106
}
95

            
96
} // namespace Rds
97
} // namespace Envoy