Line data Source code
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/vhds.h" 41 : 42 : #include "absl/container/node_hash_map.h" 43 : #include "absl/container/node_hash_set.h" 44 : 45 : namespace Envoy { 46 : namespace Router { 47 : 48 : // For friend class declaration in RdsRouteConfigSubscription. 49 : class ScopedRdsConfigSubscription; 50 : 51 : /** 52 : * Route configuration provider utilities. 53 : */ 54 : class RouteConfigProviderUtil { 55 : public: 56 : /** 57 : * @return RouteConfigProviderSharedPtr a new route configuration provider based on the supplied 58 : * proto configuration. Notes the provider object could be shared among multiple listeners. 59 : */ 60 : static RouteConfigProviderSharedPtr create( 61 : const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& 62 : config, 63 : Server::Configuration::ServerFactoryContext& factory_context, 64 : ProtobufMessage::ValidationVisitor& validator, Init::Manager& init_manager, 65 : const std::string& stat_prefix, RouteConfigProviderManager& route_config_provider_manager); 66 : }; 67 : 68 : /** 69 : * Implementation of RouteConfigProvider that holds a static route configuration. 70 : */ 71 : class StaticRouteConfigProviderImpl : public RouteConfigProvider { 72 : public: 73 : StaticRouteConfigProviderImpl(const envoy::config::route::v3::RouteConfiguration& config, 74 : Rds::ConfigTraits& config_traits, 75 : Server::Configuration::ServerFactoryContext& factory_context, 76 : Rds::RouteConfigProviderManager& route_config_provider_manager); 77 : ~StaticRouteConfigProviderImpl() override; 78 : 79 : // Router::RouteConfigProvider 80 393 : Rds::ConfigConstSharedPtr config() const override { return base_.config(); } 81 140 : const absl::optional<ConfigInfo>& configInfo() const override { return base_.configInfo(); } 82 70 : SystemTime lastUpdated() const override { return base_.lastUpdated(); } 83 0 : absl::Status onConfigUpdate() override { return base_.onConfigUpdate(); } 84 : ConfigConstSharedPtr configCast() const override; 85 : void requestVirtualHostsUpdate(const std::string&, Event::Dispatcher&, 86 0 : std::weak_ptr<Http::RouteConfigUpdatedCallback>) override {} 87 : 88 : private: 89 : Rds::StaticRouteConfigProviderImpl base_; 90 : Rds::RouteConfigProviderManager& route_config_provider_manager_; 91 : }; 92 : 93 : /** 94 : * A class that fetches the route configuration dynamically using the RDS API and updates them to 95 : * RDS config providers. 96 : */ 97 : 98 : class RdsRouteConfigSubscription : public Rds::RdsRouteConfigSubscription { 99 : public: 100 : RdsRouteConfigSubscription( 101 : RouteConfigUpdatePtr&& config_update, 102 : Envoy::Config::OpaqueResourceDecoderSharedPtr&& resource_decoder, 103 : const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds, 104 : const uint64_t manager_identifier, 105 : Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix, 106 : Rds::RouteConfigProviderManager& route_config_provider_manager); 107 : ~RdsRouteConfigSubscription() override; 108 : 109 50 : RouteConfigUpdatePtr& routeConfigUpdate() { return config_update_info_; } 110 : void updateOnDemand(const std::string& aliases); 111 : void maybeCreateInitManager(const std::string& version_info, 112 : std::unique_ptr<Init::ManagerImpl>& init_manager, 113 : std::unique_ptr<Cleanup>& resume_rds); 114 : 115 : private: 116 : void beforeProviderUpdate(std::unique_ptr<Init::ManagerImpl>& noop_init_manager, 117 : std::unique_ptr<Cleanup>& resume_rds) override; 118 : void afterProviderUpdate() override; 119 : 120 0 : ABSL_MUST_USE_RESULT Common::CallbackHandlePtr addUpdateCallback(std::function<void()> callback) { 121 0 : return update_callback_manager_.add(callback); 122 0 : } 123 : 124 : VhdsSubscriptionPtr vhds_subscription_; 125 : RouteConfigUpdatePtr config_update_info_; 126 : Common::CallbackManager<> update_callback_manager_; 127 : 128 : // Access to addUpdateCallback 129 : friend class ScopedRdsConfigSubscription; 130 : }; 131 : 132 : using RdsRouteConfigSubscriptionSharedPtr = std::shared_ptr<RdsRouteConfigSubscription>; 133 : 134 : struct UpdateOnDemandCallback { 135 : const std::string alias_; 136 : Event::Dispatcher& thread_local_dispatcher_; 137 : std::weak_ptr<Http::RouteConfigUpdatedCallback> cb_; 138 : }; 139 : 140 : /** 141 : * Implementation of RouteConfigProvider that fetches the route configuration dynamically using 142 : * the subscription. 143 : */ 144 : class RdsRouteConfigProviderImpl : public RouteConfigProvider, 145 : Logger::Loggable<Logger::Id::router> { 146 : public: 147 : RdsRouteConfigProviderImpl(RdsRouteConfigSubscriptionSharedPtr&& subscription, 148 : Server::Configuration::ServerFactoryContext& factory_context); 149 : 150 : RdsRouteConfigSubscription& subscription(); 151 : 152 : // Router::RouteConfigProvider 153 0 : Rds::ConfigConstSharedPtr config() const override { return base_.config(); } 154 154 : const absl::optional<ConfigInfo>& configInfo() const override { return base_.configInfo(); } 155 36 : SystemTime lastUpdated() const override { return base_.lastUpdated(); } 156 : 157 : absl::Status onConfigUpdate() override; 158 : ConfigConstSharedPtr configCast() const override; 159 : void requestVirtualHostsUpdate( 160 : const std::string& for_domain, Event::Dispatcher& thread_local_dispatcher, 161 : std::weak_ptr<Http::RouteConfigUpdatedCallback> route_config_updated_cb) override; 162 : 163 : private: 164 : Rds::RdsRouteConfigProviderImpl base_; 165 : 166 : RouteConfigUpdatePtr& config_update_info_; 167 : Server::Configuration::ServerFactoryContext& factory_context_; 168 : std::list<UpdateOnDemandCallback> config_update_callbacks_; 169 : // A flag used to determine if this instance of RdsRouteConfigProviderImpl hasn't been 170 : // deallocated. Please also see a comment in requestVirtualHostsUpdate() method implementation. 171 : std::shared_ptr<bool> still_alive_{std::make_shared<bool>(true)}; 172 : }; 173 : 174 : using RdsRouteConfigProviderImplSharedPtr = std::shared_ptr<RdsRouteConfigProviderImpl>; 175 : 176 : using ProtoTraitsImpl = 177 : Rds::Common::ProtoTraitsImpl<envoy::config::route::v3::RouteConfiguration, 1>; 178 : 179 : class RouteConfigProviderManagerImpl : public RouteConfigProviderManager, 180 : public Singleton::Instance { 181 : public: 182 : RouteConfigProviderManagerImpl(OptRef<Server::Admin> admin); 183 : 184 : std::unique_ptr<envoy::admin::v3::RoutesConfigDump> 185 0 : dumpRouteConfigs(const Matchers::StringMatcher& name_matcher) const { 186 0 : return manager_.dumpRouteConfigs(name_matcher); 187 0 : } 188 : 189 : // RouteConfigProviderManager 190 : RouteConfigProviderSharedPtr createRdsRouteConfigProvider( 191 : const envoy::extensions::filters::network::http_connection_manager::v3::Rds& rds, 192 : Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix, 193 : Init::Manager& init_manager) override; 194 : 195 : RouteConfigProviderPtr 196 : createStaticRouteConfigProvider(const envoy::config::route::v3::RouteConfiguration& route_config, 197 : Server::Configuration::ServerFactoryContext& factory_context, 198 : ProtobufMessage::ValidationVisitor& validator) override; 199 : 200 : private: 201 : ProtoTraitsImpl proto_traits_; 202 : Rds::RouteConfigProviderManager manager_; 203 : }; 204 : 205 : using RouteConfigProviderManagerImplPtr = std::unique_ptr<RouteConfigProviderManagerImpl>; 206 : 207 : } // namespace Router 208 : } // namespace Envoy