Reviewer comments

reviewable/pr18746/r6
Yash Tibrewal 6 years ago
parent 71ecf17eb7
commit 156d743c37
  1. 2
      BUILD
  2. 2
      BUILD.gn
  3. 6
      CMakeLists.txt
  4. 6
      Makefile
  5. 2
      build.yaml
  6. 1
      config.m4
  7. 1
      config.w32
  8. 1
      gRPC-C++.podspec
  9. 3
      gRPC-Core.podspec
  10. 2
      grpc.gemspec
  11. 4
      grpc.gyp
  12. 2
      package.xml
  13. 26
      src/core/ext/filters/client_channel/client_channel.cc
  14. 8
      src/core/ext/filters/client_channel/client_channel_plugin.cc
  15. 84
      src/core/ext/filters/client_channel/health/health_check_parser.cc
  16. 3
      src/core/ext/filters/client_channel/health/health_check_parser.h
  17. 39
      src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
  18. 32
      src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
  19. 34
      src/core/ext/filters/client_channel/lb_policy_registry.cc
  20. 9
      src/core/ext/filters/client_channel/lb_policy_registry.h
  21. 312
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  22. 33
      src/core/ext/filters/client_channel/resolver_result_parsing.h
  23. 2
      src/core/ext/filters/client_channel/resolving_lb_policy.cc
  24. 2
      src/core/ext/filters/client_channel/resolving_lb_policy.h
  25. 8
      src/core/ext/filters/client_channel/service_config.cc
  26. 52
      src/core/ext/filters/client_channel/service_config.h
  27. 22
      src/core/ext/filters/message_size/message_size_filter.cc
  28. 2
      src/core/lib/gprpp/optional.h
  29. 19
      src/core/lib/iomgr/error.h
  30. 1
      src/python/grpcio/grpc_core_dependencies.py
  31. 116
      test/core/client_channel/service_config_test.cc
  32. 2
      tools/doxygen/Doxyfile.core.internal
  33. 3
      tools/run_tests/generated/sources_and_headers.json

@ -1082,7 +1082,6 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/connector.cc",
"src/core/ext/filters/client_channel/global_subchannel_pool.cc", "src/core/ext/filters/client_channel/global_subchannel_pool.cc",
"src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/health/health_check_parser.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc",
"src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/http_proxy.cc",
"src/core/ext/filters/client_channel/lb_policy.cc", "src/core/ext/filters/client_channel/lb_policy.cc",
@ -1109,7 +1108,6 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/connector.h", "src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/health/health_check_parser.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/http_proxy.h",
"src/core/ext/filters/client_channel/lb_policy.h", "src/core/ext/filters/client_channel/lb_policy.h",

@ -260,8 +260,6 @@ config("grpc_config") {
"src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/health/health_check_parser.cc",
"src/core/ext/filters/client_channel/health/health_check_parser.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/http_proxy.cc",

@ -1235,7 +1235,6 @@ add_library(grpc
src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_parser.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy.cc
@ -1591,7 +1590,6 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_parser.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy.cc
@ -1972,7 +1970,6 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_parser.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy.cc
@ -2298,7 +2295,6 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_parser.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy.cc
@ -2635,7 +2631,6 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_parser.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy.cc
@ -3508,7 +3503,6 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/connector.cc src/core/ext/filters/client_channel/connector.cc
src/core/ext/filters/client_channel/global_subchannel_pool.cc src/core/ext/filters/client_channel/global_subchannel_pool.cc
src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/health/health_check_client.cc
src/core/ext/filters/client_channel/health/health_check_parser.cc
src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc
src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/http_proxy.cc
src/core/ext/filters/client_channel/lb_policy.cc src/core/ext/filters/client_channel/lb_policy.cc

@ -3695,7 +3695,6 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \
@ -4045,7 +4044,6 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \
@ -4419,7 +4417,6 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \
@ -4732,7 +4729,6 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \
@ -5043,7 +5039,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \
@ -5892,7 +5887,6 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \

@ -576,7 +576,6 @@ filegroups:
- src/core/ext/filters/client_channel/connector.h - src/core/ext/filters/client_channel/connector.h
- src/core/ext/filters/client_channel/global_subchannel_pool.h - src/core/ext/filters/client_channel/global_subchannel_pool.h
- src/core/ext/filters/client_channel/health/health_check_client.h - src/core/ext/filters/client_channel/health/health_check_client.h
- src/core/ext/filters/client_channel/health/health_check_parser.h
- src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_connect_handshaker.h
- src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/http_proxy.h
- src/core/ext/filters/client_channel/lb_policy.h - src/core/ext/filters/client_channel/lb_policy.h
@ -606,7 +605,6 @@ filegroups:
- src/core/ext/filters/client_channel/connector.cc - src/core/ext/filters/client_channel/connector.cc
- src/core/ext/filters/client_channel/global_subchannel_pool.cc - src/core/ext/filters/client_channel/global_subchannel_pool.cc
- src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/health/health_check_client.cc
- src/core/ext/filters/client_channel/health/health_check_parser.cc
- src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc
- src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/http_proxy.cc
- src/core/ext/filters/client_channel/lb_policy.cc - src/core/ext/filters/client_channel/lb_policy.cc

@ -348,7 +348,6 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.cc \
src/core/ext/filters/client_channel/global_subchannel_pool.cc \ src/core/ext/filters/client_channel/global_subchannel_pool.cc \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \
src/core/ext/filters/client_channel/lb_policy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \

@ -323,7 +323,6 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\connector.cc " + "src\\core\\ext\\filters\\client_channel\\connector.cc " +
"src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " + "src\\core\\ext\\filters\\client_channel\\global_subchannel_pool.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health_check_parser.cc " +
"src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " +
"src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " +

@ -367,7 +367,6 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/health/health_check_parser.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/http_proxy.h',
'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy.h',

@ -347,7 +347,6 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/health/health_check_parser.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/http_proxy.h',
'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy.h',
@ -797,7 +796,6 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/health/health_check_parser.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc',
@ -991,7 +989,6 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/connector.h', 'src/core/ext/filters/client_channel/connector.h',
'src/core/ext/filters/client_channel/global_subchannel_pool.h', 'src/core/ext/filters/client_channel/global_subchannel_pool.h',
'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/health/health_check_client.h',
'src/core/ext/filters/client_channel/health/health_check_parser.h',
'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h',
'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/http_proxy.h',
'src/core/ext/filters/client_channel/lb_policy.h', 'src/core/ext/filters/client_channel/lb_policy.h',

@ -281,7 +281,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/connector.h ) s.files += %w( src/core/ext/filters/client_channel/connector.h )
s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h ) s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.h )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_parser.h )
s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h )
s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
@ -734,7 +733,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/connector.cc ) s.files += %w( src/core/ext/filters/client_channel/connector.cc )
s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc ) s.files += %w( src/core/ext/filters/client_channel/global_subchannel_pool.cc )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc )
s.files += %w( src/core/ext/filters/client_channel/health/health_check_parser.cc )
s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc )
s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc )

@ -530,7 +530,6 @@
'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/health/health_check_parser.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc',
@ -795,7 +794,6 @@
'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/health/health_check_parser.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc',
@ -1041,7 +1039,6 @@
'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/health/health_check_parser.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc',
@ -1298,7 +1295,6 @@
'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/health/health_check_parser.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc',

@ -286,7 +286,6 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_parser.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
@ -739,7 +738,6 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/global_subchannel_pool.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_parser.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" />

@ -240,6 +240,7 @@ class ChannelData {
const size_t per_rpc_retry_buffer_size_; const size_t per_rpc_retry_buffer_size_;
grpc_channel_stack* owning_stack_; grpc_channel_stack* owning_stack_;
ClientChannelFactory* client_channel_factory_; ClientChannelFactory* client_channel_factory_;
UniquePtr<char> server_name_;
// Initialized shortly after construction. // Initialized shortly after construction.
channelz::ClientChannelNode* channelz_node_ = nullptr; channelz::ClientChannelNode* channelz_node_ = nullptr;
@ -263,7 +264,7 @@ class ChannelData {
OrphanablePtr<LoadBalancingPolicy> resolving_lb_policy_; OrphanablePtr<LoadBalancingPolicy> resolving_lb_policy_;
grpc_connectivity_state_tracker state_tracker_; grpc_connectivity_state_tracker state_tracker_;
ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_; ExternalConnectivityWatcher::WatcherList external_connectivity_watcher_list_;
const char* health_check_service_name_ = nullptr; UniquePtr<char> health_check_service_name_;
// //
// Fields accessed from both data plane and control plane combiners. // Fields accessed from both data plane and control plane combiners.
@ -762,12 +763,11 @@ class ChannelData::ConnectivityStateAndPickerSetter {
class ChannelData::ServiceConfigSetter { class ChannelData::ServiceConfigSetter {
public: public:
ServiceConfigSetter( ServiceConfigSetter(
ChannelData* chand, UniquePtr<char> server_name, ChannelData* chand,
Optional<internal::ClientChannelGlobalParsedObject::RetryThrottling> Optional<internal::ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data, retry_throttle_data,
RefCountedPtr<ServiceConfig> service_config) RefCountedPtr<ServiceConfig> service_config)
: chand_(chand), : chand_(chand),
server_name_(std::move(server_name)),
retry_throttle_data_(retry_throttle_data), retry_throttle_data_(retry_throttle_data),
service_config_(std::move(service_config)) { service_config_(std::move(service_config)) {
GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter"); GRPC_CHANNEL_STACK_REF(chand->owning_stack_, "ServiceConfigSetter");
@ -785,7 +785,7 @@ class ChannelData::ServiceConfigSetter {
if (self->retry_throttle_data_.has_value()) { if (self->retry_throttle_data_.has_value()) {
chand->retry_throttle_data_ = chand->retry_throttle_data_ =
internal::ServerRetryThrottleMap::GetDataForServer( internal::ServerRetryThrottleMap::GetDataForServer(
self->server_name_.get(), chand->server_name_.get(),
self->retry_throttle_data_.value().max_milli_tokens, self->retry_throttle_data_.value().max_milli_tokens,
self->retry_throttle_data_.value().milli_token_ratio); self->retry_throttle_data_.value().milli_token_ratio);
} }
@ -803,7 +803,6 @@ class ChannelData::ServiceConfigSetter {
} }
ChannelData* chand_; ChannelData* chand_;
UniquePtr<char> server_name_;
Optional<internal::ClientChannelGlobalParsedObject::RetryThrottling> Optional<internal::ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data_; retry_throttle_data_;
RefCountedPtr<ServiceConfig> service_config_; RefCountedPtr<ServiceConfig> service_config_;
@ -948,7 +947,7 @@ class ChannelData::ClientChannelControlHelper
if (chand_->health_check_service_name_ != nullptr) { if (chand_->health_check_service_name_ != nullptr) {
args_to_add[0] = grpc_channel_arg_string_create( args_to_add[0] = grpc_channel_arg_string_create(
const_cast<char*>("grpc.temp.health_check"), const_cast<char*>("grpc.temp.health_check"),
const_cast<char*>(chand_->health_check_service_name_)); const_cast<char*>(chand_->health_check_service_name_.get()));
num_args_to_add++; num_args_to_add++;
} }
args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg( args_to_add[num_args_to_add++] = SubchannelPoolInterface::CreateChannelArg(
@ -1067,6 +1066,10 @@ ChannelData::ChannelData(grpc_channel_element_args* args, grpc_error** error)
"filter"); "filter");
return; return;
} }
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
server_name_.reset(
gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path));
char* proxy_name = nullptr; char* proxy_name = nullptr;
grpc_channel_args* new_args = nullptr; grpc_channel_args* new_args = nullptr;
grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name, grpc_proxy_mappers_map_name(server_uri, args->channel_args, &proxy_name,
@ -1135,11 +1138,12 @@ bool ChannelData::ProcessResolverResultLocked(
gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"", gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"",
chand, service_config_json); chand, service_config_json);
} }
chand->health_check_service_name_.reset(
gpr_strdup(resolver_result.health_check_service_name()));
// Create service config setter to update channel state in the data // Create service config setter to update channel state in the data
// plane combiner. Destroys itself when done. // plane combiner. Destroys itself when done.
New<ServiceConfigSetter>( New<ServiceConfigSetter>(chand, resolver_result.retry_throttle_data(),
chand, UniquePtr<char>(gpr_strdup(resolver_result.server_name())), resolver_result.service_config());
resolver_result.retry_throttle_data(), resolver_result.service_config());
// Swap out the data used by GetChannelInfo(). // Swap out the data used by GetChannelInfo().
bool service_config_changed; bool service_config_changed;
{ {
@ -1156,8 +1160,6 @@ bool ChannelData::ProcessResolverResultLocked(
// Return results. // Return results.
*lb_policy_name = chand->info_lb_policy_name_.get(); *lb_policy_name = chand->info_lb_policy_name_.get();
*lb_policy_config = resolver_result.lb_policy_config(); *lb_policy_config = resolver_result.lb_policy_config();
chand->health_check_service_name_ =
resolver_result.health_check_service_name();
return service_config_changed; return service_config_changed;
} }
@ -3101,7 +3103,7 @@ void CallData::ApplyServiceConfigToCallLocked(grpc_call_element* elem) {
// it. // it.
service_config_call_data_ = service_config_call_data_ =
ServiceConfig::CallData(chand->service_config(), path_); ServiceConfig::CallData(chand->service_config(), path_);
if (!service_config_call_data_.empty()) { if (service_config_call_data_.service_config() != nullptr) {
call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value = call_context_[GRPC_SERVICE_CONFIG_CALL_DATA].value =
&service_config_call_data_; &service_config_call_data_;
method_params_ = static_cast<ClientChannelMethodParsedObject*>( method_params_ = static_cast<ClientChannelMethodParsedObject*>(

@ -27,7 +27,6 @@
#include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/client_channel_channelz.h" #include "src/core/ext/filters/client_channel/client_channel_channelz.h"
#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" #include "src/core/ext/filters/client_channel/global_subchannel_pool.h"
#include "src/core/ext/filters/client_channel/health/health_check_parser.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h" #include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/http_proxy.h" #include "src/core/ext/filters/client_channel/http_proxy.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
@ -50,14 +49,9 @@ static bool append_filter(grpc_channel_stack_builder* builder, void* arg) {
builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr); builder, static_cast<const grpc_channel_filter*>(arg), nullptr, nullptr);
} }
void grpc_service_config_register_parsers() {
grpc_core::internal::ClientChannelServiceConfigParser::Register();
grpc_core::HealthCheckParser::Register();
}
void grpc_client_channel_init(void) { void grpc_client_channel_init(void) {
grpc_core::ServiceConfig::Init(); grpc_core::ServiceConfig::Init();
grpc_service_config_register_parsers(); grpc_core::internal::ClientChannelServiceConfigParser::Register();
grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry(); grpc_core::LoadBalancingPolicyRegistry::Builder::InitRegistry();
grpc_core::ResolverRegistry::Builder::InitRegistry(); grpc_core::ResolverRegistry::Builder::InitRegistry();
grpc_core::internal::ServerRetryThrottleMap::Init(); grpc_core::internal::ServerRetryThrottleMap::Init();

@ -1,84 +0,0 @@
/*
*
* 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 <grpc/support/port_platform.h>
#include "src/core/ext/filters/client_channel/health/health_check_parser.h"
namespace grpc_core {
namespace {
size_t g_health_check_parser_index;
}
UniquePtr<ServiceConfig::ParsedConfig> HealthCheckParser::ParseGlobalParams(
const grpc_json* json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
const char* service_name = nullptr;
InlinedVector<grpc_error*, 2> error_list;
for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) {
GPR_DEBUG_ASSERT(false);
continue;
}
if (strcmp(field->key, "healthCheckConfig") == 0) {
if (field->type != GRPC_JSON_OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:should be of type object");
return nullptr;
}
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) {
GPR_DEBUG_ASSERT(false);
continue;
}
if (strcmp(sub_field->key, "serviceName") == 0) {
if (service_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:Duplicate "
"entry"));
continue;
}
if (sub_field->type != GRPC_JSON_STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:should be of type string"));
continue;
}
service_name = sub_field->value;
}
}
}
}
if (error_list.empty()) {
if (service_name == nullptr) return nullptr;
return UniquePtr<ServiceConfig::ParsedConfig>(
New<HealthCheckParsedObject>(service_name));
}
*error = ServiceConfig::CreateErrorFromVector("field:healthCheckConfig",
&error_list);
return nullptr;
}
void HealthCheckParser::Register() {
g_health_check_parser_index = ServiceConfig::RegisterParser(
UniquePtr<ServiceConfig::Parser>(New<HealthCheckParser>()));
}
size_t HealthCheckParser::ParserIndex() { return g_health_check_parser_index; }
} // namespace grpc_core

@ -24,7 +24,7 @@
#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/service_config.h"
namespace grpc_core { namespace grpc_core {
#if 0
class HealthCheckParsedObject : public ServiceConfig::ParsedConfig { class HealthCheckParsedObject : public ServiceConfig::ParsedConfig {
public: public:
HealthCheckParsedObject(const char* service_name) HealthCheckParsedObject(const char* service_name)
@ -47,5 +47,6 @@ class HealthCheckParser : public ServiceConfig::Parser {
static size_t ParserIndex(); static size_t ParserIndex();
}; };
#endif
} // namespace grpc_core } // namespace grpc_core
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */ #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_PARSER_H */

@ -120,7 +120,8 @@ constexpr char kGrpclb[] = "grpclb";
class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig { class ParsedGrpcLbConfig : public ParsedLoadBalancingConfig {
public: public:
ParsedGrpcLbConfig(RefCountedPtr<ParsedLoadBalancingConfig> child_policy) explicit ParsedGrpcLbConfig(
RefCountedPtr<ParsedLoadBalancingConfig> child_policy)
: child_policy_(std::move(child_policy)) {} : child_policy_(std::move(child_policy)) {}
const char* name() const override { return kGrpclb; } const char* name() const override { return kGrpclb; }
@ -1142,13 +1143,13 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// we want to retry connecting. Otherwise, we have deliberately ended this // we want to retry connecting. Otherwise, we have deliberately ended this
// call and no further action is required. // call and no further action is required.
if (lb_calld == grpclb_policy->lb_calld_.get()) { if (lb_calld == grpclb_policy->lb_calld_.get()) {
// If the fallback-at-startup checks are pending, go into fallback mode // If we did not receive a serverlist and the fallback-at-startup checks
// immediately. This short-circuits the timeout for the fallback-at-startup // are pending, go into fallback mode immediately. This short-circuits
// case. // the timeout for the fallback-at-startup case.
if (grpclb_policy->fallback_at_startup_checks_pending_) { if (!lb_calld->seen_serverlist_ &&
GPR_ASSERT(!lb_calld->seen_serverlist_); grpclb_policy->fallback_at_startup_checks_pending_) {
gpr_log(GPR_INFO, gpr_log(GPR_INFO,
"[grpclb %p] Balancer call finished without receiving " "[grpclb %p] balancer call finished without receiving "
"serverlist; entering fallback mode", "serverlist; entering fallback mode",
grpclb_policy); grpclb_policy);
grpclb_policy->fallback_at_startup_checks_pending_ = false; grpclb_policy->fallback_at_startup_checks_pending_ = false;
@ -1393,7 +1394,6 @@ void GrpcLb::UpdateLocked(UpdateArgs args) {
} else { } else {
child_policy_config_ = nullptr; child_policy_config_ = nullptr;
} }
ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args);
// Update the existing child policy. // Update the existing child policy.
if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked(); if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked();
@ -1627,16 +1627,20 @@ void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked( grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked(
bool is_backend_from_grpclb_load_balancer) { bool is_backend_from_grpclb_load_balancer) {
InlinedVector<grpc_arg, 2> args_to_add; grpc_arg args_to_add[2] = {
args_to_add.emplace_back(grpc_channel_arg_integer_create( // A channel arg indicating if the target is a backend inferred from a
const_cast<char*>(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), // grpclb load balancer.
is_backend_from_grpclb_load_balancer)); grpc_channel_arg_integer_create(
const_cast<char*>(
GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
is_backend_from_grpclb_load_balancer),
};
size_t num_args_to_add = 1;
if (is_backend_from_grpclb_load_balancer) { if (is_backend_from_grpclb_load_balancer) {
args_to_add.emplace_back(grpc_channel_arg_integer_create( args_to_add[num_args_to_add++] = grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1)); const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
} }
return grpc_channel_args_copy_and_add(args_, args_to_add.data(), return grpc_channel_args_copy_and_add(args_, args_to_add, num_args_to_add);
args_to_add.size());
} }
OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked( OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
@ -1830,8 +1834,7 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory {
return RefCountedPtr<ParsedLoadBalancingConfig>( return RefCountedPtr<ParsedLoadBalancingConfig>(
New<ParsedGrpcLbConfig>(std::move(child_policy))); New<ParsedGrpcLbConfig>(std::move(child_policy)));
} else { } else {
*error = *error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list);
ServiceConfig::CreateErrorFromVector("GrpcLb Parser", &error_list);
return nullptr; return nullptr;
} }
} }

@ -362,10 +362,9 @@ class XdsLb : public LoadBalancingPolicy {
: parent_(std::move(parent)), locality_weight_(locality_weight) {} : parent_(std::move(parent)), locality_weight_(locality_weight) {}
~LocalityEntry() = default; ~LocalityEntry() = default;
void UpdateLocked( void UpdateLocked(xds_grpclb_serverlist* serverlist,
xds_grpclb_serverlist* serverlist, ParsedLoadBalancingConfig* child_policy_config,
const RefCountedPtr<ParsedLoadBalancingConfig>& child_policy_config, const grpc_channel_args* args);
const grpc_channel_args* args);
void ShutdownLocked(); void ShutdownLocked();
void ResetBackoffLocked(); void ResetBackoffLocked();
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
@ -410,10 +409,9 @@ class XdsLb : public LoadBalancingPolicy {
uint32_t locality_weight_; uint32_t locality_weight_;
}; };
void UpdateLocked( void UpdateLocked(const LocalityList& locality_list,
const LocalityList& locality_list, ParsedLoadBalancingConfig* child_policy_config,
const RefCountedPtr<ParsedLoadBalancingConfig>& child_policy_config, const grpc_channel_args* args, XdsLb* parent);
const grpc_channel_args* args, XdsLb* parent);
void ShutdownLocked(); void ShutdownLocked();
void ResetBackoffLocked(); void ResetBackoffLocked();
void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels, void FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
@ -1217,7 +1215,7 @@ void XdsLb::BalancerChannelState::BalancerCallState::
xdslb_policy->locality_serverlist_[0]->serverlist = serverlist; xdslb_policy->locality_serverlist_[0]->serverlist = serverlist;
xdslb_policy->locality_map_.UpdateLocked( xdslb_policy->locality_map_.UpdateLocked(
xdslb_policy->locality_serverlist_, xdslb_policy->locality_serverlist_,
xdslb_policy->child_policy_config_, xdslb_policy->args_, xdslb_policy->child_policy_config_.get(), xdslb_policy->args_,
xdslb_policy); xdslb_policy);
} }
} else { } else {
@ -1530,8 +1528,8 @@ void XdsLb::UpdateLocked(UpdateArgs args) {
return; return;
} }
ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args); ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args);
locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_, args_, locality_map_.UpdateLocked(locality_serverlist_, child_policy_config_.get(),
this); args_, this);
// Update the existing fallback policy. The fallback policy config and/or the // Update the existing fallback policy. The fallback policy config and/or the
// fallback addresses may be new. // fallback addresses may be new.
if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked(); if (fallback_policy_ != nullptr) UpdateFallbackPolicyLocked();
@ -1750,7 +1748,7 @@ void XdsLb::LocalityMap::PruneLocalities(const LocalityList& locality_list) {
void XdsLb::LocalityMap::UpdateLocked( void XdsLb::LocalityMap::UpdateLocked(
const LocalityList& locality_serverlist, const LocalityList& locality_serverlist,
const RefCountedPtr<ParsedLoadBalancingConfig>& child_policy_config, ParsedLoadBalancingConfig* child_policy_config,
const grpc_channel_args* args, XdsLb* parent) { const grpc_channel_args* args, XdsLb* parent) {
if (parent->shutting_down_) return; if (parent->shutting_down_) return;
for (size_t i = 0; i < locality_serverlist.size(); i++) { for (size_t i = 0; i < locality_serverlist.size(); i++) {
@ -1845,13 +1843,13 @@ XdsLb::LocalityMap::LocalityEntry::CreateChildPolicyLocked(
void XdsLb::LocalityMap::LocalityEntry::UpdateLocked( void XdsLb::LocalityMap::LocalityEntry::UpdateLocked(
xds_grpclb_serverlist* serverlist, xds_grpclb_serverlist* serverlist,
const RefCountedPtr<ParsedLoadBalancingConfig>& child_policy_config, ParsedLoadBalancingConfig* child_policy_config,
const grpc_channel_args* args_in) { const grpc_channel_args* args_in) {
if (parent_->shutting_down_) return; if (parent_->shutting_down_) return;
// Construct update args. // Construct update args.
UpdateArgs update_args; UpdateArgs update_args;
update_args.addresses = ProcessServerlist(serverlist); update_args.addresses = ProcessServerlist(serverlist);
update_args.config = child_policy_config; update_args.config = child_policy_config->Ref();
update_args.args = CreateChildPolicyArgsLocked(args_in); update_args.args = CreateChildPolicyArgsLocked(args_in);
// If the child policy name changes, we need to create a new child // If the child policy name changes, we need to create a new child
// policy. When this happens, we leave child_policy_ as-is and store // policy. When this happens, we leave child_policy_ as-is and store
@ -2176,8 +2174,8 @@ class XdsFactory : public LoadBalancingPolicyFactory {
InlinedVector<grpc_error*, 3> error_list; InlinedVector<grpc_error*, 3> error_list;
const char* balancer_name = nullptr; const char* balancer_name = nullptr;
RefCountedPtr<ParsedLoadBalancingConfig> child_policy = nullptr; RefCountedPtr<ParsedLoadBalancingConfig> child_policy;
RefCountedPtr<ParsedLoadBalancingConfig> fallback_policy = nullptr; RefCountedPtr<ParsedLoadBalancingConfig> fallback_policy;
for (const grpc_json* field = json->child; field != nullptr; for (const grpc_json* field = json->child; field != nullptr;
field = field->next) { field = field->next) {
if (field->key == nullptr) continue; if (field->key == nullptr) continue;
@ -2229,7 +2227,7 @@ class XdsFactory : public LoadBalancingPolicyFactory {
return RefCountedPtr<ParsedLoadBalancingConfig>(New<ParsedXdsConfig>( return RefCountedPtr<ParsedLoadBalancingConfig>(New<ParsedXdsConfig>(
balancer_name, std::move(child_policy), std::move(fallback_policy))); balancer_name, std::move(child_policy), std::move(fallback_policy)));
} else { } else {
*error = ServiceConfig::CreateErrorFromVector("Xds Parser", &error_list); *error = GRPC_ERROR_CREATE_FROM_VECTOR("Xds Parser", &error_list);
return nullptr; return nullptr;
} }
} }

@ -94,9 +94,21 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
return factory->CreateLoadBalancingPolicy(std::move(args)); return factory->CreateLoadBalancingPolicy(std::move(args));
} }
bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) { bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
const char* name, bool* requires_config) {
GPR_ASSERT(g_state != nullptr); GPR_ASSERT(g_state != nullptr);
return g_state->GetLoadBalancingPolicyFactory(name) != nullptr; auto* factory = g_state->GetLoadBalancingPolicyFactory(name);
if (factory == nullptr) {
return false;
}
if (requires_config != nullptr) {
grpc_error* error = GRPC_ERROR_NONE;
// Check if the load balancing policy allows an empty config
*requires_config =
factory->ParseLoadBalancingConfig(nullptr, &error) == nullptr;
GRPC_ERROR_UNREF(error);
}
return true;
} }
namespace { namespace {
@ -152,7 +164,8 @@ grpc_json* ParseLoadBalancingConfigHelper(const grpc_json* lb_config_array,
return nullptr; return nullptr;
} }
// If we support this policy, then select it. // If we support this policy, then select it.
if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key)) { if (LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(policy->key,
nullptr)) {
return policy; return policy;
} }
} }
@ -189,19 +202,4 @@ LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(const grpc_json* json,
} }
} }
grpc_error* LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy(
const char* lb_policy_name) {
GPR_DEBUG_ASSERT(g_state != nullptr);
gpr_log(GPR_ERROR, "%s", lb_policy_name);
auto* factory = g_state->GetLoadBalancingPolicyFactory(lb_policy_name);
if (factory == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:Unknown lb policy");
}
grpc_error* error = GRPC_ERROR_NONE;
// Check if the load balancing policy allows an empty config
factory->ParseLoadBalancingConfig(nullptr, &error);
return error;
}
} // namespace grpc_core } // namespace grpc_core

@ -49,16 +49,15 @@ class LoadBalancingPolicyRegistry {
const char* name, LoadBalancingPolicy::Args args); const char* name, LoadBalancingPolicy::Args args);
/// Returns true if the LB policy factory specified by \a name exists in this /// Returns true if the LB policy factory specified by \a name exists in this
/// registry. /// registry. If the load balancing policy requires a config to be specified
static bool LoadBalancingPolicyExists(const char* name); /// then sets \a requires_config to true.
static bool LoadBalancingPolicyExists(const char* name,
bool* requires_config);
/// Returns a parsed object of the load balancing policy to be used from a /// Returns a parsed object of the load balancing policy to be used from a
/// LoadBalancingConfig array \a json. /// LoadBalancingConfig array \a json.
static RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig( static RefCountedPtr<ParsedLoadBalancingConfig> ParseLoadBalancingConfig(
const grpc_json* json, grpc_error** error); const grpc_json* json, grpc_error** error);
/// Validates if a load balancing policy can be created from \a lb_policy_name
static grpc_error* CanCreateLoadBalancingPolicy(const char* lb_policy_name);
}; };
} // namespace grpc_core } // namespace grpc_core

@ -29,7 +29,6 @@
#include <grpc/support/string_util.h> #include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/filters/client_channel/health/health_check_parser.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h" #include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_args.h"
@ -88,25 +87,13 @@ ProcessedResolverResult::ProcessedResolverResult(
void ProcessedResolverResult::ProcessServiceConfig( void ProcessedResolverResult::ProcessServiceConfig(
const Resolver::Result& resolver_result, const Resolver::Result& resolver_result,
const ClientChannelGlobalParsedObject* parsed_object) { const ClientChannelGlobalParsedObject* parsed_object) {
auto* health_check = static_cast<HealthCheckParsedObject*>( health_check_service_name_ = parsed_object->health_check_service_name();
service_config_->GetParsedGlobalServiceConfigObject(
HealthCheckParser::ParserIndex()));
health_check_service_name_ =
health_check != nullptr ? health_check->service_name() : nullptr;
service_config_json_ = service_config_->service_config_json(); service_config_json_ = service_config_->service_config_json();
if (!parsed_object) { if (!parsed_object) {
return; return;
} }
if (parsed_object->retry_throttling().has_value()) { if (parsed_object->retry_throttling().has_value()) {
const grpc_arg* channel_arg =
grpc_channel_args_find(resolver_result.args, GRPC_ARG_SERVER_URI);
const char* server_uri = grpc_channel_arg_get_string(channel_arg);
GPR_ASSERT(server_uri != nullptr);
grpc_uri* uri = grpc_uri_parse(server_uri, true);
GPR_ASSERT(uri->path[0] != '\0');
server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
retry_throttle_data_ = parsed_object->retry_throttling(); retry_throttle_data_ = parsed_object->retry_throttling();
grpc_uri_destroy(uri);
} }
} }
@ -122,12 +109,6 @@ void ProcessedResolverResult::ProcessLbPolicy(
} else { } else {
lb_policy_name_.reset( lb_policy_name_.reset(
gpr_strdup(parsed_object->parsed_deprecated_lb_policy())); gpr_strdup(parsed_object->parsed_deprecated_lb_policy()));
if (lb_policy_name_ != nullptr) {
char* lb_policy_name = lb_policy_name_.get();
for (size_t i = 0; i < strlen(lb_policy_name); ++i) {
lb_policy_name[i] = tolower(lb_policy_name[i]);
}
}
} }
} }
// Otherwise, find the LB policy name set by the client API. // Otherwise, find the LB policy name set by the client API.
@ -215,8 +196,7 @@ UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
if (retry_policy->max_attempts != 0) { if (retry_policy->max_attempts != 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxAttempts error:Duplicate entry")); "field:maxAttempts error:Duplicate entry"));
continue; } // Duplicate. Continue Parsing
} // Duplicate.
if (sub_field->type != GRPC_JSON_NUMBER) { if (sub_field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxAttempts error:should be of type number")); "field:maxAttempts error:should be of type number"));
@ -238,8 +218,7 @@ UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
if (retry_policy->initial_backoff > 0) { if (retry_policy->initial_backoff > 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:initialBackoff error:Duplicate entry")); "field:initialBackoff error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) { if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:initialBackoff error:Failed to parse")); "field:initialBackoff error:Failed to parse"));
@ -253,8 +232,7 @@ UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
if (retry_policy->max_backoff > 0) { if (retry_policy->max_backoff > 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxBackoff error:Duplicate entry")); "field:maxBackoff error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
if (!ParseDuration(sub_field, &retry_policy->max_backoff)) { if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxBackoff error:failed to parse")); "field:maxBackoff error:failed to parse"));
@ -268,8 +246,7 @@ UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
if (retry_policy->backoff_multiplier != 0) { if (retry_policy->backoff_multiplier != 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:backoffMultiplier error:Duplicate entry")); "field:backoffMultiplier error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
if (sub_field->type != GRPC_JSON_NUMBER) { if (sub_field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:backoffMultiplier error:should be of type number")); "field:backoffMultiplier error:should be of type number"));
@ -289,8 +266,7 @@ UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
if (!retry_policy->retryable_status_codes.Empty()) { if (!retry_policy->retryable_status_codes.Empty()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:Duplicate entry")); "field:retryableStatusCodes error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
if (sub_field->type != GRPC_JSON_ARRAY) { if (sub_field->type != GRPC_JSON_ARRAY) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryableStatusCodes error:should be of type array")); "field:retryableStatusCodes error:should be of type array"));
@ -329,10 +305,48 @@ UniquePtr<ClientChannelMethodParsedObject::RetryPolicy> ParseRetryPolicy(
return nullptr; return nullptr;
} }
} }
*error = ServiceConfig::CreateErrorFromVector("retryPolicy", &error_list); *error = GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr; return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr;
} }
const char* ParseHealthCheckConfig(const grpc_json* field, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
const char* service_name = nullptr;
GPR_DEBUG_ASSERT(strcmp(field->key, "healthCheckConfig") == 0);
if (field->type != GRPC_JSON_OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:should be of type object");
return nullptr;
}
InlinedVector<grpc_error*, 2> error_list;
for (grpc_json* sub_field = field->child; sub_field != nullptr;
sub_field = sub_field->next) {
if (sub_field->key == nullptr) {
GPR_DEBUG_ASSERT(false);
continue;
}
if (strcmp(sub_field->key, "serviceName") == 0) {
if (service_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:Duplicate "
"entry"));
} // Duplicate. Continue parsing
if (sub_field->type != GRPC_JSON_STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:serviceName error:should be of type string"));
continue;
}
service_name = sub_field->value;
}
}
if (!error_list.empty()) {
return nullptr;
}
*error =
GRPC_ERROR_CREATE_FROM_VECTOR("field:healthCheckConfig", &error_list);
return service_name;
}
} // namespace } // namespace
UniquePtr<ServiceConfig::ParsedConfig> UniquePtr<ServiceConfig::ParsedConfig>
@ -343,6 +357,7 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json,
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config; RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config;
UniquePtr<char> lb_policy_name; UniquePtr<char> lb_policy_name;
Optional<ClientChannelGlobalParsedObject::RetryThrottling> retry_throttling; Optional<ClientChannelGlobalParsedObject::RetryThrottling> retry_throttling;
const char* health_check_service_name = nullptr;
for (grpc_json* field = json->child; field != nullptr; field = field->next) { for (grpc_json* field = json->child; field != nullptr; field = field->next) {
if (field->key == nullptr) { if (field->key == nullptr) {
continue; // Not the LB config global parameter continue; // Not the LB config global parameter
@ -352,14 +367,12 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json,
if (parsed_lb_config != nullptr) { if (parsed_lb_config != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingConfig error:Duplicate entry")); "field:loadBalancingConfig error:Duplicate entry"));
} else { } // Duplicate, continue parsing.
grpc_error* parse_error = GRPC_ERROR_NONE; grpc_error* parse_error = GRPC_ERROR_NONE;
parsed_lb_config = parsed_lb_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(field, field, &parse_error);
&parse_error); if (parsed_lb_config == nullptr) {
if (parsed_lb_config == nullptr) { error_list.push_back(parse_error);
error_list.push_back(parse_error);
}
} }
} }
// Parse deprecated loadBalancingPolicy // Parse deprecated loadBalancingPolicy
@ -367,8 +380,8 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json,
if (lb_policy_name != nullptr) { if (lb_policy_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:Duplicate entry")); "field:loadBalancingPolicy error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
} else if (field->type != GRPC_JSON_STRING) { if (field->type != GRPC_JSON_STRING) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:type should be string")); "field:loadBalancingPolicy error:type should be string"));
continue; continue;
@ -380,126 +393,141 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const grpc_json* json,
lb_policy[i] = tolower(lb_policy[i]); lb_policy[i] = tolower(lb_policy[i]);
} }
} }
if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(lb_policy)) { bool requires_config = false;
if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
lb_policy, &requires_config)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:loadBalancingPolicy error:Unknown lb policy")); "field:loadBalancingPolicy error:Unknown lb policy"));
} else { } else if (requires_config) {
grpc_error* parsing_error = char* error_msg;
LoadBalancingPolicyRegistry::CanCreateLoadBalancingPolicy( gpr_asprintf(&error_msg,
lb_policy); "field:loadBalancingPolicy error:%s requires a config. "
if (parsing_error != GRPC_ERROR_NONE) { "Please use loadBalancingConfig instead.",
error_list.push_back(parsing_error); lb_policy);
} error_list.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING(error_msg));
gpr_free(error_msg);
} }
} }
// Parse retry throttling // Parse retry throttling
if (strcmp(field->key, "retryThrottling") == 0) { if (strcmp(field->key, "retryThrottling") == 0) {
if (retry_throttling.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling error:Duplicate entry"));
} // Duplicate, continue parsing.
if (field->type != GRPC_JSON_OBJECT) { if (field->type != GRPC_JSON_OBJECT) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling error:Type should be object")); "field:retryThrottling error:Type should be object"));
} else if (retry_throttling.has_value()) { continue;
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( }
"field:retryThrottling error:Duplicate entry")); Optional<int> max_milli_tokens;
} else { Optional<int> milli_token_ratio;
Optional<int> max_milli_tokens; for (grpc_json* sub_field = field->child; sub_field != nullptr;
Optional<int> milli_token_ratio; sub_field = sub_field->next) {
for (grpc_json* sub_field = field->child; sub_field != nullptr; if (sub_field->key == nullptr) continue;
sub_field = sub_field->next) { if (strcmp(sub_field->key, "maxTokens") == 0) {
if (sub_field->key == nullptr) continue; if (max_milli_tokens.has_value()) {
if (strcmp(sub_field->key, "maxTokens") == 0) { error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
if (max_milli_tokens.has_value()) { "field:retryThrottling field:maxTokens error:Duplicate "
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( "entry"));
"field:retryThrottling field:maxTokens error:Duplicate " } else if (sub_field->type != GRPC_JSON_NUMBER) {
"entry")); error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
} else if (sub_field->type != GRPC_JSON_NUMBER) { "field:retryThrottling field:maxTokens error:Type should be "
"number"));
} else {
max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) *
1000);
if (max_milli_tokens.value() <= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:maxTokens error:Type should be " "field:retryThrottling field:maxTokens error:should be "
"number")); "greater than zero"));
} else {
max_milli_tokens.set(gpr_parse_nonnegative_int(sub_field->value) *
1000);
if (max_milli_tokens.value() <= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:maxTokens error:should be "
"greater than zero"));
}
} }
} else if (strcmp(sub_field->key, "tokenRatio") == 0) { }
if (milli_token_ratio.has_value()) { } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( if (milli_token_ratio.has_value()) {
"field:retryThrottling field:tokenRatio error:Duplicate " error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"entry")); "field:retryThrottling field:tokenRatio error:Duplicate "
} else if (sub_field->type != GRPC_JSON_NUMBER) { "entry"));
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( } // Duplicate, continue parsing.
"field:retryThrottling field:tokenRatio error:type should be " if (sub_field->type != GRPC_JSON_NUMBER) {
"number")); error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
} else { "field:retryThrottling field:tokenRatio error:type should be "
// We support up to 3 decimal digits. "number"));
size_t whole_len = strlen(sub_field->value); } else {
uint32_t multiplier = 1; // We support up to 3 decimal digits.
uint32_t decimal_value = 0; size_t whole_len = strlen(sub_field->value);
const char* decimal_point = strchr(sub_field->value, '.'); uint32_t multiplier = 1;
if (decimal_point != nullptr) { uint32_t decimal_value = 0;
whole_len = const char* decimal_point = strchr(sub_field->value, '.');
static_cast<size_t>(decimal_point - sub_field->value); if (decimal_point != nullptr) {
multiplier = 1000; whole_len = static_cast<size_t>(decimal_point - sub_field->value);
size_t decimal_len = strlen(decimal_point + 1); multiplier = 1000;
if (decimal_len > 3) decimal_len = 3; size_t decimal_len = strlen(decimal_point + 1);
if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len, if (decimal_len > 3) decimal_len = 3;
&decimal_value)) { if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( &decimal_value)) {
"field:retryThrottling field:tokenRatio error:Failed "
"parsing"));
continue;
}
uint32_t decimal_multiplier = 1;
for (size_t i = 0; i < (3 - decimal_len); ++i) {
decimal_multiplier *= 10;
}
decimal_value *= decimal_multiplier;
}
uint32_t whole_value;
if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
&whole_value)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:Failed " "field:retryThrottling field:tokenRatio error:Failed "
"parsing")); "parsing"));
continue; continue;
} }
milli_token_ratio.set( uint32_t decimal_multiplier = 1;
static_cast<int>((whole_value * multiplier) + decimal_value)); for (size_t i = 0; i < (3 - decimal_len); ++i) {
if (milli_token_ratio.value() <= 0) { decimal_multiplier *= 10;
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:value should "
"be greater than 0"));
} }
decimal_value *= decimal_multiplier;
}
uint32_t whole_value;
if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
&whole_value)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:Failed "
"parsing"));
continue;
}
milli_token_ratio.set(
static_cast<int>((whole_value * multiplier) + decimal_value));
if (milli_token_ratio.value() <= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryThrottling field:tokenRatio error:value should "
"be greater than 0"));
} }
} }
} }
if (!max_milli_tokens.has_value()) { }
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( if (!max_milli_tokens.has_value()) {
"field:retryThrottling field:maxTokens error:Not found")); error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
} "field:retryThrottling field:maxTokens error:Not found"));
if (!milli_token_ratio.has_value()) { }
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( if (!milli_token_ratio.has_value()) {
"field:retryThrottling field:tokenRatio error:Not found")); error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
} "field:retryThrottling field:tokenRatio error:Not found"));
if (error_list.size() == 0) { }
ClientChannelGlobalParsedObject::RetryThrottling data; if (error_list.size() == 0) {
data.max_milli_tokens = max_milli_tokens.value(); ClientChannelGlobalParsedObject::RetryThrottling data;
data.milli_token_ratio = milli_token_ratio.value(); data.max_milli_tokens = max_milli_tokens.value();
retry_throttling.set(data); data.milli_token_ratio = milli_token_ratio.value();
} retry_throttling.set(data);
}
}
if (strcmp(field->key, "healthCheckConfig") == 0) {
if (health_check_service_name != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:Duplicate entry"));
} // Duplicate continue parsing
grpc_error* parsing_error = GRPC_ERROR_NONE;
health_check_service_name = ParseHealthCheckConfig(field, &parsing_error);
if (parsing_error != GRPC_ERROR_NONE) {
error_list.push_back(parsing_error);
} }
} }
} }
*error = ServiceConfig::CreateErrorFromVector("Client channel global parser", *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser",
&error_list); &error_list);
if (*error == GRPC_ERROR_NONE) { if (*error == GRPC_ERROR_NONE) {
return UniquePtr<ServiceConfig::ParsedConfig>( return UniquePtr<ServiceConfig::ParsedConfig>(
New<ClientChannelGlobalParsedObject>(std::move(parsed_lb_config), New<ClientChannelGlobalParsedObject>(
std::move(lb_policy_name), std::move(parsed_lb_config), std::move(lb_policy_name),
retry_throttling)); retry_throttling, health_check_service_name));
} }
return nullptr; return nullptr;
} }
@ -518,8 +546,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json,
if (wait_for_ready.has_value()) { if (wait_for_ready.has_value()) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:waitForReady error:Duplicate entry")); "field:waitForReady error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
if (field->type == GRPC_JSON_TRUE) { if (field->type == GRPC_JSON_TRUE) {
wait_for_ready.set(true); wait_for_ready.set(true);
} else if (field->type == GRPC_JSON_FALSE) { } else if (field->type == GRPC_JSON_FALSE) {
@ -532,8 +559,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json,
if (timeout > 0) { if (timeout > 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:timeout error:Duplicate entry")); "field:timeout error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
if (!ParseDuration(field, &timeout)) { if (!ParseDuration(field, &timeout)) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:timeout error:Failed parsing")); "field:timeout error:Failed parsing"));
@ -542,8 +568,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json,
if (retry_policy != nullptr) { if (retry_policy != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:retryPolicy error:Duplicate entry")); "field:retryPolicy error:Duplicate entry"));
continue; } // Duplicate, continue parsing.
}
grpc_error* error = GRPC_ERROR_NONE; grpc_error* error = GRPC_ERROR_NONE;
retry_policy = ParseRetryPolicy(field, &error); retry_policy = ParseRetryPolicy(field, &error);
if (retry_policy == nullptr) { if (retry_policy == nullptr) {
@ -551,8 +576,7 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(const grpc_json* json,
} }
} }
} }
*error = ServiceConfig::CreateErrorFromVector("Client channel parser", *error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list);
&error_list);
if (*error == GRPC_ERROR_NONE) { if (*error == GRPC_ERROR_NONE) {
return UniquePtr<ServiceConfig::ParsedConfig>( return UniquePtr<ServiceConfig::ParsedConfig>(
New<ClientChannelMethodParsedObject>(timeout, wait_for_ready, New<ClientChannelMethodParsedObject>(timeout, wait_for_ready,

@ -47,10 +47,12 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig {
ClientChannelGlobalParsedObject( ClientChannelGlobalParsedObject(
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config, RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config,
UniquePtr<char> parsed_deprecated_lb_policy, UniquePtr<char> parsed_deprecated_lb_policy,
const Optional<RetryThrottling>& retry_throttling) const Optional<RetryThrottling>& retry_throttling,
const char* health_check_service_name)
: parsed_lb_config_(std::move(parsed_lb_config)), : parsed_lb_config_(std::move(parsed_lb_config)),
parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)), parsed_deprecated_lb_policy_(std::move(parsed_deprecated_lb_policy)),
retry_throttling_(retry_throttling) {} retry_throttling_(retry_throttling),
health_check_service_name_(health_check_service_name) {}
Optional<RetryThrottling> retry_throttling() const { Optional<RetryThrottling> retry_throttling() const {
return retry_throttling_; return retry_throttling_;
@ -64,10 +66,15 @@ class ClientChannelGlobalParsedObject : public ServiceConfig::ParsedConfig {
return parsed_deprecated_lb_policy_.get(); return parsed_deprecated_lb_policy_.get();
} }
const char* health_check_service_name() const {
return health_check_service_name_;
}
private: private:
RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config_; RefCountedPtr<ParsedLoadBalancingConfig> parsed_lb_config_;
UniquePtr<char> parsed_deprecated_lb_policy_; UniquePtr<char> parsed_deprecated_lb_policy_;
Optional<RetryThrottling> retry_throttling_; Optional<RetryThrottling> retry_throttling_;
const char* health_check_service_name_ = nullptr;
}; };
class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig { class ClientChannelMethodParsedObject : public ServiceConfig::ParsedConfig {
@ -111,8 +118,9 @@ class ClientChannelServiceConfigParser : public ServiceConfig::Parser {
static void Register(); static void Register();
}; };
// A container of processed fields from the resolver result. Simplifies the // TODO(yashykt): It would be cleaner to move this logic to the client_channel
// usage of resolver result. // code. A container of processed fields from the resolver result. Simplifies
// the usage of resolver result.
class ProcessedResolverResult { class ProcessedResolverResult {
public: public:
// Processes the resolver result and populates the relative members // Processes the resolver result and populates the relative members
@ -122,21 +130,19 @@ class ProcessedResolverResult {
// Getters. Any managed object's ownership is transferred. // Getters. Any managed object's ownership is transferred.
const char* service_config_json() { return service_config_json_; } const char* service_config_json() { return service_config_json_; }
const char* server_name() { return server_name_; } RefCountedPtr<ServiceConfig> service_config() { return service_config_; }
Optional<ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data() {
return retry_throttle_data_;
}
UniquePtr<char> lb_policy_name() { return std::move(lb_policy_name_); } UniquePtr<char> lb_policy_name() { return std::move(lb_policy_name_); }
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config() { RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config() {
return lb_policy_config_; return lb_policy_config_;
} }
const char* health_check_service_name() { return health_check_service_name_; } Optional<ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data() {
return retry_throttle_data_;
}
RefCountedPtr<ServiceConfig> service_config() { return service_config_; } const char* health_check_service_name() { return health_check_service_name_; }
private: private:
// Finds the service config; extracts LB config and (maybe) retry throttle // Finds the service config; extracts LB config and (maybe) retry throttle
@ -163,9 +169,8 @@ class ProcessedResolverResult {
RefCountedPtr<ServiceConfig> service_config_; RefCountedPtr<ServiceConfig> service_config_;
// LB policy. // LB policy.
UniquePtr<char> lb_policy_name_; UniquePtr<char> lb_policy_name_;
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config_ = nullptr; RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config_;
// Retry throttle data. // Retry throttle data.
const char* server_name_ = nullptr;
Optional<ClientChannelGlobalParsedObject::RetryThrottling> Optional<ClientChannelGlobalParsedObject::RetryThrottling>
retry_throttle_data_; retry_throttle_data_;
const char* health_check_service_name_ = nullptr; const char* health_check_service_name_ = nullptr;

@ -530,7 +530,7 @@ void ResolvingLoadBalancingPolicy::OnResolverResultChangedLocked(
const bool resolution_contains_addresses = result.addresses.size() > 0; const bool resolution_contains_addresses = result.addresses.size() > 0;
// Process the resolver result. // Process the resolver result.
const char* lb_policy_name = nullptr; const char* lb_policy_name = nullptr;
RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config = nullptr; RefCountedPtr<ParsedLoadBalancingConfig> lb_policy_config;
bool service_config_changed = false; bool service_config_changed = false;
if (process_resolver_result_ != nullptr) { if (process_resolver_result_ != nullptr) {
service_config_changed = service_config_changed =

@ -123,7 +123,7 @@ class ResolvingLoadBalancingPolicy : public LoadBalancingPolicy {
ProcessResolverResultCallback process_resolver_result_ = nullptr; ProcessResolverResultCallback process_resolver_result_ = nullptr;
void* process_resolver_result_user_data_ = nullptr; void* process_resolver_result_user_data_ = nullptr;
UniquePtr<char> child_policy_name_; UniquePtr<char> child_policy_name_;
RefCountedPtr<ParsedLoadBalancingConfig> child_lb_config_ = nullptr; RefCountedPtr<ParsedLoadBalancingConfig> child_lb_config_;
// Resolver and associated state. // Resolver and associated state.
OrphanablePtr<Resolver> resolver_; OrphanablePtr<Resolver> resolver_;

@ -98,7 +98,7 @@ grpc_error* ServiceConfig::ParseGlobalParams(const grpc_json* json_tree) {
} }
parsed_global_service_config_objects_.push_back(std::move(parsed_obj)); parsed_global_service_config_objects_.push_back(std::move(parsed_obj));
} }
return CreateErrorFromVector("Global Params", &error_list); return GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list);
} }
grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable( grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable(
@ -154,7 +154,7 @@ grpc_error* ServiceConfig::ParseJsonMethodConfigToServiceConfigObjectsTable(
++*idx; ++*idx;
} }
wrap_error: wrap_error:
return CreateErrorFromVector("methodConfig", &error_list); return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
} }
grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) { grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) {
@ -211,7 +211,7 @@ grpc_error* ServiceConfig::ParsePerMethodParams(const grpc_json* json_tree) {
num_entries, entries, nullptr); num_entries, entries, nullptr);
gpr_free(entries); gpr_free(entries);
} }
return CreateErrorFromVector("Method Params", &error_list); return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list);
} }
ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); } ServiceConfig::~ServiceConfig() { grpc_json_destroy(json_tree_); }
@ -313,7 +313,7 @@ ServiceConfig::GetMethodServiceConfigObjectsVector(const grpc_slice& path) {
return *value; return *value;
} }
size_t ServiceConfig::RegisterParser(UniquePtr<ServiceConfig::Parser> parser) { size_t ServiceConfig::RegisterParser(UniquePtr<Parser> parser) {
g_registered_parsers->push_back(std::move(parser)); g_registered_parsers->push_back(std::move(parser));
return g_registered_parsers->size() - 1; return g_registered_parsers->size() - 1;
} }

@ -71,14 +71,14 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
public: public:
virtual ~Parser() = default; virtual ~Parser() = default;
virtual UniquePtr<ServiceConfig::ParsedConfig> ParseGlobalParams( virtual UniquePtr<ParsedConfig> ParseGlobalParams(const grpc_json* json,
const grpc_json* json, grpc_error** error) { grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr); GPR_DEBUG_ASSERT(error != nullptr);
return nullptr; return nullptr;
} }
virtual UniquePtr<ServiceConfig::ParsedConfig> ParsePerMethodParams( virtual UniquePtr<ParsedConfig> ParsePerMethodParams(const grpc_json* json,
const grpc_json* json, grpc_error** error) { grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr); GPR_DEBUG_ASSERT(error != nullptr);
return nullptr; return nullptr;
} }
@ -87,10 +87,14 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
}; };
static constexpr int kNumPreallocatedParsers = 4; static constexpr int kNumPreallocatedParsers = 4;
typedef InlinedVector<UniquePtr<ServiceConfig::ParsedConfig>, typedef InlinedVector<UniquePtr<ParsedConfig>, kNumPreallocatedParsers>
kNumPreallocatedParsers>
ServiceConfigObjectsVector; ServiceConfigObjectsVector;
/// When a service config is applied to a call in the client_channel_filter,
/// we create an instance of this object and store it in the call_data for
/// client_channel. A pointer to this object is also stored in the
/// call_context, so that future filters can easily access method and global
/// parameters for the call.
class CallData { class CallData {
public: public:
CallData() = default; CallData() = default;
@ -102,20 +106,21 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
} }
} }
RefCountedPtr<ServiceConfig> service_config() { return service_config_; } ServiceConfig* service_config() { return service_config_.get(); }
ServiceConfig::ParsedConfig* GetMethodParsedObject(int index) const { ParsedConfig* GetMethodParsedObject(size_t index) const {
return method_params_vector_ != nullptr return method_params_vector_ != nullptr
? (*method_params_vector_)[index].get() ? (*method_params_vector_)[index].get()
: nullptr; : nullptr;
} }
bool empty() const { return service_config_ == nullptr; } ParsedConfig* GetGlobalParsedObject(size_t index) const {
return service_config_->GetParsedGlobalServiceConfigObject(index);
}
private: private:
RefCountedPtr<ServiceConfig> service_config_; RefCountedPtr<ServiceConfig> service_config_;
const ServiceConfig::ServiceConfigObjectsVector* method_params_vector_ = const ServiceConfigObjectsVector* method_params_vector_ = nullptr;
nullptr;
}; };
/// Creates a new service config from parsing \a json_string. /// Creates a new service config from parsing \a json_string.
@ -130,8 +135,7 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
/// Retrieves the parsed global service config object at index \a index. The /// Retrieves the parsed global service config object at index \a index. The
/// lifetime of the returned object is tied to the lifetime of the /// lifetime of the returned object is tied to the lifetime of the
/// ServiceConfig object. /// ServiceConfig object.
ServiceConfig::ParsedConfig* GetParsedGlobalServiceConfigObject( ParsedConfig* GetParsedGlobalServiceConfigObject(size_t index) {
size_t index) {
GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size()); GPR_DEBUG_ASSERT(index < parsed_global_service_config_objects_.size());
return parsed_global_service_config_objects_[index].get(); return parsed_global_service_config_objects_[index].get();
} }
@ -148,30 +152,12 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
/// registered parser. Each parser is responsible for reading the service /// registered parser. Each parser is responsible for reading the service
/// config json and returning a parsed object. This parsed object can later be /// config json and returning a parsed object. This parsed object can later be
/// retrieved using the same index that was returned at registration time. /// retrieved using the same index that was returned at registration time.
static size_t RegisterParser(UniquePtr<ServiceConfig::Parser> parser); static size_t RegisterParser(UniquePtr<Parser> parser);
static void Init(); static void Init();
static void Shutdown(); static void Shutdown();
// Consumes all the errors in the vector and forms a referencing error from
// them. If the vector is empty, return GRPC_ERROR_NONE.
template <size_t N>
static grpc_error* CreateErrorFromVector(
const char* desc, InlinedVector<grpc_error*, N>* error_list) {
grpc_error* error = GRPC_ERROR_NONE;
if (error_list->size() != 0) {
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
desc, error_list->data(), error_list->size());
// Remove refs to all errors in error_list.
for (size_t i = 0; i < error_list->size(); i++) {
GRPC_ERROR_UNREF((*error_list)[i]);
}
error_list->clear();
}
return error;
}
private: private:
// So New() can call our private ctor. // So New() can call our private ctor.
template <typename T, typename... Args> template <typename T, typename... Args>
@ -203,7 +189,7 @@ class ServiceConfig : public RefCounted<ServiceConfig> {
UniquePtr<char> json_string_; // Underlying storage for json_tree. UniquePtr<char> json_string_; // Underlying storage for json_tree.
grpc_json* json_tree_; grpc_json* json_tree_;
InlinedVector<UniquePtr<ServiceConfig::ParsedConfig>, kNumPreallocatedParsers> InlinedVector<UniquePtr<ParsedConfig>, kNumPreallocatedParsers>
parsed_global_service_config_objects_; parsed_global_service_config_objects_;
// A map from the method name to the service config objects vector. Note that // A map from the method name to the service config objects vector. Note that
// we are using a raw pointer and not a unique pointer so that we can use the // we are using a raw pointer and not a unique pointer so that we can use the

@ -38,12 +38,12 @@
static void recv_message_ready(void* user_data, grpc_error* error); static void recv_message_ready(void* user_data, grpc_error* error);
static void recv_trailing_metadata_ready(void* user_data, grpc_error* error); static void recv_trailing_metadata_ready(void* user_data, grpc_error* error);
namespace grpc_core {
namespace { namespace {
size_t g_message_size_parser_index; size_t g_message_size_parser_index;
} // namespace } // namespace
namespace grpc_core {
UniquePtr<ServiceConfig::ParsedConfig> MessageSizeParser::ParsePerMethodParams( UniquePtr<ServiceConfig::ParsedConfig> MessageSizeParser::ParsePerMethodParams(
const grpc_json* json, grpc_error** error) { const grpc_json* json, grpc_error** error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE); GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
@ -56,8 +56,8 @@ UniquePtr<ServiceConfig::ParsedConfig> MessageSizeParser::ParsePerMethodParams(
if (max_request_message_bytes >= 0) { if (max_request_message_bytes >= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxRequestMessageBytes error:Duplicate entry")); "field:maxRequestMessageBytes error:Duplicate entry"));
} else if (field->type != GRPC_JSON_STRING && } // Duplicate, continue parsing.
field->type != GRPC_JSON_NUMBER) { if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxRequestMessageBytes error:should be of type number")); "field:maxRequestMessageBytes error:should be of type number"));
} else { } else {
@ -71,8 +71,8 @@ UniquePtr<ServiceConfig::ParsedConfig> MessageSizeParser::ParsePerMethodParams(
if (max_response_message_bytes >= 0) { if (max_response_message_bytes >= 0) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxResponseMessageBytes error:Duplicate entry")); "field:maxResponseMessageBytes error:Duplicate entry"));
} else if (field->type != GRPC_JSON_STRING && } // Duplicate, conitnue parsing
field->type != GRPC_JSON_NUMBER) { if (field->type != GRPC_JSON_STRING && field->type != GRPC_JSON_NUMBER) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING( error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:maxResponseMessageBytes error:should be of type number")); "field:maxResponseMessageBytes error:should be of type number"));
} else { } else {
@ -85,8 +85,7 @@ UniquePtr<ServiceConfig::ParsedConfig> MessageSizeParser::ParsePerMethodParams(
} }
} }
if (!error_list.empty()) { if (!error_list.empty()) {
*error = ServiceConfig::CreateErrorFromVector("Message size parser", *error = GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list);
&error_list);
return nullptr; return nullptr;
} }
return UniquePtr<ServiceConfig::ParsedConfig>(New<MessageSizeParsedObject>( return UniquePtr<ServiceConfig::ParsedConfig>(New<MessageSizeParsedObject>(
@ -332,7 +331,12 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
channel_data* chand = static_cast<channel_data*>(elem->channel_data); channel_data* chand = static_cast<channel_data*>(elem->channel_data);
new (chand) channel_data(); new (chand) channel_data();
chand->limits = get_message_size_limits(args->channel_args); chand->limits = get_message_size_limits(args->channel_args);
// Get method config table from channel args. // TODO(yashykt): We only need to read GRPC_ARG_SERVICE_CONFIG in the case of
// direct channels. (Service config is otherwise stored in the call_context by
// client_channel filter.) If we ever need a second filter that also needs to
// parse GRPC_ARG_SERVICE_CONFIG, we should refactor this code and add a
// separate filter that reads GRPC_ARG_SERVICE_CONFIG and saves the parsed
// config in the call_context. Get service config from channel args.
const grpc_arg* channel_arg = const grpc_arg* channel_arg =
grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG);
const char* service_config_str = grpc_channel_arg_get_string(channel_arg); const char* service_config_str = grpc_channel_arg_get_string(channel_arg);

@ -26,7 +26,7 @@ namespace grpc_core {
template <typename T> template <typename T>
class Optional { class Optional {
public: public:
Optional() { value_ = {}; } Optional() { value_ = T(); }
void set(const T& val) { void set(const T& val) {
value_ = val; value_ = val;
set_ = true; set_ = true;

@ -30,6 +30,7 @@
#include <grpc/support/time.h> #include <grpc/support/time.h>
#include "src/core/lib/debug/trace.h" #include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/inlined_vector.h"
/// Opaque representation of an error. /// Opaque representation of an error.
/// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a /// See https://github.com/grpc/grpc/blob/master/doc/core/grpc-error.md for a
@ -193,6 +194,24 @@ inline void grpc_error_unref(grpc_error* err) {
#define GRPC_ERROR_UNREF(err) grpc_error_unref(err) #define GRPC_ERROR_UNREF(err) grpc_error_unref(err)
#endif #endif
// Consumes all the errors in the vector and forms a referencing error from
// them. If the vector is empty, return GRPC_ERROR_NONE.
template <size_t N>
static grpc_error* GRPC_ERROR_CREATE_FROM_VECTOR(
const char* desc, grpc_core::InlinedVector<grpc_error*, N>* error_list) {
grpc_error* error = GRPC_ERROR_NONE;
if (error_list->size() != 0) {
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
desc, error_list->data(), error_list->size());
// Remove refs to all errors in error_list.
for (size_t i = 0; i < error_list->size(); i++) {
GRPC_ERROR_UNREF((*error_list)[i]);
}
error_list->clear();
}
return error;
}
grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which,
intptr_t value) GRPC_MUST_USE_RESULT; intptr_t value) GRPC_MUST_USE_RESULT;
/// It is an error to pass nullptr as `p`. Caller should allocate a dummy /// It is an error to pass nullptr as `p`. Caller should allocate a dummy

@ -322,7 +322,6 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/connector.cc', 'src/core/ext/filters/client_channel/connector.cc',
'src/core/ext/filters/client_channel/global_subchannel_pool.cc', 'src/core/ext/filters/client_channel/global_subchannel_pool.cc',
'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/health/health_check_client.cc',
'src/core/ext/filters/client_channel/health/health_check_parser.cc',
'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc',
'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/http_proxy.cc',
'src/core/ext/filters/client_channel/lb_policy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc',

@ -21,7 +21,6 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include "src/core/ext/filters/client_channel/health/health_check_parser.h"
#include "src/core/ext/filters/client_channel/resolver_result_parsing.h" #include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
#include "src/core/ext/filters/client_channel/service_config.h" #include "src/core/ext/filters/client_channel/service_config.h"
#include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/ext/filters/message_size/message_size_filter.h"
@ -528,13 +527,13 @@ TEST_F(ClientChannelParserTest, LoadBalancingPolicyXdsNotAllowed) {
auto svc_cfg = ServiceConfig::Create(test_json, &error); auto svc_cfg = ServiceConfig::Create(test_json, &error);
gpr_log(GPR_ERROR, "%s", grpc_error_string(error)); gpr_log(GPR_ERROR, "%s", grpc_error_string(error));
ASSERT_TRUE(error != GRPC_ERROR_NONE); ASSERT_TRUE(error != GRPC_ERROR_NONE);
std::regex e(std::string( std::regex e(
"(Service config parsing " std::string("(Service config parsing "
"error)(.*)(referenced_errors)(.*)(Global " "error)(.*)(referenced_errors)(.*)(Global "
"Params)(.*)(referenced_errors)(.*)(Client channel global " "Params)(.*)(referenced_errors)(.*)(Client channel global "
"parser)(.*)(referenced_errors)(.*)(field:loadBalancingPolicy error:Xds " "parser)(.*)(referenced_errors)(.*)(field:"
"Parser has required field - balancerName. Please use " "loadBalancingPolicy error:xds_experimental requires a "
"loadBalancingConfig field of service config instead.)")); "config. Please use loadBalancingConfig instead.)"));
VerifyRegexMatch(error, e); VerifyRegexMatch(error, e);
} }
@ -856,7 +855,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyBackoffMultiplier) {
" \"retryPolicy\": {\n" " \"retryPolicy\": {\n"
" \"maxAttempts\": 1,\n" " \"maxAttempts\": 1,\n"
" \"initialBackoff\": \"1s\",\n" " \"initialBackoff\": \"1s\",\n"
" \"maxBackoff\": \"120sec\",\n" " \"maxBackoff\": \"120s\",\n"
" \"backoffMultiplier\": \"1.6\",\n" " \"backoffMultiplier\": \"1.6\",\n"
" \"retryableStatusCodes\": [ \"ABORTED\" ]\n" " \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
" }\n" " }\n"
@ -886,7 +885,7 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) {
" \"retryPolicy\": {\n" " \"retryPolicy\": {\n"
" \"maxAttempts\": 1,\n" " \"maxAttempts\": 1,\n"
" \"initialBackoff\": \"1s\",\n" " \"initialBackoff\": \"1s\",\n"
" \"maxBackoff\": \"120sec\",\n" " \"maxBackoff\": \"120s\",\n"
" \"backoffMultiplier\": \"1.6\",\n" " \"backoffMultiplier\": \"1.6\",\n"
" \"retryableStatusCodes\": []\n" " \"retryableStatusCodes\": []\n"
" }\n" " }\n"
@ -906,6 +905,50 @@ TEST_F(ClientChannelParserTest, InvalidRetryPolicyRetryableStatusCodes) {
VerifyRegexMatch(error, e); VerifyRegexMatch(error, e);
} }
TEST_F(ClientChannelParserTest, ValidHealthCheck) {
const char* test_json =
"{\n"
" \"healthCheckConfig\": {\n"
" \"serviceName\": \"health_check_service_name\"\n"
" }\n"
"}";
grpc_error* error = GRPC_ERROR_NONE;
auto svc_cfg = ServiceConfig::Create(test_json, &error);
ASSERT_TRUE(error == GRPC_ERROR_NONE);
const auto* parsed_object =
static_cast<grpc_core::internal::ClientChannelGlobalParsedObject*>(
svc_cfg->GetParsedGlobalServiceConfigObject(0));
ASSERT_TRUE(parsed_object != nullptr);
EXPECT_EQ(strcmp(parsed_object->health_check_service_name(),
"health_check_service_name"),
0);
}
TEST_F(ClientChannelParserTest, InvalidHealthCheckMultipleEntries) {
const char* test_json =
"{\n"
" \"healthCheckConfig\": {\n"
" \"serviceName\": \"health_check_service_name\"\n"
" },\n"
" \"healthCheckConfig\": {\n"
" \"serviceName\": \"health_check_service_name1\"\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)(.*)(field:healthCheckConfig "
"error:Duplicate entry)"));
std::smatch match;
std::string s(grpc_error_string(error));
EXPECT_TRUE(std::regex_search(s, match, e));
GRPC_ERROR_UNREF(error);
}
class MessageSizeParserTest : public ::testing::Test { class MessageSizeParserTest : public ::testing::Test {
protected: protected:
void SetUp() override { void SetUp() override {
@ -989,59 +1032,6 @@ TEST_F(MessageSizeParserTest, InvalidMaxResponseMessageBytes) {
VerifyRegexMatch(error, e); VerifyRegexMatch(error, e);
} }
class HealthCheckParserTest : public ::testing::Test {
protected:
void SetUp() override {
ServiceConfig::Shutdown();
ServiceConfig::Init();
EXPECT_TRUE(ServiceConfig::RegisterParser(UniquePtr<ServiceConfig::Parser>(
New<HealthCheckParser>())) == 0);
}
};
TEST_F(HealthCheckParserTest, Valid) {
const char* test_json =
"{\n"
" \"healthCheckConfig\": {\n"
" \"serviceName\": \"health_check_service_name\"\n"
" }\n"
"}";
grpc_error* error = GRPC_ERROR_NONE;
auto svc_cfg = ServiceConfig::Create(test_json, &error);
ASSERT_TRUE(error == GRPC_ERROR_NONE);
const auto* parsed_object = static_cast<grpc_core::HealthCheckParsedObject*>(
svc_cfg->GetParsedGlobalServiceConfigObject(0));
ASSERT_TRUE(parsed_object != nullptr);
EXPECT_EQ(strcmp(parsed_object->service_name(), "health_check_service_name"),
0);
}
TEST_F(HealthCheckParserTest, MultipleEntries) {
const char* test_json =
"{\n"
" \"healthCheckConfig\": {\n"
" \"serviceName\": \"health_check_service_name\"\n"
" },\n"
" \"healthCheckConfig\": {\n"
" \"serviceName\": \"health_check_service_name1\"\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)(.*)(field:healthCheckConfig)("
".*)(referenced_errors)(.*)"
"(field:serviceName error:Duplicate entry)"));
std::smatch match;
std::string s(grpc_error_string(error));
EXPECT_TRUE(std::regex_search(s, match, e));
GRPC_ERROR_UNREF(error);
}
} // namespace testing } // namespace testing
} // namespace grpc_core } // namespace grpc_core

@ -892,8 +892,6 @@ src/core/ext/filters/client_channel/health/health.pb.c \
src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/filters/client_channel/health/health.pb.h \
src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/health/health_check_client.cc \
src/core/ext/filters/client_channel/health/health_check_client.h \ src/core/ext/filters/client_channel/health/health_check_client.h \
src/core/ext/filters/client_channel/health/health_check_parser.cc \
src/core/ext/filters/client_channel/health/health_check_parser.h \
src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \
src/core/ext/filters/client_channel/http_connect_handshaker.h \ src/core/ext/filters/client_channel/http_connect_handshaker.h \
src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/http_proxy.cc \

@ -8732,7 +8732,6 @@
"src/core/ext/filters/client_channel/connector.h", "src/core/ext/filters/client_channel/connector.h",
"src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/health/health_check_parser.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/http_proxy.h",
"src/core/ext/filters/client_channel/lb_policy.h", "src/core/ext/filters/client_channel/lb_policy.h",
@ -8773,8 +8772,6 @@
"src/core/ext/filters/client_channel/global_subchannel_pool.h", "src/core/ext/filters/client_channel/global_subchannel_pool.h",
"src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/health/health_check_client.cc",
"src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/health/health_check_client.h",
"src/core/ext/filters/client_channel/health/health_check_parser.cc",
"src/core/ext/filters/client_channel/health/health_check_parser.h",
"src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc",
"src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h",
"src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/http_proxy.cc",

Loading…
Cancel
Save