1
#pragma once
2

            
3
#include <cstdint>
4
#include <functional>
5
#include <memory>
6
#include <queue>
7
#include <string>
8

            
9
#include "envoy/admin/v3/config_dump.pb.h"
10
#include "envoy/config/core/v3/config_source.pb.h"
11
#include "envoy/config/route/v3/route.pb.h"
12
#include "envoy/config/route/v3/route.pb.validate.h"
13
#include "envoy/config/subscription.h"
14
#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h"
15
#include "envoy/http/codes.h"
16
#include "envoy/local_info/local_info.h"
17
#include "envoy/router/rds.h"
18
#include "envoy/router/route_config_provider_manager.h"
19
#include "envoy/router/route_config_update_receiver.h"
20
#include "envoy/server/admin.h"
21
#include "envoy/server/filter_config.h"
22
#include "envoy/service/discovery/v3/discovery.pb.h"
23
#include "envoy/singleton/instance.h"
24
#include "envoy/stats/scope.h"
25
#include "envoy/thread_local/thread_local.h"
26

            
27
#include "source/common/common/callback_impl.h"
28
#include "source/common/common/cleanup.h"
29
#include "source/common/common/logger.h"
30
#include "source/common/init/manager_impl.h"
31
#include "source/common/init/target_impl.h"
32
#include "source/common/init/watcher_impl.h"
33
#include "source/common/protobuf/utility.h"
34
#include "source/common/rds/common/proto_traits_impl.h"
35
#include "source/common/rds/rds_route_config_provider_impl.h"
36
#include "source/common/rds/rds_route_config_subscription.h"
37
#include "source/common/rds/route_config_provider_manager.h"
38
#include "source/common/rds/route_config_update_receiver_impl.h"
39
#include "source/common/rds/static_route_config_provider_impl.h"
40
#include "source/common/router/route_provider_manager.h"
41
#include "source/common/router/vhds.h"
42

            
43
#include "absl/container/node_hash_map.h"
44
#include "absl/container/node_hash_set.h"
45

            
46
namespace Envoy {
47
namespace Router {
48

            
49
// For friend class declaration in RdsRouteConfigSubscription.
50
class ScopedRdsConfigSubscription;
51

            
52
/**
53
 * A class that fetches the route configuration dynamically using the RDS API and updates them to
54
 * RDS config providers.
55
 */
56

            
57
class RdsRouteConfigSubscription : public Rds::RdsRouteConfigSubscription {
58
public:
59
  static absl::StatusOr<std::unique_ptr<RdsRouteConfigSubscription>>
60
  create(RouteConfigUpdatePtr&& config_update,
61
         Envoy::Config::OpaqueResourceDecoderSharedPtr&& resource_decoder,
62
         const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds,
63
         const uint64_t manager_identifier,
64
         Server::Configuration::ServerFactoryContext& factory_context,
65
         const std::string& stat_prefix,
66
         Rds::RouteConfigProviderManager& route_config_provider_manager);
67
  ~RdsRouteConfigSubscription() override;
68

            
69
408
  RouteConfigUpdatePtr& routeConfigUpdate() { return config_update_info_; }
70
  void updateOnDemand(const std::string& aliases);
71
  void maybeCreateInitManager(const std::string& version_info,
72
                              std::unique_ptr<Init::ManagerImpl>& init_manager,
73
                              std::unique_ptr<Cleanup>& resume_rds);
74

            
75
protected:
76
  RdsRouteConfigSubscription(
77
      RouteConfigUpdatePtr&& config_update,
78
      Envoy::Config::OpaqueResourceDecoderSharedPtr&& resource_decoder,
79
      const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds,
80
      const uint64_t manager_identifier,
81
      Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix,
82
      Rds::RouteConfigProviderManager& route_config_provider_manager,
83
      absl::Status& creation_status);
84

            
85
private:
86
  absl::Status beforeProviderUpdate(std::unique_ptr<Init::ManagerImpl>& noop_init_manager,
87
                                    std::unique_ptr<Cleanup>& resume_rds) override;
88
  absl::Status afterProviderUpdate() override;
89

            
90
  ABSL_MUST_USE_RESULT Common::CallbackHandlePtr
91
142
  addUpdateCallback(std::function<absl::Status()> callback) {
92
142
    return update_callback_manager_.add(callback);
93
142
  }
94

            
95
  VhdsSubscriptionPtr vhds_subscription_;
96
  RouteConfigUpdatePtr config_update_info_;
97
  Common::CallbackManager<absl::Status> update_callback_manager_;
98

            
99
  // Access to addUpdateCallback
100
  friend class ScopedRdsConfigSubscription;
101
};
102

            
103
using RdsRouteConfigSubscriptionSharedPtr = std::shared_ptr<RdsRouteConfigSubscription>;
104

            
105
struct UpdateOnDemandCallback {
106
  const std::string alias_;
107
  Event::Dispatcher& thread_local_dispatcher_;
108
  std::weak_ptr<Http::RouteConfigUpdatedCallback> cb_;
109
};
110

            
111
/**
112
 * Implementation of RouteConfigProvider that fetches the route configuration dynamically using
113
 * the subscription.
114
 */
115
class RdsRouteConfigProviderImpl : public RouteConfigProvider,
116
                                   Logger::Loggable<Logger::Id::router> {
117
public:
118
  RdsRouteConfigProviderImpl(RdsRouteConfigSubscriptionSharedPtr&& subscription,
119
                             Server::Configuration::ServerFactoryContext& factory_context);
120

            
121
  RdsRouteConfigSubscription& subscription();
122

            
123
  // Router::RouteConfigProvider
124
757
  Rds::ConfigConstSharedPtr config() const override { return base_.config(); }
125
179
  const absl::optional<ConfigInfo>& configInfo() const override { return base_.configInfo(); }
126
42
  SystemTime lastUpdated() const override { return base_.lastUpdated(); }
127

            
128
  absl::Status onConfigUpdate() override;
129
  ConfigConstSharedPtr configCast() const override;
130
  void requestVirtualHostsUpdate(
131
      const std::string& for_domain, Event::Dispatcher& thread_local_dispatcher,
132
      std::weak_ptr<Http::RouteConfigUpdatedCallback> route_config_updated_cb) override;
133

            
134
private:
135
  Rds::RdsRouteConfigProviderImpl base_;
136

            
137
  RouteConfigUpdatePtr& config_update_info_;
138
  Server::Configuration::ServerFactoryContext& factory_context_;
139
  std::list<UpdateOnDemandCallback> config_update_callbacks_;
140
  // A flag used to determine if this instance of RdsRouteConfigProviderImpl hasn't been
141
  // deallocated. Please also see a comment in requestVirtualHostsUpdate() method implementation.
142
  std::shared_ptr<bool> still_alive_{std::make_shared<bool>(true)};
143
};
144

            
145
using RdsRouteConfigProviderImplSharedPtr = std::shared_ptr<RdsRouteConfigProviderImpl>;
146

            
147
class RdsFactoryImpl : public RdsFactory {
148
public:
149
508
  std::string name() const override { return "envoy.rds_factory.default"; }
150
  RouteConfigProviderSharedPtr createRdsRouteConfigProvider(
151
      const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds,
152
      Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix,
153
      Init::Manager& init_manager, ProtoTraitsImpl& proto_traits,
154
      Rds::RouteConfigProviderManager& manager) override;
155
};
156

            
157
DECLARE_FACTORY(RdsFactoryImpl);
158

            
159
} // namespace Router
160
} // namespace Envoy