-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
config: Scoped RDS (PR 1/4): Introduce {static,dynamic} config provider framework #5243
config: Scoped RDS (PR 1/4): Introduce {static,dynamic} config provider framework #5243
Conversation
This commit introduces a framework for implementing configuration providers by generalizing the RouteConfigProvider{,Manager} which currently implement HttpConnectionManager routing configuration and the RDS API. This is the first deliverable (out of a planned 4 or 5 PRs) of the Scoped RDS implementation (envoyproxy#4704). Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
@htuch I am assigning you as a first pass reviewer as you were involved in the design process. I am also assigning myself, but I will not be able to do a full review until next week. |
Apologies for the review delay; will take a pass in the next 1-2 days. |
namespace Config { | ||
|
||
/** | ||
* A provider for configuration obtained ether statically or dynamically via xDS APIs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One high level question to kick this off with. Is the plan to also replace the static/dynamic treatment of SDS resoureces (e.g. see https://github.com/envoyproxy/envoy/blob/master/source/common/ssl/context_config_impl.cc#L57) with this class framework? It would be helpful to have in mind the concrete types that this will be instantiated with and places used when reading.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, SDS looks like a good candidate as well, although I was not planning to transition it to the new API as part of this PR chain so there are likely a few gaps that will need to be addressed.
One of those gaps is that the ConfigProvider
currently only exposes a std::shared_ptr<const Config> config() const
function, but the SDS config impls require allowing the user/consumer of the API to set a callback (see ContextConfigImpl::setSecretUpdateCallback). From an API standpoint, I think the solution is trivial by exposing a std::shared_ptr<Config> config()
overload, and having the config impl enforce thread safety itself by leveraging any synchronization mechanisms required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be ideal from a tech debt perspective if we could at least file an issue for this if not do the conversion at the end of the PR chain. There is a lot of commonality here between RDS and SDS, having multiple methods of managing static/dynamic resources seems redundant. Anyway, I'll do a deep dive now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, I'll file an issue to keep track of SDS. I plan to take a deeper look at it once I get through these PRs and will likely take on the work myself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue filed: #5329.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I might be being dense here. However, this discussion and @lizan's comment here leave me with a few questions:
- The advantage of this framework is that it simplifies managing config providers that provide configuration that have shared semantics. In the PR comment this is clear, but I think it would be clarifying to spell that out in the interface here.
- Given the fact that listeners, and clusters have similar (between them), but different (w.r.t SDS/RDS) ownership models, I wonder if it is worth it to spell out the fact that this framework, as is, is not really intended for config objects that are not shared. Or is the plan long term to use this framework to manage "singly owned" config providers?
- About @lizan's comment. Should we put some effort in unifying what we mean when we say static vs inline? And how is the framework going to deal with the third origin model in SDS (what they call static)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, more emphasis on the shared aspect in this comment would make sense; a short sentence or two explaining where this fits into the taxonomy of configuration management in Envoy would be rad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Answering @junr03 's questions below:
- The advantage of this framework is that it simplifies managing config providers that provide configuration that have shared semantics. In the PR comment this is clear, but I think it would be clarifying to spell that out in the interface here.
Done.
- Given the fact that listeners, and clusters have similar (between them), but different (w.r.t SDS/RDS) ownership models, I wonder if it is worth it to spell out the fact that this framework, as is, is not really intended for config objects that are not shared. Or is the plan long term to use this framework to manage "singly owned" config providers?
This framework can also be leveraged for use cases where there is no expected sharing of dynamic resources, since that use case is a simplification of the target use case and the publicly exposed ConfigProvider API should suffice as well. However, I have avoided introducing this framework as the solution for config management, since it's likely that some of these "singly owned" use cases could make due with simpler implementations than what is imposed by this framework.
- About @lizan's comment. Should we put some effort in unifying what we mean when we say static vs inline? And how is the framework going to deal with the third origin model in SDS (what they call static)?
I have changed the naming of the *ImplBase classes and added comments to clarify how this framework can be leveraged for SDS as well and the static/inline distinction that it makes. Essentially, the ImmutableConfigProviderImplBase
can satisfy both config types, and I've introduced a ConfigProviderInstanceType
parameter to the constructor to distinguish between them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, more emphasis on the shared aspect in this comment would make sense; a short sentence or two explaining where this fits into the taxonomy of configuration management in Envoy would be rad.
Done.
Signed-off-by: Andres Guedez <aguedez@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a very clean and understandable approach to structuring things, a bunch of nits and deeper comments/questions to get started with.
if (!config_proto) { | ||
return {}; | ||
} | ||
return ConfigInfo<P>{*config_proto, getConfigVersion()}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm struck by the similarity to
class TypedMetadata { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a pattern that repeats several times across the codebase; other classes that implement it are ThreadLocal::Slot and Tcp::ConnectionPool::ConnectionData.
I'll experiment with/prototype an abstraction to figure out whether it makes sense to generalize it into a common class or whether it's better left as a design pattern separately implemented by each class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, no need to do gymnastics or anything here, just maybe there is an opportunity for some lightweight refactor. Thanks for taking a look.
*/ | ||
template <typename T> | ||
std::shared_ptr<T> | ||
getSubscription(const Protobuf::Message& config_source_proto, Init::Manager& init_manager, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering what, if any, relationship this bears with what is being discussed in #5270?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to dive deeper into the various subscription classes' internals, but based on my current understanding of that issue, I don't see the relationship with my use here. This function is simply looking for an existing ConfigSubscriptionInstance (if any) that can be shared with a newly allocated dynamic config provider.
Any changes introduced by #5270 would be transparent to this function, although the ConfigSubscriptionInstance may have to be modified at to reflect API level changes.
ASSERT(!dynamic_config_providers_.empty()); | ||
ConfigProvider::ConfigConstSharedPtr new_config; | ||
for (auto* provider : dynamic_config_providers_) { | ||
if (new_config == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loop looks wrong based on a quick glance; the new_config
nullness gets shared across dynamic providers... unless onConfigProtoUpdate
is identical across them all? If so, please add comments and maybe ASSERTs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These dynamic providers are all instances of the same class, and they share the underlying ConfigSubscriptionInstance on which this function is taking effect.
I will add the comments and assert()s.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments and an ASSERT to bindConfigProvider(). The assertion is tricky due to the lack of concrete type information in these functions, so PTAL and let me know your thoughts on my approach using RTTI.
|
||
ASSERT(!dynamic_config_providers_.empty()); | ||
ConfigProvider::ConfigConstSharedPtr new_config; | ||
for (auto* provider : dynamic_config_providers_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm scratching my head and trying to remember why we have/need multiple dynamic config providers for a single config proto update?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is another carryover from the existing RDS implementation of config providers. Currently, each HttpConnectionManager instantiates its own RdsRouteConfigProviderImpl (if RDS is configured).
I found some context on the decision to avoid sharing the RouteConfigProvider in #3960 and #3967. Based on those PRs, it appears the goal was to avoid use of shared_ptr outside the *ProviderImpl.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, anything you could do to document this design history would be great. I feel this is something I will forget in 6 months again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added class level comment explaining this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal was to avoid use of shared_ptr outside the *ProviderImpl.
This is not quite true, see #3960 description. FactoryContext is tied to Listener (some of refs in it), and they will be dangling after they are updated by LDS, while the config provider may outlive them.
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the progression from the existing config provider implementation is a bit clearer, thanks. @lizan can you take a look as well, since this was your old stomping ground?
source/common/common/assert.h
Outdated
// type checks using typeid can trigger it. | ||
#define ASSERT_WITH_PRECOND(PRECOND, COND) \ | ||
do { \ | ||
if (PRECOND) { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we just structure this as ASSERT(!PRECOND || COND)
? Might simplify if that is possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I'm still using a wrapper macro to hide the verbose #pragma
s required to silence the potentially evaluated statement warnings from clang.
|
||
ASSERT(!dynamic_config_providers_.empty()); | ||
ConfigProvider::ConfigConstSharedPtr new_config; | ||
for (auto* provider : dynamic_config_providers_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, anything you could do to document this design history would be great. I feel this is something I will forget in 6 months again.
Sure, I will take a pass tomorrow. |
Signed-off-by: Andres Guedez <aguedez@google.com>
|
||
ASSERT(!dynamic_config_providers_.empty()); | ||
ConfigProvider::ConfigConstSharedPtr new_config; | ||
for (auto* provider : dynamic_config_providers_) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal was to avoid use of shared_ptr outside the *ProviderImpl.
This is not quite true, see #3960 description. FactoryContext is tied to Listener (some of refs in it), and they will be dangling after they are updated by LDS, while the config provider may outlive them.
const std::string& version_info); | ||
|
||
const std::unordered_set<const DynamicConfigProviderImpl*> dynamic_config_providers() const { | ||
return std::unordered_set<const DynamicConfigProviderImpl*>(dynamic_config_providers_.begin(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need copy here? Seems you're only checking the size and the first element when you use it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed this accessor and replaced it getAnyBoundDynamicConfigProvider().
…-provider-refactor Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Also, formalizes the concept of types of ConfigProvider instances via the introduction of a ConfigProviderInstanceType. Signed-off-by: Andres Guedez <aguedez@google.com>
142d9c1 renames the {Static,Dynamic}ConfigProviderImplBase classes to {Immutable,Mutable}* respectively. This enables the introduction of a ConfigProviderInstanceType that allows users of the framework to specify the type of config associated with a provider. See #5243 (comment) for context on this commit. These changes should allow a clean transition to this framework for both RDS and SDS. |
namespace Envoy { | ||
namespace Config { | ||
|
||
std::ostream& operator<<(std::ostream& os, ConfigProviderInstanceType type) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was needed for an fmt::format() statement, but I have now removed it.
LGTM re: naming, seems build is broken though. |
…-provider-refactor Signed-off-by: Andres Guedez <aguedez@google.com>
Also, removes thread safety assertions due to changes introduced in (envoyproxy#5072); it is no longer possible to statically call functions to obtain/check the current thread ID. I will reintroduce these checks once static accessors are available again. Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
…-provider-refactor Signed-off-by: Andres Guedez <aguedez@google.com>
Build is fixed now. Just merged master to fix the mac build as well. |
namespace Config { | ||
|
||
/** | ||
* A provider for configuration obtained ether statically or dynamically via xDS APIs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, more emphasis on the shared aspect in this comment would make sense; a short sentence or two explaining where this fits into the taxonomy of configuration management in Envoy would be rad.
source/common/common/assert.h
Outdated
#define ASSERT_IGNORE_POTENTIALLY_EVALUATED(COND) \ | ||
do { \ | ||
__CLANG_PRAGMA("clang diagnostic push") \ | ||
__CLANG_PRAGMA("clang diagnostic ignored \"-Wpotentially-evaluated-expression\"") \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Searching around for what this does, it seems to involve side-effects, which I don't see at the sites where it is used. Can you add some comments on when you need to use this?
Alternatively, can we just fold these pragmas into ASSERT
? Fewer knobs here seems better, we could potentially have an unbounded number of these ASSERT
s, one for each clang warning :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment in https://github.com/envoyproxy/envoy/pull/5243/files#diff-0bbc1b7ef8d5cfd41d41b2296caf7f1fR65 attempts to address the reason for this assert: the typeid(**mutable_config_providers_.begin())
statement triggers the potentially evaluated warning in clang.
This seems like a useful enough warning that I would rather not hide it by default (by folding it into the ASSERT() macro), but if others feel strongly about this I am certainly open to doing so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I guess I'm still not a huge fan of adding compiler specific ASSERTs into the implementation here. @envoyproxy/maintainers WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, if we do assert like this (evaluate the expression outside of typeid
) then we don't need the pragma at all, since it is no longer potentially evaluated expression, do you think this is cleaner?
ASSERT([&]() {
if (!mutable_config_providers_.empty()) {
const auto& first_provider = **mutable_config_providers_.begin();
return typeid(*provider) == typeid(first_provider);
}
return true;
}());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good solution; I definitely think it's cleaner overall even though it makes the ASSERT() slightly harder to parse. I just pushed this change and removed my changes to assert.h. Thanks!
return tls_->getTyped<ThreadLocalConfig>().config_; | ||
} | ||
|
||
virtual ConfigConstSharedPtr onConfigProtoUpdate(const Protobuf::Message& config_proto) PURE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment on what the semantics of this are? It's still unclear why it's safe to only call this once in checkAndApplyConfig()
. I get that it returns identical objects for the same type, but doesn't the config provider need to latch the proto for configProtoInfo
for all providers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comments.
The latching of the config proto happens in the onConfigUpdate() override
that must be implemented by the concrete subscription class that derives from ConfigSubscriptionInstanceBase
and Envoy::Config::SubscriptionCallbacks<ConfigProto>
. See here for the test source that does this.
return *it->second; | ||
} | ||
|
||
void ConfigProviderManagerImplBase::bindImmutableConfigProvider( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, the new naming scheme is also a bit confusing, since the config object that is provided is always immutable, but the fact that a new config can be swapped in is being assigned the mutability characteristic. IDK if it's worth bike shedding further on this, but just raising this as a potential reader confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added to the file level comment more details regarding the mutability property and how it applies in this context.
I am open to considering other names but this is the best I have come up with given the constraints pointed out by @lizan related to naming conventions already in place for the concrete classes.
// xDS. | ||
Inline, | ||
// Configuration obtained from an xDS subscription. | ||
xDS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: prefer Xds
for consistency here for the enum class value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* | ||
* All config processing is done on the main thread, so instantiation of *ConfigProvider* objects | ||
* via createStaticConfigProvider() and createXdsConfigProvider() is naturally thread safe. Care | ||
* must be taken with regards to destruction of these objects, since it must also happen on the main |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, relative ordering of object destruction on the main thread.. We've had a bunch of use-after-frees by getting this wrong.. would love to have a structural approach to dealing with enforcement of object graph destruction ordering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added note to comment regarding destruction order.
would love to have a structural approach to dealing with enforcement of object graph destruction ordering.
I agree this would be great to have. Is there a pattern already in place elsewhere in the codebase that I should be following?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this is something we would benefit from adding.
Signed-off-by: Andres Guedez <aguedez@google.com>
Signed-off-by: Andres Guedez <aguedez@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo the ASSERT comment/nit. @lizan since I'm going to be off-grid until Fri, can I hand you the baton for final discussion on that topic and merge? Thanks!
source/common/common/assert.h
Outdated
#define ASSERT_IGNORE_POTENTIALLY_EVALUATED(COND) \ | ||
do { \ | ||
__CLANG_PRAGMA("clang diagnostic push") \ | ||
__CLANG_PRAGMA("clang diagnostic ignored \"-Wpotentially-evaluated-expression\"") \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I guess I'm still not a huge fan of adding compiler specific ASSERTs into the implementation here. @envoyproxy/maintainers WDYT?
|
||
const auto* config_proto = dynamic_cast<const P*>(getConfigProto()); | ||
if (config_proto == nullptr) { | ||
return {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: absl::nullopt
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Signed-off-by: Andres Guedez <aguedez@google.com>
Thanks to all involved for the reviews! |
…er framework (envoyproxy#5243) This PR introduces a framework for creating static, inline and dynamic (xDS) config providers. The intent is to create a shared foundation that simplifies implementation of Envoy configuration, in particular xDS config handlers with shared ownership semantics such that the underlying subscription, config proto and config implementation (i.e., the resulting data structures and business logic) are shared across providers and Envoy worker threads. This PR generalizes the RouteConfigProvider, RouteConfigProviderManager and associated *Impls currently used for implementing HTTP route configuration and the RDS API. Note that static route configuration and RDS are not being transitioned to the generalized framework as part of this PR (see note below for details). NOTE: This is PR 1 (out of 4) to implement the scoped HTTP routing design introduced in envoyproxy#4704. The planned PR chain is as follows: 1. Introduce generalized config provider framework 2. Implement static and dynamic scoped routing configuration based on framework introduced in PR 1; the scoped routing business logic will _not_ be part of PR 2 3. Implement scoped routing business logic 4. Refactor RDS to use generalized config provider *Risk Level*: Low (this code is not yet in use; it will be enabled in a follow up PR) *Testing*: New tests added. *Docs Changes*: N/A *Release Notes*: N/A Signed-off-by: Andres Guedez <aguedez@google.com> Signed-off-by: Fred Douglas <fredlas@google.com>
Implement the scoped RDS (SRDS) API config subscription and provider based on the config protos introduced in #6675 and the ConfigProvider framework introduced in #5243 and #6781. NOTES: See parent PR #5839 for full context into these changes. PRs 2a (#6675) and 2b (#6781) have already been merged. The API is not yet fully implemented. This PR introduces static and dynamic (xDS config subscription) handling of scoped routing configuration, but the new L7 multi tenant routing logic (see #4704) has not yet been introduced. The API is not yet plumbed into the HttpConnectionManager, that will be done in the next PR. This PR includes unit tests only; integration tests will follow in the next PR. Risk Level: Low (this DS API is not yet integrated into the HCM and can not be enabled via config). Testing: Unit tests added. Docs Changes: N/A. Signed-off-by: Andres Guedez <aguedez@google.com>
This PR introduces a framework for creating static, inline and dynamic (xDS) config providers.
The intent is to create a shared foundation that simplifies implementation of Envoy configuration, in particular xDS config handlers with shared ownership semantics such that the underlying subscription, config proto and config implementation (i.e., the resulting data structures and business logic) are shared across providers and Envoy worker threads.
This PR generalizes the RouteConfigProvider, RouteConfigProviderManager and associated *Impls currently used for implementing HTTP route configuration and the RDS API. Note that static route configuration and RDS are not being transitioned to the generalized framework as part of this PR (see note below for details).
NOTE: This is PR 1 (out of 4) to implement the scoped HTTP routing design introduced in #4704. The planned PR chain is as follows:
Risk Level: Low (this code is not yet in use; it will be enabled in a follow up PR)
Testing: New tests added.
Docs Changes: N/A
Release Notes: N/A