Line data Source code
1 : #pragma once 2 : 3 : #include <memory> 4 : #include <typeinfo> 5 : 6 : #include "envoy/config/route/v3/scoped_route.pb.h" 7 : #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" 8 : #include "envoy/router/rds.h" 9 : #include "envoy/router/router.h" 10 : #include "envoy/router/scopes.h" 11 : #include "envoy/thread_local/thread_local.h" 12 : 13 : #include "source/common/common/hash.h" 14 : #include "source/common/protobuf/utility.h" 15 : #include "source/common/router/config_impl.h" 16 : 17 : #include "absl/numeric/int128.h" 18 : #include "absl/strings/str_format.h" 19 : 20 : namespace Envoy { 21 : namespace Router { 22 : 23 : using envoy::extensions::filters::network::http_connection_manager::v3::ScopedRoutes; 24 : 25 : /** 26 : * Base class for fragment builders. 27 : */ 28 : class FragmentBuilderBase { 29 : public: 30 : explicit FragmentBuilderBase(ScopedRoutes::ScopeKeyBuilder::FragmentBuilder&& config) 31 0 : : config_(std::move(config)) {} 32 0 : virtual ~FragmentBuilderBase() = default; 33 : 34 : // Returns a fragment if the fragment rule applies, a nullptr indicates no fragment could be 35 : // generated from the headers. 36 : virtual std::unique_ptr<ScopeKeyFragmentBase> 37 : computeFragment(const Http::HeaderMap& headers) const PURE; 38 : 39 : protected: 40 : const ScopedRoutes::ScopeKeyBuilder::FragmentBuilder config_; 41 : }; 42 : 43 : class HeaderValueExtractorImpl : public FragmentBuilderBase { 44 : public: 45 : explicit HeaderValueExtractorImpl(ScopedRoutes::ScopeKeyBuilder::FragmentBuilder&& config); 46 : 47 : std::unique_ptr<ScopeKeyFragmentBase> 48 : computeFragment(const Http::HeaderMap& headers) const override; 49 : 50 : private: 51 : const ScopedRoutes::ScopeKeyBuilder::FragmentBuilder::HeaderValueExtractor& 52 : header_value_extractor_config_; 53 : }; 54 : 55 : /** 56 : * Base class for ScopeKeyBuilder implementations. 57 : */ 58 : class ScopeKeyBuilderBase : public ScopeKeyBuilder { 59 : public: 60 : explicit ScopeKeyBuilderBase(ScopedRoutes::ScopeKeyBuilder&& config) 61 0 : : config_(std::move(config)) {} 62 : 63 : protected: 64 : const ScopedRoutes::ScopeKeyBuilder config_; 65 : }; 66 : 67 : class ScopeKeyBuilderImpl : public ScopeKeyBuilderBase { 68 : public: 69 : explicit ScopeKeyBuilderImpl(ScopedRoutes::ScopeKeyBuilder&& config); 70 : 71 : ScopeKeyPtr computeScopeKey(const Http::HeaderMap& headers) const override; 72 : 73 : private: 74 : std::vector<std::unique_ptr<FragmentBuilderBase>> fragment_builders_; 75 : }; 76 : 77 : // ScopedRouteConfiguration and corresponding RouteConfigProvider. 78 : class ScopedRouteInfo { 79 : public: 80 : ScopedRouteInfo(envoy::config::route::v3::ScopedRouteConfiguration config_proto, 81 : ConfigConstSharedPtr route_config); 82 : 83 0 : const ConfigConstSharedPtr& routeConfig() const { return route_config_; } 84 0 : const ScopeKey& scopeKey() const { return scope_key_; } 85 0 : const envoy::config::route::v3::ScopedRouteConfiguration& configProto() const { 86 0 : return config_proto_; 87 0 : } 88 0 : const std::string& scopeName() const { return config_proto_.name(); } 89 0 : uint64_t configHash() const { return config_hash_; } 90 : 91 : private: 92 : envoy::config::route::v3::ScopedRouteConfiguration config_proto_; 93 : ScopeKey scope_key_; 94 : ConfigConstSharedPtr route_config_; 95 : const uint64_t config_hash_; 96 : }; 97 : using ScopedRouteInfoConstSharedPtr = std::shared_ptr<const ScopedRouteInfo>; 98 : // Ordered map for consistent config dumping. 99 : using ScopedRouteMap = std::map<std::string, ScopedRouteInfoConstSharedPtr>; 100 : 101 : /** 102 : * Each Envoy worker is assigned an instance of this type. When config updates are received, 103 : * addOrUpdateRoutingScope() and removeRoutingScope() are called to update the set of scoped routes. 104 : * 105 : * ConnectionManagerImpl::refreshCachedRoute() will call getRouterConfig() to obtain the 106 : * Router::ConfigConstSharedPtr to use for route selection. 107 : */ 108 : class ScopedConfigImpl : public ScopedConfig { 109 : public: 110 0 : ScopedConfigImpl() = default; 111 : 112 0 : ScopedConfigImpl(const std::vector<ScopedRouteInfoConstSharedPtr>& scoped_route_infos) { 113 0 : addOrUpdateRoutingScopes(scoped_route_infos); 114 0 : } 115 : 116 : void 117 : addOrUpdateRoutingScopes(const std::vector<ScopedRouteInfoConstSharedPtr>& scoped_route_infos); 118 : 119 : void removeRoutingScopes(const std::vector<std::string>& scope_names); 120 : 121 : // Envoy::Router::ScopedConfig 122 : Router::ConfigConstSharedPtr getRouteConfig(const ScopeKeyPtr& scope_key) const override; 123 : 124 : private: 125 : // From scope name to cached ScopedRouteInfo. 126 : absl::flat_hash_map<std::string, ScopedRouteInfoConstSharedPtr> scoped_route_info_by_name_; 127 : // Hash by ScopeKey hash to lookup in constant time. 128 : absl::flat_hash_map<uint64_t, ScopedRouteInfoConstSharedPtr> scoped_route_info_by_key_; 129 : }; 130 : 131 : /** 132 : * A NULL implementation of the scoped routing configuration. 133 : */ 134 : class NullScopedConfigImpl : public ScopedConfig { 135 : public: 136 0 : Router::ConfigConstSharedPtr getRouteConfig(const ScopeKeyPtr&) const override { 137 0 : return std::make_shared<const NullConfigImpl>(); 138 0 : } 139 : }; 140 : 141 : } // namespace Router 142 : } // namespace Envoy