xds: Add XdsLbRegistry (#29756)

* xds: Add XdsLbRegistry

* Formatting

* Fix upb output

* Allow alternative type url for Custom LBs

* Cleanup

* Reviewer comments

* Add some comments

* Reviewer comments

* Reviewer comments

* Reviewer comments

* Reviewer comments

* Fix tests

* Fix tests

* Fix tests

* Fix tests

* Fix tests

* Unused parameters

* Change to make TextFormat usage work internally

* Fix namespace qualification error
pull/29862/head
Yash Tibrewal 3 years ago committed by GitHub
parent 5dc917e1f9
commit 5d9cdc8e67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      BUILD
  2. 117
      CMakeLists.txt
  3. 6
      Makefile
  4. 43
      build_autogenerated.yaml
  5. 5
      config.m4
  6. 8
      config.w32
  7. 6
      gRPC-C++.podspec
  8. 9
      gRPC-Core.podspec
  9. 6
      grpc.gemspec
  10. 3
      grpc.gyp
  11. 6
      package.xml
  12. 52
      src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c
  13. 164
      src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h
  14. 46
      src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c
  15. 94
      src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h
  16. 32
      src/core/ext/xds/xds_common_types.cc
  17. 12
      src/core/ext/xds/xds_common_types.h
  18. 291
      src/core/ext/xds/xds_lb_policy_registry.cc
  19. 72
      src/core/ext/xds/xds_lb_policy_registry.h
  20. 23
      src/core/ext/xds/xds_listener.cc
  21. 27
      src/core/ext/xds/xds_route_config.cc
  22. 44
      src/proto/grpc/testing/xds/v3/BUILD
  23. 39
      src/proto/grpc/testing/xds/v3/cluster.proto
  24. 59
      src/proto/grpc/testing/xds/v3/ring_hash.proto
  25. 28
      src/proto/grpc/testing/xds/v3/round_robin.proto
  26. 53
      src/proto/grpc/testing/xds/v3/typed_struct.proto
  27. 53
      src/proto/grpc/testing/xds/v3/udpa_typed_struct.proto
  28. 31
      src/proto/grpc/testing/xds/v3/wrr_locality.proto
  29. 3
      src/python/grpcio/grpc_core_dependencies.py
  30. 20
      test/core/xds/BUILD
  31. 534
      test/core/xds/xds_lb_policy_registry_test.cc
  32. 6
      test/cpp/end2end/xds/xds_end2end_test.cc
  33. 8
      test/cpp/end2end/xds/xds_routing_end2end_test.cc
  34. 6
      tools/doxygen/Doxyfile.c++.internal
  35. 6
      tools/doxygen/Doxyfile.core.internal
  36. 24
      tools/run_tests/generated/tests.json

15
BUILD

@ -3623,6 +3623,7 @@ grpc_cc_library(
"src/core/ext/xds/xds_http_fault_filter.cc",
"src/core/ext/xds/xds_http_filters.cc",
"src/core/ext/xds/xds_http_rbac_filter.cc",
"src/core/ext/xds/xds_lb_policy_registry.cc",
"src/core/ext/xds/xds_listener.cc",
"src/core/ext/xds/xds_resource_type.cc",
"src/core/ext/xds/xds_route_config.cc",
@ -3648,6 +3649,7 @@ grpc_cc_library(
"src/core/ext/xds/xds_http_fault_filter.h",
"src/core/ext/xds/xds_http_filters.h",
"src/core/ext/xds/xds_http_rbac_filter.h",
"src/core/ext/xds/xds_lb_policy_registry.h",
"src/core/ext/xds/xds_listener.h",
"src/core/ext/xds/xds_resource_type.h",
"src/core/ext/xds/xds_resource_type_impl.h",
@ -3699,6 +3701,8 @@ grpc_cc_library(
"envoy_extensions_filters_http_router_upbdefs",
"envoy_extensions_filters_network_http_connection_manager_upb",
"envoy_extensions_filters_network_http_connection_manager_upbdefs",
"envoy_extensions_load_balancing_policies_ring_hash_upb",
"envoy_extensions_load_balancing_policies_wrr_locality_upb",
"envoy_extensions_transport_sockets_tls_upb",
"envoy_extensions_transport_sockets_tls_upbdefs",
"envoy_service_discovery_upb",
@ -3736,6 +3740,7 @@ grpc_cc_library(
"protobuf_any_upb",
"protobuf_duration_upb",
"protobuf_struct_upb",
"protobuf_struct_upbdefs",
"protobuf_timestamp_upb",
"protobuf_wrappers_upb",
"ref_counted_ptr",
@ -6624,6 +6629,16 @@ grpc_upb_proto_reflection_library(
deps = ["@envoy_api//envoy/extensions/filters/http/router/v3:pkg"],
)
grpc_upb_proto_library(
name = "envoy_extensions_load_balancing_policies_ring_hash_upb",
deps = ["@envoy_api//envoy/extensions/load_balancing_policies/ring_hash/v3:pkg"],
)
grpc_upb_proto_library(
name = "envoy_extensions_load_balancing_policies_wrr_locality_upb",
deps = ["@envoy_api//envoy/extensions/load_balancing_policies/wrr_locality/v3:pkg"],
)
grpc_upb_proto_library(
name = "envoy_extensions_filters_network_http_connection_manager_upb",
deps = ["@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg"],

117
CMakeLists.txt generated

@ -730,6 +730,12 @@ protobuf_generate_grpc_cpp_with_import_path_correction(
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/regex.proto src/proto/grpc/testing/xds/v3/regex.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/ring_hash.proto src/proto/grpc/testing/xds/v3/ring_hash.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/round_robin.proto src/proto/grpc/testing/xds/v3/round_robin.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/route.proto src/proto/grpc/testing/xds/v3/route.proto
)
@ -742,6 +748,15 @@ protobuf_generate_grpc_cpp_with_import_path_correction(
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/tls.proto src/proto/grpc/testing/xds/v3/tls.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/typed_struct.proto src/proto/grpc/testing/xds/v3/typed_struct.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/udpa_typed_struct.proto src/proto/grpc/testing/xds/v3/udpa_typed_struct.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/wrr_locality.proto src/proto/grpc/testing/xds/v3/wrr_locality.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
test/core/tsi/alts/fake_handshaker/handshaker.proto test/core/tsi/alts/fake_handshaker/handshaker.proto
)
@ -1209,6 +1224,7 @@ if(gRPC_BUILD_TESTS)
endif()
add_dependencies(buildtests_cxx xds_interop_client)
add_dependencies(buildtests_cxx xds_interop_server)
add_dependencies(buildtests_cxx xds_lb_policy_registry_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx xds_outlier_detection_end2end_test)
endif()
@ -1779,6 +1795,8 @@ add_library(grpc
src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c
@ -2004,6 +2022,7 @@ add_library(grpc
src/core/ext/xds/xds_http_fault_filter.cc
src/core/ext/xds/xds_http_filters.cc
src/core/ext/xds/xds_http_rbac_filter.cc
src/core/ext/xds/xds_lb_policy_registry.cc
src/core/ext/xds/xds_listener.cc
src/core/ext/xds/xds_resource_type.cc
src/core/ext/xds/xds_route_config.cc
@ -19047,6 +19066,104 @@ target_link_libraries(xds_interop_server
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(xds_lb_policy_registry_test
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/address.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/base.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/cluster.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/config_source.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/endpoint.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/extension.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/outlier_detection.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/percent.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ring_hash.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ring_hash.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ring_hash.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/ring_hash.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/round_robin.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/round_robin.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/round_robin.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/round_robin.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/typed_struct.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/typed_struct.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/typed_struct.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/typed_struct.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/udpa_typed_struct.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/udpa_typed_struct.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/udpa_typed_struct.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/udpa_typed_struct.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/wrr_locality.grpc.pb.h
test/core/xds/xds_lb_policy_registry_test.cc
test/cpp/util/cli_call.cc
test/cpp/util/cli_credentials.cc
test/cpp/util/proto_file_parser.cc
test/cpp/util/proto_reflection_descriptor_database.cc
test/cpp/util/service_describer.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(xds_lb_policy_registry_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(xds_lb_policy_registry_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::flags
grpc++
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)

6
Makefile generated

@ -1186,6 +1186,8 @@ LIBGRPC_SRC = \
src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c \
@ -1411,6 +1413,7 @@ LIBGRPC_SRC = \
src/core/ext/xds/xds_http_fault_filter.cc \
src/core/ext/xds/xds_http_filters.cc \
src/core/ext/xds/xds_http_rbac_filter.cc \
src/core/ext/xds/xds_lb_policy_registry.cc \
src/core/ext/xds/xds_listener.cc \
src/core/ext/xds/xds_resource_type.cc \
src/core/ext/xds/xds_route_config.cc \
@ -2896,6 +2899,8 @@ src/core/ext/upb-generated/envoy/extensions/filters/http/fault/v3/fault.upb.c: $
src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c: $(OPENSSL_DEP)
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c: $(OPENSSL_DEP)
@ -3104,6 +3109,7 @@ src/core/ext/xds/xds_endpoint.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_http_fault_filter.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_http_filters.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_http_rbac_filter.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_lb_policy_registry.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_listener.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_resource_type.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_route_config.cc: $(OPENSSL_DEP)

@ -487,6 +487,8 @@ libs:
- src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h
- src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h
- src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h
- src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h
- src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h
- src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h
- src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h
- src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h
@ -715,6 +717,7 @@ libs:
- src/core/ext/xds/xds_http_fault_filter.h
- src/core/ext/xds/xds_http_filters.h
- src/core/ext/xds/xds_http_rbac_filter.h
- src/core/ext/xds/xds_lb_policy_registry.h
- src/core/ext/xds/xds_listener.h
- src/core/ext/xds/xds_resource_type.h
- src/core/ext/xds/xds_resource_type_impl.h
@ -1165,6 +1168,8 @@ libs:
- src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c
- src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c
- src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c
- src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c
- src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c
- src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c
- src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c
- src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c
@ -1390,6 +1395,7 @@ libs:
- src/core/ext/xds/xds_http_fault_filter.cc
- src/core/ext/xds/xds_http_filters.cc
- src/core/ext/xds/xds_http_rbac_filter.cc
- src/core/ext/xds/xds_lb_policy_registry.cc
- src/core/ext/xds/xds_listener.cc
- src/core/ext/xds/xds_resource_type.cc
- src/core/ext/xds/xds_route_config.cc
@ -9350,6 +9356,43 @@ targets:
- grpcpp_channelz
- grpc_test_util
- grpc++_test_config
- name: xds_lb_policy_registry_test
gtest: true
build: test
language: c++
headers:
- test/cpp/util/cli_call.h
- test/cpp/util/cli_credentials.h
- test/cpp/util/config_grpc_cli.h
- test/cpp/util/proto_file_parser.h
- test/cpp/util/proto_reflection_descriptor_database.h
- test/cpp/util/service_describer.h
src:
- src/proto/grpc/reflection/v1alpha/reflection.proto
- src/proto/grpc/testing/xds/v3/address.proto
- src/proto/grpc/testing/xds/v3/base.proto
- src/proto/grpc/testing/xds/v3/cluster.proto
- src/proto/grpc/testing/xds/v3/config_source.proto
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/outlier_detection.proto
- src/proto/grpc/testing/xds/v3/percent.proto
- src/proto/grpc/testing/xds/v3/ring_hash.proto
- src/proto/grpc/testing/xds/v3/round_robin.proto
- src/proto/grpc/testing/xds/v3/typed_struct.proto
- src/proto/grpc/testing/xds/v3/udpa_typed_struct.proto
- src/proto/grpc/testing/xds/v3/wrr_locality.proto
- test/core/xds/xds_lb_policy_registry_test.cc
- test/cpp/util/cli_call.cc
- test/cpp/util/cli_credentials.cc
- test/cpp/util/proto_file_parser.cc
- test/cpp/util/proto_reflection_descriptor_database.cc
- test/cpp/util/service_describer.cc
deps:
- absl/flags:flag
- grpc++
- grpc_test_util
uses_polling: false
- name: xds_outlier_detection_end2end_test
gtest: true
build: test

5
config.m4 generated

@ -208,6 +208,8 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c \
@ -433,6 +435,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/xds/xds_http_fault_filter.cc \
src/core/ext/xds/xds_http_filters.cc \
src/core/ext/xds/xds_http_rbac_filter.cc \
src/core/ext/xds/xds_lb_policy_registry.cc \
src/core/ext/xds/xds_listener.cc \
src/core/ext/xds/xds_resource_type.cc \
src/core/ext/xds/xds_route_config.cc \
@ -1221,6 +1224,8 @@ if test "$PHP_GRPC" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/service/discovery/v3)
PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/service/load_stats/v3)

8
config.w32 generated

@ -174,6 +174,8 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\http\\rbac\\v3\\rbac.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\http\\router\\v3\\router.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network\\http_connection_manager\\v3\\http_connection_manager.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies\\ring_hash\\v3\\ring_hash.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies\\wrr_locality\\v3\\wrr_locality.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\cert.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\common.upb.c " +
"src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\secret.upb.c " +
@ -399,6 +401,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\xds\\xds_http_fault_filter.cc " +
"src\\core\\ext\\xds\\xds_http_filters.cc " +
"src\\core\\ext\\xds\\xds_http_rbac_filter.cc " +
"src\\core\\ext\\xds\\xds_lb_policy_registry.cc " +
"src\\core\\ext\\xds\\xds_listener.cc " +
"src\\core\\ext\\xds\\xds_resource_type.cc " +
"src\\core\\ext\\xds\\xds_route_config.cc " +
@ -1251,6 +1254,11 @@ if (PHP_GRPC != "no") {
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network\\http_connection_manager");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network\\http_connection_manager\\v3");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies\\ring_hash");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies\\ring_hash\\v3");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies\\wrr_locality");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\load_balancing_policies\\wrr_locality\\v3");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls");
FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls\\v3");

6
gRPC-C++.podspec generated

@ -411,6 +411,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h',
@ -639,6 +641,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_http_fault_filter.h',
'src/core/ext/xds/xds_http_filters.h',
'src/core/ext/xds/xds_http_rbac_filter.h',
'src/core/ext/xds/xds_lb_policy_registry.h',
'src/core/ext/xds/xds_listener.h',
'src/core/ext/xds/xds_resource_type.h',
'src/core/ext/xds/xds_resource_type_impl.h',
@ -1229,6 +1232,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h',
@ -1457,6 +1462,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_http_fault_filter.h',
'src/core/ext/xds/xds_http_filters.h',
'src/core/ext/xds/xds_http_rbac_filter.h',
'src/core/ext/xds/xds_lb_policy_registry.h',
'src/core/ext/xds/xds_listener.h',
'src/core/ext/xds/xds_resource_type.h',
'src/core/ext/xds/xds_resource_type_impl.h',

9
gRPC-Core.podspec generated

@ -519,6 +519,10 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c',
@ -972,6 +976,8 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_http_filters.h',
'src/core/ext/xds/xds_http_rbac_filter.cc',
'src/core/ext/xds/xds_http_rbac_filter.h',
'src/core/ext/xds/xds_lb_policy_registry.cc',
'src/core/ext/xds/xds_lb_policy_registry.h',
'src/core/ext/xds/xds_listener.cc',
'src/core/ext/xds/xds_listener.h',
'src/core/ext/xds/xds_resource_type.cc',
@ -1828,6 +1834,8 @@ Pod::Spec.new do |s|
'src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h',
@ -2056,6 +2064,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_http_fault_filter.h',
'src/core/ext/xds/xds_http_filters.h',
'src/core/ext/xds/xds_http_rbac_filter.h',
'src/core/ext/xds/xds_lb_policy_registry.h',
'src/core/ext/xds/xds_listener.h',
'src/core/ext/xds/xds_resource_type.h',
'src/core/ext/xds/xds_resource_type_impl.h',

6
grpc.gemspec generated

@ -432,6 +432,10 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h )
s.files += %w( src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c )
@ -885,6 +889,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/xds_http_filters.h )
s.files += %w( src/core/ext/xds/xds_http_rbac_filter.cc )
s.files += %w( src/core/ext/xds/xds_http_rbac_filter.h )
s.files += %w( src/core/ext/xds/xds_lb_policy_registry.cc )
s.files += %w( src/core/ext/xds/xds_lb_policy_registry.h )
s.files += %w( src/core/ext/xds/xds_listener.cc )
s.files += %w( src/core/ext/xds/xds_listener.h )
s.files += %w( src/core/ext/xds/xds_resource_type.cc )

3
grpc.gyp generated

@ -543,6 +543,8 @@
'src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c',
'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c',
@ -768,6 +770,7 @@
'src/core/ext/xds/xds_http_fault_filter.cc',
'src/core/ext/xds/xds_http_filters.cc',
'src/core/ext/xds/xds_http_rbac_filter.cc',
'src/core/ext/xds/xds_lb_policy_registry.cc',
'src/core/ext/xds/xds_listener.cc',
'src/core/ext/xds/xds_resource_type.cc',
'src/core/ext/xds/xds_route_config.cc',

6
package.xml generated

@ -414,6 +414,10 @@
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c" role="src" />
@ -867,6 +871,8 @@
<file baseinstalldir="/" name="src/core/ext/xds/xds_http_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_http_rbac_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_http_rbac_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_lb_policy_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_lb_policy_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_listener.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_listener.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_resource_type.cc" role="src" />

@ -0,0 +1,52 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg_internal.h"
#include "envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h"
#include "google/protobuf/wrappers.upb.h"
#include "udpa/annotations/status.upb.h"
#include "validate/validate.upb.h"
#include "upb/port_def.inc"
static const upb_MiniTable_Sub envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_submsgs[3] = {
{.submsg = &google_protobuf_UInt64Value_msginit},
{.submsg = &google_protobuf_UInt64Value_msginit},
{.submsg = &google_protobuf_UInt32Value_msginit},
};
static const upb_MiniTable_Field envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash__fields[5] = {
{1, UPB_SIZE(4, 4), UPB_SIZE(0, 0), kUpb_NoSub, 5, kUpb_FieldMode_Scalar | (kUpb_FieldRep_4Byte << kUpb_FieldRep_Shift)},
{2, UPB_SIZE(12, 16), UPB_SIZE(1, 1), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{3, UPB_SIZE(16, 24), UPB_SIZE(2, 2), 1, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
{4, UPB_SIZE(8, 8), UPB_SIZE(0, 0), kUpb_NoSub, 8, kUpb_FieldMode_Scalar | (kUpb_FieldRep_1Byte << kUpb_FieldRep_Shift)},
{5, UPB_SIZE(20, 32), UPB_SIZE(3, 3), 2, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
};
const upb_MiniTable envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit = {
&envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_submsgs[0],
&envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash__fields[0],
UPB_SIZE(24, 40), 5, kUpb_ExtMode_NonExtendable, 5, 255, 0,
};
static const upb_MiniTable *messages_layout[1] = {
&envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit,
};
const upb_MiniTable_File envoy_extensions_load_balancing_policies_ring_hash_v3_ring_hash_proto_upb_file_layout = {
messages_layout,
NULL,
NULL,
1,
0,
0,
};
#include "upb/port_undef.inc"

@ -0,0 +1,164 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef ENVOY_EXTENSIONS_LOAD_BALANCING_POLICIES_RING_HASH_V3_RING_HASH_PROTO_UPB_H_
#define ENVOY_EXTENSIONS_LOAD_BALANCING_POLICIES_RING_HASH_V3_RING_HASH_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 envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash;
typedef struct envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash;
extern const upb_MiniTable envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit;
struct google_protobuf_UInt32Value;
struct google_protobuf_UInt64Value;
extern const upb_MiniTable google_protobuf_UInt32Value_msginit;
extern const upb_MiniTable google_protobuf_UInt64Value_msginit;
typedef enum {
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_DEFAULT_HASH = 0,
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_XX_HASH = 1,
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_MURMUR_HASH_2 = 2
} envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_HashFunction;
/* envoy.extensions.load_balancing_policies.ring_hash.v3.RingHash */
UPB_INLINE envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_new(upb_Arena* arena) {
return (envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash*)_upb_Message_New(&envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit, arena);
}
UPB_INLINE envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_parse(const char* buf, size_t size, upb_Arena* arena) {
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* ret = envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* ret = envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_serialize(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit, 0, arena, len);
}
UPB_INLINE char* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_serialize_ex(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_msginit, options, arena, len);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_clear_hash_function(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
*UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = 0;
}
UPB_INLINE int32_t envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_hash_function(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t);
}
UPB_INLINE bool envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_has_minimum_ring_size(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return _upb_hasbit(msg, 1);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_clear_minimum_ring_size(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
*UPB_PTR_AT(msg, UPB_SIZE(12, 16), const upb_Message*) = NULL;
}
UPB_INLINE const struct google_protobuf_UInt64Value* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_minimum_ring_size(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(12, 16), const struct google_protobuf_UInt64Value*);
}
UPB_INLINE bool envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_has_maximum_ring_size(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return _upb_hasbit(msg, 2);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_clear_maximum_ring_size(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
*UPB_PTR_AT(msg, UPB_SIZE(16, 24), const upb_Message*) = NULL;
}
UPB_INLINE const struct google_protobuf_UInt64Value* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_maximum_ring_size(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(16, 24), const struct google_protobuf_UInt64Value*);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_clear_use_hostname_for_hashing(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = 0;
}
UPB_INLINE bool envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_use_hostname_for_hashing(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool);
}
UPB_INLINE bool envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_has_hash_balance_factor(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return _upb_hasbit(msg, 3);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_clear_hash_balance_factor(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
*UPB_PTR_AT(msg, UPB_SIZE(20, 32), const upb_Message*) = NULL;
}
UPB_INLINE const struct google_protobuf_UInt32Value* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_hash_balance_factor(const envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(20, 32), const struct google_protobuf_UInt32Value*);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_hash_function(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash *msg, int32_t value) {
*UPB_PTR_AT(msg, UPB_SIZE(4, 4), int32_t) = value;
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_minimum_ring_size(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash *msg, struct google_protobuf_UInt64Value* value) {
_upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(12, 16), struct google_protobuf_UInt64Value*) = value;
}
UPB_INLINE struct google_protobuf_UInt64Value* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_mutable_minimum_ring_size(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg, upb_Arena* arena) {
struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_minimum_ring_size(msg);
if (sub == NULL) {
sub = (struct google_protobuf_UInt64Value*)_upb_Message_New(&google_protobuf_UInt64Value_msginit, arena);
if (!sub) return NULL;
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_minimum_ring_size(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_maximum_ring_size(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash *msg, struct google_protobuf_UInt64Value* value) {
_upb_sethas(msg, 2);
*UPB_PTR_AT(msg, UPB_SIZE(16, 24), struct google_protobuf_UInt64Value*) = value;
}
UPB_INLINE struct google_protobuf_UInt64Value* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_mutable_maximum_ring_size(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg, upb_Arena* arena) {
struct google_protobuf_UInt64Value* sub = (struct google_protobuf_UInt64Value*)envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_maximum_ring_size(msg);
if (sub == NULL) {
sub = (struct google_protobuf_UInt64Value*)_upb_Message_New(&google_protobuf_UInt64Value_msginit, arena);
if (!sub) return NULL;
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_maximum_ring_size(msg, sub);
}
return sub;
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_use_hostname_for_hashing(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash *msg, bool value) {
*UPB_PTR_AT(msg, UPB_SIZE(8, 8), bool) = value;
}
UPB_INLINE void envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_hash_balance_factor(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash *msg, struct google_protobuf_UInt32Value* value) {
_upb_sethas(msg, 3);
*UPB_PTR_AT(msg, UPB_SIZE(20, 32), struct google_protobuf_UInt32Value*) = value;
}
UPB_INLINE struct google_protobuf_UInt32Value* envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_mutable_hash_balance_factor(envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash* msg, upb_Arena* arena) {
struct google_protobuf_UInt32Value* sub = (struct google_protobuf_UInt32Value*)envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_hash_balance_factor(msg);
if (sub == NULL) {
sub = (struct google_protobuf_UInt32Value*)_upb_Message_New(&google_protobuf_UInt32Value_msginit, arena);
if (!sub) return NULL;
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_set_hash_balance_factor(msg, sub);
}
return sub;
}
extern const upb_MiniTable_File envoy_extensions_load_balancing_policies_ring_hash_v3_ring_hash_proto_upb_file_layout;
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* ENVOY_EXTENSIONS_LOAD_BALANCING_POLICIES_RING_HASH_V3_RING_HASH_PROTO_UPB_H_ */

@ -0,0 +1,46 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#include <stddef.h>
#include "upb/msg_internal.h"
#include "envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h"
#include "envoy/config/cluster/v3/cluster.upb.h"
#include "udpa/annotations/status.upb.h"
#include "validate/validate.upb.h"
#include "upb/port_def.inc"
static const upb_MiniTable_Sub envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_submsgs[1] = {
{.submsg = &envoy_config_cluster_v3_LoadBalancingPolicy_msginit},
};
static const upb_MiniTable_Field envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality__fields[1] = {
{1, UPB_SIZE(4, 8), UPB_SIZE(1, 1), 0, 11, kUpb_FieldMode_Scalar | (kUpb_FieldRep_Pointer << kUpb_FieldRep_Shift)},
};
const upb_MiniTable envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit = {
&envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_submsgs[0],
&envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality__fields[0],
UPB_SIZE(8, 24), 1, kUpb_ExtMode_NonExtendable, 1, 255, 0,
};
static const upb_MiniTable *messages_layout[1] = {
&envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit,
};
const upb_MiniTable_File envoy_extensions_load_balancing_policies_wrr_locality_v3_wrr_locality_proto_upb_file_layout = {
messages_layout,
NULL,
NULL,
1,
0,
0,
};
#include "upb/port_undef.inc"

@ -0,0 +1,94 @@
/* This file was generated by upbc (the upb compiler) from the input
* file:
*
* envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.proto
*
* Do not edit -- your changes will be discarded when the file is
* regenerated. */
#ifndef ENVOY_EXTENSIONS_LOAD_BALANCING_POLICIES_WRR_LOCALITY_V3_WRR_LOCALITY_PROTO_UPB_H_
#define ENVOY_EXTENSIONS_LOAD_BALANCING_POLICIES_WRR_LOCALITY_V3_WRR_LOCALITY_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 envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality;
typedef struct envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality;
extern const upb_MiniTable envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit;
struct envoy_config_cluster_v3_LoadBalancingPolicy;
extern const upb_MiniTable envoy_config_cluster_v3_LoadBalancingPolicy_msginit;
/* envoy.extensions.load_balancing_policies.wrr_locality.v3.WrrLocality */
UPB_INLINE envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_new(upb_Arena* arena) {
return (envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality*)_upb_Message_New(&envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit, arena);
}
UPB_INLINE envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_parse(const char* buf, size_t size, upb_Arena* arena) {
envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* ret = envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit, NULL, 0, arena) != kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_parse_ex(const char* buf, size_t size,
const upb_ExtensionRegistry* extreg,
int options, upb_Arena* arena) {
envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* ret = envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_new(arena);
if (!ret) return NULL;
if (upb_Decode(buf, size, ret, &envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit, extreg, options, arena) !=
kUpb_DecodeStatus_Ok) {
return NULL;
}
return ret;
}
UPB_INLINE char* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_serialize(const envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* msg, upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit, 0, arena, len);
}
UPB_INLINE char* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_serialize_ex(const envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* msg, int options,
upb_Arena* arena, size_t* len) {
return upb_Encode(msg, &envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_msginit, options, arena, len);
}
UPB_INLINE bool envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_has_endpoint_picking_policy(const envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* msg) {
return _upb_hasbit(msg, 1);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_clear_endpoint_picking_policy(const envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* msg) {
*UPB_PTR_AT(msg, UPB_SIZE(4, 8), const upb_Message*) = NULL;
}
UPB_INLINE const struct envoy_config_cluster_v3_LoadBalancingPolicy* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_endpoint_picking_policy(const envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* msg) {
return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct envoy_config_cluster_v3_LoadBalancingPolicy*);
}
UPB_INLINE void envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_set_endpoint_picking_policy(envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality *msg, struct envoy_config_cluster_v3_LoadBalancingPolicy* value) {
_upb_sethas(msg, 1);
*UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct envoy_config_cluster_v3_LoadBalancingPolicy*) = value;
}
UPB_INLINE struct envoy_config_cluster_v3_LoadBalancingPolicy* envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_mutable_endpoint_picking_policy(envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality* msg, upb_Arena* arena) {
struct envoy_config_cluster_v3_LoadBalancingPolicy* sub = (struct envoy_config_cluster_v3_LoadBalancingPolicy*)envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_endpoint_picking_policy(msg);
if (sub == NULL) {
sub = (struct envoy_config_cluster_v3_LoadBalancingPolicy*)_upb_Message_New(&envoy_config_cluster_v3_LoadBalancingPolicy_msginit, arena);
if (!sub) return NULL;
envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_set_endpoint_picking_policy(msg, sub);
}
return sub;
}
extern const upb_MiniTable_File envoy_extensions_load_balancing_policies_wrr_locality_v3_wrr_locality_proto_upb_file_layout;
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port_undef.inc"
#endif /* ENVOY_EXTENSIONS_LOAD_BALANCING_POLICIES_WRR_LOCALITY_V3_WRR_LOCALITY_PROTO_UPB_H_ */

@ -30,7 +30,6 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/strip.h"
#include "envoy/extensions/transport_sockets/tls/v3/common.upb.h"
#include "envoy/extensions/transport_sockets/tls/v3/tls.upb.h"
#include "envoy/type/matcher/v3/regex.upb.h"
@ -376,24 +375,29 @@ grpc_error_handle CommonTlsContext::Parse(
&errors);
}
grpc_error_handle ExtractExtensionTypeName(const XdsEncodingContext& context,
const google_protobuf_Any* any,
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") {
absl::StatusOr<ExtractExtensionTypeNameResult> ExtractExtensionTypeName(
const XdsEncodingContext& context, const google_protobuf_Any* any) {
ExtractExtensionTypeNameResult result;
result.type = UpbStringToAbsl(google_protobuf_Any_type_url(any));
if (result.type == "type.googleapis.com/xds.type.v3.TypedStruct" ||
result.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(
result.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(
if (result.typed_struct == nullptr) {
return absl::InvalidArgumentError(
"could not parse TypedStruct from extension");
}
*extension_type =
UpbStringToAbsl(xds_type_v3_TypedStruct_type_url(typed_struct));
result.type =
UpbStringToAbsl(xds_type_v3_TypedStruct_type_url(result.typed_struct));
}
*extension_type = absl::StripPrefix(*extension_type, "type.googleapis.com/");
return GRPC_ERROR_NONE;
size_t pos = result.type.rfind('/');
if (pos == absl::string_view::npos || pos == result.type.size() - 1) {
return absl::InvalidArgumentError(
absl::StrCat("Invalid type_url ", result.type));
}
result.type = result.type.substr(pos + 1);
return result;
}
} // namespace grpc_core

@ -22,10 +22,12 @@
#include <string>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "envoy/extensions/transport_sockets/tls/v3/tls.upb.h"
#include "google/protobuf/any.upb.h"
#include "google/protobuf/duration.upb.h"
#include "xds/type/v3/typed_struct.upb.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/lib/gprpp/time.h"
@ -88,9 +90,13 @@ struct CommonTlsContext {
CommonTlsContext* common_tls_context);
};
grpc_error_handle ExtractExtensionTypeName(const XdsEncodingContext& context,
const google_protobuf_Any* any,
absl::string_view* extension_type);
struct ExtractExtensionTypeNameResult {
absl::string_view type;
xds_type_v3_TypedStruct* typed_struct = nullptr;
};
absl::StatusOr<ExtractExtensionTypeNameResult> ExtractExtensionTypeName(
const XdsEncodingContext& context, const google_protobuf_Any* any);
} // namespace grpc_core

@ -0,0 +1,291 @@
//
// 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_lb_policy_registry.h"
#include <stddef.h>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "envoy/config/core/v3/extension.upb.h"
#include "envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h"
#include "envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h"
#include "google/protobuf/any.upb.h"
#include "google/protobuf/struct.upb.h"
#include "google/protobuf/struct.upbdefs.h"
#include "google/protobuf/wrappers.upb.h"
#include "upb/json_encode.h"
#include "upb/upb.h"
#include "upb/upb.hpp"
#include "xds/type/v3/typed_struct.upb.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/lib/iomgr/error.h"
namespace grpc_core {
namespace {
class RingHashLbPolicyConfigFactory
: public XdsLbPolicyRegistry::ConfigFactory {
public:
absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context, absl::string_view configuration,
int /* recursion_depth */) override {
const auto* resource =
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_parse(
configuration.data(), configuration.size(), context.arena);
if (resource == nullptr) {
return absl::InvalidArgumentError(
"Can't decode RingHash loadbalancing policy");
}
if (envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_hash_function(
resource) !=
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_XX_HASH) {
return absl::InvalidArgumentError(
"Invalid hash function provided for RingHash loadbalancing policy. "
"Only XX_HASH is supported.");
}
Json::Object json;
const auto* min_ring_size =
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_minimum_ring_size(
resource);
if (min_ring_size != nullptr) {
json.emplace("minRingSize",
google_protobuf_UInt64Value_value(min_ring_size));
}
const auto* max_ring_size =
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_maximum_ring_size(
resource);
if (max_ring_size != nullptr) {
json.emplace("maxRingSize",
google_protobuf_UInt64Value_value(max_ring_size));
}
return Json::Object{{"ring_hash_experimental", std::move(json)}};
}
absl::string_view type() override { return Type(); }
static absl::string_view Type() {
return "envoy.extensions.load_balancing_policies.ring_hash.v3.RingHash";
}
};
class RoundRobinLbPolicyConfigFactory
: public XdsLbPolicyRegistry::ConfigFactory {
public:
absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& /* context */,
absl::string_view /* configuration */,
int /* recursion_depth */) override {
return Json::Object{{"round_robin", Json::Object()}};
}
absl::string_view type() override { return Type(); }
static absl::string_view Type() {
return "envoy.extensions.load_balancing_policies.round_robin.v3.RoundRobin";
}
};
class WrrLocalityLbPolicyConfigFactory
: public XdsLbPolicyRegistry::ConfigFactory {
public:
absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context, absl::string_view configuration,
int recursion_depth) override {
const auto* resource =
envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_parse(
configuration.data(), configuration.size(), context.arena);
if (resource == nullptr) {
return absl::InvalidArgumentError(
"Can't decode WrrLocality loadbalancing policy");
}
const auto* endpoint_picking_policy =
envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_endpoint_picking_policy(
resource);
if (endpoint_picking_policy == nullptr) {
return absl::InvalidArgumentError(
"WrrLocality: endpoint_picking_policy not found");
}
auto child_policy = XdsLbPolicyRegistry::ConvertXdsLbPolicyConfig(
context, endpoint_picking_policy, recursion_depth + 1);
if (!child_policy.ok()) {
return absl::InvalidArgumentError(
absl::StrCat("Error parsing WrrLocality load balancing policy: ",
child_policy.status().message()));
}
return Json::Object{
{"xds_wrr_locality_experimental",
Json::Object{{"child_policy", *std::move(child_policy)}}}};
}
absl::string_view type() override { return Type(); }
static absl::string_view Type() {
return "envoy.extensions.load_balancing_policies.wrr_locality.v3."
"WrrLocality";
}
};
absl::StatusOr<Json> ParseStructToJson(const XdsEncodingContext& context,
const google_protobuf_Struct* resource) {
upb::Status status;
const auto* msg_def = google_protobuf_Struct_getmsgdef(context.symtab);
size_t json_size = upb_JsonEncode(resource, msg_def, context.symtab, 0,
nullptr, 0, status.ptr());
if (json_size == static_cast<size_t>(-1)) {
return absl::InvalidArgumentError(
absl::StrCat("Error parsing google::Protobuf::Struct: ",
upb_Status_ErrorMessage(status.ptr())));
}
void* buf = upb_Arena_Malloc(context.arena, json_size + 1);
upb_JsonEncode(resource, msg_def, context.symtab, 0,
reinterpret_cast<char*>(buf), json_size + 1, status.ptr());
grpc_error_handle error = GRPC_ERROR_NONE;
auto json = Json::Parse(reinterpret_cast<char*>(buf), &error);
if (error != GRPC_ERROR_NONE) {
// This should not happen
auto ret_status = absl::InternalError(
absl::StrCat("Error parsing JSON form of google::Protobuf::Struct "
"produced by upb library: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return ret_status;
}
return json;
}
} // namespace
//
// XdsLbPolicyRegistry
//
absl::StatusOr<Json::Array> XdsLbPolicyRegistry::ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context,
const envoy_config_cluster_v3_LoadBalancingPolicy* lb_policy,
int recursion_depth) {
constexpr int kMaxRecursionDepth = 16;
if (recursion_depth >= kMaxRecursionDepth) {
return absl::InvalidArgumentError(
absl::StrFormat("LoadBalancingPolicy configuration has a recursion "
"depth of more than %d.",
kMaxRecursionDepth));
}
size_t size = 0;
const auto* policies =
envoy_config_cluster_v3_LoadBalancingPolicy_policies(lb_policy, &size);
for (size_t i = 0; i < size; ++i) {
absl::StatusOr<Json::Object> policy;
const auto* typed_extension_config =
envoy_config_cluster_v3_LoadBalancingPolicy_Policy_typed_extension_config(
policies[i]);
if (typed_extension_config == nullptr) {
return absl::InvalidArgumentError(
"Error parsing LoadBalancingPolicy::Policy - Missing "
"typed_extension_config field");
}
const auto* typed_config =
envoy_config_core_v3_TypedExtensionConfig_typed_config(
typed_extension_config);
if (typed_config == nullptr) {
return absl::InvalidArgumentError(
"Error parsing LoadBalancingPolicy::Policy - Missing "
"TypedExtensionConfig::typed_config field");
}
auto type = ExtractExtensionTypeName(context, typed_config);
if (!type.ok()) {
return absl::InvalidArgumentError(absl::StrCat(
"Error parsing "
"LoadBalancingPolicy::Policy::TypedExtensionConfig::typed_config: ",
type.status().message()));
}
absl::string_view value =
UpbStringToAbsl(google_protobuf_Any_value(typed_config));
auto config_factory_it = Get()->policy_config_factories_.find(type->type);
if (config_factory_it != Get()->policy_config_factories_.end()) {
policy = config_factory_it->second->ConvertXdsLbPolicyConfig(
context, value, recursion_depth);
if (!policy.ok()) {
return absl::InvalidArgumentError(
absl::StrCat("Error parsing "
"LoadBalancingPolicy::Policy::TypedExtensionConfig::"
"typed_config to JSON: ",
policy.status().message()));
}
} else if (type->typed_struct != nullptr) {
// Custom lb policy config
std::string custom_type = std::string(type->type);
if (!LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
custom_type.c_str(), nullptr)) {
// Skip unsupported custom lb policy.
continue;
}
// Convert typed struct to json.
auto value = xds_type_v3_TypedStruct_value(type->typed_struct);
if (value == nullptr) {
policy = Json::Object{{std::move(custom_type), Json() /* null */}};
} else {
auto parsed_value = ParseStructToJson(context, value);
if (!parsed_value.ok()) {
return absl::InvalidArgumentError(absl::StrCat(
"Error parsing LoadBalancingPolicy: Custom Policy: ", custom_type,
": ", parsed_value.status().message()));
}
policy =
Json::Object{{std::move(custom_type), *(std::move(parsed_value))}};
}
} else {
// Unsupported type. Skipping entry.
continue;
}
return Json::Array{std::move(policy.value())};
}
return absl::InvalidArgumentError(
"No supported load balancing policy config found.");
}
XdsLbPolicyRegistry::XdsLbPolicyRegistry() {
policy_config_factories_.emplace(
RingHashLbPolicyConfigFactory::Type(),
absl::make_unique<RingHashLbPolicyConfigFactory>());
policy_config_factories_.emplace(
RoundRobinLbPolicyConfigFactory::Type(),
absl::make_unique<RoundRobinLbPolicyConfigFactory>());
policy_config_factories_.emplace(
WrrLocalityLbPolicyConfigFactory::Type(),
absl::make_unique<WrrLocalityLbPolicyConfigFactory>());
}
XdsLbPolicyRegistry* XdsLbPolicyRegistry::Get() {
// This is thread-safe since C++11
static XdsLbPolicyRegistry* instance = new XdsLbPolicyRegistry();
return instance;
}
} // namespace grpc_core

@ -0,0 +1,72 @@
//
// 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_LB_POLICY_REGISTRY_H
#define GRPC_CORE_EXT_XDS_XDS_LB_POLICY_REGISTRY_H
#include <grpc/support/port_platform.h>
#include <map>
#include <memory>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "envoy/config/cluster/v3/cluster.upb.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/lib/json/json.h"
namespace grpc_core {
// A registry that maintans a set of converters that are able to map xDS
// loadbalancing policy configurations to gRPC's JSON format.
class XdsLbPolicyRegistry {
public:
class ConfigFactory {
public:
virtual ~ConfigFactory() {}
virtual absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context, absl::string_view configuration,
int recursion_depth) = 0;
virtual absl::string_view type() = 0;
};
// Converts an xDS cluster load balancing policy message to gRPC's JSON
// format. An error is returned if none of the lb policies in the list are
// supported, or if a supported lb policy configuration conversion fails. \a
// recursion_depth indicates the current depth of the tree if lb_policy
// configuration recursively holds other lb policies.
static absl::StatusOr<Json::Array> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context,
const envoy_config_cluster_v3_LoadBalancingPolicy* lb_policy,
int recursion_depth = 0);
private:
XdsLbPolicyRegistry();
static XdsLbPolicyRegistry* Get();
// A map of config factories that goes from the type of the lb policy config
// to the config factory.
std::map<absl::string_view /* Owned by ConfigFactory */,
std::unique_ptr<ConfigFactory>>
policy_config_factories_;
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_XDS_XDS_LB_POLICY_REGISTRY_H

@ -60,6 +60,7 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -350,30 +351,30 @@ grpc_error_handle HttpConnectionManagerParse(
return GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("no filter config specified for filter name ", name));
}
absl::string_view filter_type;
grpc_error_handle error =
ExtractExtensionTypeName(context, any, &filter_type);
if (error != GRPC_ERROR_NONE) return error;
auto filter_type = ExtractExtensionTypeName(context, any);
if (!filter_type.ok()) {
return absl_status_to_grpc_error(filter_type.status());
}
const XdsHttpFilterImpl* filter_impl =
XdsHttpFilterRegistry::GetFilterForType(filter_type);
XdsHttpFilterRegistry::GetFilterForType(filter_type->type);
if (filter_impl == nullptr) {
if (is_optional) continue;
return GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("no filter registered for config type ", filter_type));
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"no filter registered for config type ", filter_type->type));
}
if ((is_client && !filter_impl->IsSupportedOnClients()) ||
(!is_client && !filter_impl->IsSupportedOnServers())) {
if (is_optional) continue;
return GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrFormat("Filter %s is not supported on %s", filter_type,
is_client ? "clients" : "servers"));
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrFormat(
"Filter %s is not supported on %s", filter_type->type,
is_client ? "clients" : "servers"));
}
absl::StatusOr<XdsHttpFilterImpl::FilterConfig> filter_config =
filter_impl->GenerateFilterConfig(google_protobuf_Any_value(any),
context.arena);
if (!filter_config.ok()) {
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"filter config for type ", filter_type,
"filter config for type ", filter_type->type,
" failed to parse: ", StatusToString(filter_config.status())));
}
http_connection_manager->http_filters.emplace_back(

@ -364,19 +364,19 @@ grpc_error_handle ClusterSpecifierPluginParse(
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;
auto plugin_type = ExtractExtensionTypeName(context, any);
if (!plugin_type.ok()) {
return absl_status_to_grpc_error(plugin_type.status());
}
bool is_optional = envoy_config_route_v3_ClusterSpecifierPlugin_is_optional(
cluster_specifier_plugin[i]);
const XdsClusterSpecifierPluginImpl* cluster_specifier_plugin_impl =
XdsClusterSpecifierPluginRegistry::GetPluginForType(plugin_type);
XdsClusterSpecifierPluginRegistry::GetPluginForType(plugin_type->type);
std::string lb_policy_config;
if (cluster_specifier_plugin_impl == nullptr) {
if (!is_optional) {
return GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("Unknown ClusterSpecifierPlugin type ", plugin_type));
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"Unknown ClusterSpecifierPlugin type ", plugin_type->type));
}
// Optional plugin, leave lb_policy_config empty.
} else {
@ -629,22 +629,23 @@ grpc_error_handle ParseTypedPerFilterConfig(
absl::StrCat("no filter config specified for filter name ", key));
}
}
grpc_error_handle error =
ExtractExtensionTypeName(context, any, &filter_type);
if (error != GRPC_ERROR_NONE) return error;
auto type = ExtractExtensionTypeName(context, any);
if (!type.ok()) {
return absl_status_to_grpc_error(type.status());
}
const XdsHttpFilterImpl* filter_impl =
XdsHttpFilterRegistry::GetFilterForType(filter_type);
XdsHttpFilterRegistry::GetFilterForType(type->type);
if (filter_impl == nullptr) {
if (is_optional) continue;
return GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("no filter registered for config type ", filter_type));
absl::StrCat("no filter registered for config type ", type->type));
}
absl::StatusOr<XdsHttpFilterImpl::FilterConfig> filter_config =
filter_impl->GenerateFilterConfigOverride(
google_protobuf_Any_value(any), context.arena);
if (!filter_config.ok()) {
return GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"filter config for type ", filter_type,
"filter config for type ", type->type,
" failed to parse: ", StatusToString(filter_config.status())));
}
(*typed_per_filter_config)[std::string(key)] = std::move(*filter_config);

@ -92,6 +92,7 @@ grpc_proto_library(
"base_proto",
"config_source_proto",
"endpoint_proto",
"extension_proto",
"outlier_detection_proto",
],
)
@ -375,6 +376,49 @@ grpc_proto_library(
],
)
grpc_proto_library(
name = "ring_hash_proto",
srcs = [
"ring_hash.proto",
],
well_known_protos = True,
)
grpc_proto_library(
name = "round_robin_proto",
srcs = [
"round_robin.proto",
],
well_known_protos = True,
)
grpc_proto_library(
name = "wrr_locality_proto",
srcs = [
"wrr_locality.proto",
],
well_known_protos = True,
deps = [
"cluster_proto",
],
)
grpc_proto_library(
name = "typed_struct_proto",
srcs = [
"typed_struct.proto",
],
well_known_protos = True,
)
grpc_proto_library(
name = "udpa_typed_struct_proto",
srcs = [
"udpa_typed_struct.proto",
],
well_known_protos = True,
)
py_proto_library(
name = "csds_py_pb2",
deps = [":_csds_proto_only"],

@ -21,6 +21,7 @@ package envoy.config.cluster.v3;
import "src/proto/grpc/testing/xds/v3/base.proto";
import "src/proto/grpc/testing/xds/v3/config_source.proto";
import "src/proto/grpc/testing/xds/v3/endpoint.proto";
import "src/proto/grpc/testing/xds/v3/extension.proto";
import "src/proto/grpc/testing/xds/v3/outlier_detection.proto";
import "google/protobuf/any.proto";
@ -224,6 +225,10 @@ message Cluster {
// will be set up with plaintext.
core.v3.TransportSocket transport_socket = 24;
// If this field is set and is supported by the client, it will supersede the value of
// :ref:`lb_policy<envoy_v3_api_field_config.cluster.v3.Cluster.lb_policy>`.
LoadBalancingPolicy load_balancing_policy = 41;
// [#not-implemented-hide:]
// If present, tells the client where to send load reports via LRS. If not present, the
// client will fall back to a client-side default, which may be either (a) don't send any
@ -240,3 +245,37 @@ message Cluster {
// from the LRS stream here.]
core.v3.ConfigSource lrs_server = 42;
}
// Extensible load balancing policy configuration.
//
// Every LB policy defined via this mechanism will be identified via a unique name using reverse
// DNS notation. If the policy needs configuration parameters, it must define a message for its
// own configuration, which will be stored in the config field. The name of the policy will tell
// clients which type of message they should expect to see in the config field.
//
// Note that there are cases where it is useful to be able to independently select LB policies
// for choosing a locality and for choosing an endpoint within that locality. For example, a
// given deployment may always use the same policy to choose the locality, but for choosing the
// endpoint within the locality, some clusters may use weighted-round-robin, while others may
// use some sort of session-based balancing.
//
// This can be accomplished via hierarchical LB policies, where the parent LB policy creates a
// child LB policy for each locality. For each request, the parent chooses the locality and then
// delegates to the child policy for that locality to choose the endpoint within the locality.
//
// To facilitate this, the config message for the top-level LB policy may include a field of
// type LoadBalancingPolicy that specifies the child policy.
message LoadBalancingPolicy {
message Policy {
reserved 2, 1, 3;
reserved "config", "name", "typed_config";
core.v3.TypedExtensionConfig typed_extension_config = 4;
}
// Each client will iterate over the list in order and stop at the first policy that it
// supports. This provides a mechanism for starting to use new LB policies that are not yet
// supported by all clients.
repeated Policy policies = 1;
}

@ -0,0 +1,59 @@
// 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 copy of Envoy xDS proto file, used for testing only.
syntax = "proto3";
package envoy.extensions.load_balancing_policies.ring_hash.v3;
import "google/protobuf/wrappers.proto";
// [#protodoc-title: Ring Hash Load Balancing Policy]
// This configuration allows the built-in RING_HASH LB policy to be configured via the LB policy
// extension point. See the :ref:`load balancing architecture overview
// <arch_overview_load_balancing_types>` for more information.
// [#extension: envoy.clusters.lb_policy]
// [#next-free-field: 6]
message RingHash {
// The hash function used to hash hosts onto the ketama ring.
enum HashFunction {
// Currently defaults to XX_HASH.
DEFAULT_HASH = 0;
// Use `xxHash <https://github.com/Cyan4973/xxHash>`_.
XX_HASH = 1;
// Use `MurmurHash2 <https://sites.google.com/site/murmurhash/>`_, this is compatible with
// std:hash<string> in GNU libstdc++ 3.4.20 or above. This is typically the case when compiled
// on Linux and not macOS.
MURMUR_HASH_2 = 2;
}
// The hash function used to hash hosts onto the ketama ring. The value defaults to
// :ref:`XX_HASH<envoy_v3_api_enum_value_config.cluster.v3.Cluster.RingHashLbConfig.HashFunction.XX_HASH>`.
HashFunction hash_function = 1;
// Minimum hash ring size. The larger the ring is (that is, the more hashes there are for each
// provided host) the better the request distribution will reflect the desired weights. Defaults
// to 1024 entries, and limited to 8M entries. See also
// :ref:`maximum_ring_size<envoy_v3_api_field_config.cluster.v3.Cluster.RingHashLbConfig.maximum_ring_size>`.
google.protobuf.UInt64Value minimum_ring_size = 2;
// Maximum hash ring size. Defaults to 8M entries, and limited to 8M entries, but can be lowered
// to further constrain resource use. See also
// :ref:`minimum_ring_size<envoy_v3_api_field_config.cluster.v3.Cluster.RingHashLbConfig.minimum_ring_size>`.
google.protobuf.UInt64Value maximum_ring_size = 3;
}

@ -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.
// Local copy of Envoy xDS proto file, used for testing only.
syntax = "proto3";
package envoy.extensions.load_balancing_policies.round_robin.v3;
// [#protodoc-title: Round Robin Load Balancing Policy]
// This configuration allows the built-in ROUND_ROBIN LB policy to be configured via the LB policy
// extension point. See the :ref:`load balancing architecture overview
// <arch_overview_load_balancing_types>` for more information.
// [#extension: envoy.clusters.lb_policy]
message RoundRobin {
}

@ -0,0 +1,53 @@
// 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 copy of xDS proto file, used for testing only.
syntax = "proto3";
package xds.type.v3;
import "google/protobuf/struct.proto";
// A TypedStruct contains an arbitrary JSON serialized protocol buffer message with a URL that
// describes the type of the serialized message. This is very similar to google.protobuf.Any,
// instead of having protocol buffer binary, this employs google.protobuf.Struct as value.
//
// This message is intended to be embedded inside Any, so it shouldn't be directly referred
// from other UDPA messages.
//
// When packing an opaque extension config, packing the expected type into Any is preferred
// wherever possible for its efficiency. TypedStruct should be used only if a proto descriptor
// is not available, for example if:
// - A control plane sends opaque message that is originally from external source in human readable
// format such as JSON or YAML.
// - The control plane doesn't have the knowledge of the protocol buffer schema hence it cannot
// serialize the message in protocol buffer binary format.
// - The DPLB doesn't have have the knowledge of the protocol buffer schema its plugin or extension
// uses. This has to be indicated in the DPLB capability negotiation.
//
// When a DPLB receives a TypedStruct in Any, it should:
// - Check if the type_url of the TypedStruct matches the type the extension expects.
// - Convert value to the type described in type_url and perform validation.
// TODO(lizan): Figure out how TypeStruct should be used with DPLB extensions that doesn't link
// protobuf descriptor with DPLB itself, (e.g. gRPC LB Plugin, Envoy WASM extensions).
message TypedStruct {
// A URL that uniquely identifies the type of the serialize protocol buffer message.
// This has same semantics and format described in google.protobuf.Any:
// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto
string type_url = 1;
// A JSON representation of the above specified type.
google.protobuf.Struct value = 2;
}

@ -0,0 +1,53 @@
// 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 copy of xDS proto file, used for testing only.
syntax = "proto3";
package udpa.type.v1;
import "google/protobuf/struct.proto";
// A TypedStruct contains an arbitrary JSON serialized protocol buffer message with a URL that
// describes the type of the serialized message. This is very similar to google.protobuf.Any,
// instead of having protocol buffer binary, this employs google.protobuf.Struct as value.
//
// This message is intended to be embedded inside Any, so it shouldn't be directly referred
// from other UDPA messages.
//
// When packing an opaque extension config, packing the expected type into Any is preferred
// wherever possible for its efficiency. TypedStruct should be used only if a proto descriptor
// is not available, for example if:
// - A control plane sends opaque message that is originally from external source in human readable
// format such as JSON or YAML.
// - The control plane doesn't have the knowledge of the protocol buffer schema hence it cannot
// serialize the message in protocol buffer binary format.
// - The DPLB doesn't have have the knowledge of the protocol buffer schema its plugin or extension
// uses. This has to be indicated in the DPLB capability negotiation.
//
// When a DPLB receives a TypedStruct in Any, it should:
// - Check if the type_url of the TypedStruct matches the type the extension expects.
// - Convert value to the type described in type_url and perform validation.
// TODO(lizan): Figure out how TypeStruct should be used with DPLB extensions that doesn't link
// protobuf descriptor with DPLB itself, (e.g. gRPC LB Plugin, Envoy WASM extensions).
message TypedStruct {
// A URL that uniquely identifies the type of the serialize protocol buffer message.
// This has same semantics and format described in google.protobuf.Any:
// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto
string type_url = 1;
// A JSON representation of the above specified type.
google.protobuf.Struct value = 2;
}

@ -0,0 +1,31 @@
// 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 copy of Envoy xDS proto file, used for testing only.
syntax = "proto3";
package envoy.extensions.load_balancing_policies.wrr_locality.v3;
import "src/proto/grpc/testing/xds/v3/cluster.proto";
// [#protodoc-title: Weighted Round Robin Locality-Picking Load Balancing Policy]
// Configuration for the wrr_locality LB policy. See the :ref:`load balancing architecture overview
// <arch_overview_load_balancing_types>` for more information.
// [#extension: envoy.clusters.lb_policy]
message WrrLocality {
// The child LB policy to create for endpoint-picking within the chosen locality.
config.cluster.v3.LoadBalancingPolicy endpoint_picking_policy = 1;
}

@ -183,6 +183,8 @@ CORE_SOURCE_FILES = [
'src/core/ext/upb-generated/envoy/extensions/filters/http/rbac/v3/rbac.upb.c',
'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c',
'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c',
'src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c',
'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c',
@ -408,6 +410,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/xds/xds_http_fault_filter.cc',
'src/core/ext/xds/xds_http_filters.cc',
'src/core/ext/xds/xds_http_rbac_filter.cc',
'src/core/ext/xds/xds_lb_policy_registry.cc',
'src/core/ext/xds/xds_listener.cc',
'src/core/ext/xds/xds_resource_type.cc',
'src/core/ext/xds/xds_route_config.cc',

@ -97,3 +97,23 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "xds_lb_policy_registry_test",
srcs = ["xds_lb_policy_registry_test.cc"],
external_deps = ["gtest"],
language = "C++",
uses_polling = False,
deps = [
"//:gpr",
"//:grpc",
"//src/proto/grpc/testing/xds/v3:cluster_proto",
"//src/proto/grpc/testing/xds/v3:ring_hash_proto",
"//src/proto/grpc/testing/xds/v3:round_robin_proto",
"//src/proto/grpc/testing/xds/v3:typed_struct_proto",
"//src/proto/grpc/testing/xds/v3:udpa_typed_struct_proto",
"//src/proto/grpc/testing/xds/v3:wrr_locality_proto",
"//test/core/util:grpc_test_util",
"//test/cpp/util:grpc_cli_utils",
],
)

@ -0,0 +1,534 @@
//
//
// 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 "src/core/ext/xds/xds_lb_policy_registry.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/strings/str_format.h"
#include "upb/def.hpp"
#include "upb/upb.h"
#include "upb/upb.hpp"
#include <grpc/grpc.h>
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/proto/grpc/testing/xds/v3/cluster.grpc.pb.h"
#include "src/proto/grpc/testing/xds/v3/ring_hash.grpc.pb.h"
#include "src/proto/grpc/testing/xds/v3/round_robin.grpc.pb.h"
#include "src/proto/grpc/testing/xds/v3/typed_struct.grpc.pb.h"
#include "src/proto/grpc/testing/xds/v3/udpa_typed_struct.grpc.pb.h"
#include "src/proto/grpc/testing/xds/v3/wrr_locality.grpc.pb.h"
#include "test/core/util/test_config.h"
#include "test/cpp/util/config_grpc_cli.h"
namespace grpc_core {
namespace testing {
namespace {
using LoadBalancingPolicyProto =
::envoy::config::cluster::v3::LoadBalancingPolicy;
using ::envoy::extensions::load_balancing_policies::ring_hash::v3::RingHash;
using ::envoy::extensions::load_balancing_policies::round_robin::v3::RoundRobin;
using ::envoy::extensions::load_balancing_policies::wrr_locality::v3::
WrrLocality;
using ::xds::type::v3::TypedStruct;
// Uses XdsLbPolicyRegistry to convert
// envoy::config::cluster::v3::LoadBalancingPolicy to gRPC's JSON form.
absl::StatusOr<Json::Array> ConvertXdsPolicy(LoadBalancingPolicyProto policy) {
std::string serialized_policy = policy.SerializeAsString();
upb::Arena arena;
upb::SymbolTable symtab;
XdsEncodingContext context = {nullptr, XdsBootstrap::XdsServer(),
nullptr, symtab.ptr(),
arena.ptr(), true,
nullptr};
auto* upb_policy = envoy_config_cluster_v3_LoadBalancingPolicy_parse(
serialized_policy.data(), serialized_policy.size(), arena.ptr());
return XdsLbPolicyRegistry::ConvertXdsLbPolicyConfig(context, upb_policy);
}
TEST(XdsLbPolicyRegistryTest, EmptyLoadBalancingPolicy) {
auto result = ConvertXdsPolicy(LoadBalancingPolicyProto());
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("No supported load balancing policy config found"));
}
TEST(XdsLbPolicyRegistryTest, UnsupportedBuiltinType) {
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
LoadBalancingPolicyProto());
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("No supported load balancing policy config found"));
}
TEST(XdsLbPolicyRegistryTest, MissingTypedExtensionConfig) {
LoadBalancingPolicyProto policy;
policy.add_policies();
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(result.status().message()),
::testing::HasSubstr("Error parsing LoadBalancingPolicy::Policy "
"- Missing typed_extension_config field"));
}
TEST(XdsLbPolicyRegistryTest, MissingTypedConfig) {
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config();
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("Error parsing LoadBalancingPolicy::Policy - "
"Missing TypedExtensionConfig::typed_config field"));
}
TEST(XdsLbPolicyRegistryTest, RingHashInvalidHash) {
RingHash ring_hash;
ring_hash.set_hash_function(RingHash::DEFAULT_HASH);
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
ring_hash);
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("Invalid hash function provided for RingHash "
"loadbalancing policy. Only XX_HASH is supported"));
}
TEST(XdsLbPolicyRegistryTest, RingHashRingSizeDefaults) {
RingHash ring_hash;
ring_hash.set_hash_function(RingHash::XX_HASH);
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
ring_hash);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"ring_hash_experimental\": {"
"}}",
&error));
}
TEST(XdsLbPolicyRegistryTest, RingHashRingSizeCustom) {
RingHash ring_hash;
ring_hash.set_hash_function(RingHash::XX_HASH);
ring_hash.mutable_minimum_ring_size()->set_value(1234);
ring_hash.mutable_maximum_ring_size()->set_value(4567);
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
ring_hash);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"ring_hash_experimental\": {"
" \"minRingSize\": 1234,"
" \"maxRingSize\": 4567"
"}}",
&error));
}
TEST(XdsLbPolicyRegistryTest, RoundRobin) {
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
RoundRobin());
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"round_robin\": {}"
"}",
&error));
}
TEST(XdsLbPolicyRegistryTest, WrrLocality) {
WrrLocality wrr_locality;
wrr_locality.mutable_endpoint_picking_policy()
->add_policies()
->mutable_typed_extension_config()
->mutable_typed_config()
->PackFrom(RoundRobin());
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
wrr_locality);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"xds_wrr_locality_experimental\": {"
" \"child_policy\": [{"
" \"round_robin\": {}"
" }]"
"}}",
&error));
}
TEST(XdsLbPolicyRegistryTest, WrrLocalityMissingEndpointPickingPolicy) {
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
WrrLocality());
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(result.status().message()),
::testing::ContainsRegex(
"Error parsing LoadBalancingPolicy.*WrrLocality: "
"endpoint_picking_policy not found"));
}
TEST(XdsLbPolicyRegistryTest, WrrLocalityChildPolicyError) {
WrrLocality wrr_locality;
wrr_locality.mutable_endpoint_picking_policy()
->add_policies()
->mutable_typed_extension_config()
->mutable_typed_config()
->PackFrom(RingHash());
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
wrr_locality);
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(result.status().message()),
::testing::ContainsRegex(
"Error parsing LoadBalancingPolicy.*Error parsing "
"WrrLocality load balancing policy.*Error parsing "
"LoadBalancingPolicy.*Invalid hash function provided for "
"RingHash loadbalancing policy. Only XX_HASH is supported."));
}
TEST(XdsLbPolicyRegistryTest, WrrLocalityUnsupportedTypeSkipped) {
// Create WrrLocality policy and add two policies to its list, an unsupported
// type and then a known RoundRobin type. Expect that the unsupported type is
// skipped and RoundRobin is selected.
WrrLocality wrr_locality;
wrr_locality.mutable_endpoint_picking_policy()
->add_policies()
->mutable_typed_extension_config()
->mutable_typed_config()
->PackFrom(LoadBalancingPolicyProto());
wrr_locality.mutable_endpoint_picking_policy()
->add_policies()
->mutable_typed_extension_config()
->mutable_typed_config()
->PackFrom(RoundRobin());
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
wrr_locality);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"xds_wrr_locality_experimental\": {"
" \"child_policy\": [{"
" \"round_robin\": {}"
" }]"
"}}",
&error));
}
class CustomLbPolicyFactory : public LoadBalancingPolicyFactory {
public:
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
LoadBalancingPolicy::Args /* args */) const override {
GPR_ASSERT(false);
return nullptr;
}
const char* name() const override { return "test.CustomLb"; }
RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
const Json& /* json */, grpc_error_handle* /* error */) const override {
return nullptr;
}
};
TEST(XdsLbPolicyRegistryTest, CustomLbPolicy) {
TypedStruct typed_struct;
typed_struct.set_type_url("type.googleapis.com/test.CustomLb");
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"test.CustomLb\": null}",
&error));
}
TEST(XdsLbPolicyRegistryTest, CustomLbPolicyUdpaTyped) {
::udpa::type::v1::TypedStruct typed_struct;
typed_struct.set_type_url("type.googleapis.com/test.CustomLb");
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"test.CustomLb\": null}",
&error));
}
TEST(XdsLbPolicyRegistryTest, UnsupportedCustomTypeError) {
TypedStruct typed_struct;
typed_struct.set_type_url("myorg/foo/bar/test.UnknownLb");
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("No supported load balancing policy config found"));
}
TEST(XdsLbPolicyRegistryTest, CustomTypeInvalidUrlMissingSlash) {
TypedStruct typed_struct;
typed_struct.set_type_url("test.UnknownLb");
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("Error parsing "
"LoadBalancingPolicy::Policy::TypedExtensionConfig::"
"typed_config: Invalid type_url test.UnknownLb"));
}
TEST(XdsLbPolicyRegistryTest, CustomTypeInvalidUrlEmptyType) {
TypedStruct typed_struct;
typed_struct.set_type_url("myorg/");
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(result.status().message()),
::testing::HasSubstr("Error parsing "
"LoadBalancingPolicy::Policy::TypedExtensionConfig::"
"typed_config: Invalid type_url myorg/"));
}
TEST(XdsLbPolicyRegistryTest, CustomLbPolicyJsonConversion) {
TypedStruct typed_struct;
ASSERT_TRUE(grpc::protobuf::TextFormat::ParseFromString(
R"pb(
type_url: "type.googleapis.com/test.CustomLb"
value {
fields {
key: "key"
value { null_value: NULL_VALUE }
}
fields {
key: "number"
value { number_value: 123 }
}
fields {
key: "string"
value { string_value: "value" }
}
fields {
key: "struct"
value {
struct_value {
fields {
key: "key"
value { null_value: NULL_VALUE }
}
}
}
}
fields {
key: "list"
value {
list_value {
values { null_value: NULL_VALUE }
values { number_value: 234 }
}
}
}
}
)pb",
&typed_struct));
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse(
R"json({
"test.CustomLb":{
"key": null,
"number": 123,
"string": "value",
"struct": {
"key": null
},
"list": [null, 234]
}
})json",
&error));
}
TEST(XdsLbPolicyRegistryTest, CustomLbPolicyListError) {
TypedStruct typed_struct;
typed_struct.set_type_url("type.googleapis.com/test.CustomLb");
auto* fields = typed_struct.mutable_value()->mutable_fields();
google::protobuf::Value value;
value.mutable_list_value()->add_values();
(*fields)["key"] = value;
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
auto result = ConvertXdsPolicy(policy);
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(result.status().message()),
::testing::HasSubstr(
"Error parsing LoadBalancingPolicy: Custom Policy: "
"test.CustomLb: Error parsing google::Protobuf::Struct: No "
"value set in Value proto"));
}
TEST(XdsLbPolicyRegistryTest, UnsupportedBuiltInTypeSkipped) {
// Add two policies to list, an unsupported type and then a known RoundRobin
// type. Expect that the unsupported type is skipped and RoundRobin is
// selected.
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
LoadBalancingPolicyProto());
lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
RoundRobin());
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"round_robin\": {}"
"}",
&error));
}
TEST(XdsLbPolicyRegistryTest, UnsupportedCustomTypeSkipped) {
// Add two policies to list, an unsupported custom type and then a known
// RoundRobin type. Expect that the unsupported type is skipped and RoundRobin
// is selected.
TypedStruct typed_struct;
typed_struct.set_type_url("myorg/foo/bar/test.UnknownLb");
LoadBalancingPolicyProto policy;
auto* lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
typed_struct);
lb_policy = policy.add_policies();
lb_policy->mutable_typed_extension_config()->mutable_typed_config()->PackFrom(
RoundRobin());
auto result = ConvertXdsPolicy(policy);
EXPECT_TRUE(result.ok());
EXPECT_EQ(result->size(), 1);
grpc_error_handle error = GRPC_ERROR_NONE;
EXPECT_EQ((*result)[0], Json::Parse("{"
"\"round_robin\": {}"
"}",
&error));
}
// Build a recurse load balancing policy that goes beyond the max allowable
// depth of 16.
LoadBalancingPolicyProto BuildRecursiveLoadBalancingPolicy(int depth) {
LoadBalancingPolicyProto policy;
if (depth >= 16) {
policy.add_policies()
->mutable_typed_extension_config()
->mutable_typed_config()
->PackFrom(RoundRobin());
return policy;
}
WrrLocality wrr_locality;
*wrr_locality.mutable_endpoint_picking_policy() =
BuildRecursiveLoadBalancingPolicy(depth + 1);
policy.add_policies()
->mutable_typed_extension_config()
->mutable_typed_config()
->PackFrom(wrr_locality);
return policy;
}
TEST(XdsLbPolicyRegistryTest, MaxRecursion) {
auto result = ConvertXdsPolicy(BuildRecursiveLoadBalancingPolicy(0));
EXPECT_EQ(result.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(result.status().message()),
::testing::ContainsRegex("LoadBalancingPolicy configuration has "
"a recursion depth of more than 16"));
}
} // namespace
} // namespace testing
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc::testing::TestEnvironment env(&argc, argv);
grpc_core::LoadBalancingPolicyRegistry::Builder::
RegisterLoadBalancingPolicyFactory(
absl::make_unique<grpc_core::testing::CustomLbPolicyFactory>());
grpc_init();
auto result = RUN_ALL_TESTS();
grpc_shutdown();
return result;
}

@ -1168,7 +1168,7 @@ TEST_P(XdsEnabledServerTest, UnsupportedHttpFilter) {
auto* http_filter = http_connection_manager.add_http_filters();
http_filter->set_name("grpc.testing.unsupported_http_filter");
http_filter->mutable_typed_config()->set_type_url(
"grpc.testing.unsupported_http_filter");
"custom/grpc.testing.unsupported_http_filter");
http_filter = http_connection_manager.add_http_filters();
http_filter->set_name("router");
http_filter->mutable_typed_config()->PackFrom(
@ -1193,7 +1193,7 @@ TEST_P(XdsEnabledServerTest, HttpFilterNotSupportedOnServer) {
auto* http_filter = http_connection_manager.add_http_filters();
http_filter->set_name("grpc.testing.client_only_http_filter");
http_filter->mutable_typed_config()->set_type_url(
"grpc.testing.client_only_http_filter");
"custom/grpc.testing.client_only_http_filter");
http_filter = http_connection_manager.add_http_filters();
http_filter->set_name("router");
http_filter->mutable_typed_config()->PackFrom(
@ -1220,7 +1220,7 @@ TEST_P(XdsEnabledServerTest,
auto* http_filter = http_connection_manager.add_http_filters();
http_filter->set_name("grpc.testing.client_only_http_filter");
http_filter->mutable_typed_config()->set_type_url(
"grpc.testing.client_only_http_filter");
"custom/grpc.testing.client_only_http_filter");
http_filter->set_is_optional(true);
http_filter = http_connection_manager.add_http_filters();
http_filter->set_name("router");

@ -142,7 +142,7 @@ TEST_P(LdsTest, NacksNonTerminalHttpFilterAtEndOfList) {
auto* filter = http_connection_manager.mutable_http_filters(0);
filter->set_name("unknown");
filter->mutable_typed_config()->set_type_url(
"grpc.testing.client_only_http_filter");
"custom/grpc.testing.client_only_http_filter");
listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
http_connection_manager);
SetListenerAndRouteConfiguration(balancer_.get(), listener,
@ -166,7 +166,7 @@ TEST_P(LdsTest, NacksTerminalFilterBeforeEndOfList) {
auto* filter = http_connection_manager.add_http_filters();
filter->set_name("grpc.testing.terminal_http_filter");
filter->mutable_typed_config()->set_type_url(
"grpc.testing.terminal_http_filter");
"custom/grpc.testing.terminal_http_filter");
listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
http_connection_manager);
SetListenerAndRouteConfiguration(balancer_.get(), listener,
@ -353,7 +353,7 @@ TEST_P(LdsTest, RejectsHttpFiltersNotSupportedOnClients) {
auto* filter = http_connection_manager.mutable_http_filters(0);
filter->set_name("grpc.testing.server_only_http_filter");
filter->mutable_typed_config()->set_type_url(
"grpc.testing.server_only_http_filter");
"custom/grpc.testing.server_only_http_filter");
listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
http_connection_manager);
SetListenerAndRouteConfiguration(balancer_.get(), listener,
@ -378,7 +378,7 @@ TEST_P(LdsTest, IgnoresOptionalHttpFiltersNotSupportedOnClients) {
auto* filter = http_connection_manager.mutable_http_filters(0);
filter->set_name("grpc.testing.server_only_http_filter");
filter->mutable_typed_config()->set_type_url(
"grpc.testing.server_only_http_filter");
"custom/grpc.testing.server_only_http_filter");
filter->set_is_optional(true);
listener.mutable_api_listener()->mutable_api_listener()->PackFrom(
http_connection_manager);

@ -1415,6 +1415,10 @@ src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
@ -1868,6 +1872,8 @@ src/core/ext/xds/xds_http_filters.cc \
src/core/ext/xds/xds_http_filters.h \
src/core/ext/xds/xds_http_rbac_filter.cc \
src/core/ext/xds/xds_http_rbac_filter.h \
src/core/ext/xds/xds_lb_policy_registry.cc \
src/core/ext/xds/xds_lb_policy_registry.h \
src/core/ext/xds/xds_listener.cc \
src/core/ext/xds/xds_listener.h \
src/core/ext/xds/xds_resource_type.cc \

@ -1204,6 +1204,10 @@ src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c
src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \
src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/ring_hash/v3/ring_hash.upb.h \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.c \
src/core/ext/upb-generated/envoy/extensions/load_balancing_policies/wrr_locality/v3/wrr_locality.upb.h \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h \
src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \
@ -1657,6 +1661,8 @@ src/core/ext/xds/xds_http_filters.cc \
src/core/ext/xds/xds_http_filters.h \
src/core/ext/xds/xds_http_rbac_filter.cc \
src/core/ext/xds/xds_http_rbac_filter.h \
src/core/ext/xds/xds_lb_policy_registry.cc \
src/core/ext/xds/xds_lb_policy_registry.h \
src/core/ext/xds/xds_listener.cc \
src/core/ext/xds/xds_listener.h \
src/core/ext/xds/xds_resource_type.cc \

@ -7801,6 +7801,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "xds_lb_policy_registry_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": false
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save