-
Notifications
You must be signed in to change notification settings - Fork 5.5k
xds: use filter type URL as the primary way to discover extensions #9618
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
Changes from 4 commits
7442509
aad3af2
ed020ad
151f640
f76c893
224d5cf
2e7c1fa
65113cb
6312737
a4b77ae
ac5504b
2e6515b
4b02241
0c3dba7
cff30cd
9265f8e
c0d29bd
18b57ca
5d3342b
a0445ec
d546d26
6a1d486
bc6f2bb
402a86d
7134d12
36ad6ec
df32987
858dfed
0b875dd
a338edf
9f398d3
1083c22
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,6 +12,7 @@ | |
| #include "common/common/assert.h" | ||
| #include "common/common/fmt.h" | ||
| #include "common/common/logger.h" | ||
| #include "common/config/api_type_oracle.h" | ||
| #include "common/protobuf/utility.h" | ||
|
|
||
| #include "absl/base/attributes.h" | ||
|
|
@@ -188,6 +189,50 @@ template <class Base> class FactoryRegistry : public Logger::Loggable<Logger::Id | |
| return *deprecated_factory_names; | ||
| } | ||
|
|
||
| /** | ||
| * Lazily constructs a mapping from the configuration message type to a factory, | ||
| * including the deprecated configuration message types. | ||
| * Must be invoked after factory registration is completed. | ||
| */ | ||
| static absl::flat_hash_map<std::string, Base*>& factoriesByType() { | ||
| static absl::flat_hash_map<std::string, Base*>* factoriesByType = [] { | ||
| auto* mapping = new absl::flat_hash_map<std::string, Base*>(); | ||
|
|
||
| for (const auto& factory : factories()) { | ||
| if (factory.second == nullptr) { | ||
| continue; | ||
| } | ||
|
|
||
| // skip untyped factories and factories that consume Struct | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Which factories consume
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Only test factories AFAICT.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It feels kind of bad that we need to have prod code here that exists just for test, any way we can improve that, e.g. switch tests to use some canonical
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't think deeply about filters that use struct as config type. I'd out-right ban Struct but that requires deprecation and will to force everyone to create their own proto types. Can this be done separately? What we did with Empty was easier since it was mostly used in Envoy code base.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. People are definitely using Empty outside of Envoy (we have filters at Lyft that have no config), but the Empty case should "just work" as there is no config needed. I agree with @kyessenov that we can't ban struct without a deprecation cycle as we don't know if anyone is using Struct for their filter configs. We could deprecate it though, but that would require a warning/stat/etc. and the full dance. Can you file an issue and TODO a follow up here?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done.
kyessenov marked this conversation as resolved.
Outdated
|
||
| std::string config_type = factory.second->configType(); | ||
| if (config_type.empty() || config_type == "google.protobuf.Struct") { | ||
| continue; | ||
| } | ||
|
|
||
| // traverse the deprecated message type chain | ||
| while (true) { | ||
| auto it = mapping->find(config_type); | ||
| if (it != mapping->end() && it->second != factory.second) { | ||
| throw EnvoyException(fmt::format("Double registration for type: '{}' by '{}' and '{}'", | ||
| config_type, factory.second->name(), | ||
| it->second->name())); | ||
| } | ||
| mapping->emplace(std::make_pair(config_type, factory.second)); | ||
|
|
||
| const Protobuf::Descriptor* previous = | ||
| Config::ApiTypeOracle::getEarlierVersionDescriptor(config_type); | ||
| if (previous == nullptr) { | ||
| break; | ||
| } | ||
| config_type = previous->full_name(); | ||
| } | ||
| } | ||
| return mapping; | ||
| }(); | ||
|
|
||
| return *factoriesByType; | ||
| } | ||
|
|
||
| /** | ||
| * instead_value are used when passed name was deprecated. | ||
| */ | ||
|
|
@@ -262,6 +307,14 @@ template <class Base> class FactoryRegistry : public Logger::Loggable<Logger::Id | |
| return it->second; | ||
| } | ||
|
|
||
| static Base* getFactoryByType(absl::string_view type) { | ||
| auto it = factoriesByType().find(type); | ||
| if (it == factoriesByType().end()) { | ||
| return nullptr; | ||
| } | ||
| return it->second; | ||
| } | ||
|
|
||
| /** | ||
| * @return the canonical name of the factory. If the given name is a | ||
| * deprecated factory name, the canonical name is returned instead. | ||
|
|
@@ -319,6 +372,7 @@ template <class Base> class FactoryRegistry : public Logger::Loggable<Logger::Id | |
|
|
||
| factories().emplace(factory.name(), &factory); | ||
| RELEASE_ASSERT(getFactory(factory.name()) == &factory, ""); | ||
| factoriesByType().emplace(factory.configType(), &factory); | ||
|
|
||
| return displaced; | ||
| } | ||
|
|
@@ -327,9 +381,10 @@ template <class Base> class FactoryRegistry : public Logger::Loggable<Logger::Id | |
| * Remove a factory by name. This method should only be used for testing purposes. | ||
| * @param name is the name of the factory to remove. | ||
| */ | ||
| static void removeFactoryForTest(absl::string_view name) { | ||
| static void removeFactoryForTest(absl::string_view name, absl::string_view config_type) { | ||
| auto result = factories().erase(name); | ||
| RELEASE_ASSERT(result == 1, ""); | ||
| factoriesByType().erase(config_type); | ||
| } | ||
| }; | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.