Merge github.com:grpc/grpc into http-reland-devel

pull/29182/head
Craig Tiller 3 years ago
commit a2d5f86978
  1. 1
      .bazelignore
  2. 2
      .github/ISSUE_TEMPLATE/bug_report_core.md
  3. 2
      .github/ISSUE_TEMPLATE/bug_report_cpp.md
  4. 14
      BUILD
  5. 17
      CMakeLists.txt
  6. 7
      Makefile
  7. 3
      bazel/supported_versions.txt
  8. 2
      bazel/test/python_test_repo/WORKSPACE
  9. 12
      build_autogenerated.yaml
  10. 5
      config.m4
  11. 9
      config.w32
  12. 44
      doc/bazel_support.md
  13. 7
      doc/environment_variables.md
  14. 8
      gRPC-C++.podspec
  15. 12
      gRPC-Core.podspec
  16. 8
      grpc.gemspec
  17. 4
      grpc.gyp
  18. 8
      package.xml
  19. 255
      src/core/ext/filters/client_channel/client_channel.cc
  20. 2
      src/core/ext/filters/client_channel/client_channel.h
  21. 314
      src/core/ext/filters/client_channel/lb_policy/priority/priority.cc
  22. 11
      src/core/ext/filters/client_channel/lb_policy/rls/rls.cc
  23. 113
      src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc
  24. 315
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
  25. 73
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
  26. 3
      src/core/ext/filters/client_channel/retry_filter.cc
  27. 2
      src/core/ext/transport/binder/client/endpoint_binder_pool.cc
  28. 55
      src/core/ext/transport/binder/utils/ndk_binder.cc
  29. 172
      src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c
  30. 623
      src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h
  31. 99
      src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c
  32. 75
      src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h
  33. 3
      src/core/ext/xds/xds_client.cc
  34. 144
      src/core/ext/xds/xds_cluster_specifier_plugin.cc
  35. 81
      src/core/ext/xds/xds_cluster_specifier_plugin.h
  36. 16
      src/core/ext/xds/xds_common_types.cc
  37. 4
      src/core/ext/xds/xds_common_types.h
  38. 2
      src/core/ext/xds/xds_listener.cc
  39. 166
      src/core/ext/xds/xds_route_config.cc
  40. 23
      src/core/ext/xds/xds_route_config.h
  41. 5
      src/core/lib/channel/call_tracer.h
  42. 26
      src/core/lib/channel/promise_based_filter.cc
  43. 4
      src/core/lib/iomgr/tcp_client_posix.cc
  44. 6
      src/core/lib/json/json_util.h
  45. 8
      src/core/tsi/ssl_transport_security.cc
  46. 28
      src/cpp/ext/filters/census/client_filter.cc
  47. 26
      src/cpp/ext/filters/census/open_census_call_tracer.h
  48. 14
      src/proto/grpc/lookup/v1/BUILD
  49. 1
      src/proto/grpc/testing/xds/v3/BUILD
  50. 19
      src/proto/grpc/testing/xds/v3/route.proto
  51. 4
      src/python/grpcio/grpc_core_dependencies.py
  52. 2
      src/upb/gen_build_yaml.py
  53. 46
      templates/doc/bazel_support.md.template
  54. 10
      templates/tools/dockerfile/compile_python_310.include
  55. 10
      templates/tools/dockerfile/compile_python_36.include
  56. 10
      templates/tools/dockerfile/compile_python_37.include
  57. 10
      templates/tools/dockerfile/compile_python_38.include
  58. 44
      test/core/client_channel/rls_lb_config_parser_test.cc
  59. 2
      test/core/ext/filters/rbac/rbac_service_config_parser_test.cc
  60. 11
      test/core/memory_usage/client.cc
  61. 10
      test/core/memory_usage/memory_usage_test.cc
  62. 13
      test/core/memory_usage/server.cc
  63. 36
      test/core/tsi/crl_ssl_transport_security_test.cc
  64. 1
      test/core/util/test_lb_policies.cc
  65. 1
      test/core/util/test_lb_policies.h
  66. 4
      test/core/xds/google_mesh_ca_certificate_provider_factory_test.cc
  67. 16
      test/cpp/end2end/BUILD
  68. 105
      test/cpp/end2end/client_lb_end2end_test.cc
  69. 117
      test/cpp/end2end/rls_end2end_test.cc
  70. 103
      test/cpp/end2end/rls_server.cc
  71. 94
      test/cpp/end2end/rls_server.h
  72. 3
      test/cpp/end2end/xds/BUILD
  73. 444
      test/cpp/end2end/xds/xds_end2end_test.cc
  74. 1
      test/cpp/ext/filters/census/BUILD
  75. 43
      test/cpp/ext/filters/census/stats_plugin_end2end_test.cc
  76. 43
      test/distrib/bazel/cpp/BUILD
  77. 27
      test/distrib/bazel/cpp/WORKSPACE
  78. 104
      test/distrib/bazel/cpp/greeter_client.cc
  79. 73
      test/distrib/bazel/cpp/greeter_server.cc
  80. 61
      test/distrib/bazel/cpp/greeter_test.sh
  81. 37
      test/distrib/bazel/cpp/protos/BUILD
  82. 38
      test/distrib/bazel/cpp/protos/helloworld.proto
  83. 1
      test/distrib/bazel/cpp/tools/bazel
  84. 10
      test/distrib/bazel/run_bazel_distrib_test.sh
  85. 14
      test/distrib/bazel/test_single_bazel_version.sh
  86. 28
      tools/buildgen/plugins/supported_bazel_versions.py
  87. 40
      tools/dockerfile/test/python_debian11_default_x64/Dockerfile
  88. 1
      tools/doxygen/Doxyfile.c++
  89. 7
      tools/doxygen/Doxyfile.c++.internal
  90. 1
      tools/doxygen/Doxyfile.core
  91. 7
      tools/doxygen/Doxyfile.core.internal
  92. 1
      tools/doxygen/Doxyfile.objc
  93. 1
      tools/doxygen/Doxyfile.objc.internal
  94. 1
      tools/doxygen/Doxyfile.php
  95. 36
      tools/internal_ci/helper_scripts/install_python_interpreters.ps1
  96. 2
      tools/internal_ci/linux/grpc_bazel_build_in_docker.sh
  97. 42
      tools/profiling/memory/memory_diff.py
  98. 46
      tools/release/update_supported_bazel_versions.sh

@ -21,6 +21,7 @@ third_party/upb
third_party/xds
bazel/test/python_test_repo
test/distrib/bazel/cpp
# Directories generated by setuptools build containing BUILD files.
src/python/grpcio_tests/src/

@ -1,7 +1,7 @@
---
name: Report a gRPC Core bug
about: Create a report to help us improve
labels: kind/bug, priority/P2, lang/core
labels: kind/bug, priority/P2, lang/core, untriaged
assignees: markdroth
---

@ -1,7 +1,7 @@
---
name: Report a gRPC C++ bug
about: Create a report to help us improve
labels: kind/bug, priority/P2, lang/c++
labels: kind/bug, priority/P2, lang/c++, untriaged
assignees: markdroth
---

14
BUILD

@ -2883,6 +2883,7 @@ grpc_cc_library(
"src/core/ext/xds/xds_client.cc",
"src/core/ext/xds/xds_client_stats.cc",
"src/core/ext/xds/xds_cluster.cc",
"src/core/ext/xds/xds_cluster_specifier_plugin.cc",
"src/core/ext/xds/xds_common_types.cc",
"src/core/ext/xds/xds_endpoint.cc",
"src/core/ext/xds/xds_http_fault_filter.cc",
@ -2907,6 +2908,7 @@ grpc_cc_library(
"src/core/ext/xds/xds_client.h",
"src/core/ext/xds/xds_client_stats.h",
"src/core/ext/xds/xds_cluster.h",
"src/core/ext/xds/xds_cluster_specifier_plugin.h",
"src/core/ext/xds/xds_common_types.h",
"src/core/ext/xds/xds_endpoint.h",
"src/core/ext/xds/xds_http_fault_filter.h",
@ -2995,6 +2997,8 @@ grpc_cc_library(
"protobuf_timestamp_upb",
"protobuf_wrappers_upb",
"ref_counted_ptr",
"rls_config_upb",
"rls_config_upbdefs",
"slice",
"slice_refcount",
"sockaddr_utils",
@ -5371,6 +5375,16 @@ grpc_upb_proto_library(
deps = ["//src/proto/grpc/lookup/v1:rls_proto_descriptor"],
)
grpc_upb_proto_library(
name = "rls_config_upb",
deps = ["//src/proto/grpc/lookup/v1:rls_config_proto_descriptor"],
)
grpc_upb_proto_reflection_library(
name = "rls_config_upbdefs",
deps = ["//src/proto/grpc/lookup/v1:rls_config_proto_descriptor"],
)
WELL_KNOWN_PROTO_TARGETS = [
"any",
"duration",

17
CMakeLists.txt generated

@ -442,6 +442,9 @@ protobuf_generate_grpc_cpp(
protobuf_generate_grpc_cpp(
src/proto/grpc/lookup/v1/rls.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/lookup/v1/rls_config.proto
)
protobuf_generate_grpc_cpp(
src/proto/grpc/reflection/v1alpha/reflection.proto
)
@ -1654,6 +1657,7 @@ add_library(grpc
src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c
src/core/ext/upb-generated/udpa/annotations/security.upb.c
src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c
@ -1788,6 +1792,7 @@ add_library(grpc
src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c
src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c
@ -1820,6 +1825,7 @@ add_library(grpc
src/core/ext/xds/xds_client.cc
src/core/ext/xds/xds_client_stats.cc
src/core/ext/xds/xds_cluster.cc
src/core/ext/xds/xds_cluster_specifier_plugin.cc
src/core/ext/xds/xds_common_types.cc
src/core/ext/xds/xds_endpoint.cc
src/core/ext/xds/xds_http_fault_filter.cc
@ -3956,6 +3962,7 @@ add_library(upb
third_party/upb/upb/decode.c
third_party/upb/upb/def.c
third_party/upb/upb/encode.c
third_party/upb/upb/json_encode.c
third_party/upb/upb/msg.c
third_party/upb/upb/reflection.c
third_party/upb/upb/table.c
@ -14118,6 +14125,7 @@ add_executable(rls_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
test/core/util/test_lb_policies.cc
test/cpp/end2end/rls_end2end_test.cc
test/cpp/end2end/rls_server.cc
test/cpp/end2end/test_service_impl.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
@ -16986,6 +16994,14 @@ if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(xds_end2end_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls_config.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls_config.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls_config.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/lookup/v1/rls_config.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h
@ -17143,6 +17159,7 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/tls.grpc.pb.h
src/cpp/server/csds/csds.cc
test/cpp/end2end/rls_server.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/end2end/xds/xds_end2end_test.cc
test/cpp/end2end/xds/xds_server.cc

7
Makefile generated

@ -1242,6 +1242,7 @@ LIBGRPC_SRC = \
src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
src/core/ext/upb-generated/udpa/annotations/security.upb.c \
src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c \
@ -1376,6 +1377,7 @@ LIBGRPC_SRC = \
src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c \
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \
@ -1408,6 +1410,7 @@ LIBGRPC_SRC = \
src/core/ext/xds/xds_client.cc \
src/core/ext/xds/xds_client_stats.cc \
src/core/ext/xds/xds_cluster.cc \
src/core/ext/xds/xds_cluster_specifier_plugin.cc \
src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_endpoint.cc \
src/core/ext/xds/xds_http_fault_filter.cc \
@ -2526,6 +2529,7 @@ LIBUPB_SRC = \
third_party/upb/upb/decode.c \
third_party/upb/upb/def.c \
third_party/upb/upb/encode.c \
third_party/upb/upb/json_encode.c \
third_party/upb/upb/msg.c \
third_party/upb/upb/reflection.c \
third_party/upb/upb/table.c \
@ -2943,6 +2947,7 @@ src/core/ext/upb-generated/opencensus/proto/trace/v1/trace_config.upb.c: $(OPENS
src/core/ext/upb-generated/src/proto/grpc/gcp/altscontext.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/src/proto/grpc/gcp/handshaker.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/src/proto/grpc/gcp/transport_security_common.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/udpa/annotations/security.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c: $(OPENSSL_DEP)
@ -3074,6 +3079,7 @@ src/core/ext/upbdefs-generated/google/protobuf/timestamp.upbdefs.c: $(OPENSSL_DE
src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c: $(OPENSSL_DEP)
src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c: $(OPENSSL_DEP)
@ -3106,6 +3112,7 @@ src/core/ext/xds/xds_channel_stack_modifier.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_client_stats.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_cluster.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_cluster_specifier_plugin.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_common_types.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_endpoint.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_http_fault_filter.cc: $(OPENSSL_DEP)

@ -0,0 +1,3 @@
5.0.0
4.2.2
3.7.2

@ -1,3 +1,5 @@
# TODO: Move to test/distrib/python.
local_repository(
name = "com_github_grpc_grpc",
path = "../../..",

@ -513,6 +513,7 @@ libs:
- src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h
- src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h
- src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h
- src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h
- src/core/ext/upb-generated/udpa/annotations/migrate.upb.h
- src/core/ext/upb-generated/udpa/annotations/security.upb.h
- src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h
@ -647,6 +648,7 @@ libs:
- src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.h
- src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h
- src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h
- src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h
- src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h
- src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.h
- src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h
@ -682,6 +684,7 @@ libs:
- src/core/ext/xds/xds_client.h
- src/core/ext/xds/xds_client_stats.h
- src/core/ext/xds/xds_cluster.h
- src/core/ext/xds/xds_cluster_specifier_plugin.h
- src/core/ext/xds/xds_common_types.h
- src/core/ext/xds/xds_endpoint.h
- src/core/ext/xds/xds_http_fault_filter.h
@ -1186,6 +1189,7 @@ libs:
- src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c
- src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c
- src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c
- src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c
- src/core/ext/upb-generated/udpa/annotations/migrate.upb.c
- src/core/ext/upb-generated/udpa/annotations/security.upb.c
- src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c
@ -1320,6 +1324,7 @@ libs:
- src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c
- src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c
- src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c
- src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c
- src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c
- src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c
- src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c
@ -1352,6 +1357,7 @@ libs:
- src/core/ext/xds/xds_client.cc
- src/core/ext/xds/xds_client_stats.cc
- src/core/ext/xds/xds_cluster.cc
- src/core/ext/xds/xds_cluster_specifier_plugin.cc
- src/core/ext/xds/xds_common_types.cc
- src/core/ext/xds/xds_endpoint.cc
- src/core/ext/xds/xds_http_fault_filter.cc
@ -7133,6 +7139,7 @@ targets:
headers:
- test/core/util/test_lb_policies.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/rls_server.h
- test/cpp/end2end/test_service_impl.h
src:
- src/proto/grpc/lookup/v1/rls.proto
@ -7142,6 +7149,7 @@ targets:
- src/proto/grpc/testing/simple_messages.proto
- test/core/util/test_lb_policies.cc
- test/cpp/end2end/rls_end2end_test.cc
- test/cpp/end2end/rls_server.cc
- test/cpp/end2end/test_service_impl.cc
deps:
- grpc++_test_config
@ -8357,10 +8365,13 @@ targets:
headers:
- src/cpp/server/csds/csds.h
- test/cpp/end2end/counted_service.h
- test/cpp/end2end/rls_server.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/end2end/xds/xds_server.h
- test/cpp/util/tls_test_utils.h
src:
- src/proto/grpc/lookup/v1/rls.proto
- src/proto/grpc/lookup/v1/rls_config.proto
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/echo_messages.proto
@ -8401,6 +8412,7 @@ targets:
- src/proto/grpc/testing/xds/v3/string.proto
- src/proto/grpc/testing/xds/v3/tls.proto
- src/cpp/server/csds/csds.cc
- test/cpp/end2end/rls_server.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/end2end/xds/xds_end2end_test.cc
- test/cpp/end2end/xds/xds_server.cc

5
config.m4 generated

@ -260,6 +260,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
src/core/ext/upb-generated/udpa/annotations/security.upb.c \
src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c \
@ -394,6 +395,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c \
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \
@ -426,6 +428,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/xds/xds_client.cc \
src/core/ext/xds/xds_client_stats.cc \
src/core/ext/xds/xds_cluster.cc \
src/core/ext/xds/xds_cluster_specifier_plugin.cc \
src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_endpoint.cc \
src/core/ext/xds/xds_http_fault_filter.cc \
@ -1150,6 +1153,7 @@ if test "$PHP_GRPC" != "no"; then
third_party/upb/upb/decode_fast.c \
third_party/upb/upb/def.c \
third_party/upb/upb/encode.c \
third_party/upb/upb/json_encode.c \
third_party/upb/upb/msg.c \
third_party/upb/upb/reflection.c \
third_party/upb/upb/table.c \
@ -1280,6 +1284,7 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/protobuf)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/rpc)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/opencensus/proto/trace/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/udpa/annotations)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/validate)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/xds/annotations/v3)

9
config.w32 generated

@ -226,6 +226,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\upb-generated\\src\\proto\\grpc\\health\\v1\\health.upb.c " +
"src\\core\\ext\\upb-generated\\src\\proto\\grpc\\lb\\v1\\load_balancer.upb.c " +
"src\\core\\ext\\upb-generated\\src\\proto\\grpc\\lookup\\v1\\rls.upb.c " +
"src\\core\\ext\\upb-generated\\src\\proto\\grpc\\lookup\\v1\\rls_config.upb.c " +
"src\\core\\ext\\upb-generated\\udpa\\annotations\\migrate.upb.c " +
"src\\core\\ext\\upb-generated\\udpa\\annotations\\security.upb.c " +
"src\\core\\ext\\upb-generated\\udpa\\annotations\\sensitive.upb.c " +
@ -360,6 +361,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\upbdefs-generated\\google\\protobuf\\wrappers.upbdefs.c " +
"src\\core\\ext\\upbdefs-generated\\google\\rpc\\status.upbdefs.c " +
"src\\core\\ext\\upbdefs-generated\\opencensus\\proto\\trace\\v1\\trace_config.upbdefs.c " +
"src\\core\\ext\\upbdefs-generated\\src\\proto\\grpc\\lookup\\v1\\rls_config.upbdefs.c " +
"src\\core\\ext\\upbdefs-generated\\udpa\\annotations\\migrate.upbdefs.c " +
"src\\core\\ext\\upbdefs-generated\\udpa\\annotations\\security.upbdefs.c " +
"src\\core\\ext\\upbdefs-generated\\udpa\\annotations\\sensitive.upbdefs.c " +
@ -392,6 +394,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\xds\\xds_client.cc " +
"src\\core\\ext\\xds\\xds_client_stats.cc " +
"src\\core\\ext\\xds\\xds_cluster.cc " +
"src\\core\\ext\\xds\\xds_cluster_specifier_plugin.cc " +
"src\\core\\ext\\xds\\xds_common_types.cc " +
"src\\core\\ext\\xds\\xds_endpoint.cc " +
"src\\core\\ext\\xds\\xds_http_fault_filter.cc " +
@ -1116,6 +1119,7 @@ if (PHP_GRPC != "no") {
"third_party\\upb\\upb\\decode_fast.c " +
"third_party\\upb\\upb\\def.c " +
"third_party\\upb\\upb\\encode.c " +
"third_party\\upb\\upb\\json_encode.c " +
"third_party\\upb\\upb\\msg.c " +
"third_party\\upb\\upb\\reflection.c " +
"third_party\\upb\\upb\\table.c " +
@ -1386,6 +1390,11 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\opencensus\\proto");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\opencensus\\proto\\trace");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\opencensus\\proto\\trace\\v1");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\src");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\src\\proto");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\src\\proto\\grpc");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\src\\proto\\grpc\\lookup");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\src\\proto\\grpc\\lookup\\v1");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\udpa");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\udpa\\annotations");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\validate");

@ -0,0 +1,44 @@
# Bazel Support
## Basic Usage
The `grpc/grpc` repository's primary build system is Bazel. Rules are provided
for C++, Python, and Objective-C. While C++ supports other build systems such as
CMake, these rules are actually generated from the Bazel definitions.
Projects built with Bazel may use the `grpc/grpc` repo not only to add a
dependency on the library itself, but also to generate protobuf, stub, and
servicer code. To do so, one must invoke the `grpc_deps` and `grpc_extra_deps`
repository rules in their `WORKSPACE` file:
```starlark
workspace(name = "example_workspace")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_github_grpc_grpc",
strip_prefix = "grpc-1.45.0",
sha256 = "ec19657a677d49af59aa806ec299c070c882986c9fcc022b1c22c2a3caf01bcd"k
urls = ["https://github.com/grpc/grpc/archive/refs/tags/v1.45.0.tar.gz"],
)
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
grpc_extra_deps()
```
## Supported Versions
In general, gRPC supports building with the latest patch release of the most
recent two major versions of Bazel. However individual releases may have a
broader compatibility range. The currently supported versions are captured by
the following list:
- [`5.0.0`](https://github.com/bazelbuild/bazel/releases/tag/5.0.0)
- [`4.2.2`](https://github.com/bazelbuild/bazel/releases/tag/4.2.2)
- [`3.7.2`](https://github.com/bazelbuild/bazel/releases/tag/3.7.2)

@ -53,9 +53,12 @@ some configuration as environment variables that can be set.
- channel - traces operations on the C core channel stack
- channel_stack - traces the set of filters in a channel stack upon
construction
- client_channel_call - traces client channel call batch activity
- client_channel_routing - traces client channel call routing, including
- client_channel - traces client channel control plane activity, including
resolver and load balancing policy interaction
- client_channel_call - traces client channel call activity related to name
resolution
- client_channel_lb_call - traces client channel call activity related
to load balancing picking
- compression - traces compression operations
- connectivity_state - traces connectivity state changes to channels
- cronet - traces state in the cronet transport engine

8
gRPC-C++.podspec generated

@ -453,6 +453,7 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.h',
'src/core/ext/upb-generated/udpa/annotations/security.upb.h',
'src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h',
@ -587,6 +588,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.h',
'src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h',
@ -622,6 +624,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.h',
'src/core/ext/xds/xds_cluster.h',
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_http_fault_filter.h',
@ -1025,6 +1028,7 @@ Pod::Spec.new do |s|
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/msg_internal.h',
'third_party/upb/upb/port_def.inc',
@ -1259,6 +1263,7 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.h',
'src/core/ext/upb-generated/udpa/annotations/security.upb.h',
'src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h',
@ -1393,6 +1398,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.h',
'src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h',
@ -1428,6 +1434,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.h',
'src/core/ext/xds/xds_cluster.h',
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_http_fault_filter.h',
@ -1781,6 +1788,7 @@ Pod::Spec.new do |s|
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/msg_internal.h',
'third_party/upb/upb/port_def.inc',

12
gRPC-Core.podspec generated

@ -612,6 +612,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.c',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.h',
'src/core/ext/upb-generated/udpa/annotations/security.upb.c',
@ -880,6 +882,8 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c',
@ -947,6 +951,8 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_client_stats.h',
'src/core/ext/xds/xds_cluster.cc',
'src/core/ext/xds/xds_cluster.h',
'src/core/ext/xds/xds_cluster_specifier_plugin.cc',
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.cc',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.cc',
@ -1639,6 +1645,8 @@ Pod::Spec.new do |s|
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.c',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_encode.c',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.c',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/msg_internal.h',
@ -1857,6 +1865,7 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.h',
'src/core/ext/upb-generated/udpa/annotations/security.upb.h',
'src/core/ext/upb-generated/udpa/annotations/sensitive.upb.h',
@ -1991,6 +2000,7 @@ Pod::Spec.new do |s|
'src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.h',
'src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.h',
'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h',
@ -2026,6 +2036,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_client.h',
'src/core/ext/xds/xds_client_stats.h',
'src/core/ext/xds/xds_cluster.h',
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_http_fault_filter.h',
@ -2369,6 +2380,7 @@ Pod::Spec.new do |s|
'third_party/upb/upb/def.h',
'third_party/upb/upb/def.hpp',
'third_party/upb/upb/encode.h',
'third_party/upb/upb/json_encode.h',
'third_party/upb/upb/msg.h',
'third_party/upb/upb/msg_internal.h',
'third_party/upb/upb/port_def.inc',

8
grpc.gemspec generated

@ -531,6 +531,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h )
s.files += %w( src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c )
s.files += %w( src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h )
s.files += %w( src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c )
s.files += %w( src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h )
s.files += %w( src/core/ext/upb-generated/udpa/annotations/migrate.upb.c )
s.files += %w( src/core/ext/upb-generated/udpa/annotations/migrate.upb.h )
s.files += %w( src/core/ext/upb-generated/udpa/annotations/security.upb.c )
@ -799,6 +801,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h )
s.files += %w( src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c )
s.files += %w( src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h )
s.files += %w( src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c )
s.files += %w( src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h )
s.files += %w( src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c )
s.files += %w( src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h )
s.files += %w( src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c )
@ -866,6 +870,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/xds_client_stats.h )
s.files += %w( src/core/ext/xds/xds_cluster.cc )
s.files += %w( src/core/ext/xds/xds_cluster.h )
s.files += %w( src/core/ext/xds/xds_cluster_specifier_plugin.cc )
s.files += %w( src/core/ext/xds/xds_cluster_specifier_plugin.h )
s.files += %w( src/core/ext/xds/xds_common_types.cc )
s.files += %w( src/core/ext/xds/xds_common_types.h )
s.files += %w( src/core/ext/xds/xds_endpoint.cc )
@ -2437,6 +2443,8 @@ Gem::Specification.new do |s|
s.files += %w( third_party/upb/upb/def.hpp )
s.files += %w( third_party/upb/upb/encode.c )
s.files += %w( third_party/upb/upb/encode.h )
s.files += %w( third_party/upb/upb/json_encode.c )
s.files += %w( third_party/upb/upb/json_encode.h )
s.files += %w( third_party/upb/upb/msg.c )
s.files += %w( third_party/upb/upb/msg.h )
s.files += %w( third_party/upb/upb/msg_internal.h )

4
grpc.gyp generated

@ -590,6 +590,7 @@
'src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.c',
'src/core/ext/upb-generated/udpa/annotations/security.upb.c',
'src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c',
@ -724,6 +725,7 @@
'src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c',
'src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c',
@ -756,6 +758,7 @@
'src/core/ext/xds/xds_client.cc',
'src/core/ext/xds/xds_client_stats.cc',
'src/core/ext/xds/xds_cluster.cc',
'src/core/ext/xds/xds_cluster_specifier_plugin.cc',
'src/core/ext/xds/xds_common_types.cc',
'src/core/ext/xds/xds_endpoint.cc',
'src/core/ext/xds/xds_http_fault_filter.cc',
@ -2036,6 +2039,7 @@
'third_party/upb/upb/decode.c',
'third_party/upb/upb/def.c',
'third_party/upb/upb/encode.c',
'third_party/upb/upb/json_encode.c',
'third_party/upb/upb/msg.c',
'third_party/upb/upb/reflection.c',
'third_party/upb/upb/table.c',

8
package.xml generated

@ -511,6 +511,8 @@
<file baseinstalldir="/" name="src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/udpa/annotations/migrate.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/udpa/annotations/migrate.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/udpa/annotations/security.upb.c" role="src" />
@ -779,6 +781,8 @@
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c" role="src" />
@ -846,6 +850,8 @@
<file baseinstalldir="/" name="src/core/ext/xds/xds_client_stats.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_cluster.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_cluster.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_cluster_specifier_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_cluster_specifier_plugin.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_common_types.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_common_types.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_endpoint.cc" role="src" />
@ -2353,6 +2359,8 @@
<file baseinstalldir="/" name="third_party/upb/upb/def.hpp" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/encode.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/encode.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/json_encode.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/json_encode.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/msg.c" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/msg.h" role="src" />
<file baseinstalldir="/" name="third_party/upb/upb/msg_internal.h" role="src" />

@ -54,6 +54,7 @@
#include "src/core/ext/filters/deadline/deadline_filter.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gpr/string.h"
@ -85,8 +86,9 @@ using internal::ClientChannelGlobalParsedConfig;
using internal::ClientChannelMethodParsedConfig;
using internal::ClientChannelServiceConfigParser;
TraceFlag grpc_client_channel_trace(false, "client_channel");
TraceFlag grpc_client_channel_call_trace(false, "client_channel_call");
TraceFlag grpc_client_channel_routing_trace(false, "client_channel_routing");
TraceFlag grpc_client_channel_lb_call_trace(false, "client_channel_lb_call");
//
// ClientChannel::CallData definition
@ -175,8 +177,6 @@ class ClientChannel::CallData {
static void RecvTrailingMetadataReadyForConfigSelectorCommitCallback(
void* arg, grpc_error_handle error);
void InjectRecvTrailingMetadataReadyForConfigSelectorCommitCallback(
grpc_transport_stream_op_batch* batch);
void CreateDynamicCall(grpc_call_element* elem);
@ -354,7 +354,7 @@ class DynamicTerminationFilter::CallData {
args, pollent, nullptr,
service_config_call_data->call_dispatch_controller(),
/*is_transparent_retry=*/false);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p dynamic_termination_calld=%p: create lb_call=%p", chand,
client_channel, calld->lb_call_.get());
@ -410,7 +410,7 @@ class ClientChannel::ResolverResultHandler : public Resolver::ResultHandler {
}
~ResolverResultHandler() override {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: resolver shutdown complete", chand_);
}
GRPC_CHANNEL_STACK_UNREF(chand_->owning_stack_, "ResolverResultHandler");
@ -441,14 +441,13 @@ class ClientChannel::SubchannelWrapper : public SubchannelInterface {
public:
SubchannelWrapper(ClientChannel* chand, RefCountedPtr<Subchannel> subchannel,
absl::optional<std::string> health_check_service_name)
: SubchannelInterface(
GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)
: SubchannelInterface(GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)
? "SubchannelWrapper"
: nullptr),
chand_(chand),
subchannel_(std::move(subchannel)),
health_check_service_name_(std::move(health_check_service_name)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: creating subchannel wrapper %p for subchannel %p",
chand, this, subchannel_.get());
@ -470,7 +469,7 @@ class ClientChannel::SubchannelWrapper : public SubchannelInterface {
}
~SubchannelWrapper() override {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: destroying subchannel wrapper %p for subchannel %p",
chand_, this, subchannel_.get());
@ -573,7 +572,7 @@ class ClientChannel::SubchannelWrapper : public SubchannelInterface {
}
void OnConnectivityStateChange() override {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: connectivity change for subchannel wrapper %p "
"subchannel %p; hopping into work_serializer",
@ -608,7 +607,7 @@ class ClientChannel::SubchannelWrapper : public SubchannelInterface {
private:
void ApplyUpdateInControlPlaneWorkSerializer()
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*parent_->chand_->work_serializer_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: processing connectivity change in work serializer "
"for subchannel wrapper %p subchannel %p "
@ -625,7 +624,7 @@ class ClientChannel::SubchannelWrapper : public SubchannelInterface {
&new_keepalive_time)) {
if (new_keepalive_time > parent_->chand_->keepalive_time_) {
parent_->chand_->keepalive_time_ = new_keepalive_time;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: throttling keepalive time to %d",
parent_->chand_, parent_->chand_->keepalive_time_);
}
@ -934,7 +933,7 @@ class ClientChannel::ClientChannelControlHelper
std::unique_ptr<LoadBalancingPolicy::SubchannelPicker> picker) override
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
if (chand_->resolver_ == nullptr) return; // Shutting down.
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
const char* extra = chand_->disconnect_error_ == GRPC_ERROR_NONE
? ""
: " (ignoring -- channel shutting down)";
@ -952,7 +951,7 @@ class ClientChannel::ClientChannelControlHelper
void RequestReresolution() override
ABSL_EXCLUSIVE_LOCKS_REQUIRED(*chand_->work_serializer_) {
if (chand_->resolver_ == nullptr) return; // Shutting down.
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: started name re-resolving", chand_);
}
chand_->resolver_->RequestReresolutionLocked();
@ -1041,7 +1040,7 @@ ClientChannel::ClientChannel(grpc_channel_element_args* args,
work_serializer_(std::make_shared<WorkSerializer>()),
state_tracker_("client_channel", GRPC_CHANNEL_IDLE),
subchannel_pool_(GetSubchannelPool(args->channel_args)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: creating client_channel for channel stack %p",
this, owning_stack_);
}
@ -1116,7 +1115,7 @@ ClientChannel::ClientChannel(grpc_channel_element_args* args,
}
ClientChannel::~ClientChannel() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: destroying channel", this);
}
DestroyResolverAndLbPolicyLocked();
@ -1203,7 +1202,7 @@ RefCountedPtr<LoadBalancingPolicy::Config> ChooseLbPolicy(
void ClientChannel::OnResolverResultChangedLocked(Resolver::Result result) {
// Handle race conditions.
if (resolver_ == nullptr) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: got resolver result", this);
}
// We only want to trace the address resolution in the follow cases:
@ -1236,14 +1235,14 @@ void ClientChannel::OnResolverResultChangedLocked(Resolver::Result result) {
RefCountedPtr<ServiceConfig> service_config;
RefCountedPtr<ConfigSelector> config_selector;
if (!result.service_config.ok()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: resolver returned service config error: %s",
this, result.service_config.status().ToString().c_str());
}
// If the service config was invalid, then fallback to the
// previously returned service config.
if (saved_service_config_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned invalid service config. "
"Continuing to use previous service config.",
@ -1260,7 +1259,7 @@ void ClientChannel::OnResolverResultChangedLocked(Resolver::Result result) {
}
} else if (*result.service_config == nullptr) {
// Resolver did not return any service config.
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned no service config. Using default "
"service config for channel.",
@ -1297,7 +1296,7 @@ void ClientChannel::OnResolverResultChangedLocked(Resolver::Result result) {
UpdateServiceConfigInControlPlaneLocked(std::move(service_config),
std::move(config_selector),
lb_policy_config->name());
} else if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
} else if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: service config not changed", this);
}
// Create or update LB policy, as needed.
@ -1328,7 +1327,7 @@ void ClientChannel::OnResolverResultChangedLocked(Resolver::Result result) {
void ClientChannel::OnResolverErrorLocked(absl::Status status) {
if (resolver_ == nullptr) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: resolver transient failure: %s", this,
status.ToString().c_str());
}
@ -1387,7 +1386,7 @@ void ClientChannel::CreateOrUpdateLbPolicyLocked(
lb_policy_ = CreateLbPolicyLocked(*update_args.args);
}
// Update the policy.
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: Updating child policy %p", this,
lb_policy_.get());
}
@ -1404,8 +1403,8 @@ OrphanablePtr<LoadBalancingPolicy> ClientChannel::CreateLbPolicyLocked(
lb_policy_args.args = &args;
OrphanablePtr<LoadBalancingPolicy> lb_policy =
MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
&grpc_client_channel_routing_trace);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
&grpc_client_channel_trace);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: created new LB policy %p", this,
lb_policy.get());
}
@ -1442,7 +1441,7 @@ void ClientChannel::UpdateServiceConfigInControlPlaneLocked(
RefCountedPtr<ServiceConfig> service_config,
RefCountedPtr<ConfigSelector> config_selector, std::string lb_policy_name) {
std::string service_config_json(service_config->json_string());
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO,
"chand=%p: resolver returned updated service config: \"%s\"", this,
service_config_json.c_str());
@ -1457,7 +1456,7 @@ void ClientChannel::UpdateServiceConfigInControlPlaneLocked(
}
// Save config selector.
saved_config_selector_ = std::move(config_selector);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: using ConfigSelector %p", this,
saved_config_selector_.get());
}
@ -1468,7 +1467,7 @@ void ClientChannel::UpdateServiceConfigInDataPlaneLocked() {
RefCountedPtr<ServiceConfig> service_config = saved_service_config_;
// Grab ref to config selector. Use default if resolver didn't supply one.
RefCountedPtr<ConfigSelector> config_selector = saved_config_selector_;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: switching to ConfigSelector %p", this,
saved_config_selector_.get());
}
@ -1539,7 +1538,7 @@ void ClientChannel::UpdateServiceConfigInDataPlaneLocked() {
}
void ClientChannel::CreateResolverLocked() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: starting name resolution", this);
}
resolver_ = CoreConfiguration::Get().resolver_registry().CreateResolver(
@ -1552,20 +1551,20 @@ void ClientChannel::CreateResolverLocked() {
GRPC_CHANNEL_CONNECTING, absl::Status(), "started resolving",
absl::make_unique<LoadBalancingPolicy::QueuePicker>(nullptr));
resolver_->StartLocked();
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: created resolver=%p", this, resolver_.get());
}
}
void ClientChannel::DestroyResolverAndLbPolicyLocked() {
if (resolver_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: shutting down resolver=%p", this,
resolver_.get());
}
resolver_.reset();
if (lb_policy_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: shutting down lb_policy=%p", this,
lb_policy_.get());
}
@ -1733,7 +1732,7 @@ void ClientChannel::StartTransportOpLocked(grpc_transport_op* op) {
}
// Disconnect or enter IDLE.
if (op->disconnect_with_error != GRPC_ERROR_NONE) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_trace)) {
gpr_log(GPR_INFO, "chand=%p: disconnect_with_error: %s", this,
grpc_error_std_string(op->disconnect_with_error).c_str());
}
@ -1911,6 +1910,11 @@ void ClientChannel::CallData::StartTransportStreamOpBatch(
GPR_TIMER_SCOPE("cc_start_transport_stream_op_batch", 0);
CallData* calld = static_cast<CallData*>(elem->call_data);
ClientChannel* chand = static_cast<ClientChannel*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace) &&
!GRPC_TRACE_FLAG_ENABLED(grpc_trace_channel)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: batch started from above: %s", chand,
calld, grpc_transport_stream_op_batch_string(batch).c_str());
}
if (GPR_LIKELY(chand->deadline_checking_enabled_)) {
grpc_deadline_state_client_start_transport_stream_op_batch(elem, batch);
}
@ -1918,8 +1922,13 @@ void ClientChannel::CallData::StartTransportStreamOpBatch(
// in case we wind up failing the call before we get down to the retry
// or LB call layer.
if (batch->recv_trailing_metadata) {
calld->InjectRecvTrailingMetadataReadyForConfigSelectorCommitCallback(
batch);
calld->original_recv_trailing_metadata_ready_ =
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready_,
RecvTrailingMetadataReadyForConfigSelectorCommitCallback,
elem, nullptr);
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
&calld->recv_trailing_metadata_ready_;
}
// If we already have a dynamic call, pass the batch down to it.
// Note that once we have done so, we do not need to acquire the channel's
@ -2144,7 +2153,7 @@ class ClientChannel::CallData::ResolverQueuedCallCanceller {
auto* calld = static_cast<CallData*>(self->elem_->call_data);
{
MutexLock lock(&chand->resolution_mu_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: cancelling resolver queued pick: "
"error=%s self=%p calld->resolver_pick_canceller=%p",
@ -2171,7 +2180,7 @@ void ClientChannel::CallData::MaybeRemoveCallFromResolverQueuedCallsLocked(
grpc_call_element* elem) {
if (!queued_pending_resolver_result_) return;
auto* chand = static_cast<ClientChannel*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: removing from resolver queued picks list",
chand, this);
@ -2186,7 +2195,7 @@ void ClientChannel::CallData::MaybeAddCallToResolverQueuedCallsLocked(
grpc_call_element* elem) {
if (queued_pending_resolver_result_) return;
auto* chand = static_cast<ClientChannel*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: adding to resolver queued picks list",
chand, this);
}
@ -2200,7 +2209,7 @@ void ClientChannel::CallData::MaybeAddCallToResolverQueuedCallsLocked(
grpc_error_handle ClientChannel::CallData::ApplyServiceConfigToCallLocked(
grpc_call_element* elem, grpc_metadata_batch* initial_metadata) {
ClientChannel* chand = static_cast<ClientChannel*>(elem->channel_data);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: applying service config to call",
chand, this);
}
@ -2261,30 +2270,27 @@ grpc_error_handle ClientChannel::CallData::ApplyServiceConfigToCallLocked(
void ClientChannel::CallData::
RecvTrailingMetadataReadyForConfigSelectorCommitCallback(
void* arg, grpc_error_handle error) {
auto* self = static_cast<CallData*>(arg);
auto* elem = static_cast<grpc_call_element*>(arg);
auto* chand = static_cast<ClientChannel*>(elem->channel_data);
auto* calld = static_cast<CallData*>(elem->call_data);
auto* service_config_call_data =
static_cast<ClientChannelServiceConfigCallData*>(
self->call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
calld->call_context_[GRPC_CONTEXT_SERVICE_CONFIG_CALL_DATA].value);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: got recv_trailing_metadata_ready: error=%s "
"service_config_call_data=%p",
chand, calld, grpc_error_std_string(error).c_str(),
service_config_call_data);
}
if (service_config_call_data != nullptr) {
service_config_call_data->call_dispatch_controller()->Commit();
}
// Chain to original callback.
Closure::Run(DEBUG_LOCATION, self->original_recv_trailing_metadata_ready_,
Closure::Run(DEBUG_LOCATION, calld->original_recv_trailing_metadata_ready_,
GRPC_ERROR_REF(error));
}
void ClientChannel::CallData::
InjectRecvTrailingMetadataReadyForConfigSelectorCommitCallback(
grpc_transport_stream_op_batch* batch) {
original_recv_trailing_metadata_ready_ =
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_,
RecvTrailingMetadataReadyForConfigSelectorCommitCallback,
this, nullptr);
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
&recv_trailing_metadata_ready_;
}
void ClientChannel::CallData::AsyncResolutionDone(grpc_call_element* elem,
grpc_error_handle error) {
// TODO(roth): Does this callback need to hold a ref to the call stack?
@ -2298,7 +2304,7 @@ void ClientChannel::CallData::ResolutionDone(void* arg,
ClientChannel* chand = static_cast<ClientChannel*>(elem->channel_data);
CallData* calld = static_cast<CallData*>(elem->call_data);
if (error != GRPC_ERROR_NONE) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: error applying config to call: error=%s",
chand, calld, grpc_error_std_string(error).c_str());
@ -2330,6 +2336,9 @@ bool ClientChannel::CallData::CheckResolutionLocked(grpc_call_element* elem,
ClientChannel* chand = static_cast<ClientChannel*>(elem->channel_data);
// If we're still in IDLE, we need to start resolving.
if (GPR_UNLIKELY(chand->CheckConnectivityState(false) == GRPC_CHANNEL_IDLE)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: triggering exit idle", chand, this);
}
// Bounce into the control plane work serializer to start resolving,
// in case we are still in IDLE state. Since we are holding on to the
// resolution mutex here, we offload it on the ExecCtx so that we don't
@ -2367,6 +2376,10 @@ bool ClientChannel::CallData::CheckResolutionLocked(grpc_call_element* elem,
absl::Status resolver_error = chand->resolver_transient_failure_error_;
if (!resolver_error.ok() && (send_initial_metadata_flags &
GRPC_INITIAL_METADATA_WAIT_FOR_READY) == 0) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: resolution failed, failing call",
chand, this);
}
MaybeRemoveCallFromResolverQueuedCallsLocked(elem);
*error = absl_status_to_grpc_error(resolver_error);
return true;
@ -2374,6 +2387,10 @@ bool ClientChannel::CallData::CheckResolutionLocked(grpc_call_element* elem,
// Either the resolver has not yet returned a result, or it has
// returned transient failure but the call is wait_for_ready. In
// either case, queue the call.
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: queuing to wait for resolution",
chand, this);
}
MaybeAddCallToResolverQueuedCallsLocked(elem);
return false;
}
@ -2398,7 +2415,7 @@ void ClientChannel::CallData::CreateDynamicCall(grpc_call_element* elem) {
call_combiner_};
grpc_error_handle error = GRPC_ERROR_NONE;
DynamicFilters* channel_stack = args.channel_stack.get();
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(
GPR_INFO,
"chand=%p calld=%p: creating dynamic call stack on channel_stack=%p",
@ -2406,7 +2423,7 @@ void ClientChannel::CallData::CreateDynamicCall(grpc_call_element* elem) {
}
dynamic_call_ = channel_stack->CreateCall(std::move(args), &error);
if (error != GRPC_ERROR_NONE) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p calld=%p: failed to create dynamic call: error=%s",
chand, this, grpc_error_std_string(error).c_str());
@ -2427,6 +2444,7 @@ class ClientChannel::LoadBalancedCall::Metadata
explicit Metadata(grpc_metadata_batch* batch) : batch_(batch) {}
void Add(absl::string_view key, absl::string_view value) override {
if (batch_ == nullptr) return;
// Gross, egregious hack to support legacy grpclb behavior.
// TODO(ctiller): Use a promise context for this once that plumbing is done.
if (key == GrpcLbClientStatsMetadata::key()) {
@ -2447,6 +2465,7 @@ class ClientChannel::LoadBalancedCall::Metadata
std::vector<std::pair<std::string, std::string>> TestOnlyCopyToVector()
override {
if (batch_ == nullptr) return {};
Encoder encoder;
batch_->Encode(&encoder);
return encoder.Take();
@ -2454,6 +2473,7 @@ class ClientChannel::LoadBalancedCall::Metadata
absl::optional<absl::string_view> Lookup(absl::string_view key,
std::string* buffer) const override {
if (batch_ == nullptr) return absl::nullopt;
return batch_->GetStringValue(key, buffer);
}
@ -2524,7 +2544,8 @@ class ClientChannel::LoadBalancedCall::BackendMetricAccessor
: lb_call_(lb_call) {}
const BackendMetricData* GetBackendMetricData() override {
if (lb_call_->backend_metric_data_ == nullptr) {
if (lb_call_->backend_metric_data_ == nullptr &&
lb_call_->recv_trailing_metadata_ != nullptr) {
if (const auto* md = lb_call_->recv_trailing_metadata_->get_pointer(
XEndpointLoadMetricsBinMetadata())) {
lb_call_->backend_metric_data_ =
@ -2560,7 +2581,7 @@ ClientChannel::LoadBalancedCall::LoadBalancedCall(
ConfigSelector::CallDispatchController* call_dispatch_controller,
bool is_transparent_retry)
: InternallyRefCounted(
GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)
GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)
? "LoadBalancedCall"
: nullptr),
chand_(chand),
@ -2574,7 +2595,11 @@ ClientChannel::LoadBalancedCall::LoadBalancedCall(
on_call_destruction_complete_(on_call_destruction_complete),
call_dispatch_controller_(call_dispatch_controller),
call_attempt_tracer_(
GetCallAttemptTracer(args.context, is_transparent_retry)) {}
GetCallAttemptTracer(args.context, is_transparent_retry)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: created", chand_, this);
}
}
ClientChannel::LoadBalancedCall::~LoadBalancedCall() {
GRPC_ERROR_UNREF(cancel_error_);
@ -2594,6 +2619,12 @@ ClientChannel::LoadBalancedCall::~LoadBalancedCall() {
}
void ClientChannel::LoadBalancedCall::Orphan() {
// If the recv_trailing_metadata op was never started, then notify
// about call completion here, as best we can. We assume status
// CANCELLED in this case.
if (recv_trailing_metadata_ == nullptr) {
RecordCallCompletion(absl::CancelledError("call cancelled"));
}
// Compute latency and report it to the tracer.
if (call_attempt_tracer_ != nullptr) {
gpr_timespec latency =
@ -2620,7 +2651,7 @@ size_t ClientChannel::LoadBalancedCall::GetBatchIndex(
void ClientChannel::LoadBalancedCall::PendingBatchesAdd(
grpc_transport_stream_op_batch* batch) {
const size_t idx = GetBatchIndex(batch);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: adding pending batch at index %" PRIuPTR,
chand_, this, idx);
@ -2647,7 +2678,7 @@ void ClientChannel::LoadBalancedCall::PendingBatchesFail(
GPR_ASSERT(error != GRPC_ERROR_NONE);
GRPC_ERROR_UNREF(failure_error_);
failure_error_ = error;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
size_t num_batches = 0;
for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
if (pending_batches_[i] != nullptr) ++num_batches;
@ -2689,7 +2720,7 @@ void ClientChannel::LoadBalancedCall::ResumePendingBatchInCallCombiner(
// This is called via the call combiner, so access to calld is synchronized.
void ClientChannel::LoadBalancedCall::PendingBatchesResume() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
size_t num_batches = 0;
for (size_t i = 0; i < GPR_ARRAY_SIZE(pending_batches_); ++i) {
if (pending_batches_[i] != nullptr) ++num_batches;
@ -2718,6 +2749,14 @@ void ClientChannel::LoadBalancedCall::PendingBatchesResume() {
void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
grpc_transport_stream_op_batch* batch) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace) ||
GRPC_TRACE_FLAG_ENABLED(grpc_trace_channel)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: batch started from above: %s, "
"call_attempt_tracer_=%p",
chand_, this, grpc_transport_stream_op_batch_string(batch).c_str(),
call_attempt_tracer_);
}
// Handle call tracing.
if (call_attempt_tracer_ != nullptr) {
// Record send ops in tracer.
@ -2781,7 +2820,7 @@ void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
// the channel's data plane mutex, which is more efficient (especially for
// streaming calls).
if (subchannel_call_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: starting batch on subchannel_call=%p",
chand_, this, subchannel_call_.get());
@ -2793,7 +2832,7 @@ void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
//
// If we've previously been cancelled, immediately fail any new batches.
if (GPR_UNLIKELY(cancel_error_ != GRPC_ERROR_NONE)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: failing batch with error: %s",
chand_, this, grpc_error_std_string(cancel_error_).c_str());
}
@ -2811,7 +2850,7 @@ void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
// error to the caller when the first batch does get passed down.
GRPC_ERROR_UNREF(cancel_error_);
cancel_error_ = GRPC_ERROR_REF(batch->payload->cancel_stream.cancel_error);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: recording cancel_error=%s",
chand_, this, grpc_error_std_string(cancel_error_).c_str());
}
@ -2827,7 +2866,7 @@ void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
// For batches containing a send_initial_metadata op, acquire the
// channel's data plane mutex to pick a subchannel.
if (GPR_LIKELY(batch->send_initial_metadata)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: grabbing data plane mutex to perform pick",
chand_, this);
@ -2835,7 +2874,7 @@ void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
PickSubchannel(this, GRPC_ERROR_NONE);
} else {
// For all other batches, release the call combiner.
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_call_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: saved batch, yielding call combiner",
chand_, this);
@ -2848,6 +2887,12 @@ void ClientChannel::LoadBalancedCall::StartTransportStreamOpBatch(
void ClientChannel::LoadBalancedCall::SendInitialMetadataOnComplete(
void* arg, grpc_error_handle error) {
auto* self = static_cast<LoadBalancedCall*>(arg);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: got on_complete for send_initial_metadata: "
"error=%s",
self->chand_, self, grpc_error_std_string(error).c_str());
}
self->call_attempt_tracer_->RecordOnDoneSendInitialMetadata(
self->peer_string_);
Closure::Run(DEBUG_LOCATION,
@ -2858,6 +2903,11 @@ void ClientChannel::LoadBalancedCall::SendInitialMetadataOnComplete(
void ClientChannel::LoadBalancedCall::RecvInitialMetadataReady(
void* arg, grpc_error_handle error) {
auto* self = static_cast<LoadBalancedCall*>(arg);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: got recv_initial_metadata_ready: error=%s",
self->chand_, self, grpc_error_std_string(error).c_str());
}
if (error == GRPC_ERROR_NONE) {
// recv_initial_metadata_flags is not populated for clients
self->call_attempt_tracer_->RecordReceivedInitialMetadata(
@ -2870,6 +2920,10 @@ void ClientChannel::LoadBalancedCall::RecvInitialMetadataReady(
void ClientChannel::LoadBalancedCall::RecvMessageReady(
void* arg, grpc_error_handle error) {
auto* self = static_cast<LoadBalancedCall*>(arg);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: got recv_message_ready: error=%s",
self->chand_, self, grpc_error_std_string(error).c_str());
}
if (*self->recv_message_ != nullptr) {
self->call_attempt_tracer_->RecordReceivedMessage(**self->recv_message_);
}
@ -2880,6 +2934,15 @@ void ClientChannel::LoadBalancedCall::RecvMessageReady(
void ClientChannel::LoadBalancedCall::RecvTrailingMetadataReady(
void* arg, grpc_error_handle error) {
auto* self = static_cast<LoadBalancedCall*>(arg);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: got recv_trailing_metadata_ready: error=%s "
"call_attempt_tracer_=%p lb_subchannel_call_tracker_=%p "
"failure_error_=%s",
self->chand_, self, grpc_error_std_string(error).c_str(),
self->call_attempt_tracer_, self->lb_subchannel_call_tracker_.get(),
grpc_error_std_string(self->failure_error_).c_str());
}
// Check if we have a tracer or an LB callback to invoke.
if (self->call_attempt_tracer_ != nullptr ||
self->lb_subchannel_call_tracker_ != nullptr) {
@ -2905,22 +2968,7 @@ void ClientChannel::LoadBalancedCall::RecvTrailingMetadataReady(
status = absl::Status(static_cast<absl::StatusCode>(code), message);
}
}
// If we have a tracer, notify it.
if (self->call_attempt_tracer_ != nullptr) {
self->call_attempt_tracer_->RecordReceivedTrailingMetadata(
status, self->recv_trailing_metadata_,
*self->transport_stream_stats_);
}
// If the LB policy requested a callback for trailing metadata, invoke
// the callback.
if (self->lb_subchannel_call_tracker_ != nullptr) {
Metadata trailing_metadata(self->recv_trailing_metadata_);
BackendMetricAccessor backend_metric_accessor(self);
LoadBalancingPolicy::SubchannelCallTrackerInterface::FinishArgs args = {
status, &trailing_metadata, &backend_metric_accessor};
self->lb_subchannel_call_tracker_->Finish(args);
self->lb_subchannel_call_tracker_.reset();
}
self->RecordCallCompletion(status);
}
// Chain to original callback.
if (self->failure_error_ != GRPC_ERROR_NONE) {
@ -2933,6 +2981,25 @@ void ClientChannel::LoadBalancedCall::RecvTrailingMetadataReady(
error);
}
void ClientChannel::LoadBalancedCall::RecordCallCompletion(
absl::Status status) {
// If we have a tracer, notify it.
if (call_attempt_tracer_ != nullptr) {
call_attempt_tracer_->RecordReceivedTrailingMetadata(
status, recv_trailing_metadata_, transport_stream_stats_);
}
// If the LB policy requested a callback for trailing metadata, invoke
// the callback.
if (lb_subchannel_call_tracker_ != nullptr) {
Metadata trailing_metadata(recv_trailing_metadata_);
BackendMetricAccessor backend_metric_accessor(this);
LoadBalancingPolicy::SubchannelCallTrackerInterface::FinishArgs args = {
status, &trailing_metadata, &backend_metric_accessor};
lb_subchannel_call_tracker_->Finish(args);
lb_subchannel_call_tracker_.reset();
}
}
void ClientChannel::LoadBalancedCall::CreateSubchannelCall() {
SubchannelCall::Args call_args = {
std::move(connected_subchannel_), pollent_, path_.Ref(), /*start_time=*/0,
@ -2942,7 +3009,7 @@ void ClientChannel::LoadBalancedCall::CreateSubchannelCall() {
call_context_, call_combiner_};
grpc_error_handle error = GRPC_ERROR_NONE;
subchannel_call_ = SubchannelCall::Create(std::move(call_args), &error);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: create subchannel_call=%p: error=%s", chand_,
this, subchannel_call_.get(), grpc_error_std_string(error).c_str());
@ -2981,7 +3048,7 @@ class ClientChannel::LoadBalancedCall::LbQueuedCallCanceller {
auto* chand = lb_call->chand_;
{
MutexLock lock(&chand->data_plane_mu_);
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: cancelling queued pick: "
"error=%s self=%p calld->pick_canceller=%p",
@ -3007,7 +3074,7 @@ class ClientChannel::LoadBalancedCall::LbQueuedCallCanceller {
void ClientChannel::LoadBalancedCall::MaybeRemoveCallFromLbQueuedCallsLocked() {
if (!queued_pending_lb_pick_) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: removing from queued picks list",
chand_, this);
}
@ -3019,7 +3086,7 @@ void ClientChannel::LoadBalancedCall::MaybeRemoveCallFromLbQueuedCallsLocked() {
void ClientChannel::LoadBalancedCall::MaybeAddCallToLbQueuedCallsLocked() {
if (queued_pending_lb_pick_) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: adding to queued picks list",
chand_, this);
}
@ -3040,7 +3107,7 @@ void ClientChannel::LoadBalancedCall::PickDone(void* arg,
grpc_error_handle error) {
auto* self = static_cast<LoadBalancedCall*>(arg);
if (error != GRPC_ERROR_NONE) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: failed to pick subchannel: error=%s",
self->chand_, self, grpc_error_std_string(error).c_str());
@ -3090,7 +3157,7 @@ bool ClientChannel::LoadBalancedCall::PickSubchannelLocked(
// CompletePick
[this](LoadBalancingPolicy::PickResult::Complete* complete_pick)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: LB pick succeeded: subchannel=%p",
chand_, this, complete_pick->subchannel.get());
@ -3106,7 +3173,7 @@ bool ClientChannel::LoadBalancedCall::PickSubchannelLocked(
// yet seen that change and given us a new picker), then just
// queue the pick. We'll try again as soon as we get a new picker.
if (connected_subchannel_ == nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO,
"chand=%p lb_call=%p: subchannel returned by LB picker "
"has no connected subchannel; queueing pick",
@ -3126,7 +3193,7 @@ bool ClientChannel::LoadBalancedCall::PickSubchannelLocked(
// QueuePick
[this](LoadBalancingPolicy::PickResult::Queue* /*queue_pick*/)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: LB pick queued", chand_,
this);
}
@ -3137,7 +3204,7 @@ bool ClientChannel::LoadBalancedCall::PickSubchannelLocked(
[this, send_initial_metadata_flags,
&error](LoadBalancingPolicy::PickResult::Fail* fail_pick)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: LB pick failed: %s",
chand_, this, fail_pick->status.ToString().c_str());
}
@ -3161,7 +3228,7 @@ bool ClientChannel::LoadBalancedCall::PickSubchannelLocked(
// DropPick
[this, &error](LoadBalancingPolicy::PickResult::Drop* drop_pick)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&ClientChannel::data_plane_mu_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_routing_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_client_channel_lb_call_trace)) {
gpr_log(GPR_INFO, "chand=%p lb_call=%p: LB pick dropped: %s",
chand_, this, drop_pick->status.ToString().c_str());
}

@ -433,6 +433,8 @@ class ClientChannel::LoadBalancedCall
static void RecvMessageReady(void* arg, grpc_error_handle error);
static void RecvTrailingMetadataReady(void* arg, grpc_error_handle error);
void RecordCallCompletion(absl::Status status);
void CreateSubchannelCall();
// Invoked when a pick is completed, on both success or failure.
static void PickDone(void* arg, grpc_error_handle error);

@ -106,7 +106,6 @@ class PriorityLb : public LoadBalancingPolicy {
void ResetBackoffLocked();
void DeactivateLocked();
void MaybeReactivateLocked();
void MaybeCancelFailoverTimerLocked();
void Orphan() override;
@ -122,9 +121,7 @@ class PriorityLb : public LoadBalancingPolicy {
return connectivity_status_;
}
bool failover_timer_callback_pending() const {
return failover_timer_callback_pending_;
}
bool FailoverTimerPending() const { return failover_timer_ != nullptr; }
private:
// A simple wrapper for ref-counting a picker from the child policy.
@ -170,6 +167,38 @@ class PriorityLb : public LoadBalancingPolicy {
RefCountedPtr<ChildPriority> priority_;
};
class DeactivationTimer : public InternallyRefCounted<DeactivationTimer> {
public:
explicit DeactivationTimer(RefCountedPtr<ChildPriority> child_priority);
void Orphan() override;
private:
static void OnTimer(void* arg, grpc_error_handle error);
void OnTimerLocked(grpc_error_handle);
RefCountedPtr<ChildPriority> child_priority_;
grpc_timer timer_;
grpc_closure on_timer_;
bool timer_pending_ = true;
};
class FailoverTimer : public InternallyRefCounted<FailoverTimer> {
public:
explicit FailoverTimer(RefCountedPtr<ChildPriority> child_priority);
void Orphan() override;
private:
static void OnTimer(void* arg, grpc_error_handle error);
void OnTimerLocked(grpc_error_handle);
RefCountedPtr<ChildPriority> child_priority_;
grpc_timer timer_;
grpc_closure on_timer_;
bool timer_pending_ = true;
};
// Methods for dealing with the child policy.
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const grpc_channel_args* args);
@ -178,13 +207,6 @@ class PriorityLb : public LoadBalancingPolicy {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker);
void StartFailoverTimerLocked();
static void OnFailoverTimer(void* arg, grpc_error_handle error);
void OnFailoverTimerLocked(grpc_error_handle error);
static void OnDeactivationTimer(void* arg, grpc_error_handle error);
void OnDeactivationTimerLocked(grpc_error_handle error);
RefCountedPtr<PriorityLb> priority_policy_;
const std::string name_;
bool ignore_reresolution_requests_ = false;
@ -195,15 +217,8 @@ class PriorityLb : public LoadBalancingPolicy {
absl::Status connectivity_status_;
RefCountedPtr<RefCountedPicker> picker_wrapper_;
// States for delayed removal.
grpc_timer deactivation_timer_;
grpc_closure on_deactivation_timer_;
bool deactivation_timer_callback_pending_ = false;
// States of failover.
grpc_timer failover_timer_;
grpc_closure on_failover_timer_;
bool failover_timer_callback_pending_ = false;
OrphanablePtr<DeactivationTimer> deactivation_timer_;
OrphanablePtr<FailoverTimer> failover_timer_;
};
~PriorityLb() override;
@ -451,7 +466,7 @@ void PriorityLb::TryNextPriorityLocked(bool report_connecting) {
}
// Child is not READY or IDLE.
// If its failover timer is still pending, give it time to fire.
if (child->failover_timer_callback_pending()) {
if (child->FailoverTimerPending()) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] priority %u, child %s: child still "
@ -501,6 +516,132 @@ void PriorityLb::SelectPriorityLocked(uint32_t priority) {
child->GetPicker());
}
//
// PriorityLb::ChildPriority::DeactivationTimer
//
PriorityLb::ChildPriority::DeactivationTimer::DeactivationTimer(
RefCountedPtr<PriorityLb::ChildPriority> child_priority)
: child_priority_(std::move(child_priority)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): deactivating -- will remove in "
"%" PRId64 "ms",
child_priority_->priority_policy_.get(),
child_priority_->name_.c_str(), child_priority_.get(),
kChildRetentionInterval.millis());
}
GRPC_CLOSURE_INIT(&on_timer_, OnTimer, this, nullptr);
Ref(DEBUG_LOCATION, "Timer").release();
grpc_timer_init(&timer_, ExecCtx::Get()->Now() + kChildRetentionInterval,
&on_timer_);
}
void PriorityLb::ChildPriority::DeactivationTimer::Orphan() {
if (timer_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO, "[priority_lb %p] child %s (%p): reactivating",
child_priority_->priority_policy_.get(),
child_priority_->name_.c_str(), child_priority_.get());
}
timer_pending_ = false;
grpc_timer_cancel(&timer_);
}
Unref();
}
void PriorityLb::ChildPriority::DeactivationTimer::OnTimer(
void* arg, grpc_error_handle error) {
auto* self = static_cast<DeactivationTimer*>(arg);
(void)GRPC_ERROR_REF(error); // ref owned by lambda
self->child_priority_->priority_policy_->work_serializer()->Run(
[self, error]() { self->OnTimerLocked(error); }, DEBUG_LOCATION);
}
void PriorityLb::ChildPriority::DeactivationTimer::OnTimerLocked(
grpc_error_handle error) {
if (error == GRPC_ERROR_NONE && timer_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): deactivation timer fired, "
"deleting child",
child_priority_->priority_policy_.get(),
child_priority_->name_.c_str(), child_priority_.get());
}
timer_pending_ = false;
child_priority_->priority_policy_->DeleteChild(child_priority_.get());
}
Unref(DEBUG_LOCATION, "Timer");
GRPC_ERROR_UNREF(error);
}
//
// PriorityLb::ChildPriority::FailoverTimer
//
PriorityLb::ChildPriority::FailoverTimer::FailoverTimer(
RefCountedPtr<PriorityLb::ChildPriority> child_priority)
: child_priority_(std::move(child_priority)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(
GPR_INFO,
"[priority_lb %p] child %s (%p): starting failover timer for %" PRId64
"ms",
child_priority_->priority_policy_.get(), child_priority_->name_.c_str(),
child_priority_.get(),
child_priority_->priority_policy_->child_failover_timeout_.millis());
}
GRPC_CLOSURE_INIT(&on_timer_, OnTimer, this, nullptr);
Ref(DEBUG_LOCATION, "Timer").release();
grpc_timer_init(
&timer_,
ExecCtx::Get()->Now() +
child_priority_->priority_policy_->child_failover_timeout_,
&on_timer_);
}
void PriorityLb::ChildPriority::FailoverTimer::Orphan() {
if (timer_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): cancelling failover timer",
child_priority_->priority_policy_.get(),
child_priority_->name_.c_str(), child_priority_.get());
}
timer_pending_ = false;
grpc_timer_cancel(&timer_);
}
Unref();
}
void PriorityLb::ChildPriority::FailoverTimer::OnTimer(
void* arg, grpc_error_handle error) {
auto* self = static_cast<FailoverTimer*>(arg);
(void)GRPC_ERROR_REF(error); // ref owned by lambda
self->child_priority_->priority_policy_->work_serializer()->Run(
[self, error]() { self->OnTimerLocked(error); }, DEBUG_LOCATION);
}
void PriorityLb::ChildPriority::FailoverTimer::OnTimerLocked(
grpc_error_handle error) {
if (error == GRPC_ERROR_NONE && timer_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): failover timer fired, "
"reporting TRANSIENT_FAILURE",
child_priority_->priority_policy_.get(),
child_priority_->name_.c_str(), child_priority_.get());
}
timer_pending_ = false;
child_priority_->OnConnectivityStateUpdateLocked(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::Status(absl::StatusCode::kUnavailable, "failover timer fired"),
nullptr);
}
Unref(DEBUG_LOCATION, "Timer");
GRPC_ERROR_UNREF(error);
}
//
// PriorityLb::ChildPriority
//
@ -512,12 +653,8 @@ PriorityLb::ChildPriority::ChildPriority(
gpr_log(GPR_INFO, "[priority_lb %p] creating child %s (%p)",
priority_policy_.get(), name_.c_str(), this);
}
GRPC_CLOSURE_INIT(&on_failover_timer_, OnFailoverTimer, this,
grpc_schedule_on_exec_ctx);
GRPC_CLOSURE_INIT(&on_deactivation_timer_, OnDeactivationTimer, this,
grpc_schedule_on_exec_ctx);
// Start the failover timer.
StartFailoverTimerLocked();
failover_timer_ = MakeOrphanable<FailoverTimer>(Ref());
}
void PriorityLb::ChildPriority::Orphan() {
@ -525,10 +662,8 @@ void PriorityLb::ChildPriority::Orphan() {
gpr_log(GPR_INFO, "[priority_lb %p] child %s (%p): orphaned",
priority_policy_.get(), name_.c_str(), this);
}
MaybeCancelFailoverTimerLocked();
if (deactivation_timer_callback_pending_) {
grpc_timer_cancel(&deactivation_timer_);
}
failover_timer_.reset();
deactivation_timer_.reset();
// Remove the child policy's interested_parties pollset_set from the
// xDS policy.
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
@ -537,9 +672,6 @@ void PriorityLb::ChildPriority::Orphan() {
// Drop our ref to the child's picker, in case it's holding a ref to
// the child.
picker_wrapper_.reset();
if (deactivation_timer_callback_pending_) {
grpc_timer_cancel(&deactivation_timer_);
}
Unref(DEBUG_LOCATION, "ChildPriority+Orphan");
}
@ -600,9 +732,8 @@ PriorityLb::ChildPriority::CreateChildPolicyLocked(
}
void PriorityLb::ChildPriority::ExitIdleLocked() {
if (connectivity_state_ == GRPC_CHANNEL_IDLE &&
!failover_timer_callback_pending_) {
StartFailoverTimerLocked();
if (connectivity_state_ == GRPC_CHANNEL_IDLE && failover_timer_ == nullptr) {
failover_timer_ = MakeOrphanable<FailoverTimer>(Ref());
}
child_policy_->ExitIdleLocked();
}
@ -628,122 +759,21 @@ void PriorityLb::ChildPriority::OnConnectivityStateUpdateLocked(
// If READY or IDLE or TRANSIENT_FAILURE, cancel failover timer.
if (state == GRPC_CHANNEL_READY || state == GRPC_CHANNEL_IDLE ||
state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
MaybeCancelFailoverTimerLocked();
failover_timer_.reset();
}
// Notify the parent policy.
priority_policy_->HandleChildConnectivityStateChangeLocked(this);
}
void PriorityLb::ChildPriority::StartFailoverTimerLocked() {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(
GPR_INFO,
"[priority_lb %p] child %s (%p): starting failover timer for %" PRId64
"ms",
priority_policy_.get(), name_.c_str(), this,
priority_policy_->child_failover_timeout_.millis());
}
Ref(DEBUG_LOCATION, "ChildPriority+OnFailoverTimerLocked").release();
grpc_timer_init(
&failover_timer_,
ExecCtx::Get()->Now() + priority_policy_->child_failover_timeout_,
&on_failover_timer_);
failover_timer_callback_pending_ = true;
}
void PriorityLb::ChildPriority::MaybeCancelFailoverTimerLocked() {
if (failover_timer_callback_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): cancelling failover timer",
priority_policy_.get(), name_.c_str(), this);
}
grpc_timer_cancel(&failover_timer_);
failover_timer_callback_pending_ = false;
}
}
void PriorityLb::ChildPriority::OnFailoverTimer(void* arg,
grpc_error_handle error) {
ChildPriority* self = static_cast<ChildPriority*>(arg);
(void)GRPC_ERROR_REF(error); // ref owned by lambda
self->priority_policy_->work_serializer()->Run(
[self, error]() { self->OnFailoverTimerLocked(error); }, DEBUG_LOCATION);
}
void PriorityLb::ChildPriority::OnFailoverTimerLocked(grpc_error_handle error) {
if (error == GRPC_ERROR_NONE && failover_timer_callback_pending_ &&
!priority_policy_->shutting_down_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): failover timer fired, "
"reporting TRANSIENT_FAILURE",
priority_policy_.get(), name_.c_str(), this);
}
failover_timer_callback_pending_ = false;
OnConnectivityStateUpdateLocked(
GRPC_CHANNEL_TRANSIENT_FAILURE,
absl::Status(absl::StatusCode::kUnavailable, "failover timer fired"),
nullptr);
}
Unref(DEBUG_LOCATION, "ChildPriority+OnFailoverTimerLocked");
GRPC_ERROR_UNREF(error);
}
void PriorityLb::ChildPriority::DeactivateLocked() {
// If already deactivated, don't do it again.
if (deactivation_timer_callback_pending_) return;
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): deactivating -- will remove in "
"%" PRId64 "ms.",
priority_policy_.get(), name_.c_str(), this,
kChildRetentionInterval.millis());
}
MaybeCancelFailoverTimerLocked();
// Start a timer to delete the child.
Ref(DEBUG_LOCATION, "ChildPriority+timer").release();
grpc_timer_init(&deactivation_timer_,
ExecCtx::Get()->Now() + kChildRetentionInterval,
&on_deactivation_timer_);
deactivation_timer_callback_pending_ = true;
if (deactivation_timer_ != nullptr) return;
failover_timer_.reset();
deactivation_timer_ = MakeOrphanable<DeactivationTimer>(Ref());
}
void PriorityLb::ChildPriority::MaybeReactivateLocked() {
if (deactivation_timer_callback_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO, "[priority_lb %p] child %s (%p): reactivating",
priority_policy_.get(), name_.c_str(), this);
}
deactivation_timer_callback_pending_ = false;
grpc_timer_cancel(&deactivation_timer_);
}
}
void PriorityLb::ChildPriority::OnDeactivationTimer(void* arg,
grpc_error_handle error) {
ChildPriority* self = static_cast<ChildPriority*>(arg);
(void)GRPC_ERROR_REF(error); // ref owned by lambda
self->priority_policy_->work_serializer()->Run(
[self, error]() { self->OnDeactivationTimerLocked(error); },
DEBUG_LOCATION);
}
void PriorityLb::ChildPriority::OnDeactivationTimerLocked(
grpc_error_handle error) {
if (error == GRPC_ERROR_NONE && deactivation_timer_callback_pending_ &&
!priority_policy_->shutting_down_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_priority_trace)) {
gpr_log(GPR_INFO,
"[priority_lb %p] child %s (%p): deactivation timer fired, "
"deleting child",
priority_policy_.get(), name_.c_str(), this);
}
deactivation_timer_callback_pending_ = false;
priority_policy_->DeleteChild(this);
}
Unref(DEBUG_LOCATION, "ChildPriority+timer");
GRPC_ERROR_UNREF(error);
deactivation_timer_.reset();
}
//

@ -83,7 +83,7 @@ TraceFlag grpc_lb_rls_trace(false, "rls_lb");
namespace {
const char* kRls = "rls";
const char* kRls = "rls_experimental";
const char kGrpc[] = "grpc";
const char* kRlsRequestPath = "/grpc.lookup.v1.RouteLookupService/RouteLookup";
const char* kFakeTargetFieldValue = "fake_target_field_value";
@ -2530,18 +2530,9 @@ class RlsLbFactory : public LoadBalancingPolicyFactory {
}
};
bool RlsEnabled() {
char* value = gpr_getenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY");
bool parsed_value;
bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value);
gpr_free(value);
return parse_succeeded && parsed_value;
}
} // namespace
void RlsLbPluginInit() {
if (!RlsEnabled()) return;
LoadBalancingPolicyRegistry::Builder::RegisterLoadBalancingPolicyFactory(
absl::make_unique<RlsLbFactory>());
}

@ -158,6 +158,23 @@ class WeightedTargetLb : public LoadBalancingPolicy {
RefCountedPtr<WeightedChild> weighted_child_;
};
class DelayedRemovalTimer
: public InternallyRefCounted<DelayedRemovalTimer> {
public:
explicit DelayedRemovalTimer(RefCountedPtr<WeightedChild> weighted_child);
void Orphan() override;
private:
static void OnTimer(void* arg, grpc_error_handle error);
void OnTimerLocked(grpc_error_handle error);
RefCountedPtr<WeightedChild> weighted_child_;
grpc_timer timer_;
grpc_closure on_timer_;
bool timer_pending_ = true;
};
// Methods for dealing with the child policy.
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const grpc_channel_args* args);
@ -166,9 +183,6 @@ class WeightedTargetLb : public LoadBalancingPolicy {
grpc_connectivity_state state, const absl::Status& status,
std::unique_ptr<SubchannelPicker> picker);
static void OnDelayedRemovalTimer(void* arg, grpc_error_handle error);
void OnDelayedRemovalTimerLocked(grpc_error_handle error);
// The owning LB policy.
RefCountedPtr<WeightedTargetLb> weighted_target_policy_;
@ -182,11 +196,7 @@ class WeightedTargetLb : public LoadBalancingPolicy {
grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_CONNECTING;
bool seen_failure_since_ready_ = false;
// States for delayed removal.
grpc_timer delayed_removal_timer_;
grpc_closure on_delayed_removal_timer_;
bool delayed_removal_timer_callback_pending_ = false;
bool shutdown_ = false;
OrphanablePtr<DelayedRemovalTimer> delayed_removal_timer_;
};
~WeightedTargetLb() override;
@ -401,6 +411,53 @@ void WeightedTargetLb::UpdateStateLocked() {
std::move(picker));
}
//
// WeightedTargetLb::WeightedChild::DelayedRemovalTimer
//
WeightedTargetLb::WeightedChild::DelayedRemovalTimer::DelayedRemovalTimer(
RefCountedPtr<WeightedTargetLb::WeightedChild> weighted_child)
: weighted_child_(std::move(weighted_child)) {
GRPC_CLOSURE_INIT(&on_timer_, OnTimer, this, nullptr);
Ref().release();
grpc_timer_init(&timer_, ExecCtx::Get()->Now() + kChildRetentionInterval,
&on_timer_);
}
void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::Orphan() {
if (timer_pending_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_weighted_target_trace)) {
gpr_log(GPR_INFO,
"[weighted_target_lb %p] WeightedChild %p %s: cancelling "
"delayed removal timer",
weighted_child_->weighted_target_policy_.get(),
weighted_child_.get(), weighted_child_->name_.c_str());
}
timer_pending_ = false;
grpc_timer_cancel(&timer_);
}
Unref();
}
void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::OnTimer(
void* arg, grpc_error_handle error) {
auto* self = static_cast<DelayedRemovalTimer*>(arg);
(void)GRPC_ERROR_REF(error); // ref owned by lambda
self->weighted_child_->weighted_target_policy_->work_serializer()->Run(
[self, error]() { self->OnTimerLocked(error); }, DEBUG_LOCATION);
}
void WeightedTargetLb::WeightedChild::DelayedRemovalTimer::OnTimerLocked(
grpc_error_handle error) {
if (error == GRPC_ERROR_NONE && timer_pending_) {
timer_pending_ = false;
weighted_child_->weighted_target_policy_->targets_.erase(
weighted_child_->name_);
}
GRPC_ERROR_UNREF(error);
Unref();
}
//
// WeightedTargetLb::WeightedChild
//
@ -413,8 +470,6 @@ WeightedTargetLb::WeightedChild::WeightedChild(
gpr_log(GPR_INFO, "[weighted_target_lb %p] created WeightedChild %p for %s",
weighted_target_policy_.get(), this, name_.c_str());
}
GRPC_CLOSURE_INIT(&on_delayed_removal_timer_, OnDelayedRemovalTimer, this,
grpc_schedule_on_exec_ctx);
}
WeightedTargetLb::WeightedChild::~WeightedChild() {
@ -441,11 +496,7 @@ void WeightedTargetLb::WeightedChild::Orphan() {
// Drop our ref to the child's picker, in case it's holding a ref to
// the child.
picker_wrapper_.reset();
if (delayed_removal_timer_callback_pending_) {
delayed_removal_timer_callback_pending_ = false;
grpc_timer_cancel(&delayed_removal_timer_);
}
shutdown_ = true;
delayed_removal_timer_.reset();
Unref();
}
@ -484,14 +535,13 @@ void WeightedTargetLb::WeightedChild::UpdateLocked(
// Update child weight.
weight_ = config.weight;
// Reactivate if needed.
if (delayed_removal_timer_callback_pending_) {
if (delayed_removal_timer_ != nullptr) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_weighted_target_trace)) {
gpr_log(GPR_INFO,
"[weighted_target_lb %p] WeightedChild %p %s: reactivating",
weighted_target_policy_.get(), this, name_.c_str());
}
delayed_removal_timer_callback_pending_ = false;
grpc_timer_cancel(&delayed_removal_timer_);
delayed_removal_timer_.reset();
}
// Create child policy if needed.
if (child_policy_ == nullptr) {
@ -561,31 +611,8 @@ void WeightedTargetLb::WeightedChild::DeactivateLocked() {
// Set the child weight to 0 so that future picker won't contain this child.
weight_ = 0;
// Start a timer to delete the child.
Ref(DEBUG_LOCATION, "WeightedChild+timer").release();
delayed_removal_timer_callback_pending_ = true;
grpc_timer_init(&delayed_removal_timer_,
ExecCtx::Get()->Now() + kChildRetentionInterval,
&on_delayed_removal_timer_);
}
void WeightedTargetLb::WeightedChild::OnDelayedRemovalTimer(
void* arg, grpc_error_handle error) {
WeightedChild* self = static_cast<WeightedChild*>(arg);
(void)GRPC_ERROR_REF(error); // ref owned by lambda
self->weighted_target_policy_->work_serializer()->Run(
[self, error]() { self->OnDelayedRemovalTimerLocked(error); },
DEBUG_LOCATION);
}
void WeightedTargetLb::WeightedChild::OnDelayedRemovalTimerLocked(
grpc_error_handle error) {
if (error == GRPC_ERROR_NONE && delayed_removal_timer_callback_pending_ &&
!shutdown_ && weight_ == 0) {
delayed_removal_timer_callback_pending_ = false;
weighted_target_policy_->targets_.erase(name_);
}
Unref(DEBUG_LOCATION, "WeightedChild+timer");
GRPC_ERROR_UNREF(error);
delayed_removal_timer_ = MakeOrphanable<DelayedRemovalTimer>(
Ref(DEBUG_LOCATION, "DelayedRemovalTimer"));
}
//

@ -131,24 +131,14 @@ class XdsClusterResolverLb : public LoadBalancingPolicy {
RefCountedPtr<XdsClusterResolverLb> xds_cluster_resolver_lb,
size_t index)
: parent_(std::move(xds_cluster_resolver_lb)), index_(index) {}
virtual void Start() = 0;
void Orphan() override = 0;
virtual Json::Array override_child_policy() = 0;
virtual bool disable_reresolution() = 0;
// Returns a pair containing the cluster and eds_service_name
// to use for LRS load reporting. Caller must ensure that config_ is set
// before calling.
std::pair<absl::string_view, absl::string_view> GetLrsClusterKey() const {
return {
parent_->config_->discovery_mechanisms()[index_].cluster_name,
parent_->config_->discovery_mechanisms()[index_].eds_service_name};
}
protected:
XdsClusterResolverLb* parent() const { return parent_.get(); }
size_t index() const { return index_; }
virtual void Start() = 0;
virtual Json::Array override_child_policy() = 0;
virtual bool disable_reresolution() = 0;
private:
RefCountedPtr<XdsClusterResolverLb> parent_;
// Stores its own index in the vector of DiscoveryMechanism.
@ -229,14 +219,9 @@ class XdsClusterResolverLb : public LoadBalancingPolicy {
friend class EndpointWatcher;
absl::string_view GetEdsResourceName() const {
if (!parent()
->config_->discovery_mechanisms()[index()]
.eds_service_name.empty()) {
return parent()
->config_->discovery_mechanisms()[index()]
.eds_service_name;
}
return parent()->config_->discovery_mechanisms()[index()].cluster_name;
auto& config = parent()->config_->discovery_mechanisms()[index()];
if (!config.eds_service_name.empty()) return config.eds_service_name;
return config.cluster_name;
}
// Note that this is not owned, so this pointer must never be dereferenced.
@ -284,15 +269,15 @@ class XdsClusterResolverLb : public LoadBalancingPolicy {
struct DiscoveryMechanismEntry {
OrphanablePtr<DiscoveryMechanism> discovery_mechanism;
bool first_update_received = false;
// Number of priorities this mechanism has contributed to priority_list_.
// (The sum of this across all discovery mechanisms should always equal
// the number of priorities in priority_list_.)
uint32_t num_priorities = 0;
RefCountedPtr<XdsEndpointResource::DropConfig> drop_config;
// Populated only when an update has been delivered by the mechanism
// but has not yet been applied to the LB policy's combined priority_list_.
absl::optional<XdsEndpointResource::PriorityList> pending_priority_list;
// Most recent update reported by the discovery mechanism.
absl::optional<XdsEndpointResource> latest_update;
// State used to retain child policy names for priority policy.
std::vector<size_t /*child_number*/> priority_child_numbers;
const XdsClusterResolverLbConfig::DiscoveryMechanism& config() const;
// Returns the child policy name for a given priority.
std::string GetChildPolicyName(size_t priority) const;
};
class Helper : public ChannelControlHelper {
@ -331,7 +316,6 @@ class XdsClusterResolverLb : public LoadBalancingPolicy {
void MaybeDestroyChildPolicyLocked();
void UpdatePriorityList(XdsEndpointResource::PriorityList priority_list);
void UpdateChildPolicyLocked();
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
const grpc_channel_args* args);
@ -353,11 +337,6 @@ class XdsClusterResolverLb : public LoadBalancingPolicy {
// Vector of discovery mechansism entries in priority order.
std::vector<DiscoveryMechanismEntry> discovery_mechanisms_;
// The latest data from the endpoint watcher.
XdsEndpointResource::PriorityList priority_list_;
// State used to retain child policy names for priority policy.
std::vector<size_t /*child_number*/> priority_child_numbers_;
OrphanablePtr<LoadBalancingPolicy> child_policy_;
};
@ -510,6 +489,22 @@ void XdsClusterResolverLb::LogicalDNSDiscoveryMechanism::ResolverResultHandler::
discovery_mechanism_->index(), std::move(update));
}
//
// XdsClusterResolverLb::DiscoveryMechanismEntry
//
const XdsClusterResolverLbConfig::DiscoveryMechanism&
XdsClusterResolverLb::DiscoveryMechanismEntry::config() const {
return discovery_mechanism->parent()
->config_->discovery_mechanisms()[discovery_mechanism->index()];
}
std::string XdsClusterResolverLb::DiscoveryMechanismEntry::GetChildPolicyName(
size_t priority) const {
return absl::StrCat("{cluster=", config().cluster_name,
", child_number=", priority_child_numbers[priority], "}");
}
//
// XdsClusterResolverLb public methods
//
@ -613,99 +608,37 @@ void XdsClusterResolverLb::OnEndpointChanged(size_t index,
" for discovery mechanism %" PRIuPTR "",
this, index);
}
DiscoveryMechanismEntry& discovery_entry = discovery_mechanisms_[index];
// We need at least one priority for each discovery mechanism, just so that we
// have a child in which to create the xds_cluster_impl policy. This ensures
// that we properly handle the case of a discovery mechanism dropping 100% of
// calls, the OnError() case, and the OnResourceDoesNotExist() case.
if (update.priorities.empty()) update.priorities.emplace_back();
discovery_mechanisms_[index].drop_config = std::move(update.drop_config);
discovery_mechanisms_[index].pending_priority_list =
std::move(update.priorities);
discovery_mechanisms_[index].first_update_received = true;
// If any discovery mechanism has not received its first update,
// wait until that happens before creating the child policy.
// TODO(roth): If this becomes problematic in the future (e.g., a
// secondary discovery mechanism delaying us from starting up at all),
// we can consider some sort of optimization whereby we can create the
// priority policy with only a subset of its children. But we need to
// make sure not to get into a situation where the priority policy
// will put the channel into TRANSIENT_FAILURE instead of CONNECTING
// while we're still waiting for the other discovery mechanism(s).
for (DiscoveryMechanismEntry& mechanism : discovery_mechanisms_) {
if (!mechanism.first_update_received) return;
}
// Construct new priority list.
XdsEndpointResource::PriorityList priority_list;
size_t priority_index = 0;
for (DiscoveryMechanismEntry& mechanism : discovery_mechanisms_) {
// If the mechanism has a pending update, use that.
// Otherwise, use the priorities that it previously contributed to the
// combined list.
if (mechanism.pending_priority_list.has_value()) {
priority_list.insert(priority_list.end(),
mechanism.pending_priority_list->begin(),
mechanism.pending_priority_list->end());
priority_index += mechanism.num_priorities;
mechanism.num_priorities = mechanism.pending_priority_list->size();
mechanism.pending_priority_list.reset();
} else {
priority_list.insert(
priority_list.end(), priority_list_.begin() + priority_index,
priority_list_.begin() + priority_index + mechanism.num_priorities);
priority_index += mechanism.num_priorities;
}
}
// Update child policy.
UpdatePriorityList(std::move(priority_list));
}
void XdsClusterResolverLb::OnError(size_t index, absl::Status status) {
gpr_log(GPR_ERROR,
"[xds_cluster_resolver_lb %p] discovery mechanism %" PRIuPTR
" xds watcher reported error: %s",
this, index, status.ToString().c_str());
if (shutting_down_) return;
if (!discovery_mechanisms_[index].first_update_received) {
// Call OnEndpointChanged with an empty update just like
// OnResourceDoesNotExist.
OnEndpointChanged(index, XdsEndpointResource());
}
}
void XdsClusterResolverLb::OnResourceDoesNotExist(size_t index) {
gpr_log(GPR_ERROR,
"[xds_cluster_resolver_lb %p] discovery mechanism %" PRIuPTR
" resource does not exist",
this, index);
if (shutting_down_) return;
// Call OnEndpointChanged with an empty update.
OnEndpointChanged(index, XdsEndpointResource());
}
//
// child policy-related methods
//
void XdsClusterResolverLb::UpdatePriorityList(
XdsEndpointResource::PriorityList priority_list) {
// Build some maps from locality to child number and the reverse from
// the old data in priority_list_ and priority_child_numbers_.
// Update priority_child_numbers, reusing old child numbers in an
// intelligent way to avoid unnecessary churn.
// First, build some maps from locality to child number and the reverse
// from the old data in the entry's update and priority_child_numbers.
std::map<XdsLocalityName*, size_t /*child_number*/, XdsLocalityName::Less>
locality_child_map;
std::map<size_t, std::set<XdsLocalityName*>> child_locality_map;
for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
size_t child_number = priority_child_numbers_[priority];
const auto& localities = priority_list_[priority].localities;
std::map<size_t, std::set<XdsLocalityName*, XdsLocalityName::Less>>
child_locality_map;
if (discovery_entry.latest_update.has_value()) {
const auto& prev_priority_list = discovery_entry.latest_update->priorities;
for (size_t priority = 0; priority < prev_priority_list.size();
++priority) {
size_t child_number = discovery_entry.priority_child_numbers[priority];
const auto& localities = prev_priority_list[priority].localities;
for (const auto& p : localities) {
XdsLocalityName* locality_name = p.first;
locality_child_map[locality_name] = child_number;
child_locality_map[child_number].insert(locality_name);
}
}
}
// Construct new list of children.
std::vector<size_t> priority_child_numbers;
for (size_t priority = 0; priority < priority_list.size(); ++priority) {
const auto& localities = priority_list[priority].localities;
for (size_t priority = 0; priority < update.priorities.size(); ++priority) {
const auto& localities = update.priorities[priority].localities;
absl::optional<size_t> child_number;
// If one of the localities in this priority already existed, reuse its
// child number.
@ -744,19 +677,62 @@ void XdsClusterResolverLb::UpdatePriorityList(
priority_child_numbers.push_back(*child_number);
}
// Save update.
priority_list_ = std::move(priority_list);
priority_child_numbers_ = std::move(priority_child_numbers);
discovery_entry.latest_update = std::move(update);
discovery_entry.priority_child_numbers = std::move(priority_child_numbers);
// If any discovery mechanism has not received its first update,
// wait until that happens before creating the child policy.
// TODO(roth): If this becomes problematic in the future (e.g., a
// secondary discovery mechanism delaying us from starting up at all),
// we can consider some sort of optimization whereby we can create the
// priority policy with only a subset of its children. But we need to
// make sure not to get into a situation where the priority policy
// will put the channel into TRANSIENT_FAILURE instead of CONNECTING
// while we're still waiting for the other discovery mechanism(s).
for (DiscoveryMechanismEntry& mechanism : discovery_mechanisms_) {
if (!mechanism.latest_update.has_value()) return;
}
// Update child policy.
UpdateChildPolicyLocked();
}
void XdsClusterResolverLb::OnError(size_t index, absl::Status status) {
gpr_log(GPR_ERROR,
"[xds_cluster_resolver_lb %p] discovery mechanism %" PRIuPTR
" xds watcher reported error: %s",
this, index, status.ToString().c_str());
if (shutting_down_) return;
if (!discovery_mechanisms_[index].latest_update.has_value()) {
// Call OnEndpointChanged with an empty update just like
// OnResourceDoesNotExist.
OnEndpointChanged(index, XdsEndpointResource());
}
}
void XdsClusterResolverLb::OnResourceDoesNotExist(size_t index) {
gpr_log(GPR_ERROR,
"[xds_cluster_resolver_lb %p] discovery mechanism %" PRIuPTR
" resource does not exist",
this, index);
if (shutting_down_) return;
// Call OnEndpointChanged with an empty update.
OnEndpointChanged(index, XdsEndpointResource());
}
//
// child policy-related methods
//
ServerAddressList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
ServerAddressList addresses;
for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
const auto& localities = priority_list_[priority].localities;
for (const auto& discovery_entry : discovery_mechanisms_) {
for (size_t priority = 0;
priority < discovery_entry.latest_update->priorities.size();
++priority) {
const auto& priority_entry =
discovery_entry.latest_update->priorities[priority];
std::string priority_child_name =
absl::StrCat("child", priority_child_numbers_[priority]);
for (const auto& p : localities) {
discovery_entry.GetChildPolicyName(priority);
for (const auto& p : priority_entry.localities) {
const auto& locality_name = p.first;
const auto& locality = p.second;
std::vector<std::string> hierarchical_path = {
@ -771,7 +747,8 @@ ServerAddressList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
}
addresses.emplace_back(
endpoint
.WithAttribute(kHierarchicalPathAttributeKey,
.WithAttribute(
kHierarchicalPathAttributeKey,
MakeHierarchicalPathAttribute(hierarchical_path))
.WithAttribute(kXdsLocalityNameAttributeKey,
absl::make_unique<XdsLocalityAttribute>(
@ -783,6 +760,7 @@ ServerAddressList XdsClusterResolverLb::CreateChildPolicyAddressesLocked() {
}
}
}
}
return addresses;
}
@ -790,39 +768,26 @@ RefCountedPtr<LoadBalancingPolicy::Config>
XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
Json::Object priority_children;
Json::Array priority_priorities;
// Setting up index to iterate through the discovery mechanisms and keeping
// track the discovery_mechanism each priority belongs to.
size_t discovery_index = 0;
// Setting up num_priorities_remaining to track the priorities in each
// discovery_mechanism.
size_t num_priorities_remaining_in_discovery =
discovery_mechanisms_[discovery_index].num_priorities;
for (size_t priority = 0; priority < priority_list_.size(); ++priority) {
for (const auto& discovery_entry : discovery_mechanisms_) {
const auto& discovery_config = discovery_entry.config();
for (size_t priority = 0;
priority < discovery_entry.latest_update->priorities.size();
++priority) {
const auto& priority_entry =
discovery_entry.latest_update->priorities[priority];
Json child_policy;
if (!discovery_mechanisms_[discovery_index]
.discovery_mechanism->override_child_policy()
if (!discovery_entry.discovery_mechanism->override_child_policy()
.empty()) {
child_policy = discovery_mechanisms_[discovery_index]
.discovery_mechanism->override_child_policy();
child_policy =
discovery_entry.discovery_mechanism->override_child_policy();
} else {
const auto& xds_lb_policy = config_->xds_lb_policy().object_value();
if (xds_lb_policy.find("ROUND_ROBIN") != xds_lb_policy.end()) {
const auto& localities = priority_list_[priority].localities;
const auto& localities = priority_entry.localities;
Json::Object weighted_targets;
for (const auto& p : localities) {
XdsLocalityName* locality_name = p.first;
const auto& locality = p.second;
// Construct JSON object containing locality name.
Json::Object locality_name_json;
if (!locality_name->region().empty()) {
locality_name_json["region"] = locality_name->region();
}
if (!locality_name->zone().empty()) {
locality_name_json["zone"] = locality_name->zone();
}
if (!locality_name->sub_zone().empty()) {
locality_name_json["sub_zone"] = locality_name->sub_zone();
}
// Add weighted target entry.
weighted_targets[locality_name->AsHumanReadableString()] =
Json::Object{
@ -849,11 +814,13 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
*(*child_policy.mutable_array())[0].mutable_object();
auto it = config.begin();
GPR_ASSERT(it != config.end());
(*it->second.mutable_object())["targets"] = std::move(weighted_targets);
(*it->second.mutable_object())["targets"] =
std::move(weighted_targets);
} else {
auto it = xds_lb_policy.find("RING_HASH");
GPR_ASSERT(it != xds_lb_policy.end());
Json::Object ring_hash_experimental_policy = it->second.object_value();
Json::Object ring_hash_experimental_policy =
it->second.object_value();
child_policy = Json::Array{
Json::Object{
{"ring_hash_experimental", ring_hash_experimental_policy},
@ -863,66 +830,44 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
}
// Wrap it in the drop policy.
Json::Array drop_categories;
if (discovery_mechanisms_[discovery_index].drop_config != nullptr) {
for (const auto& category : discovery_mechanisms_[discovery_index]
.drop_config->drop_category_list()) {
if (discovery_entry.latest_update->drop_config != nullptr) {
for (const auto& category :
discovery_entry.latest_update->drop_config->drop_category_list()) {
drop_categories.push_back(Json::Object{
{"category", category.name},
{"requests_per_million", category.parts_per_million},
});
}
}
const auto lrs_key = discovery_mechanisms_[discovery_index]
.discovery_mechanism->GetLrsClusterKey();
Json::Object xds_cluster_impl_config = {
{"clusterName", std::string(lrs_key.first)},
{"clusterName", discovery_config.cluster_name},
{"childPolicy", std::move(child_policy)},
{"dropCategories", std::move(drop_categories)},
{"maxConcurrentRequests",
config_->discovery_mechanisms()[discovery_index]
.max_concurrent_requests},
{"maxConcurrentRequests", discovery_config.max_concurrent_requests},
};
if (!lrs_key.second.empty()) {
xds_cluster_impl_config["edsServiceName"] = std::string(lrs_key.second);
if (!discovery_config.eds_service_name.empty()) {
xds_cluster_impl_config["edsServiceName"] =
discovery_config.eds_service_name;
}
if (config_->discovery_mechanisms()[discovery_index]
.lrs_load_reporting_server.has_value()) {
if (discovery_config.lrs_load_reporting_server.has_value()) {
xds_cluster_impl_config["lrsLoadReportingServer"] =
config_->discovery_mechanisms()[discovery_index]
.lrs_load_reporting_server->ToJson();
discovery_config.lrs_load_reporting_server->ToJson();
}
Json locality_picking_policy = Json::Array{Json::Object{
{"xds_cluster_impl_experimental", std::move(xds_cluster_impl_config)},
}};
// Add priority entry.
const size_t child_number = priority_child_numbers_[priority];
std::string child_name = absl::StrCat("child", child_number);
// Add priority entry, with the appropriate child name.
std::string child_name = discovery_entry.GetChildPolicyName(priority);
priority_priorities.emplace_back(child_name);
Json::Object child_config = {
{"config", std::move(locality_picking_policy)},
};
if (discovery_mechanisms_[discovery_index]
.discovery_mechanism->disable_reresolution()) {
if (discovery_entry.discovery_mechanism->disable_reresolution()) {
child_config["ignore_reresolution_requests"] = true;
}
priority_children[child_name] = std::move(child_config);
// Each priority in the priority_list_ should correspond to a priority in a
// discovery mechanism in discovery_mechanisms_ (both in the same order).
// Keeping track of the discovery_mechanism each priority belongs to.
--num_priorities_remaining_in_discovery;
while (num_priorities_remaining_in_discovery == 0 &&
discovery_index < discovery_mechanisms_.size() - 1) {
++discovery_index;
num_priorities_remaining_in_discovery =
discovery_mechanisms_[discovery_index].num_priorities;
}
}
// There should be matching number of priorities in discovery_mechanisms_ and
// in priority_list_; therefore at the end of looping through all the
// priorities, num_priorities_remaining should be down to 0, and index should
// be the last index in discovery_mechanisms_.
GPR_ASSERT(num_priorities_remaining_in_discovery == 0);
GPR_ASSERT(discovery_index == discovery_mechanisms_.size() - 1);
}
}
Json json = Json::Array{Json::Object{
{"priority_experimental",
Json::Object{

@ -330,6 +330,9 @@ class XdsResolver : public Resolver {
std::string route_config_name_;
RouteConfigWatcher* route_config_watcher_ = nullptr;
XdsRouteConfigResource::VirtualHost current_virtual_host_;
std::map<std::string /*cluster_specifier_plugin_name*/,
std::string /*LB policy config*/>
cluster_specifier_plugin_map_;
ClusterState::ClusterStateMap cluster_state_map_;
};
@ -416,13 +419,23 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
resolver_->current_listener_.http_connection_manager
.http_max_stream_duration;
}
if (route_action->weighted_clusters.empty()) {
if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::kClusterIndex) {
*error = CreateMethodConfig(route_entry.route, nullptr,
&route_entry.method_config);
MaybeAddCluster(route_action->cluster_name);
} else {
MaybeAddCluster(absl::StrCat(
"cluster:",
absl::get<
XdsRouteConfigResource::Route::RouteAction::kClusterIndex>(
route_action->action)));
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kWeightedClustersIndex) {
auto& action_weighted_clusters = absl::get<
XdsRouteConfigResource::Route::RouteAction::kWeightedClustersIndex>(
route_action->action);
uint32_t end = 0;
for (const auto& weighted_cluster : route_action->weighted_clusters) {
for (const auto& weighted_cluster : action_weighted_clusters) {
Route::ClusterWeightState cluster_weight_state;
*error = CreateMethodConfig(route_entry.route, &weighted_cluster,
&cluster_weight_state.method_config);
@ -432,8 +445,18 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
cluster_weight_state.cluster = weighted_cluster.name;
route_entry.weighted_cluster_state.push_back(
std::move(cluster_weight_state));
MaybeAddCluster(weighted_cluster.name);
MaybeAddCluster(absl::StrCat("cluster:", weighted_cluster.name));
}
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex) {
// cluster_specifier_plugin case:
*error = CreateMethodConfig(route_entry.route, nullptr,
&route_entry.method_config);
MaybeAddCluster(absl::StrCat(
"cluster_specifier_plugin:",
absl::get<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(route_action->action)));
}
}
}
@ -612,12 +635,18 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
return call_config;
}
absl::string_view cluster_name;
std::string cluster_name;
RefCountedPtr<ServiceConfig> method_config;
if (route_action->weighted_clusters.empty()) {
cluster_name = route_action->cluster_name;
if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::kClusterIndex) {
cluster_name = absl::StrCat(
"cluster:",
absl::get<XdsRouteConfigResource::Route::RouteAction::kClusterIndex>(
route_action->action));
method_config = entry.method_config;
} else {
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kWeightedClustersIndex) {
const uint32_t key =
rand() %
entry.weighted_cluster_state[entry.weighted_cluster_state.size() - 1]
@ -640,8 +669,17 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
}
if (index == 0) index = start_index;
GPR_ASSERT(entry.weighted_cluster_state[index].range_end > key);
cluster_name = entry.weighted_cluster_state[index].cluster;
cluster_name =
absl::StrCat("cluster:", entry.weighted_cluster_state[index].cluster);
method_config = entry.weighted_cluster_state[index].method_config;
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex) {
cluster_name = absl::StrCat(
"cluster_specifier_plugin:",
absl::get<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(route_action->action));
method_config = entry.method_config;
}
auto it = clusters_.find(cluster_name);
GPR_ASSERT(it != clusters_.end());
@ -863,6 +901,8 @@ void XdsResolver::OnRouteConfigUpdate(XdsRouteConfigResource rds_update) {
}
// Save the virtual host in the resolver.
current_virtual_host_ = std::move(rds_update.virtual_hosts[*vhost_index]);
cluster_specifier_plugin_map_ =
std::move(rds_update.cluster_specifier_plugin_map);
// Send a new result to the channel.
GenerateResult();
}
@ -900,6 +940,16 @@ absl::StatusOr<RefCountedPtr<ServiceConfig>>
XdsResolver::CreateServiceConfig() {
std::vector<std::string> clusters;
for (const auto& cluster : cluster_state_map_) {
absl::string_view child_name = cluster.first;
if (absl::ConsumePrefix(&child_name, "cluster_specifier_plugin:")) {
clusters.push_back(absl::StrFormat(
" \"%s\":{\n"
" \"childPolicy\": %s\n"
" }",
cluster.first,
cluster_specifier_plugin_map_[std::string(child_name)]));
} else {
absl::ConsumePrefix(&child_name, "cluster:");
clusters.push_back(
absl::StrFormat(" \"%s\":{\n"
" \"childPolicy\":[ {\n"
@ -908,7 +958,8 @@ XdsResolver::CreateServiceConfig() {
" }\n"
" } ]\n"
" }",
cluster.first, cluster.first));
cluster.first, child_name));
}
}
std::vector<std::string> config_parts;
config_parts.push_back(

@ -2163,7 +2163,8 @@ RetryFilter::CallData::~CallData() {
void RetryFilter::CallData::StartTransportStreamOpBatch(
grpc_transport_stream_op_batch* batch) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_retry_trace) &&
!GRPC_TRACE_FLAG_ENABLED(grpc_trace_channel)) {
gpr_log(GPR_INFO, "chand=%p calld=%p: batch started from surface: %s",
chand_, this, grpc_transport_stream_op_batch_string(batch).c_str());
}

@ -53,7 +53,7 @@ Java_io_grpc_binder_cpp_GrpcBinderConnection_notifyConnected__Ljava_lang_String_
namespace grpc_binder {
void EndpointBinderPool ::GetEndpointBinder(
void EndpointBinderPool::GetEndpointBinder(
std::string conn_id,
std::function<void(std::unique_ptr<grpc_binder::Binder>)> cb) {
gpr_log(GPR_INFO, "EndpointBinder requested. conn_id = %s", conn_id.c_str());

@ -24,6 +24,9 @@
#include <grpc/support/log.h>
#include "src/core/lib/gpr/tls.h"
#include "src/core/lib/gprpp/sync.h"
namespace {
void* GetNdkBinderHandle() {
// TODO(mingcl): Consider using RTLD_NOLOAD to check if it is already loaded
@ -37,6 +40,53 @@ void* GetNdkBinderHandle() {
}
return handle;
}
JavaVM* g_jvm = nullptr;
grpc_core::Mutex g_jvm_mu;
// Whether the thread has already attached to JVM (this is to prevent
// repeated attachment in `AttachJvm()`)
GPR_THREAD_LOCAL(bool) g_is_jvm_attached = false;
void SetJvm(JNIEnv* env) {
// OK to lock here since this function will only be called once for each
// connection.
grpc_core::MutexLock lock(&g_jvm_mu);
if (g_jvm != nullptr) {
return;
}
JavaVM* jvm = nullptr;
jint error = env->GetJavaVM(&jvm);
if (error != JNI_OK) {
gpr_log(GPR_ERROR, "Failed to get JVM");
}
g_jvm = jvm;
gpr_log(GPR_INFO, "JVM cached");
}
// `SetJvm` need to be called in the process before `AttachJvm`. This is always
// the case because one of `AIBinder_fromJavaBinder`/`AIBinder_toJavaBinder`
// will be called before we actually uses the binder. Return `false` if not able
// to attach to JVM. Return `true` if JVM is attached (or already attached).
bool AttachJvm() {
if (g_is_jvm_attached) {
return true;
}
// Note: The following code would be run at most once per thread.
grpc_core::MutexLock lock(&g_jvm_mu);
if (g_jvm == nullptr) {
gpr_log(GPR_ERROR, "JVM not cached yet");
return false;
}
JNIEnv* env_unused;
// Note that attach a thread that is already attached is a no-op, so it is
// fine to call this again if the thread has already been attached by other.
g_jvm->AttachCurrentThread(&env_unused, /* thr_args= */ nullptr);
gpr_log(GPR_INFO, "JVM attached successfully");
g_is_jvm_attached = true;
return true;
}
} // namespace
namespace grpc_binder {
@ -67,6 +117,7 @@ void* AIBinder_getUserData(AIBinder* binder) {
uid_t AIBinder_getCallingUid() { FORWARD(AIBinder_getCallingUid)(); }
AIBinder* AIBinder_fromJavaBinder(JNIEnv* env, jobject binder) {
SetJvm(env);
FORWARD(AIBinder_fromJavaBinder)(env, binder);
}
@ -97,6 +148,9 @@ void AIBinder_decStrong(AIBinder* binder) {
binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code,
AParcel** in, AParcel** out,
binder_flags_t flags) {
if (!AttachJvm()) {
gpr_log(GPR_ERROR, "failed to attach JVM. AIBinder_transact might fail.");
}
FORWARD(AIBinder_transact)(binder, code, in, out, flags);
}
@ -155,6 +209,7 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) {
}
jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder) {
SetJvm(env);
FORWARD(AIBinder_toJavaBinder)(env, binder);
}

@ -0,0 +1,172 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* src/proto/grpc/lookup/v1/rls_config.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg_internal.h"
#include "src/proto/grpc/lookup/v1/rls_config.upb.h"
#include "google/protobuf/duration.upb.h"
#include "upb/port_def.inc"
static const upb_MiniTable_Field grpc_lookup_v1_NameMatcher__fields[3] = {
{1, UPB_SIZE(4, 8), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{2, UPB_SIZE(12, 24), 0, 0, 9, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{3, UPB_SIZE(0, 0), 0, 0, 8, kUpb_FieldMode_Scalar | (upb_FieldRep_1Byte << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_NameMatcher_msginit = {
NULL,
&grpc_lookup_v1_NameMatcher__fields[0],
UPB_SIZE(16, 32), 3, upb_ExtMode_NonExtendable, 3, 255, 0,
};
static const upb_MiniTable_Sub grpc_lookup_v1_GrpcKeyBuilder_submsgs[4] = {
{.submsg = &grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_msginit},
{.submsg = &grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit},
{.submsg = &grpc_lookup_v1_GrpcKeyBuilder_Name_msginit},
{.submsg = &grpc_lookup_v1_NameMatcher_msginit},
};
static const upb_MiniTable_Field grpc_lookup_v1_GrpcKeyBuilder__fields[4] = {
{1, UPB_SIZE(8, 16), 0, 2, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{2, UPB_SIZE(12, 24), 0, 3, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{3, UPB_SIZE(4, 8), 1, 1, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{4, UPB_SIZE(16, 32), 0, 0, 11, kUpb_FieldMode_Map | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_msginit = {
&grpc_lookup_v1_GrpcKeyBuilder_submsgs[0],
&grpc_lookup_v1_GrpcKeyBuilder__fields[0],
UPB_SIZE(24, 40), 4, upb_ExtMode_NonExtendable, 4, 255, 0,
};
static const upb_MiniTable_Field grpc_lookup_v1_GrpcKeyBuilder_Name__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{2, UPB_SIZE(8, 16), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_Name_msginit = {
NULL,
&grpc_lookup_v1_GrpcKeyBuilder_Name__fields[0],
UPB_SIZE(16, 32), 2, upb_ExtMode_NonExtendable, 2, 255, 0,
};
static const upb_MiniTable_Field grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys__fields[3] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{2, UPB_SIZE(8, 16), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{3, UPB_SIZE(16, 32), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit = {
NULL,
&grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys__fields[0],
UPB_SIZE(24, 48), 3, upb_ExtMode_NonExtendable, 3, 255, 0,
};
static const upb_MiniTable_Field grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{2, UPB_SIZE(8, 16), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_msginit = {
NULL,
&grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry__fields[0],
UPB_SIZE(16, 32), 2, upb_ExtMode_NonExtendable, 2, 255, 0,
};
static const upb_MiniTable_Sub grpc_lookup_v1_HttpKeyBuilder_submsgs[2] = {
{.submsg = &grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_msginit},
{.submsg = &grpc_lookup_v1_NameMatcher_msginit},
};
static const upb_MiniTable_Field grpc_lookup_v1_HttpKeyBuilder__fields[5] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{2, UPB_SIZE(4, 8), 0, 0, 9, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{3, UPB_SIZE(8, 16), 0, 1, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{4, UPB_SIZE(12, 24), 0, 1, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{5, UPB_SIZE(16, 32), 0, 0, 11, kUpb_FieldMode_Map | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_HttpKeyBuilder_msginit = {
&grpc_lookup_v1_HttpKeyBuilder_submsgs[0],
&grpc_lookup_v1_HttpKeyBuilder__fields[0],
UPB_SIZE(24, 40), 5, upb_ExtMode_NonExtendable, 5, 255, 0,
};
static const upb_MiniTable_Field grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry__fields[2] = {
{1, UPB_SIZE(0, 0), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{2, UPB_SIZE(8, 16), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_msginit = {
NULL,
&grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry__fields[0],
UPB_SIZE(16, 32), 2, upb_ExtMode_NonExtendable, 2, 255, 0,
};
static const upb_MiniTable_Sub grpc_lookup_v1_RouteLookupConfig_submsgs[3] = {
{.submsg = &google_protobuf_Duration_msginit},
{.submsg = &grpc_lookup_v1_GrpcKeyBuilder_msginit},
{.submsg = &grpc_lookup_v1_HttpKeyBuilder_msginit},
};
static const upb_MiniTable_Field grpc_lookup_v1_RouteLookupConfig__fields[9] = {
{1, UPB_SIZE(44, 72), 0, 2, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{2, UPB_SIZE(48, 80), 0, 1, 11, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{3, UPB_SIZE(16, 16), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
{4, UPB_SIZE(32, 48), 1, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{5, UPB_SIZE(36, 56), 2, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{6, UPB_SIZE(40, 64), 3, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{7, UPB_SIZE(8, 8), 0, 0, 3, kUpb_FieldMode_Scalar | (upb_FieldRep_8Byte << upb_FieldRep_Shift)},
{8, UPB_SIZE(52, 88), 0, 0, 9, kUpb_FieldMode_Array | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
{9, UPB_SIZE(24, 32), 0, 0, 9, kUpb_FieldMode_Scalar | (upb_FieldRep_StringView << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_RouteLookupConfig_msginit = {
&grpc_lookup_v1_RouteLookupConfig_submsgs[0],
&grpc_lookup_v1_RouteLookupConfig__fields[0],
UPB_SIZE(56, 96), 9, upb_ExtMode_NonExtendable, 9, 255, 0,
};
static const upb_MiniTable_Sub grpc_lookup_v1_RouteLookupClusterSpecifier_submsgs[1] = {
{.submsg = &grpc_lookup_v1_RouteLookupConfig_msginit},
};
static const upb_MiniTable_Field grpc_lookup_v1_RouteLookupClusterSpecifier__fields[1] = {
{1, UPB_SIZE(4, 8), 1, 0, 11, kUpb_FieldMode_Scalar | (upb_FieldRep_Pointer << upb_FieldRep_Shift)},
};
const upb_MiniTable grpc_lookup_v1_RouteLookupClusterSpecifier_msginit = {
&grpc_lookup_v1_RouteLookupClusterSpecifier_submsgs[0],
&grpc_lookup_v1_RouteLookupClusterSpecifier__fields[0],
UPB_SIZE(8, 16), 1, upb_ExtMode_NonExtendable, 1, 255, 0,
};
static const upb_MiniTable *messages_layout[9] = {
&grpc_lookup_v1_NameMatcher_msginit,
&grpc_lookup_v1_GrpcKeyBuilder_msginit,
&grpc_lookup_v1_GrpcKeyBuilder_Name_msginit,
&grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit,
&grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_msginit,
&grpc_lookup_v1_HttpKeyBuilder_msginit,
&grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_msginit,
&grpc_lookup_v1_RouteLookupConfig_msginit,
&grpc_lookup_v1_RouteLookupClusterSpecifier_msginit,
};
const upb_MiniTable_File src_proto_grpc_lookup_v1_rls_config_proto_upb_file_layout = {
messages_layout,
NULL,
NULL,
9,
0,
0,
};
#include "upb/port_undef.inc"

@ -0,0 +1,623 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* src/proto/grpc/lookup/v1/rls_config.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef SRC_PROTO_GRPC_LOOKUP_V1_RLS_CONFIG_PROTO_UPB_H_
#define SRC_PROTO_GRPC_LOOKUP_V1_RLS_CONFIG_PROTO_UPB_H_
#include "upb/msg_internal.h"
#include "upb/decode.h"
#include "upb/decode_fast.h"
#include "upb/encode.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
struct grpc_lookup_v1_NameMatcher;
struct grpc_lookup_v1_GrpcKeyBuilder;
struct grpc_lookup_v1_GrpcKeyBuilder_Name;
struct grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys;
struct grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry;
struct grpc_lookup_v1_HttpKeyBuilder;
struct grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry;
struct grpc_lookup_v1_RouteLookupConfig;
struct grpc_lookup_v1_RouteLookupClusterSpecifier;
typedef struct grpc_lookup_v1_NameMatcher grpc_lookup_v1_NameMatcher;
typedef struct grpc_lookup_v1_GrpcKeyBuilder grpc_lookup_v1_GrpcKeyBuilder;
typedef struct grpc_lookup_v1_GrpcKeyBuilder_Name grpc_lookup_v1_GrpcKeyBuilder_Name;
typedef struct grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys;
typedef struct grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry;
typedef struct grpc_lookup_v1_HttpKeyBuilder grpc_lookup_v1_HttpKeyBuilder;
typedef struct grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry;
typedef struct grpc_lookup_v1_RouteLookupConfig grpc_lookup_v1_RouteLookupConfig;
typedef struct grpc_lookup_v1_RouteLookupClusterSpecifier grpc_lookup_v1_RouteLookupClusterSpecifier;
extern const upb_MiniTable grpc_lookup_v1_NameMatcher_msginit;
extern const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_msginit;
extern const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_Name_msginit;
extern const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit;
extern const upb_MiniTable grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_msginit;
extern const upb_MiniTable grpc_lookup_v1_HttpKeyBuilder_msginit;
extern const upb_MiniTable grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_msginit;
extern const upb_MiniTable grpc_lookup_v1_RouteLookupConfig_msginit;
extern const upb_MiniTable grpc_lookup_v1_RouteLookupClusterSpecifier_msginit;
struct google_protobuf_Duration;
extern const upb_MiniTable google_protobuf_Duration_msginit;
/* grpc.lookup.v1.NameMatcher */
UPB_INLINE grpc_lookup_v1_NameMatcher* grpc_lookup_v1_NameMatcher_new(upb_Arena* arena) {
return (grpc_lookup_v1_NameMatcher*)_upb_Message_New(&grpc_lookup_v1_NameMatcher_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_NameMatcher* grpc_lookup_v1_NameMatcher_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_NameMatcher* ret = grpc_lookup_v1_NameMatcher_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_NameMatcher_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_NameMatcher* grpc_lookup_v1_NameMatcher_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_NameMatcher* ret = grpc_lookup_v1_NameMatcher_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_NameMatcher_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_NameMatcher_serialize(const grpc_lookup_v1_NameMatcher* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_NameMatcher_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_NameMatcher_serialize_ex(const grpc_lookup_v1_NameMatcher* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_NameMatcher_msginit, options, arena, len);
}
UPB_INLINE upb_StringView grpc_lookup_v1_NameMatcher_key(const grpc_lookup_v1_NameMatcher* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView);
}
UPB_INLINE upb_StringView const* grpc_lookup_v1_NameMatcher_names(const grpc_lookup_v1_NameMatcher *msg, size_t *len) { return (upb_StringView const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
UPB_INLINE bool grpc_lookup_v1_NameMatcher_required_match(const grpc_lookup_v1_NameMatcher* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool);
}
UPB_INLINE void grpc_lookup_v1_NameMatcher_set_key(grpc_lookup_v1_NameMatcher *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_StringView) = value;
}
UPB_INLINE upb_StringView* grpc_lookup_v1_NameMatcher_mutable_names(grpc_lookup_v1_NameMatcher *msg, size_t *len) {
return (upb_StringView*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
}
UPB_INLINE upb_StringView* grpc_lookup_v1_NameMatcher_resize_names(grpc_lookup_v1_NameMatcher *msg, size_t len, upb_Arena *arena) {
return (upb_StringView*)_upb_Array_Resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(3, 4), arena);
}
UPB_INLINE bool grpc_lookup_v1_NameMatcher_add_names(grpc_lookup_v1_NameMatcher *msg, upb_StringView val, upb_Arena *arena) {
return _upb_Array_Append_accessor2(msg, UPB_SIZE(12, 24), UPB_SIZE(3, 4), &val,
arena);
}
UPB_INLINE void grpc_lookup_v1_NameMatcher_set_required_match(grpc_lookup_v1_NameMatcher *msg, bool value) {
*UPB_PTR_AT(msg, UPB_SIZE(0, 0), bool) = value;
}
/* grpc.lookup.v1.GrpcKeyBuilder */
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder* grpc_lookup_v1_GrpcKeyBuilder_new(upb_Arena* arena) {
return (grpc_lookup_v1_GrpcKeyBuilder*)_upb_Message_New(&grpc_lookup_v1_GrpcKeyBuilder_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder* grpc_lookup_v1_GrpcKeyBuilder_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_GrpcKeyBuilder* ret = grpc_lookup_v1_GrpcKeyBuilder_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_GrpcKeyBuilder_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder* grpc_lookup_v1_GrpcKeyBuilder_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_GrpcKeyBuilder* ret = grpc_lookup_v1_GrpcKeyBuilder_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_GrpcKeyBuilder_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_GrpcKeyBuilder_serialize(const grpc_lookup_v1_GrpcKeyBuilder* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_GrpcKeyBuilder_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_GrpcKeyBuilder_serialize_ex(const grpc_lookup_v1_GrpcKeyBuilder* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_GrpcKeyBuilder_msginit, options, arena, len);
}
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_has_names(const grpc_lookup_v1_GrpcKeyBuilder *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
UPB_INLINE const grpc_lookup_v1_GrpcKeyBuilder_Name* const* grpc_lookup_v1_GrpcKeyBuilder_names(const grpc_lookup_v1_GrpcKeyBuilder *msg, size_t *len) { return (const grpc_lookup_v1_GrpcKeyBuilder_Name* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_has_headers(const grpc_lookup_v1_GrpcKeyBuilder *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
UPB_INLINE const grpc_lookup_v1_NameMatcher* const* grpc_lookup_v1_GrpcKeyBuilder_headers(const grpc_lookup_v1_GrpcKeyBuilder *msg, size_t *len) { return (const grpc_lookup_v1_NameMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_has_extra_keys(const grpc_lookup_v1_GrpcKeyBuilder *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* grpc_lookup_v1_GrpcKeyBuilder_extra_keys(const grpc_lookup_v1_GrpcKeyBuilder* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys*);
}
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_has_constant_keys(const grpc_lookup_v1_GrpcKeyBuilder *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
UPB_INLINE size_t grpc_lookup_v1_GrpcKeyBuilder_constant_keys_size(const grpc_lookup_v1_GrpcKeyBuilder *msg) {return _upb_msg_map_size(msg, UPB_SIZE(16, 32)); }
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_constant_keys_get(const grpc_lookup_v1_GrpcKeyBuilder *msg, upb_StringView key, upb_StringView *val) { return _upb_msg_map_get(msg, UPB_SIZE(16, 32), &key, 0, val, 0); }
UPB_INLINE const grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry* grpc_lookup_v1_GrpcKeyBuilder_constant_keys_next(const grpc_lookup_v1_GrpcKeyBuilder *msg, size_t* iter) { return (const grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_Name** grpc_lookup_v1_GrpcKeyBuilder_mutable_names(grpc_lookup_v1_GrpcKeyBuilder *msg, size_t *len) {
return (grpc_lookup_v1_GrpcKeyBuilder_Name**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_Name** grpc_lookup_v1_GrpcKeyBuilder_resize_names(grpc_lookup_v1_GrpcKeyBuilder *msg, size_t len, upb_Arena *arena) {
return (grpc_lookup_v1_GrpcKeyBuilder_Name**)_upb_Array_Resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
}
UPB_INLINE struct grpc_lookup_v1_GrpcKeyBuilder_Name* grpc_lookup_v1_GrpcKeyBuilder_add_names(grpc_lookup_v1_GrpcKeyBuilder *msg, upb_Arena *arena) {
struct grpc_lookup_v1_GrpcKeyBuilder_Name* sub = (struct grpc_lookup_v1_GrpcKeyBuilder_Name*)_upb_Message_New(&grpc_lookup_v1_GrpcKeyBuilder_Name_msginit, arena);
bool ok = _upb_Array_Append_accessor2(
msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE grpc_lookup_v1_NameMatcher** grpc_lookup_v1_GrpcKeyBuilder_mutable_headers(grpc_lookup_v1_GrpcKeyBuilder *msg, size_t *len) {
return (grpc_lookup_v1_NameMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
}
UPB_INLINE grpc_lookup_v1_NameMatcher** grpc_lookup_v1_GrpcKeyBuilder_resize_headers(grpc_lookup_v1_GrpcKeyBuilder *msg, size_t len, upb_Arena *arena) {
return (grpc_lookup_v1_NameMatcher**)_upb_Array_Resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
}
UPB_INLINE struct grpc_lookup_v1_NameMatcher* grpc_lookup_v1_GrpcKeyBuilder_add_headers(grpc_lookup_v1_GrpcKeyBuilder *msg, upb_Arena *arena) {
struct grpc_lookup_v1_NameMatcher* sub = (struct grpc_lookup_v1_NameMatcher*)_upb_Message_New(&grpc_lookup_v1_NameMatcher_msginit, arena);
bool ok = _upb_Array_Append_accessor2(
msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_set_extra_keys(grpc_lookup_v1_GrpcKeyBuilder *msg, grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* value) {
_upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(4, 8), grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys*) = value;
}
UPB_INLINE struct grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* grpc_lookup_v1_GrpcKeyBuilder_mutable_extra_keys(grpc_lookup_v1_GrpcKeyBuilder *msg, upb_Arena *arena) {
struct grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* sub = (struct grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys*)grpc_lookup_v1_GrpcKeyBuilder_extra_keys(msg);
if (sub == NULL) {
sub = (struct grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys*)_upb_Message_New(&grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit, arena);
if (!sub) return NULL;
grpc_lookup_v1_GrpcKeyBuilder_set_extra_keys(msg, sub);
}
return sub;
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_constant_keys_clear(grpc_lookup_v1_GrpcKeyBuilder *msg) { _upb_msg_map_clear(msg, UPB_SIZE(16, 32)); }
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_constant_keys_set(grpc_lookup_v1_GrpcKeyBuilder *msg, upb_StringView key, upb_StringView val, upb_Arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(16, 32), &key, 0, &val, 0, a); }
UPB_INLINE bool grpc_lookup_v1_GrpcKeyBuilder_constant_keys_delete(grpc_lookup_v1_GrpcKeyBuilder *msg, upb_StringView key) { return _upb_msg_map_delete(msg, UPB_SIZE(16, 32), &key, 0); }
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry* grpc_lookup_v1_GrpcKeyBuilder_constant_keys_nextmutable(grpc_lookup_v1_GrpcKeyBuilder *msg, size_t* iter) { return (grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
/* grpc.lookup.v1.GrpcKeyBuilder.Name */
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_Name* grpc_lookup_v1_GrpcKeyBuilder_Name_new(upb_Arena* arena) {
return (grpc_lookup_v1_GrpcKeyBuilder_Name*)_upb_Message_New(&grpc_lookup_v1_GrpcKeyBuilder_Name_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_Name* grpc_lookup_v1_GrpcKeyBuilder_Name_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_GrpcKeyBuilder_Name* ret = grpc_lookup_v1_GrpcKeyBuilder_Name_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_GrpcKeyBuilder_Name_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_Name* grpc_lookup_v1_GrpcKeyBuilder_Name_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_GrpcKeyBuilder_Name* ret = grpc_lookup_v1_GrpcKeyBuilder_Name_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_GrpcKeyBuilder_Name_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_GrpcKeyBuilder_Name_serialize(const grpc_lookup_v1_GrpcKeyBuilder_Name* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_GrpcKeyBuilder_Name_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_GrpcKeyBuilder_Name_serialize_ex(const grpc_lookup_v1_GrpcKeyBuilder_Name* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_GrpcKeyBuilder_Name_msginit, options, arena, len);
}
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_Name_service(const grpc_lookup_v1_GrpcKeyBuilder_Name* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_StringView);
}
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_Name_method(const grpc_lookup_v1_GrpcKeyBuilder_Name* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_StringView);
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_Name_set_service(grpc_lookup_v1_GrpcKeyBuilder_Name *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_StringView) = value;
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_Name_set_method(grpc_lookup_v1_GrpcKeyBuilder_Name *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_StringView) = value;
}
/* grpc.lookup.v1.GrpcKeyBuilder.ExtraKeys */
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_new(upb_Arena* arena) {
return (grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys*)_upb_Message_New(&grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* ret = grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* ret = grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_serialize(const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_serialize_ex(const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_msginit, options, arena, len);
}
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_host(const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_StringView);
}
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_service(const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_StringView);
}
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_method(const grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_StringView);
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_set_host(grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(0, 0), upb_StringView) = value;
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_set_service(grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(8, 16), upb_StringView) = value;
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_set_method(grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(16, 32), upb_StringView) = value;
}
/* grpc.lookup.v1.GrpcKeyBuilder.ConstantKeysEntry */
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_key(const grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry *msg) {
upb_StringView ret;
_upb_msg_map_key(msg, &ret, 0);
return ret;
}
UPB_INLINE upb_StringView grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_value(const grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry *msg) {
upb_StringView ret;
_upb_msg_map_value(msg, &ret, 0);
return ret;
}
UPB_INLINE void grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_set_value(grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry *msg, upb_StringView value) {
_upb_msg_map_set_value(msg, &value, 0);
}
/* grpc.lookup.v1.HttpKeyBuilder */
UPB_INLINE grpc_lookup_v1_HttpKeyBuilder* grpc_lookup_v1_HttpKeyBuilder_new(upb_Arena* arena) {
return (grpc_lookup_v1_HttpKeyBuilder*)_upb_Message_New(&grpc_lookup_v1_HttpKeyBuilder_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_HttpKeyBuilder* grpc_lookup_v1_HttpKeyBuilder_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_HttpKeyBuilder* ret = grpc_lookup_v1_HttpKeyBuilder_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_HttpKeyBuilder_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_HttpKeyBuilder* grpc_lookup_v1_HttpKeyBuilder_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_HttpKeyBuilder* ret = grpc_lookup_v1_HttpKeyBuilder_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_HttpKeyBuilder_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_HttpKeyBuilder_serialize(const grpc_lookup_v1_HttpKeyBuilder* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_HttpKeyBuilder_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_HttpKeyBuilder_serialize_ex(const grpc_lookup_v1_HttpKeyBuilder* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_HttpKeyBuilder_msginit, options, arena, len);
}
UPB_INLINE upb_StringView const* grpc_lookup_v1_HttpKeyBuilder_host_patterns(const grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) { return (upb_StringView const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); }
UPB_INLINE upb_StringView const* grpc_lookup_v1_HttpKeyBuilder_path_patterns(const grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) { return (upb_StringView const*)_upb_array_accessor(msg, UPB_SIZE(4, 8), len); }
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_has_query_parameters(const grpc_lookup_v1_HttpKeyBuilder *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); }
UPB_INLINE const grpc_lookup_v1_NameMatcher* const* grpc_lookup_v1_HttpKeyBuilder_query_parameters(const grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) { return (const grpc_lookup_v1_NameMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); }
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_has_headers(const grpc_lookup_v1_HttpKeyBuilder *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(12, 24)); }
UPB_INLINE const grpc_lookup_v1_NameMatcher* const* grpc_lookup_v1_HttpKeyBuilder_headers(const grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) { return (const grpc_lookup_v1_NameMatcher* const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); }
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_has_constant_keys(const grpc_lookup_v1_HttpKeyBuilder *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(16, 32)); }
UPB_INLINE size_t grpc_lookup_v1_HttpKeyBuilder_constant_keys_size(const grpc_lookup_v1_HttpKeyBuilder *msg) {return _upb_msg_map_size(msg, UPB_SIZE(16, 32)); }
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_constant_keys_get(const grpc_lookup_v1_HttpKeyBuilder *msg, upb_StringView key, upb_StringView *val) { return _upb_msg_map_get(msg, UPB_SIZE(16, 32), &key, 0, val, 0); }
UPB_INLINE const grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry* grpc_lookup_v1_HttpKeyBuilder_constant_keys_next(const grpc_lookup_v1_HttpKeyBuilder *msg, size_t* iter) { return (const grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
UPB_INLINE upb_StringView* grpc_lookup_v1_HttpKeyBuilder_mutable_host_patterns(grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) {
return (upb_StringView*)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len);
}
UPB_INLINE upb_StringView* grpc_lookup_v1_HttpKeyBuilder_resize_host_patterns(grpc_lookup_v1_HttpKeyBuilder *msg, size_t len, upb_Arena *arena) {
return (upb_StringView*)_upb_Array_Resize_accessor2(msg, UPB_SIZE(0, 0), len, UPB_SIZE(3, 4), arena);
}
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_add_host_patterns(grpc_lookup_v1_HttpKeyBuilder *msg, upb_StringView val, upb_Arena *arena) {
return _upb_Array_Append_accessor2(msg, UPB_SIZE(0, 0), UPB_SIZE(3, 4), &val,
arena);
}
UPB_INLINE upb_StringView* grpc_lookup_v1_HttpKeyBuilder_mutable_path_patterns(grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) {
return (upb_StringView*)_upb_array_mutable_accessor(msg, UPB_SIZE(4, 8), len);
}
UPB_INLINE upb_StringView* grpc_lookup_v1_HttpKeyBuilder_resize_path_patterns(grpc_lookup_v1_HttpKeyBuilder *msg, size_t len, upb_Arena *arena) {
return (upb_StringView*)_upb_Array_Resize_accessor2(msg, UPB_SIZE(4, 8), len, UPB_SIZE(3, 4), arena);
}
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_add_path_patterns(grpc_lookup_v1_HttpKeyBuilder *msg, upb_StringView val, upb_Arena *arena) {
return _upb_Array_Append_accessor2(msg, UPB_SIZE(4, 8), UPB_SIZE(3, 4), &val,
arena);
}
UPB_INLINE grpc_lookup_v1_NameMatcher** grpc_lookup_v1_HttpKeyBuilder_mutable_query_parameters(grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) {
return (grpc_lookup_v1_NameMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len);
}
UPB_INLINE grpc_lookup_v1_NameMatcher** grpc_lookup_v1_HttpKeyBuilder_resize_query_parameters(grpc_lookup_v1_HttpKeyBuilder *msg, size_t len, upb_Arena *arena) {
return (grpc_lookup_v1_NameMatcher**)_upb_Array_Resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena);
}
UPB_INLINE struct grpc_lookup_v1_NameMatcher* grpc_lookup_v1_HttpKeyBuilder_add_query_parameters(grpc_lookup_v1_HttpKeyBuilder *msg, upb_Arena *arena) {
struct grpc_lookup_v1_NameMatcher* sub = (struct grpc_lookup_v1_NameMatcher*)_upb_Message_New(&grpc_lookup_v1_NameMatcher_msginit, arena);
bool ok = _upb_Array_Append_accessor2(
msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE grpc_lookup_v1_NameMatcher** grpc_lookup_v1_HttpKeyBuilder_mutable_headers(grpc_lookup_v1_HttpKeyBuilder *msg, size_t *len) {
return (grpc_lookup_v1_NameMatcher**)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len);
}
UPB_INLINE grpc_lookup_v1_NameMatcher** grpc_lookup_v1_HttpKeyBuilder_resize_headers(grpc_lookup_v1_HttpKeyBuilder *msg, size_t len, upb_Arena *arena) {
return (grpc_lookup_v1_NameMatcher**)_upb_Array_Resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(2, 3), arena);
}
UPB_INLINE struct grpc_lookup_v1_NameMatcher* grpc_lookup_v1_HttpKeyBuilder_add_headers(grpc_lookup_v1_HttpKeyBuilder *msg, upb_Arena *arena) {
struct grpc_lookup_v1_NameMatcher* sub = (struct grpc_lookup_v1_NameMatcher*)_upb_Message_New(&grpc_lookup_v1_NameMatcher_msginit, arena);
bool ok = _upb_Array_Append_accessor2(
msg, UPB_SIZE(12, 24), UPB_SIZE(2, 3), &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE void grpc_lookup_v1_HttpKeyBuilder_constant_keys_clear(grpc_lookup_v1_HttpKeyBuilder *msg) { _upb_msg_map_clear(msg, UPB_SIZE(16, 32)); }
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_constant_keys_set(grpc_lookup_v1_HttpKeyBuilder *msg, upb_StringView key, upb_StringView val, upb_Arena *a) { return _upb_msg_map_set(msg, UPB_SIZE(16, 32), &key, 0, &val, 0, a); }
UPB_INLINE bool grpc_lookup_v1_HttpKeyBuilder_constant_keys_delete(grpc_lookup_v1_HttpKeyBuilder *msg, upb_StringView key) { return _upb_msg_map_delete(msg, UPB_SIZE(16, 32), &key, 0); }
UPB_INLINE grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry* grpc_lookup_v1_HttpKeyBuilder_constant_keys_nextmutable(grpc_lookup_v1_HttpKeyBuilder *msg, size_t* iter) { return (grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry*)_upb_msg_map_next(msg, UPB_SIZE(16, 32), iter); }
/* grpc.lookup.v1.HttpKeyBuilder.ConstantKeysEntry */
UPB_INLINE upb_StringView grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_key(const grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry *msg) {
upb_StringView ret;
_upb_msg_map_key(msg, &ret, 0);
return ret;
}
UPB_INLINE upb_StringView grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_value(const grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry *msg) {
upb_StringView ret;
_upb_msg_map_value(msg, &ret, 0);
return ret;
}
UPB_INLINE void grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_set_value(grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry *msg, upb_StringView value) {
_upb_msg_map_set_value(msg, &value, 0);
}
/* grpc.lookup.v1.RouteLookupConfig */
UPB_INLINE grpc_lookup_v1_RouteLookupConfig* grpc_lookup_v1_RouteLookupConfig_new(upb_Arena* arena) {
return (grpc_lookup_v1_RouteLookupConfig*)_upb_Message_New(&grpc_lookup_v1_RouteLookupConfig_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_RouteLookupConfig* grpc_lookup_v1_RouteLookupConfig_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_RouteLookupConfig* ret = grpc_lookup_v1_RouteLookupConfig_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_RouteLookupConfig_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_RouteLookupConfig* grpc_lookup_v1_RouteLookupConfig_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_RouteLookupConfig* ret = grpc_lookup_v1_RouteLookupConfig_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_RouteLookupConfig_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_RouteLookupConfig_serialize(const grpc_lookup_v1_RouteLookupConfig* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_RouteLookupConfig_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_RouteLookupConfig_serialize_ex(const grpc_lookup_v1_RouteLookupConfig* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_RouteLookupConfig_msginit, options, arena, len);
}
UPB_INLINE bool grpc_lookup_v1_RouteLookupConfig_has_http_keybuilders(const grpc_lookup_v1_RouteLookupConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(44, 72)); }
UPB_INLINE const grpc_lookup_v1_HttpKeyBuilder* const* grpc_lookup_v1_RouteLookupConfig_http_keybuilders(const grpc_lookup_v1_RouteLookupConfig *msg, size_t *len) { return (const grpc_lookup_v1_HttpKeyBuilder* const*)_upb_array_accessor(msg, UPB_SIZE(44, 72), len); }
UPB_INLINE bool grpc_lookup_v1_RouteLookupConfig_has_grpc_keybuilders(const grpc_lookup_v1_RouteLookupConfig *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(48, 80)); }
UPB_INLINE const grpc_lookup_v1_GrpcKeyBuilder* const* grpc_lookup_v1_RouteLookupConfig_grpc_keybuilders(const grpc_lookup_v1_RouteLookupConfig *msg, size_t *len) { return (const grpc_lookup_v1_GrpcKeyBuilder* const*)_upb_array_accessor(msg, UPB_SIZE(48, 80), len); }
UPB_INLINE upb_StringView grpc_lookup_v1_RouteLookupConfig_lookup_service(const grpc_lookup_v1_RouteLookupConfig* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_StringView);
}
UPB_INLINE bool grpc_lookup_v1_RouteLookupConfig_has_lookup_service_timeout(const grpc_lookup_v1_RouteLookupConfig *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE const struct google_protobuf_Duration* grpc_lookup_v1_RouteLookupConfig_lookup_service_timeout(const grpc_lookup_v1_RouteLookupConfig* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(32, 48), const struct google_protobuf_Duration*);
}
UPB_INLINE bool grpc_lookup_v1_RouteLookupConfig_has_max_age(const grpc_lookup_v1_RouteLookupConfig *msg) { return _upb_hasbit(msg, 2); }
UPB_INLINE const struct google_protobuf_Duration* grpc_lookup_v1_RouteLookupConfig_max_age(const grpc_lookup_v1_RouteLookupConfig* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(36, 56), const struct google_protobuf_Duration*);
}
UPB_INLINE bool grpc_lookup_v1_RouteLookupConfig_has_stale_age(const grpc_lookup_v1_RouteLookupConfig *msg) { return _upb_hasbit(msg, 3); }
UPB_INLINE const struct google_protobuf_Duration* grpc_lookup_v1_RouteLookupConfig_stale_age(const grpc_lookup_v1_RouteLookupConfig* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(40, 64), const struct google_protobuf_Duration*);
}
UPB_INLINE int64_t grpc_lookup_v1_RouteLookupConfig_cache_size_bytes(const grpc_lookup_v1_RouteLookupConfig* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t);
}
UPB_INLINE upb_StringView const* grpc_lookup_v1_RouteLookupConfig_valid_targets(const grpc_lookup_v1_RouteLookupConfig *msg, size_t *len) { return (upb_StringView const*)_upb_array_accessor(msg, UPB_SIZE(52, 88), len); }
UPB_INLINE upb_StringView grpc_lookup_v1_RouteLookupConfig_default_target(const grpc_lookup_v1_RouteLookupConfig* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(24, 32), upb_StringView);
}
UPB_INLINE grpc_lookup_v1_HttpKeyBuilder** grpc_lookup_v1_RouteLookupConfig_mutable_http_keybuilders(grpc_lookup_v1_RouteLookupConfig *msg, size_t *len) {
return (grpc_lookup_v1_HttpKeyBuilder**)_upb_array_mutable_accessor(msg, UPB_SIZE(44, 72), len);
}
UPB_INLINE grpc_lookup_v1_HttpKeyBuilder** grpc_lookup_v1_RouteLookupConfig_resize_http_keybuilders(grpc_lookup_v1_RouteLookupConfig *msg, size_t len, upb_Arena *arena) {
return (grpc_lookup_v1_HttpKeyBuilder**)_upb_Array_Resize_accessor2(msg, UPB_SIZE(44, 72), len, UPB_SIZE(2, 3), arena);
}
UPB_INLINE struct grpc_lookup_v1_HttpKeyBuilder* grpc_lookup_v1_RouteLookupConfig_add_http_keybuilders(grpc_lookup_v1_RouteLookupConfig *msg, upb_Arena *arena) {
struct grpc_lookup_v1_HttpKeyBuilder* sub = (struct grpc_lookup_v1_HttpKeyBuilder*)_upb_Message_New(&grpc_lookup_v1_HttpKeyBuilder_msginit, arena);
bool ok = _upb_Array_Append_accessor2(
msg, UPB_SIZE(44, 72), UPB_SIZE(2, 3), &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder** grpc_lookup_v1_RouteLookupConfig_mutable_grpc_keybuilders(grpc_lookup_v1_RouteLookupConfig *msg, size_t *len) {
return (grpc_lookup_v1_GrpcKeyBuilder**)_upb_array_mutable_accessor(msg, UPB_SIZE(48, 80), len);
}
UPB_INLINE grpc_lookup_v1_GrpcKeyBuilder** grpc_lookup_v1_RouteLookupConfig_resize_grpc_keybuilders(grpc_lookup_v1_RouteLookupConfig *msg, size_t len, upb_Arena *arena) {
return (grpc_lookup_v1_GrpcKeyBuilder**)_upb_Array_Resize_accessor2(msg, UPB_SIZE(48, 80), len, UPB_SIZE(2, 3), arena);
}
UPB_INLINE struct grpc_lookup_v1_GrpcKeyBuilder* grpc_lookup_v1_RouteLookupConfig_add_grpc_keybuilders(grpc_lookup_v1_RouteLookupConfig *msg, upb_Arena *arena) {
struct grpc_lookup_v1_GrpcKeyBuilder* sub = (struct grpc_lookup_v1_GrpcKeyBuilder*)_upb_Message_New(&grpc_lookup_v1_GrpcKeyBuilder_msginit, arena);
bool ok = _upb_Array_Append_accessor2(
msg, UPB_SIZE(48, 80), UPB_SIZE(2, 3), &sub, arena);
if (!ok) return NULL;
return sub;
}
UPB_INLINE void grpc_lookup_v1_RouteLookupConfig_set_lookup_service(grpc_lookup_v1_RouteLookupConfig *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(16, 16), upb_StringView) = value;
}
UPB_INLINE void grpc_lookup_v1_RouteLookupConfig_set_lookup_service_timeout(grpc_lookup_v1_RouteLookupConfig *msg, struct google_protobuf_Duration* value) {
_upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(32, 48), struct google_protobuf_Duration*) = value;
}
UPB_INLINE struct google_protobuf_Duration* grpc_lookup_v1_RouteLookupConfig_mutable_lookup_service_timeout(grpc_lookup_v1_RouteLookupConfig *msg, upb_Arena *arena) {
struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)grpc_lookup_v1_RouteLookupConfig_lookup_service_timeout(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Duration*)_upb_Message_New(&google_protobuf_Duration_msginit, arena);
if (!sub) return NULL;
grpc_lookup_v1_RouteLookupConfig_set_lookup_service_timeout(msg, sub);
}
return sub;
}
UPB_INLINE void grpc_lookup_v1_RouteLookupConfig_set_max_age(grpc_lookup_v1_RouteLookupConfig *msg, struct google_protobuf_Duration* value) {
_upb_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(36, 56), struct google_protobuf_Duration*) = value;
}
UPB_INLINE struct google_protobuf_Duration* grpc_lookup_v1_RouteLookupConfig_mutable_max_age(grpc_lookup_v1_RouteLookupConfig *msg, upb_Arena *arena) {
struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)grpc_lookup_v1_RouteLookupConfig_max_age(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Duration*)_upb_Message_New(&google_protobuf_Duration_msginit, arena);
if (!sub) return NULL;
grpc_lookup_v1_RouteLookupConfig_set_max_age(msg, sub);
}
return sub;
}
UPB_INLINE void grpc_lookup_v1_RouteLookupConfig_set_stale_age(grpc_lookup_v1_RouteLookupConfig *msg, struct google_protobuf_Duration* value) {
_upb_sethas(msg, 3);
*UPB_PTR_AT(msg, UPB_SIZE(40, 64), struct google_protobuf_Duration*) = value;
}
UPB_INLINE struct google_protobuf_Duration* grpc_lookup_v1_RouteLookupConfig_mutable_stale_age(grpc_lookup_v1_RouteLookupConfig *msg, upb_Arena *arena) {
struct google_protobuf_Duration* sub = (struct google_protobuf_Duration*)grpc_lookup_v1_RouteLookupConfig_stale_age(msg);
if (sub == NULL) {
sub = (struct google_protobuf_Duration*)_upb_Message_New(&google_protobuf_Duration_msginit, arena);
if (!sub) return NULL;
grpc_lookup_v1_RouteLookupConfig_set_stale_age(msg, sub);
}
return sub;
}
UPB_INLINE void grpc_lookup_v1_RouteLookupConfig_set_cache_size_bytes(grpc_lookup_v1_RouteLookupConfig *msg, int64_t value) {
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), int64_t) = value;
}
UPB_INLINE upb_StringView* grpc_lookup_v1_RouteLookupConfig_mutable_valid_targets(grpc_lookup_v1_RouteLookupConfig *msg, size_t *len) {
return (upb_StringView*)_upb_array_mutable_accessor(msg, UPB_SIZE(52, 88), len);
}
UPB_INLINE upb_StringView* grpc_lookup_v1_RouteLookupConfig_resize_valid_targets(grpc_lookup_v1_RouteLookupConfig *msg, size_t len, upb_Arena *arena) {
return (upb_StringView*)_upb_Array_Resize_accessor2(msg, UPB_SIZE(52, 88), len, UPB_SIZE(3, 4), arena);
}
UPB_INLINE bool grpc_lookup_v1_RouteLookupConfig_add_valid_targets(grpc_lookup_v1_RouteLookupConfig *msg, upb_StringView val, upb_Arena *arena) {
return _upb_Array_Append_accessor2(msg, UPB_SIZE(52, 88), UPB_SIZE(3, 4), &val,
arena);
}
UPB_INLINE void grpc_lookup_v1_RouteLookupConfig_set_default_target(grpc_lookup_v1_RouteLookupConfig *msg, upb_StringView value) {
*UPB_PTR_AT(msg, UPB_SIZE(24, 32), upb_StringView) = value;
}
/* grpc.lookup.v1.RouteLookupClusterSpecifier */
UPB_INLINE grpc_lookup_v1_RouteLookupClusterSpecifier* grpc_lookup_v1_RouteLookupClusterSpecifier_new(upb_Arena* arena) {
return (grpc_lookup_v1_RouteLookupClusterSpecifier*)_upb_Message_New(&grpc_lookup_v1_RouteLookupClusterSpecifier_msginit, arena);
}
UPB_INLINE grpc_lookup_v1_RouteLookupClusterSpecifier* grpc_lookup_v1_RouteLookupClusterSpecifier_parse(const char* buf, size_t size, upb_Arena* arena) {
grpc_lookup_v1_RouteLookupClusterSpecifier* ret = grpc_lookup_v1_RouteLookupClusterSpecifier_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_RouteLookupClusterSpecifier_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE grpc_lookup_v1_RouteLookupClusterSpecifier* grpc_lookup_v1_RouteLookupClusterSpecifier_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
grpc_lookup_v1_RouteLookupClusterSpecifier* ret = grpc_lookup_v1_RouteLookupClusterSpecifier_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &grpc_lookup_v1_RouteLookupClusterSpecifier_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* grpc_lookup_v1_RouteLookupClusterSpecifier_serialize(const grpc_lookup_v1_RouteLookupClusterSpecifier* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_RouteLookupClusterSpecifier_msginit, 0, arena, len);
}
UPB_INLINE char* grpc_lookup_v1_RouteLookupClusterSpecifier_serialize_ex(const grpc_lookup_v1_RouteLookupClusterSpecifier* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &grpc_lookup_v1_RouteLookupClusterSpecifier_msginit, options, arena, len);
}
UPB_INLINE bool grpc_lookup_v1_RouteLookupClusterSpecifier_has_route_lookup_config(const grpc_lookup_v1_RouteLookupClusterSpecifier *msg) { return _upb_hasbit(msg, 1); }
UPB_INLINE const grpc_lookup_v1_RouteLookupConfig* grpc_lookup_v1_RouteLookupClusterSpecifier_route_lookup_config(const grpc_lookup_v1_RouteLookupClusterSpecifier* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const grpc_lookup_v1_RouteLookupConfig*);
}
UPB_INLINE void grpc_lookup_v1_RouteLookupClusterSpecifier_set_route_lookup_config(grpc_lookup_v1_RouteLookupClusterSpecifier *msg, grpc_lookup_v1_RouteLookupConfig* value) {
_upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(4, 8), grpc_lookup_v1_RouteLookupConfig*) = value;
}
UPB_INLINE struct grpc_lookup_v1_RouteLookupConfig* grpc_lookup_v1_RouteLookupClusterSpecifier_mutable_route_lookup_config(grpc_lookup_v1_RouteLookupClusterSpecifier *msg, upb_Arena *arena) {
struct grpc_lookup_v1_RouteLookupConfig* sub = (struct grpc_lookup_v1_RouteLookupConfig*)grpc_lookup_v1_RouteLookupClusterSpecifier_route_lookup_config(msg);
if (sub == NULL) {
sub = (struct grpc_lookup_v1_RouteLookupConfig*)_upb_Message_New(&grpc_lookup_v1_RouteLookupConfig_msginit, arena);
if (!sub) return NULL;
grpc_lookup_v1_RouteLookupClusterSpecifier_set_route_lookup_config(msg, sub);
}
return sub;
}
extern const upb_MiniTable_File src_proto_grpc_lookup_v1_rls_config_proto_upb_file_layout;
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* SRC_PROTO_GRPC_LOOKUP_V1_RLS_CONFIG_PROTO_UPB_H_ */

@ -0,0 +1,99 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* src/proto/grpc/lookup/v1/rls_config.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include "upb/def.h"
#include "src/proto/grpc/lookup/v1/rls_config.upbdefs.h"
#include "src/proto/grpc/lookup/v1/rls_config.upb.h"
extern _upb_DefPool_Init google_protobuf_duration_proto_upbdefinit;
static const char descriptor[1816] = {'\n', ')', 's', 'r', 'c', '/', 'p', 'r', 'o', 't', 'o', '/', 'g', 'r', 'p', 'c', '/', 'l', 'o', 'o', 'k', 'u', 'p', '/', 'v',
'1', '/', 'r', 'l', 's', '_', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'p', 'r', 'o', 't', 'o', '\022', '\016', 'g', 'r', 'p', 'c', '.',
'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '\032', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u',
'f', '/', 'd', 'u', 'r', 'a', 't', 'i', 'o', 'n', '.', 'p', 'r', 'o', 't', 'o', '\"', '\\', '\n', '\013', 'N', 'a', 'm', 'e', 'M',
'a', 't', 'c', 'h', 'e', 'r', '\022', '\020', '\n', '\003', 'k', 'e', 'y', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\003', 'k', 'e', 'y', '\022',
'\024', '\n', '\005', 'n', 'a', 'm', 'e', 's', '\030', '\002', ' ', '\003', '(', '\t', 'R', '\005', 'n', 'a', 'm', 'e', 's', '\022', '%', '\n', '\016',
'r', 'e', 'q', 'u', 'i', 'r', 'e', 'd', '_', 'm', 'a', 't', 'c', 'h', '\030', '\003', ' ', '\001', '(', '\010', 'R', '\r', 'r', 'e', 'q',
'u', 'i', 'r', 'e', 'd', 'M', 'a', 't', 'c', 'h', '\"', '\360', '\003', '\n', '\016', 'G', 'r', 'p', 'c', 'K', 'e', 'y', 'B', 'u', 'i',
'l', 'd', 'e', 'r', '\022', '9', '\n', '\005', 'n', 'a', 'm', 'e', 's', '\030', '\001', ' ', '\003', '(', '\013', '2', '#', '.', 'g', 'r', 'p',
'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'G', 'r', 'p', 'c', 'K', 'e', 'y', 'B', 'u', 'i', 'l', 'd', 'e',
'r', '.', 'N', 'a', 'm', 'e', 'R', '\005', 'n', 'a', 'm', 'e', 's', '\022', 'G', '\n', '\n', 'e', 'x', 't', 'r', 'a', '_', 'k', 'e',
'y', 's', '\030', '\003', ' ', '\001', '(', '\013', '2', '(', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1',
'.', 'G', 'r', 'p', 'c', 'K', 'e', 'y', 'B', 'u', 'i', 'l', 'd', 'e', 'r', '.', 'E', 'x', 't', 'r', 'a', 'K', 'e', 'y', 's',
'R', '\t', 'e', 'x', 't', 'r', 'a', 'K', 'e', 'y', 's', '\022', '5', '\n', '\007', 'h', 'e', 'a', 'd', 'e', 'r', 's', '\030', '\002', ' ',
'\003', '(', '\013', '2', '\033', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'N', 'a', 'm', 'e',
'M', 'a', 't', 'c', 'h', 'e', 'r', 'R', '\007', 'h', 'e', 'a', 'd', 'e', 'r', 's', '\022', 'U', '\n', '\r', 'c', 'o', 'n', 's', 't',
'a', 'n', 't', '_', 'k', 'e', 'y', 's', '\030', '\004', ' ', '\003', '(', '\013', '2', '0', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o',
'k', 'u', 'p', '.', 'v', '1', '.', 'G', 'r', 'p', 'c', 'K', 'e', 'y', 'B', 'u', 'i', 'l', 'd', 'e', 'r', '.', 'C', 'o', 'n',
's', 't', 'a', 'n', 't', 'K', 'e', 'y', 's', 'E', 'n', 't', 'r', 'y', 'R', '\014', 'c', 'o', 'n', 's', 't', 'a', 'n', 't', 'K',
'e', 'y', 's', '\032', '8', '\n', '\004', 'N', 'a', 'm', 'e', '\022', '\030', '\n', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\030', '\001', ' ',
'\001', '(', '\t', 'R', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\022', '\026', '\n', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\030', '\002', ' ',
'\001', '(', '\t', 'R', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\032', 'Q', '\n', '\t', 'E', 'x', 't', 'r', 'a', 'K', 'e', 'y', 's', '\022',
'\022', '\n', '\004', 'h', 'o', 's', 't', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\004', 'h', 'o', 's', 't', '\022', '\030', '\n', '\007', 's', 'e',
'r', 'v', 'i', 'c', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\007', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\022', '\026', '\n', '\006', 'm',
'e', 't', 'h', 'o', 'd', '\030', '\003', ' ', '\001', '(', '\t', 'R', '\006', 'm', 'e', 't', 'h', 'o', 'd', '\032', '?', '\n', '\021', 'C', 'o',
'n', 's', 't', 'a', 'n', 't', 'K', 'e', 'y', 's', 'E', 'n', 't', 'r', 'y', '\022', '\020', '\n', '\003', 'k', 'e', 'y', '\030', '\001', ' ',
'\001', '(', '\t', 'R', '\003', 'k', 'e', 'y', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\005',
'v', 'a', 'l', 'u', 'e', ':', '\002', '8', '\001', '\"', '\361', '\002', '\n', '\016', 'H', 't', 't', 'p', 'K', 'e', 'y', 'B', 'u', 'i', 'l',
'd', 'e', 'r', '\022', '#', '\n', '\r', 'h', 'o', 's', 't', '_', 'p', 'a', 't', 't', 'e', 'r', 'n', 's', '\030', '\001', ' ', '\003', '(',
'\t', 'R', '\014', 'h', 'o', 's', 't', 'P', 'a', 't', 't', 'e', 'r', 'n', 's', '\022', '#', '\n', '\r', 'p', 'a', 't', 'h', '_', 'p',
'a', 't', 't', 'e', 'r', 'n', 's', '\030', '\002', ' ', '\003', '(', '\t', 'R', '\014', 'p', 'a', 't', 'h', 'P', 'a', 't', 't', 'e', 'r',
'n', 's', '\022', 'F', '\n', '\020', 'q', 'u', 'e', 'r', 'y', '_', 'p', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', 's', '\030', '\003', ' ',
'\003', '(', '\013', '2', '\033', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'N', 'a', 'm', 'e',
'M', 'a', 't', 'c', 'h', 'e', 'r', 'R', '\017', 'q', 'u', 'e', 'r', 'y', 'P', 'a', 'r', 'a', 'm', 'e', 't', 'e', 'r', 's', '\022',
'5', '\n', '\007', 'h', 'e', 'a', 'd', 'e', 'r', 's', '\030', '\004', ' ', '\003', '(', '\013', '2', '\033', '.', 'g', 'r', 'p', 'c', '.', 'l',
'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'N', 'a', 'm', 'e', 'M', 'a', 't', 'c', 'h', 'e', 'r', 'R', '\007', 'h', 'e', 'a',
'd', 'e', 'r', 's', '\022', 'U', '\n', '\r', 'c', 'o', 'n', 's', 't', 'a', 'n', 't', '_', 'k', 'e', 'y', 's', '\030', '\005', ' ', '\003',
'(', '\013', '2', '0', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'H', 't', 't', 'p', 'K',
'e', 'y', 'B', 'u', 'i', 'l', 'd', 'e', 'r', '.', 'C', 'o', 'n', 's', 't', 'a', 'n', 't', 'K', 'e', 'y', 's', 'E', 'n', 't',
'r', 'y', 'R', '\014', 'c', 'o', 'n', 's', 't', 'a', 'n', 't', 'K', 'e', 'y', 's', '\032', '?', '\n', '\021', 'C', 'o', 'n', 's', 't',
'a', 'n', 't', 'K', 'e', 'y', 's', 'E', 'n', 't', 'r', 'y', '\022', '\020', '\n', '\003', 'k', 'e', 'y', '\030', '\001', ' ', '\001', '(', '\t',
'R', '\003', 'k', 'e', 'y', '\022', '\024', '\n', '\005', 'v', 'a', 'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\t', 'R', '\005', 'v', 'a', 'l',
'u', 'e', ':', '\002', '8', '\001', '\"', '\246', '\004', '\n', '\021', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'C', 'o', 'n',
'f', 'i', 'g', '\022', 'I', '\n', '\020', 'h', 't', 't', 'p', '_', 'k', 'e', 'y', 'b', 'u', 'i', 'l', 'd', 'e', 'r', 's', '\030', '\001',
' ', '\003', '(', '\013', '2', '\036', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'H', 't', 't',
'p', 'K', 'e', 'y', 'B', 'u', 'i', 'l', 'd', 'e', 'r', 'R', '\017', 'h', 't', 't', 'p', 'K', 'e', 'y', 'b', 'u', 'i', 'l', 'd',
'e', 'r', 's', '\022', 'I', '\n', '\020', 'g', 'r', 'p', 'c', '_', 'k', 'e', 'y', 'b', 'u', 'i', 'l', 'd', 'e', 'r', 's', '\030', '\002',
' ', '\003', '(', '\013', '2', '\036', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'G', 'r', 'p',
'c', 'K', 'e', 'y', 'B', 'u', 'i', 'l', 'd', 'e', 'r', 'R', '\017', 'g', 'r', 'p', 'c', 'K', 'e', 'y', 'b', 'u', 'i', 'l', 'd',
'e', 'r', 's', '\022', '%', '\n', '\016', 'l', 'o', 'o', 'k', 'u', 'p', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', '\030', '\003', ' ', '\001',
'(', '\t', 'R', '\r', 'l', 'o', 'o', 'k', 'u', 'p', 'S', 'e', 'r', 'v', 'i', 'c', 'e', '\022', 'O', '\n', '\026', 'l', 'o', 'o', 'k',
'u', 'p', '_', 's', 'e', 'r', 'v', 'i', 'c', 'e', '_', 't', 'i', 'm', 'e', 'o', 'u', 't', '\030', '\004', ' ', '\001', '(', '\013', '2',
'\031', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'u', 'r', 'a', 't', 'i', 'o',
'n', 'R', '\024', 'l', 'o', 'o', 'k', 'u', 'p', 'S', 'e', 'r', 'v', 'i', 'c', 'e', 'T', 'i', 'm', 'e', 'o', 'u', 't', '\022', '2',
'\n', '\007', 'm', 'a', 'x', '_', 'a', 'g', 'e', '\030', '\005', ' ', '\001', '(', '\013', '2', '\031', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.',
'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'R', '\006', 'm', 'a', 'x', 'A', 'g', 'e',
'\022', '6', '\n', '\t', 's', 't', 'a', 'l', 'e', '_', 'a', 'g', 'e', '\030', '\006', ' ', '\001', '(', '\013', '2', '\031', '.', 'g', 'o', 'o',
'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'D', 'u', 'r', 'a', 't', 'i', 'o', 'n', 'R', '\010', 's', 't',
'a', 'l', 'e', 'A', 'g', 'e', '\022', '(', '\n', '\020', 'c', 'a', 'c', 'h', 'e', '_', 's', 'i', 'z', 'e', '_', 'b', 'y', 't', 'e',
's', '\030', '\007', ' ', '\001', '(', '\003', 'R', '\016', 'c', 'a', 'c', 'h', 'e', 'S', 'i', 'z', 'e', 'B', 'y', 't', 'e', 's', '\022', '#',
'\n', '\r', 'v', 'a', 'l', 'i', 'd', '_', 't', 'a', 'r', 'g', 'e', 't', 's', '\030', '\010', ' ', '\003', '(', '\t', 'R', '\014', 'v', 'a',
'l', 'i', 'd', 'T', 'a', 'r', 'g', 'e', 't', 's', '\022', '%', '\n', '\016', 'd', 'e', 'f', 'a', 'u', 'l', 't', '_', 't', 'a', 'r',
'g', 'e', 't', '\030', '\t', ' ', '\001', '(', '\t', 'R', '\r', 'd', 'e', 'f', 'a', 'u', 'l', 't', 'T', 'a', 'r', 'g', 'e', 't', 'J',
'\004', '\010', '\n', '\020', '\013', 'R', '\033', 'r', 'e', 'q', 'u', 'e', 's', 't', '_', 'p', 'r', 'o', 'c', 'e', 's', 's', 'i', 'n', 'g',
'_', 's', 't', 'r', 'a', 't', 'e', 'g', 'y', '\"', 'p', '\n', '\033', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'C',
'l', 'u', 's', 't', 'e', 'r', 'S', 'p', 'e', 'c', 'i', 'f', 'i', 'e', 'r', '\022', 'Q', '\n', '\023', 'r', 'o', 'u', 't', 'e', '_',
'l', 'o', 'o', 'k', 'u', 'p', '_', 'c', 'o', 'n', 'f', 'i', 'g', '\030', '\001', ' ', '\001', '(', '\013', '2', '!', '.', 'g', 'r', 'p',
'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', '.', 'R', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'C', 'o',
'n', 'f', 'i', 'g', 'R', '\021', 'r', 'o', 'u', 't', 'e', 'L', 'o', 'o', 'k', 'u', 'p', 'C', 'o', 'n', 'f', 'i', 'g', 'B', 'S',
'\n', '\021', 'i', 'o', '.', 'g', 'r', 'p', 'c', '.', 'l', 'o', 'o', 'k', 'u', 'p', '.', 'v', '1', 'B', '\016', 'R', 'l', 's', 'C',
'o', 'n', 'f', 'i', 'g', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'Z', ',', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'g', 'o', 'l', 'a',
'n', 'g', '.', 'o', 'r', 'g', '/', 'g', 'r', 'p', 'c', '/', 'l', 'o', 'o', 'k', 'u', 'p', '/', 'g', 'r', 'p', 'c', '_', 'l',
'o', 'o', 'k', 'u', 'p', '_', 'v', '1', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3',
};
static _upb_DefPool_Init *deps[2] = {
&google_protobuf_duration_proto_upbdefinit,
NULL
};
_upb_DefPool_Init src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit = {
deps,
&src_proto_grpc_lookup_v1_rls_config_proto_upb_file_layout,
"src/proto/grpc/lookup/v1/rls_config.proto",
UPB_STRINGVIEW_INIT(descriptor, 1816)
};

@ -0,0 +1,75 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* src/proto/grpc/lookup/v1/rls_config.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef SRC_PROTO_GRPC_LOOKUP_V1_RLS_CONFIG_PROTO_UPBDEFS_H_
#define SRC_PROTO_GRPC_LOOKUP_V1_RLS_CONFIG_PROTO_UPBDEFS_H_
#include "upb/def.h"
#include "upb/port_def.inc"
#ifdef __cplusplus
extern "C" {
#endif
#include "upb/def.h"
#include "upb/port_def.inc"
extern _upb_DefPool_Init src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit;
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_NameMatcher_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.NameMatcher");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_GrpcKeyBuilder_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.GrpcKeyBuilder");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_GrpcKeyBuilder_Name_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.GrpcKeyBuilder.Name");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_GrpcKeyBuilder_ExtraKeys_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.GrpcKeyBuilder.ExtraKeys");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_GrpcKeyBuilder_ConstantKeysEntry_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.GrpcKeyBuilder.ConstantKeysEntry");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_HttpKeyBuilder_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.HttpKeyBuilder");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_HttpKeyBuilder_ConstantKeysEntry_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.HttpKeyBuilder.ConstantKeysEntry");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_RouteLookupConfig_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.RouteLookupConfig");
}
UPB_INLINE const upb_MessageDef *grpc_lookup_v1_RouteLookupClusterSpecifier_getmsgdef(upb_DefPool *s) {
_upb_DefPool_LoadDefInit(s, &src_proto_grpc_lookup_v1_rls_config_proto_upbdefinit);
return upb_DefPool_FindMessageByName(s, "grpc.lookup.v1.RouteLookupClusterSpecifier");
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* SRC_PROTO_GRPC_LOOKUP_V1_RLS_CONFIG_PROTO_UPBDEFS_H_ */

@ -38,6 +38,7 @@
#include "src/core/ext/xds/xds_channel_args.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/ext/xds/xds_cluster.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
#include "src/core/ext/xds/xds_endpoint.h"
#include "src/core/ext/xds/xds_http_filters.h"
#include "src/core/ext/xds/xds_listener.h"
@ -2333,6 +2334,7 @@ std::string XdsClient::DumpClientConfigBinary() {
void XdsClientGlobalInit() {
g_mu = new Mutex;
XdsHttpFilterRegistry::Init();
XdsClusterSpecifierPluginRegistry::Init();
}
// TODO(roth): Find a better way to clear the fallback config that does
@ -2343,6 +2345,7 @@ void XdsClientGlobalShutdown() ABSL_NO_THREAD_SAFETY_ANALYSIS {
delete g_mu;
g_mu = nullptr;
XdsHttpFilterRegistry::Shutdown();
XdsClusterSpecifierPluginRegistry::Shutdown();
}
namespace {

@ -0,0 +1,144 @@
//
// Copyright 2022 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/xds/xds_cluster_specifier_plugin.h"
#include "absl/strings/str_format.h"
#include "envoy/extensions/filters/http/router/v3/router.upb.h"
#include "envoy/extensions/filters/http/router/v3/router.upbdefs.h"
#include "google/protobuf/duration.upb.h"
#include "upb/json_encode.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/proto/grpc/lookup/v1/rls_config.upb.h"
#include "src/proto/grpc/lookup/v1/rls_config.upbdefs.h"
namespace grpc_core {
const char* kXdsRouteLookupClusterSpecifierPluginConfigName =
"grpc.lookup.v1.RouteLookupClusterSpecifier";
void XdsRouteLookupClusterSpecifierPlugin::PopulateSymtab(
upb_DefPool* symtab) const {
grpc_lookup_v1_RouteLookupConfig_getmsgdef(symtab);
}
absl::StatusOr<Json>
XdsRouteLookupClusterSpecifierPlugin::GenerateLoadBalancingPolicyConfig(
upb_StringView serialized_plugin_config, upb_Arena* arena,
upb_DefPool* symtab) const {
const auto* specifier = grpc_lookup_v1_RouteLookupClusterSpecifier_parse(
serialized_plugin_config.data, serialized_plugin_config.size, arena);
if (specifier == nullptr) {
return absl::InvalidArgumentError("Could not parse plugin config");
}
const auto* plugin_config =
grpc_lookup_v1_RouteLookupClusterSpecifier_route_lookup_config(specifier);
if (plugin_config == nullptr) {
return absl::InvalidArgumentError(
"Could not get route lookup config from route lookup cluster "
"specifier");
}
upb::Status status;
const upb_MessageDef* msg_type =
grpc_lookup_v1_RouteLookupConfig_getmsgdef(symtab);
size_t json_size = upb_JsonEncode(plugin_config, msg_type, symtab, 0, nullptr,
0, status.ptr());
if (json_size == static_cast<size_t>(-1)) {
return absl::InvalidArgumentError(
absl::StrCat("failed to dump proto to JSON: ",
upb_Status_ErrorMessage(status.ptr())));
}
void* buf = upb_Arena_Malloc(arena, json_size + 1);
upb_JsonEncode(plugin_config, msg_type, symtab, 0,
reinterpret_cast<char*>(buf), json_size + 1, status.ptr());
Json::Object rls_policy;
grpc_error_handle error = GRPC_ERROR_NONE;
rls_policy["routeLookupConfig"] =
Json::Parse(reinterpret_cast<char*>(buf), &error);
GPR_ASSERT(error == GRPC_ERROR_NONE);
Json::Object cds_policy;
cds_policy["cds_experimental"] = Json::Object();
Json::Array child_policy;
child_policy.emplace_back(std::move(cds_policy));
rls_policy["childPolicy"] = std::move(child_policy);
rls_policy["childPolicyConfigTargetFieldName"] = "cluster";
Json::Object policy;
policy["rls_experimental"] = std::move(rls_policy);
Json::Array policies;
policies.emplace_back(std::move(policy));
return Json(policies);
}
namespace {
using PluginRegistryMap =
std::map<absl::string_view, std::unique_ptr<XdsClusterSpecifierPluginImpl>>;
PluginRegistryMap* g_plugin_registry = nullptr;
} // namespace
void XdsClusterSpecifierPluginRegistry::PopulateSymtab(upb_DefPool* symtab) {
for (const auto& p : *g_plugin_registry) {
p.second->PopulateSymtab(symtab);
}
}
void XdsClusterSpecifierPluginRegistry::RegisterPlugin(
std::unique_ptr<XdsClusterSpecifierPluginImpl> plugin,
absl::string_view config_proto_type_name) {
(*g_plugin_registry)[config_proto_type_name] = std::move(plugin);
}
absl::StatusOr<std::string>
XdsClusterSpecifierPluginRegistry::GenerateLoadBalancingPolicyConfig(
absl::string_view proto_type_name, upb_StringView serialized_plugin_config,
upb_Arena* arena, upb_DefPool* symtab) {
auto it = g_plugin_registry->find(proto_type_name);
if (it == g_plugin_registry->end()) {
return absl::InvalidArgumentError(
"Unable to locate the cluster specifier plugin in the registry");
}
auto lb_policy_config = it->second->GenerateLoadBalancingPolicyConfig(
serialized_plugin_config, arena, symtab);
if (!lb_policy_config.ok()) return lb_policy_config.status();
grpc_error_handle parse_error = GRPC_ERROR_NONE;
LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(*lb_policy_config,
&parse_error);
if (parse_error != GRPC_ERROR_NONE) {
absl::Status status = absl::InvalidArgumentError(absl::StrCat(
proto_type_name,
" ClusterSpecifierPlugin returned invalid LB policy config: ",
grpc_error_std_string(parse_error)));
GRPC_ERROR_UNREF(parse_error);
return status;
}
return lb_policy_config->Dump();
}
void XdsClusterSpecifierPluginRegistry::Init() {
g_plugin_registry = new PluginRegistryMap;
RegisterPlugin(absl::make_unique<XdsRouteLookupClusterSpecifierPlugin>(),
kXdsRouteLookupClusterSpecifierPluginConfigName);
}
void XdsClusterSpecifierPluginRegistry::Shutdown() { delete g_plugin_registry; }
} // namespace grpc_core

@ -0,0 +1,81 @@
//
// Copyright 2022 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.
//
#ifndef GRPC_CORE_EXT_XDS_XDS_CLUSTER_SPECIFIER_PLUGIN_H
#define GRPC_CORE_EXT_XDS_XDS_CLUSTER_SPECIFIER_PLUGIN_H
#include <grpc/support/port_platform.h>
#include <memory>
#include <set>
#include <string>
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/any.upb.h"
#include "upb/def.h"
#include <grpc/grpc.h>
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/json/json.h"
namespace grpc_core {
class XdsClusterSpecifierPluginImpl {
public:
virtual ~XdsClusterSpecifierPluginImpl() = default;
// Loads the proto message into the upb symtab.
virtual void PopulateSymtab(upb_DefPool* symtab) const = 0;
// Returns the LB policy config in JSON form.
virtual absl::StatusOr<Json> GenerateLoadBalancingPolicyConfig(
upb_StringView serialized_plugin_config, upb_Arena* arena,
upb_DefPool* symtab) const = 0;
};
class XdsRouteLookupClusterSpecifierPlugin
: public XdsClusterSpecifierPluginImpl {
void PopulateSymtab(upb_DefPool* symtab) const override;
absl::StatusOr<Json> GenerateLoadBalancingPolicyConfig(
upb_StringView serialized_plugin_config, upb_Arena* arena,
upb_DefPool* symtab) const override;
};
class XdsClusterSpecifierPluginRegistry {
public:
static void RegisterPlugin(
std::unique_ptr<XdsClusterSpecifierPluginImpl> plugin,
absl::string_view config_proto_type_name);
static void PopulateSymtab(upb_DefPool* symtab);
static absl::StatusOr<std::string> GenerateLoadBalancingPolicyConfig(
absl::string_view proto_type_name,
upb_StringView serialized_plugin_config, upb_Arena* arena,
upb_DefPool* symtab);
// Global init and shutdown.
static void Init();
static void Shutdown();
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_XDS_XDS_CLUSTER_SPECIFIER_PLUGIN_H

@ -365,23 +365,23 @@ grpc_error_handle CommonTlsContext::Parse(
&errors);
}
grpc_error_handle ExtractHttpFilterTypeName(const XdsEncodingContext& context,
grpc_error_handle ExtractExtensionTypeName(const XdsEncodingContext& context,
const google_protobuf_Any* any,
absl::string_view* filter_type) {
*filter_type = UpbStringToAbsl(google_protobuf_Any_type_url(any));
if (*filter_type == "type.googleapis.com/xds.type.v3.TypedStruct" ||
*filter_type == "type.googleapis.com/udpa.type.v1.TypedStruct") {
absl::string_view* extension_type) {
*extension_type = UpbStringToAbsl(google_protobuf_Any_type_url(any));
if (*extension_type == "type.googleapis.com/xds.type.v3.TypedStruct" ||
*extension_type == "type.googleapis.com/udpa.type.v1.TypedStruct") {
upb_StringView any_value = google_protobuf_Any_value(any);
const auto* typed_struct = xds_type_v3_TypedStruct_parse(
any_value.data, any_value.size, context.arena);
if (typed_struct == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"could not parse TypedStruct from filter config");
"could not parse TypedStruct from extension");
}
*filter_type =
*extension_type =
UpbStringToAbsl(xds_type_v3_TypedStruct_type_url(typed_struct));
}
*filter_type = absl::StripPrefix(*filter_type, "type.googleapis.com/");
*extension_type = absl::StripPrefix(*extension_type, "type.googleapis.com/");
return GRPC_ERROR_NONE;
}

@ -86,9 +86,9 @@ struct CommonTlsContext {
CommonTlsContext* common_tls_context);
};
grpc_error_handle ExtractHttpFilterTypeName(const XdsEncodingContext& context,
grpc_error_handle ExtractExtensionTypeName(const XdsEncodingContext& context,
const google_protobuf_Any* any,
absl::string_view* filter_type);
absl::string_view* extension_type);
} // namespace grpc_core

@ -332,7 +332,7 @@ grpc_error_handle HttpConnectionManagerParse(
}
absl::string_view filter_type;
grpc_error_handle error =
ExtractHttpFilterTypeName(context, any, &filter_type);
ExtractExtensionTypeName(context, any, &filter_type);
if (error != GRPC_ERROR_NONE) return error;
const XdsHttpFilterImpl* filter_impl =
XdsHttpFilterRegistry::GetFilterForType(filter_type);

@ -23,6 +23,7 @@
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "envoy/config/core/v3/base.upb.h"
#include "envoy/config/core/v3/extension.upb.h"
#include "envoy/config/route/v3/route.upb.h"
#include "envoy/config/route/v3/route.upbdefs.h"
#include "envoy/config/route/v3/route_components.upb.h"
@ -39,12 +40,14 @@
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_api.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_routing.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -57,6 +60,15 @@ bool XdsRbacEnabled() {
return parse_succeeded && parsed_value;
}
// TODO(donnadionne): Remove once RLS is no longer experimental
bool XdsRlsEnabled() {
char* value = gpr_getenv("GRPC_EXPERIMENTAL_XDS_RLS_LB");
bool parsed_value;
bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value);
gpr_free(value);
return parse_succeeded && parsed_value;
}
//
// XdsRouteConfigResource::RetryPolicy
//
@ -212,12 +224,19 @@ std::string XdsRouteConfigResource::Route::RouteAction::ToString() const {
if (retry_policy.has_value()) {
contents.push_back(absl::StrCat("retry_policy=", retry_policy->ToString()));
}
if (!cluster_name.empty()) {
contents.push_back(absl::StrFormat("Cluster name: %s", cluster_name));
}
for (const ClusterWeight& cluster_weight : weighted_clusters) {
if (action.index() == kClusterIndex) {
contents.push_back(
absl::StrFormat("Cluster name: %s", absl::get<kClusterIndex>(action)));
} else if (action.index() == kWeightedClustersIndex) {
auto& action_weighted_clusters = absl::get<kWeightedClustersIndex>(action);
for (const ClusterWeight& cluster_weight : action_weighted_clusters) {
contents.push_back(cluster_weight.ToString());
}
} else if (action.index() == kClusterSpecifierPluginIndex) {
contents.push_back(
absl::StrFormat("Cluster specifier plugin name: %s",
absl::get<kClusterSpecifierPluginIndex>(action)));
}
if (max_stream_duration.has_value()) {
contents.push_back(max_stream_duration->ToString());
}
@ -258,35 +277,78 @@ std::string XdsRouteConfigResource::Route::ToString() const {
//
std::string XdsRouteConfigResource::ToString() const {
std::vector<std::string> vhosts;
std::vector<std::string> parts;
for (const VirtualHost& vhost : virtual_hosts) {
vhosts.push_back(
parts.push_back(
absl::StrCat("vhost={\n"
" domains=[",
absl::StrJoin(vhost.domains, ", "),
"]\n"
" routes=[\n"));
for (const XdsRouteConfigResource::Route& route : vhost.routes) {
vhosts.push_back(" {\n");
vhosts.push_back(route.ToString());
vhosts.push_back("\n }\n");
parts.push_back(" {\n");
parts.push_back(route.ToString());
parts.push_back("\n }\n");
}
vhosts.push_back(" ]\n");
vhosts.push_back(" typed_per_filter_config={\n");
parts.push_back(" ]\n");
parts.push_back(" typed_per_filter_config={\n");
for (const auto& p : vhost.typed_per_filter_config) {
const std::string& name = p.first;
const auto& config = p.second;
vhosts.push_back(
absl::StrCat(" ", name, "=", config.ToString(), "\n"));
parts.push_back(absl::StrCat(" ", name, "=", config.ToString(), "\n"));
}
parts.push_back(" }\n");
parts.push_back("]\n");
}
vhosts.push_back(" }\n");
vhosts.push_back("]\n");
parts.push_back("cluster_specifier_plugins={\n");
for (const auto& it : cluster_specifier_plugin_map) {
parts.push_back(absl::StrFormat("%s={%s}\n", it.first, it.second));
}
return absl::StrJoin(vhosts, "");
parts.push_back("}");
return absl::StrJoin(parts, "");
}
namespace {
grpc_error_handle ClusterSpecifierPluginParse(
const XdsEncodingContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config,
XdsRouteConfigResource* rds_update) {
size_t num_cluster_specifier_plugins;
const envoy_config_route_v3_ClusterSpecifierPlugin* const*
cluster_specifier_plugin =
envoy_config_route_v3_RouteConfiguration_cluster_specifier_plugins(
route_config, &num_cluster_specifier_plugins);
for (size_t i = 0; i < num_cluster_specifier_plugins; ++i) {
const envoy_config_core_v3_TypedExtensionConfig* extension =
envoy_config_route_v3_ClusterSpecifierPlugin_extension(
cluster_specifier_plugin[i]);
std::string name = UpbStringToStdString(
envoy_config_core_v3_TypedExtensionConfig_name(extension));
const google_protobuf_Any* any =
envoy_config_core_v3_TypedExtensionConfig_typed_config(extension);
if (any == nullptr) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"could not obtrain TypedExtensionConfig for plugin config");
}
absl::string_view plugin_type;
grpc_error_handle error =
ExtractExtensionTypeName(context, any, &plugin_type);
if (error != GRPC_ERROR_NONE) return error;
// Find the plugin and generate the policy.
auto lb_policy_config =
XdsClusterSpecifierPluginRegistry::GenerateLoadBalancingPolicyConfig(
plugin_type, google_protobuf_Any_value(any), context.arena,
context.symtab);
if (!lb_policy_config.ok()) {
return absl_status_to_grpc_error(lb_policy_config.status());
}
rds_update->cluster_specifier_plugin_map[std::move(name)] =
std::move(lb_policy_config.value());
}
return GRPC_ERROR_NONE;
}
grpc_error_handle RoutePathMatchParse(
const envoy_config_route_v3_RouteMatch* match,
XdsRouteConfigResource::Route* route, bool* ignore_route) {
@ -523,7 +585,7 @@ grpc_error_handle ParseTypedPerFilterConfig(
}
}
grpc_error_handle error =
ExtractHttpFilterTypeName(context, any, &filter_type);
ExtractExtensionTypeName(context, any, &filter_type);
if (error != GRPC_ERROR_NONE) return error;
const XdsHttpFilterImpl* filter_impl =
XdsHttpFilterRegistry::GetFilterForType(filter_type);
@ -623,19 +685,27 @@ grpc_error_handle RetryPolicyParse(
grpc_error_handle RouteActionParse(
const XdsEncodingContext& context,
const envoy_config_route_v3_Route* route_msg,
const std::map<std::string /*cluster_specifier_plugin_name*/,
std::string /*LB policy config*/>&
cluster_specifier_plugin_map,
XdsRouteConfigResource::Route::RouteAction* route, bool* ignore_route) {
const envoy_config_route_v3_RouteAction* route_action =
envoy_config_route_v3_Route_route(route_msg);
// Get the cluster or weighted_clusters in the RouteAction.
if (envoy_config_route_v3_RouteAction_has_cluster(route_action)) {
route->cluster_name = UpbStringToStdString(
std::string cluster_name = UpbStringToStdString(
envoy_config_route_v3_RouteAction_cluster(route_action));
if (route->cluster_name.empty()) {
if (cluster_name.empty()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"RouteAction cluster contains empty cluster name.");
}
route->action
.emplace<XdsRouteConfigResource::Route::RouteAction::kClusterIndex>(
std::move(cluster_name));
} else if (envoy_config_route_v3_RouteAction_has_weighted_clusters(
route_action)) {
std::vector<XdsRouteConfigResource::Route::RouteAction::ClusterWeight>
action_weighted_clusters;
const envoy_config_route_v3_WeightedCluster* weighted_cluster =
envoy_config_route_v3_RouteAction_weighted_clusters(route_action);
uint32_t total_weight = 100;
@ -682,18 +752,39 @@ grpc_error_handle RouteActionParse(
&cluster.typed_per_filter_config);
if (error != GRPC_ERROR_NONE) return error;
}
route->weighted_clusters.emplace_back(std::move(cluster));
action_weighted_clusters.emplace_back(std::move(cluster));
}
if (total_weight != sum_of_weights) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"RouteAction weighted_cluster has incorrect total weight");
}
if (route->weighted_clusters.empty()) {
if (action_weighted_clusters.empty()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"RouteAction weighted_cluster has no valid clusters specified.");
}
route->action = std::move(action_weighted_clusters);
} else if (XdsRlsEnabled() &&
envoy_config_route_v3_RouteAction_has_cluster_specifier_plugin(
route_action)) {
std::string plugin_name = UpbStringToStdString(
envoy_config_route_v3_RouteAction_cluster_specifier_plugin(
route_action));
if (plugin_name.empty()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"RouteAction cluster contains empty cluster specifier plugin name.");
}
if (cluster_specifier_plugin_map.find(plugin_name) ==
cluster_specifier_plugin_map.end()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"RouteAction cluster contains cluster specifier plugin name not "
"configured.");
}
route->action.emplace<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(
std::move(plugin_name));
} else {
// No cluster or weighted_clusters found in RouteAction, ignore this route.
// No cluster or weighted_clusters or plugin found in RouteAction, ignore
// this route.
*ignore_route = true;
}
if (!*ignore_route) {
@ -808,6 +899,12 @@ grpc_error_handle XdsRouteConfigResource::Parse(
const XdsEncodingContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config,
XdsRouteConfigResource* rds_update) {
// Get the cluster spcifier plugins
if (XdsRlsEnabled()) {
grpc_error_handle error =
ClusterSpecifierPluginParse(context, route_config, rds_update);
if (error != GRPC_ERROR_NONE) return error;
}
// Get the virtual hosts.
size_t num_virtual_hosts;
const envoy_config_route_v3_VirtualHost* const* virtual_hosts =
@ -862,6 +959,12 @@ grpc_error_handle XdsRouteConfigResource::Parse(
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"No route found in the virtual host.");
}
// Build a set of cluster_specifier_plugin configured to make sure each is
// actually referenced by a route action.
std::set<absl::string_view> cluster_specifier_plugins;
for (auto& plugin : rds_update->cluster_specifier_plugin_map) {
cluster_specifier_plugins.emplace(plugin.first);
}
// Loop over the whole list of routes
for (size_t j = 0; j < num_routes; ++j) {
const envoy_config_route_v3_RouteMatch* match =
@ -889,14 +992,23 @@ grpc_error_handle XdsRouteConfigResource::Parse(
route.action.emplace<XdsRouteConfigResource::Route::RouteAction>();
auto& route_action =
absl::get<XdsRouteConfigResource::Route::RouteAction>(route.action);
error =
RouteActionParse(context, routes[j], &route_action, &ignore_route);
error = RouteActionParse(context, routes[j],
rds_update->cluster_specifier_plugin_map,
&route_action, &ignore_route);
if (error != GRPC_ERROR_NONE) return error;
if (ignore_route) continue;
if (route_action.retry_policy == absl::nullopt &&
retry_policy != nullptr) {
route_action.retry_policy = virtual_host_retry_policy;
}
// Mark off plugins used in route action.
std::string* cluster_specifier_action =
absl::get_if<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(
&route_action.action);
if (cluster_specifier_action != nullptr) {
cluster_specifier_plugins.erase(*cluster_specifier_action);
}
} else if (envoy_config_route_v3_Route_has_non_forwarding_action(
routes[j])) {
route.action
@ -918,6 +1030,12 @@ grpc_error_handle XdsRouteConfigResource::Parse(
if (vhost.routes.empty()) {
return GRPC_ERROR_CREATE_FROM_STATIC_STRING("No valid routes specified.");
}
// For plugins not used in route action, delete from the update to prevent
// further use.
for (auto& unused_plugin : cluster_specifier_plugins) {
rds_update->cluster_specifier_plugin_map.erase(
std::string(unused_plugin));
}
}
return GRPC_ERROR_NONE;
}

@ -30,6 +30,7 @@
#include "re2/re2.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_http_filters.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
@ -67,8 +68,6 @@ struct XdsRouteConfigResource {
std::string ToString() const;
};
// TODO(donnadionne): When we can use absl::variant<>, consider using that
// for: PathMatcher, HeaderMatcher, cluster_name and weighted_clusters
struct Route {
// Matchers for this route.
struct Matchers {
@ -130,10 +129,11 @@ struct XdsRouteConfigResource {
absl::optional<RetryPolicy> retry_policy;
// Action for this route.
// TODO(roth): When we can use absl::variant<>, consider using that
// here, to enforce the fact that only one of the two fields can be set.
std::string cluster_name;
std::vector<ClusterWeight> weighted_clusters;
static constexpr size_t kClusterIndex = 0;
static constexpr size_t kWeightedClustersIndex = 1;
static constexpr size_t kClusterSpecifierPluginIndex = 2;
absl::variant<std::string, std::vector<ClusterWeight>, std::string>
action;
// Storing the timeout duration from route action:
// RouteAction.max_stream_duration.grpc_timeout_header_max or
// RouteAction.max_stream_duration.max_stream_duration if the former is
@ -142,9 +142,7 @@ struct XdsRouteConfigResource {
bool operator==(const RouteAction& other) const {
return hash_policies == other.hash_policies &&
retry_policy == other.retry_policy &&
cluster_name == other.cluster_name &&
weighted_clusters == other.weighted_clusters &&
retry_policy == other.retry_policy && action == other.action &&
max_stream_duration == other.max_stream_duration;
}
std::string ToString() const;
@ -178,9 +176,13 @@ struct XdsRouteConfigResource {
};
std::vector<VirtualHost> virtual_hosts;
std::map<std::string /*cluster_specifier_plugin_name*/,
std::string /*LB policy config*/>
cluster_specifier_plugin_map;
bool operator==(const XdsRouteConfigResource& other) const {
return virtual_hosts == other.virtual_hosts;
return virtual_hosts == other.virtual_hosts &&
cluster_specifier_plugin_map == other.cluster_specifier_plugin_map;
}
std::string ToString() const;
@ -207,6 +209,7 @@ class XdsRouteConfigResourceType
void InitUpbSymtab(upb_DefPool* symtab) const override {
envoy_config_route_v3_RouteConfiguration_getmsgdef(symtab);
XdsClusterSpecifierPluginRegistry::PopulateSymtab(symtab);
}
};

@ -59,9 +59,12 @@ class CallTracer {
virtual void RecordReceivedInitialMetadata(
grpc_metadata_batch* recv_initial_metadata, uint32_t flags) = 0;
virtual void RecordReceivedMessage(const ByteStream& recv_message) = 0;
// If the call was cancelled before the recv_trailing_metadata op
// was started, recv_trailing_metadata and transport_stream_stats
// will be null.
virtual void RecordReceivedTrailingMetadata(
absl::Status status, grpc_metadata_batch* recv_trailing_metadata,
const grpc_transport_stream_stats& transport_stream_stats) = 0;
const grpc_transport_stream_stats* transport_stream_stats) = 0;
virtual void RecordCancel(grpc_error_handle cancel_error) = 0;
// Should be the last API call to the object. Once invoked, the tracer
// library is free to destroy the object.

@ -179,7 +179,8 @@ class ClientCallData::PollContext {
} else {
destroy_md = false;
}
gpr_log(GPR_DEBUG, "Respond to trailing metadata: %s", self_->recv_trailing_metadata_->DebugString().c_str());
gpr_log(GPR_DEBUG, "Respond to trailing metadata: %s",
self_->recv_trailing_metadata_->DebugString().c_str());
self_->recv_trailing_state_ = RecvTrailingState::kResponded;
call_closures_.Add(
absl::exchange(self_->original_recv_trailing_metadata_ready_,
@ -189,9 +190,11 @@ class ClientCallData::PollContext {
switch (self_->recv_initial_metadata_->state) {
case RecvInitialMetadata::kInitial:
case RecvInitialMetadata::kGotLatch:
self_->recv_initial_metadata_->state = RecvInitialMetadata::kRespondedToTrailingMetadataPriorToHook;
self_->recv_initial_metadata_->state = RecvInitialMetadata::
kRespondedToTrailingMetadataPriorToHook;
break;
case RecvInitialMetadata::kRespondedToTrailingMetadataPriorToHook:
case RecvInitialMetadata::
kRespondedToTrailingMetadataPriorToHook:
abort(); // not reachable
break;
case RecvInitialMetadata::kHookedWaitingForLatch:
@ -229,13 +232,15 @@ class ClientCallData::PollContext {
switch (self_->recv_initial_metadata_->state) {
case RecvInitialMetadata::kInitial:
case RecvInitialMetadata::kGotLatch:
self_->recv_initial_metadata_->state = RecvInitialMetadata::kRespondedToTrailingMetadataPriorToHook;
self_->recv_initial_metadata_->state = RecvInitialMetadata::
kRespondedToTrailingMetadataPriorToHook;
break;
case RecvInitialMetadata::kHookedWaitingForLatch:
case RecvInitialMetadata::kHookedAndGotLatch:
case RecvInitialMetadata::kResponded:
break;
case RecvInitialMetadata::kRespondedToTrailingMetadataPriorToHook:
case RecvInitialMetadata::
kRespondedToTrailingMetadataPriorToHook:
abort(); // not reachable
break;
case RecvInitialMetadata::kCompleteWaitingForLatch:
@ -285,7 +290,8 @@ class ClientCallData::PollContext {
// that up. (note: that situation isn't possible once we finish the
// promise transition).
if (self_->recv_trailing_state_ == RecvTrailingState::kComplete) {
gpr_log(GPR_DEBUG, "Respond to trailing metadata: %s", self_->recv_trailing_metadata_->DebugString().c_str());
gpr_log(GPR_DEBUG, "Respond to trailing metadata: %s",
self_->recv_trailing_metadata_->DebugString().c_str());
self_->recv_trailing_state_ = RecvTrailingState::kResponded;
call_closures_.Add(
absl::exchange(self_->original_recv_trailing_metadata_ready_,
@ -720,9 +726,13 @@ void ClientCallData::RecvTrailingMetadataReadyCallback(
}
void ClientCallData::RecvTrailingMetadataReady(grpc_error_handle error) {
// If we were cancelled prior to receiving this callback, we should simply
// forward the callback up with the same error.
if (recv_trailing_state_ == RecvTrailingState::kCancelled) {
Closure::Run(DEBUG_LOCATION, original_recv_trailing_metadata_ready_,
GRPC_ERROR_REF(cancelled_error_));
if (grpc_closure* call_closure =
absl::exchange(original_recv_trailing_metadata_ready_, nullptr)) {
Closure::Run(DEBUG_LOCATION, call_closure, GRPC_ERROR_REF(error));
}
return;
}
// If there was an error, we'll put that into the trailing metadata and

@ -136,6 +136,7 @@ static void on_writable(void* acp, grpc_error_handle error) {
int done;
grpc_endpoint** ep = ac->ep;
grpc_closure* closure = ac->closure;
std::string addr_str = ac->addr_str;
grpc_fd* fd;
(void)GRPC_ERROR_REF(error);
@ -221,8 +222,7 @@ finish:
std::string description =
absl::StrCat("Failed to connect to remote host: ", str);
error = grpc_error_set_str(error, GRPC_ERROR_STR_DESCRIPTION, description);
error =
grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, ac->addr_str);
error = grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS, addr_str);
}
if (done) {
// This is safe even outside the lock, because "done", the sentinel, is

@ -45,9 +45,9 @@ bool ExtractJsonNumber(const Json& json, absl::string_view field_name,
NumericType* output,
std::vector<grpc_error_handle>* error_list) {
static_assert(std::is_integral<NumericType>::value, "Integral required");
if (json.type() != Json::Type::NUMBER) {
error_list->push_back(GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("field:", field_name, " error:type should be NUMBER")));
if (json.type() != Json::Type::NUMBER && json.type() != Json::Type::STRING) {
error_list->push_back(GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"field:", field_name, " error:type should be NUMBER or STRING")));
return false;
}
if (!absl::SimpleAtoi(json.string_value(), output)) {

@ -1939,8 +1939,16 @@ static void ssl_keylogging_callback(const SSL* ssl, const char* info) {
factory->key_logger->LogSessionKeys(ssl_context, info);
}
// This callback is invoked when the CRL has been verified and will soft-fail
// errors in verification depending on certain error types.
static int verify_cb(int ok, X509_STORE_CTX* ctx) {
int cert_error = X509_STORE_CTX_get_error(ctx);
if (cert_error == X509_V_ERR_UNABLE_TO_GET_CRL) {
gpr_log(
GPR_INFO,
"Certificate verification failed to get CRL files. Ignoring error.");
return 1;
}
if (cert_error != 0) {
gpr_log(GPR_ERROR, "Certificate verify failed with code %d", cert_error);
}

@ -95,7 +95,7 @@ OpenCensusCallTracer::OpenCensusCallAttemptTracer::OpenCensusCallAttemptTracer(
void OpenCensusCallTracer::OpenCensusCallAttemptTracer::
RecordSendInitialMetadata(grpc_metadata_batch* send_initial_metadata,
uint32_t /* flags */) {
uint32_t /*flags*/) {
char tracing_buf[kMaxTraceContextLen];
size_t tracing_len = TraceContextSerialize(context_.Context(), tracing_buf,
kMaxTraceContextLen);
@ -114,12 +114,12 @@ void OpenCensusCallTracer::OpenCensusCallAttemptTracer::
}
void OpenCensusCallTracer::OpenCensusCallAttemptTracer::RecordSendMessage(
const grpc_core::ByteStream& /* send_message */) {
const grpc_core::ByteStream& /*send_message*/) {
++sent_message_count_;
}
void OpenCensusCallTracer::OpenCensusCallAttemptTracer::RecordReceivedMessage(
const grpc_core::ByteStream& /* recv_message */) {
const grpc_core::ByteStream& /*recv_message*/) {
++recv_message_count_;
}
@ -140,21 +140,25 @@ void FilterTrailingMetadata(grpc_metadata_batch* b, uint64_t* elapsed_time) {
void OpenCensusCallTracer::OpenCensusCallAttemptTracer::
RecordReceivedTrailingMetadata(
absl::Status status, grpc_metadata_batch* recv_trailing_metadata,
const grpc_transport_stream_stats& transport_stream_stats) {
FilterTrailingMetadata(recv_trailing_metadata, &elapsed_time_);
const uint64_t request_size = transport_stream_stats.outgoing.data_bytes;
const uint64_t response_size = transport_stream_stats.incoming.data_bytes;
const grpc_transport_stream_stats* transport_stream_stats) {
status_code_ = status.code();
if (recv_trailing_metadata == nullptr || transport_stream_stats == nullptr) {
return;
}
uint64_t elapsed_time = 0;
FilterTrailingMetadata(recv_trailing_metadata, &elapsed_time);
std::vector<std::pair<opencensus::tags::TagKey, std::string>> tags =
context_.tags().tags();
tags.emplace_back(ClientMethodTagKey(), std::string(parent_->method_));
status_code_ = status.code();
std::string final_status = absl::StatusCodeToString(status_code_);
tags.emplace_back(ClientStatusTagKey(), final_status);
::opencensus::stats::Record(
{{RpcClientSentBytesPerRpc(), static_cast<double>(request_size)},
{RpcClientReceivedBytesPerRpc(), static_cast<double>(response_size)},
{{RpcClientSentBytesPerRpc(),
static_cast<double>(transport_stream_stats->outgoing.data_bytes)},
{RpcClientReceivedBytesPerRpc(),
static_cast<double>(transport_stream_stats->incoming.data_bytes)},
{RpcClientServerLatency(),
ToDoubleMilliseconds(absl::Nanoseconds(elapsed_time_))}},
ToDoubleMilliseconds(absl::Nanoseconds(elapsed_time))}},
tags);
}
@ -165,7 +169,7 @@ void OpenCensusCallTracer::OpenCensusCallAttemptTracer::RecordCancel(
}
void OpenCensusCallTracer::OpenCensusCallAttemptTracer::RecordEnd(
const gpr_timespec& /* latency */) {
const gpr_timespec& /*latency*/) {
double latency_ms = absl::ToDoubleMilliseconds(absl::Now() - start_time_);
std::vector<std::pair<opencensus::tags::TagKey, std::string>> tags =
context_.tags().tags();

@ -33,25 +33,23 @@ class OpenCensusCallTracer : public grpc_core::CallTracer {
OpenCensusCallAttemptTracer(OpenCensusCallTracer* parent,
uint64_t attempt_num, bool is_transparent_retry,
bool arena_allocated);
void RecordSendInitialMetadata(
grpc_metadata_batch* /* send_initial_metadata */,
uint32_t /* flags */) override;
void RecordOnDoneSendInitialMetadata(gpr_atm* /* peer_string */) override {}
void RecordSendInitialMetadata(grpc_metadata_batch* send_initial_metadata,
uint32_t /*flags*/) override;
void RecordOnDoneSendInitialMetadata(gpr_atm* /*peer_string*/) override {}
void RecordSendTrailingMetadata(
grpc_metadata_batch* /* send_trailing_metadata */) override {}
grpc_metadata_batch* /*send_trailing_metadata*/) override {}
void RecordSendMessage(
const grpc_core::ByteStream& /* send_message */) override;
const grpc_core::ByteStream& /*send_message*/) override;
void RecordReceivedInitialMetadata(
grpc_metadata_batch* /* recv_initial_metadata */,
uint32_t /* flags */) override {}
grpc_metadata_batch* /*recv_initial_metadata*/,
uint32_t /*flags*/) override {}
void RecordReceivedMessage(
const grpc_core::ByteStream& /* recv_message */) override;
const grpc_core::ByteStream& /*recv_message*/) override;
void RecordReceivedTrailingMetadata(
absl::Status /* status */, grpc_metadata_batch* recv_trailing_metadata,
const grpc_transport_stream_stats& /* transport_stream_stats */)
override;
absl::Status status, grpc_metadata_batch* recv_trailing_metadata,
const grpc_transport_stream_stats* transport_stream_stats) override;
void RecordCancel(grpc_error_handle cancel_error) override;
void RecordEnd(const gpr_timespec& /* latency */) override;
void RecordEnd(const gpr_timespec& /*latency*/) override;
CensusContext* context() { return &context_; }
@ -65,8 +63,6 @@ class OpenCensusCallTracer : public grpc_core::CallTracer {
CensusContext context_;
// Start time (for measuring latency).
absl::Time start_time_;
// Server elapsed time in nanoseconds.
uint64_t elapsed_time_ = 0;
// Number of messages in this RPC.
uint64_t recv_message_count_ = 0;
uint64_t sent_message_count_ = 0;

@ -28,7 +28,21 @@ grpc_proto_library(
well_known_protos = True,
)
grpc_proto_library(
name = "rls_config_proto",
srcs = ["rls_config.proto"],
well_known_protos = True,
)
proto_library(
name = "rls_proto_descriptor",
srcs = ["rls.proto"],
)
proto_library(
name = "rls_config_proto_descriptor",
srcs = ["rls_config.proto"],
deps = [
"@com_google_protobuf//:duration_proto",
],
)

@ -197,6 +197,7 @@ grpc_proto_library(
well_known_protos = True,
deps = [
"base_proto",
"extension_proto",
"percent_proto",
"range_proto",
"regex_proto",

@ -19,6 +19,7 @@ syntax = "proto3";
package envoy.config.route.v3;
import "src/proto/grpc/testing/xds/v3/base.proto";
import "src/proto/grpc/testing/xds/v3/extension.proto";
import "src/proto/grpc/testing/xds/v3/regex.proto";
import "src/proto/grpc/testing/xds/v3/percent.proto";
import "src/proto/grpc/testing/xds/v3/range.proto";
@ -268,6 +269,13 @@ message RouteAction {
// :ref:`traffic splitting <config_http_conn_man_route_table_traffic_splitting_split>`
// for additional documentation.
WeightedCluster weighted_clusters = 3;
// Name of the cluster specifier plugin to use to determine the cluster for
// requests on this route. The plugin name must be defined in the associated
// :ref:`envoy_v3_api_field_config.route.v3.RouteConfiguration.cluster_specifier_plugins`
// in the
// :ref:`envoy_v3_api_field_config.core.v3.TypedExtensionConfig.name` field.
string cluster_specifier_plugin = 37;
}
message HashPolicy {
@ -435,6 +443,12 @@ message HeaderMatcher {
message QueryParameterMatcher {
}
// Configuration for a cluster specifier plugin.
message ClusterSpecifierPlugin {
// The name of the plugin and its opaque configuration.
core.v3.TypedExtensionConfig extension = 1;
}
// [#protodoc-title: HTTP route configuration]
// * Routing :ref:`architecture overview <arch_overview_http_routing>`
// * HTTP :ref:`router filter <config_http_filters_router>`
@ -449,6 +463,11 @@ message RouteConfiguration {
// An array of virtual hosts that make up the route table.
repeated VirtualHost virtual_hosts = 2;
// A list of plugins and their configurations which may be used by a
// :ref:`envoy_v3_api_field_config.route.v3.RouteAction.cluster_specifier_plugin`
// within the route. All *extension.name* fields in this list must be unique.
repeated ClusterSpecifierPlugin cluster_specifier_plugins = 12;
}
message RedirectAction {

@ -235,6 +235,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/upb-generated/src/proto/grpc/health/v1/health.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c',
'src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c',
'src/core/ext/upb-generated/udpa/annotations/migrate.upb.c',
'src/core/ext/upb-generated/udpa/annotations/security.upb.c',
'src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c',
@ -369,6 +370,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/upbdefs-generated/google/protobuf/wrappers.upbdefs.c',
'src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c',
'src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c',
'src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c',
'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c',
@ -401,6 +403,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/xds/xds_client.cc',
'src/core/ext/xds/xds_client_stats.cc',
'src/core/ext/xds/xds_cluster.cc',
'src/core/ext/xds/xds_cluster_specifier_plugin.cc',
'src/core/ext/xds/xds_common_types.cc',
'src/core/ext/xds/xds_endpoint.cc',
'src/core/ext/xds/xds_http_fault_filter.cc',
@ -1171,6 +1174,7 @@ CORE_SOURCE_FILES = [
'third_party/upb/upb/decode_fast.c',
'third_party/upb/upb/def.c',
'third_party/upb/upb/encode.c',
'third_party/upb/upb/json_encode.c',
'third_party/upb/upb/msg.c',
'third_party/upb/upb/reflection.c',
'third_party/upb/upb/table.c',

@ -36,6 +36,7 @@ try:
"third_party/upb/upb/decode.c",
"third_party/upb/upb/def.c",
"third_party/upb/upb/encode.c",
"third_party/upb/upb/json_encode.c",
"third_party/upb/upb/msg.c",
"third_party/upb/upb/reflection.c",
"third_party/upb/upb/table.c",
@ -52,6 +53,7 @@ try:
"third_party/upb/upb/def.h",
"third_party/upb/upb/def.hpp",
"third_party/upb/upb/encode.h",
"third_party/upb/upb/json_encode.h",
"third_party/upb/upb/msg_internal.h",
"third_party/upb/upb/msg.h",
"third_party/upb/upb/port_def.inc",

@ -0,0 +1,46 @@
%YAML 1.2
--- |
# Bazel Support
${ '##' } Basic Usage
The `grpc/grpc` repository's primary build system is Bazel. Rules are provided
for C++, Python, and Objective-C. While C++ supports other build systems such as
CMake, these rules are actually generated from the Bazel definitions.
Projects built with Bazel may use the `grpc/grpc` repo not only to add a
dependency on the library itself, but also to generate protobuf, stub, and
servicer code. To do so, one must invoke the `grpc_deps` and `grpc_extra_deps`
repository rules in their `WORKSPACE` file:
```starlark
workspace(name = "example_workspace")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_github_grpc_grpc",
strip_prefix = "grpc-1.45.0",
sha256 = "ec19657a677d49af59aa806ec299c070c882986c9fcc022b1c22c2a3caf01bcd"k
urls = ["https://github.com/grpc/grpc/archive/refs/tags/v1.45.0.tar.gz"],
)
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
grpc_extra_deps()
```
${ '##' } Supported Versions
In general, gRPC supports building with the latest patch release of the most
recent two major versions of Bazel. However individual releases may have a
broader compatibility range. The currently supported versions are captured by
the following list:
% for version in supported_bazel_versions:
- [`${version}`](https://github.com/bazelbuild/bazel/releases/tag/${version})
% endfor

@ -1,19 +1,19 @@
#=================
# Compile CPython 3.10.2 from source
# Compile CPython 3.10.3 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && ${'\\'}
wget -q https://www.python.org/ftp/python/3.10.2/Python-3.10.2.tgz && ${'\\'}
tar xzvf Python-3.10.2.tgz && ${'\\'}
cd Python-3.10.2 && ${'\\'}
wget -q https://www.python.org/ftp/python/3.10.3/Python-3.10.3.tgz && ${'\\'}
tar xzvf Python-3.10.3.tgz && ${'\\'}
cd Python-3.10.3 && ${'\\'}
./configure && ${'\\'}
make -j4 && ${'\\'}
make install
RUN cd /tmp && ${'\\'}
echo "67c92270be6701f4a6fed57c4530139b Python-3.10.2.tgz" > checksum.md5 && ${'\\'}
echo "f276ffcd05bccafe46da023d0a5bb04a Python-3.10.3.tgz" > checksum.md5 && ${'\\'}
md5sum -c checksum.md5
RUN python3.10 -m ensurepip && ${'\\'}

@ -1,19 +1,19 @@
#=================
# Compile CPython 3.6.9 from source
# Compile CPython 3.6.15 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && ${'\\'}
wget -q https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz && ${'\\'}
tar xzvf Python-3.6.9.tgz && ${'\\'}
cd Python-3.6.9 && ${'\\'}
wget -q https://www.python.org/ftp/python/3.6.15/Python-3.6.15.tgz && ${'\\'}
tar xzvf Python-3.6.15.tgz && ${'\\'}
cd Python-3.6.15 && ${'\\'}
./configure && ${'\\'}
make -j4 && ${'\\'}
make install
RUN cd /tmp && ${'\\'}
echo "ff7cdaef4846c89c1ec0d7b709bbd54d Python-3.6.9.tgz" > checksum.md5 && ${'\\'}
echo "f9e6f91c754a604f4fc6f6c7683723fb Python-3.6.15.tgz" > checksum.md5 && ${'\\'}
md5sum -c checksum.md5
RUN python3.6 -m ensurepip && ${'\\'}

@ -1,19 +1,19 @@
#=================
# Compile CPython 3.7.12 from source
# Compile CPython 3.7.13 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && ${'\\'}
wget -q https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz && ${'\\'}
tar xzvf Python-3.7.12.tgz && ${'\\'}
cd Python-3.7.12 && ${'\\'}
wget -q https://www.python.org/ftp/python/3.7.13/Python-3.7.13.tgz && ${'\\'}
tar xzvf Python-3.7.13.tgz && ${'\\'}
cd Python-3.7.13 && ${'\\'}
./configure && ${'\\'}
make -j4 && ${'\\'}
make install
RUN cd /tmp && ${'\\'}
echo "6fe83678c085a7735a943cf1e4d41c14 Python-3.7.12.tgz" > checksum.md5 && ${'\\'}
echo "e0d3321026d4a5f3a3890b5d821ad762 Python-3.7.13.tgz" > checksum.md5 && ${'\\'}
md5sum -c checksum.md5
RUN python3.7 -m ensurepip && ${'\\'}

@ -1,19 +1,19 @@
#=================
# Compile CPython 3.8.0b4 from source
# Compile CPython 3.8.13 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && ${'\\'}
wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0b4.tgz && ${'\\'}
tar xzvf Python-3.8.0b4.tgz && ${'\\'}
cd Python-3.8.0b4 && ${'\\'}
wget -q https://www.python.org/ftp/python/3.8.13/Python-3.8.13.tgz && ${'\\'}
tar xzvf Python-3.8.13.tgz && ${'\\'}
cd Python-3.8.13 && ${'\\'}
./configure && ${'\\'}
make -j4 && ${'\\'}
make install
RUN cd /tmp && ${'\\'}
echo "b8f4f897df967014ddb42033b90c3058 Python-3.8.0b4.tgz" > checksum.md5 && ${'\\'}
echo "3c49180c6b43df3519849b7e390af0b9 Python-3.8.13.tgz" > checksum.md5 && ${'\\'}
md5sum -c checksum.md5
RUN python3.8 -m ensurepip && ${'\\'}

@ -35,22 +35,16 @@ namespace {
class RlsConfigParsingTest : public ::testing::Test {
public:
static void SetUpTestSuite() {
gpr_setenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY", "true");
grpc_init();
}
static void SetUpTestSuite() { grpc_init(); }
static void TearDownTestSuite() {
grpc_shutdown_blocking();
gpr_unsetenv("GRPC_EXPERIMENTAL_ENABLE_RLS_LB_POLICY");
}
static void TearDownTestSuite() { grpc_shutdown_blocking(); }
};
TEST_F(RlsConfigParsingTest, ValidConfig) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"lookupService\":\"rls.example.com:80\",\n"
" \"cacheSizeBytes\":1,\n"
@ -88,7 +82,7 @@ TEST_F(RlsConfigParsingTest, TopLevelRequiredFieldsMissing) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" }\n"
" }]\n"
"}\n";
@ -109,7 +103,7 @@ TEST_F(RlsConfigParsingTest, TopLevelFieldsWrongTypes) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":1,\n"
" \"routeLookupChannelServiceConfig\": 1,\n"
" \"childPolicy\":1,\n"
@ -135,7 +129,7 @@ TEST_F(RlsConfigParsingTest, TopLevelFieldsInvalidValues) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"childPolicy\":[\n"
" {\"unknown\":{}}\n"
" ],\n"
@ -160,7 +154,7 @@ TEST_F(RlsConfigParsingTest, InvalidChildPolicyConfig) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"childPolicy\":[\n"
" {\"grpclb\":{\"childPolicy\":1}}\n"
" ],\n"
@ -184,7 +178,7 @@ TEST_F(RlsConfigParsingTest, InvalidRlsChannelServiceConfig) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupChannelServiceConfig\": {\n"
" \"loadBalancingPolicy\": \"unknown\"\n"
" },\n"
@ -217,7 +211,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigRequiredFieldsMissing) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" }\n"
" }\n"
@ -239,7 +233,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":1,\n"
" \"name\":1,\n"
@ -264,7 +258,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
"field:lookupService error:type should be STRING.*"
"field:maxAge error:type should be STRING.*"
"field:staleAge error:type should be STRING.*"
"field:cacheSizeBytes error:type should be NUMBER.*"
"field:cacheSizeBytes error:failed to parse.*"
"field:defaultTarget error:type should be STRING"));
GRPC_ERROR_UNREF(error);
}
@ -273,7 +267,7 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsInvalidValues) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"lookupService\":\"\",\n"
" \"cacheSizeBytes\":0\n"
@ -301,7 +295,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderRequiredFieldsMissing) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"
@ -328,7 +322,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"
@ -362,7 +356,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"
@ -403,7 +397,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"
@ -463,7 +457,7 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"
@ -500,7 +494,7 @@ TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInSameKeyBuilder) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"
@ -537,7 +531,7 @@ TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInDifferentKeyBuilders) {
const char* service_config_json =
"{\n"
" \"loadBalancingConfig\":[{\n"
" \"rls\":{\n"
" \"rls_experimental\":{\n"
" \"routeLookupConfig\":{\n"
" \"grpcKeybuilders\":[\n"
" {\n"

@ -410,7 +410,7 @@ TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsBadTypes) {
"permissions\\[5\\]" CHILD_ERROR_TAG
"field:destinationIp error:type should be OBJECT.*"
"permissions\\[6\\]" CHILD_ERROR_TAG
"field:destinationPort error:type should be NUMBER.*"
"field:destinationPort error:failed to parse.*"
"permissions\\[7\\]" CHILD_ERROR_TAG
"field:metadata error:type should be OBJECT.*"
"permissions\\[8\\]" CHILD_ERROR_TAG

@ -30,6 +30,7 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
@ -214,6 +215,7 @@ std::pair<MemStats, MemStats> run_test_loop(int iterations, int* call_idx) {
ABSL_FLAG(std::string, target, "localhost:443", "Target host:port");
ABSL_FLAG(int, warmup, 100, "Warmup iterations");
ABSL_FLAG(int, benchmark, 1000, "Benchmark iterations");
ABSL_FLAG(bool, minstack, false, "Use minimal stack");
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
@ -233,8 +235,15 @@ int main(int argc, char** argv) {
cq = grpc_completion_queue_create_for_next(nullptr);
std::vector<grpc_arg> args_vec;
if (absl::GetFlag(FLAGS_minstack)) {
args_vec.push_back(grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MINIMAL_STACK), 1));
}
grpc_channel_args args = {args_vec.size(), args_vec.data()};
channel = grpc_channel_create(absl::GetFlag(FLAGS_target).c_str(),
grpc_insecure_credentials_create(), nullptr);
grpc_insecure_credentials_create(), &args);
int call_idx = 0;
const int warmup_iterations = absl::GetFlag(FLAGS_warmup);

@ -34,6 +34,7 @@
ABSL_FLAG(int, warmup, 100, "Warmup iterations");
ABSL_FLAG(int, benchmark, 1000, "Benchmark iterations");
ABSL_FLAG(bool, minstack, false, "Use minimal stack");
class Subprocess {
public:
@ -74,15 +75,16 @@ int main(int argc, char** argv) {
/* start the server */
Subprocess svr({absl::StrCat(root, "/memory_usage_server",
gpr_subprocess_binary_extension()),
"--bind", grpc_core::JoinHostPort("::", port), "--nosecure"});
"--bind", grpc_core::JoinHostPort("::", port), "--nosecure",
absl::StrCat("--minstack=", absl::GetFlag(FLAGS_minstack))});
/* start the client */
Subprocess cli(
{absl::StrCat(root, "/memory_usage_client",
Subprocess cli({absl::StrCat(root, "/memory_usage_client",
gpr_subprocess_binary_extension()),
"--target", grpc_core::JoinHostPort("127.0.0.1", port),
absl::StrCat("--warmup=", absl::GetFlag(FLAGS_warmup)),
absl::StrCat("--benchmark=", absl::GetFlag(FLAGS_benchmark))});
absl::StrCat("--benchmark=", absl::GetFlag(FLAGS_benchmark)),
absl::StrCat("--minstack=", absl::GetFlag(FLAGS_minstack))});
/* wait for completion */
if ((status = cli.Join()) != 0) {

@ -40,6 +40,7 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/host_port.h"
#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/memory_usage/memstats.h"
@ -154,6 +155,7 @@ static void sigint_handler(int /*x*/) { _exit(0); }
ABSL_FLAG(std::string, bind, "", "Bind host:port");
ABSL_FLAG(bool, secure, false, "Use security");
ABSL_FLAG(bool, minstack, false, "Use minimal stack");
int main(int argc, char** argv) {
absl::ParseCommandLine(argc, argv);
@ -180,17 +182,24 @@ int main(int argc, char** argv) {
cq = grpc_completion_queue_create_for_next(nullptr);
std::vector<grpc_arg> args_vec;
if (absl::GetFlag(FLAGS_minstack)) {
args_vec.push_back(grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_MINIMAL_STACK), 1));
}
grpc_channel_args args = {args_vec.size(), args_vec.data()};
MemStats before_server_create = MemStats::Snapshot();
if (absl::GetFlag(FLAGS_secure)) {
grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {test_server1_key,
test_server1_cert};
grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create(
nullptr, &pem_key_cert_pair, 1, 0, nullptr);
server = grpc_server_create(nullptr, nullptr);
server = grpc_server_create(&args, nullptr);
GPR_ASSERT(grpc_server_add_http2_port(server, addr.c_str(), ssl_creds));
grpc_server_credentials_release(ssl_creds);
} else {
server = grpc_server_create(nullptr, nullptr);
server = grpc_server_create(&args, nullptr);
GPR_ASSERT(grpc_server_add_http2_port(
server, addr.c_str(), grpc_insecure_server_credentials_create()));
}

@ -43,6 +43,7 @@ const int kSslTsiTestRevokedKeyCertPairsNum = 1;
const int kSslTsiTestValidKeyCertPairsNum = 1;
const char* kSslTsiTestCrlSupportedCredentialsDir =
"test/core/tsi/test_creds/crl_data/";
const char* kSslTsiTestFaultyCrlsDir = "bad_path/";
class CrlSslTransportSecurityTest
: public testing::TestWithParam<tsi_tls_version> {
@ -50,10 +51,14 @@ class CrlSslTransportSecurityTest
// A tsi_test_fixture implementation.
class SslTsiTestFixture {
public:
// When use_faulty_crl_directory is set, the crl_directory of the
// client is set to a non-existant path.
static SslTsiTestFixture* Create(bool use_revoked_server_cert,
bool use_revoked_client_cert) {
bool use_revoked_client_cert,
bool use_faulty_crl_directory) {
return new SslTsiTestFixture(use_revoked_server_cert,
use_revoked_client_cert);
use_revoked_client_cert,
use_faulty_crl_directory);
}
void Run() {
@ -63,9 +68,11 @@ class CrlSslTransportSecurityTest
private:
SslTsiTestFixture(bool use_revoked_server_cert,
bool use_revoked_client_cert)
bool use_revoked_client_cert,
bool use_faulty_crl_directory)
: use_revoked_server_cert_(use_revoked_server_cert),
use_revoked_client_cert_(use_revoked_client_cert) {
use_revoked_client_cert_(use_revoked_client_cert),
use_faulty_crl_directory_(use_faulty_crl_directory) {
tsi_test_fixture_init(&base_);
base_.test_unused_bytes = true;
base_.vtable = &kVtable;
@ -120,7 +127,11 @@ class CrlSslTransportSecurityTest
} else {
client_options.pem_key_cert_pair = valid_pem_key_cert_pairs_;
}
if (use_faulty_crl_directory_) {
client_options.crl_directory = kSslTsiTestFaultyCrlsDir;
} else {
client_options.crl_directory = kSslTsiTestCrlSupportedCredentialsDir;
}
client_options.root_store = root_store_;
client_options.min_tls_version = GetParam();
client_options.max_tls_version = GetParam();
@ -228,6 +239,7 @@ class CrlSslTransportSecurityTest
tsi_test_fixture base_;
bool use_revoked_server_cert_;
bool use_revoked_client_cert_;
bool use_faulty_crl_directory_;
char* root_cert_;
tsi_ssl_root_certs_store* root_store_;
tsi_ssl_pem_key_cert_pair* revoked_pem_key_cert_pairs_;
@ -245,19 +257,29 @@ struct tsi_test_fixture_vtable
TEST_P(CrlSslTransportSecurityTest, RevokedServerCert) {
auto* fixture = SslTsiTestFixture::Create(/*use_revoked_server_cert=*/true,
/*use_revoked_client_cert=*/false);
/*use_revoked_client_cert=*/false,
/*use_faulty_crl_directory=*/false);
fixture->Run();
}
TEST_P(CrlSslTransportSecurityTest, RevokedClientCert) {
auto* fixture = SslTsiTestFixture::Create(/*use_revoked_server_cert=*/false,
/*use_revoked_client_cert=*/true);
/*use_revoked_client_cert=*/true,
/*use_faulty_crl_directory=*/false);
fixture->Run();
}
TEST_P(CrlSslTransportSecurityTest, ValidCerts) {
auto* fixture = SslTsiTestFixture::Create(/*use_revoked_server_cert=*/false,
/*use_revoked_client_cert=*/false);
/*use_revoked_client_cert=*/false,
/*use_faulty_crl_directory=*/false);
fixture->Run();
}
TEST_P(CrlSslTransportSecurityTest, UseFaultyCrlDirectory) {
auto* fixture = SslTsiTestFixture::Create(/*use_revoked_server_cert=*/false,
/*use_revoked_client_cert=*/false,
/*use_faulty_crl_directory=*/true);
fixture->Run();
}

@ -281,6 +281,7 @@ class InterceptRecvTrailingMetadataLoadBalancingPolicy
void Finish(FinishArgs args) override {
TrailingMetadataArgsSeen args_seen;
args_seen.status = args.status;
args_seen.backend_metric_data =
args.backend_metric_accessor->GetBackendMetricData();
args_seen.metadata = args.trailing_metadata->TestOnlyCopyToVector();

@ -36,6 +36,7 @@ void RegisterTestPickArgsLoadBalancingPolicy(
TestPickArgsCallback cb, const char* delegate_policy_name = "pick_first");
struct TrailingMetadataArgsSeen {
absl::Status status;
const LoadBalancingPolicy::BackendMetricAccessor::BackendMetricData*
backend_metric_data;
MetadataVector metadata;

@ -214,7 +214,7 @@ TEST(GoogleMeshCaConfigTest, WrongTypes) {
" \"certificate_lifetime\": 400,"
" \"renewal_grace_period\": 100,"
" \"key_type\": 123,"
" \"key_size\": \"1024\","
" \"key_size\": \"1024A\","
" \"location\": 123"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
@ -245,7 +245,7 @@ TEST(GoogleMeshCaConfigTest, WrongTypes) {
"field:renewal_grace_period error:type should be STRING of the form "
"given by google.proto.Duration..*"
"field:key_type error:type should be STRING.*"
"field:key_size error:type should be NUMBER.*"
"field:key_size error:failed to parse.*"
"field:location error:type should be STRING"));
GRPC_ERROR_UNREF(error);
}

@ -70,6 +70,21 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "rls_server",
testonly = True,
srcs = ["rls_server.cc"],
hdrs = ["rls_server.h"],
external_deps = [
"gtest",
],
deps = [
":counted_service",
"//src/proto/grpc/lookup/v1:rls_proto",
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "async_end2end_test",
srcs = ["async_end2end_test.cc"],
@ -487,6 +502,7 @@ grpc_cc_test(
tags = ["no_test_ios"],
deps = [
":counted_service",
":rls_server",
":test_service_impl",
"//:gpr",
"//:grpc",

@ -78,6 +78,8 @@ namespace grpc {
namespace testing {
namespace {
constexpr char kRequestMessage[] = "Live long and prosper.";
gpr_atm g_connection_delay_ms;
void tcp_client_connect_with_delay(grpc_closure* closure, grpc_endpoint** ep,
@ -232,7 +234,6 @@ class ClientLbEnd2endTest : public ::testing::Test {
protected:
ClientLbEnd2endTest()
: server_host_("localhost"),
kRequestMessage_("Live long and prosper."),
creds_(new SecureChannelCredentials(
grpc_fake_transport_security_credentials_create())) {}
@ -316,21 +317,22 @@ class ClientLbEnd2endTest : public ::testing::Test {
bool SendRpc(
const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
EchoResponse* response = nullptr, int timeout_ms = 1000,
Status* result = nullptr, bool wait_for_ready = false) {
const bool local_response = (response == nullptr);
if (local_response) response = new EchoResponse;
EchoRequest request;
request.set_message(kRequestMessage_);
request.mutable_param()->set_echo_metadata(true);
Status* result = nullptr, bool wait_for_ready = false,
EchoRequest* request = nullptr) {
EchoResponse local_response;
if (response == nullptr) response = &local_response;
EchoRequest local_request;
if (request == nullptr) request = &local_request;
request->set_message(kRequestMessage);
request->mutable_param()->set_echo_metadata(true);
ClientContext context;
context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms));
if (wait_for_ready) context.set_wait_for_ready(true);
context.AddMetadata("foo", "1");
context.AddMetadata("bar", "2");
context.AddMetadata("baz", "3");
Status status = stub->Echo(&context, request, response);
Status status = stub->Echo(&context, *request, response);
if (result != nullptr) *result = status;
if (local_response) delete response;
return status.ok();
}
@ -345,7 +347,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
<< "\n"
<< "Error: " << status.error_message() << " "
<< status.error_details();
ASSERT_EQ(response.message(), kRequestMessage_)
ASSERT_EQ(response.message(), kRequestMessage)
<< "From " << location.file() << ":" << location.line();
if (!success) abort();
}
@ -483,7 +485,6 @@ class ClientLbEnd2endTest : public ::testing::Test {
const std::string server_host_;
std::vector<std::unique_ptr<ServerData>> servers_;
const std::string kRequestMessage_;
std::shared_ptr<ChannelCredentials> creds_;
bool ipv6_only_ = false;
};
@ -1832,14 +1833,19 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
return trailers_intercepted_;
}
const grpc_core::MetadataVector& trailing_metadata() {
absl::Status last_status() {
grpc::internal::MutexLock lock(&mu_);
return last_status_;
}
grpc_core::MetadataVector trailing_metadata() {
grpc::internal::MutexLock lock(&mu_);
return trailing_metadata_;
return std::move(trailing_metadata_);
}
const xds::data::orca::v3::OrcaLoadReport* backend_load_report() {
std::unique_ptr<xds::data::orca::v3::OrcaLoadReport> backend_load_report() {
grpc::internal::MutexLock lock(&mu_);
return load_report_.get();
return std::move(load_report_);
}
private:
@ -1848,6 +1854,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
const auto* backend_metric_data = args_seen.backend_metric_data;
ClientLbInterceptTrailingMetadataTest* self = current_test_instance_;
grpc::internal::MutexLock lock(&self->mu_);
self->last_status_ = args_seen.status;
self->trailers_intercepted_++;
self->trailing_metadata_ = args_seen.metadata;
if (backend_metric_data != nullptr) {
@ -1872,6 +1879,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
static ClientLbInterceptTrailingMetadataTest* current_test_instance_;
grpc::internal::Mutex mu_;
int trailers_intercepted_ = 0;
absl::Status last_status_;
grpc_core::MetadataVector trailing_metadata_;
std::unique_ptr<xds::data::orca::v3::OrcaLoadReport> load_report_;
};
@ -1879,13 +1887,74 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
ClientLbInterceptTrailingMetadataTest*
ClientLbInterceptTrailingMetadataTest::current_test_instance_ = nullptr;
TEST_F(ClientLbInterceptTrailingMetadataTest, StatusOk) {
StartServers(1);
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
// Send an OK RPC.
CheckRpcSendOk(stub, DEBUG_LOCATION);
// Check LB policy name for the channel.
EXPECT_EQ("intercept_trailing_metadata_lb",
channel->GetLoadBalancingPolicyName());
EXPECT_EQ(1, trailers_intercepted());
EXPECT_EQ(absl::OkStatus(), last_status());
}
TEST_F(ClientLbInterceptTrailingMetadataTest, StatusFailed) {
StartServers(1);
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
EchoRequest request;
auto* expected_error = request.mutable_param()->mutable_expected_error();
expected_error->set_code(GRPC_STATUS_PERMISSION_DENIED);
expected_error->set_error_message("bummer, man");
Status status;
SendRpc(stub, /*response=*/nullptr, /*timeout_ms=*/1000, &status,
/*wait_for_ready=*/false, &request);
EXPECT_EQ(status.error_code(), GRPC_STATUS_PERMISSION_DENIED);
EXPECT_EQ(status.error_message(), "bummer, man");
absl::Status status_seen_by_lb = last_status();
EXPECT_EQ(status_seen_by_lb.code(), absl::StatusCode::kPermissionDenied);
EXPECT_EQ(status_seen_by_lb.message(), "bummer, man");
}
TEST_F(ClientLbInterceptTrailingMetadataTest,
StatusCancelledWithoutStartingRecvTrailingMetadata) {
StartServers(1);
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
response_generator.SetNextResolution(GetServersPorts());
auto stub = BuildStub(channel);
{
// Start a stream (sends initial metadata) and then cancel without
// calling Finish().
ClientContext ctx;
auto stream = stub->BidiStream(&ctx);
ctx.TryCancel();
}
// Check status seen by LB policy.
EXPECT_EQ(1, trailers_intercepted());
absl::Status status_seen_by_lb = last_status();
EXPECT_EQ(status_seen_by_lb.code(), absl::StatusCode::kCancelled);
EXPECT_EQ(status_seen_by_lb.message(), "call cancelled");
}
TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesDisabled) {
const int kNumServers = 1;
const int kNumRpcs = 10;
StartServers(kNumServers);
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
ChannelArguments channel_args;
channel_args.SetInt(GRPC_ARG_ENABLE_RETRIES, 0);
auto channel = BuildChannel("intercept_trailing_metadata_lb",
response_generator, channel_args);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
for (size_t i = 0; i < kNumRpcs; ++i) {
@ -1971,7 +2040,7 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricData) {
response_generator.SetNextResolution(GetServersPorts());
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(stub, DEBUG_LOCATION);
auto* actual = backend_load_report();
auto actual = backend_load_report();
ASSERT_NE(actual, nullptr);
// TODO(roth): Change this to use EqualsProto() once that becomes
// available in OSS.

@ -60,11 +60,11 @@
#include "test/core/util/test_config.h"
#include "test/core/util/test_lb_policies.h"
#include "test/cpp/end2end/counted_service.h"
#include "test/cpp/end2end/rls_server.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/test_config.h"
using ::grpc::lookup::v1::RouteLookupRequest;
using ::grpc::lookup::v1::RouteLookupResponse;
namespace grpc {
namespace testing {
@ -87,92 +87,6 @@ const char* kConstantKey = "constant_key";
const char* kConstantValue = "constant_value";
using BackendService = CountedService<TestServiceImpl>;
using RlsService =
CountedService<grpc::lookup::v1::RouteLookupService::Service>;
class RlsServiceImpl : public RlsService {
public:
grpc::Status RouteLookup(grpc::ServerContext* context,
const RouteLookupRequest* request,
RouteLookupResponse* response) override {
gpr_log(GPR_INFO, "RLS: Received request: %s",
request->DebugString().c_str());
// RLS server should see call creds.
EXPECT_THAT(context->client_metadata(),
::testing::Contains(
::testing::Pair(kCallCredsMdKey, kCallCredsMdValue)));
IncreaseRequestCount();
EXPECT_EQ(request->target_type(), "grpc");
// See if we have a configured response for this request.
ResponseData res;
{
grpc::internal::MutexLock lock(&mu_);
auto it = responses_.find(*request);
if (it == responses_.end()) {
gpr_log(GPR_INFO, "RLS: no matching request, returning INTERNAL");
unmatched_requests_.push_back(*request);
return Status(StatusCode::INTERNAL, "no response entry");
}
res = it->second;
}
// Configured response found, so use it.
if (res.response_delay > grpc_core::Duration::Zero()) {
gpr_sleep_until(
grpc_timeout_milliseconds_to_deadline(res.response_delay.millis()));
}
IncreaseResponseCount();
*response = res.response;
gpr_log(GPR_INFO, "RLS: returning configured response: %s",
response->DebugString().c_str());
return Status::OK;
}
void Start() {}
void Shutdown() {}
void SetResponse(RouteLookupRequest request, RouteLookupResponse response,
grpc_core::Duration response_delay = grpc_core::Duration()) {
grpc::internal::MutexLock lock(&mu_);
responses_[std::move(request)] = {std::move(response), response_delay};
}
void RemoveResponse(const RouteLookupRequest& request) {
grpc::internal::MutexLock lock(&mu_);
responses_.erase(request);
}
std::vector<RouteLookupRequest> GetUnmatchedRequests() {
grpc::internal::MutexLock lock(&mu_);
return std::move(unmatched_requests_);
}
private:
// Sorting thunk for RouteLookupRequest.
struct RlsRequestLessThan {
bool operator()(const RouteLookupRequest& req1,
const RouteLookupRequest& req2) const {
std::map<absl::string_view, absl::string_view> key_map1(
req1.key_map().begin(), req1.key_map().end());
std::map<absl::string_view, absl::string_view> key_map2(
req2.key_map().begin(), req2.key_map().end());
if (key_map1 < key_map2) return true;
if (req1.reason() < req2.reason()) return true;
if (req1.stale_header_data() < req2.stale_header_data()) return true;
return false;
}
};
struct ResponseData {
RouteLookupResponse response;
grpc_core::Duration response_delay;
};
grpc::internal::Mutex mu_;
std::map<RouteLookupRequest, ResponseData, RlsRequestLessThan> responses_
ABSL_GUARDED_BY(&mu_);
std::vector<RouteLookupRequest> unmatched_requests_ ABSL_GUARDED_BY(&mu_);
};
// Subclass of TestServiceImpl that increments a request counter for
// every call to the Echo Rpc.
@ -265,7 +179,12 @@ class RlsEnd2endTest : public ::testing::Test {
grpc_core::LocalhostResolves(&localhost_resolves_to_ipv4,
&localhost_resolves_to_ipv6);
ipv6_only_ = !localhost_resolves_to_ipv4 && localhost_resolves_to_ipv6;
rls_server_ = absl::make_unique<ServerThread<RlsServiceImpl>>("rls");
rls_server_ = absl::make_unique<ServerThread<RlsServiceImpl>>(
"rls", [](grpc::ServerContext* ctx) {
EXPECT_THAT(ctx->client_metadata(),
::testing::Contains(
::testing::Pair(kCallCredsMdKey, kCallCredsMdValue)));
});
rls_server_->Start();
resolver_response_generator_ =
absl::make_unique<FakeResolverResponseGeneratorWrapper>();
@ -316,26 +235,6 @@ class RlsEnd2endTest : public ::testing::Test {
return absl::StrCat("ipv4:127.0.0.1:", port);
}
static RouteLookupRequest BuildRlsRequest(
std::map<std::string, std::string> key,
RouteLookupRequest::Reason reason = RouteLookupRequest::REASON_MISS,
const char* stale_header_data = "") {
RouteLookupRequest request;
request.set_target_type("grpc");
request.mutable_key_map()->insert(key.begin(), key.end());
request.set_reason(reason);
request.set_stale_header_data(stale_header_data);
return request;
}
static RouteLookupResponse BuildRlsResponse(std::vector<std::string> targets,
const char* header_data = "") {
RouteLookupResponse response;
response.mutable_targets()->Add(targets.begin(), targets.end());
response.set_header_data(header_data);
return response;
}
struct RpcOptions {
int timeout_ms = 1000;
bool wait_for_ready = false;
@ -481,7 +380,7 @@ class RlsEnd2endTest : public ::testing::Test {
return absl::StrCat(
"{"
" \"loadBalancingConfig\":[{"
" \"rls\":{",
" \"rls_experimental\":{",
absl::StrJoin(rls_config_parts, ","),
" }"
" }]"

@ -0,0 +1,103 @@
//
// Copyright 2020 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 "test/cpp/end2end/rls_server.h"
#include <gmock/gmock.h>
#include "src/proto/grpc/lookup/v1/rls.grpc.pb.h"
#include "src/proto/grpc/lookup/v1/rls.pb.h"
#include "test/core/util/test_config.h"
using ::grpc::lookup::v1::RouteLookupRequest;
using ::grpc::lookup::v1::RouteLookupResponse;
namespace grpc {
namespace testing {
::grpc::Status RlsServiceImpl::RouteLookup(grpc::ServerContext* context,
const RouteLookupRequest* request,
RouteLookupResponse* response) {
gpr_log(GPR_INFO, "RLS: Received request: %s",
request->DebugString().c_str());
if (context_proc_ != nullptr) {
context_proc_(context);
}
IncreaseRequestCount();
EXPECT_EQ(request->target_type(), "grpc");
// See if we have a configured response for this request.
ResponseData res;
{
grpc::internal::MutexLock lock(&mu_);
auto it = responses_.find(*request);
if (it == responses_.end()) {
gpr_log(GPR_INFO, "RLS: no matching request, returning INTERNAL");
unmatched_requests_.push_back(*request);
return Status(StatusCode::INTERNAL, "no response entry");
}
res = it->second;
}
// Configured response found, so use it.
if (res.response_delay > grpc_core::Duration::Zero()) {
gpr_sleep_until(
grpc_timeout_milliseconds_to_deadline(res.response_delay.millis()));
}
IncreaseResponseCount();
*response = res.response;
gpr_log(GPR_INFO, "RLS: returning configured response: %s",
response->DebugString().c_str());
return Status::OK;
}
void RlsServiceImpl::SetResponse(RouteLookupRequest request,
RouteLookupResponse response,
grpc_core::Duration response_delay) {
grpc::internal::MutexLock lock(&mu_);
responses_[std::move(request)] = {std::move(response), response_delay};
}
void RlsServiceImpl::RemoveResponse(const RouteLookupRequest& request) {
grpc::internal::MutexLock lock(&mu_);
responses_.erase(request);
}
std::vector<RouteLookupRequest> RlsServiceImpl::GetUnmatchedRequests() {
grpc::internal::MutexLock lock(&mu_);
return std::move(unmatched_requests_);
}
grpc::lookup::v1::RouteLookupRequest BuildRlsRequest(
std::map<std::string, std::string> key,
grpc::lookup::v1::RouteLookupRequest::Reason reason,
const char* stale_header_data) {
grpc::lookup::v1::RouteLookupRequest request;
request.set_target_type("grpc");
request.mutable_key_map()->insert(key.begin(), key.end());
request.set_reason(reason);
request.set_stale_header_data(stale_header_data);
return request;
}
grpc::lookup::v1::RouteLookupResponse BuildRlsResponse(
std::vector<std::string> targets, const char* header_data) {
grpc::lookup::v1::RouteLookupResponse response;
response.mutable_targets()->Add(targets.begin(), targets.end());
response.set_header_data(header_data);
return response;
}
} // namespace testing
} // namespace grpc

@ -0,0 +1,94 @@
//
// Copyright 2020 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 "absl/types/optional.h"
#include "src/core/lib/gprpp/time.h"
#include "src/proto/grpc/lookup/v1/rls.grpc.pb.h"
#include "src/proto/grpc/lookup/v1/rls.pb.h"
#include "test/cpp/end2end/counted_service.h"
namespace grpc {
namespace testing {
using RlsService =
CountedService<grpc::lookup::v1::RouteLookupService::Service>;
class RlsServiceImpl : public RlsService {
public:
using ContextProcessingFunc = std::function<void(grpc::ServerContext*)>;
explicit RlsServiceImpl(ContextProcessingFunc context_proc = nullptr)
: context_proc_(std::move(context_proc)) {}
grpc::Status RouteLookup(
grpc::ServerContext* context,
const grpc::lookup::v1::RouteLookupRequest* request,
grpc::lookup::v1::RouteLookupResponse* response) override;
void Start() {}
void Shutdown() {}
void SetResponse(grpc::lookup::v1::RouteLookupRequest request,
grpc::lookup::v1::RouteLookupResponse response,
grpc_core::Duration response_delay = grpc_core::Duration());
void RemoveResponse(const grpc::lookup::v1::RouteLookupRequest& request);
std::vector<grpc::lookup::v1::RouteLookupRequest> GetUnmatchedRequests();
private:
// Sorting thunk for RouteLookupRequest.
struct RlsRequestLessThan {
bool operator()(const grpc::lookup::v1::RouteLookupRequest& req1,
const grpc::lookup::v1::RouteLookupRequest& req2) const {
std::map<absl::string_view, absl::string_view> key_map1(
req1.key_map().begin(), req1.key_map().end());
std::map<absl::string_view, absl::string_view> key_map2(
req2.key_map().begin(), req2.key_map().end());
if (key_map1 < key_map2) return true;
if (req1.reason() < req2.reason()) return true;
if (req1.stale_header_data() < req2.stale_header_data()) return true;
return false;
}
};
struct ResponseData {
grpc::lookup::v1::RouteLookupResponse response;
grpc_core::Duration response_delay;
};
ContextProcessingFunc context_proc_;
grpc::internal::Mutex mu_;
std::map<grpc::lookup::v1::RouteLookupRequest, ResponseData,
RlsRequestLessThan>
responses_ ABSL_GUARDED_BY(&mu_);
std::vector<grpc::lookup::v1::RouteLookupRequest> unmatched_requests_
ABSL_GUARDED_BY(&mu_);
};
grpc::lookup::v1::RouteLookupRequest BuildRlsRequest(
std::map<std::string, std::string> key,
grpc::lookup::v1::RouteLookupRequest::Reason reason =
grpc::lookup::v1::RouteLookupRequest::REASON_MISS,
const char* stale_header_data = "");
grpc::lookup::v1::RouteLookupResponse BuildRlsResponse(
std::vector<std::string> targets, const char* header_data = "");
} // namespace testing
} // namespace grpc

@ -77,6 +77,8 @@ grpc_cc_test(
"//:grpc++",
"//:grpc_resolver_fake",
"//:grpcpp_csds",
"//src/proto/grpc/lookup/v1:rls_config_proto",
"//src/proto/grpc/lookup/v1:rls_proto",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//src/proto/grpc/testing/duplicate:echo_duplicate_proto",
@ -96,6 +98,7 @@ grpc_cc_test(
"//src/proto/grpc/testing/xds/v3:tls_proto",
"//test/core/util:grpc_test_util",
"//test/cpp/end2end:counted_service",
"//test/cpp/end2end:rls_server",
"//test/cpp/end2end:test_service_impl",
"//test/cpp/util:test_config",
"//test/cpp/util:test_util",

@ -80,6 +80,9 @@
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/server/secure_server_credentials.h"
#include "src/proto/grpc/lookup/v1/rls.grpc.pb.h"
#include "src/proto/grpc/lookup/v1/rls.pb.h"
#include "src/proto/grpc/lookup/v1/rls_config.pb.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "src/proto/grpc/testing/xds/ads_for_test.grpc.pb.h"
#include "src/proto/grpc/testing/xds/cds_for_test.grpc.pb.h"
@ -103,6 +106,7 @@
#include "test/core/util/resolve_localhost_ip46.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/counted_service.h"
#include "test/cpp/end2end/rls_server.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/end2end/xds/xds_server.h"
#include "test/cpp/util/test_config.h"
@ -153,6 +157,8 @@ using ClientStats = LrsServiceImpl::ClientStats;
using ::grpc::experimental::ExternalCertificateVerifier;
using ::grpc::experimental::IdentityKeyCertPair;
using ::grpc::experimental::StaticDataCertificateProvider;
using ::grpc::lookup::v1::RouteLookupClusterSpecifier;
using ::grpc::lookup::v1::RouteLookupConfig;
constexpr char kDefaultLocalityRegion[] = "xds_default_locality_region";
constexpr char kDefaultLocalityZone[] = "xds_default_locality_zone";
@ -177,6 +183,18 @@ constexpr char kClientKeyPath[] = "src/core/tsi/test_creds/client.key";
constexpr char kBadClientCertPath[] = "src/core/tsi/test_creds/badclient.pem";
constexpr char kBadClientKeyPath[] = "src/core/tsi/test_creds/badclient.key";
constexpr char kRlsTestKey[] = "test_key";
constexpr char kRlsTestKey1[] = "key1";
constexpr char kRlsTestValue[] = "test_value";
constexpr char kRlsHostKey[] = "host_key";
constexpr char kRlsServiceKey[] = "service_key";
constexpr char kRlsServiceValue[] = "grpc.testing.EchoTestService";
constexpr char kRlsMethodKey[] = "method_key";
constexpr char kRlsMethodValue[] = "Echo";
constexpr char kRlsConstantKey[] = "constant_key";
constexpr char kRlsConstantValue[] = "constant_value";
constexpr char kRlsClusterSpecifierPluginInstanceName[] = "rls_plugin_instance";
template <typename RpcService>
class BackendServiceImpl
: public CountedService<TestMultipleServiceImpl<RpcService>> {
@ -6598,6 +6616,128 @@ TEST_P(CdsTest, AggregateClusterLogicalDnsToEds) {
"GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER");
}
// This test covers a bug seen in the wild where the
// xds_cluster_resolver policy's code to reuse child policy names did
// not correctly handle the case where the LOGICAL_DNS priority failed,
// thus returning a priority with no localities. This caused the child
// name to be reused incorrectly, which triggered an assertion failure
// in the xds_cluster_impl policy caused by changing its cluster name.
TEST_P(CdsTest, AggregateClusterReconfigEdsWhileLogicalDnsChildFails) {
gpr_setenv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER",
"true");
const char* kNewCluster1Name = "new_cluster_1";
const char* kNewEdsService1Name = "new_eds_service_name_1";
const char* kLogicalDNSClusterName = "logical_dns_cluster";
// Populate EDS resource with all unreachable endpoints.
// - Priority 0: locality0
// - Priority 1: locality1, locality2
EdsResourceArgs args1({
{"locality0", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 0},
{"locality1", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
{"locality2", {MakeNonExistantEndpoint()}, kDefaultLocalityWeight, 1},
});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsService1Name));
// Populate new CDS resources.
Cluster new_cluster1 = default_cluster_;
new_cluster1.set_name(kNewCluster1Name);
new_cluster1.mutable_eds_cluster_config()->set_service_name(
kNewEdsService1Name);
balancer_->ads_service()->SetCdsResource(new_cluster1);
// Create Logical DNS Cluster
auto logical_dns_cluster = default_cluster_;
logical_dns_cluster.set_name(kLogicalDNSClusterName);
logical_dns_cluster.set_type(Cluster::LOGICAL_DNS);
auto* address = logical_dns_cluster.mutable_load_assignment()
->add_endpoints()
->add_lb_endpoints()
->mutable_endpoint()
->mutable_address()
->mutable_socket_address();
address->set_address(kServerName);
address->set_port_value(443);
balancer_->ads_service()->SetCdsResource(logical_dns_cluster);
// Create Aggregate Cluster
auto cluster = default_cluster_;
CustomClusterType* custom_cluster = cluster.mutable_cluster_type();
custom_cluster->set_name("envoy.clusters.aggregate");
ClusterConfig cluster_config;
cluster_config.add_clusters(kNewCluster1Name);
cluster_config.add_clusters(kLogicalDNSClusterName);
custom_cluster->mutable_typed_config()->PackFrom(cluster_config);
balancer_->ads_service()->SetCdsResource(cluster);
// Set Logical DNS result
{
grpc_core::ExecCtx exec_ctx;
grpc_core::Resolver::Result result;
result.addresses = absl::UnavailableError("injected error");
logical_dns_cluster_resolver_response_generator_->SetResponse(
std::move(result));
}
// When an RPC fails, we know the channel has seen the update.
CheckRpcSendFailure();
// Send an EDS update that moves locality1 to priority 0.
args1 = EdsResourceArgs({
{"locality1", CreateEndpointsForBackends(0, 1), kDefaultLocalityWeight,
0},
{"locality2", CreateEndpointsForBackends(1, 2), kDefaultLocalityWeight,
1},
});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsService1Name));
WaitForBackend(0, WaitForBackendOptions().set_allow_failures(true));
gpr_unsetenv(
"GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER");
}
TEST_P(CdsTest, AggregateClusterMultipleClustersWithSameLocalities) {
gpr_setenv("GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER",
"true");
const char* kNewClusterName1 = "new_cluster_1";
const char* kNewEdsServiceName1 = "new_eds_service_name_1";
const char* kNewClusterName2 = "new_cluster_2";
const char* kNewEdsServiceName2 = "new_eds_service_name_2";
// Populate EDS resource for cluster 1 with unreachable endpoint.
EdsResourceArgs args1({{"locality0", {MakeNonExistantEndpoint()}}});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName1));
// Populate CDS resource for cluster 1.
Cluster new_cluster1 = default_cluster_;
new_cluster1.set_name(kNewClusterName1);
new_cluster1.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName1);
balancer_->ads_service()->SetCdsResource(new_cluster1);
// Populate EDS resource for cluster 2.
args1 = EdsResourceArgs({{"locality1", CreateEndpointsForBackends(0, 1)}});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName2));
// Populate CDS resource for cluster 2.
Cluster new_cluster2 = default_cluster_;
new_cluster2.set_name(kNewClusterName2);
new_cluster2.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName2);
balancer_->ads_service()->SetCdsResource(new_cluster2);
// Create Aggregate Cluster
auto cluster = default_cluster_;
CustomClusterType* custom_cluster = cluster.mutable_cluster_type();
custom_cluster->set_name("envoy.clusters.aggregate");
ClusterConfig cluster_config;
cluster_config.add_clusters(kNewClusterName1);
cluster_config.add_clusters(kNewClusterName2);
custom_cluster->mutable_typed_config()->PackFrom(cluster_config);
balancer_->ads_service()->SetCdsResource(cluster);
// Wait for channel to get the resources and get connected.
WaitForBackend(0);
// Send an EDS update for cluster 1 that reuses the locality name from
// cluster 1 and points traffic to backend 1.
args1 = EdsResourceArgs({{"locality1", CreateEndpointsForBackends(1, 2)}});
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName1));
WaitForBackend(1);
gpr_unsetenv(
"GRPC_XDS_EXPERIMENTAL_ENABLE_AGGREGATE_AND_LOGICAL_DNS_CLUSTER");
}
// Test that CDS client should send a NACK if cluster type is Logical DNS but
// the feature is not yet supported.
TEST_P(CdsTest, LogicalDNSClusterTypeDisabled) {
@ -7493,6 +7633,302 @@ TEST_P(CdsTest, RingHashPolicyHasInvalidRingSizeMinGreaterThanMax) {
"min_ring_size cannot be greater than max_ring_size."));
}
class RlsTest : public XdsEnd2endTest {
protected:
class RlsServerThread : public ServerThread {
public:
explicit RlsServerThread(XdsEnd2endTest* test_obj)
: ServerThread(test_obj, /*use_xds_enabled_server=*/false),
rls_service_(new RlsServiceImpl()) {}
RlsServiceImpl* rls_service() { return rls_service_.get(); }
private:
void RegisterAllServices(ServerBuilder* builder) override {
builder->RegisterService(rls_service_.get());
}
void StartAllServices() override { rls_service_->Start(); }
void ShutdownAllServices() override { rls_service_->Shutdown(); }
const char* Type() override { return "Rls"; }
std::shared_ptr<RlsServiceImpl> rls_service_;
};
RlsTest() : XdsEnd2endTest(4) {
rls_server_ = absl::make_unique<RlsServerThread>(this);
rls_server_->Start();
}
void SetUp() override {
XdsEnd2endTest::SetUp();
StartAllBackends();
}
void TearDown() override {
rls_server_->Shutdown();
XdsEnd2endTest::TearDown();
}
std::unique_ptr<RlsServerThread> rls_server_;
};
TEST_P(RlsTest, XdsRoutingClusterSpecifierPlugin) {
gpr_setenv("GRPC_EXPERIMENTAL_XDS_RLS_LB", "true");
const char* kNewClusterName = "new_cluster";
const char* kNewEdsServiceName = "new_eds_service_name";
const size_t kNumEchoRpcs = 5;
// Populate new EDS resources.
EdsResourceArgs args({
{"locality0", CreateEndpointsForBackends(0, 1)},
});
EdsResourceArgs args1({
{"locality0", CreateEndpointsForBackends(1, 2)},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName));
// Populate new CDS resources.
Cluster new_cluster = default_cluster_;
new_cluster.set_name(kNewClusterName);
new_cluster.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName);
balancer_->ads_service()->SetCdsResource(new_cluster);
// Prepare the RLSLookupConfig and configure all the keys; change route
// configurations to use cluster specifier plugin.
rls_server_->rls_service()->SetResponse(
BuildRlsRequest({{kRlsTestKey, kRlsTestValue},
{kRlsHostKey, kServerName},
{kRlsServiceKey, kRlsServiceValue},
{kRlsMethodKey, kRlsMethodValue},
{kRlsConstantKey, kRlsConstantValue}}),
BuildRlsResponse({kNewClusterName}));
RouteLookupConfig route_lookup_config;
auto* key_builder = route_lookup_config.add_grpc_keybuilders();
auto* name = key_builder->add_names();
name->set_service(kRlsServiceValue);
name->set_method(kRlsMethodValue);
auto* header = key_builder->add_headers();
header->set_key(kRlsTestKey);
header->add_names(kRlsTestKey1);
header->add_names("key2");
auto* extra_keys = key_builder->mutable_extra_keys();
extra_keys->set_host(kRlsHostKey);
extra_keys->set_service(kRlsServiceKey);
extra_keys->set_method(kRlsMethodKey);
(*key_builder->mutable_constant_keys())[kRlsConstantKey] = kRlsConstantValue;
route_lookup_config.set_lookup_service(
absl::StrCat("localhost:", rls_server_->port()));
route_lookup_config.set_cache_size_bytes(5000);
RouteLookupClusterSpecifier rls;
*rls.mutable_route_lookup_config() = std::move(route_lookup_config);
RouteConfiguration new_route_config = default_route_config_;
auto* plugin = new_route_config.add_cluster_specifier_plugins();
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
auto* default_route =
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
default_route->mutable_route()->set_cluster_specifier_plugin(
kRlsClusterSpecifierPluginInstanceName);
SetRouteConfiguration(balancer_.get(), new_route_config);
auto rpc_options = RpcOptions().set_metadata({{kRlsTestKey1, kRlsTestValue}});
WaitForAllBackends(1, 2, WaitForBackendOptions(), rpc_options);
CheckRpcSendOk(kNumEchoRpcs, rpc_options);
// Make sure RPCs all go to the correct backend.
EXPECT_EQ(kNumEchoRpcs, backends_[1]->backend_service()->request_count());
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_XDS_RLS_LB");
}
TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginNacksUndefinedSpecifier) {
gpr_setenv("GRPC_EXPERIMENTAL_XDS_RLS_LB", "true");
const char* kNewClusterName = "new_cluster";
const char* kNewEdsServiceName = "new_eds_service_name";
// Populate new EDS resources.
EdsResourceArgs args({
{"locality0", CreateEndpointsForBackends(0, 1)},
});
EdsResourceArgs args1({
{"locality0", CreateEndpointsForBackends(1, 2)},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName));
// Populate new CDS resources.
Cluster new_cluster = default_cluster_;
new_cluster.set_name(kNewClusterName);
new_cluster.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName);
balancer_->ads_service()->SetCdsResource(new_cluster);
RouteConfiguration new_route_config = default_route_config_;
auto* default_route =
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
// Set Cluster Specifier Plugin to something that does not exist.
default_route->mutable_route()->set_cluster_specifier_plugin(
kRlsClusterSpecifierPluginInstanceName);
SetRouteConfiguration(balancer_.get(), new_route_config);
const auto response_state = WaitForRdsNack();
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
EXPECT_THAT(response_state->error_message,
::testing::HasSubstr("RouteAction cluster contains cluster "
"specifier plugin name not configured."));
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_XDS_RLS_LB");
}
TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginNacksUnknownSpecifierProto) {
// TODO(donnadionne): Doug is working on adding a new is_optional field to
// ClusterSpecifierPlugin in envoyproxy/envoy#20301. Once that goes in, the
// behavior we want in this case is that if is_optional is true, then we
// ignore that plugin and ignore any routes that refer to that plugin.
// However, if is_optional is false, then we want to NACK.
gpr_setenv("GRPC_EXPERIMENTAL_XDS_RLS_LB", "true");
const char* kNewClusterName = "new_cluster";
const char* kNewEdsServiceName = "new_eds_service_name";
// Populate new EDS resources.
EdsResourceArgs args({
{"locality0", CreateEndpointsForBackends(0, 1)},
});
EdsResourceArgs args1({
{"locality0", CreateEndpointsForBackends(1, 2)},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName));
// Populate new CDS resources.
Cluster new_cluster = default_cluster_;
new_cluster.set_name(kNewClusterName);
new_cluster.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName);
balancer_->ads_service()->SetCdsResource(new_cluster);
// Prepare the RLSLookupConfig: change route configurations to use cluster
// specifier plugin.
RouteLookupConfig route_lookup_config;
RouteConfiguration new_route_config = default_route_config_;
auto* plugin = new_route_config.add_cluster_specifier_plugins();
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
// Instead of grpc.lookup.v1.RouteLookupClusterSpecifier, let's say we
// mistakenly packed the inner RouteLookupConfig instead.
plugin->mutable_extension()->mutable_typed_config()->PackFrom(
route_lookup_config);
auto* default_route =
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
default_route->mutable_route()->set_cluster_specifier_plugin(
kRlsClusterSpecifierPluginInstanceName);
SetRouteConfiguration(balancer_.get(), new_route_config);
const auto response_state = WaitForRdsNack();
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
EXPECT_THAT(
response_state->error_message,
::testing::HasSubstr(
"Unable to locate the cluster specifier plugin in the registry"));
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_XDS_RLS_LB");
}
TEST_P(RlsTest, XdsRoutingRlsClusterSpecifierPluginNacksRequiredMatch) {
gpr_setenv("GRPC_EXPERIMENTAL_XDS_RLS_LB", "true");
const char* kNewClusterName = "new_cluster";
const char* kNewEdsServiceName = "new_eds_service_name";
// Populate new EDS resources.
EdsResourceArgs args({
{"locality0", CreateEndpointsForBackends(0, 1)},
});
EdsResourceArgs args1({
{"locality0", CreateEndpointsForBackends(1, 2)},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName));
// Populate new CDS resources.
Cluster new_cluster = default_cluster_;
new_cluster.set_name(kNewClusterName);
new_cluster.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName);
balancer_->ads_service()->SetCdsResource(new_cluster);
// Prepare the RLSLookupConfig and configure all the keys; add required_match
// field which should not be there.
RouteLookupConfig route_lookup_config;
auto* key_builder = route_lookup_config.add_grpc_keybuilders();
auto* name = key_builder->add_names();
name->set_service(kRlsServiceValue);
name->set_method(kRlsMethodValue);
auto* header = key_builder->add_headers();
header->set_key(kRlsTestKey);
header->add_names(kRlsTestKey1);
header->set_required_match(true);
route_lookup_config.set_lookup_service(
absl::StrCat("localhost:", rls_server_->port()));
route_lookup_config.set_cache_size_bytes(5000);
RouteLookupClusterSpecifier rls;
*rls.mutable_route_lookup_config() = std::move(route_lookup_config);
RouteConfiguration new_route_config = default_route_config_;
auto* plugin = new_route_config.add_cluster_specifier_plugins();
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
auto* default_route =
new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
default_route->mutable_route()->set_cluster_specifier_plugin(
kRlsClusterSpecifierPluginInstanceName);
SetRouteConfiguration(balancer_.get(), new_route_config);
const auto response_state = WaitForRdsNack();
ASSERT_TRUE(response_state.has_value()) << "timed out waiting for NACK";
EXPECT_THAT(
response_state->error_message,
::testing::HasSubstr("field:requiredMatch error:must not be present"));
gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_XDS_RLS_LB");
}
TEST_P(RlsTest, XdsRoutingClusterSpecifierPluginDisabled) {
const char* kNewClusterName = "new_cluster";
const char* kNewEdsServiceName = "new_eds_service_name";
// Populate new EDS resources.
EdsResourceArgs args({
{"locality0", CreateEndpointsForBackends(0, 1)},
});
EdsResourceArgs args1({
{"locality0", CreateEndpointsForBackends(1, 2)},
});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
balancer_->ads_service()->SetEdsResource(
BuildEdsResource(args1, kNewEdsServiceName));
// Populate new CDS resources.
Cluster new_cluster = default_cluster_;
new_cluster.set_name(kNewClusterName);
new_cluster.mutable_eds_cluster_config()->set_service_name(
kNewEdsServiceName);
balancer_->ads_service()->SetCdsResource(new_cluster);
// Prepare the RLSLookupConfig and configure all the keys; change route
// configurations to use cluster specifier plugin.
RouteLookupConfig route_lookup_config;
auto* key_builder = route_lookup_config.add_grpc_keybuilders();
auto* name = key_builder->add_names();
name->set_service(kRlsServiceValue);
name->set_method(kRlsMethodValue);
auto* header = key_builder->add_headers();
header->set_key(kRlsTestKey);
header->add_names(kRlsTestKey1);
route_lookup_config.set_lookup_service(
absl::StrCat("localhost:", rls_server_->port()));
route_lookup_config.set_cache_size_bytes(5000);
RouteLookupClusterSpecifier rls;
*rls.mutable_route_lookup_config() = std::move(route_lookup_config);
RouteConfiguration new_route_config = default_route_config_;
auto* plugin = new_route_config.add_cluster_specifier_plugins();
plugin->mutable_extension()->set_name(kRlsClusterSpecifierPluginInstanceName);
plugin->mutable_extension()->mutable_typed_config()->PackFrom(rls);
auto* route = new_route_config.mutable_virtual_hosts(0)->mutable_routes(0);
route->mutable_route()->set_cluster_specifier_plugin(
kRlsClusterSpecifierPluginInstanceName);
auto* default_route = new_route_config.mutable_virtual_hosts(0)->add_routes();
default_route->mutable_match()->set_prefix("");
default_route->mutable_route()->set_cluster(kDefaultClusterName);
SetRouteConfiguration(balancer_.get(), new_route_config);
// Ensure we ignore the cluster specifier plugin and send traffic according to
// the default route.
auto rpc_options = RpcOptions().set_metadata({{kRlsTestKey1, kRlsTestValue}});
WaitForAllBackends(0, 1, WaitForBackendOptions(), rpc_options);
}
class XdsSecurityTest : public BasicTest {
protected:
void SetUp() override {
@ -13465,6 +13901,14 @@ INSTANTIATE_TEST_SUITE_P(
TestType().set_enable_rds_testing().set_use_v2()),
&TestTypeName);
// Rls tests depend on XdsResolver.
INSTANTIATE_TEST_SUITE_P(
XdsTest, RlsTest,
::testing::Values(TestType(), TestType().set_enable_rds_testing(),
// Also test with xDS v2.
TestType().set_enable_rds_testing().set_use_v2()),
&TestTypeName);
// CDS depends on XdsResolver.
INSTANTIATE_TEST_SUITE_P(
XdsTest, CdsTest,

@ -37,6 +37,7 @@ grpc_cc_test(
"//:grpc_opencensus_plugin",
"//src/proto/grpc/testing:echo_proto",
"//test/core/util:grpc_test_util",
"//test/cpp/end2end:test_service_impl",
"//test/cpp/util:test_config",
"//test/cpp/util:test_util",
],

@ -37,6 +37,7 @@
#include "src/cpp/ext/filters/census/grpc_plugin.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
namespace grpc {
namespace testing {
@ -54,12 +55,25 @@ const auto TEST_TAG_KEY = TagKey::Register("my_key");
const auto TEST_TAG_VALUE = "my_value";
const char* kExpectedTraceIdKey = "expected_trace_id";
class EchoServer final : public EchoTestService::Service {
grpc::Status Echo(grpc::ServerContext* context, const EchoRequest* request,
class EchoServer final : public TestServiceImpl {
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) override {
CheckMetadata(context);
return TestServiceImpl::Echo(context, request, response);
}
Status BidiStream(
ServerContext* context,
ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
CheckMetadata(context);
return TestServiceImpl::BidiStream(context, stream);
}
private:
void CheckMetadata(ServerContext* context) {
for (const auto& metadata : context->client_metadata()) {
if (metadata.first == kExpectedTraceIdKey) {
EXPECT_EQ(metadata.second, reinterpret_cast<const grpc::CensusContext*>(
EXPECT_EQ(metadata.second, reinterpret_cast<const CensusContext*>(
context->census_context())
->Span()
.context()
@ -68,14 +82,6 @@ class EchoServer final : public EchoTestService::Service {
break;
}
}
if (request->param().expected_error().code() == 0) {
response->set_message(request->message());
return grpc::Status::OK;
} else {
return grpc::Status(static_cast<grpc::StatusCode>(
request->param().expected_error().code()),
"");
}
}
};
@ -374,6 +380,20 @@ TEST_F(StatsPluginEnd2EndTest, CompletedRpcs) {
::testing::UnorderedElementsAre(::testing::Pair(
::testing::ElementsAre(server_method_name_, "OK"), i + 1)));
}
// Client should see calls that are cancelled without calling Finish().
{
ClientContext ctx;
auto stream = stub_->BidiStream(&ctx);
ctx.TryCancel();
}
absl::SleepFor(absl::Milliseconds(500));
TestUtils::Flush();
EXPECT_THAT(client_completed_rpcs_view.GetData().int_data(),
::testing::Contains(::testing::Pair(
::testing::ElementsAre(
"grpc.testing.EchoTestService/BidiStream", "CANCELLED"),
1)));
}
TEST_F(StatsPluginEnd2EndTest, RequestReceivedMessagesPerRpc) {
@ -472,7 +492,6 @@ TEST_F(StatsPluginEnd2EndTest, TestRetryStatsWithAdditionalRetries) {
ClientTransparentRetriesCumulative());
View client_retry_delay_per_call_view(ClientRetryDelayPerCallCumulative());
ChannelArguments args;
args.SetInt(GRPC_ARG_ENABLE_RETRIES, 1);
args.SetString(GRPC_ARG_SERVICE_CONFIG,
"{\n"
" \"methodConfig\": [ {\n"

@ -0,0 +1,43 @@
# Copyright 2022 the 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.
licenses(["notice"])
cc_binary(
name = "greeter_client",
srcs = ["greeter_client.cc"],
deps = [
"//protos:helloworld_cc_grpc",
"@com_github_grpc_grpc//:grpc++",
],
)
cc_binary(
name = "greeter_server",
srcs = ["greeter_server.cc"],
deps = [
"//protos:helloworld_cc_grpc",
"@com_github_grpc_grpc//:grpc++",
"@com_github_grpc_grpc//:grpc++_reflection",
],
)
sh_test(
name = "greeter_test",
srcs = ["greeter_test.sh"],
data = [
":greeter_client",
":greeter_server",
],
)

@ -0,0 +1,27 @@
# Copyright 2022 The 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.
local_repository(
name = "com_github_grpc_grpc",
path = "../../../..",
)
workspace(name = "bazel_cpp_distribtests")
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
grpc_deps()
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
grpc_extra_deps()

@ -0,0 +1,104 @@
/*
*
* Copyright 2022 The 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 <iostream>
#include <memory>
#include <string>
#include <grpcpp/grpcpp.h>
#include "protos/helloworld.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
// Assembles the client's payload, sends it and presents the response back
// from the server.
std::string SayHello(const std::string& user) {
// Data we are sending to the server.
HelloRequest request;
request.set_name(user);
// Container for the data we expect from the server.
HelloReply reply;
// Context for the client. It could be used to convey extra information to
// the server and/or tweak certain RPC behaviors.
ClientContext context;
// The actual RPC.
Status status = stub_->SayHello(&context, request, &reply);
// Act upon its status.
if (status.ok()) {
return reply.message();
} else {
std::cout << status.error_code() << ": " << status.error_message()
<< std::endl;
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
// Instantiate the client. It requires a channel, out of which the actual RPCs
// are created. This channel models a connection to an endpoint specified by
// the argument "--target=" which is the only expected argument.
// We indicate that the channel isn't authenticated (use of
// InsecureChannelCredentials()).
std::string target_str;
std::string arg_str("--target");
if (argc > 1) {
std::string arg_val = argv[1];
size_t start_pos = arg_val.find(arg_str);
if (start_pos != std::string::npos) {
start_pos += arg_str.size();
if (arg_val[start_pos] == '=') {
target_str = arg_val.substr(start_pos + 1);
} else {
std::cout << "The only correct argument syntax is --target="
<< std::endl;
return 0;
}
} else {
std::cout << "The only acceptable argument is --target=" << std::endl;
return 0;
}
} else {
target_str = "localhost:50051";
}
GreeterClient greeter(
grpc::CreateChannel(target_str, grpc::InsecureChannelCredentials()));
std::string user("world");
std::string reply = greeter.SayHello(user);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}

@ -0,0 +1,73 @@
/*
*
* Copyright 2022 The 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 <iostream>
#include <memory>
#include <string>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#include "protos/helloworld.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using helloworld::Greeter;
using helloworld::HelloReply;
using helloworld::HelloRequest;
// Logic and data behind the server's behavior.
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:0");
GreeterServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
int bound_port;
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials(), &bound_port);
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "127.0.0.1:" << bound_port << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char** argv) {
RunServer();
return 0;
}

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Copyright 2022 The 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.
set -exo pipefail
SERVER_PID=""
SERVER_TIMEOUT=10
SERVER_OUTPUT=$(mktemp)
function cleanup() {
if [ -n "$SERVER_PID" ]; then
kill "$SERVER_PID"
fi
}
function fail() {
echo "$1" >/dev/stderr
echo "Failed." >/dev/stderr
exit 1
}
function await_server() {
TIME=0
while [ ! -s "$SERVER_OUTPUT" ]; do
if [ "$TIME" == "$SERVER_TIMEOUT" ] ; then
fail "Server not listening after $SERVER_TIMEOUT seconds."
fi
sleep 1
TIME=$((TIME+1))
done
cat "$SERVER_OUTPUT"
}
trap cleanup SIGINT SIGTERM EXIT
./greeter_server >"$SERVER_OUTPUT" &
SERVER_PID=$!
SERVER_ADDRESS=$(await_server)
RESPONSE=$(./greeter_client --target="$SERVER_ADDRESS")
EXPECTED_RESPONSE="Greeter received: Hello world"
if [ "$RESPONSE" != "$EXPECTED_RESPONSE" ]; then
fail "Received response \"$RESPONSE\" but expected \"$EXPECTED_RESPONSE\""
fi
echo "Success."

@ -0,0 +1,37 @@
# Copyright 2022 the 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.
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
licenses(["notice"])
package(default_visibility = ["//:__subpackages__"])
proto_library(
name = "helloworld_proto",
srcs = ["helloworld.proto"],
)
cc_proto_library(
name = "helloworld_cc_proto",
deps = [":helloworld_proto"],
)
cc_grpc_library(
name = "helloworld_cc_grpc",
srcs = [":helloworld_proto"],
grpc_only = True,
deps = [":helloworld_cc_proto"],
)

@ -0,0 +1,38 @@
// Copyright 2015 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.
syntax = "proto3";
option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}

@ -0,0 +1 @@
../../../../../tools/bazel

@ -18,20 +18,16 @@ set -ex
cd "$(dirname "$0")"
# TODO(jtattermusch): make build work with bazel 2.2.0 and bazel 1.2.1 if that's reasonably simple.
SUPPORTED_VERSIONS=(
"3.7.2"
"4.0.0"
"5.0.0"
)
VERSIONS=$(cat ../../../bazel/supported_versions.txt)
FAILED_VERSIONS=""
for VERSION in "${SUPPORTED_VERSIONS[@]}"; do
for VERSION in $VERSIONS; do
echo "Running bazel distribtest with bazel version ${VERSION}"
./test_single_bazel_version.sh "${VERSION}" || FAILED_VERSIONS="${FAILED_VERSIONS}${VERSION} "
done
if [ "$FAILED_VERSIONS" != "" ]
then
echo "Bazel distribtest failed: Failed to build with bazel versions ${FAILED_VERSIONS}"
echo "Bazel distribtest failed: Failing versions: ${FAILED_VERSIONS}"
exit 1
fi

@ -41,7 +41,19 @@ EXCLUDED_TARGETS=(
"-//examples/android/binder/..."
)
FAILED_TESTS=""
export OVERRIDE_BAZEL_VERSION="$VERSION"
# when running under bazel docker image, the workspace is read only.
export OVERRIDE_BAZEL_WRAPPER_DOWNLOAD_DIR=/tmp
bazel build -- //... "${EXCLUDED_TARGETS[@]}"
bazel build -- //... "${EXCLUDED_TARGETS[@]}" || FAILED_TESTS="${FAILED_TESTS}Build "
cd test/distrib/bazel/cpp/
bazel test //:all || FAILED_TESTS="${FAILED_TESTS}C++ Distribtest"
if [ "$FAILED_TESTS" != "" ]
then
echo "Failed tests at version ${VERSION}: ${FAILED_TESTS}"
exit 1
fi

@ -0,0 +1,28 @@
# Copyright 2022 The 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.
"""Retrieves supported bazel versions from plaintext file."""
_SUPPORTED_VERSIONS_FILE = "bazel/supported_versions.txt"
def _get_supported_bazel_versions():
versions = []
with open(_SUPPORTED_VERSIONS_FILE, "r") as f:
for line in f:
versions.append(line.strip())
return versions
def mako_plugin(dictionary):
dictionary["supported_bazel_versions"] = _get_supported_bazel_versions()

@ -58,84 +58,84 @@ RUN mkdir /var/local/jenkins
#=================
# Compile CPython 3.6.9 from source
# Compile CPython 3.6.15 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && \
wget -q https://www.python.org/ftp/python/3.6.9/Python-3.6.9.tgz && \
tar xzvf Python-3.6.9.tgz && \
cd Python-3.6.9 && \
wget -q https://www.python.org/ftp/python/3.6.15/Python-3.6.15.tgz && \
tar xzvf Python-3.6.15.tgz && \
cd Python-3.6.15 && \
./configure && \
make -j4 && \
make install
RUN cd /tmp && \
echo "ff7cdaef4846c89c1ec0d7b709bbd54d Python-3.6.9.tgz" > checksum.md5 && \
echo "f9e6f91c754a604f4fc6f6c7683723fb Python-3.6.15.tgz" > checksum.md5 && \
md5sum -c checksum.md5
RUN python3.6 -m ensurepip && \
python3.6 -m pip install coverage
#=================
# Compile CPython 3.7.12 from source
# Compile CPython 3.7.13 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && \
wget -q https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz && \
tar xzvf Python-3.7.12.tgz && \
cd Python-3.7.12 && \
wget -q https://www.python.org/ftp/python/3.7.13/Python-3.7.13.tgz && \
tar xzvf Python-3.7.13.tgz && \
cd Python-3.7.13 && \
./configure && \
make -j4 && \
make install
RUN cd /tmp && \
echo "6fe83678c085a7735a943cf1e4d41c14 Python-3.7.12.tgz" > checksum.md5 && \
echo "e0d3321026d4a5f3a3890b5d821ad762 Python-3.7.13.tgz" > checksum.md5 && \
md5sum -c checksum.md5
RUN python3.7 -m ensurepip && \
python3.7 -m pip install coverage
#=================
# Compile CPython 3.8.0b4 from source
# Compile CPython 3.8.13 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && \
wget -q https://www.python.org/ftp/python/3.8.0/Python-3.8.0b4.tgz && \
tar xzvf Python-3.8.0b4.tgz && \
cd Python-3.8.0b4 && \
wget -q https://www.python.org/ftp/python/3.8.13/Python-3.8.13.tgz && \
tar xzvf Python-3.8.13.tgz && \
cd Python-3.8.13 && \
./configure && \
make -j4 && \
make install
RUN cd /tmp && \
echo "b8f4f897df967014ddb42033b90c3058 Python-3.8.0b4.tgz" > checksum.md5 && \
echo "3c49180c6b43df3519849b7e390af0b9 Python-3.8.13.tgz" > checksum.md5 && \
md5sum -c checksum.md5
RUN python3.8 -m ensurepip && \
python3.8 -m pip install coverage
#=================
# Compile CPython 3.10.2 from source
# Compile CPython 3.10.3 from source
RUN apt-get update && apt-get install -y zlib1g-dev libssl-dev && apt-get clean
RUN apt-get update && apt-get install -y jq build-essential libffi-dev && apt-get clean
RUN cd /tmp && \
wget -q https://www.python.org/ftp/python/3.10.2/Python-3.10.2.tgz && \
tar xzvf Python-3.10.2.tgz && \
cd Python-3.10.2 && \
wget -q https://www.python.org/ftp/python/3.10.3/Python-3.10.3.tgz && \
tar xzvf Python-3.10.3.tgz && \
cd Python-3.10.3 && \
./configure && \
make -j4 && \
make install
RUN cd /tmp && \
echo "67c92270be6701f4a6fed57c4530139b Python-3.10.2.tgz" > checksum.md5 && \
echo "f276ffcd05bccafe46da023d0a5bb04a Python-3.10.3.tgz" > checksum.md5 && \
md5sum -c checksum.md5
RUN python3.10 -m ensurepip && \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \
@ -1510,6 +1511,8 @@ src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.h \
src/core/ext/upb-generated/udpa/annotations/security.upb.c \
@ -1778,6 +1781,8 @@ src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h \
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
@ -1845,6 +1850,8 @@ src/core/ext/xds/xds_client_stats.cc \
src/core/ext/xds/xds_client_stats.h \
src/core/ext/xds/xds_cluster.cc \
src/core/ext/xds/xds_cluster.h \
src/core/ext/xds/xds_cluster_specifier_plugin.cc \
src/core/ext/xds/xds_cluster_specifier_plugin.h \
src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_common_types.h \
src/core/ext/xds/xds_endpoint.cc \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \
@ -1300,6 +1301,8 @@ src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lb/v1/load_balancer.upb.h \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls.upb.h \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.c \
src/core/ext/upb-generated/src/proto/grpc/lookup/v1/rls_config.upb.h \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.c \
src/core/ext/upb-generated/udpa/annotations/migrate.upb.h \
src/core/ext/upb-generated/udpa/annotations/security.upb.c \
@ -1568,6 +1571,8 @@ src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.c \
src/core/ext/upbdefs-generated/google/rpc/status.upbdefs.h \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.c \
src/core/ext/upbdefs-generated/opencensus/proto/trace/v1/trace_config.upbdefs.h \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.c \
src/core/ext/upbdefs-generated/src/proto/grpc/lookup/v1/rls_config.upbdefs.h \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.c \
src/core/ext/upbdefs-generated/udpa/annotations/migrate.upbdefs.h \
src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c \
@ -1635,6 +1640,8 @@ src/core/ext/xds/xds_client_stats.cc \
src/core/ext/xds/xds_client_stats.h \
src/core/ext/xds/xds_cluster.cc \
src/core/ext/xds/xds_cluster.h \
src/core/ext/xds/xds_cluster_specifier_plugin.cc \
src/core/ext/xds/xds_cluster_specifier_plugin.h \
src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_common_types.h \
src/core/ext/xds/xds_endpoint.cc \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \

@ -762,6 +762,7 @@ WARN_LOGFILE =
INPUT = doc/PROTOCOL-HTTP2.md \
doc/PROTOCOL-WEB.md \
doc/bazel_support.md \
doc/binary-logging.md \
doc/c-style-guide.md \
doc/command_line_tool.md \

@ -63,51 +63,51 @@ function Install-Python {
# Python 3.8
$Python38x86Config = @{
PythonVersion = "3.8.0"
PythonInstaller = "python-3.8.0"
PythonVersion = "3.8.10"
PythonInstaller = "python-3.8.10"
PythonInstallPath = "C:\Python38_32bit"
PythonInstallerHash = "412a649d36626d33b8ca5593cf18318c"
PythonInstallerHash = "b355cfc84b681ace8908ae50908e8761"
}
Install-Python @Python38x86Config
$Python38x64Config = @{
PythonVersion = "3.8.0"
PythonInstaller = "python-3.8.0-amd64"
PythonVersion = "3.8.10"
PythonInstaller = "python-3.8.10-amd64"
PythonInstallPath = "C:\Python38"
PythonInstallerHash = "29ea87f24c32f5e924b7d63f8a08ee8d"
PythonInstallerHash = "62cf1a12a5276b0259e8761d4cf4fe42"
}
Install-Python @Python38x64Config
# Python 3.9
$Python39x86Config = @{
PythonVersion = "3.9.0"
PythonInstaller = "python-3.9.0"
PythonVersion = "3.9.11"
PythonInstaller = "python-3.9.11"
PythonInstallPath = "C:\Python39_32bit"
PythonInstallerHash = "4a2812db8ab9f2e522c96c7728cfcccb"
PythonInstallerHash = "4210652b14a030517046cdf111c09c1e"
}
Install-Python @Python39x86Config
$Python39x64Config = @{
PythonVersion = "3.9.0"
PythonInstaller = "python-3.9.0-amd64"
PythonVersion = "3.9.11"
PythonInstaller = "python-3.9.11-amd64"
PythonInstallPath = "C:\Python39"
PythonInstallerHash = "b61a33dc28f13b561452f3089c87eb63"
PythonInstallerHash = "fef52176a572efd48b7148f006b25801"
}
Install-Python @Python39x64Config
# Python 3.10
$Python310x86Config = @{
PythonVersion = "3.10.0"
PythonInstaller = "python-3.10.0rc1"
PythonVersion = "3.10.3"
PythonInstaller = "python-3.10.3"
PythonInstallPath = "C:\Python310_32bit"
PythonInstallerHash = "6de353f2f7422aa030d4ccc788ffa75e"
PythonInstallerHash = "6a336cb2aca62dd05805316ab3aaf2b5"
}
Install-Python @Python310x86Config
$Python310x64Config = @{
PythonVersion = "3.10.0"
PythonInstaller = "python-3.10.0rc1-amd64"
PythonVersion = "3.10.3"
PythonInstaller = "python-3.10.3-amd64"
PythonInstallPath = "C:\Python310"
PythonInstallerHash = "39135519b044757f0a3b09d63612b0da"
PythonInstallerHash = "9ea305690dbfd424a632b6a659347c1e"
}
Install-Python @Python310x64Config

@ -53,7 +53,7 @@ bazel build --define=use_strict_warning=true --define=use_abseil_status=true \
bazel build //test/cpp/end2end:end2end_test --define=grpc_no_xds=true
# Test that builds that need xDS do not build with --define=grpc_no_xds=true
EXIT_CODE=0
bazel build //test/cpp/end2end:xds_end2end_test --define=grpc_no_xds=true || EXIT_CODE=$?
bazel build //test/cpp/end2end/xds:xds_end2end_test --define=grpc_no_xds=true || EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]
then
echo "Building xds_end2end_test succeeded even with --define=grpc_no_xds=true"

@ -49,6 +49,11 @@ _INTERESTING = {
(rb'server call memory usage: ([0-9\.]+) bytes per call', float),
}
_SCENARIOS = {
'default': [],
'minstack': ['--minstack'],
}
def _run():
"""Build with Bazel, then run, and extract interesting lines from the output."""
@ -56,24 +61,27 @@ def _run():
'tools/bazel', 'build', '-c', 'opt',
'test/core/memory_usage/memory_usage_test'
])
ret = {}
for scenario, extra_args in _SCENARIOS.items():
try:
output = subprocess.check_output([
'bazel-bin/test/core/memory_usage/memory_usage_test',
'--warmup=10000',
'--benchmark=50000',
])
ret = {}
] + extra_args)
except subprocess.CalledProcessError as e:
print('Error running benchmark:', e)
continue
for line in output.splitlines():
for key, (pattern, conversion) in _INTERESTING.items():
m = re.match(pattern, line)
if m:
ret[key] = conversion(m.group(1))
ret[scenario + ': ' + key] = conversion(m.group(1))
return ret
cur = _run()
new = None
print(cur)
old = None
if args.diff_base:
where_am_i = subprocess.check_output(
@ -81,24 +89,28 @@ if args.diff_base:
# checkout the diff base (="old")
subprocess.check_call(['git', 'checkout', args.diff_base])
try:
new = _run()
old = _run()
finally:
# restore the original revision (="new")
# restore the original revision (="cur")
subprocess.check_call(['git', 'checkout', where_am_i])
text = ''
if new is None:
for key, value in cur.items():
if old is None:
print(cur)
for key, value in sorted(cur.items()):
text += '{}: {}\n'.format(key, value)
else:
print(cur, old)
diff_size = 0
for key, value in _INTERESTING.items():
for scenario in _SCENARIOS.keys():
for key, value in sorted(_INTERESTING.items()):
key = scenario + ': ' + key
if key in cur:
if key not in new:
text += '{}: {}\n'.format(key, value)
if key not in old:
text += '{}: {}\n'.format(key, cur[key])
else:
diff_size += cur[key] - new[key]
text += '{}: {} -> {}\n'.format(key, cur[key], new[key])
diff_size += cur[key] - old[key]
text += '{}: {} -> {}\n'.format(key, old[key], cur[key])
print("DIFF_SIZE: %f" % diff_size)
check_on_pr.label_increase_decrease_on_pr('per-call-memory', diff_size, 64)

@ -0,0 +1,46 @@
#!/bin/bash
#Copyright 2022 The 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.
# This script can be used to manually update the specific versions of Bazel
# tested by the Bazel distribtests and advertised as supported in documentation.
# This will update the supported_versions.txt file, which will be templated into
# the bazel_support.md document.
# This script selects the latest patch release of the two most recent major
# versions of Bazel. If you want to include other versions in the set of
# supported versions, then you will need to manually edit the ifle.
set -xeuo pipefail
cd "$(dirname "$0")/../.."
# The number of most recent supported major Bazel versions.
SUPPORT_RANGE="2"
# Retrieve all git tags from the Bazel git repo.
TAGS=$(git ls-remote --tags git@github.com:bazelbuild/bazel.git | awk '{print $2;}' | sed 's|refs/tags/||g')
# Find the n most recent major versions.
MAJOR_VERSIONS=$(echo "$TAGS" | egrep '^[0-9]+\.[0-9]+\.[0-9]+$' | cut -d'.' -f1 | sort -r | uniq | head -n"$SUPPORT_RANGE")
SUPPORTED_VERSIONS=""
# For each major version selected, find the most recent patch release.
while read -r MAJOR_VERSION; do
LATEST_PATCH=$(echo "$TAGS" | egrep "^${MAJOR_VERSION}\.[0-9]+\.[0-9]+$" | sort -nr | head -n1)
SUPPORTED_VERSIONS="$SUPPORTED_VERSIONS$LATEST_PATCH\n"
done<<<"$MAJOR_VERSIONS"
printf "$SUPPORTED_VERSIONS" | tee bazel/supported_versions.txt
Loading…
Cancel
Save