diff --git a/BUILD b/BUILD index d5e863c552d..c510757c35d 100644 --- a/BUILD +++ b/BUILD @@ -991,6 +991,7 @@ grpc_cc_library( "grpc_resolver_fake", "grpc_resolver_dns_native", "grpc_resolver_sockaddr", + "grpc_resolver_xds", "grpc_transport_chttp2_client_insecure", "grpc_transport_chttp2_server_insecure", "grpc_transport_inproc", @@ -1527,6 +1528,18 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "grpc_resolver_xds", + srcs = [ + "src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc", + ], + language = "c++", + deps = [ + "grpc_base", + "grpc_client_channel", + ], +) + grpc_cc_library( name = "grpc_secure", srcs = [ diff --git a/BUILD.gn b/BUILD.gn index 18204a17c33..1b157427087 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -305,6 +305,7 @@ config("grpc_config") { "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc", "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h", "src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc", + "src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc", "src/core/ext/filters/client_channel/resolver_factory.h", "src/core/ext/filters/client_channel/resolver_registry.cc", "src/core/ext/filters/client_channel/resolver_registry.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b6dba6dedb..86a77c95663 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1368,6 +1368,7 @@ add_library(grpc src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc + src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc src/core/ext/filters/census/grpc_context.cc src/core/ext/filters/client_idle/client_idle_filter.cc src/core/ext/filters/max_age/max_age_filter.cc @@ -2808,6 +2809,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc + src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc diff --git a/Makefile b/Makefile index 8080efcc41a..a0692f38d20 100644 --- a/Makefile +++ b/Makefile @@ -3891,6 +3891,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ + src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ src/core/ext/filters/client_idle/client_idle_filter.cc \ src/core/ext/filters/max_age/max_age_filter.cc \ @@ -5255,6 +5256,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ + src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc \ diff --git a/build.yaml b/build.yaml index 87ca412d12f..7431dbb2a53 100644 --- a/build.yaml +++ b/build.yaml @@ -1224,6 +1224,13 @@ filegroups: uses: - grpc_base - grpc_client_channel +- name: grpc_resolver_xds + src: + - src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc + plugin: grpc_resolver_xds + uses: + - grpc_base + - grpc_client_channel - name: grpc_secure public_headers: - include/grpc/grpc_security.h @@ -1672,6 +1679,7 @@ libs: - grpc_resolver_dns_native - grpc_resolver_sockaddr - grpc_resolver_fake + - grpc_resolver_xds - grpc_secure - census - grpc_client_idle_filter @@ -1743,6 +1751,7 @@ libs: - grpc_resolver_dns_native - grpc_resolver_sockaddr - grpc_resolver_fake + - grpc_resolver_xds - grpc_lb_policy_grpclb - grpc_lb_policy_xds - grpc_lb_policy_pick_first diff --git a/config.m4 b/config.m4 index 72fd381fd53..2a074768f57 100644 --- a/config.m4 +++ b/config.m4 @@ -447,6 +447,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc \ src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ + src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \ src/core/ext/filters/census/grpc_context.cc \ src/core/ext/filters/client_idle/client_idle_filter.cc \ src/core/ext/filters/max_age/max_age_filter.cc \ @@ -732,6 +733,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/sockaddr) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/xds) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_idle) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/deadline) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/http) diff --git a/config.w32 b/config.w32 index a2d0d0f6abf..065da74bfb9 100644 --- a/config.w32 +++ b/config.w32 @@ -420,6 +420,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\dns_resolver_selection.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\xds\\xds_resolver.cc " + "src\\core\\ext\\filters\\census\\grpc_context.cc " + "src\\core\\ext\\filters\\client_idle\\client_idle_filter.cc " + "src\\core\\ext\\filters\\max_age\\max_age_filter.cc " + @@ -738,6 +739,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\fake"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\xds"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_idle"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\deadline"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\http"); diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 2a35ca35fb5..3244e9d08f9 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -945,6 +945,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', + 'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/client_idle/client_idle_filter.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', diff --git a/grpc.gemspec b/grpc.gemspec index c817006b125..5a29165c92d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -874,6 +874,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc ) s.files += %w( src/core/ext/filters/census/grpc_context.cc ) s.files += %w( src/core/ext/filters/client_idle/client_idle_filter.cc ) s.files += %w( src/core/ext/filters/max_age/max_age_filter.cc ) diff --git a/grpc.gyp b/grpc.gyp index 173aef52a79..ba847d99548 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -657,6 +657,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', + 'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/client_idle/client_idle_filter.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', @@ -1434,6 +1435,7 @@ 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', + 'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc', diff --git a/package.xml b/package.xml index 979bc465a75..196c6a6d7db 100644 --- a/package.xml +++ b/package.xml @@ -879,6 +879,7 @@ + diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 11bbb72a367..75fa544c80a 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -1832,6 +1832,7 @@ void XdsLb::ProcessAddressesAndChannelArgsLocked( void XdsLb::ParseLbConfig(const ParsedXdsConfig* xds_config) { if (xds_config == nullptr || xds_config->balancer_name() == nullptr) return; // TODO(yashykt) : does this need to be a gpr_strdup + // TODO(juanlishen): Read balancer name from bootstrap file. balancer_name_ = UniquePtr(gpr_strdup(xds_config->balancer_name())); child_policy_config_ = xds_config->child_policy(); fallback_policy_config_ = xds_config->fallback_policy(); @@ -2588,10 +2589,6 @@ class XdsFactory : public LoadBalancingPolicyFactory { } } } - if (balancer_name == nullptr) { - error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "field:balancerName error:not found")); - } if (error_list.empty()) { return RefCountedPtr(New( balancer_name, std::move(child_policy), std::move(fallback_policy))); diff --git a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc new file mode 100644 index 00000000000..8be1b89eee0 --- /dev/null +++ b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc @@ -0,0 +1,89 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "src/core/ext/filters/client_channel/resolver_registry.h" + +namespace grpc_core { + +namespace { + +class XdsResolver : public Resolver { + public: + explicit XdsResolver(ResolverArgs args) + : Resolver(args.combiner, std::move(args.result_handler)), + args_(grpc_channel_args_copy(args.args)) {} + ~XdsResolver() override { grpc_channel_args_destroy(args_); } + + void StartLocked() override; + + void ShutdownLocked() override{}; + + private: + const grpc_channel_args* args_; +}; + +void XdsResolver::StartLocked() { + static const char* service_config = + "{\n" + " \"loadBalancingConfig\":[\n" + " { \"xds_experimental\":{} }\n" + " ]\n" + "}"; + Result result; + result.args = args_; + args_ = nullptr; + grpc_error* error = GRPC_ERROR_NONE; + result.service_config = ServiceConfig::Create(service_config, &error); + result_handler()->ReturnResult(std::move(result)); +} + +// +// Factory +// + +class XdsResolverFactory : public ResolverFactory { + public: + bool IsValidUri(const grpc_uri* uri) const override { + if (GPR_UNLIKELY(0 != strcmp(uri->authority, ""))) { + gpr_log(GPR_ERROR, "URI authority not supported"); + return false; + } + return true; + } + + OrphanablePtr CreateResolver(ResolverArgs args) const override { + if (!IsValidUri(args.uri)) return nullptr; + return OrphanablePtr(New(std::move(args))); + } + + const char* scheme() const override { return "xds-experimental"; } +}; + +} // namespace + +} // namespace grpc_core + +void grpc_resolver_xds_init() { + grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( + grpc_core::UniquePtr( + grpc_core::New())); +} + +void grpc_resolver_xds_shutdown() {} diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc index 9b011d8df0f..ebe3def245a 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_plugin_registry.cc @@ -46,6 +46,8 @@ void grpc_resolver_dns_native_init(void); void grpc_resolver_dns_native_shutdown(void); void grpc_resolver_sockaddr_init(void); void grpc_resolver_sockaddr_shutdown(void); +void grpc_resolver_xds_init(void); +void grpc_resolver_xds_shutdown(void); void grpc_client_idle_filter_init(void); void grpc_client_idle_filter_shutdown(void); void grpc_max_age_filter_init(void); @@ -84,6 +86,8 @@ void grpc_register_built_in_plugins(void) { grpc_resolver_dns_native_shutdown); grpc_register_plugin(grpc_resolver_sockaddr_init, grpc_resolver_sockaddr_shutdown); + grpc_register_plugin(grpc_resolver_xds_init, + grpc_resolver_xds_shutdown); grpc_register_plugin(grpc_client_idle_filter_init, grpc_client_idle_filter_shutdown); grpc_register_plugin(grpc_max_age_filter_init, diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc index 055c3ccc134..6668836f02f 100644 --- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc @@ -38,6 +38,8 @@ void grpc_resolver_sockaddr_init(void); void grpc_resolver_sockaddr_shutdown(void); void grpc_resolver_fake_init(void); void grpc_resolver_fake_shutdown(void); +void grpc_resolver_xds_init(void); +void grpc_resolver_xds_shutdown(void); void grpc_lb_policy_grpclb_init(void); void grpc_lb_policy_grpclb_shutdown(void); void grpc_lb_policy_xds_init(void); @@ -76,6 +78,8 @@ void grpc_register_built_in_plugins(void) { grpc_resolver_sockaddr_shutdown); grpc_register_plugin(grpc_resolver_fake_init, grpc_resolver_fake_shutdown); + grpc_register_plugin(grpc_resolver_xds_init, + grpc_resolver_xds_shutdown); grpc_register_plugin(grpc_lb_policy_grpclb_init, grpc_lb_policy_grpclb_shutdown); grpc_register_plugin(grpc_lb_policy_xds_init, diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 58c1fd3daba..607235556e3 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -419,6 +419,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc', 'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc', 'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc', + 'src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc', 'src/core/ext/filters/census/grpc_context.cc', 'src/core/ext/filters/client_idle/client_idle_filter.cc', 'src/core/ext/filters/max_age/max_age_filter.cc', diff --git a/test/core/client_channel/service_config_test.cc b/test/core/client_channel/service_config_test.cc index 919441d706a..79dde6bcabe 100644 --- a/test/core/client_channel/service_config_test.cc +++ b/test/core/client_channel/service_config_test.cc @@ -457,28 +457,6 @@ TEST_F(ClientChannelParserTest, InvalidGrpclbLoadBalancingConfig) { VerifyRegexMatch(error, e); } -TEST_F(ClientChannelParserTest, InalidLoadBalancingConfigXds) { - const char* test_json = - "{\n" - " \"loadBalancingConfig\":[\n" - " { \"does_not_exist\":{} },\n" - " { \"xds_experimental\":{} }\n" - " ]\n" - "}"; - grpc_error* error = GRPC_ERROR_NONE; - auto svc_cfg = ServiceConfig::Create(test_json, &error); - gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); - ASSERT_TRUE(error != GRPC_ERROR_NONE); - std::regex e( - std::string("(Service config parsing " - "error)(.*)(referenced_errors)(.*)(Global " - "Params)(.*)(referenced_errors)(.*)(Client channel global " - "parser)(.*)(referenced_errors)(.*)(Xds " - "Parser)(.*)(referenced_errors)(.*)(field:balancerName " - "error:not found)")); - VerifyRegexMatch(error, e); -} - TEST_F(ClientChannelParserTest, ValidLoadBalancingPolicy) { const char* test_json = "{\"loadBalancingPolicy\":\"pick_first\"}"; grpc_error* error = GRPC_ERROR_NONE; diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index 0a5c3740096..9bc7efe957f 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -551,7 +551,8 @@ class XdsEnd2endTest : public ::testing::Test { void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } void ResetStub(int fallback_timeout = 0, - const grpc::string& expected_targets = "") { + const grpc::string& expected_targets = "", + grpc::string scheme = "") { ChannelArguments args; // TODO(juanlishen): Add setter to ChannelArguments. if (fallback_timeout > 0) { @@ -562,8 +563,9 @@ class XdsEnd2endTest : public ::testing::Test { if (!expected_targets.empty()) { args.SetString(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS, expected_targets); } + if (scheme.empty()) scheme = "fake"; std::ostringstream uri; - uri << "fake:///" << kApplicationTargetName_; + uri << scheme << ":///" << kApplicationTargetName_; // TODO(dgq): templatize tests to run everything using both secure and // insecure channel credentials. grpc_channel_credentials* channel_creds = @@ -913,6 +915,20 @@ class XdsEnd2endTest : public ::testing::Test { "}"; }; +class XdsResolverTest : public XdsEnd2endTest { + public: + XdsResolverTest() : XdsEnd2endTest(0, 0, 0) {} +}; + +TEST_F(XdsResolverTest, XdsResolverIsUsed) { + // Use xds-experimental scheme in URI. + ResetStub(0, "", "xds-experimental"); + // Send an RPC to trigger resolution. + SendRpc(); + // Xds resolver returns xds_experimental as the LB policy. + EXPECT_EQ("xds_experimental", channel_->GetLoadBalancingPolicyName()); +} + class SingleBalancerTest : public XdsEnd2endTest { public: SingleBalancerTest() : XdsEnd2endTest(4, 1, 0) {} diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index e9bd8e463ba..e2900b2e701 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -952,6 +952,7 @@ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h \ src/core/ext/filters/client_channel/resolver/sockaddr/README.md \ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \ +src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc \ src/core/ext/filters/client_channel/resolver_factory.h \ src/core/ext/filters/client_channel/resolver_registry.cc \ src/core/ext/filters/client_channel/resolver_registry.h \