Second attempt: xDS stateful session affinity: add config plumbing (#31874)

* Revert "Revert "xDS stateful session affinity: add config plumbing (#31827)" (#31873)"

This reverts commit 4f15d3dcf9.

* fix build for compilers too dumb to recognize the full set of enum values
pull/31875/head^2
Mark D. Roth 2 years ago committed by GitHub
parent fe9f9afaa0
commit 5192021637
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 56
      CMakeLists.txt
  2. 2
      Makefile
  3. 18
      build_autogenerated.yaml
  4. 1
      config.m4
  5. 1
      config.w32
  6. 2
      gRPC-C++.podspec
  7. 3
      gRPC-Core.podspec
  8. 2
      grpc.gemspec
  9. 1
      grpc.gyp
  10. 2
      package.xml
  11. 2
      src/core/BUILD
  12. 9
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  13. 18
      src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc
  14. 33
      src/core/ext/xds/xds_cluster.cc
  15. 6
      src/core/ext/xds/xds_cluster.h
  16. 10
      src/core/ext/xds/xds_endpoint.cc
  17. 77
      src/core/ext/xds/xds_health_status.cc
  18. 78
      src/core/ext/xds/xds_health_status.h
  19. 10
      src/core/lib/json/json_object_loader.cc
  20. 15
      src/core/lib/json/json_object_loader.h
  21. 9
      src/proto/grpc/testing/xds/v3/BUILD
  22. 7
      src/proto/grpc/testing/xds/v3/cluster.proto
  23. 29
      src/proto/grpc/testing/xds/v3/endpoint.proto
  24. 55
      src/proto/grpc/testing/xds/v3/health_check.proto
  25. 1
      src/python/grpcio/grpc_core_dependencies.py
  26. 61
      test/core/json/json_object_loader_test.cc
  27. 1
      test/core/xds/BUILD
  28. 58
      test/core/xds/xds_cluster_resource_type_test.cc
  29. 113
      test/core/xds/xds_endpoint_resource_type_test.cc
  30. 2
      test/cpp/end2end/xds/xds_cluster_end2end_test.cc
  31. 2
      test/cpp/end2end/xds/xds_end2end_test_lib.cc
  32. 19
      test/cpp/end2end/xds/xds_end2end_test_lib.h
  33. 10
      test/cpp/end2end/xds/xds_ring_hash_end2end_test.cc
  34. 2
      tools/doxygen/Doxyfile.c++.internal
  35. 2
      tools/doxygen/Doxyfile.core.internal

56
CMakeLists.txt generated

@ -676,6 +676,9 @@ protobuf_generate_grpc_cpp_with_import_path_correction(
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/fault_common.proto src/proto/grpc/testing/xds/v3/fault_common.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/health_check.proto src/proto/grpc/testing/xds/v3/health_check.proto
)
protobuf_generate_grpc_cpp_with_import_path_correction(
src/proto/grpc/testing/xds/v3/http_connection_manager.proto src/proto/grpc/testing/xds/v3/http_connection_manager.proto
)
@ -2079,6 +2082,7 @@ add_library(grpc
src/core/ext/xds/xds_cluster_specifier_plugin.cc
src/core/ext/xds/xds_common_types.cc
src/core/ext/xds/xds_endpoint.cc
src/core/ext/xds/xds_health_status.cc
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
@ -22263,6 +22267,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -22402,6 +22410,10 @@ add_executable(xds_cluster_resource_type_test
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.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
@ -22529,6 +22541,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -22773,6 +22789,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -23047,6 +23067,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -23223,6 +23247,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -23350,6 +23378,10 @@ add_executable(xds_endpoint_resource_type_test
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.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
@ -23453,6 +23485,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -23866,6 +23902,10 @@ add_executable(xds_lb_policy_registry_test
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.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
@ -24135,6 +24175,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -24376,6 +24420,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -24548,6 +24596,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_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/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h
@ -24836,6 +24888,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/fault_common.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/health_check.grpc.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/http_connection_manager.pb.h

2
Makefile generated

@ -1362,6 +1362,7 @@ LIBGRPC_SRC = \
src/core/ext/xds/xds_cluster_specifier_plugin.cc \
src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_endpoint.cc \
src/core/ext/xds/xds_health_status.cc \
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 \
@ -3205,6 +3206,7 @@ src/core/ext/xds/xds_cluster.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_cluster_specifier_plugin.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_common_types.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_endpoint.cc: $(OPENSSL_DEP)
src/core/ext/xds/xds_health_status.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)

@ -706,6 +706,7 @@ libs:
- src/core/ext/xds/xds_cluster_specifier_plugin.h
- src/core/ext/xds/xds_common_types.h
- src/core/ext/xds/xds_endpoint.h
- src/core/ext/xds/xds_health_status.h
- 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
@ -1460,6 +1461,7 @@ libs:
- src/core/ext/xds/xds_cluster_specifier_plugin.cc
- src/core/ext/xds/xds_common_types.cc
- src/core/ext/xds/xds_endpoint.cc
- src/core/ext/xds/xds_health_status.cc
- 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
@ -12516,6 +12518,7 @@ targets:
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -12559,6 +12562,7 @@ targets:
- 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/health_check.proto
- src/proto/grpc/testing/xds/v3/outlier_detection.proto
- src/proto/grpc/testing/xds/v3/percent.proto
- src/proto/grpc/testing/xds/v3/regex.proto
@ -12599,6 +12603,7 @@ targets:
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -12686,6 +12691,7 @@ targets:
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -12790,6 +12796,7 @@ targets:
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -12847,6 +12854,7 @@ targets:
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/fault.proto
- src/proto/grpc/testing/xds/v3/fault_common.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -12881,11 +12889,13 @@ targets:
gtest: true
build: test
language: c++
headers: []
headers:
- test/core/util/scoped_env_var.h
src:
- src/proto/grpc/testing/xds/v3/address.proto
- src/proto/grpc/testing/xds/v3/base.proto
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/percent.proto
- src/cpp/util/status.cc
- test/core/xds/xds_endpoint_resource_type_test.cc
@ -12919,6 +12929,7 @@ targets:
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/fault.proto
- src/proto/grpc/testing/xds/v3/fault_common.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -13059,6 +13070,7 @@ targets:
- 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/health_check.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
@ -13150,6 +13162,7 @@ targets:
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/fault.proto
- src/proto/grpc/testing/xds/v3/fault_common.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -13224,6 +13237,7 @@ targets:
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -13281,6 +13295,7 @@ targets:
- src/proto/grpc/testing/xds/v3/endpoint.proto
- src/proto/grpc/testing/xds/v3/expr.proto
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto
@ -13379,6 +13394,7 @@ targets:
- src/proto/grpc/testing/xds/v3/extension.proto
- src/proto/grpc/testing/xds/v3/fault.proto
- src/proto/grpc/testing/xds/v3/fault_common.proto
- src/proto/grpc/testing/xds/v3/health_check.proto
- src/proto/grpc/testing/xds/v3/http_connection_manager.proto
- src/proto/grpc/testing/xds/v3/http_filter_rbac.proto
- src/proto/grpc/testing/xds/v3/listener.proto

1
config.m4 generated

@ -445,6 +445,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/xds/xds_cluster_specifier_plugin.cc \
src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_endpoint.cc \
src/core/ext/xds/xds_health_status.cc \
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 \

1
config.w32 generated

@ -411,6 +411,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\xds\\xds_cluster_specifier_plugin.cc " +
"src\\core\\ext\\xds\\xds_common_types.cc " +
"src\\core\\ext\\xds\\xds_endpoint.cc " +
"src\\core\\ext\\xds\\xds_health_status.cc " +
"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 " +

2
gRPC-C++.podspec generated

@ -664,6 +664,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_health_status.h',
'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',
@ -1561,6 +1562,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_health_status.h',
'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',

3
gRPC-Core.podspec generated

@ -994,6 +994,8 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.cc',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_health_status.cc',
'src/core/ext/xds/xds_health_status.h',
'src/core/ext/xds/xds_http_fault_filter.cc',
'src/core/ext/xds/xds_http_fault_filter.h',
'src/core/ext/xds/xds_http_filters.cc',
@ -2202,6 +2204,7 @@ Pod::Spec.new do |s|
'src/core/ext/xds/xds_cluster_specifier_plugin.h',
'src/core/ext/xds/xds_common_types.h',
'src/core/ext/xds/xds_endpoint.h',
'src/core/ext/xds/xds_health_status.h',
'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',

2
grpc.gemspec generated

@ -905,6 +905,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/xds/xds_common_types.h )
s.files += %w( src/core/ext/xds/xds_endpoint.cc )
s.files += %w( src/core/ext/xds/xds_endpoint.h )
s.files += %w( src/core/ext/xds/xds_health_status.cc )
s.files += %w( src/core/ext/xds/xds_health_status.h )
s.files += %w( src/core/ext/xds/xds_http_fault_filter.cc )
s.files += %w( src/core/ext/xds/xds_http_fault_filter.h )
s.files += %w( src/core/ext/xds/xds_http_filters.cc )

1
grpc.gyp generated

@ -775,6 +775,7 @@
'src/core/ext/xds/xds_cluster_specifier_plugin.cc',
'src/core/ext/xds/xds_common_types.cc',
'src/core/ext/xds/xds_endpoint.cc',
'src/core/ext/xds/xds_health_status.cc',
'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',

2
package.xml generated

@ -887,6 +887,8 @@
<file baseinstalldir="/" name="src/core/ext/xds/xds_common_types.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_endpoint.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_health_status.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_health_status.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_http_fault_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_http_fault_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/xds/xds_http_filters.cc" role="src" />

@ -3578,6 +3578,7 @@ grpc_cc_library(
"ext/xds/xds_cluster_specifier_plugin.cc",
"ext/xds/xds_common_types.cc",
"ext/xds/xds_endpoint.cc",
"ext/xds/xds_health_status.cc",
"ext/xds/xds_http_fault_filter.cc",
"ext/xds/xds_http_filters.cc",
"ext/xds/xds_http_rbac_filter.cc",
@ -3599,6 +3600,7 @@ grpc_cc_library(
"ext/xds/xds_cluster_specifier_plugin.h",
"ext/xds/xds_common_types.h",
"ext/xds/xds_endpoint.h",
"ext/xds/xds_health_status.h",
"ext/xds/xds_http_fault_filter.h",
"ext/xds/xds_http_filters.h",
"ext/xds/xds_http_rbac_filter.h",

@ -358,7 +358,7 @@ absl::Status CdsLb::UpdateLocked(UpdateArgs args) {
// Generates the discovery mechanism config for the specified cluster name.
//
// If no CdsUpdate has been received for the cluster, starts the watcher
// If no CDS update has been received for the cluster, starts the watcher
// if needed, and returns false. Otherwise, generates the discovery
// mechanism config, adds it to *discovery_mechanisms, and returns true.
//
@ -462,6 +462,13 @@ absl::StatusOr<bool> CdsLb::GenerateDiscoveryMechanismForCluster(
mechanism["lrsLoadReportingServer"] =
state.update->lrs_load_reporting_server->ToJson();
}
if (!state.update->host_override_statuses.empty()) {
Json::Array status_list;
for (const auto& status : state.update->host_override_statuses) {
status_list.emplace_back(status.ToString());
}
mechanism["overrideHostStatus"] = std::move(status_list);
}
discovery_mechanisms->emplace_back(std::move(mechanism));
return true;
}

@ -97,6 +97,8 @@ class XdsClusterResolverLbConfig : public LoadBalancingPolicy::Config {
std::string eds_service_name;
std::string dns_hostname;
Json::Array host_override_statuses;
// This is type Json::Object instead of OutlierDetectionConfig, because we
// don't actually need to validate the contents of the outlier detection
// config here. In this case, the JSON is generated by the CDS policy
@ -112,6 +114,7 @@ class XdsClusterResolverLbConfig : public LoadBalancingPolicy::Config {
type == other.type &&
eds_service_name == other.eds_service_name &&
dns_hostname == other.dns_hostname &&
host_override_statuses == other.host_override_statuses &&
outlier_detection_lb_config == other.outlier_detection_lb_config);
}
@ -869,6 +872,7 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
for (size_t priority = 0;
priority < discovery_entry.latest_update->priorities.size();
++priority) {
// Determine what xDS LB policy to use.
Json child_policy;
if (!discovery_entry.discovery_mechanism->override_child_policy()
.empty()) {
@ -877,7 +881,14 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
} else {
child_policy = config_->xds_lb_policy();
}
// Wrap it in the drop policy.
// Wrap the xDS LB policy in the xds_override_host policy.
Json::Array xds_override_host_config = {Json::Object{
{"xds_override_host_experimental",
Json::Object{
{"overrideHostStatus", discovery_config.host_override_statuses},
{"childPolicy", std::move(child_policy)},
}}}};
// Wrap it in the xds_cluster_impl policy.
Json::Array drop_categories;
if (discovery_entry.latest_update->drop_config != nullptr) {
for (const auto& category :
@ -890,7 +901,7 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
}
Json::Object xds_cluster_impl_config = {
{"clusterName", discovery_config.cluster_name},
{"childPolicy", std::move(child_policy)},
{"childPolicy", std::move(xds_override_host_config)},
{"dropCategories", std::move(drop_categories)},
{"maxConcurrentRequests", discovery_config.max_concurrent_requests},
};
@ -902,6 +913,7 @@ XdsClusterResolverLb::CreateChildPolicyConfigLocked() {
xds_cluster_impl_config["lrsLoadReportingServer"] =
discovery_config.lrs_load_reporting_server->ToJson();
}
// Wrap it in the outlier_detection policy.
Json::Object outlier_detection_config;
if (discovery_entry.config().outlier_detection_lb_config.has_value()) {
outlier_detection_config =
@ -1032,6 +1044,8 @@ XdsClusterResolverLbConfig::DiscoveryMechanism::JsonLoader(const JsonArgs&) {
&DiscoveryMechanism::max_concurrent_requests)
.OptionalField("outlierDetection",
&DiscoveryMechanism::outlier_detection_lb_config)
.OptionalField("overrideHostStatus",
&DiscoveryMechanism::host_override_statuses)
.Finish();
return loader;
}

@ -35,6 +35,7 @@
#include "envoy/config/core/v3/address.upb.h"
#include "envoy/config/core/v3/base.upb.h"
#include "envoy/config/core/v3/config_source.upb.h"
#include "envoy/config/core/v3/health_check.upb.h"
#include "envoy/config/endpoint/v3/endpoint.upb.h"
#include "envoy/config/endpoint/v3/endpoint_components.upb.h"
#include "envoy/extensions/clusters/aggregate/v3/cluster.upb.h"
@ -121,6 +122,15 @@ std::string XdsClusterResource::ToString() const {
}
contents.push_back(
absl::StrCat("max_concurrent_requests=", max_concurrent_requests));
if (!host_override_statuses.empty()) {
std::vector<const char*> statuses;
statuses.reserve(host_override_statuses.size());
for (const auto& status : host_override_statuses) {
statuses.push_back(status.ToString());
}
contents.push_back(absl::StrCat("override_host_statuses={",
absl::StrJoin(statuses, ", "), "}"));
}
return absl::StrCat("{", absl::StrJoin(contents, ", "), "}");
}
@ -617,6 +627,29 @@ absl::StatusOr<XdsClusterResource> CdsResourceParse(
}
cds_update.outlier_detection = outlier_detection_update;
}
// Validate override host status.
if (XdsHostOverrideEnabled()) {
const auto* common_lb_config =
envoy_config_cluster_v3_Cluster_common_lb_config(cluster);
if (common_lb_config != nullptr) {
ValidationErrors::ScopedField field(&errors, ".common_lb_config");
const auto* override_host_status =
envoy_config_cluster_v3_Cluster_CommonLbConfig_override_host_status(
common_lb_config);
if (override_host_status != nullptr) {
ValidationErrors::ScopedField field(&errors, ".override_host_status");
size_t size;
const int32_t* statuses = envoy_config_core_v3_HealthStatusSet_statuses(
override_host_status, &size);
for (size_t i = 0; i < size; ++i) {
auto status = XdsHealthStatus::FromUpb(statuses[i]);
if (status.has_value()) {
cds_update.host_override_statuses.insert(*status);
}
}
}
}
}
// Return result.
if (!errors.ok()) return errors.status("errors validating Cluster resource");
return cds_update;

@ -38,6 +38,7 @@
#include "src/core/ext/xds/xds_bootstrap_grpc.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_health_status.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
#include "src/core/lib/json/json.h"
@ -95,12 +96,15 @@ struct XdsClusterResource : public XdsResourceType::ResourceData {
absl::optional<OutlierDetectionConfig> outlier_detection;
std::set<XdsHealthStatus> host_override_statuses;
bool operator==(const XdsClusterResource& other) const {
return type == other.type && lb_policy_config == other.lb_policy_config &&
lrs_load_reporting_server == other.lrs_load_reporting_server &&
common_tls_context == other.common_tls_context &&
max_concurrent_requests == other.max_concurrent_requests &&
outlier_detection == other.outlier_detection;
outlier_detection == other.outlier_detection &&
host_override_statuses == other.host_override_statuses;
}
std::string ToString() const;

@ -44,6 +44,8 @@
#include <grpc/support/log.h>
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_cluster.h"
#include "src/core/ext/xds/xds_health_status.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/lib/address_utils/parse_address.h"
#include "src/core/lib/address_utils/sockaddr_utils.h"
@ -150,13 +152,15 @@ absl::optional<ServerAddress> ServerAddressParse(
const envoy_config_endpoint_v3_LbEndpoint* lb_endpoint,
ValidationErrors* errors) {
// health_status
// If not HEALTHY or UNKNOWN, skip this endpoint.
const int32_t health_status =
envoy_config_endpoint_v3_LbEndpoint_health_status(lb_endpoint);
if (health_status != envoy_config_core_v3_UNKNOWN &&
if (!XdsHostOverrideEnabled() &&
health_status != envoy_config_core_v3_UNKNOWN &&
health_status != envoy_config_core_v3_HEALTHY) {
return absl::nullopt;
}
auto status = XdsHealthStatus::FromUpb(health_status);
if (!status.has_value()) return absl::nullopt;
// load_balancing_weight
uint32_t weight = 1;
{
@ -217,6 +221,8 @@ absl::optional<ServerAddress> ServerAddressParse(
attributes;
attributes[ServerAddressWeightAttribute::kServerAddressWeightAttributeKey] =
std::make_unique<ServerAddressWeightAttribute>(weight);
attributes[XdsEndpointHealthStatusAttribute::kKey] =
std::make_unique<XdsEndpointHealthStatusAttribute>(*status);
return ServerAddress(grpc_address, ChannelArgs(), std::move(attributes));
}

@ -0,0 +1,77 @@
//
// 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_health_status.h"
#include "envoy/config/core/v3/health_check.upb.h"
namespace grpc_core {
absl::optional<XdsHealthStatus> XdsHealthStatus::FromUpb(uint32_t status) {
switch (status) {
case envoy_config_core_v3_UNKNOWN:
return XdsHealthStatus(kUnknown);
case envoy_config_core_v3_HEALTHY:
return XdsHealthStatus(kHealthy);
case envoy_config_core_v3_DRAINING:
return XdsHealthStatus(kDraining);
default:
return absl::nullopt;
}
}
absl::optional<XdsHealthStatus> XdsHealthStatus::FromString(
absl::string_view status) {
if (status == "UNKNOWN") return XdsHealthStatus(kUnknown);
if (status == "HEALTHY") return XdsHealthStatus(kHealthy);
if (status == "DRAINING") return XdsHealthStatus(kDraining);
return absl::nullopt;
}
const char* XdsHealthStatus::ToString() const {
switch (status_) {
case kUnknown:
return "UNKNOWN";
case kHealthy:
return "HEALTHY";
case kDraining:
return "DRAINING";
default:
return "<INVALID>";
}
}
bool operator<(const XdsHealthStatus& hs1, const XdsHealthStatus& hs2) {
return hs1.status() < hs2.status();
}
const char* XdsEndpointHealthStatusAttribute::kKey =
"xds_endpoint_health_status";
int XdsEndpointHealthStatusAttribute::Cmp(
const AttributeInterface* other) const {
const auto* other_attr =
static_cast<const XdsEndpointHealthStatusAttribute*>(other);
return QsortCompare(status_, other_attr->status_);
}
std::string XdsEndpointHealthStatusAttribute::ToString() const {
return absl::StrCat("{status_=", status_.ToString(), "}");
}
} // namespace grpc_core

@ -0,0 +1,78 @@
//
// 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_HEALTH_STATUS_H
#define GRPC_CORE_EXT_XDS_XDS_HEALTH_STATUS_H
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include "absl/types/optional.h"
#include "src/core/lib/resolver/server_address.h"
namespace grpc_core {
class XdsHealthStatus {
public:
enum HealthStatus { kUnknown, kHealthy, kDraining };
// Returns an XdsHealthStatus for supported enum values, else nullopt.
static absl::optional<XdsHealthStatus> FromUpb(uint32_t status);
static absl::optional<XdsHealthStatus> FromString(absl::string_view status);
explicit XdsHealthStatus(HealthStatus status) : status_(status) {}
HealthStatus status() const { return status_; }
bool operator==(const XdsHealthStatus& other) const {
return status_ == other.status_;
}
const char* ToString() const;
private:
HealthStatus status_;
};
bool operator<(const XdsHealthStatus& hs1, const XdsHealthStatus& hs2);
class XdsEndpointHealthStatusAttribute
: public ServerAddress::AttributeInterface {
public:
static const char* kKey;
explicit XdsEndpointHealthStatusAttribute(XdsHealthStatus status)
: status_(status) {}
XdsHealthStatus status() const { return status_; }
std::unique_ptr<AttributeInterface> Copy() const override {
return std::make_unique<XdsEndpointHealthStatusAttribute>(status_);
}
int Cmp(const AttributeInterface* other) const override;
std::string ToString() const override;
private:
XdsHealthStatus status_;
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_XDS_XDS_HEALTH_STATUS_H

@ -110,6 +110,16 @@ void LoadUnprocessedJsonObject::LoadInto(const Json& json, const JsonArgs&,
*static_cast<Json::Object*>(dst) = json.object_value();
}
void LoadUnprocessedJsonArray::LoadInto(const Json& json, const JsonArgs&,
void* dst,
ValidationErrors* errors) const {
if (json.type() != Json::Type::ARRAY) {
errors->AddError("is not an array");
return;
}
*static_cast<Json::Array*>(dst) = json.array_value();
}
void LoadVector::LoadInto(const Json& json, const JsonArgs& args, void* dst,
ValidationErrors* errors) const {
if (json.type() != Json::Type::ARRAY) {

@ -214,6 +214,16 @@ class LoadUnprocessedJsonObject : public LoaderInterface {
~LoadUnprocessedJsonObject() = default;
};
// Loads an unprocessed JSON array value.
class LoadUnprocessedJsonArray : public LoaderInterface {
public:
void LoadInto(const Json& json, const JsonArgs& /*args*/, void* dst,
ValidationErrors* errors) const override;
protected:
~LoadUnprocessedJsonArray() = default;
};
// Load a vector of some type.
class LoadVector : public LoaderInterface {
public:
@ -328,6 +338,11 @@ class AutoLoader<Json::Object> final : public LoadUnprocessedJsonObject {
private:
~AutoLoader() = default;
};
template <>
class AutoLoader<Json::Array> final : public LoadUnprocessedJsonArray {
private:
~AutoLoader() = default;
};
// Specializations of AutoLoader for vectors.
template <typename T>

@ -93,6 +93,7 @@ grpc_proto_library(
"config_source_proto",
"endpoint_proto",
"extension_proto",
"health_check_proto",
"outlier_detection_proto",
],
)
@ -106,10 +107,18 @@ grpc_proto_library(
deps = [
"address_proto",
"base_proto",
"health_check_proto",
"percent_proto",
],
)
grpc_proto_library(
name = "health_check_proto",
srcs = [
"health_check.proto",
],
)
grpc_proto_library(
name = "extension_proto",
srcs = [

@ -22,6 +22,7 @@ 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/health_check.proto";
import "src/proto/grpc/testing/xds/v3/outlier_detection.proto";
import "google/protobuf/any.proto";
@ -137,6 +138,10 @@ message Cluster {
string service_name = 2;
}
message CommonLbConfig {
core.v3.HealthStatusSet override_host_status = 8;
}
// Supplies the name of the cluster which must be unique across all clusters.
// The cluster name is used when emitting
// :ref:`statistics <config_cluster_manager_cluster_stats>` if :ref:`alt_stat_name
@ -218,6 +223,8 @@ message Cluster {
RingHashLbConfig ring_hash_lb_config = 23;
}
CommonLbConfig common_lb_config = 27;
// Optional custom transport socket implementation to use for upstream connections.
// To setup TLS, set a transport socket with name `tls` and
// :ref:`UpstreamTlsContexts <envoy_api_msg_extensions.transport_sockets.tls.v3.UpstreamTlsContext>` in the `typed_config`.

@ -20,38 +20,13 @@ package envoy.config.endpoint.v3;
import "src/proto/grpc/testing/xds/v3/address.proto";
import "src/proto/grpc/testing/xds/v3/base.proto";
import "src/proto/grpc/testing/xds/v3/health_check.proto";
import "src/proto/grpc/testing/xds/v3/percent.proto";
import "google/protobuf/wrappers.proto";
// [#protodoc-title: Endpoints]
// Endpoint health status.
enum HealthStatus {
// The health status is not known. This is interpreted by Envoy as *HEALTHY*.
UNKNOWN = 0;
// Healthy.
HEALTHY = 1;
// Unhealthy.
UNHEALTHY = 2;
// Connection draining in progress. E.g.,
// `<https://aws.amazon.com/blogs/aws/elb-connection-draining-remove-instances-from-service-with-care/>`_
// or
// `<https://cloud.google.com/compute/docs/load-balancing/enabling-connection-draining>`_.
// This is interpreted by Envoy as *UNHEALTHY*.
DRAINING = 3;
// Health check timed out. This is part of HDS and is interpreted by Envoy as
// *UNHEALTHY*.
TIMEOUT = 4;
// Degraded.
DEGRADED = 5;
}
// Upstream host identifier.
message Endpoint {
// The upstream host address.
@ -75,7 +50,7 @@ message LbEndpoint {
}
// Optional health status when known and supplied by EDS server.
HealthStatus health_status = 2;
core.v3.HealthStatus health_status = 2;
// The optional load balancing weight of the upstream host; at least 1.
// Envoy uses the load balancing weight in some of the built in load

@ -0,0 +1,55 @@
// 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.
// Local copy of Envoy xDS proto file, used for testing only.
syntax = "proto3";
package envoy.config.core.v3;
// [#protodoc-title: Health check]
// * Health checking :ref:`architecture overview <arch_overview_health_checking>`.
// * If health checking is configured for a cluster, additional statistics are emitted. They are
// documented :ref:`here <config_cluster_manager_cluster_stats>`.
// Endpoint health status.
enum HealthStatus {
// The health status is not known. This is interpreted by Envoy as ``HEALTHY``.
UNKNOWN = 0;
// Healthy.
HEALTHY = 1;
// Unhealthy.
UNHEALTHY = 2;
// Connection draining in progress. E.g.,
// `<https://aws.amazon.com/blogs/aws/elb-connection-draining-remove-instances-from-service-with-care/>`_
// or
// `<https://cloud.google.com/compute/docs/load-balancing/enabling-connection-draining>`_.
// This is interpreted by Envoy as ``UNHEALTHY``.
DRAINING = 3;
// Health check timed out. This is part of HDS and is interpreted by Envoy as
// ``UNHEALTHY``.
TIMEOUT = 4;
// Degraded.
DEGRADED = 5;
}
message HealthStatusSet {
// An order-independent set of health status.
repeated HealthStatus statuses = 1;
}

@ -420,6 +420,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/xds/xds_cluster_specifier_plugin.cc',
'src/core/ext/xds/xds_common_types.cc',
'src/core/ext/xds/xds_endpoint.cc',
'src/core/ext/xds/xds_health_status.cc',
'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',

@ -569,6 +569,67 @@ TEST(JsonObjectLoader, JsonObjectFields) {
<< test_struct.status();
}
//
// Json::Array tests
//
TEST(JsonObjectLoader, JsonArrayFields) {
struct TestStruct {
Json::Array value;
Json::Array optional_value;
absl::optional<Json::Array> absl_optional_value;
std::unique_ptr<Json::Array> unique_ptr_value;
static const JsonLoaderInterface* JsonLoader(const JsonArgs&) {
static const auto* loader =
JsonObjectLoader<TestStruct>()
.Field("value", &TestStruct::value)
.OptionalField("optional_value", &TestStruct::optional_value)
.OptionalField("absl_optional_value",
&TestStruct::absl_optional_value)
.OptionalField("unique_ptr_value", &TestStruct::unique_ptr_value)
.Finish();
return loader;
}
};
// Valid object.
auto test_struct = Parse<TestStruct>("{\"value\": [1, \"a\"]}");
ASSERT_TRUE(test_struct.ok()) << test_struct.status();
EXPECT_EQ(Json{test_struct->value}.Dump(), "[1,\"a\"]");
EXPECT_EQ(Json{test_struct->optional_value}.Dump(), "[]");
EXPECT_FALSE(test_struct->absl_optional_value.has_value());
EXPECT_EQ(test_struct->unique_ptr_value, nullptr);
// Fails if required field is not present.
test_struct = Parse<TestStruct>("{}");
EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(test_struct.status().message(),
"errors validating JSON: [field:value error:field not present]")
<< test_struct.status();
// Optional fields present.
test_struct = Parse<TestStruct>(
"{\"value\": [1, \"a\"], \"optional_value\": [2, \"b\"], "
"\"absl_optional_value\": [3, \"c\"], \"unique_ptr_value\": [4, \"d\"]}");
ASSERT_TRUE(test_struct.ok()) << test_struct.status();
EXPECT_EQ(Json{test_struct->value}.Dump(), "[1,\"a\"]");
EXPECT_EQ(Json{test_struct->optional_value}.Dump(), "[2,\"b\"]");
ASSERT_TRUE(test_struct->absl_optional_value.has_value());
EXPECT_EQ(Json{*test_struct->absl_optional_value}.Dump(), "[3,\"c\"]");
ASSERT_NE(test_struct->unique_ptr_value, nullptr);
EXPECT_EQ(Json{*test_struct->unique_ptr_value}.Dump(), "[4,\"d\"]");
// Wrong JSON type.
test_struct = Parse<TestStruct>(
"{\"value\": {}, \"optional_value\": true, "
"\"absl_optional_value\": 1, \"unique_ptr_value\": \"foo\"}");
EXPECT_EQ(test_struct.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_EQ(test_struct.status().message(),
"errors validating JSON: ["
"field:absl_optional_value error:is not an array; "
"field:optional_value error:is not an array; "
"field:unique_ptr_value error:is not an array; "
"field:value error:is not an array]")
<< test_struct.status();
}
//
// map<> tests
//

@ -308,5 +308,6 @@ grpc_cc_test(
"//src/core:grpc_xds_client",
"//src/proto/grpc/testing/xds/v3:endpoint_proto",
"//test/core/util:grpc_test_util",
"//test/core/util:scoped_env_var",
],
)

@ -1287,6 +1287,64 @@ TEST_F(OutlierDetectionTest, InvalidValues) {
<< decode_result.resource.status();
}
//
// host override status tests
//
using HostOverrideStatusTest = XdsClusterTest;
TEST_F(HostOverrideStatusTest, IgnoredWhenNotEnabled) {
Cluster cluster;
cluster.set_name("foo");
cluster.set_type(cluster.EDS);
cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
auto* status_set =
cluster.mutable_common_lb_config()->mutable_override_host_status();
status_set->add_statuses(envoy::config::core::v3::UNKNOWN);
status_set->add_statuses(envoy::config::core::v3::HEALTHY);
status_set->add_statuses(envoy::config::core::v3::DRAINING);
status_set->add_statuses(envoy::config::core::v3::UNHEALTHY);
std::string serialized_resource;
ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
auto* resource_type = XdsClusterResourceType::Get();
auto decode_result =
resource_type->Decode(decode_context_, serialized_resource);
ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
ASSERT_TRUE(decode_result.name.has_value());
EXPECT_EQ(*decode_result.name, "foo");
auto& resource = static_cast<XdsClusterResource&>(**decode_result.resource);
EXPECT_THAT(resource.host_override_statuses, ::testing::ElementsAre());
}
TEST_F(HostOverrideStatusTest, PassesOnRelevantHealthStatuses) {
ScopedExperimentalEnvVar env_var(
"GRPC_EXPERIMENTAL_XDS_ENABLE_HOST_OVERRIDE");
Cluster cluster;
cluster.set_name("foo");
cluster.set_type(cluster.EDS);
cluster.mutable_eds_cluster_config()->mutable_eds_config()->mutable_self();
auto* status_set =
cluster.mutable_common_lb_config()->mutable_override_host_status();
status_set->add_statuses(envoy::config::core::v3::UNKNOWN);
status_set->add_statuses(envoy::config::core::v3::HEALTHY);
status_set->add_statuses(envoy::config::core::v3::DRAINING);
status_set->add_statuses(envoy::config::core::v3::UNHEALTHY);
std::string serialized_resource;
ASSERT_TRUE(cluster.SerializeToString(&serialized_resource));
auto* resource_type = XdsClusterResourceType::Get();
auto decode_result =
resource_type->Decode(decode_context_, serialized_resource);
ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
ASSERT_TRUE(decode_result.name.has_value());
EXPECT_EQ(*decode_result.name, "foo");
auto& resource = static_cast<XdsClusterResource&>(**decode_result.resource);
EXPECT_THAT(resource.host_override_statuses,
::testing::UnorderedElementsAre(
XdsHealthStatus(XdsHealthStatus::kUnknown),
XdsHealthStatus(XdsHealthStatus::kHealthy),
XdsHealthStatus(XdsHealthStatus::kDraining)));
}
} // namespace
} // namespace testing
} // namespace grpc_core

@ -39,6 +39,7 @@
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/ext/xds/xds_endpoint.h"
#include "src/core/ext/xds/xds_health_status.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/lib/address_utils/sockaddr_utils.h"
#include "src/core/lib/channel/channel_args.h"
@ -50,6 +51,7 @@
#include "src/proto/grpc/testing/xds/v3/base.pb.h"
#include "src/proto/grpc/testing/xds/v3/endpoint.pb.h"
#include "src/proto/grpc/testing/xds/v3/percent.pb.h"
#include "test/core/util/scoped_env_var.h"
#include "test/core/util/test_config.h"
using envoy::config::endpoint::v3::ClusterLoadAssignment;
@ -911,6 +913,117 @@ TEST_F(XdsEndpointTest, DropPercentageInvalidDenominator) {
<< decode_result.resource.status();
}
TEST_F(XdsEndpointTest, IgnoresEndpointsInUnsupportedStates) {
ClusterLoadAssignment cla;
cla.set_cluster_name("foo");
auto* locality = cla.add_endpoints();
locality->mutable_load_balancing_weight()->set_value(1);
auto* locality_name = locality->mutable_locality();
locality_name->set_region("myregion");
locality_name->set_zone("myzone");
locality_name->set_sub_zone("mysubzone");
auto* endpoint = locality->add_lb_endpoints();
auto* socket_address =
endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
socket_address->set_address("127.0.0.1");
socket_address->set_port_value(443);
endpoint = locality->add_lb_endpoints();
endpoint->set_health_status(envoy::config::core::v3::HealthStatus::DRAINING);
socket_address =
endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
socket_address->set_address("127.0.0.1");
socket_address->set_port_value(444);
std::string serialized_resource;
ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
auto* resource_type = XdsEndpointResourceType::Get();
auto decode_result =
resource_type->Decode(decode_context_, serialized_resource);
ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
ASSERT_TRUE(decode_result.name.has_value());
EXPECT_EQ(*decode_result.name, "foo");
auto& resource = static_cast<XdsEndpointResource&>(**decode_result.resource);
ASSERT_EQ(resource.priorities.size(), 1);
const auto& priority = resource.priorities[0];
ASSERT_EQ(priority.localities.size(), 1);
const auto& p = *priority.localities.begin();
ASSERT_EQ(p.first, p.second.name.get());
EXPECT_EQ(p.first->region(), "myregion");
EXPECT_EQ(p.first->zone(), "myzone");
EXPECT_EQ(p.first->sub_zone(), "mysubzone");
EXPECT_EQ(p.second.lb_weight, 1);
ASSERT_EQ(p.second.endpoints.size(), 1);
const auto& address = p.second.endpoints.front();
auto addr = grpc_sockaddr_to_string(&address.address(), /*normalize=*/false);
ASSERT_TRUE(addr.ok()) << addr.status();
EXPECT_EQ(*addr, "127.0.0.1:443");
}
TEST_F(XdsEndpointTest, EndpointHealthStatus) {
ScopedExperimentalEnvVar env_var(
"GRPC_EXPERIMENTAL_XDS_ENABLE_HOST_OVERRIDE");
ClusterLoadAssignment cla;
cla.set_cluster_name("foo");
auto* locality = cla.add_endpoints();
locality->mutable_load_balancing_weight()->set_value(1);
auto* locality_name = locality->mutable_locality();
locality_name->set_region("myregion");
locality_name->set_zone("myzone");
locality_name->set_sub_zone("mysubzone");
auto* endpoint = locality->add_lb_endpoints();
auto* socket_address =
endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
socket_address->set_address("127.0.0.1");
socket_address->set_port_value(443);
endpoint = locality->add_lb_endpoints();
endpoint->set_health_status(envoy::config::core::v3::HealthStatus::DRAINING);
socket_address =
endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
socket_address->set_address("127.0.0.2");
socket_address->set_port_value(443);
endpoint = locality->add_lb_endpoints();
endpoint->set_health_status(envoy::config::core::v3::HealthStatus::UNHEALTHY);
socket_address =
endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address();
socket_address->set_address("127.0.0.3");
socket_address->set_port_value(443);
std::string serialized_resource;
ASSERT_TRUE(cla.SerializeToString(&serialized_resource));
auto* resource_type = XdsEndpointResourceType::Get();
auto decode_result =
resource_type->Decode(decode_context_, serialized_resource);
ASSERT_TRUE(decode_result.resource.ok()) << decode_result.resource.status();
ASSERT_TRUE(decode_result.name.has_value());
EXPECT_EQ(*decode_result.name, "foo");
auto& resource = static_cast<XdsEndpointResource&>(**decode_result.resource);
ASSERT_EQ(resource.priorities.size(), 1);
const auto& priority = resource.priorities[0];
ASSERT_EQ(priority.localities.size(), 1);
const auto& p = *priority.localities.begin();
ASSERT_EQ(p.first, p.second.name.get());
EXPECT_EQ(p.first->region(), "myregion");
EXPECT_EQ(p.first->zone(), "myzone");
EXPECT_EQ(p.first->sub_zone(), "mysubzone");
EXPECT_EQ(p.second.lb_weight, 1);
ASSERT_EQ(p.second.endpoints.size(), 2);
const auto* address = &p.second.endpoints[0];
auto addr = grpc_sockaddr_to_string(&address->address(), /*normalize=*/false);
ASSERT_TRUE(addr.ok()) << addr.status();
EXPECT_EQ(*addr, "127.0.0.1:443");
const auto* health_attribute =
static_cast<const XdsEndpointHealthStatusAttribute*>(
address->GetAttribute(XdsEndpointHealthStatusAttribute::kKey));
ASSERT_NE(health_attribute, nullptr);
EXPECT_EQ(health_attribute->status().status(), XdsHealthStatus::kUnknown);
address = &p.second.endpoints[1];
addr = grpc_sockaddr_to_string(&address->address(), /*normalize=*/false);
ASSERT_TRUE(addr.ok()) << addr.status();
EXPECT_EQ(*addr, "127.0.0.2:443");
health_attribute = static_cast<const XdsEndpointHealthStatusAttribute*>(
address->GetAttribute(XdsEndpointHealthStatusAttribute::kKey));
ASSERT_NE(health_attribute, nullptr);
EXPECT_EQ(health_attribute->status().status(), XdsHealthStatus::kDraining);
}
} // namespace
} // namespace testing
} // namespace grpc_core

@ -34,7 +34,7 @@ namespace {
using ::envoy::config::cluster::v3::CircuitBreakers;
using ::envoy::config::cluster::v3::RoutingPriority;
using ::envoy::config::endpoint::v3::HealthStatus;
using ::envoy::config::core::v3::HealthStatus;
using ::envoy::type::v3::FractionalPercent;
using ClientStats = LrsServiceImpl::ClientStats;

@ -51,8 +51,8 @@
namespace grpc {
namespace testing {
using ::envoy::config::core::v3::HealthStatus;
using ::envoy::config::endpoint::v3::ClusterLoadAssignment;
using ::envoy::config::endpoint::v3::HealthStatus;
using ::envoy::config::listener::v3::Listener;
using ::envoy::extensions::filters::network::http_connection_manager::v3::
HttpConnectionManager;

@ -542,15 +542,14 @@ class XdsEnd2endTest : public ::testing::TestWithParam<XdsTestType> {
struct EdsResourceArgs {
// An individual endpoint for a backend running on a specified port.
struct Endpoint {
explicit Endpoint(
int port,
::envoy::config::endpoint::v3::HealthStatus health_status =
::envoy::config::endpoint::v3::HealthStatus::UNKNOWN,
int lb_weight = 1)
explicit Endpoint(int port,
::envoy::config::core::v3::HealthStatus health_status =
::envoy::config::core::v3::HealthStatus::UNKNOWN,
int lb_weight = 1)
: port(port), health_status(health_status), lb_weight(lb_weight) {}
int port;
::envoy::config::endpoint::v3::HealthStatus health_status;
::envoy::config::core::v3::HealthStatus health_status;
int lb_weight;
};
@ -584,8 +583,8 @@ class XdsEnd2endTest : public ::testing::TestWithParam<XdsTestType> {
// constructing an EDS resource.
EdsResourceArgs::Endpoint CreateEndpoint(
size_t backend_idx,
::envoy::config::endpoint::v3::HealthStatus health_status =
::envoy::config::endpoint::v3::HealthStatus::UNKNOWN,
::envoy::config::core::v3::HealthStatus health_status =
::envoy::config::core::v3::HealthStatus::UNKNOWN,
int lb_weight = 1) {
return EdsResourceArgs::Endpoint(backends_[backend_idx]->port(),
health_status, lb_weight);
@ -595,8 +594,8 @@ class XdsEnd2endTest : public ::testing::TestWithParam<XdsTestType> {
// for use in constructing an EDS resource.
std::vector<EdsResourceArgs::Endpoint> CreateEndpointsForBackends(
size_t start_index = 0, size_t stop_index = 0,
::envoy::config::endpoint::v3::HealthStatus health_status =
::envoy::config::endpoint::v3::HealthStatus::UNKNOWN,
::envoy::config::core::v3::HealthStatus health_status =
::envoy::config::core::v3::HealthStatus::UNKNOWN,
int lb_weight = 1);
// Returns an endpoint for an unused port, for use in constructing an

@ -39,7 +39,7 @@ namespace testing {
namespace {
using ::envoy::config::cluster::v3::CustomClusterType;
using ::envoy::config::endpoint::v3::HealthStatus;
using ::envoy::config::core::v3::HealthStatus;
using ::envoy::extensions::clusters::aggregate::v3::ClusterConfig;
class RingHashTest : public XdsEnd2endTest {
@ -504,11 +504,9 @@ TEST_P(RingHashTest, EndpointWeights) {
// Endpoint 2 has weight 2.
EdsResourceArgs args(
{{"locality0",
{CreateEndpoint(0, ::envoy::config::endpoint::v3::HealthStatus::UNKNOWN,
0),
CreateEndpoint(1, ::envoy::config::endpoint::v3::HealthStatus::UNKNOWN,
1),
CreateEndpoint(2, ::envoy::config::endpoint::v3::HealthStatus::UNKNOWN,
{CreateEndpoint(0, ::envoy::config::core::v3::HealthStatus::UNKNOWN, 0),
CreateEndpoint(1, ::envoy::config::core::v3::HealthStatus::UNKNOWN, 1),
CreateEndpoint(2, ::envoy::config::core::v3::HealthStatus::UNKNOWN,
2)}}});
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
// TODO(donnadionne): remove extended timeout after ring creation

@ -1903,6 +1903,8 @@ src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_common_types.h \
src/core/ext/xds/xds_endpoint.cc \
src/core/ext/xds/xds_endpoint.h \
src/core/ext/xds/xds_health_status.cc \
src/core/ext/xds/xds_health_status.h \
src/core/ext/xds/xds_http_fault_filter.cc \
src/core/ext/xds/xds_http_fault_filter.h \
src/core/ext/xds/xds_http_filters.cc \

@ -1676,6 +1676,8 @@ src/core/ext/xds/xds_common_types.cc \
src/core/ext/xds/xds_common_types.h \
src/core/ext/xds/xds_endpoint.cc \
src/core/ext/xds/xds_endpoint.h \
src/core/ext/xds/xds_health_status.cc \
src/core/ext/xds/xds_health_status.h \
src/core/ext/xds/xds_http_fault_filter.cc \
src/core/ext/xds/xds_http_fault_filter.h \
src/core/ext/xds/xds_http_filters.cc \

Loading…
Cancel
Save