diff options
185 files changed, 8867 insertions, 3921 deletions
diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 0000000000..bc31c54e94 --- /dev/null +++ b/.bazelrc @@ -0,0 +1,3 @@ +# load bazelrc from the legacy location +# as recommended in https://github.com/bazelbuild/bazel/issues/6319 +import %workspace%/tools/bazel.rc diff --git a/.clang_complete b/.clang_complete index aa77554f4e..1448b01342 100644 --- a/.clang_complete +++ b/.clang_complete @@ -14,4 +14,5 @@ -Ithird_party/cares -Ithird_party/googletest/googletest/include -Ithird_party/googletest/googlemock/include +-Ithird_party/nanopb @@ -131,7 +131,6 @@ GRPCXX_SRCS = [ "src/cpp/server/create_default_thread_pool.cc", "src/cpp/server/dynamic_thread_pool.cc", "src/cpp/server/health/default_health_check_service.cc", - "src/cpp/server/health/health.pb.c", "src/cpp/server/health/health_check_service.cc", "src/cpp/server/health/health_check_service_server_builder_option.cc", "src/cpp/server/server_builder.cc", @@ -151,7 +150,6 @@ GRPCXX_HDRS = [ "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/health/default_health_check_service.h", - "src/cpp/server/health/health.pb.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/thread_manager/thread_manager.h", ] @@ -279,6 +277,7 @@ grpc_cc_library( deps = [ "grpc_common", "grpc_lb_policy_grpclb", + "grpc_lb_policy_xds", ], ) @@ -294,6 +293,7 @@ grpc_cc_library( deps = [ "grpc_common", "grpc_lb_policy_grpclb_secure", + "grpc_lb_policy_xds_secure", "grpc_secure", "grpc_transport_chttp2_client_secure", "grpc_transport_chttp2_server_secure", @@ -1038,6 +1038,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_factory.cc", "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", + "src/core/ext/filters/client_channel/health/health_check_client.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_proxy.cc", "src/core/ext/filters/client_channel/lb_policy.cc", @@ -1060,6 +1061,7 @@ grpc_cc_library( "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", @@ -1087,6 +1089,7 @@ grpc_cc_library( "orphanable", "ref_counted", "ref_counted_ptr", + "health_proto", ], ) @@ -1199,6 +1202,38 @@ grpc_cc_library( ) grpc_cc_library( + name = "health_proto", + srcs = [ + "src/core/ext/filters/client_channel/health/health.pb.c", + ], + hdrs = [ + "src/core/ext/filters/client_channel/health/health.pb.h", + ], + external_deps = [ + "nanopb", + ], + language = "c++", +) + +grpc_cc_library( + name = "grpclb_proto", + srcs = [ + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + ], + hdrs = [ + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", + ], + external_deps = [ + "nanopb", + ], + language = "c++", +) + +grpc_cc_library( name = "grpc_lb_policy_grpclb", srcs = [ "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc", @@ -1206,9 +1241,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", ], hdrs = [ "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", @@ -1216,9 +1248,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", ], external_deps = [ "nanopb", @@ -1228,6 +1257,7 @@ grpc_cc_library( "grpc_base", "grpc_client_channel", "grpc_resolver_fake", + "grpclb_proto", ], ) @@ -1239,9 +1269,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", ], hdrs = [ "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h", @@ -1249,9 +1276,6 @@ grpc_cc_library( "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", ], external_deps = [ "nanopb", @@ -1262,30 +1286,23 @@ grpc_cc_library( "grpc_client_channel", "grpc_resolver_fake", "grpc_secure", + "grpclb_proto", ], ) grpc_cc_library( name = "grpc_lb_policy_xds", srcs = [ - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", ], hdrs = [ - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h", ], external_deps = [ "nanopb", @@ -1295,30 +1312,23 @@ grpc_cc_library( "grpc_base", "grpc_client_channel", "grpc_resolver_fake", + "grpclb_proto", ], ) grpc_cc_library( name = "grpc_lb_policy_xds_secure", srcs = [ - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", ], hdrs = [ - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h", ], external_deps = [ "nanopb", @@ -1329,6 +1339,7 @@ grpc_cc_library( "grpc_client_channel", "grpc_resolver_fake", "grpc_secure", + "grpclb_proto", ], ) @@ -1570,11 +1581,14 @@ grpc_cc_library( "src/core/lib/security/credentials/oauth2/oauth2_credentials.cc", "src/core/lib/security/credentials/plugin/plugin_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", - "src/core/lib/security/security_connector/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", "src/core/lib/security/security_connector/load_system_roots_linux.cc", - "src/core/lib/security/security_connector/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.cc", "src/core/lib/security/security_connector/security_connector.cc", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", "src/core/lib/security/transport/security_handshaker.cc", @@ -1586,6 +1600,7 @@ grpc_cc_library( ], hdrs = [ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/lib/security/context/security_context.h", "src/core/lib/security/credentials/alts/alts_credentials.h", "src/core/lib/security/credentials/composite/composite_credentials.h", @@ -1600,11 +1615,14 @@ grpc_cc_library( "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.h", - "src/core/lib/security/security_connector/alts_security_connector.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_linux.h", - "src/core/lib/security/security_connector/local_security_connector.h", + "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", @@ -1990,6 +2008,7 @@ grpc_cc_library( deps = [ "grpc", "grpc++_codegen_base", + "health_proto", ], ) @@ -2002,6 +2021,7 @@ grpc_cc_library( deps = [ "grpc++_codegen_base", "grpc_unsecure", + "health_proto", ], ) @@ -2204,7 +2224,6 @@ grpc_cc_library( grpc_cc_library( name = "grpc_opencensus_plugin", srcs = [ - "src/core/ext/filters/census/grpc_context.cc", "src/cpp/ext/filters/census/channel_filter.cc", "src/cpp/ext/filters/census/client_filter.cc", "src/cpp/ext/filters/census/context.cc", diff --git a/CMakeLists.txt b/CMakeLists.txt index e8de383ab1..23ef8b3b64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -488,7 +488,6 @@ add_dependencies(buildtests_c h2_sockpair_1byte_nosec_test) if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) add_dependencies(buildtests_c h2_uds_nosec_test) endif() -add_dependencies(buildtests_c inproc_nosec_test) add_dependencies(buildtests_c alts_credentials_fuzzer_one_entry) add_dependencies(buildtests_c api_fuzzer_one_entry) add_dependencies(buildtests_c client_fuzzer_one_entry) @@ -1170,11 +1169,14 @@ add_library(grpc src/core/lib/security/credentials/oauth2/oauth2_credentials.cc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc - src/core/lib/security/security_connector/alts_security_connector.cc + src/core/lib/security/security_connector/alts/alts_security_connector.cc + src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc src/core/lib/security/security_connector/load_system_roots_linux.cc - src/core/lib/security/security_connector/local_security_connector.cc + src/core/lib/security/security_connector/local/local_security_connector.cc src/core/lib/security/security_connector/security_connector.cc + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + src/core/lib/security/security_connector/ssl_utils.cc src/core/lib/security/transport/client_auth_filter.cc src/core/lib/security/transport/secure_endpoint.cc src/core/lib/security/transport/security_handshaker.cc @@ -1229,6 +1231,7 @@ add_library(grpc src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1245,6 +1248,7 @@ add_library(grpc src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c src/core/tsi/alts_transport_security.cc src/core/tsi/fake_transport_security.cc src/core/tsi/local_transport_security.cc @@ -1264,10 +1268,14 @@ add_library(grpc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc + src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -1575,6 +1583,7 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1591,6 +1600,10 @@ add_library(grpc_cronet src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/lib/http/httpcli_security_connector.cc src/core/lib/security/context/security_context.cc src/core/lib/security/credentials/alts/alts_credentials.cc @@ -1608,11 +1621,14 @@ add_library(grpc_cronet src/core/lib/security/credentials/oauth2/oauth2_credentials.cc src/core/lib/security/credentials/plugin/plugin_credentials.cc src/core/lib/security/credentials/ssl/ssl_credentials.cc - src/core/lib/security/security_connector/alts_security_connector.cc + src/core/lib/security/security_connector/alts/alts_security_connector.cc + src/core/lib/security/security_connector/fake/fake_security_connector.cc src/core/lib/security/security_connector/load_system_roots_fallback.cc src/core/lib/security/security_connector/load_system_roots_linux.cc - src/core/lib/security/security_connector/local_security_connector.cc + src/core/lib/security/security_connector/local/local_security_connector.cc src/core/lib/security/security_connector/security_connector.cc + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + src/core/lib/security/security_connector/ssl_utils.cc src/core/lib/security/transport/client_auth_filter.cc src/core/lib/security/transport/secure_endpoint.cc src/core/lib/security/transport/security_handshaker.cc @@ -1652,9 +1668,6 @@ add_library(grpc_cronet src/core/tsi/alts/handshaker/altscontext.pb.c src/core/tsi/alts/handshaker/handshaker.pb.c src/core/tsi/alts/handshaker/transport_security_common.pb.c - third_party/nanopb/pb_common.c - third_party/nanopb/pb_decode.c - third_party/nanopb/pb_encode.c src/core/tsi/transport_security.cc src/core/ext/transport/chttp2/client/insecure/channel_create.cc src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc @@ -1942,6 +1955,7 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -1958,6 +1972,10 @@ add_library(grpc_test_util src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/ext/transport/chttp2/transport/bin_decoder.cc src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -2256,6 +2274,7 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2272,6 +2291,10 @@ add_library(grpc_test_util_unsecure src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/ext/transport/chttp2/transport/bin_decoder.cc src/core/ext/transport/chttp2/transport/bin_encoder.cc src/core/ext/transport/chttp2/transport/chttp2_plugin.cc @@ -2583,6 +2606,7 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -2599,6 +2623,10 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/subchannel_index.cc src/core/ext/filters/client_channel/uri_parser.cc src/core/ext/filters/deadline/deadline_filter.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/core/ext/transport/inproc/inproc_plugin.cc src/core/ext/transport/inproc/inproc_transport.cc src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -2620,9 +2648,10 @@ add_library(grpc_unsecure src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c - third_party/nanopb/pb_common.c - third_party/nanopb/pb_decode.c - third_party/nanopb/pb_encode.c + src/core/ext/filters/client_channel/lb_policy/xds/xds.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc + src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc src/core/ext/filters/census/grpc_context.cc @@ -2849,7 +2878,6 @@ add_library(grpc++ src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/health.pb.c src/cpp/server/health/health_check_service.cc src/cpp/server/health/health_check_service_server_builder_option.cc src/cpp/server/server_builder.cc @@ -2862,6 +2890,10 @@ add_library(grpc++ src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/cpp/codegen/codegen_init.cc ) @@ -3210,7 +3242,6 @@ add_library(grpc++_cronet src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/health.pb.c src/cpp/server/health/health_check_service.cc src/cpp/server/health/health_check_service_server_builder_option.cc src/cpp/server/server_builder.cc @@ -3223,6 +3254,10 @@ add_library(grpc++_cronet src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/cpp/codegen/codegen_init.cc src/core/ext/transport/chttp2/client/insecure/channel_create.cc src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc @@ -3413,6 +3448,7 @@ add_library(grpc++_cronet src/core/ext/filters/client_channel/client_channel_factory.cc src/core/ext/filters/client_channel/client_channel_plugin.cc src/core/ext/filters/client_channel/connector.cc + src/core/ext/filters/client_channel/health/health_check_client.cc src/core/ext/filters/client_channel/http_connect_handshaker.cc src/core/ext/filters/client_channel/http_proxy.cc src/core/ext/filters/client_channel/lb_policy.cc @@ -4333,7 +4369,6 @@ add_library(grpc++_unsecure src/cpp/server/create_default_thread_pool.cc src/cpp/server/dynamic_thread_pool.cc src/cpp/server/health/default_health_check_service.cc - src/cpp/server/health/health.pb.c src/cpp/server/health/health_check_service.cc src/cpp/server/health/health_check_service_server_builder_option.cc src/cpp/server/server_builder.cc @@ -4346,6 +4381,10 @@ add_library(grpc++_unsecure src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time_cc.cc + src/core/ext/filters/client_channel/health/health.pb.c + third_party/nanopb/pb_common.c + third_party/nanopb/pb_decode.c + third_party/nanopb/pb_encode.c src/cpp/codegen/codegen_init.cc ) @@ -17590,42 +17629,6 @@ endif() endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) -add_executable(inproc_nosec_test - test/core/end2end/fixtures/inproc.cc -) - - -target_include_directories(inproc_nosec_test - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include - PRIVATE ${_gRPC_SSL_INCLUDE_DIR} - PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR} - PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR} - PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR} - PRIVATE ${_gRPC_CARES_INCLUDE_DIR} - PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR} - PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR} - PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR} -) - -target_link_libraries(inproc_nosec_test - ${_gRPC_ALLTARGETS_LIBRARIES} - end2end_nosec_tests - grpc_test_util_unsecure - grpc_unsecure - gpr_test_util - gpr -) - - # avoid dependency on libstdc++ - if (_gRPC_CORE_NOSTDCXX_FLAGS) - set_target_properties(inproc_nosec_test PROPERTIES LINKER_LANGUAGE C) - target_compile_options(inproc_nosec_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>) - endif() - -endif (gRPC_BUILD_TESTS) -if (gRPC_BUILD_TESTS) - add_executable(resolver_component_test_unsecure test/cpp/naming/resolver_component_test.cc third_party/googletest/googletest/src/gtest-all.cc @@ -1343,7 +1343,6 @@ h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test h2_sockpair_1byte_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test h2_uds_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_nosec_test -inproc_nosec_test: $(BINDIR)/$(CONFIG)/inproc_nosec_test resolver_component_test_unsecure: $(BINDIR)/$(CONFIG)/resolver_component_test_unsecure resolver_component_test: $(BINDIR)/$(CONFIG)/resolver_component_test resolver_component_tests_runner_invoker_unsecure: $(BINDIR)/$(CONFIG)/resolver_component_tests_runner_invoker_unsecure @@ -1602,7 +1601,6 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_nosec_test \ $(BINDIR)/$(CONFIG)/h2_uds_nosec_test \ - $(BINDIR)/$(CONFIG)/inproc_nosec_test \ $(BINDIR)/$(CONFIG)/alts_credentials_fuzzer_one_entry \ $(BINDIR)/$(CONFIG)/api_fuzzer_one_entry \ $(BINDIR)/$(CONFIG)/client_fuzzer_one_entry \ @@ -3638,11 +3636,14 @@ LIBGRPC_SRC = \ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ - src/core/lib/security/security_connector/alts_security_connector.cc \ + src/core/lib/security/security_connector/alts/alts_security_connector.cc \ + src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ - src/core/lib/security/security_connector/local_security_connector.cc \ + src/core/lib/security/security_connector/local/local_security_connector.cc \ src/core/lib/security/security_connector/security_connector.cc \ + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ + src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -3697,6 +3698,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -3713,6 +3715,7 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ @@ -3732,10 +3735,14 @@ LIBGRPC_SRC = \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \ + src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \ src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ @@ -4037,6 +4044,7 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4053,6 +4061,10 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/lib/http/httpcli_security_connector.cc \ src/core/lib/security/context/security_context.cc \ src/core/lib/security/credentials/alts/alts_credentials.cc \ @@ -4070,11 +4082,14 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ - src/core/lib/security/security_connector/alts_security_connector.cc \ + src/core/lib/security/security_connector/alts/alts_security_connector.cc \ + src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ - src/core/lib/security/security_connector/local_security_connector.cc \ + src/core/lib/security/security_connector/local/local_security_connector.cc \ src/core/lib/security/security_connector/security_connector.cc \ + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ + src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -4114,9 +4129,6 @@ LIBGRPC_CRONET_SRC = \ src/core/tsi/alts/handshaker/altscontext.pb.c \ src/core/tsi/alts/handshaker/handshaker.pb.c \ src/core/tsi/alts/handshaker/transport_security_common.pb.c \ - third_party/nanopb/pb_common.c \ - third_party/nanopb/pb_decode.c \ - third_party/nanopb/pb_encode.c \ src/core/tsi/transport_security.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \ @@ -4397,6 +4409,7 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4413,6 +4426,10 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/ext/transport/chttp2/transport/bin_decoder.cc \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ @@ -4697,6 +4714,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -4713,6 +4731,10 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/ext/transport/chttp2/transport/bin_decoder.cc \ src/core/ext/transport/chttp2/transport/bin_encoder.cc \ src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \ @@ -4997,6 +5019,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -5013,6 +5036,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/core/ext/transport/inproc/inproc_plugin.cc \ src/core/ext/transport/inproc/inproc_transport.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ @@ -5034,9 +5061,10 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ - third_party/nanopb/pb_common.c \ - third_party/nanopb/pb_decode.c \ - third_party/nanopb/pb_encode.c \ + src/core/ext/filters/client_channel/lb_policy/xds/xds.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \ src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ src/core/ext/filters/census/grpc_context.cc \ @@ -5228,7 +5256,6 @@ LIBGRPC++_SRC = \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ - src/cpp/server/health/health.pb.c \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/server_builder.cc \ @@ -5241,6 +5268,10 @@ LIBGRPC++_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/cpp/codegen/codegen_init.cc \ PUBLIC_HEADERS_CXX += \ @@ -5599,7 +5630,6 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ - src/cpp/server/health/health.pb.c \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/server_builder.cc \ @@ -5612,6 +5642,10 @@ LIBGRPC++_CRONET_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/cpp/codegen/codegen_init.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create.cc \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \ @@ -5802,6 +5836,7 @@ LIBGRPC++_CRONET_SRC = \ src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -6687,7 +6722,6 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/server/create_default_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/health/default_health_check_service.cc \ - src/cpp/server/health/health.pb.c \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/server_builder.cc \ @@ -6700,6 +6734,10 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ + third_party/nanopb/pb_common.c \ + third_party/nanopb/pb_decode.c \ + third_party/nanopb/pb_encode.c \ src/cpp/codegen/codegen_init.cc \ PUBLIC_HEADERS_CXX += \ @@ -23984,26 +24022,6 @@ ifneq ($(NO_DEPS),true) endif -INPROC_NOSEC_TEST_SRC = \ - test/core/end2end/fixtures/inproc.cc \ - -INPROC_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INPROC_NOSEC_TEST_SRC)))) - - -$(BINDIR)/$(CONFIG)/inproc_nosec_test: $(INPROC_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - $(E) "[LD] Linking $@" - $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(INPROC_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/inproc_nosec_test - -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/inproc.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a - -deps_inproc_nosec_test: $(INPROC_NOSEC_TEST_OBJS:.o=.dep) - -ifneq ($(NO_DEPS),true) --include $(INPROC_NOSEC_TEST_OBJS:.o=.dep) -endif - - RESOLVER_COMPONENT_TEST_UNSECURE_SRC = \ test/cpp/naming/resolver_component_test.cc \ @@ -24804,6 +24822,7 @@ ifneq ($(OPENSSL_DEP),) # installing headers to their final destination on the drive. We need this # otherwise parallel compilation will fail if a source is compiled first. src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc: $(OPENSSL_DEP) +src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc: $(OPENSSL_DEP) src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc: $(OPENSSL_DEP) src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc: $(OPENSSL_DEP) src/core/ext/transport/cronet/client/secure/cronet_channel_create.cc: $(OPENSSL_DEP) @@ -24833,11 +24852,14 @@ src/core/lib/security/credentials/local/local_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/oauth2/oauth2_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/plugin/plugin_credentials.cc: $(OPENSSL_DEP) src/core/lib/security/credentials/ssl/ssl_credentials.cc: $(OPENSSL_DEP) -src/core/lib/security/security_connector/alts_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/alts/alts_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/fake/fake_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_fallback.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/load_system_roots_linux.cc: $(OPENSSL_DEP) -src/core/lib/security/security_connector/local_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/local/local_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/security_connector/security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/ssl/ssl_security_connector.cc: $(OPENSSL_DEP) +src/core/lib/security/security_connector/ssl_utils.cc: $(OPENSSL_DEP) src/core/lib/security/transport/client_auth_filter.cc: $(OPENSSL_DEP) src/core/lib/security/transport/secure_endpoint.cc: $(OPENSSL_DEP) src/core/lib/security/transport/security_handshaker.cc: $(OPENSSL_DEP) diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl index 4096720569..03bed3593d 100644 --- a/bazel/grpc_deps.bzl +++ b/bazel/grpc_deps.bzl @@ -169,12 +169,12 @@ def grpc_deps(): if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules(): native.http_archive( name = "com_github_bazelbuild_bazeltoolchains", - strip_prefix = "bazel-toolchains-cdea5b8675914d0a354d89f108de5d28e54e0edc", + strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz", - "https://github.com/bazelbuild/bazel-toolchains/archive/cdea5b8675914d0a354d89f108de5d28e54e0edc.tar.gz", + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/280edaa6f93623074513d2b426068de42e62ea4d.tar.gz", ], - sha256 = "cefb6ccf86ca592baaa029bcef04148593c0efe8f734542f10293ea58f170715", + sha256 = "50c9df51f80cdf9ff8f2bc27620c155526b9ba67be95e8a686f32ff8898a06e2", ) if "io_opencensus_cpp" not in native.existing_rules(): diff --git a/build.yaml b/build.yaml index b2011562a2..d8d51c1b94 100644 --- a/build.yaml +++ b/build.yaml @@ -572,6 +572,7 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_channelz.h - src/core/ext/filters/client_channel/client_channel_factory.h - src/core/ext/filters/client_channel/connector.h + - src/core/ext/filters/client_channel/health/health_check_client.h - src/core/ext/filters/client_channel/http_connect_handshaker.h - src/core/ext/filters/client_channel/http_proxy.h - src/core/ext/filters/client_channel/lb_policy.h @@ -596,6 +597,7 @@ filegroups: - src/core/ext/filters/client_channel/client_channel_factory.cc - src/core/ext/filters/client_channel/client_channel_plugin.cc - src/core/ext/filters/client_channel/connector.cc + - src/core/ext/filters/client_channel/health/health_check_client.cc - src/core/ext/filters/client_channel/http_connect_handshaker.cc - src/core/ext/filters/client_channel/http_proxy.cc - src/core/ext/filters/client_channel/lb_policy.cc @@ -615,6 +617,7 @@ filegroups: uses: - grpc_base - grpc_deadline_filter + - health_proto - name: grpc_codegen public_headers: - include/grpc/impl/codegen/byte_buffer.h @@ -655,24 +658,19 @@ filegroups: - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h src: - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c plugin: grpc_lb_policy_grpclb uses: - grpc_base - grpc_client_channel - nanopb - grpc_resolver_fake + - grpclb_proto - name: grpc_lb_policy_grpclb_secure headers: - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h @@ -680,18 +678,12 @@ filegroups: - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h src: - src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc - src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c plugin: grpc_lb_policy_grpclb uses: - grpc_base @@ -699,6 +691,7 @@ filegroups: - grpc_client_channel - nanopb - grpc_resolver_fake + - grpclb_proto - name: grpc_lb_policy_pick_first src: - src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -717,48 +710,33 @@ filegroups: - grpc_lb_subchannel_list - name: grpc_lb_policy_xds headers: - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h - - src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h - - src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h - src/core/ext/filters/client_channel/lb_policy/xds/xds.h - src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h - src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h + - src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h src: - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c - - src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc - - src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc - src/core/ext/filters/client_channel/lb_policy/xds/xds.cc - src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc - src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc + - src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc plugin: grpc_lb_policy_xds uses: - grpc_base - grpc_client_channel - nanopb - grpc_resolver_fake + - grpclb_proto - name: grpc_lb_policy_xds_secure headers: - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h - - src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h - - src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h - src/core/ext/filters/client_channel/lb_policy/xds/xds.h - src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h - src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h + - src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h src: - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c - - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c - - src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc - - src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc - src/core/ext/filters/client_channel/lb_policy/xds/xds.cc - src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc - src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc + - src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc plugin: grpc_lb_policy_xds uses: - grpc_base @@ -766,6 +744,7 @@ filegroups: - grpc_client_channel - nanopb - grpc_resolver_fake + - grpclb_proto - name: grpc_lb_subchannel_list headers: - src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -833,6 +812,7 @@ filegroups: - include/grpc/grpc_security.h headers: - src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h + - src/core/ext/filters/client_channel/lb_policy/xds/xds.h - src/core/lib/security/context/security_context.h - src/core/lib/security/credentials/alts/alts_credentials.h - src/core/lib/security/credentials/composite/composite_credentials.h @@ -847,11 +827,14 @@ filegroups: - src/core/lib/security/credentials/oauth2/oauth2_credentials.h - src/core/lib/security/credentials/plugin/plugin_credentials.h - src/core/lib/security/credentials/ssl/ssl_credentials.h - - src/core/lib/security/security_connector/alts_security_connector.h + - src/core/lib/security/security_connector/alts/alts_security_connector.h + - src/core/lib/security/security_connector/fake/fake_security_connector.h - src/core/lib/security/security_connector/load_system_roots.h - src/core/lib/security/security_connector/load_system_roots_linux.h - - src/core/lib/security/security_connector/local_security_connector.h + - src/core/lib/security/security_connector/local/local_security_connector.h - src/core/lib/security/security_connector/security_connector.h + - src/core/lib/security/security_connector/ssl/ssl_security_connector.h + - src/core/lib/security/security_connector/ssl_utils.h - src/core/lib/security/transport/auth_filters.h - src/core/lib/security/transport/secure_endpoint.h - src/core/lib/security/transport/security_handshaker.h @@ -876,11 +859,14 @@ filegroups: - src/core/lib/security/credentials/oauth2/oauth2_credentials.cc - src/core/lib/security/credentials/plugin/plugin_credentials.cc - src/core/lib/security/credentials/ssl/ssl_credentials.cc - - src/core/lib/security/security_connector/alts_security_connector.cc + - src/core/lib/security/security_connector/alts/alts_security_connector.cc + - src/core/lib/security/security_connector/fake/fake_security_connector.cc - src/core/lib/security/security_connector/load_system_roots_fallback.cc - src/core/lib/security/security_connector/load_system_roots_linux.cc - - src/core/lib/security/security_connector/local_security_connector.cc + - src/core/lib/security/security_connector/local/local_security_connector.cc - src/core/lib/security/security_connector/security_connector.cc + - src/core/lib/security/security_connector/ssl/ssl_security_connector.cc + - src/core/lib/security/security_connector/ssl_utils.cc - src/core/lib/security/transport/client_auth_filter.cc - src/core/lib/security/transport/secure_endpoint.cc - src/core/lib/security/transport/security_handshaker.cc @@ -1119,6 +1105,24 @@ filegroups: uses: - grpc_base - grpc_server_backward_compatibility +- name: grpclb_proto + headers: + - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h + - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h + - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h + src: + - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c + - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c + - src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c + uses: + - nanopb +- name: health_proto + headers: + - src/core/ext/filters/client_channel/health/health.pb.h + src: + - src/core/ext/filters/client_channel/health/health.pb.c + uses: + - nanopb - name: nanopb src: - third_party/nanopb/pb_common.c @@ -1366,7 +1370,6 @@ filegroups: - src/cpp/common/channel_filter.h - src/cpp/server/dynamic_thread_pool.h - src/cpp/server/health/default_health_check_service.h - - src/cpp/server/health/health.pb.h - src/cpp/server/thread_pool_interface.h - src/cpp/thread_manager/thread_manager.h src: @@ -1390,7 +1393,6 @@ filegroups: - src/cpp/server/create_default_thread_pool.cc - src/cpp/server/dynamic_thread_pool.cc - src/cpp/server/health/default_health_check_service.cc - - src/cpp/server/health/health.pb.c - src/cpp/server/health/health_check_service.cc - src/cpp/server/health/health_check_service_server_builder_option.cc - src/cpp/server/server_builder.cc @@ -1409,6 +1411,7 @@ filegroups: - grpc_transport_inproc_headers - grpc++_codegen_base - nanopb_headers + - health_proto - name: grpc++_config_proto language: c++ public_headers: @@ -1514,6 +1517,7 @@ libs: - grpc_transport_chttp2_client_insecure - grpc_transport_inproc - grpc_lb_policy_grpclb_secure + - grpc_lb_policy_xds_secure - grpc_lb_policy_pick_first - grpc_lb_policy_round_robin - grpc_resolver_dns_ares @@ -1593,6 +1597,7 @@ libs: - grpc_resolver_sockaddr - grpc_resolver_fake - grpc_lb_policy_grpclb + - grpc_lb_policy_xds - grpc_lb_policy_pick_first - grpc_lb_policy_round_robin - census @@ -280,11 +280,14 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/security/credentials/oauth2/oauth2_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ - src/core/lib/security/security_connector/alts_security_connector.cc \ + src/core/lib/security/security_connector/alts/alts_security_connector.cc \ + src/core/lib/security/security_connector/fake/fake_security_connector.cc \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ - src/core/lib/security/security_connector/local_security_connector.cc \ + src/core/lib/security/security_connector/local/local_security_connector.cc \ src/core/lib/security/security_connector/security_connector.cc \ + src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ + src/core/lib/security/security_connector/ssl_utils.cc \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ src/core/lib/security/transport/security_handshaker.cc \ @@ -339,6 +342,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/client_channel_factory.cc \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ + src/core/ext/filters/client_channel/health/health_check_client.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_proxy.cc \ src/core/ext/filters/client_channel/lb_policy.cc \ @@ -355,6 +359,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/subchannel_index.cc \ src/core/ext/filters/client_channel/uri_parser.cc \ src/core/ext/filters/deadline/deadline_filter.cc \ + src/core/ext/filters/client_channel/health/health.pb.c \ src/core/tsi/alts_transport_security.cc \ src/core/tsi/fake_transport_security.cc \ src/core/tsi/local_transport_security.cc \ @@ -374,10 +379,14 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc \ + src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c \ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ - src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \ + src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \ src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \ @@ -663,11 +672,13 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/census) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/health) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/pick_first) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/round_robin) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/lb_policy/xds) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/c_ares) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/dns/native) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/filters/client_channel/resolver/fake) @@ -713,6 +724,10 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/plugin) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/credentials/ssl) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/alts) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/fake) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/local) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/security_connector/ssl) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/transport) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/security/util) PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/slice) diff --git a/config.w32 b/config.w32 index 90a51057c4..da1279ccbc 100644 --- a/config.w32 +++ b/config.w32 @@ -255,11 +255,14 @@ if (PHP_GRPC != "no") { "src\\core\\lib\\security\\credentials\\oauth2\\oauth2_credentials.cc " + "src\\core\\lib\\security\\credentials\\plugin\\plugin_credentials.cc " + "src\\core\\lib\\security\\credentials\\ssl\\ssl_credentials.cc " + - "src\\core\\lib\\security\\security_connector\\alts_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\alts\\alts_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\fake\\fake_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_fallback.cc " + "src\\core\\lib\\security\\security_connector\\load_system_roots_linux.cc " + - "src\\core\\lib\\security\\security_connector\\local_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\local\\local_security_connector.cc " + "src\\core\\lib\\security\\security_connector\\security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\ssl\\ssl_security_connector.cc " + + "src\\core\\lib\\security\\security_connector\\ssl_utils.cc " + "src\\core\\lib\\security\\transport\\client_auth_filter.cc " + "src\\core\\lib\\security\\transport\\secure_endpoint.cc " + "src\\core\\lib\\security\\transport\\security_handshaker.cc " + @@ -314,6 +317,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\client_channel_factory.cc " + "src\\core\\ext\\filters\\client_channel\\client_channel_plugin.cc " + "src\\core\\ext\\filters\\client_channel\\connector.cc " + + "src\\core\\ext\\filters\\client_channel\\health\\health_check_client.cc " + "src\\core\\ext\\filters\\client_channel\\http_connect_handshaker.cc " + "src\\core\\ext\\filters\\client_channel\\http_proxy.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy.cc " + @@ -330,6 +334,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " + "src\\core\\ext\\filters\\client_channel\\uri_parser.cc " + "src\\core\\ext\\filters\\deadline\\deadline_filter.cc " + + "src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " + "src\\core\\tsi\\alts_transport_security.cc " + "src\\core\\tsi\\fake_transport_security.cc " + "src\\core\\tsi\\local_transport_security.cc " + @@ -349,10 +354,14 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_channel_secure.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\grpclb_client_stats.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\load_balancer_api.cc " + + "src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google\\protobuf\\duration.pb.c " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google\\protobuf\\timestamp.pb.c " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\load_balancer.pb.c " + - "src\\core\\ext\\filters\\client_channel\\resolver\\fake\\fake_resolver.cc " + + "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds.cc " + + "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_channel_secure.cc " + + "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_client_stats.cc " + + "src\\core\\ext\\filters\\client_channel\\lb_policy\\xds\\xds_load_balancer_api.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first\\pick_first.cc " + "src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin\\round_robin.cc " + "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " + @@ -668,6 +677,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\census"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\health"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto"); @@ -678,6 +688,7 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\grpclb\\proto\\grpc\\lb\\v1\\google\\protobuf"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\pick_first"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\round_robin"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\lb_policy\\xds"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares"); @@ -729,6 +740,10 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\plugin"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\credentials\\ssl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\alts"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\fake"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\local"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\security_connector\\ssl"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\transport"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\security\\util"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\lib\\slice"); diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md index bdd00ca363..a354dad863 100644 --- a/doc/PROTOCOL-HTTP2.md +++ b/doc/PROTOCOL-HTTP2.md @@ -92,7 +92,7 @@ The repeated sequence of **Length-Prefixed-Message** items is delivered in DATA * **Length-Prefixed-Message** → Compressed-Flag Message-Length Message * <a name="compressed-flag"></a>**Compressed-Flag** → 0 / 1 # encoded as 1 byte unsigned integer -* **Message-Length** → {_length of Message_} # encoded as 4 byte unsigned integer +* **Message-Length** → {_length of Message_} # encoded as 4 byte unsigned integer (big endian) * **Message** → \*{binary octet} A **Compressed-Flag** value of 1 indicates that the binary octet sequence of **Message** is compressed using the mechanism declared by the **Message-Encoding** header. A value of 0 indicates that no encoding of **Message** bytes has occurred. Compression contexts are NOT maintained over message boundaries, implementations must create a new context for each message in the stream. If the **Message-Encoding** header is omitted then the **Compressed-Flag** must be 0. diff --git a/doc/combiner-explainer.md b/doc/core/combiner-explainer.md index 9e9d077273..9e9d077273 100644 --- a/doc/combiner-explainer.md +++ b/doc/core/combiner-explainer.md diff --git a/doc/epoll-polling-engine.md b/doc/core/epoll-polling-engine.md index 1f5d855743..1f5d855743 100644 --- a/doc/epoll-polling-engine.md +++ b/doc/core/epoll-polling-engine.md diff --git a/doc/images/new_epoll_impl.png b/doc/core/images/new_epoll_impl.png Binary files differindex 9ca1f49cbd..9ca1f49cbd 100644 --- a/doc/images/new_epoll_impl.png +++ b/doc/core/images/new_epoll_impl.png diff --git a/doc/images/old_epoll_impl.png b/doc/core/images/old_epoll_impl.png Binary files differindex 7ac3df8367..7ac3df8367 100644 --- a/doc/images/old_epoll_impl.png +++ b/doc/core/images/old_epoll_impl.png diff --git a/doc/environment_variables.md b/doc/environment_variables.md index b472f7e126..1eb850e976 100644 --- a/doc/environment_variables.md +++ b/doc/environment_variables.md @@ -52,6 +52,7 @@ some configuration as environment variables that can be set. traces epoll-fd creation/close calls for epollex polling engine - glb - traces the grpclb load balancer - handshaker - traces handshaking state + - health_check_client - traces health checking client code - http - traces state in the http2 transport engine - http2_stream_state - traces all http2 stream state mutations. - http1 - traces HTTP/1.x operations performed by gRPC diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py new file mode 100644 index 0000000000..7eda8c9066 --- /dev/null +++ b/examples/python/helloworld/greeter_client_with_options.py @@ -0,0 +1,44 @@ +# Copyright 2018 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. +"""The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters.""" + +from __future__ import print_function + +import grpc + +import helloworld_pb2 +import helloworld_pb2_grpc + + +def run(): + # NOTE(gRPC Python Team): .close() is possible on a channel and should be + # used in circumstances in which the with statement does not fit the needs + # of the code. + # + # For more channel options, please see https://grpc.io/grpc/core/group__grpc__arg__keys.html + with grpc.insecure_channel( + target='localhost:50051', + options=[('grpc.lb_policy_name', 'pick_first'), + ('grpc.enable_retries', 0), ('grpc.keepalive_timeout_ms', + 10000)]) as channel: + stub = helloworld_pb2_grpc.GreeterStub(channel) + # Timeout in seconds. + # Please refer gRPC Python documents for more detail. https://grpc.io/grpc/python/grpc.html + response = stub.SayHello( + helloworld_pb2.HelloRequest(name='you'), timeout=10) + print("Greeter client received: " + response.message) + + +if __name__ == '__main__': + run() diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 3cc19d5908..187551da87 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -173,7 +173,6 @@ Pod::Spec.new do |s| 'src/cpp/common/channel_filter.h', 'src/cpp/server/dynamic_thread_pool.h', 'src/cpp/server/health/default_health_check_service.h', - 'src/cpp/server/health/health.pb.h', 'src/cpp/server/thread_pool_interface.h', 'src/cpp/thread_manager/thread_manager.h', 'src/cpp/client/insecure_credentials.cc', @@ -204,7 +203,6 @@ Pod::Spec.new do |s| 'src/cpp/server/create_default_thread_pool.cc', 'src/cpp/server/dynamic_thread_pool.cc', 'src/cpp/server/health/default_health_check_service.cc', - 'src/cpp/server/health/health.pb.c', 'src/cpp/server/health/health_check_service.cc', 'src/cpp/server/health/health_check_service_server_builder_option.cc', 'src/cpp/server/server_builder.cc', @@ -269,6 +267,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/http/message_compress/message_compress_filter.h', 'src/core/ext/filters/http/server/http_server_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.h', 'src/core/lib/security/context/security_context.h', 'src/core/lib/security/credentials/alts/alts_credentials.h', 'src/core/lib/security/credentials/composite/composite_credentials.h', @@ -283,11 +282,14 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h', 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', - 'src/core/lib/security/security_connector/alts_security_connector.h', + 'src/core/lib/security/security_connector/alts/alts_security_connector.h', + 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', 'src/core/lib/security/security_connector/load_system_roots_linux.h', - 'src/core/lib/security/security_connector/local_security_connector.h', + 'src/core/lib/security/security_connector/local/local_security_connector.h', 'src/core/lib/security/security_connector/security_connector.h', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', + 'src/core/lib/security/security_connector/ssl_utils.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -328,6 +330,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -345,6 +348,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', @@ -495,10 +499,13 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', @@ -516,7 +523,6 @@ Pod::Spec.new do |s| 'src/cpp/common/channel_filter.h', 'src/cpp/server/dynamic_thread_pool.h', 'src/cpp/server/health/default_health_check_service.h', - 'src/cpp/server/health/health.pb.h', 'src/cpp/server/thread_pool_interface.h', 'src/cpp/thread_manager/thread_manager.h', 'src/core/lib/gpr/alloc.h', @@ -680,7 +686,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/lib/debug/trace.h', - 'src/core/ext/transport/inproc/inproc_transport.h' + 'src/core/ext/transport/inproc/inproc_transport.h', + 'src/core/ext/filters/client_channel/health/health.pb.h' end s.subspec 'Protobuf' do |ss| diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8bb2311414..bbd5d7e961 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -276,6 +276,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/http/message_compress/message_compress_filter.h', 'src/core/ext/filters/http/server/http_server_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.h', 'src/core/lib/security/context/security_context.h', 'src/core/lib/security/credentials/alts/alts_credentials.h', 'src/core/lib/security/credentials/composite/composite_credentials.h', @@ -290,11 +291,14 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h', 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', - 'src/core/lib/security/security_connector/alts_security_connector.h', + 'src/core/lib/security/security_connector/alts/alts_security_connector.h', + 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', 'src/core/lib/security/security_connector/load_system_roots_linux.h', - 'src/core/lib/security/security_connector/local_security_connector.h', + 'src/core/lib/security/security_connector/local/local_security_connector.h', 'src/core/lib/security/security_connector/security_connector.h', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', + 'src/core/lib/security/security_connector/ssl_utils.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -335,6 +339,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -352,6 +357,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', @@ -502,10 +508,13 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', @@ -711,11 +720,14 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/security_connector/alts_security_connector.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', 'src/core/lib/security/security_connector/load_system_roots_linux.cc', - 'src/core/lib/security/security_connector/local_security_connector.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -767,6 +779,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -783,6 +796,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', @@ -802,10 +816,14 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc', 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', @@ -877,6 +895,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/http/message_compress/message_compress_filter.h', 'src/core/ext/filters/http/server/http_server_filter.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.h', 'src/core/lib/security/context/security_context.h', 'src/core/lib/security/credentials/alts/alts_credentials.h', 'src/core/lib/security/credentials/composite/composite_credentials.h', @@ -891,11 +910,14 @@ Pod::Spec.new do |s| 'src/core/lib/security/credentials/oauth2/oauth2_credentials.h', 'src/core/lib/security/credentials/plugin/plugin_credentials.h', 'src/core/lib/security/credentials/ssl/ssl_credentials.h', - 'src/core/lib/security/security_connector/alts_security_connector.h', + 'src/core/lib/security/security_connector/alts/alts_security_connector.h', + 'src/core/lib/security/security_connector/fake/fake_security_connector.h', 'src/core/lib/security/security_connector/load_system_roots.h', 'src/core/lib/security/security_connector/load_system_roots_linux.h', - 'src/core/lib/security/security_connector/local_security_connector.h', + 'src/core/lib/security/security_connector/local/local_security_connector.h', 'src/core/lib/security/security_connector/security_connector.h', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.h', + 'src/core/lib/security/security_connector/ssl_utils.h', 'src/core/lib/security/transport/auth_filters.h', 'src/core/lib/security/transport/secure_endpoint.h', 'src/core/lib/security/transport/security_handshaker.h', @@ -936,6 +958,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/client_channel_channelz.h', 'src/core/ext/filters/client_channel/client_channel_factory.h', 'src/core/ext/filters/client_channel/connector.h', + 'src/core/ext/filters/client_channel/health/health_check_client.h', 'src/core/ext/filters/client_channel/http_connect_handshaker.h', 'src/core/ext/filters/client_channel/http_proxy.h', 'src/core/ext/filters/client_channel/lb_policy.h', @@ -953,6 +976,7 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/subchannel_index.h', 'src/core/ext/filters/client_channel/uri_parser.h', 'src/core/ext/filters/deadline/deadline_filter.h', + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/tsi/alts_transport_security.h', 'src/core/tsi/fake_transport_security.h', 'src/core/tsi/local_transport_security.h', @@ -1103,10 +1127,13 @@ Pod::Spec.new do |s| 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h', 'src/core/ext/filters/client_channel/lb_policy/subchannel_list.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h', @@ -1195,6 +1222,9 @@ Pod::Spec.new do |s| 'test/core/util/tracer_util.cc', 'test/core/util/trickle_endpoint.cc', 'test/core/util/cmdline.cc', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'test/core/end2end/data/ssl_test_data.h', 'test/core/security/oauth2_utils.h', 'test/core/end2end/cq_verifier.h', @@ -1216,6 +1246,10 @@ Pod::Spec.new do |s| 'test/core/util/tracer_util.h', 'test/core/util/trickle_endpoint.h', 'test/core/util/cmdline.h', + 'third_party/nanopb/pb.h', + 'third_party/nanopb/pb_common.h', + 'third_party/nanopb/pb_decode.h', + 'third_party/nanopb/pb_encode.h', 'test/core/end2end/end2end_tests.cc', 'test/core/end2end/end2end_test_utils.cc', 'test/core/end2end/tests/authority_not_supported.cc', diff --git a/grpc.gemspec b/grpc.gemspec index 81f93f4419..a3924d0d93 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -208,6 +208,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/http/message_compress/message_compress_filter.h ) s.files += %w( src/core/ext/filters/http/server/http_server_filter.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds.h ) s.files += %w( src/core/lib/security/context/security_context.h ) s.files += %w( src/core/lib/security/credentials/alts/alts_credentials.h ) s.files += %w( src/core/lib/security/credentials/composite/composite_credentials.h ) @@ -222,11 +223,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.h ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.h ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.h ) - s.files += %w( src/core/lib/security/security_connector/alts_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots.h ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_linux.h ) - s.files += %w( src/core/lib/security/security_connector/local_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/local/local_security_connector.h ) s.files += %w( src/core/lib/security/security_connector/security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.h ) + s.files += %w( src/core/lib/security/security_connector/ssl_utils.h ) s.files += %w( src/core/lib/security/transport/auth_filters.h ) s.files += %w( src/core/lib/security/transport/secure_endpoint.h ) s.files += %w( src/core/lib/security/transport/security_handshaker.h ) @@ -271,6 +275,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_channelz.h ) s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.h ) s.files += %w( src/core/ext/filters/client_channel/connector.h ) + s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.h ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.h ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.h ) @@ -288,6 +293,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h ) s.files += %w( src/core/ext/filters/client_channel/uri_parser.h ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.h ) + s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h ) s.files += %w( src/core/tsi/alts_transport_security.h ) s.files += %w( src/core/tsi/fake_transport_security.h ) s.files += %w( src/core/tsi/local_transport_security.h ) @@ -438,10 +444,13 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h ) + s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h ) - s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/subchannel_list.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h ) @@ -647,11 +656,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/security/credentials/oauth2/oauth2_credentials.cc ) s.files += %w( src/core/lib/security/credentials/plugin/plugin_credentials.cc ) s.files += %w( src/core/lib/security/credentials/ssl/ssl_credentials.cc ) - s.files += %w( src/core/lib/security/security_connector/alts_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/alts/alts_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/fake/fake_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_fallback.cc ) s.files += %w( src/core/lib/security/security_connector/load_system_roots_linux.cc ) - s.files += %w( src/core/lib/security/security_connector/local_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/local/local_security_connector.cc ) s.files += %w( src/core/lib/security/security_connector/security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/ssl/ssl_security_connector.cc ) + s.files += %w( src/core/lib/security/security_connector/ssl_utils.cc ) s.files += %w( src/core/lib/security/transport/client_auth_filter.cc ) s.files += %w( src/core/lib/security/transport/secure_endpoint.cc ) s.files += %w( src/core/lib/security/transport/security_handshaker.cc ) @@ -706,6 +718,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/client_channel_factory.cc ) s.files += %w( src/core/ext/filters/client_channel/client_channel_plugin.cc ) s.files += %w( src/core/ext/filters/client_channel/connector.cc ) + s.files += %w( src/core/ext/filters/client_channel/health/health_check_client.cc ) s.files += %w( src/core/ext/filters/client_channel/http_connect_handshaker.cc ) s.files += %w( src/core/ext/filters/client_channel/http_proxy.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc ) @@ -722,6 +735,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc ) s.files += %w( src/core/ext/filters/client_channel/uri_parser.cc ) s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc ) + s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c ) s.files += %w( src/core/tsi/alts_transport_security.cc ) s.files += %w( src/core/tsi/fake_transport_security.cc ) s.files += %w( src/core/tsi/local_transport_security.cc ) @@ -741,10 +755,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc ) + s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c ) - s.files += %w( src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds.cc ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc ) + s.files += %w( src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc ) s.files += %w( src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc ) s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc ) @@ -472,11 +472,14 @@ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/security_connector/alts_security_connector.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', 'src/core/lib/security/security_connector/load_system_roots_linux.cc', - 'src/core/lib/security/security_connector/local_security_connector.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -531,6 +534,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -547,6 +551,7 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', @@ -566,10 +571,14 @@ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc', 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', @@ -785,6 +794,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -801,6 +811,10 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', @@ -1019,6 +1033,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1035,6 +1050,10 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/core/ext/transport/chttp2/transport/bin_decoder.cc', 'src/core/ext/transport/chttp2/transport/bin_encoder.cc', 'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc', @@ -1265,6 +1284,7 @@ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -1281,6 +1301,10 @@ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/core/ext/transport/inproc/inproc_plugin.cc', 'src/core/ext/transport/inproc/inproc_transport.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', @@ -1302,9 +1326,10 @@ 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', - 'third_party/nanopb/pb_common.c', - 'third_party/nanopb/pb_decode.c', - 'third_party/nanopb/pb_encode.c', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc', 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/census/grpc_context.cc', @@ -1379,7 +1404,6 @@ 'src/cpp/server/create_default_thread_pool.cc', 'src/cpp/server/dynamic_thread_pool.cc', 'src/cpp/server/health/default_health_check_service.cc', - 'src/cpp/server/health/health.pb.c', 'src/cpp/server/health/health_check_service.cc', 'src/cpp/server/health/health_check_service_server_builder_option.cc', 'src/cpp/server/server_builder.cc', @@ -1392,6 +1416,10 @@ 'src/cpp/util/status.cc', 'src/cpp/util/string_ref.cc', 'src/cpp/util/time_cc.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/cpp/codegen/codegen_init.cc', ], }, @@ -1526,7 +1554,6 @@ 'src/cpp/server/create_default_thread_pool.cc', 'src/cpp/server/dynamic_thread_pool.cc', 'src/cpp/server/health/default_health_check_service.cc', - 'src/cpp/server/health/health.pb.c', 'src/cpp/server/health/health_check_service.cc', 'src/cpp/server/health/health_check_service_server_builder_option.cc', 'src/cpp/server/server_builder.cc', @@ -1539,6 +1566,10 @@ 'src/cpp/util/status.cc', 'src/cpp/util/string_ref.cc', 'src/cpp/util/time_cc.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', + 'third_party/nanopb/pb_common.c', + 'third_party/nanopb/pb_decode.c', + 'third_party/nanopb/pb_encode.c', 'src/cpp/codegen/codegen_init.cc', ], }, diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 02ab6e8ba4..514d9ddc4b 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -248,10 +248,13 @@ GRPCAPI void* grpc_call_arena_alloc(grpc_call* call, size_t size); appropriate to call grpc_completion_queue_next or grpc_completion_queue_pluck consequent to the failed grpc_call_start_batch call. + If a call to grpc_call_start_batch with an empty batch returns + GRPC_CALL_OK, the tag is put in the completion queue immediately. THREAD SAFETY: access to grpc_call_start_batch in multi-threaded environment needs to be synchronized. As an optimization, you may synchronize batches containing just send operations independently from batches containing just - receive operations. */ + receive operations. Access to grpc_call_start_batch with an empty batch is + thread-compatible. */ GRPCAPI grpc_call_error grpc_call_start_batch(grpc_call* call, const grpc_op* ops, size_t nops, void* tag, void* reserved); diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 4cf13edca9..402e490e34 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -347,6 +347,9 @@ typedef struct { /** If set to non zero, surfaces the user agent string to the server. User agent is surfaced by default. */ #define GRPC_ARG_SURFACE_USER_AGENT "grpc.surface_user_agent" +/** If set, inhibits health checking (which may be enabled via the + * service config.) */ +#define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking" /** gRPC Objective-C channel pooling domain string. */ #define GRPC_ARG_CHANNEL_POOL_DOMAIN "grpc.channel_pooling_domain" /** gRPC Objective-C channel pooling id. */ diff --git a/include/grpcpp/impl/codegen/call.h b/include/grpcpp/impl/codegen/call.h index 7cadea0055..789ea805a3 100644 --- a/include/grpcpp/impl/codegen/call.h +++ b/include/grpcpp/impl/codegen/call.h @@ -624,6 +624,19 @@ class CallOpSet : public CallOpSetInterface, public Op6 { public: CallOpSet() : cq_tag_(this), return_tag_(this), call_(nullptr) {} + + // The copy constructor and assignment operator reset the value of + // cq_tag_ and return_tag_ since those are only meaningful on a specific + // object, not across objects. + CallOpSet(const CallOpSet& other) + : cq_tag_(this), return_tag_(this), call_(other.call_) {} + CallOpSet& operator=(const CallOpSet& other) { + cq_tag_ = this; + return_tag_ = this; + call_ = other.call_; + return *this; + } + void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override { this->Op1::AddOp(ops, nops); this->Op2::AddOp(ops, nops); diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h index ca2f867d04..a9835973ac 100644 --- a/include/grpcpp/impl/codegen/callback_common.h +++ b/include/grpcpp/impl/codegen/callback_common.h @@ -32,16 +32,16 @@ namespace grpc { namespace internal { /// An exception-safe way of invoking a user-specified callback function -template <class Func, class Arg> -void CatchingCallback(Func&& func, Arg&& arg) { +template <class Func, class... Args> +void CatchingCallback(Func&& func, Args&&... args) { #if GRPC_ALLOW_EXCEPTIONS try { - func(arg); + func(std::forward<Args>(args)...); } catch (...) { // nothing to return or change here, just don't crash the library } #else // GRPC_ALLOW_EXCEPTIONS - func(arg); + func(std::forward<Args>(args)...); #endif // GRPC_ALLOW_EXCEPTIONS } diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h index f52f9a53be..a62d48abe7 100644 --- a/include/grpcpp/impl/codegen/completion_queue.h +++ b/include/grpcpp/impl/codegen/completion_queue.h @@ -387,6 +387,7 @@ class ServerCompletionQueue : public CompletionQueue { grpc_cq_polling_type polling_type_; friend class ServerBuilder; + friend class Server; }; } // namespace grpc diff --git a/include/grpcpp/impl/codegen/config_protobuf.h b/include/grpcpp/impl/codegen/config_protobuf.h index 94e593d1ef..8c2e9e6792 100644 --- a/include/grpcpp/impl/codegen/config_protobuf.h +++ b/include/grpcpp/impl/codegen/config_protobuf.h @@ -66,6 +66,12 @@ #define GRPC_CUSTOM_CODEDINPUTSTREAM ::google::protobuf::io::CodedInputStream #endif +#ifndef GRPC_CUSTOM_JSONUTIL +#include <google/protobuf/util/json_util.h> +#define GRPC_CUSTOM_JSONUTIL ::google::protobuf::util +#define GRPC_CUSTOM_UTIL_STATUS ::google::protobuf::util::Status +#endif + namespace grpc { namespace protobuf { @@ -83,6 +89,12 @@ typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor; typedef GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase; typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation; +namespace util { +typedef GRPC_CUSTOM_UTIL_STATUS Status; +} // namespace util + +namespace json = GRPC_CUSTOM_JSONUTIL; + namespace io { typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream; typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream; diff --git a/package.xml b/package.xml index be3fd0d4c2..c90cee8fe9 100644 --- a/package.xml +++ b/package.xml @@ -213,6 +213,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/http/message_compress/message_compress_filter.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/http/server/http_server_filter.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/context/security_context.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/alts/alts_credentials.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/composite/composite_credentials.h" role="src" /> @@ -227,11 +228,14 @@ <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.h" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts/alts_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/fake/fake_security_connector.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots_linux.h" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/local_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/local/local_security_connector.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl/ssl_security_connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl_utils.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.h" role="src" /> @@ -276,6 +280,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_channelz.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" /> @@ -293,6 +298,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.h" role="src" /> <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" /> <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" /> <file baseinstalldir="/" name="src/core/tsi/local_transport_security.h" role="src" /> @@ -443,10 +449,13 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" /> - <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/subchannel_list.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h" role="src" /> @@ -652,11 +661,14 @@ <file baseinstalldir="/" name="src/core/lib/security/credentials/oauth2/oauth2_credentials.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/plugin/plugin_credentials.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/credentials/ssl/ssl_credentials.cc" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/alts/alts_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/fake/fake_security_connector.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots_fallback.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/load_system_roots_linux.cc" role="src" /> - <file baseinstalldir="/" name="src/core/lib/security/security_connector/local_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/local/local_security_connector.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/security_connector/security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl/ssl_security_connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/lib/security/security_connector/ssl_utils.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" /> <file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.cc" role="src" /> @@ -711,6 +723,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_factory.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/client_channel_plugin.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/connector.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health_check_client.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_connect_handshaker.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/http_proxy.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" /> @@ -727,6 +740,7 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/uri_parser.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.c" role="src" /> <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" /> <file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" /> <file baseinstalldir="/" name="src/core/tsi/local_transport_security.cc" role="src" /> @@ -746,10 +760,14 @@ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" /> - <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc" role="src" /> + <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc" role="src" /> <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" /> diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 23da11363b..daf1b89b09 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -131,6 +131,8 @@ typedef struct client_channel_channel_data { grpc_core::UniquePtr<char> info_service_config_json; /* backpointer to grpc_channel's channelz node */ grpc_core::channelz::ClientChannelNode* channelz_channel; + /* caches if the last resolution event contained addresses */ + bool previous_resolution_contained_addresses; } channel_data; typedef struct { @@ -401,6 +403,8 @@ static void request_reresolution_locked(void* arg, grpc_error* error) { chand->lb_policy->SetReresolutionClosureLocked(&args->closure); } +using TraceStringVector = grpc_core::InlinedVector<char*, 3>; + // Creates a new LB policy, replacing any previous one. // If the new policy is created successfully, sets *connectivity_state and // *connectivity_error to its initial connectivity state; otherwise, @@ -408,7 +412,7 @@ static void request_reresolution_locked(void* arg, grpc_error* error) { static void create_new_lb_policy_locked( channel_data* chand, char* lb_policy_name, grpc_connectivity_state* connectivity_state, - grpc_error** connectivity_error) { + grpc_error** connectivity_error, TraceStringVector* trace_strings) { grpc_core::LoadBalancingPolicy::Args lb_policy_args; lb_policy_args.combiner = chand->combiner; lb_policy_args.client_channel_factory = chand->client_channel_factory; @@ -418,11 +422,21 @@ static void create_new_lb_policy_locked( lb_policy_name, lb_policy_args); if (GPR_UNLIKELY(new_lb_policy == nullptr)) { gpr_log(GPR_ERROR, "could not create LB policy \"%s\"", lb_policy_name); + if (chand->channelz_channel != nullptr) { + char* str; + gpr_asprintf(&str, "Could not create LB policy \'%s\'", lb_policy_name); + trace_strings->push_back(str); + } } else { if (grpc_client_channel_trace.enabled()) { gpr_log(GPR_INFO, "chand=%p: created new LB policy \"%s\" (%p)", chand, lb_policy_name, new_lb_policy.get()); } + if (chand->channelz_channel != nullptr) { + char* str; + gpr_asprintf(&str, "Created new LB policy \'%s\'", lb_policy_name); + trace_strings->push_back(str); + } // Swap out the LB policy and update the fds in // chand->interested_parties. if (chand->lb_policy != nullptr) { @@ -497,6 +511,51 @@ get_service_config_from_resolver_result_locked(channel_data* chand) { return grpc_core::UniquePtr<char>(gpr_strdup(service_config_json)); } +static void maybe_add_trace_message_for_address_changes_locked( + channel_data* chand, TraceStringVector* trace_strings) { + int resolution_contains_addresses = false; + const grpc_arg* channel_arg = + grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); + if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) { + grpc_lb_addresses* addresses = + static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p); + if (addresses->num_addresses > 0) { + resolution_contains_addresses = true; + } + } + if (!resolution_contains_addresses && + chand->previous_resolution_contained_addresses) { + trace_strings->push_back(gpr_strdup("Address list became empty")); + } else if (resolution_contains_addresses && + !chand->previous_resolution_contained_addresses) { + trace_strings->push_back(gpr_strdup("Address list became non-empty")); + } + chand->previous_resolution_contained_addresses = + resolution_contains_addresses; +} + +static void concatenate_and_add_channel_trace_locked( + channel_data* chand, TraceStringVector* trace_strings) { + if (!trace_strings->empty()) { + gpr_strvec v; + gpr_strvec_init(&v); + gpr_strvec_add(&v, gpr_strdup("Resolution event: ")); + bool is_first = 1; + for (size_t i = 0; i < trace_strings->size(); ++i) { + if (!is_first) gpr_strvec_add(&v, gpr_strdup(", ")); + is_first = false; + gpr_strvec_add(&v, (*trace_strings)[i]); + } + char* flat; + size_t flat_len = 0; + flat = gpr_strvec_flatten(&v, &flat_len); + chand->channelz_channel->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_new(flat, flat_len, gpr_free)); + gpr_strvec_destroy(&v); + } +} + // Callback invoked when a resolver result is available. static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { channel_data* chand = static_cast<channel_data*>(arg); @@ -518,6 +577,16 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { } // Data used to set the channel's connectivity state. bool set_connectivity_state = true; + // We only want to trace the address resolution in the follow cases: + // (a) Address resolution resulted in service config change. + // (b) Address resolution that causes number of backends to go from + // zero to non-zero. + // (c) Address resolution that causes number of backends to go from + // non-zero to zero. + // (d) Address resolution that causes a new LB policy to be created. + // + // we track a list of strings to eventually be concatenated and traced. + TraceStringVector trace_strings; grpc_connectivity_state connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE; grpc_error* connectivity_error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("No load balancing policy"); @@ -552,11 +621,29 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) { } else { // Instantiate new LB policy. create_new_lb_policy_locked(chand, lb_policy_name.get(), - &connectivity_state, &connectivity_error); + &connectivity_state, &connectivity_error, + &trace_strings); } // Find service config. grpc_core::UniquePtr<char> service_config_json = get_service_config_from_resolver_result_locked(chand); + // Note: It's safe to use chand->info_service_config_json here without + // taking a lock on chand->info_mu, because this function is the + // only thing that modifies its value, and it can only be invoked + // once at any given time. + if (chand->channelz_channel != nullptr) { + if (((service_config_json == nullptr) != + (chand->info_service_config_json == nullptr)) || + (service_config_json != nullptr && + strcmp(service_config_json.get(), + chand->info_service_config_json.get()) != 0)) { + // TODO(ncteisen): might be worth somehow including a snippet of the + // config in the trace, at the risk of bloating the trace logs. + trace_strings.push_back(gpr_strdup("Service config changed")); + } + maybe_add_trace_message_for_address_changes_locked(chand, &trace_strings); + concatenate_and_add_channel_trace_locked(chand, &trace_strings); + } // Swap out the data used by cc_get_channel_info(). gpr_mu_lock(&chand->info_mu); chand->info_lb_policy_name = std::move(lb_policy_name); @@ -725,6 +812,7 @@ static grpc_error* cc_init_channel_elem(grpc_channel_element* elem, arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_ENABLE_RETRIES); chand->enable_retries = grpc_channel_arg_get_bool(arg, true); chand->channelz_channel = nullptr; + chand->previous_resolution_contained_addresses = false; // Record client channel factory. arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_CLIENT_CHANNEL_FACTORY); diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc index bad1ef668c..8e5426081c 100644 --- a/src/core/ext/filters/client_channel/client_channel_channelz.cc +++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc @@ -128,7 +128,8 @@ void SubchannelNode::PopulateConnectivityState(grpc_json* json) { if (subchannel_ == nullptr) { state = GRPC_CHANNEL_SHUTDOWN; } else { - state = grpc_subchannel_check_connectivity(subchannel_, nullptr); + state = grpc_subchannel_check_connectivity( + subchannel_, nullptr, true /* inhibit_health_checking */); } json = grpc_json_create_child(nullptr, json, "state", nullptr, GRPC_JSON_OBJECT, false); diff --git a/src/cpp/server/health/health.pb.c b/src/core/ext/filters/client_channel/health/health.pb.c index 09bd98a3d9..5499c549cc 100644 --- a/src/cpp/server/health/health.pb.c +++ b/src/core/ext/filters/client_channel/health/health.pb.c @@ -1,8 +1,7 @@ /* Automatically generated nanopb constant definitions */ /* Generated by nanopb-0.3.7-dev */ -#include "src/cpp/server/health/health.pb.h" - +#include "src/core/ext/filters/client_channel/health/health.pb.h" /* @@protoc_insertion_point(includes) */ #if PB_PROTO_HEADER_VERSION != 30 #error Regenerate this file with the current version of nanopb generator. diff --git a/src/cpp/server/health/health.pb.h b/src/core/ext/filters/client_channel/health/health.pb.h index 29e1f3bacb..9d54ccd618 100644 --- a/src/cpp/server/health/health.pb.h +++ b/src/core/ext/filters/client_channel/health/health.pb.h @@ -17,11 +17,12 @@ extern "C" { typedef enum _grpc_health_v1_HealthCheckResponse_ServingStatus { grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN = 0, grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING = 1, - grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2 + grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2, + grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN = 3 } grpc_health_v1_HealthCheckResponse_ServingStatus; #define _grpc_health_v1_HealthCheckResponse_ServingStatus_MIN grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING -#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING+1)) +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN +#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN+1)) /* Struct definitions */ typedef struct _grpc_health_v1_HealthCheckRequest { diff --git a/src/core/ext/filters/client_channel/health/health_check_client.cc b/src/core/ext/filters/client_channel/health/health_check_client.cc new file mode 100644 index 0000000000..400d99b07c --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_client.cc @@ -0,0 +1,646 @@ +/* + * + * Copyright 2018 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 <stdint.h> + +#include "src/core/ext/filters/client_channel/health/health_check_client.h" + +#include "pb_decode.h" +#include "pb_encode.h" +#include "src/core/ext/filters/client_channel/health/health.pb.h" +#include "src/core/lib/debug/trace.h" +#include "src/core/lib/gprpp/mutex_lock.h" +#include "src/core/lib/slice/slice_internal.h" +#include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/status_metadata.h" + +#define HEALTH_CHECK_INITIAL_CONNECT_BACKOFF_SECONDS 1 +#define HEALTH_CHECK_RECONNECT_BACKOFF_MULTIPLIER 1.6 +#define HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS 120 +#define HEALTH_CHECK_RECONNECT_JITTER 0.2 + +grpc_core::TraceFlag grpc_health_check_client_trace(false, + "health_check_client"); + +namespace grpc_core { + +// +// HealthCheckClient +// + +HealthCheckClient::HealthCheckClient( + const char* service_name, + RefCountedPtr<ConnectedSubchannel> connected_subchannel, + grpc_pollset_set* interested_parties, + grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode> channelz_node) + : InternallyRefCountedWithTracing<HealthCheckClient>( + &grpc_health_check_client_trace), + service_name_(service_name), + connected_subchannel_(std::move(connected_subchannel)), + interested_parties_(interested_parties), + channelz_node_(std::move(channelz_node)), + retry_backoff_( + BackOff::Options() + .set_initial_backoff( + HEALTH_CHECK_INITIAL_CONNECT_BACKOFF_SECONDS * 1000) + .set_multiplier(HEALTH_CHECK_RECONNECT_BACKOFF_MULTIPLIER) + .set_jitter(HEALTH_CHECK_RECONNECT_JITTER) + .set_max_backoff(HEALTH_CHECK_RECONNECT_MAX_BACKOFF_SECONDS * + 1000)) { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "created HealthCheckClient %p", this); + } + GRPC_CLOSURE_INIT(&retry_timer_callback_, OnRetryTimer, this, + grpc_schedule_on_exec_ctx); + gpr_mu_init(&mu_); + StartCall(); +} + +HealthCheckClient::~HealthCheckClient() { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "destroying HealthCheckClient %p", this); + } + GRPC_ERROR_UNREF(error_); + gpr_mu_destroy(&mu_); +} + +void HealthCheckClient::NotifyOnHealthChange(grpc_connectivity_state* state, + grpc_closure* closure) { + MutexLock lock(&mu_); + GPR_ASSERT(notify_state_ == nullptr); + if (*state != state_) { + *state = state_; + GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_REF(error_)); + return; + } + notify_state_ = state; + on_health_changed_ = closure; +} + +void HealthCheckClient::SetHealthStatus(grpc_connectivity_state state, + grpc_error* error) { + MutexLock lock(&mu_); + SetHealthStatusLocked(state, error); +} + +void HealthCheckClient::SetHealthStatusLocked(grpc_connectivity_state state, + grpc_error* error) { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: setting state=%d error=%s", this, + state, grpc_error_string(error)); + } + if (notify_state_ != nullptr && *notify_state_ != state) { + *notify_state_ = state; + notify_state_ = nullptr; + GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_REF(error)); + on_health_changed_ = nullptr; + } + state_ = state; + GRPC_ERROR_UNREF(error_); + error_ = error; +} + +void HealthCheckClient::Orphan() { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: shutting down", this); + } + { + MutexLock lock(&mu_); + if (on_health_changed_ != nullptr) { + *notify_state_ = GRPC_CHANNEL_SHUTDOWN; + notify_state_ = nullptr; + GRPC_CLOSURE_SCHED(on_health_changed_, GRPC_ERROR_NONE); + on_health_changed_ = nullptr; + } + shutting_down_ = true; + call_state_.reset(); + if (retry_timer_callback_pending_) { + grpc_timer_cancel(&retry_timer_); + } + } + Unref(DEBUG_LOCATION, "orphan"); +} + +void HealthCheckClient::StartCall() { + MutexLock lock(&mu_); + StartCallLocked(); +} + +void HealthCheckClient::StartCallLocked() { + if (shutting_down_) return; + GPR_ASSERT(call_state_ == nullptr); + SetHealthStatusLocked(GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE); + call_state_ = MakeOrphanable<CallState>(Ref(), interested_parties_); + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: created CallState %p", this, + call_state_.get()); + } + call_state_->StartCall(); +} + +void HealthCheckClient::StartRetryTimer() { + MutexLock lock(&mu_); + SetHealthStatusLocked( + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "health check call failed; will retry after backoff")); + grpc_millis next_try = retry_backoff_.NextAttemptTime(); + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: health check call lost...", this); + grpc_millis timeout = next_try - ExecCtx::Get()->Now(); + if (timeout > 0) { + gpr_log(GPR_INFO, + "HealthCheckClient %p: ... will retry in %" PRId64 "ms.", this, + timeout); + } else { + gpr_log(GPR_INFO, "HealthCheckClient %p: ... retrying immediately.", + this); + } + } + // Ref for callback, tracked manually. + Ref(DEBUG_LOCATION, "health_retry_timer").release(); + retry_timer_callback_pending_ = true; + grpc_timer_init(&retry_timer_, next_try, &retry_timer_callback_); +} + +void HealthCheckClient::OnRetryTimer(void* arg, grpc_error* error) { + HealthCheckClient* self = static_cast<HealthCheckClient*>(arg); + { + MutexLock lock(&self->mu_); + self->retry_timer_callback_pending_ = false; + if (!self->shutting_down_ && error == GRPC_ERROR_NONE && + self->call_state_ == nullptr) { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: restarting health check call", + self); + } + self->StartCallLocked(); + } + } + self->Unref(DEBUG_LOCATION, "health_retry_timer"); +} + +// +// protobuf helpers +// + +namespace { + +void EncodeRequest(const char* service_name, + ManualConstructor<SliceBufferByteStream>* send_message) { + grpc_health_v1_HealthCheckRequest request_struct; + request_struct.has_service = true; + snprintf(request_struct.service, sizeof(request_struct.service), "%s", + service_name); + pb_ostream_t ostream; + memset(&ostream, 0, sizeof(ostream)); + pb_encode(&ostream, grpc_health_v1_HealthCheckRequest_fields, + &request_struct); + grpc_slice request_slice = GRPC_SLICE_MALLOC(ostream.bytes_written); + ostream = pb_ostream_from_buffer(GRPC_SLICE_START_PTR(request_slice), + GRPC_SLICE_LENGTH(request_slice)); + GPR_ASSERT(pb_encode(&ostream, grpc_health_v1_HealthCheckRequest_fields, + &request_struct) != 0); + grpc_slice_buffer slice_buffer; + grpc_slice_buffer_init(&slice_buffer); + grpc_slice_buffer_add(&slice_buffer, request_slice); + send_message->Init(&slice_buffer, 0); + grpc_slice_buffer_destroy_internal(&slice_buffer); +} + +// Returns true if healthy. +// If there was an error parsing the response, sets *error and returns false. +bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) { + // If message is empty, assume unhealthy. + if (slice_buffer->length == 0) { + *error = + GRPC_ERROR_CREATE_FROM_STATIC_STRING("health check response was empty"); + return false; + } + // Concatenate the slices to form a single string. + UniquePtr<uint8_t> recv_message_deleter; + uint8_t* recv_message; + if (slice_buffer->count == 1) { + recv_message = GRPC_SLICE_START_PTR(slice_buffer->slices[0]); + } else { + recv_message = static_cast<uint8_t*>(gpr_malloc(slice_buffer->length)); + recv_message_deleter.reset(recv_message); + size_t offset = 0; + for (size_t i = 0; i < slice_buffer->count; ++i) { + memcpy(recv_message + offset, + GRPC_SLICE_START_PTR(slice_buffer->slices[i]), + GRPC_SLICE_LENGTH(slice_buffer->slices[i])); + offset += GRPC_SLICE_LENGTH(slice_buffer->slices[i]); + } + } + // Deserialize message. + grpc_health_v1_HealthCheckResponse response_struct; + pb_istream_t istream = + pb_istream_from_buffer(recv_message, slice_buffer->length); + if (!pb_decode(&istream, grpc_health_v1_HealthCheckResponse_fields, + &response_struct)) { + // Can't parse message; assume unhealthy. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "cannot parse health check response"); + return false; + } + if (!response_struct.has_status) { + // Field not present; assume unhealthy. + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "status field not present in health check response"); + return false; + } + return response_struct.status == + grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING; +} + +} // namespace + +// +// HealthCheckClient::CallState +// + +HealthCheckClient::CallState::CallState( + RefCountedPtr<HealthCheckClient> health_check_client, + grpc_pollset_set* interested_parties) + : InternallyRefCountedWithTracing<CallState>( + &grpc_health_check_client_trace), + health_check_client_(std::move(health_check_client)), + pollent_(grpc_polling_entity_create_from_pollset_set(interested_parties)), + arena_(gpr_arena_create(health_check_client_->connected_subchannel_ + ->GetInitialCallSizeEstimate(0))) { + memset(&call_combiner_, 0, sizeof(call_combiner_)); + grpc_call_combiner_init(&call_combiner_); + memset(context_, 0, sizeof(context_)); + gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(0)); +} + +HealthCheckClient::CallState::~CallState() { + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, "HealthCheckClient %p: destroying CallState %p", + health_check_client_.get(), this); + } + if (call_ != nullptr) GRPC_SUBCHANNEL_CALL_UNREF(call_, "call_ended"); + // Unset the call combiner cancellation closure. This has the + // effect of scheduling the previously set cancellation closure, if + // any, so that it can release any internal references it may be + // holding to the call stack. Also flush the closures on exec_ctx so that + // filters that schedule cancel notification closures on exec_ctx do not + // need to take a ref of the call stack to guarantee closure liveness. + grpc_call_combiner_set_notify_on_cancel(&call_combiner_, nullptr); + grpc_core::ExecCtx::Get()->Flush(); + grpc_call_combiner_destroy(&call_combiner_); + gpr_arena_destroy(arena_); +} + +void HealthCheckClient::CallState::Orphan() { + grpc_call_combiner_cancel(&call_combiner_, GRPC_ERROR_CANCELLED); + Cancel(); +} + +void HealthCheckClient::CallState::StartCall() { + ConnectedSubchannel::CallArgs args = { + &pollent_, + GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH, + gpr_now(GPR_CLOCK_MONOTONIC), // start_time + GRPC_MILLIS_INF_FUTURE, // deadline + arena_, + context_, + &call_combiner_, + 0, // parent_data_size + }; + grpc_error* error = + health_check_client_->connected_subchannel_->CreateCall(args, &call_); + if (error != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, + "HealthCheckClient %p CallState %p: error creating health " + "checking call on subchannel (%s); will retry", + health_check_client_.get(), this, grpc_error_string(error)); + GRPC_ERROR_UNREF(error); + // Schedule instead of running directly, since we must not be + // holding health_check_client_->mu_ when CallEnded() is called. + Ref(DEBUG_LOCATION, "call_end_closure").release(); + GRPC_CLOSURE_SCHED( + GRPC_CLOSURE_INIT(&batch_.handler_private.closure, CallEndedRetry, this, + grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE); + return; + } + // Initialize payload and batch. + memset(&batch_, 0, sizeof(batch_)); + batch_.payload = &payload_; + // on_complete callback takes ref, handled manually. + Ref(DEBUG_LOCATION, "on_complete").release(); + batch_.on_complete = GRPC_CLOSURE_INIT(&on_complete_, OnComplete, this, + grpc_schedule_on_exec_ctx); + // Add send_initial_metadata op. + grpc_metadata_batch_init(&send_initial_metadata_); + error = grpc_metadata_batch_add_head( + &send_initial_metadata_, &path_metadata_storage_, + grpc_mdelem_from_slices( + GRPC_MDSTR_PATH, + GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH)); + GPR_ASSERT(error == GRPC_ERROR_NONE); + payload_.send_initial_metadata.send_initial_metadata = + &send_initial_metadata_; + payload_.send_initial_metadata.send_initial_metadata_flags = 0; + payload_.send_initial_metadata.peer_string = nullptr; + batch_.send_initial_metadata = true; + // Add send_message op. + EncodeRequest(health_check_client_->service_name_, &send_message_); + payload_.send_message.send_message.reset(send_message_.get()); + batch_.send_message = true; + // Add send_trailing_metadata op. + grpc_metadata_batch_init(&send_trailing_metadata_); + payload_.send_trailing_metadata.send_trailing_metadata = + &send_trailing_metadata_; + batch_.send_trailing_metadata = true; + // Add recv_initial_metadata op. + grpc_metadata_batch_init(&recv_initial_metadata_); + payload_.recv_initial_metadata.recv_initial_metadata = + &recv_initial_metadata_; + payload_.recv_initial_metadata.recv_flags = nullptr; + payload_.recv_initial_metadata.trailing_metadata_available = nullptr; + payload_.recv_initial_metadata.peer_string = nullptr; + // recv_initial_metadata_ready callback takes ref, handled manually. + Ref(DEBUG_LOCATION, "recv_initial_metadata_ready").release(); + payload_.recv_initial_metadata.recv_initial_metadata_ready = + GRPC_CLOSURE_INIT(&recv_initial_metadata_ready_, RecvInitialMetadataReady, + this, grpc_schedule_on_exec_ctx); + batch_.recv_initial_metadata = true; + // Add recv_message op. + payload_.recv_message.recv_message = &recv_message_; + // recv_message callback takes ref, handled manually. + Ref(DEBUG_LOCATION, "recv_message_ready").release(); + payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( + &recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx); + batch_.recv_message = true; + // Start batch. + StartBatch(&batch_); + // Initialize recv_trailing_metadata batch. + memset(&recv_trailing_metadata_batch_, 0, + sizeof(recv_trailing_metadata_batch_)); + recv_trailing_metadata_batch_.payload = &payload_; + // Add recv_trailing_metadata op. + grpc_metadata_batch_init(&recv_trailing_metadata_); + payload_.recv_trailing_metadata.recv_trailing_metadata = + &recv_trailing_metadata_; + payload_.recv_trailing_metadata.collect_stats = &collect_stats_; + // This callback signals the end of the call, so it relies on the + // initial ref instead of taking a new ref. When it's invoked, the + // initial ref is released. + payload_.recv_trailing_metadata.recv_trailing_metadata_ready = + GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, + RecvTrailingMetadataReady, this, + grpc_schedule_on_exec_ctx); + recv_trailing_metadata_batch_.recv_trailing_metadata = true; + // Start recv_trailing_metadata batch. + StartBatch(&recv_trailing_metadata_batch_); +} + +void HealthCheckClient::CallState::StartBatchInCallCombiner(void* arg, + grpc_error* error) { + grpc_transport_stream_op_batch* batch = + static_cast<grpc_transport_stream_op_batch*>(arg); + grpc_subchannel_call* call = + static_cast<grpc_subchannel_call*>(batch->handler_private.extra_arg); + grpc_subchannel_call_process_op(call, batch); +} + +void HealthCheckClient::CallState::StartBatch( + grpc_transport_stream_op_batch* batch) { + batch->handler_private.extra_arg = call_; + GRPC_CLOSURE_INIT(&batch->handler_private.closure, StartBatchInCallCombiner, + batch, grpc_schedule_on_exec_ctx); + GRPC_CALL_COMBINER_START(&call_combiner_, &batch->handler_private.closure, + GRPC_ERROR_NONE, "start_subchannel_batch"); +} + +void HealthCheckClient::CallState::OnCancelComplete(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "health_cancel"); + self->Unref(DEBUG_LOCATION, "cancel"); +} + +void HealthCheckClient::CallState::StartCancel(void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + auto* batch = grpc_make_transport_stream_op( + GRPC_CLOSURE_CREATE(OnCancelComplete, self, grpc_schedule_on_exec_ctx)); + batch->cancel_stream = true; + batch->payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED; + grpc_subchannel_call_process_op(self->call_, batch); +} + +void HealthCheckClient::CallState::Cancel() { + if (call_ != nullptr) { + Ref(DEBUG_LOCATION, "cancel").release(); + GRPC_CALL_COMBINER_START( + &call_combiner_, + GRPC_CLOSURE_CREATE(StartCancel, this, grpc_schedule_on_exec_ctx), + GRPC_ERROR_NONE, "health_cancel"); + } +} + +void HealthCheckClient::CallState::OnComplete(void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "on_complete"); + grpc_metadata_batch_destroy(&self->send_initial_metadata_); + grpc_metadata_batch_destroy(&self->send_trailing_metadata_); + self->Unref(DEBUG_LOCATION, "on_complete"); +} + +void HealthCheckClient::CallState::RecvInitialMetadataReady(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_initial_metadata_ready"); + grpc_metadata_batch_destroy(&self->recv_initial_metadata_); + self->Unref(DEBUG_LOCATION, "recv_initial_metadata_ready"); +} + +void HealthCheckClient::CallState::DoneReadingRecvMessage(grpc_error* error) { + recv_message_.reset(); + if (error != GRPC_ERROR_NONE) { + GRPC_ERROR_UNREF(error); + Cancel(); + grpc_slice_buffer_destroy_internal(&recv_message_buffer_); + Unref(DEBUG_LOCATION, "recv_message_ready"); + return; + } + const bool healthy = DecodeResponse(&recv_message_buffer_, &error); + const grpc_connectivity_state state = + healthy ? GRPC_CHANNEL_READY : GRPC_CHANNEL_TRANSIENT_FAILURE; + if (error == GRPC_ERROR_NONE && !healthy) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("backend unhealthy"); + } + health_check_client_->SetHealthStatus(state, error); + gpr_atm_rel_store(&seen_response_, static_cast<gpr_atm>(1)); + grpc_slice_buffer_destroy_internal(&recv_message_buffer_); + // Start another recv_message batch. + // This re-uses the ref we're holding. + // Note: Can't just reuse batch_ here, since we don't know that all + // callbacks from the original batch have completed yet. + memset(&recv_message_batch_, 0, sizeof(recv_message_batch_)); + recv_message_batch_.payload = &payload_; + payload_.recv_message.recv_message = &recv_message_; + payload_.recv_message.recv_message_ready = GRPC_CLOSURE_INIT( + &recv_message_ready_, RecvMessageReady, this, grpc_schedule_on_exec_ctx); + recv_message_batch_.recv_message = true; + StartBatch(&recv_message_batch_); +} + +grpc_error* HealthCheckClient::CallState::PullSliceFromRecvMessage() { + grpc_slice slice; + grpc_error* error = recv_message_->Pull(&slice); + if (error == GRPC_ERROR_NONE) { + grpc_slice_buffer_add(&recv_message_buffer_, slice); + } + return error; +} + +void HealthCheckClient::CallState::ContinueReadingRecvMessage() { + while (recv_message_->Next(SIZE_MAX, &recv_message_ready_)) { + grpc_error* error = PullSliceFromRecvMessage(); + if (error != GRPC_ERROR_NONE) { + DoneReadingRecvMessage(error); + return; + } + if (recv_message_buffer_.length == recv_message_->length()) { + DoneReadingRecvMessage(GRPC_ERROR_NONE); + break; + } + } +} + +void HealthCheckClient::CallState::OnByteStreamNext(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + if (error != GRPC_ERROR_NONE) { + self->DoneReadingRecvMessage(GRPC_ERROR_REF(error)); + return; + } + error = self->PullSliceFromRecvMessage(); + if (error != GRPC_ERROR_NONE) { + self->DoneReadingRecvMessage(error); + return; + } + if (self->recv_message_buffer_.length == self->recv_message_->length()) { + self->DoneReadingRecvMessage(GRPC_ERROR_NONE); + } else { + self->ContinueReadingRecvMessage(); + } +} + +void HealthCheckClient::CallState::RecvMessageReady(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, "recv_message_ready"); + if (self->recv_message_ == nullptr) { + self->Unref(DEBUG_LOCATION, "recv_message_ready"); + return; + } + grpc_slice_buffer_init(&self->recv_message_buffer_); + GRPC_CLOSURE_INIT(&self->recv_message_ready_, OnByteStreamNext, self, + grpc_schedule_on_exec_ctx); + self->ContinueReadingRecvMessage(); + // Ref will continue to be held until we finish draining the byte stream. +} + +void HealthCheckClient::CallState::RecvTrailingMetadataReady( + void* arg, grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + GRPC_CALL_COMBINER_STOP(&self->call_combiner_, + "recv_trailing_metadata_ready"); + // Get call status. + grpc_status_code status = GRPC_STATUS_UNKNOWN; + if (error != GRPC_ERROR_NONE) { + grpc_error_get_status(error, GRPC_MILLIS_INF_FUTURE, &status, + nullptr /* slice */, nullptr /* http_error */, + nullptr /* error_string */); + } else if (self->recv_trailing_metadata_.idx.named.grpc_status != nullptr) { + status = grpc_get_status_code_from_metadata( + self->recv_trailing_metadata_.idx.named.grpc_status->md); + } + if (grpc_health_check_client_trace.enabled()) { + gpr_log(GPR_INFO, + "HealthCheckClient %p CallState %p: health watch failed with " + "status %d", + self->health_check_client_.get(), self, status); + } + // Clean up. + grpc_metadata_batch_destroy(&self->recv_trailing_metadata_); + // For status UNIMPLEMENTED, give up and assume always healthy. + bool retry = true; + if (status == GRPC_STATUS_UNIMPLEMENTED) { + static const char kErrorMessage[] = + "health checking Watch method returned UNIMPLEMENTED; " + "disabling health checks but assuming server is healthy"; + gpr_log(GPR_ERROR, kErrorMessage); + if (self->health_check_client_->channelz_node_ != nullptr) { + self->health_check_client_->channelz_node_->AddTraceEvent( + channelz::ChannelTrace::Error, + grpc_slice_from_static_string(kErrorMessage)); + } + self->health_check_client_->SetHealthStatus(GRPC_CHANNEL_READY, + GRPC_ERROR_NONE); + retry = false; + } + self->CallEnded(retry); +} + +void HealthCheckClient::CallState::CallEndedRetry(void* arg, + grpc_error* error) { + HealthCheckClient::CallState* self = + static_cast<HealthCheckClient::CallState*>(arg); + self->CallEnded(true /* retry */); + self->Unref(DEBUG_LOCATION, "call_end_closure"); +} + +void HealthCheckClient::CallState::CallEnded(bool retry) { + // If this CallState is still in use, this call ended because of a failure, + // so we need to stop using it and optionally create a new one. + // Otherwise, we have deliberately ended this call, and no further action + // is required. + if (this == health_check_client_->call_state_.get()) { + health_check_client_->call_state_.reset(); + if (retry) { + GPR_ASSERT(!health_check_client_->shutting_down_); + if (static_cast<bool>(gpr_atm_acq_load(&seen_response_))) { + // If the call fails after we've gotten a successful response, reset + // the backoff and restart the call immediately. + health_check_client_->retry_backoff_.Reset(); + health_check_client_->StartCall(); + } else { + // If the call failed without receiving any messages, retry later. + health_check_client_->StartRetryTimer(); + } + } + } + Unref(DEBUG_LOCATION, "call_ended"); +} + +} // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/health/health_check_client.h b/src/core/ext/filters/client_channel/health/health_check_client.h new file mode 100644 index 0000000000..7f77348f18 --- /dev/null +++ b/src/core/ext/filters/client_channel/health/health_check_client.h @@ -0,0 +1,173 @@ +/* + * + * Copyright 2018 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_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc.h> +#include <grpc/support/atm.h> +#include <grpc/support/sync.h> + +#include "src/core/ext/filters/client_channel/client_channel_channelz.h" +#include "src/core/ext/filters/client_channel/subchannel.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/arena.h" +#include "src/core/lib/gprpp/orphanable.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/iomgr/call_combiner.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/polling_entity.h" +#include "src/core/lib/iomgr/timer.h" +#include "src/core/lib/transport/byte_stream.h" +#include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/transport.h" + +namespace grpc_core { + +class HealthCheckClient + : public InternallyRefCountedWithTracing<HealthCheckClient> { + public: + HealthCheckClient(const char* service_name, + RefCountedPtr<ConnectedSubchannel> connected_subchannel, + grpc_pollset_set* interested_parties, + RefCountedPtr<channelz::SubchannelNode> channelz_node); + + ~HealthCheckClient(); + + // When the health state changes from *state, sets *state to the new + // value and schedules closure. + // Only one closure can be outstanding at a time. + void NotifyOnHealthChange(grpc_connectivity_state* state, + grpc_closure* closure); + + void Orphan() override; + + private: + // Contains a call to the backend and all the data related to the call. + class CallState : public InternallyRefCountedWithTracing<CallState> { + public: + CallState(RefCountedPtr<HealthCheckClient> health_check_client, + grpc_pollset_set* interested_parties_); + ~CallState(); + + void Orphan() override; + + void StartCall(); + + private: + void Cancel(); + + void StartBatch(grpc_transport_stream_op_batch* batch); + static void StartBatchInCallCombiner(void* arg, grpc_error* error); + + static void CallEndedRetry(void* arg, grpc_error* error); + void CallEnded(bool retry); + + static void OnComplete(void* arg, grpc_error* error); + static void RecvInitialMetadataReady(void* arg, grpc_error* error); + static void RecvMessageReady(void* arg, grpc_error* error); + static void RecvTrailingMetadataReady(void* arg, grpc_error* error); + static void StartCancel(void* arg, grpc_error* error); + static void OnCancelComplete(void* arg, grpc_error* error); + + static void OnByteStreamNext(void* arg, grpc_error* error); + void ContinueReadingRecvMessage(); + grpc_error* PullSliceFromRecvMessage(); + void DoneReadingRecvMessage(grpc_error* error); + + RefCountedPtr<HealthCheckClient> health_check_client_; + grpc_polling_entity pollent_; + + gpr_arena* arena_; + grpc_call_combiner call_combiner_; + grpc_call_context_element context_[GRPC_CONTEXT_COUNT]; + + // The streaming call to the backend. Always non-NULL. + grpc_subchannel_call* call_; + + grpc_transport_stream_op_batch_payload payload_; + grpc_transport_stream_op_batch batch_; + grpc_transport_stream_op_batch recv_message_batch_; + grpc_transport_stream_op_batch recv_trailing_metadata_batch_; + + grpc_closure on_complete_; + + // send_initial_metadata + grpc_metadata_batch send_initial_metadata_; + grpc_linked_mdelem path_metadata_storage_; + + // send_message + ManualConstructor<SliceBufferByteStream> send_message_; + + // send_trailing_metadata + grpc_metadata_batch send_trailing_metadata_; + + // recv_initial_metadata + grpc_metadata_batch recv_initial_metadata_; + grpc_closure recv_initial_metadata_ready_; + + // recv_message + OrphanablePtr<ByteStream> recv_message_; + grpc_closure recv_message_ready_; + grpc_slice_buffer recv_message_buffer_; + gpr_atm seen_response_; + + // recv_trailing_metadata + grpc_metadata_batch recv_trailing_metadata_; + grpc_transport_stream_stats collect_stats_; + grpc_closure recv_trailing_metadata_ready_; + }; + + void StartCall(); + void StartCallLocked(); // Requires holding mu_. + + void StartRetryTimer(); + static void OnRetryTimer(void* arg, grpc_error* error); + + void SetHealthStatus(grpc_connectivity_state state, grpc_error* error); + void SetHealthStatusLocked(grpc_connectivity_state state, + grpc_error* error); // Requires holding mu_. + + const char* service_name_; // Do not own. + RefCountedPtr<ConnectedSubchannel> connected_subchannel_; + grpc_pollset_set* interested_parties_; // Do not own. + RefCountedPtr<channelz::SubchannelNode> channelz_node_; + + gpr_mu mu_; + grpc_connectivity_state state_ = GRPC_CHANNEL_CONNECTING; + grpc_error* error_ = GRPC_ERROR_NONE; + grpc_connectivity_state* notify_state_ = nullptr; + grpc_closure* on_health_changed_ = nullptr; + bool shutting_down_ = false; + + // The data associated with the current health check call. It holds a ref + // to this HealthCheckClient object. + OrphanablePtr<CallState> call_state_; + + // Call retry state. + BackOff retry_backoff_; + grpc_timer retry_timer_; + grpc_closure retry_timer_callback_; + bool retry_timer_callback_pending_ = false; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_HEALTH_HEALTH_CHECK_CLIENT_H */ diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc index 5511df7a27..17e0d26875 100644 --- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc @@ -1699,7 +1699,7 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { // Replace the LB addresses in the channel args that we pass down to // the subchannel. static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES}; - const grpc_arg args_to_add[] = { + grpc_arg args_to_add[3] = { grpc_lb_addresses_create_channel_arg(addresses), // A channel arg indicating if the target is a backend inferred from a // grpclb load balancer. @@ -1708,9 +1708,15 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() { GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER), is_backend_from_grpclb_load_balancer), }; + size_t num_args_to_add = 2; + if (is_backend_from_grpclb_load_balancer) { + args_to_add[2] = grpc_channel_arg_integer_create( + const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + ++num_args_to_add; + } grpc_channel_args* args = grpc_channel_args_copy_and_add_and_remove( args_, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + num_args_to_add); grpc_lb_addresses_destroy(addresses); return args; } diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc index f4dca146f7..eb494486b9 100644 --- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc @@ -359,9 +359,14 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) { "Pick First %p received update with %" PRIuPTR " addresses", this, addresses->num_addresses); } + grpc_arg new_arg = grpc_channel_arg_integer_create( + const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(&args, &new_arg, 1); auto subchannel_list = MakeOrphanable<PickFirstSubchannelList>( this, &grpc_lb_pick_first_trace, addresses, combiner(), - client_channel_factory(), args); + client_channel_factory(), *new_args); + grpc_channel_args_destroy(new_args); if (subchannel_list->num_subchannels() == 0) { // Empty update or no valid subchannels. Unsubscribe from all current // subchannels and put the channel in TRANSIENT_FAILURE. diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h index e0e0e1e638..4ec9e935ed 100644 --- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h @@ -102,8 +102,8 @@ class SubchannelData { // ProcessConnectivityChangeLocked()). grpc_connectivity_state CheckConnectivityStateLocked(grpc_error** error) { GPR_ASSERT(!connectivity_notification_pending_); - pending_connectivity_state_unsafe_ = - grpc_subchannel_check_connectivity(subchannel(), error); + pending_connectivity_state_unsafe_ = grpc_subchannel_check_connectivity( + subchannel(), error, subchannel_list_->inhibit_health_checking()); UpdateConnectedSubchannelLocked(); return pending_connectivity_state_unsafe_; } @@ -216,6 +216,7 @@ class SubchannelList // Accessors. LoadBalancingPolicy* policy() const { return policy_; } TraceFlag* tracer() const { return tracer_; } + bool inhibit_health_checking() const { return inhibit_health_checking_; } // Resets connection backoff of all subchannels. // TODO(roth): We will probably need to rethink this as part of moving @@ -254,6 +255,8 @@ class SubchannelList TraceFlag* tracer_; + bool inhibit_health_checking_; + grpc_combiner* combiner_; // The list of subchannels. @@ -340,7 +343,8 @@ void SubchannelData<SubchannelListType, subchannel_list()->Ref(DEBUG_LOCATION, "connectivity_watch").release(); grpc_subchannel_notify_on_state_change( subchannel_, subchannel_list_->policy()->interested_parties(), - &pending_connectivity_state_unsafe_, &connectivity_changed_closure_); + &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template <typename SubchannelListType, typename SubchannelDataType> @@ -359,7 +363,8 @@ void SubchannelData<SubchannelListType, GPR_ASSERT(connectivity_notification_pending_); grpc_subchannel_notify_on_state_change( subchannel_, subchannel_list_->policy()->interested_parties(), - &pending_connectivity_state_unsafe_, &connectivity_changed_closure_); + &pending_connectivity_state_unsafe_, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template <typename SubchannelListType, typename SubchannelDataType> @@ -390,8 +395,9 @@ void SubchannelData<SubchannelListType, SubchannelDataType>:: subchannel_, reason); } GPR_ASSERT(connectivity_notification_pending_); - grpc_subchannel_notify_on_state_change(subchannel_, nullptr, nullptr, - &connectivity_changed_closure_); + grpc_subchannel_notify_on_state_change( + subchannel_, nullptr, nullptr, &connectivity_changed_closure_, + subchannel_list_->inhibit_health_checking()); } template <typename SubchannelListType, typename SubchannelDataType> @@ -499,8 +505,13 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList( subchannels_.reserve(addresses->num_addresses); // We need to remove the LB addresses in order to be able to compare the // subchannel keys of subchannels from a different batch of addresses. + // We also remove the inhibit-health-checking arg, since we are + // handling that here. + inhibit_health_checking_ = grpc_channel_arg_get_bool( + grpc_channel_args_find(&args, GRPC_ARG_INHIBIT_HEALTH_CHECKING), false); static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS, - GRPC_ARG_LB_ADDRESSES}; + GRPC_ARG_LB_ADDRESSES, + GRPC_ARG_INHIBIT_HEALTH_CHECKING}; // Create a subchannel for each address. grpc_subchannel_args sc_args; for (size_t i = 0; i < addresses->num_addresses; i++) { diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc b/src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc deleted file mode 100644 index d79453d008..0000000000 --- a/src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * Copyright 2018 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <grpc/support/port_platform.h> - -#include "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h" - -#include <grpc/support/atm.h> -#include <grpc/support/log.h> - -#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" -#include "src/core/lib/iomgr/error.h" -#include "src/core/lib/profiling/timers.h" - -static grpc_error* init_channel_elem(grpc_channel_element* elem, - grpc_channel_element_args* args) { - return GRPC_ERROR_NONE; -} - -static void destroy_channel_elem(grpc_channel_element* elem) {} - -namespace { - -struct call_data { - // Stats object to update. - grpc_core::RefCountedPtr<grpc_core::XdsLbClientStats> client_stats; - // State for intercepting send_initial_metadata. - grpc_closure on_complete_for_send; - grpc_closure* original_on_complete_for_send; - bool send_initial_metadata_succeeded; - // State for intercepting recv_initial_metadata. - grpc_closure recv_initial_metadata_ready; - grpc_closure* original_recv_initial_metadata_ready; - bool recv_initial_metadata_succeeded; -}; - -} // namespace - -static void on_complete_for_send(void* arg, grpc_error* error) { - call_data* calld = static_cast<call_data*>(arg); - if (error == GRPC_ERROR_NONE) { - calld->send_initial_metadata_succeeded = true; - } - GRPC_CLOSURE_RUN(calld->original_on_complete_for_send, GRPC_ERROR_REF(error)); -} - -static void recv_initial_metadata_ready(void* arg, grpc_error* error) { - call_data* calld = static_cast<call_data*>(arg); - if (error == GRPC_ERROR_NONE) { - calld->recv_initial_metadata_succeeded = true; - } - GRPC_CLOSURE_RUN(calld->original_recv_initial_metadata_ready, - GRPC_ERROR_REF(error)); -} - -static grpc_error* init_call_elem(grpc_call_element* elem, - const grpc_call_element_args* args) { - call_data* calld = static_cast<call_data*>(elem->call_data); - // Get stats object from context and take a ref. - GPR_ASSERT(args->context != nullptr); - if (args->context[GRPC_GRPCLB_CLIENT_STATS].value != nullptr) { - calld->client_stats = static_cast<grpc_core::XdsLbClientStats*>( - args->context[GRPC_GRPCLB_CLIENT_STATS].value) - ->Ref(); - // Record call started. - calld->client_stats->AddCallStarted(); - } - return GRPC_ERROR_NONE; -} - -static void destroy_call_elem(grpc_call_element* elem, - const grpc_call_final_info* final_info, - grpc_closure* ignored) { - call_data* calld = static_cast<call_data*>(elem->call_data); - if (calld->client_stats != nullptr) { - // Record call finished, optionally setting client_failed_to_send and - // received. - calld->client_stats->AddCallFinished( - !calld->send_initial_metadata_succeeded /* client_failed_to_send */, - calld->recv_initial_metadata_succeeded /* known_received */); - // All done, so unref the stats object. - // TODO(roth): Eliminate this once filter stack is converted to C++. - calld->client_stats.reset(); - } -} - -static void start_transport_stream_op_batch( - grpc_call_element* elem, grpc_transport_stream_op_batch* batch) { - call_data* calld = static_cast<call_data*>(elem->call_data); - GPR_TIMER_SCOPE("clr_start_transport_stream_op_batch", 0); - if (calld->client_stats != nullptr) { - // Intercept send_initial_metadata. - if (batch->send_initial_metadata) { - calld->original_on_complete_for_send = batch->on_complete; - GRPC_CLOSURE_INIT(&calld->on_complete_for_send, on_complete_for_send, - calld, grpc_schedule_on_exec_ctx); - batch->on_complete = &calld->on_complete_for_send; - } - // Intercept recv_initial_metadata. - if (batch->recv_initial_metadata) { - calld->original_recv_initial_metadata_ready = - batch->payload->recv_initial_metadata.recv_initial_metadata_ready; - GRPC_CLOSURE_INIT(&calld->recv_initial_metadata_ready, - recv_initial_metadata_ready, calld, - grpc_schedule_on_exec_ctx); - batch->payload->recv_initial_metadata.recv_initial_metadata_ready = - &calld->recv_initial_metadata_ready; - } - } - // Chain to next filter. - grpc_call_next_op(elem, batch); -} - -const grpc_channel_filter xds_client_load_reporting_filter = { - start_transport_stream_op_batch, - grpc_channel_next_op, - sizeof(call_data), - init_call_elem, - grpc_call_stack_ignore_set_pollset_or_pollset_set, - destroy_call_elem, - 0, // sizeof(channel_data) - init_channel_elem, - destroy_channel_elem, - grpc_channel_next_get_info, - "client_load_reporting"}; diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h b/src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h deleted file mode 100644 index 31a799154c..0000000000 --- a/src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * - * Copyright 2018 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_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_CLIENT_LOAD_REPORTING_FILTER_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_CLIENT_LOAD_REPORTING_FILTER_H - -#include <grpc/support/port_platform.h> - -#include "src/core/lib/channel/channel_stack.h" - -extern const grpc_channel_filter xds_client_load_reporting_filter; - -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_CLIENT_LOAD_REPORTING_FILTER_H \ - */ diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc index 16e910b2d9..7fb4cbdcd2 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc @@ -75,11 +75,10 @@ #include "src/core/ext/filters/client_channel/client_channel.h" #include "src/core/ext/filters/client_channel/client_channel_factory.h" -#include "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h" -#include "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h" #include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" +#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.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/core/ext/filters/client_channel/parse_address.h" @@ -1483,7 +1482,6 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg, xdslb_policy->lb_call_backoff_.Reset(); xdslb_policy->StartBalancerCallLocked(); } - [[fallthrough]]; // Fall through. case GRPC_CHANNEL_SHUTDOWN: done: @@ -1861,34 +1859,11 @@ class XdsFactory : public LoadBalancingPolicyFactory { // Plugin registration // -namespace { - -// Only add client_load_reporting filter if the grpclb LB policy is used. -bool maybe_add_client_load_reporting_filter(grpc_channel_stack_builder* builder, - void* arg) { - const grpc_channel_args* args = - grpc_channel_stack_builder_get_channel_arguments(builder); - const grpc_arg* channel_arg = - grpc_channel_args_find(args, GRPC_ARG_LB_POLICY_NAME); - if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_STRING && - strcmp(channel_arg->value.string, "grpclb") == 0) { - return grpc_channel_stack_builder_append_filter( - builder, (const grpc_channel_filter*)arg, nullptr, nullptr); - } - return true; -} - -} // namespace - void grpc_lb_policy_xds_init() { grpc_core::LoadBalancingPolicyRegistry::Builder:: RegisterLoadBalancingPolicyFactory( grpc_core::UniquePtr<grpc_core::LoadBalancingPolicyFactory>( grpc_core::New<grpc_core::XdsFactory>())); - grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, - GRPC_CHANNEL_INIT_BUILTIN_PRIORITY, - maybe_add_client_load_reporting_filter, - (void*)&xds_client_load_reporting_filter); } void grpc_lb_policy_xds_shutdown() {} diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc index 3bd2653635..79b7bdbe33 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc @@ -20,7 +20,7 @@ #include "pb_decode.h" #include "pb_encode.h" -#include "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h" +#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h" #include <grpc/support/alloc.h> diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h index 3f096af6d6..9d08defa7e 100644 --- a/src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h +++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_LOAD_BALANCER_API_H -#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_LOAD_BALANCER_API_H +#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_LOAD_BALANCER_API_H +#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_LOAD_BALANCER_API_H #include <grpc/support/port_platform.h> @@ -85,5 +85,5 @@ grpc_millis xds_grpclb_duration_to_millis(xds_grpclb_duration* duration_pb); /** Destroy \a initial_response */ void xds_grpclb_initial_response_destroy(xds_grpclb_initial_response* response); -#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_LOAD_BALANCER_API_H \ +#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_LB_POLICY_XDS_XDS_LOAD_BALANCER_API_H \ */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc index dfa52867d8..01796ca08f 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc @@ -201,7 +201,7 @@ void AresDnsResolver::ShutdownLocked() { grpc_timer_cancel(&next_resolution_timer_); } if (pending_request_ != nullptr) { - grpc_cancel_ares_request(pending_request_); + grpc_cancel_ares_request_locked(pending_request_); } if (next_completion_ != nullptr) { *target_result_ = nullptr; @@ -298,6 +298,7 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) { grpc_channel_args* result = nullptr; GPR_ASSERT(r->resolving_); r->resolving_ = false; + gpr_free(r->pending_request_); r->pending_request_ = nullptr; if (r->lb_addresses_ != nullptr) { static const char* args_to_remove[2]; @@ -473,7 +474,9 @@ void grpc_resolver_dns_ares_init() { GRPC_LOG_IF_ERROR("ares_library_init() failed", error); return; } - default_resolver = grpc_resolve_address_impl; + if (default_resolver == nullptr) { + default_resolver = grpc_resolve_address_impl; + } grpc_set_resolver_impl(&ares_resolver); grpc_core::ResolverRegistry::Builder::RegisterResolverFactory( grpc_core::UniquePtr<grpc_core::ResolverFactory>( diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc index 4c795c34c8..582e2203fc 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc @@ -144,12 +144,12 @@ static void grpc_ares_request_unref_locked(grpc_ares_request* r) { void grpc_ares_complete_request_locked(grpc_ares_request* r) { /* Invoke on_done callback and destroy the request */ + r->ev_driver = nullptr; grpc_lb_addresses* lb_addrs = *(r->lb_addrs_out); if (lb_addrs != nullptr) { grpc_cares_wrapper_address_sorting_sort(lb_addrs); } GRPC_CLOSURE_SCHED(r->on_done, r->error); - gpr_free(r); } static grpc_ares_hostbyname_request* create_hostbyname_request_locked( @@ -356,15 +356,12 @@ done: grpc_ares_request_unref_locked(r); } -static grpc_ares_request* -grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( - const char* dns_server, const char* name, const char* default_port, - grpc_pollset_set* interested_parties, grpc_closure* on_done, - grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, - grpc_combiner* combiner) { +void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( + grpc_ares_request* r, const char* dns_server, const char* name, + const char* default_port, grpc_pollset_set* interested_parties, + bool check_grpclb, grpc_combiner* combiner) { grpc_error* error = GRPC_ERROR_NONE; grpc_ares_hostbyname_request* hr = nullptr; - grpc_ares_request* r = nullptr; ares_channel* channel = nullptr; /* TODO(zyc): Enable tracing after #9603 is checked in */ /* if (grpc_dns_trace) { @@ -390,14 +387,6 @@ grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( } port = gpr_strdup(default_port); } - r = static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request))); - r->ev_driver = nullptr; - r->on_done = on_done; - r->lb_addrs_out = addrs; - r->service_config_json_out = service_config_json; - r->success = false; - r->error = GRPC_ERROR_NONE; - r->pending_queries = 0; error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties, combiner, r); if (error != GRPC_ERROR_NONE) goto error_cleanup; @@ -458,7 +447,7 @@ grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( on_srv_query_done_locked, r); gpr_free(service_name); } - if (service_config_json != nullptr) { + if (r->service_config_json_out != nullptr) { grpc_ares_request_ref_locked(r); char* config_name; gpr_asprintf(&config_name, "_grpc_config.%s", host); @@ -470,14 +459,12 @@ grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( grpc_ares_request_unref_locked(r); gpr_free(host); gpr_free(port); - return r; + return; error_cleanup: - GRPC_CLOSURE_SCHED(on_done, error); - gpr_free(r); + GRPC_CLOSURE_SCHED(r->on_done, error); gpr_free(host); gpr_free(port); - return nullptr; } static bool inner_resolve_as_ip_literal_locked(const char* name, @@ -536,21 +523,31 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl( grpc_pollset_set* interested_parties, grpc_closure* on_done, grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, grpc_combiner* combiner) { + grpc_ares_request* r = + static_cast<grpc_ares_request*>(gpr_zalloc(sizeof(grpc_ares_request))); + r->ev_driver = nullptr; + r->on_done = on_done; + r->lb_addrs_out = addrs; + r->service_config_json_out = service_config_json; + r->success = false; + r->error = GRPC_ERROR_NONE; + r->pending_queries = 0; // Early out if the target is an ipv4 or ipv6 literal. if (resolve_as_ip_literal_locked(name, default_port, addrs)) { GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); - return nullptr; + return r; } // Early out if the target is localhost and we're on Windows. if (grpc_ares_maybe_resolve_localhost_manually_locked(name, default_port, addrs)) { GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE); - return nullptr; + return r; } // Look up name using c-ares lib. - return grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( - dns_server, name, default_port, interested_parties, on_done, addrs, - check_grpclb, service_config_json, combiner); + grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked( + r, dns_server, name, default_port, interested_parties, check_grpclb, + combiner); + return r; } grpc_ares_request* (*grpc_dns_lookup_ares_locked)( @@ -559,14 +556,16 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; -void grpc_cancel_ares_request(grpc_ares_request* r) { - if (grpc_dns_lookup_ares_locked == grpc_dns_lookup_ares_locked_impl) { - if (r != nullptr) { - grpc_ares_ev_driver_shutdown_locked(r->ev_driver); - } +static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) { + GPR_ASSERT(r != nullptr); + if (r->ev_driver != nullptr) { + grpc_ares_ev_driver_shutdown_locked(r->ev_driver); } } +void (*grpc_cancel_ares_request_locked)(grpc_ares_request* r) = + grpc_cancel_ares_request_locked_impl; + grpc_error* grpc_ares_init(void) { gpr_once_init(&g_basic_init, do_basic_init); gpr_mu_lock(&g_init_mu); @@ -603,20 +602,23 @@ typedef struct grpc_resolve_address_ares_request { grpc_lb_addresses* lb_addrs; /** closure to call when the resolve_address_ares request completes */ grpc_closure* on_resolve_address_done; - /** a closure wrapping on_dns_lookup_done_cb, which should be invoked when the - grpc_dns_lookup_ares_locked operation is done. */ - grpc_closure on_dns_lookup_done; + /** a closure wrapping on_resolve_address_done, which should be invoked when + the grpc_dns_lookup_ares_locked operation is done. */ + grpc_closure on_dns_lookup_done_locked; /* target name */ const char* name; /* default port to use if none is specified */ const char* default_port; /* pollset_set to be driven by */ grpc_pollset_set* interested_parties; + /* underlying ares_request that the query is performed on */ + grpc_ares_request* ares_request; } grpc_resolve_address_ares_request; -static void on_dns_lookup_done_cb(void* arg, grpc_error* error) { +static void on_dns_lookup_done_locked(void* arg, grpc_error* error) { grpc_resolve_address_ares_request* r = static_cast<grpc_resolve_address_ares_request*>(arg); + gpr_free(r->ares_request); grpc_resolved_addresses** resolved_addresses = r->addrs_out; if (r->lb_addrs == nullptr || r->lb_addrs->num_addresses == 0) { *resolved_addresses = nullptr; @@ -643,9 +645,9 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked( void* arg, grpc_error* unused_error) { grpc_resolve_address_ares_request* r = static_cast<grpc_resolve_address_ares_request*>(arg); - grpc_dns_lookup_ares_locked( + r->ares_request = grpc_dns_lookup_ares_locked( nullptr /* dns_server */, r->name, r->default_port, r->interested_parties, - &r->on_dns_lookup_done, &r->lb_addrs, false /* check_grpclb */, + &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */, nullptr /* service_config_json */, r->combiner); } @@ -660,8 +662,8 @@ static void grpc_resolve_address_ares_impl(const char* name, r->combiner = grpc_combiner_create(); r->addrs_out = addrs; r->on_resolve_address_done = on_done; - GRPC_CLOSURE_INIT(&r->on_dns_lookup_done, on_dns_lookup_done_cb, r, - grpc_schedule_on_exec_ctx); + GRPC_CLOSURE_INIT(&r->on_dns_lookup_done_locked, on_dns_lookup_done_locked, r, + grpc_combiner_scheduler(r->combiner)); r->name = name; r->default_port = default_port; r->interested_parties = interested_parties; diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h index 1bc457d4cf..a1231cc4e0 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h @@ -54,7 +54,8 @@ extern void (*grpc_resolve_address_ares)(const char* name, port in \a name. grpc_ares_init() must be called at least once before this function. \a on_done may be called directly in this function without being scheduled with \a exec_ctx, so it must not try to acquire locks that are - being held by the caller. */ + being held by the caller. The returned grpc_ares_request object is owned + by the caller and it is safe to free after on_done is called back. */ extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( const char* dns_server, const char* name, const char* default_port, grpc_pollset_set* interested_parties, grpc_closure* on_done, @@ -62,7 +63,7 @@ extern grpc_ares_request* (*grpc_dns_lookup_ares_locked)( char** service_config_json, grpc_combiner* combiner); /* Cancel the pending grpc_ares_request \a request */ -void grpc_cancel_ares_request(grpc_ares_request* request); +extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request); /* Initialize gRPC ares wrapper. Must be called at least once before grpc_resolve_address_ares(). */ diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc index d6a76fc8b6..9f293c1ac0 100644 --- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc @@ -40,7 +40,10 @@ grpc_ares_request* (*grpc_dns_lookup_ares_locked)( grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json, grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl; -void grpc_cancel_ares_request(grpc_ares_request* r) {} +static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {} + +void (*grpc_cancel_ares_request_locked)(grpc_ares_request* r) = + grpc_cancel_ares_request_locked_impl; grpc_error* grpc_ares_init(void) { return GRPC_ERROR_NONE; } diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc index a0a40eb2b3..e4c6efe862 100644 --- a/src/core/ext/filters/client_channel/subchannel.cc +++ b/src/core/ext/filters/client_channel/subchannel.cc @@ -30,6 +30,7 @@ #include <grpc/support/string_util.h> #include "src/core/ext/filters/client_channel/client_channel.h" +#include "src/core/ext/filters/client_channel/health/health_check_client.h" #include "src/core/ext/filters/client_channel/parse_address.h" #include "src/core/ext/filters/client_channel/proxy_mapper_registry.h" #include "src/core/ext/filters/client_channel/subchannel_index.h" @@ -41,6 +42,7 @@ #include "src/core/lib/gpr/alloc.h" #include "src/core/lib/gprpp/debug_location.h" #include "src/core/lib/gprpp/manual_constructor.h" +#include "src/core/lib/gprpp/mutex_lock.h" #include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/core/lib/iomgr/timer.h" @@ -50,6 +52,7 @@ #include "src/core/lib/surface/channel_init.h" #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/error_utils.h" +#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/status_metadata.h" #define INTERNAL_REF_BITS 16 @@ -66,6 +69,10 @@ struct state_watcher { grpc_closure closure; grpc_subchannel* subchannel; grpc_connectivity_state connectivity_state; + grpc_connectivity_state last_connectivity_state; + grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client; + grpc_closure health_check_closure; + grpc_connectivity_state health_state; }; } // namespace @@ -78,6 +85,12 @@ typedef struct external_state_watcher { struct external_state_watcher* prev; } external_state_watcher; +namespace grpc_core { + +class ConnectedSubchannelStateWatcher; + +} // namespace grpc_core + struct grpc_subchannel { grpc_connector* connector; @@ -109,19 +122,24 @@ struct grpc_subchannel { being setup */ grpc_pollset_set* pollset_set; + grpc_core::UniquePtr<char> health_check_service_name; + /** mutex protecting remaining elements */ gpr_mu mu; - /** active connection, or null; of type grpc_core::ConnectedSubchannel - */ + /** active connection, or null */ grpc_core::RefCountedPtr<grpc_core::ConnectedSubchannel> connected_subchannel; + grpc_core::OrphanablePtr<grpc_core::ConnectedSubchannelStateWatcher> + connected_subchannel_watcher; /** have we seen a disconnection? */ bool disconnected; /** are we connecting */ bool connecting; + /** connectivity state tracking */ grpc_connectivity_state_tracker state_tracker; + grpc_connectivity_state_tracker state_and_health_tracker; external_state_watcher root_external_state_watcher; @@ -153,6 +171,171 @@ struct grpc_subchannel_call { grpc_millis deadline; }; +static void maybe_start_connecting_locked(grpc_subchannel* c); + +static const char* subchannel_connectivity_state_change_string( + grpc_connectivity_state state) { + switch (state) { + case GRPC_CHANNEL_IDLE: + return "Subchannel state change to IDLE"; + case GRPC_CHANNEL_CONNECTING: + return "Subchannel state change to CONNECTING"; + case GRPC_CHANNEL_READY: + return "Subchannel state change to READY"; + case GRPC_CHANNEL_TRANSIENT_FAILURE: + return "Subchannel state change to TRANSIENT_FAILURE"; + case GRPC_CHANNEL_SHUTDOWN: + return "Subchannel state change to SHUTDOWN"; + } + GPR_UNREACHABLE_CODE(return "UNKNOWN"); +} + +static void set_subchannel_connectivity_state_locked( + grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, + const char* reason) { + if (c->channelz_subchannel != nullptr) { + c->channelz_subchannel->AddTraceEvent( + grpc_core::channelz::ChannelTrace::Severity::Info, + grpc_slice_from_static_string( + subchannel_connectivity_state_change_string(state))); + } + grpc_connectivity_state_set(&c->state_tracker, state, error, reason); +} + +namespace grpc_core { + +class ConnectedSubchannelStateWatcher + : public InternallyRefCounted<ConnectedSubchannelStateWatcher> { + public: + // Must be instantiated while holding c->mu. + explicit ConnectedSubchannelStateWatcher(grpc_subchannel* c) + : subchannel_(c) { + // Steal subchannel ref for connecting. + GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher"); + GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting"); + // Start watching for connectivity state changes. + // Callback uses initial ref to this. + GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this, + grpc_schedule_on_exec_ctx); + c->connected_subchannel->NotifyOnStateChange(c->pollset_set, + &pending_connectivity_state_, + &on_connectivity_changed_); + // Start health check if needed. + grpc_connectivity_state health_state = GRPC_CHANNEL_READY; + if (c->health_check_service_name != nullptr) { + health_check_client_ = grpc_core::MakeOrphanable<HealthCheckClient>( + c->health_check_service_name.get(), c->connected_subchannel, + c->pollset_set, c->channelz_subchannel); + GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this, + grpc_schedule_on_exec_ctx); + Ref().release(); // Ref for health callback tracked manually. + health_check_client_->NotifyOnHealthChange(&health_state_, + &on_health_changed_); + health_state = GRPC_CHANNEL_CONNECTING; + } + // Report initial state. + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected"); + grpc_connectivity_state_set(&c->state_and_health_tracker, health_state, + GRPC_ERROR_NONE, "subchannel_connected"); + } + + ~ConnectedSubchannelStateWatcher() { + GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher"); + } + + void Orphan() override { health_check_client_.reset(); } + + private: + static void OnConnectivityChanged(void* arg, grpc_error* error) { + auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg); + grpc_subchannel* c = self->subchannel_; + { + MutexLock lock(&c->mu); + switch (self->pending_connectivity_state_) { + case GRPC_CHANNEL_TRANSIENT_FAILURE: + case GRPC_CHANNEL_SHUTDOWN: { + if (!c->disconnected && c->connected_subchannel != nullptr) { + if (grpc_trace_stream_refcount.enabled()) { + gpr_log(GPR_INFO, + "Connected subchannel %p of subchannel %p has gone into " + "%s. Attempting to reconnect.", + c->connected_subchannel.get(), c, + grpc_connectivity_state_name( + self->pending_connectivity_state_)); + } + c->connected_subchannel.reset(); + c->connected_subchannel_watcher.reset(); + self->last_connectivity_state_ = GRPC_CHANNEL_TRANSIENT_FAILURE; + set_subchannel_connectivity_state_locked( + c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), + "reflect_child"); + grpc_connectivity_state_set(&c->state_and_health_tracker, + GRPC_CHANNEL_TRANSIENT_FAILURE, + GRPC_ERROR_REF(error), "reflect_child"); + c->backoff_begun = false; + c->backoff->Reset(); + maybe_start_connecting_locked(c); + } else { + self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN; + } + self->health_check_client_.reset(); + break; + } + default: { + // In principle, this should never happen. We should not get + // a callback for READY, because that was the state we started + // this watch from. And a connected subchannel should never go + // from READY to CONNECTING or IDLE. + self->last_connectivity_state_ = self->pending_connectivity_state_; + set_subchannel_connectivity_state_locked( + c, self->pending_connectivity_state_, GRPC_ERROR_REF(error), + "reflect_child"); + if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) { + grpc_connectivity_state_set(&c->state_and_health_tracker, + self->pending_connectivity_state_, + GRPC_ERROR_REF(error), "reflect_child"); + } + c->connected_subchannel->NotifyOnStateChange( + nullptr, &self->pending_connectivity_state_, + &self->on_connectivity_changed_); + self = nullptr; // So we don't unref below. + } + } + } + // Don't unref until we've released the lock, because this might + // cause the subchannel (which contains the lock) to be destroyed. + if (self != nullptr) self->Unref(); + } + + static void OnHealthChanged(void* arg, grpc_error* error) { + auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg); + if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) { + self->Unref(); + return; + } + grpc_subchannel* c = self->subchannel_; + MutexLock lock(&c->mu); + if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) { + grpc_connectivity_state_set(&c->state_and_health_tracker, + self->health_state_, GRPC_ERROR_REF(error), + "health_changed"); + } + self->health_check_client_->NotifyOnHealthChange(&self->health_state_, + &self->on_health_changed_); + } + + grpc_subchannel* subchannel_; + grpc_closure on_connectivity_changed_; + grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY; + grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY; + grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client_; + grpc_closure on_health_changed_; + grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING; +}; + +} // namespace grpc_core + #define SUBCHANNEL_CALL_TO_CALL_STACK(call) \ (grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \ sizeof(grpc_subchannel_call))) @@ -198,8 +381,10 @@ static void subchannel_destroy(void* arg, grpc_error* error) { c->channelz_subchannel.reset(); } gpr_free((void*)c->filters); + c->health_check_service_name.reset(); grpc_channel_args_destroy(c->args); grpc_connectivity_state_destroy(&c->state_tracker); + grpc_connectivity_state_destroy(&c->state_and_health_tracker); grpc_connector_unref(c->connector); grpc_pollset_set_destroy(c->pollset_set); grpc_subchannel_key_destroy(c->key); @@ -262,6 +447,7 @@ static void disconnect(grpc_subchannel* c) { grpc_connector_shutdown(c->connector, GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Subchannel disconnected")); c->connected_subchannel.reset(); + c->connected_subchannel_watcher.reset(); gpr_mu_unlock(&c->mu); } @@ -337,6 +523,31 @@ static void parse_args_for_backoff_values( .set_max_backoff(max_backoff_ms); } +namespace grpc_core { +namespace { + +struct HealthCheckParams { + UniquePtr<char> service_name; + + static void Parse(const grpc_json* field, HealthCheckParams* params) { + if (strcmp(field->key, "healthCheckConfig") == 0) { + if (field->type != GRPC_JSON_OBJECT) return; + for (grpc_json* sub_field = field->child; sub_field != nullptr; + sub_field = sub_field->next) { + if (sub_field->key == nullptr) return; + if (strcmp(sub_field->key, "serviceName") == 0) { + if (params->service_name != nullptr) return; // Duplicate. + if (sub_field->type != GRPC_JSON_STRING) return; + params->service_name.reset(gpr_strdup(sub_field->value)); + } + } + } + } +}; + +} // namespace +} // namespace grpc_core + grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, const grpc_subchannel_args* args) { grpc_subchannel_key* key = grpc_subchannel_key_create(args); @@ -387,12 +598,28 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector, grpc_schedule_on_exec_ctx); grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE, "subchannel"); + grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE, + "subchannel"); grpc_core::BackOff::Options backoff_options; parse_args_for_backoff_values(args->args, &backoff_options, &c->min_connect_timeout_ms); c->backoff.Init(backoff_options); gpr_mu_init(&c->mu); + // Check whether we should enable health checking. + const char* service_config_json = grpc_channel_arg_get_string( + grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG)); + if (service_config_json != nullptr) { + grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config = + grpc_core::ServiceConfig::Create(service_config_json); + if (service_config != nullptr) { + grpc_core::HealthCheckParams params; + service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse, + ¶ms); + c->health_check_service_name = std::move(params.service_name); + } + } + const grpc_arg* arg = grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ); bool channelz_enabled = @@ -428,35 +655,6 @@ intptr_t grpc_subchannel_get_child_socket_uuid(grpc_subchannel* subchannel) { } } -static const char* subchannel_connectivity_state_change_string( - grpc_connectivity_state state) { - switch (state) { - case GRPC_CHANNEL_IDLE: - return "Subchannel state change to IDLE"; - case GRPC_CHANNEL_CONNECTING: - return "Subchannel state change to CONNECTING"; - case GRPC_CHANNEL_READY: - return "Subchannel state change to READY"; - case GRPC_CHANNEL_TRANSIENT_FAILURE: - return "Subchannel state change to TRANSIENT_FAILURE"; - case GRPC_CHANNEL_SHUTDOWN: - return "Subchannel state change to SHUTDOWN"; - } - GPR_UNREACHABLE_CODE(return "UNKNOWN"); -} - -static void set_subchannel_connectivity_state_locked( - grpc_subchannel* c, grpc_connectivity_state state, grpc_error* error, - const char* reason) { - if (c->channelz_subchannel != nullptr) { - c->channelz_subchannel->AddTraceEvent( - grpc_core::channelz::ChannelTrace::Severity::Info, - grpc_slice_from_static_string( - subchannel_connectivity_state_change_string(state))); - } - grpc_connectivity_state_set(&c->state_tracker, state, error, reason); -} - static void continue_connect_locked(grpc_subchannel* c) { grpc_connect_in_args args; args.interested_parties = c->pollset_set; @@ -467,15 +665,19 @@ static void continue_connect_locked(grpc_subchannel* c) { args.channel_args = c->args; set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, "connecting"); + grpc_connectivity_state_set(&c->state_and_health_tracker, + GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE, + "connecting"); grpc_connector_connect(c->connector, &args, &c->connecting_result, &c->on_connected); } -grpc_connectivity_state grpc_subchannel_check_connectivity(grpc_subchannel* c, - grpc_error** error) { - grpc_connectivity_state state; +grpc_connectivity_state grpc_subchannel_check_connectivity( + grpc_subchannel* c, grpc_error** error, bool inhibit_health_checks) { gpr_mu_lock(&c->mu); - state = grpc_connectivity_state_get(&c->state_tracker, error); + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; + grpc_connectivity_state state = grpc_connectivity_state_get(tracker, error); gpr_mu_unlock(&c->mu); return state; } @@ -533,7 +735,8 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { /* Already connected: don't restart */ return; } - if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) { + if (!grpc_connectivity_state_has_watchers(&c->state_tracker) && + !grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) { /* Nobody is interested in connecting: so don't just yet */ return; } @@ -560,16 +763,18 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) { void grpc_subchannel_notify_on_state_change( grpc_subchannel* c, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify) { + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks) { + grpc_connectivity_state_tracker* tracker = + inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker; external_state_watcher* w; - if (state == nullptr) { gpr_mu_lock(&c->mu); for (w = c->root_external_state_watcher.next; w != &c->root_external_state_watcher; w = w->next) { if (w->notify == notify) { - grpc_connectivity_state_notify_on_state_change(&c->state_tracker, - nullptr, &w->closure); + grpc_connectivity_state_notify_on_state_change(tracker, nullptr, + &w->closure); } } gpr_mu_unlock(&c->mu); @@ -588,62 +793,12 @@ void grpc_subchannel_notify_on_state_change( w->next = &c->root_external_state_watcher; w->prev = w->next->prev; w->next->prev = w->prev->next = w; - grpc_connectivity_state_notify_on_state_change(&c->state_tracker, state, - &w->closure); + grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure); maybe_start_connecting_locked(c); gpr_mu_unlock(&c->mu); } } -static void on_connected_subchannel_connectivity_changed(void* p, - grpc_error* error) { - state_watcher* connected_subchannel_watcher = static_cast<state_watcher*>(p); - grpc_subchannel* c = connected_subchannel_watcher->subchannel; - gpr_mu* mu = &c->mu; - - gpr_mu_lock(mu); - - switch (connected_subchannel_watcher->connectivity_state) { - case GRPC_CHANNEL_TRANSIENT_FAILURE: - case GRPC_CHANNEL_SHUTDOWN: { - if (!c->disconnected && c->connected_subchannel != nullptr) { - if (grpc_trace_stream_refcount.enabled()) { - gpr_log(GPR_INFO, - "Connected subchannel %p of subchannel %p has gone into %s. " - "Attempting to reconnect.", - c->connected_subchannel.get(), c, - grpc_connectivity_state_name( - connected_subchannel_watcher->connectivity_state)); - } - c->connected_subchannel.reset(); - set_subchannel_connectivity_state_locked( - c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error), - "reflect_child"); - c->backoff_begun = false; - c->backoff->Reset(); - maybe_start_connecting_locked(c); - } else { - connected_subchannel_watcher->connectivity_state = - GRPC_CHANNEL_SHUTDOWN; - } - break; - } - default: { - set_subchannel_connectivity_state_locked( - c, connected_subchannel_watcher->connectivity_state, - GRPC_ERROR_REF(error), "reflect_child"); - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - c->connected_subchannel->NotifyOnStateChange( - nullptr, &connected_subchannel_watcher->connectivity_state, - &connected_subchannel_watcher->closure); - connected_subchannel_watcher = nullptr; - } - } - gpr_mu_unlock(mu); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "state_watcher"); - gpr_free(connected_subchannel_watcher); -} - static bool publish_transport_locked(grpc_subchannel* c) { /* construct channel stack */ grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create(); @@ -670,17 +825,7 @@ static bool publish_transport_locked(grpc_subchannel* c) { intptr_t socket_uuid = c->connecting_result.socket_uuid; memset(&c->connecting_result, 0, sizeof(c->connecting_result)); - /* initialize state watcher */ - state_watcher* connected_subchannel_watcher = static_cast<state_watcher*>( - gpr_zalloc(sizeof(*connected_subchannel_watcher))); - connected_subchannel_watcher->subchannel = c; - connected_subchannel_watcher->connectivity_state = GRPC_CHANNEL_READY; - GRPC_CLOSURE_INIT(&connected_subchannel_watcher->closure, - on_connected_subchannel_connectivity_changed, - connected_subchannel_watcher, grpc_schedule_on_exec_ctx); - if (c->disconnected) { - gpr_free(connected_subchannel_watcher); grpc_channel_stack_destroy(stk); gpr_free(stk); return false; @@ -692,17 +837,10 @@ static bool publish_transport_locked(grpc_subchannel* c) { gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p", c->connected_subchannel.get(), c); - /* setup subchannel watching connected subchannel for changes; subchannel - ref for connecting is donated to the state watcher */ - GRPC_SUBCHANNEL_WEAK_REF(c, "state_watcher"); - GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting"); - c->connected_subchannel->NotifyOnStateChange( - c->pollset_set, &connected_subchannel_watcher->connectivity_state, - &connected_subchannel_watcher->closure); - - /* signal completion */ - set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_READY, - GRPC_ERROR_NONE, "connected"); + // Instantiate state watcher. Will clean itself up. + c->connected_subchannel_watcher = + grpc_core::MakeOrphanable<grpc_core::ConnectedSubchannelStateWatcher>(c); + return true; } @@ -725,6 +863,12 @@ static void on_subchannel_connected(void* arg, grpc_error* error) { "Connect Failed", &error, 1), GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), "connect_failed"); + grpc_connectivity_state_set( + &c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE, + grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING( + "Connect Failed", &error, 1), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE), + "connect_failed"); const char* errmsg = grpc_error_string(error); gpr_log(GPR_INFO, "Connect failed: %s", errmsg); @@ -956,15 +1100,8 @@ void ConnectedSubchannel::Ping(grpc_closure* on_initiate, grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, grpc_subchannel_call** call) { - size_t allocation_size = - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); - if (args.parent_data_size > 0) { - allocation_size += - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + - args.parent_data_size; - } else { - allocation_size += channel_stack_->call_stack_size; - } + const size_t allocation_size = + GetInitialCallSizeEstimate(args.parent_data_size); *call = static_cast<grpc_subchannel_call*>( gpr_arena_alloc(args.arena, allocation_size)); grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); @@ -994,4 +1131,18 @@ grpc_error* ConnectedSubchannel::CreateCall(const CallArgs& args, return GRPC_ERROR_NONE; } +size_t ConnectedSubchannel::GetInitialCallSizeEstimate( + size_t parent_data_size) const { + size_t allocation_size = + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_subchannel_call)); + if (parent_data_size > 0) { + allocation_size += + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) + + parent_data_size; + } else { + allocation_size += channel_stack_->call_stack_size; + } + return allocation_size; +} + } // namespace grpc_core diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h index c53b13e37e..ec3b4d86e4 100644 --- a/src/core/ext/filters/client_channel/subchannel.h +++ b/src/core/ext/filters/client_channel/subchannel.h @@ -103,6 +103,8 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> { } intptr_t socket_uuid() { return socket_uuid_; } + size_t GetInitialCallSizeEstimate(size_t parent_data_size) const; + private: grpc_channel_stack* channel_stack_; // ref counted pointer to the channelz node in this connected subchannel's @@ -143,13 +145,14 @@ void* grpc_connected_subchannel_call_get_parent_data( /** poll the current connectivity state of a channel */ grpc_connectivity_state grpc_subchannel_check_connectivity( - grpc_subchannel* channel, grpc_error** error); + grpc_subchannel* channel, grpc_error** error, bool inhibit_health_checking); /** Calls notify when the connectivity state of a channel becomes different from *state. Updates *state with the new state of the channel. */ void grpc_subchannel_notify_on_state_change( grpc_subchannel* channel, grpc_pollset_set* interested_parties, - grpc_connectivity_state* state, grpc_closure* notify); + grpc_connectivity_state* state, grpc_closure* notify, + bool inhibit_health_checks); /** retrieve the grpc_core::ConnectedSubchannel - or nullptr if not connected * (which may happen before it initially connects or during transient failures) diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc index 5229304fa4..60a32022f5 100644 --- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc +++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc @@ -163,9 +163,8 @@ static void start_handshake_locked(chttp2_connector* c) { c->args.interested_parties, c->handshake_mgr); grpc_endpoint_add_to_pollset_set(c->endpoint, c->args.interested_parties); grpc_handshake_manager_do_handshake( - c->handshake_mgr, c->args.interested_parties, c->endpoint, - c->args.channel_args, c->args.deadline, nullptr /* acceptor */, - on_handshake_done, c); + c->handshake_mgr, c->endpoint, c->args.channel_args, c->args.deadline, + nullptr /* acceptor */, on_handshake_done, c); c->endpoint = nullptr; // Endpoint handed off to handshake manager. } @@ -213,9 +212,17 @@ static void chttp2_connector_connect(grpc_connector* con, GRPC_CLOSURE_INIT(&c->connected, connected, c, grpc_schedule_on_exec_ctx); GPR_ASSERT(!c->connecting); c->connecting = true; - grpc_tcp_client_connect(&c->connected, &c->endpoint, args->interested_parties, - args->channel_args, &addr, args->deadline); + grpc_closure* closure = &c->connected; + grpc_endpoint** ep = &c->endpoint; gpr_mu_unlock(&c->mu); + // In some implementations, the closure can be flushed before + // grpc_tcp_client_connect and since the closure requires access to c->mu, + // this can result in a deadlock. Refer + // https://github.com/grpc/grpc/issues/16427 + // grpc_tcp_client_connect would fill c->endpoint with proper contents and we + // make sure that we would still exist at that point by taking a ref. + grpc_tcp_client_connect(closure, ep, args->interested_parties, + args->channel_args, &addr, args->deadline); } static const grpc_connector_vtable chttp2_connector_vtable = { diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc index 6ed88dfb5e..07b304b320 100644 --- a/src/core/ext/transport/chttp2/server/chttp2_server.cc +++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc @@ -208,10 +208,10 @@ static void on_accept(void* arg, grpc_endpoint* tcp, grpc_core::ExecCtx::Get()->Now() + grpc_channel_arg_get_integer(timeout_arg, {120 * GPR_MS_PER_SEC, 1, INT_MAX}); - grpc_handshake_manager_do_handshake( - connection_state->handshake_mgr, nullptr /* interested_parties */, tcp, - state->args, connection_state->deadline, acceptor, on_handshake_done, - connection_state); + grpc_handshake_manager_do_handshake(connection_state->handshake_mgr, tcp, + state->args, connection_state->deadline, + acceptor, on_handshake_done, + connection_state); } /* Server callback: start listening on our ports */ diff --git a/src/core/ext/transport/chttp2/transport/parsing.cc b/src/core/ext/transport/chttp2/transport/parsing.cc index f532b084c9..1ff96d3cd3 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.cc +++ b/src/core/ext/transport/chttp2/transport/parsing.cc @@ -368,6 +368,7 @@ static grpc_error* init_data_frame_parser(grpc_chttp2_transport* t) { &s->data_parser, t->incoming_frame_flags, s->id, s); } error_handler: + intptr_t unused; if (err == GRPC_ERROR_NONE) { t->incoming_stream = s; /* t->parser = grpc_chttp2_data_parser_parse;*/ @@ -375,7 +376,7 @@ error_handler: t->parser_data = &s->data_parser; t->ping_state.last_ping_sent_time = GRPC_MILLIS_INF_PAST; return GRPC_ERROR_NONE; - } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, nullptr)) { + } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, &unused)) { /* handle stream errors by closing the stream */ if (s != nullptr) { grpc_chttp2_mark_stream_closed(t, s, true, false, err); @@ -756,9 +757,10 @@ static grpc_error* parse_frame_slice(grpc_chttp2_transport* t, grpc_slice slice, int is_last) { grpc_chttp2_stream* s = t->incoming_stream; grpc_error* err = t->parser(t->parser_data, t, s, slice, is_last); + intptr_t unused; if (GPR_LIKELY(err == GRPC_ERROR_NONE)) { return err; - } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, nullptr)) { + } else if (grpc_error_get_int(err, GRPC_ERROR_INT_STREAM_ID, &unused)) { if (grpc_http_trace.enabled()) { const char* msg = grpc_error_string(err); gpr_log(GPR_ERROR, "%s", msg); diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc index fe81acb617..f0d21db32a 100644 --- a/src/core/lib/channel/channel_trace.cc +++ b/src/core/lib/channel/channel_trace.cc @@ -108,16 +108,20 @@ void ChannelTrace::AddTraceEventHelper(TraceEvent* new_trace_event) { } void ChannelTrace::AddTraceEvent(Severity severity, grpc_slice data) { - if (max_event_memory_ == 0) + if (max_event_memory_ == 0) { + grpc_slice_unref_internal(data); return; // tracing is disabled if max_event_memory_ == 0 + } AddTraceEventHelper(New<TraceEvent>(severity, data)); } void ChannelTrace::AddTraceEventWithReference( Severity severity, grpc_slice data, RefCountedPtr<BaseNode> referenced_entity) { - if (max_event_memory_ == 0) + if (max_event_memory_ == 0) { + grpc_slice_unref_internal(data); return; // tracing is disabled if max_event_memory_ == 0 + } // create and fill up the new event AddTraceEventHelper( New<TraceEvent>(severity, data, std::move(referenced_entity))); diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc index e90a9e1f7f..1fe2fad3e1 100644 --- a/src/core/lib/channel/channelz_registry.cc +++ b/src/core/lib/channel/channelz_registry.cc @@ -79,12 +79,13 @@ void ChannelzRegistry::MaybePerformCompactionLocked() { } } -int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid) { - size_t left = 0; - size_t right = entities_.size() - 1; +int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid, + bool direct_hit_needed) { + int left = 0; + int right = int(entities_.size() - 1); while (left <= right) { - size_t true_middle = left + (right - left) / 2; - size_t first_non_null = true_middle; + int true_middle = left + (right - left) / 2; + int first_non_null = true_middle; while (first_non_null < right && entities_[first_non_null] == nullptr) { first_non_null++; } @@ -102,14 +103,14 @@ int ChannelzRegistry::FindByUuidLocked(intptr_t target_uuid) { right = true_middle - 1; } } - return -1; + return direct_hit_needed ? -1 : left; } void ChannelzRegistry::InternalUnregister(intptr_t uuid) { GPR_ASSERT(uuid >= 1); MutexLock lock(&mu_); GPR_ASSERT(uuid <= uuid_generator_); - int idx = FindByUuidLocked(uuid); + int idx = FindByUuidLocked(uuid, true); GPR_ASSERT(idx >= 0); entities_[idx] = nullptr; num_empty_slots_++; @@ -121,7 +122,7 @@ BaseNode* ChannelzRegistry::InternalGet(intptr_t uuid) { if (uuid < 1 || uuid > uuid_generator_) { return nullptr; } - int idx = FindByUuidLocked(uuid); + int idx = FindByUuidLocked(uuid, true); return idx < 0 ? nullptr : entities_[idx]; } @@ -131,16 +132,13 @@ char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) { grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; InlinedVector<BaseNode*, 10> top_level_channels; - // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is - // reserved). However, we want to support requests coming in with - // start_channel_id=0, which signifies "give me everything." Hence this - // funky looking line below. - size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1; bool reached_pagination_limit = false; + int start_idx = GPR_MAX(FindByUuidLocked(start_channel_id, false), 0); for (size_t i = start_idx; i < entities_.size(); ++i) { if (entities_[i] != nullptr && entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel) { + grpc_core::channelz::BaseNode::EntityType::kTopLevelChannel && + entities_[i]->uuid() >= start_channel_id) { // check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that // when the loop terminates, we have <= to kPaginationLimit. @@ -176,15 +174,13 @@ char* ChannelzRegistry::InternalGetServers(intptr_t start_server_id) { grpc_json* json = top_level_json; grpc_json* json_iterator = nullptr; InlinedVector<BaseNode*, 10> servers; - // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is - // reserved). However, we want to support requests coming in with - // start_server_id=0, which signifies "give me everything." - size_t start_idx = start_server_id == 0 ? 0 : start_server_id - 1; bool reached_pagination_limit = false; + int start_idx = GPR_MAX(FindByUuidLocked(start_server_id, false), 0); for (size_t i = start_idx; i < entities_.size(); ++i) { if (entities_[i] != nullptr && entities_[i]->type() == - grpc_core::channelz::BaseNode::EntityType::kServer) { + grpc_core::channelz::BaseNode::EntityType::kServer && + entities_[i]->uuid() >= start_server_id) { // check if we are over pagination limit to determine if we need to set // the "end" element. If we don't go through this block, we know that // when the loop terminates, we have <= to kPaginationLimit. diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h index ea6ab6c8e5..326f0201c7 100644 --- a/src/core/lib/channel/channelz_registry.h +++ b/src/core/lib/channel/channelz_registry.h @@ -92,7 +92,9 @@ class ChannelzRegistry { void MaybePerformCompactionLocked(); // Performs binary search on entities_ to find the index with that uuid. - int FindByUuidLocked(intptr_t uuid); + // If direct_hit_needed, then will return -1 in case of absence. + // Else, will return idx of the first uuid higher than the target. + int FindByUuidLocked(intptr_t uuid, bool direct_hit_needed); // protects members gpr_mu mu_; diff --git a/src/core/lib/channel/handshaker.cc b/src/core/lib/channel/handshaker.cc index ad3250b7e9..e516b56b74 100644 --- a/src/core/lib/channel/handshaker.cc +++ b/src/core/lib/channel/handshaker.cc @@ -292,17 +292,18 @@ static void on_timeout(void* arg, grpc_error* error) { grpc_handshake_manager_unref(mgr); } -void grpc_handshake_manager_do_handshake( - grpc_handshake_manager* mgr, grpc_pollset_set* interested_parties, - grpc_endpoint* endpoint, const grpc_channel_args* channel_args, - grpc_millis deadline, grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, void* user_data) { +void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, + grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, + void* user_data) { gpr_mu_lock(&mgr->mu); GPR_ASSERT(mgr->index == 0); GPR_ASSERT(!mgr->shutdown); // Construct handshaker args. These will be passed through all // handshakers and eventually be freed by the on_handshake_done callback. - mgr->args.interested_parties = interested_parties; mgr->args.endpoint = endpoint; mgr->args.args = grpc_channel_args_copy(channel_args); mgr->args.user_data = user_data; diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h index be7fd127e4..a65990fceb 100644 --- a/src/core/lib/channel/handshaker.h +++ b/src/core/lib/channel/handshaker.h @@ -56,7 +56,6 @@ typedef struct grpc_handshaker grpc_handshaker; /// For the on_handshake_done callback, all members are input arguments, /// which the callback takes ownership of. typedef struct { - grpc_pollset_set* interested_parties; grpc_endpoint* endpoint; grpc_channel_args* args; grpc_slice_buffer* read_buffer; @@ -132,8 +131,6 @@ void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, grpc_error* why); /// Invokes handshakers in the order they were added. -/// \a interested_parties may be non-nullptr to provide a pollset_set that -/// may be used during handshaking. Ownership is not taken. /// Takes ownership of \a endpoint, and then passes that ownership to /// the \a on_handshake_done callback. /// Does NOT take ownership of \a channel_args. Instead, makes a copy before @@ -145,11 +142,13 @@ void grpc_handshake_manager_shutdown(grpc_handshake_manager* mgr, /// GRPC_ERROR_NONE, then handshaking failed and the handshaker has done /// the necessary clean-up. Otherwise, the callback takes ownership of /// the arguments. -void grpc_handshake_manager_do_handshake( - grpc_handshake_manager* mgr, grpc_pollset_set* interested_parties, - grpc_endpoint* endpoint, const grpc_channel_args* channel_args, - grpc_millis deadline, grpc_tcp_server_acceptor* acceptor, - grpc_iomgr_cb_func on_handshake_done, void* user_data); +void grpc_handshake_manager_do_handshake(grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, + const grpc_channel_args* channel_args, + grpc_millis deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_iomgr_cb_func on_handshake_done, + void* user_data); /// Add \a mgr to the server side list of all pending handshake managers, the /// list starts with \a *head. diff --git a/src/core/lib/gpr/mpscq.h b/src/core/lib/gpr/mpscq.h index 6b67880d1b..5ded2522bd 100644 --- a/src/core/lib/gpr/mpscq.h +++ b/src/core/lib/gpr/mpscq.h @@ -38,9 +38,11 @@ typedef struct gpr_mpscq_node { // Actual queue type typedef struct gpr_mpscq { - gpr_atm head; // make sure head & tail don't share a cacheline - char padding[GPR_CACHELINE_SIZE]; + union { + char padding[GPR_CACHELINE_SIZE]; + gpr_atm head; + }; gpr_mpscq_node* tail; gpr_mpscq_node stub; } gpr_mpscq; diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc index 5a5e0b72d5..1c798d368b 100644 --- a/src/core/lib/http/httpcli_security_connector.cc +++ b/src/core/lib/http/httpcli_security_connector.cc @@ -30,6 +30,7 @@ #include "src/core/lib/channel/handshaker_registry.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/security/transport/security_handshaker.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/tsi/ssl_transport_security.h" @@ -194,9 +195,8 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host, grpc_handshakers_add(HANDSHAKER_CLIENT, &args, nullptr /* interested_parties */, c->handshake_mgr); grpc_handshake_manager_do_handshake( - c->handshake_mgr, nullptr /* interested_parties */, tcp, - nullptr /* channel_args */, deadline, nullptr /* acceptor */, - on_handshake_done, c /* user_data */); + c->handshake_mgr, tcp, nullptr /* channel_args */, deadline, + nullptr /* acceptor */, on_handshake_done, c /* user_data */); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); } diff --git a/src/core/lib/iomgr/error.cc b/src/core/lib/iomgr/error.cc index 146a539027..6ae077fd54 100644 --- a/src/core/lib/iomgr/error.cc +++ b/src/core/lib/iomgr/error.cc @@ -121,14 +121,8 @@ static const char* error_time_name(grpc_error_times key) { GPR_UNREACHABLE_CODE(return "unknown"); } -bool grpc_error_is_special(grpc_error* err) { - return err == GRPC_ERROR_NONE || err == GRPC_ERROR_OOM || - err == GRPC_ERROR_CANCELLED; -} - #ifndef NDEBUG -grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line) { - if (grpc_error_is_special(err)) return err; +grpc_error* grpc_error_do_ref(grpc_error* err, const char* file, int line) { if (grpc_trace_error_refcount.enabled()) { gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d]", err, gpr_atm_no_barrier_load(&err->atomics.refs.count), @@ -138,8 +132,7 @@ grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line) { return err; } #else -grpc_error* grpc_error_ref(grpc_error* err) { - if (grpc_error_is_special(err)) return err; +grpc_error* grpc_error_do_ref(grpc_error* err) { gpr_ref(&err->atomics.refs); return err; } @@ -177,8 +170,7 @@ static void error_destroy(grpc_error* err) { } #ifndef NDEBUG -void grpc_error_unref(grpc_error* err, const char* file, int line) { - if (grpc_error_is_special(err)) return; +void grpc_error_do_unref(grpc_error* err, const char* file, int line) { if (grpc_trace_error_refcount.enabled()) { gpr_log(GPR_DEBUG, "%p: %" PRIdPTR " -> %" PRIdPTR " [%s:%d]", err, gpr_atm_no_barrier_load(&err->atomics.refs.count), @@ -189,8 +181,7 @@ void grpc_error_unref(grpc_error* err, const char* file, int line) { } } #else -void grpc_error_unref(grpc_error* err) { - if (grpc_error_is_special(err)) return; +void grpc_error_do_unref(grpc_error* err) { if (gpr_unref(&err->atomics.refs)) { error_destroy(err); } @@ -450,26 +441,23 @@ grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, } typedef struct { - grpc_error* error; grpc_status_code code; const char* msg; } special_error_status_map; static const special_error_status_map error_status_map[] = { - {GRPC_ERROR_NONE, GRPC_STATUS_OK, ""}, - {GRPC_ERROR_CANCELLED, GRPC_STATUS_CANCELLED, "Cancelled"}, - {GRPC_ERROR_OOM, GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, + {GRPC_STATUS_OK, ""}, // GRPC_ERROR_NONE + {GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_1 + {GRPC_STATUS_RESOURCE_EXHAUSTED, "Out of memory"}, // GRPC_ERROR_OOM + {GRPC_STATUS_INVALID_ARGUMENT, ""}, // GRPC_ERROR_RESERVED_2 + {GRPC_STATUS_CANCELLED, "Cancelled"}, // GRPC_ERROR_CANCELLED }; bool grpc_error_get_int(grpc_error* err, grpc_error_ints which, intptr_t* p) { GPR_TIMER_SCOPE("grpc_error_get_int", 0); if (grpc_error_is_special(err)) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { - if (error_status_map[i].error == err) { - if (which != GRPC_ERROR_INT_GRPC_STATUS) return false; - if (p != nullptr) *p = error_status_map[i].code; - return true; - } - } + if (which != GRPC_ERROR_INT_GRPC_STATUS) return false; + *p = error_status_map[reinterpret_cast<size_t>(err)].code; + return true; } uint8_t slot = err->ints[which]; if (slot != UINT8_MAX) { @@ -490,13 +478,10 @@ grpc_error* grpc_error_set_str(grpc_error* src, grpc_error_strs which, bool grpc_error_get_str(grpc_error* err, grpc_error_strs which, grpc_slice* str) { if (grpc_error_is_special(err)) { - for (size_t i = 0; i < GPR_ARRAY_SIZE(error_status_map); i++) { - if (error_status_map[i].error == err) { - if (which != GRPC_ERROR_STR_GRPC_MESSAGE) return false; - *str = grpc_slice_from_static_string(error_status_map[i].msg); - return true; - } - } + if (which != GRPC_ERROR_STR_GRPC_MESSAGE) return false; + *str = grpc_slice_from_static_string( + error_status_map[reinterpret_cast<size_t>(err)].msg); + return true; } uint8_t slot = err->strs[which]; if (slot != UINT8_MAX) { diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 49f4029bc2..cb740d5b01 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -120,8 +120,15 @@ typedef enum { /// polling engines) can safely use the lower bit for themselves. #define GRPC_ERROR_NONE ((grpc_error*)NULL) +#define GRPC_ERROR_RESERVED_1 ((grpc_error*)1) #define GRPC_ERROR_OOM ((grpc_error*)2) +#define GRPC_ERROR_RESERVED_2 ((grpc_error*)3) #define GRPC_ERROR_CANCELLED ((grpc_error*)4) +#define GRPC_ERROR_SPECIAL_MAX GRPC_ERROR_CANCELLED + +inline bool grpc_error_is_special(struct grpc_error* err) { + return err <= GRPC_ERROR_SPECIAL_MAX; +} // debug only toggles that allow for a sanity to check that ensures we will // never create any errors in the per-RPC hotpath. @@ -158,19 +165,37 @@ grpc_error* grpc_error_create(const char* file, int line, grpc_slice desc, errs, count) #ifndef NDEBUG -grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line); -void grpc_error_unref(grpc_error* err, const char* file, int line); +grpc_error* grpc_error_do_ref(grpc_error* err, const char* file, int line); +void grpc_error_do_unref(grpc_error* err, const char* file, int line); +inline grpc_error* grpc_error_ref(grpc_error* err, const char* file, int line) { + if (grpc_error_is_special(err)) return err; + return grpc_error_do_ref(err, file, line); +} +inline void grpc_error_unref(grpc_error* err, const char* file, int line) { + if (grpc_error_is_special(err)) return; + grpc_error_do_unref(err, file, line); +} #define GRPC_ERROR_REF(err) grpc_error_ref(err, __FILE__, __LINE__) #define GRPC_ERROR_UNREF(err) grpc_error_unref(err, __FILE__, __LINE__) #else -grpc_error* grpc_error_ref(grpc_error* err); -void grpc_error_unref(grpc_error* err); +grpc_error* grpc_error_do_ref(grpc_error* err); +void grpc_error_do_unref(grpc_error* err); +inline grpc_error* grpc_error_ref(grpc_error* err) { + if (grpc_error_is_special(err)) return err; + return grpc_error_do_ref(err); +} +inline void grpc_error_unref(grpc_error* err) { + if (grpc_error_is_special(err)) return; + grpc_error_do_unref(err); +} #define GRPC_ERROR_REF(err) grpc_error_ref(err) #define GRPC_ERROR_UNREF(err) grpc_error_unref(err) #endif grpc_error* grpc_error_set_int(grpc_error* src, grpc_error_ints which, intptr_t value) GRPC_MUST_USE_RESULT; +/// It is an error to pass nullptr as `p`. Caller should allocate a dummy +/// intptr_t for `p`, even if the value of `p` is not used. bool grpc_error_get_int(grpc_error* error, grpc_error_ints which, intptr_t* p); /// This call takes ownership of the slice; the error is responsible for /// eventually unref-ing it. diff --git a/src/core/lib/iomgr/error_internal.h b/src/core/lib/iomgr/error_internal.h index 7fde347abd..8027396019 100644 --- a/src/core/lib/iomgr/error_internal.h +++ b/src/core/lib/iomgr/error_internal.h @@ -58,6 +58,4 @@ struct grpc_error { intptr_t arena[0]; }; -bool grpc_error_is_special(struct grpc_error* err); - #endif /* GRPC_CORE_LIB_IOMGR_ERROR_INTERNAL_H */ diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 6ef889b0fe..38571b1957 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -193,9 +193,13 @@ struct grpc_pollset_worker { #define MAX_NEIGHBORHOODS 1024 typedef struct pollset_neighborhood { - gpr_mu mu; - grpc_pollset* active_root; - char pad[GPR_CACHELINE_SIZE]; + union { + char pad[GPR_CACHELINE_SIZE]; + struct { + gpr_mu mu; + grpc_pollset* active_root; + }; + }; } pollset_neighborhood; struct grpc_pollset { diff --git a/src/core/lib/iomgr/tcp_client_custom.cc b/src/core/lib/iomgr/tcp_client_custom.cc index 9389861d07..73344b18d8 100644 --- a/src/core/lib/iomgr/tcp_client_custom.cc +++ b/src/core/lib/iomgr/tcp_client_custom.cc @@ -81,9 +81,8 @@ static void on_alarm(void* acp, grpc_error* error) { } } -static void custom_connect_callback(grpc_custom_socket* socket, - grpc_error* error) { - grpc_core::ExecCtx exec_ctx; +static void custom_connect_callback_internal(grpc_custom_socket* socket, + grpc_error* error) { grpc_custom_tcp_connect* connect = socket->connector; int done; grpc_closure* closure = connect->closure; @@ -100,6 +99,18 @@ static void custom_connect_callback(grpc_custom_socket* socket, GRPC_CLOSURE_SCHED(closure, error); } +static void custom_connect_callback(grpc_custom_socket* socket, + grpc_error* error) { + if (grpc_core::ExecCtx::Get() == nullptr) { + /* If we are being run on a thread which does not have an exec_ctx created + * yet, we should create one. */ + grpc_core::ExecCtx exec_ctx; + custom_connect_callback_internal(socket, error); + } else { + custom_connect_callback_internal(socket, error); + } +} + static void tcp_connect(grpc_closure* closure, grpc_endpoint** ep, grpc_pollset_set* interested_parties, const grpc_channel_args* channel_args, diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc index fa05d901bf..1fbef4ae0c 100644 --- a/src/core/lib/security/credentials/alts/alts_credentials.cc +++ b/src/core/lib/security/credentials/alts/alts_credentials.cc @@ -28,7 +28,7 @@ #include <grpc/support/string_util.h> #include "src/core/lib/security/credentials/alts/check_gcp_environment.h" -#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #define GRPC_CREDENTIALS_TYPE_ALTS "Alts" #define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080" diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc index 858ab6b41b..d3e0e8c816 100644 --- a/src/core/lib/security/credentials/fake/fake_credentials.cc +++ b/src/core/lib/security/credentials/fake/fake_credentials.cc @@ -29,6 +29,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/executor.h" +#include "src/core/lib/security/security_connector/fake/fake_security_connector.h" /* -- Fake transport security credentials. -- */ diff --git a/src/core/lib/security/credentials/local/local_credentials.cc b/src/core/lib/security/credentials/local/local_credentials.cc index 9a2f646ba5..3ccfa2b908 100644 --- a/src/core/lib/security/credentials/local/local_credentials.cc +++ b/src/core/lib/security/credentials/local/local_credentials.cc @@ -25,7 +25,7 @@ #include <grpc/support/log.h> #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/security/security_connector/local_security_connector.h" +#include "src/core/lib/security/security_connector/local/local_security_connector.h" #define GRPC_CREDENTIALS_TYPE_LOCAL "Local" diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h index 712d34c733..0fba413876 100644 --- a/src/core/lib/security/credentials/ssl/ssl_credentials.h +++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h @@ -22,6 +22,8 @@ #include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h" + typedef struct { grpc_channel_credentials base; grpc_ssl_config config; diff --git a/src/core/lib/security/security_connector/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc index d38c0ff044..dd71c8bc60 100644 --- a/src/core/lib/security/security_connector/alts_security_connector.cc +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc @@ -18,7 +18,7 @@ #include <grpc/support/port_platform.h> -#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #include <stdbool.h> #include <string.h> @@ -33,6 +33,7 @@ #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/transport/transport.h" #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" +#include "src/core/tsi/transport_security.h" typedef struct { grpc_channel_security_connector base; diff --git a/src/core/lib/security/security_connector/alts_security_connector.h b/src/core/lib/security/security_connector/alts/alts_security_connector.h index e7e4cffe2a..d2e057a76a 100644 --- a/src/core/lib/security/security_connector/alts_security_connector.h +++ b/src/core/lib/security/security_connector/alts/alts_security_connector.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H -#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_ALTS_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_ALTS_SECURITY_CONNECTOR_H #include <grpc/support/port_platform.h> @@ -65,5 +65,5 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer( } // namespace internal } // namespace grpc_core -#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_SECURITY_CONNECTOR_H \ +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_ALTS_ALTS_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.cc b/src/core/lib/security/security_connector/fake/fake_security_connector.cc new file mode 100644 index 0000000000..5c0c89b88f --- /dev/null +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc @@ -0,0 +1,310 @@ +/* + * + * Copyright 2018 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/lib/security/security_connector/fake/fake_security_connector.h" + +#include <stdbool.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/lib/security/transport/target_authority_table.h" +#include "src/core/tsi/fake_transport_security.h" + +typedef struct { + grpc_channel_security_connector base; + char* target; + char* expected_targets; + bool is_lb_channel; + char* target_name_override; +} grpc_fake_channel_security_connector; + +static void fake_channel_destroy(grpc_security_connector* sc) { + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + grpc_call_credentials_unref(c->base.request_metadata_creds); + gpr_free(c->target); + gpr_free(c->expected_targets); + gpr_free(c->target_name_override); + gpr_free(c); +} + +static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } + +static bool fake_check_target(const char* target_type, const char* target, + const char* set_str) { + GPR_ASSERT(target_type != nullptr); + GPR_ASSERT(target != nullptr); + char** set = nullptr; + size_t set_size = 0; + gpr_string_split(set_str, ",", &set, &set_size); + bool found = false; + for (size_t i = 0; i < set_size; ++i) { + if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; + } + for (size_t i = 0; i < set_size; ++i) { + gpr_free(set[i]); + } + gpr_free(set); + return found; +} + +static void fake_secure_name_check(const char* target, + const char* expected_targets, + bool is_lb_channel) { + if (expected_targets == nullptr) return; + char** lbs_and_backends = nullptr; + size_t lbs_and_backends_size = 0; + bool success = false; + gpr_string_split(expected_targets, ";", &lbs_and_backends, + &lbs_and_backends_size); + if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { + gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", + expected_targets); + goto done; + } + if (is_lb_channel) { + if (lbs_and_backends_size != 2) { + gpr_log(GPR_ERROR, + "Invalid expected targets arg value: '%s'. Expectations for LB " + "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", + expected_targets); + goto done; + } + if (!fake_check_target("LB", target, lbs_and_backends[1])) { + gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", + target, lbs_and_backends[1]); + goto done; + } + success = true; + } else { + if (!fake_check_target("Backend", target, lbs_and_backends[0])) { + gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", + target, lbs_and_backends[0]); + goto done; + } + success = true; + } +done: + for (size_t i = 0; i < lbs_and_backends_size; ++i) { + gpr_free(lbs_and_backends[i]); + } + gpr_free(lbs_and_backends); + if (!success) abort(); +} + +static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + const char* prop_name; + grpc_error* error = GRPC_ERROR_NONE; + *auth_context = nullptr; + if (peer.property_count != 1) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Fake peers should only have 1 property."); + goto end; + } + prop_name = peer.properties[0].name; + if (prop_name == nullptr || + strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { + char* msg; + gpr_asprintf(&msg, "Unexpected property in fake peer: %s.", + prop_name == nullptr ? "<EMPTY>" : prop_name); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + goto end; + } + if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, + peer.properties[0].value.length)) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Invalid value for cert type property."); + goto end; + } + *auth_context = grpc_auth_context_create(nullptr); + grpc_auth_context_add_cstring_property( + *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + GRPC_FAKE_TRANSPORT_SECURITY_TYPE); +end: + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(sc, peer, auth_context, on_peer_checked); + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); +} + +static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + fake_check_peer(sc, peer, auth_context, on_peer_checked); +} + +static int fake_channel_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + grpc_fake_channel_security_connector* c1 = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc1); + grpc_fake_channel_security_connector* c2 = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc2); + int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); + if (c != 0) return c; + c = strcmp(c1->target, c2->target); + if (c != 0) return c; + if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { + c = GPR_ICMP(c1->expected_targets, c2->expected_targets); + } else { + c = strcmp(c1->expected_targets, c2->expected_targets); + } + if (c != 0) return c; + return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); +} + +static int fake_server_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + return grpc_server_security_connector_cmp( + reinterpret_cast<grpc_server_security_connector*>(sc1), + reinterpret_cast<grpc_server_security_connector*>(sc2)); +} + +static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, + const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) { + grpc_fake_channel_security_connector* c = + reinterpret_cast<grpc_fake_channel_security_connector*>(sc); + char* authority_hostname = nullptr; + char* authority_ignored_port = nullptr; + char* target_hostname = nullptr; + char* target_ignored_port = nullptr; + gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); + gpr_split_host_port(c->target, &target_hostname, &target_ignored_port); + if (c->target_name_override != nullptr) { + char* fake_security_target_name_override_hostname = nullptr; + char* fake_security_target_name_override_ignored_port = nullptr; + gpr_split_host_port(c->target_name_override, + &fake_security_target_name_override_hostname, + &fake_security_target_name_override_ignored_port); + if (strcmp(authority_hostname, + fake_security_target_name_override_hostname) != 0) { + gpr_log(GPR_ERROR, + "Authority (host) '%s' != Fake Security Target override '%s'", + host, fake_security_target_name_override_hostname); + abort(); + } + gpr_free(fake_security_target_name_override_hostname); + gpr_free(fake_security_target_name_override_ignored_port); + } else if (strcmp(authority_hostname, target_hostname) != 0) { + gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", + authority_hostname, target_hostname); + abort(); + } + gpr_free(authority_hostname); + gpr_free(authority_ignored_port); + gpr_free(target_hostname); + gpr_free(target_ignored_port); + return true; +} + +static void fake_channel_cancel_check_call_host( + grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, + grpc_error* error) { + GRPC_ERROR_UNREF(error); +} + +static void fake_channel_add_handshakers( + grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_handshake_manager_add( + handshake_mgr, + grpc_security_handshaker_create( + tsi_create_fake_handshaker(true /* is_client */), &sc->base)); +} + +static void fake_server_add_handshakers(grpc_server_security_connector* sc, + grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_handshake_manager_add( + handshake_mgr, + grpc_security_handshaker_create( + tsi_create_fake_handshaker(false /* is_client */), &sc->base)); +} + +static grpc_security_connector_vtable fake_channel_vtable = { + fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; + +static grpc_security_connector_vtable fake_server_vtable = { + fake_server_destroy, fake_server_check_peer, fake_server_cmp}; + +grpc_channel_security_connector* grpc_fake_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, const char* target, + const grpc_channel_args* args) { + grpc_fake_channel_security_connector* c = + static_cast<grpc_fake_channel_security_connector*>( + gpr_zalloc(sizeof(*c))); + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + c->base.base.vtable = &fake_channel_vtable; + c->base.channel_creds = channel_creds; + c->base.request_metadata_creds = + grpc_call_credentials_ref(request_metadata_creds); + c->base.check_call_host = fake_channel_check_call_host; + c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; + c->base.add_handshakers = fake_channel_add_handshakers; + c->target = gpr_strdup(target); + const char* expected_targets = grpc_fake_transport_get_expected_targets(args); + c->expected_targets = gpr_strdup(expected_targets); + c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr; + const grpc_arg* target_name_override_arg = + grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); + if (target_name_override_arg != nullptr) { + c->target_name_override = + gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); + } + return &c->base; +} + +grpc_server_security_connector* grpc_fake_server_security_connector_create( + grpc_server_credentials* server_creds) { + grpc_server_security_connector* c = + static_cast<grpc_server_security_connector*>( + gpr_zalloc(sizeof(grpc_server_security_connector))); + gpr_ref_init(&c->base.refcount, 1); + c->base.vtable = &fake_server_vtable; + c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; + c->server_creds = server_creds; + c->add_handshakers = fake_server_add_handshakers; + return c; +} diff --git a/src/core/lib/security/security_connector/fake/fake_security_connector.h b/src/core/lib/security/security_connector/fake/fake_security_connector.h new file mode 100644 index 0000000000..fdfe048c6e --- /dev/null +++ b/src/core/lib/security/security_connector/fake/fake_security_connector.h @@ -0,0 +1,42 @@ +/* + * + * Copyright 2018 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_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc_security.h> + +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/security/security_connector/security_connector.h" + +#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" + +/* Creates a fake connector that emulates real channel security. */ +grpc_channel_security_connector* grpc_fake_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, const char* target, + const grpc_channel_args* args); + +/* Creates a fake connector that emulates real server security. */ +grpc_server_security_connector* grpc_fake_server_security_connector_create( + grpc_server_credentials* server_creds); + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_FAKE_FAKE_SECURITY_CONNECTOR_H \ + */ diff --git a/src/core/lib/security/security_connector/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc index 911013ae58..008a98df28 100644 --- a/src/core/lib/security/security_connector/local_security_connector.cc +++ b/src/core/lib/security/security_connector/local/local_security_connector.cc @@ -18,7 +18,7 @@ #include <grpc/support/port_platform.h> -#include "src/core/lib/security/security_connector/local_security_connector.h" +#include "src/core/lib/security/security_connector/local/local_security_connector.h" #include <stdbool.h> #include <string.h> diff --git a/src/core/lib/security/security_connector/local_security_connector.h b/src/core/lib/security/security_connector/local/local_security_connector.h index a970a74788..5369a2127a 100644 --- a/src/core/lib/security/security_connector/local_security_connector.h +++ b/src/core/lib/security/security_connector/local/local_security_connector.h @@ -16,8 +16,8 @@ * */ -#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H -#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H #include <grpc/support/port_platform.h> @@ -54,5 +54,5 @@ grpc_security_status grpc_local_channel_security_connector_create( grpc_security_status grpc_local_server_security_connector_create( grpc_server_credentials* server_creds, grpc_server_security_connector** sc); -#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_SECURITY_CONNECTOR_H \ +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_LOCAL_LOCAL_SECURITY_CONNECTOR_H \ */ diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc index 7028ae8d16..02cecb0eb1 100644 --- a/src/core/lib/security/security_connector/security_connector.cc +++ b/src/core/lib/security/security_connector/security_connector.cc @@ -20,8 +20,6 @@ #include "src/core/lib/security/security_connector/security_connector.h" -#include <stdbool.h> - #include <grpc/slice_buffer.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> @@ -36,88 +34,12 @@ #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" #include "src/core/lib/security/security_connector/load_system_roots.h" -#include "src/core/lib/security/transport/secure_endpoint.h" #include "src/core/lib/security/transport/security_handshaker.h" -#include "src/core/lib/security/transport/target_authority_table.h" -#include "src/core/tsi/fake_transport_security.h" -#include "src/core/tsi/ssl_transport_security.h" grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount( false, "security_connector_refcount"); -/* -- Constants. -- */ - -#ifndef INSTALL_PREFIX -static const char* installed_roots_path = "/usr/share/grpc/roots.pem"; -#else -static const char* installed_roots_path = - INSTALL_PREFIX "/share/grpc/roots.pem"; -#endif - -/** Environment variable used as a flag to enable/disable loading system root - certificates from the OS trust store. */ -#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR -#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" -#endif - -#ifndef TSI_OPENSSL_ALPN_SUPPORT -#define TSI_OPENSSL_ALPN_SUPPORT 1 -#endif - -/* -- Overridden default roots. -- */ - -static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr; - -void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { - ssl_roots_override_cb = cb; -} - -/* -- Cipher suites. -- */ - -/* Defines the cipher suites that we accept by default. All these cipher suites - are compliant with HTTP2. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-ECDSA-AES128-GCM-SHA256:" \ - "ECDHE-ECDSA-AES256-GCM-SHA384:" \ - "ECDHE-RSA-AES128-GCM-SHA256:" \ - "ECDHE-RSA-AES256-GCM-SHA384" - -static gpr_once cipher_suites_once = GPR_ONCE_INIT; -static const char* cipher_suites = nullptr; - -static void init_cipher_suites(void) { - char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); - cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; -} - -static const char* ssl_cipher_suites(void) { - gpr_once_init(&cipher_suites_once, init_cipher_suites); - return cipher_suites; -} - -/* -- Common methods. -- */ - -/* Returns the first property with that name. */ -const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, - const char* name) { - size_t i; - if (peer == nullptr) return nullptr; - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property* property = &peer->properties[i]; - if (name == nullptr && property->name == nullptr) { - return property; - } - if (name != nullptr && property->name != nullptr && - strcmp(property->name, name) == 0) { - return property; - } - } - return nullptr; -} - void grpc_channel_security_connector_add_handshakers( grpc_channel_security_connector* connector, grpc_pollset_set* interested_parties, @@ -288,965 +210,3 @@ grpc_security_connector* grpc_security_connector_find_in_args( } return nullptr; } - -static tsi_client_certificate_request_type -get_tsi_client_certificate_request_type( - grpc_ssl_client_certificate_request_type grpc_request_type) { - switch (grpc_request_type) { - case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE: - return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; - - case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; - - case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: - return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY; - - case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: - return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; - - case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: - return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; - - default: - return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; - } -} - -/* -- Fake implementation. -- */ - -typedef struct { - grpc_channel_security_connector base; - char* target; - char* expected_targets; - bool is_lb_channel; - char* target_name_override; -} grpc_fake_channel_security_connector; - -static void fake_channel_destroy(grpc_security_connector* sc) { - grpc_fake_channel_security_connector* c = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc); - grpc_call_credentials_unref(c->base.request_metadata_creds); - gpr_free(c->target); - gpr_free(c->expected_targets); - gpr_free(c->target_name_override); - gpr_free(c); -} - -static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); } - -static bool fake_check_target(const char* target_type, const char* target, - const char* set_str) { - GPR_ASSERT(target_type != nullptr); - GPR_ASSERT(target != nullptr); - char** set = nullptr; - size_t set_size = 0; - gpr_string_split(set_str, ",", &set, &set_size); - bool found = false; - for (size_t i = 0; i < set_size; ++i) { - if (set[i] != nullptr && strcmp(target, set[i]) == 0) found = true; - } - for (size_t i = 0; i < set_size; ++i) { - gpr_free(set[i]); - } - gpr_free(set); - return found; -} - -static void fake_secure_name_check(const char* target, - const char* expected_targets, - bool is_lb_channel) { - if (expected_targets == nullptr) return; - char** lbs_and_backends = nullptr; - size_t lbs_and_backends_size = 0; - bool success = false; - gpr_string_split(expected_targets, ";", &lbs_and_backends, - &lbs_and_backends_size); - if (lbs_and_backends_size > 2 || lbs_and_backends_size == 0) { - gpr_log(GPR_ERROR, "Invalid expected targets arg value: '%s'", - expected_targets); - goto done; - } - if (is_lb_channel) { - if (lbs_and_backends_size != 2) { - gpr_log(GPR_ERROR, - "Invalid expected targets arg value: '%s'. Expectations for LB " - "channels must be of the form 'be1,be2,be3,...;lb1,lb2,...", - expected_targets); - goto done; - } - if (!fake_check_target("LB", target, lbs_and_backends[1])) { - gpr_log(GPR_ERROR, "LB target '%s' not found in expected set '%s'", - target, lbs_and_backends[1]); - goto done; - } - success = true; - } else { - if (!fake_check_target("Backend", target, lbs_and_backends[0])) { - gpr_log(GPR_ERROR, "Backend target '%s' not found in expected set '%s'", - target, lbs_and_backends[0]); - goto done; - } - success = true; - } -done: - for (size_t i = 0; i < lbs_and_backends_size; ++i) { - gpr_free(lbs_and_backends[i]); - } - gpr_free(lbs_and_backends); - if (!success) abort(); -} - -static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - const char* prop_name; - grpc_error* error = GRPC_ERROR_NONE; - *auth_context = nullptr; - if (peer.property_count != 1) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Fake peers should only have 1 property."); - goto end; - } - prop_name = peer.properties[0].name; - if (prop_name == nullptr || - strcmp(prop_name, TSI_CERTIFICATE_TYPE_PEER_PROPERTY)) { - char* msg; - gpr_asprintf(&msg, "Unexpected property in fake peer: %s.", - prop_name == nullptr ? "<EMPTY>" : prop_name); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - goto end; - } - if (strncmp(peer.properties[0].value.data, TSI_FAKE_CERTIFICATE_TYPE, - peer.properties[0].value.length)) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Invalid value for cert type property."); - goto end; - } - *auth_context = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property( - *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, - GRPC_FAKE_TRANSPORT_SECURITY_TYPE); -end: - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} - -static void fake_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); - grpc_fake_channel_security_connector* c = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc); - fake_secure_name_check(c->target, c->expected_targets, c->is_lb_channel); -} - -static void fake_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - fake_check_peer(sc, peer, auth_context, on_peer_checked); -} - -static int fake_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_fake_channel_security_connector* c1 = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc1); - grpc_fake_channel_security_connector* c2 = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target, c2->target); - if (c != 0) return c; - if (c1->expected_targets == nullptr || c2->expected_targets == nullptr) { - c = GPR_ICMP(c1->expected_targets, c2->expected_targets); - } else { - c = strcmp(c1->expected_targets, c2->expected_targets); - } - if (c != 0) return c; - return GPR_ICMP(c1->is_lb_channel, c2->is_lb_channel); -} - -static int fake_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast<grpc_server_security_connector*>(sc1), - reinterpret_cast<grpc_server_security_connector*>(sc2)); -} - -static bool fake_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_fake_channel_security_connector* c = - reinterpret_cast<grpc_fake_channel_security_connector*>(sc); - char* authority_hostname = nullptr; - char* authority_ignored_port = nullptr; - char* target_hostname = nullptr; - char* target_ignored_port = nullptr; - gpr_split_host_port(host, &authority_hostname, &authority_ignored_port); - gpr_split_host_port(c->target, &target_hostname, &target_ignored_port); - if (c->target_name_override != nullptr) { - char* fake_security_target_name_override_hostname = nullptr; - char* fake_security_target_name_override_ignored_port = nullptr; - gpr_split_host_port(c->target_name_override, - &fake_security_target_name_override_hostname, - &fake_security_target_name_override_ignored_port); - if (strcmp(authority_hostname, - fake_security_target_name_override_hostname) != 0) { - gpr_log(GPR_ERROR, - "Authority (host) '%s' != Fake Security Target override '%s'", - host, fake_security_target_name_override_hostname); - abort(); - } - gpr_free(fake_security_target_name_override_hostname); - gpr_free(fake_security_target_name_override_ignored_port); - } else if (strcmp(authority_hostname, target_hostname) != 0) { - gpr_log(GPR_ERROR, "Authority (host) '%s' != Target '%s'", - authority_hostname, target_hostname); - abort(); - } - gpr_free(authority_hostname); - gpr_free(authority_ignored_port); - gpr_free(target_hostname); - gpr_free(target_ignored_port); - return true; -} - -static void fake_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static void fake_channel_add_handshakers( - grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(true /* is_client */), &sc->base)); -} - -static void fake_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_handshake_manager_add( - handshake_mgr, - grpc_security_handshaker_create( - tsi_create_fake_handshaker(false /* is_client */), &sc->base)); -} - -static grpc_security_connector_vtable fake_channel_vtable = { - fake_channel_destroy, fake_channel_check_peer, fake_channel_cmp}; - -static grpc_security_connector_vtable fake_server_vtable = { - fake_server_destroy, fake_server_check_peer, fake_server_cmp}; - -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args) { - grpc_fake_channel_security_connector* c = - static_cast<grpc_fake_channel_security_connector*>( - gpr_zalloc(sizeof(*c))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->base.base.vtable = &fake_channel_vtable; - c->base.channel_creds = channel_creds; - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = fake_channel_check_call_host; - c->base.cancel_check_call_host = fake_channel_cancel_check_call_host; - c->base.add_handshakers = fake_channel_add_handshakers; - c->target = gpr_strdup(target); - const char* expected_targets = grpc_fake_transport_get_expected_targets(args); - c->expected_targets = gpr_strdup(expected_targets); - c->is_lb_channel = grpc_core::FindTargetAuthorityTableInArgs(args) != nullptr; - const grpc_arg* target_name_override_arg = - grpc_channel_args_find(args, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG); - if (target_name_override_arg != nullptr) { - c->target_name_override = - gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg)); - } - return &c->base; -} - -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds) { - grpc_server_security_connector* c = - static_cast<grpc_server_security_connector*>( - gpr_zalloc(sizeof(grpc_server_security_connector))); - gpr_ref_init(&c->base.refcount, 1); - c->base.vtable = &fake_server_vtable; - c->base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME; - c->server_creds = server_creds; - c->add_handshakers = fake_server_add_handshakers; - return c; -} - -/* --- Ssl implementation. --- */ - -grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) { - tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity); - return reinterpret_cast<grpc_ssl_session_cache*>(cache); -} - -void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) { - tsi_ssl_session_cache* tsi_cache = - reinterpret_cast<tsi_ssl_session_cache*>(cache); - tsi_ssl_session_cache_unref(tsi_cache); -} - -static void* grpc_ssl_session_cache_arg_copy(void* p) { - tsi_ssl_session_cache* tsi_cache = - reinterpret_cast<tsi_ssl_session_cache*>(p); - // destroy call below will unref the pointer. - tsi_ssl_session_cache_ref(tsi_cache); - return p; -} - -static void grpc_ssl_session_cache_arg_destroy(void* p) { - tsi_ssl_session_cache* tsi_cache = - reinterpret_cast<tsi_ssl_session_cache*>(p); - tsi_ssl_session_cache_unref(tsi_cache); -} - -static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) { - return GPR_ICMP(p, q); -} - -grpc_arg grpc_ssl_session_cache_create_channel_arg( - grpc_ssl_session_cache* cache) { - static const grpc_arg_pointer_vtable vtable = { - grpc_ssl_session_cache_arg_copy, - grpc_ssl_session_cache_arg_destroy, - grpc_ssl_session_cache_arg_cmp, - }; - return grpc_channel_arg_pointer_create( - const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable); -} - -typedef struct { - grpc_channel_security_connector base; - tsi_ssl_client_handshaker_factory* client_handshaker_factory; - char* target_name; - char* overridden_target_name; - const verify_peer_options* verify_options; -} grpc_ssl_channel_security_connector; - -typedef struct { - grpc_server_security_connector base; - tsi_ssl_server_handshaker_factory* server_handshaker_factory; -} grpc_ssl_server_security_connector; - -static bool server_connector_has_cert_config_fetcher( - grpc_ssl_server_security_connector* c) { - GPR_ASSERT(c != nullptr); - grpc_ssl_server_credentials* server_creds = - reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds); - GPR_ASSERT(server_creds != nullptr); - return server_creds->certificate_config_fetcher.cb != nullptr; -} - -static void ssl_channel_destroy(grpc_security_connector* sc) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - grpc_channel_credentials_unref(c->base.channel_creds); - grpc_call_credentials_unref(c->base.request_metadata_creds); - tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); - c->client_handshaker_factory = nullptr; - if (c->target_name != nullptr) gpr_free(c->target_name); - if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); - gpr_free(sc); -} - -static void ssl_server_destroy(grpc_security_connector* sc) { - grpc_ssl_server_security_connector* c = - reinterpret_cast<grpc_ssl_server_security_connector*>(sc); - grpc_server_credentials_unref(c->base.server_creds); - tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); - c->server_handshaker_factory = nullptr; - gpr_free(sc); -} - -static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - // Instantiate TSI handshaker. - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( - c->client_handshaker_factory, - c->overridden_target_name != nullptr ? c->overridden_target_name - : c->target_name, - &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -static const char** fill_alpn_protocol_strings(size_t* num_alpn_protocols) { - GPR_ASSERT(num_alpn_protocols != nullptr); - *num_alpn_protocols = grpc_chttp2_num_alpn_versions(); - const char** alpn_protocol_strings = static_cast<const char**>( - gpr_malloc(sizeof(const char*) * (*num_alpn_protocols))); - for (size_t i = 0; i < *num_alpn_protocols; i++) { - alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i); - } - return alpn_protocol_strings; -} - -/* Attempts to replace the server_handshaker_factory with a new factory using - * the provided grpc_ssl_server_certificate_config. Should new factory creation - * fail, the existing factory will not be replaced. Returns true on success (new - * factory created). */ -static bool try_replace_server_handshaker_factory( - grpc_ssl_server_security_connector* sc, - const grpc_ssl_server_certificate_config* config) { - if (config == nullptr) { - gpr_log(GPR_ERROR, - "Server certificate config callback returned invalid (NULL) " - "config."); - return false; - } - gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); - - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - fill_alpn_protocol_strings(&num_alpn_protocols); - tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( - config->pem_key_cert_pairs, config->num_key_cert_pairs); - tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; - grpc_ssl_server_credentials* server_creds = - reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); - tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( - cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, - get_tsi_client_certificate_request_type( - server_creds->config.client_certificate_request), - ssl_cipher_suites(), alpn_protocol_strings, - static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory); - gpr_free(cert_pairs); - gpr_free((void*)alpn_protocol_strings); - - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - return false; - } - tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); - sc->server_handshaker_factory = new_handshaker_factory; - return true; -} - -/* Attempts to fetch the server certificate config if a callback is available. - * Current certificate config will continue to be used if the callback returns - * an error. Returns true if new credentials were sucessfully loaded. */ -static bool try_fetch_ssl_server_credentials( - grpc_ssl_server_security_connector* sc) { - grpc_ssl_server_certificate_config* certificate_config = nullptr; - bool status; - - GPR_ASSERT(sc != nullptr); - if (!server_connector_has_cert_config_fetcher(sc)) return false; - - grpc_ssl_server_credentials* server_creds = - reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); - grpc_ssl_certificate_config_reload_status cb_result = - server_creds->certificate_config_fetcher.cb( - server_creds->certificate_config_fetcher.user_data, - &certificate_config); - if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { - gpr_log(GPR_DEBUG, "No change in SSL server credentials."); - status = false; - } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { - status = try_replace_server_handshaker_factory(sc, certificate_config); - } else { - // Log error, continue using previously-loaded credentials. - gpr_log(GPR_ERROR, - "Failed fetching new server credentials, continuing to " - "use previously-loaded credentials."); - status = false; - } - - if (certificate_config != nullptr) { - grpc_ssl_server_certificate_config_destroy(certificate_config); - } - return status; -} - -static void ssl_server_add_handshakers(grpc_server_security_connector* sc, - grpc_pollset_set* interested_parties, - grpc_handshake_manager* handshake_mgr) { - grpc_ssl_server_security_connector* c = - reinterpret_cast<grpc_ssl_server_security_connector*>(sc); - // Instantiate TSI handshaker. - try_fetch_ssl_server_credentials(c); - tsi_handshaker* tsi_hs = nullptr; - tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( - c->server_handshaker_factory, &tsi_hs); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", - tsi_result_to_string(result)); - return; - } - // Create handshakers. - grpc_handshake_manager_add( - handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); -} - -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { - char* allocated_name = nullptr; - int r; - - char* ignored_port; - gpr_split_host_port(peer_name, &allocated_name, &ignored_port); - gpr_free(ignored_port); - peer_name = allocated_name; - if (!peer_name) return 0; - - // IPv6 zone-id should not be included in comparisons. - char* const zone_id = strchr(allocated_name, '%'); - if (zone_id != nullptr) *zone_id = '\0'; - - r = tsi_ssl_peer_matches_name(peer, peer_name); - gpr_free(allocated_name); - return r; -} - -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { - size_t i; - grpc_auth_context* ctx = nullptr; - const char* peer_identity_property_name = nullptr; - - /* The caller has checked the certificate type property. */ - GPR_ASSERT(peer->property_count >= 1); - ctx = grpc_auth_context_create(nullptr); - grpc_auth_context_add_cstring_property( - ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, - GRPC_SSL_TRANSPORT_SECURITY_TYPE); - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property* prop = &peer->properties[i]; - if (prop->name == nullptr) continue; - if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { - /* If there is no subject alt name, have the CN as the identity. */ - if (peer_identity_property_name == nullptr) { - peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; - } - grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { - peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; - grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, - prop->value.data, prop->value.length); - } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { - grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, - prop->value.data, prop->value.length); - } - } - if (peer_identity_property_name != nullptr) { - GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( - ctx, peer_identity_property_name) == 1); - } - return ctx; -} - -static grpc_error* ssl_check_peer(grpc_security_connector* sc, - const char* peer_name, const tsi_peer* peer, - grpc_auth_context** auth_context) { -#if TSI_OPENSSL_ALPN_SUPPORT - /* Check the ALPN if ALPN is supported. */ - const tsi_peer_property* p = - tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); - if (p == nullptr) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing selected ALPN property."); - } - if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: invalid ALPN value."); - } -#endif /* TSI_OPENSSL_ALPN_SUPPORT */ - /* Check the peer name if specified. */ - if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { - char* msg; - gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); - grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - return error; - } - *auth_context = grpc_ssl_peer_to_auth_context(peer); - return GRPC_ERROR_NONE; -} - -static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - const char* target_name = c->overridden_target_name != nullptr - ? c->overridden_target_name - : c->target_name; - grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); - if (error == GRPC_ERROR_NONE && - c->verify_options->verify_peer_callback != nullptr) { - const tsi_peer_property* p = - tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); - if (p == nullptr) { - error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "Cannot check peer: missing pem cert property."); - } else { - char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1)); - memcpy(peer_pem, p->value.data, p->value.length); - peer_pem[p->value.length] = '\0'; - int callback_status = c->verify_options->verify_peer_callback( - target_name, peer_pem, - c->verify_options->verify_peer_callback_userdata); - gpr_free(peer_pem); - if (callback_status) { - char* msg; - gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", - callback_status); - error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); - gpr_free(msg); - } - } - } - GRPC_CLOSURE_SCHED(on_peer_checked, error); - tsi_peer_destruct(&peer); -} - -static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, - grpc_auth_context** auth_context, - grpc_closure* on_peer_checked) { - grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); - tsi_peer_destruct(&peer); - GRPC_CLOSURE_SCHED(on_peer_checked, error); -} - -static int ssl_channel_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - grpc_ssl_channel_security_connector* c1 = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1); - grpc_ssl_channel_security_connector* c2 = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2); - int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); - if (c != 0) return c; - c = strcmp(c1->target_name, c2->target_name); - if (c != 0) return c; - return (c1->overridden_target_name == nullptr || - c2->overridden_target_name == nullptr) - ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) - : strcmp(c1->overridden_target_name, c2->overridden_target_name); -} - -static int ssl_server_cmp(grpc_security_connector* sc1, - grpc_security_connector* sc2) { - return grpc_server_security_connector_cmp( - reinterpret_cast<grpc_server_security_connector*>(sc1), - reinterpret_cast<grpc_server_security_connector*>(sc2)); -} - -static void add_shallow_auth_property_to_peer(tsi_peer* peer, - const grpc_auth_property* prop, - const char* tsi_prop_name) { - tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++]; - tsi_prop->name = const_cast<char*>(tsi_prop_name); - tsi_prop->value.data = prop->value; - tsi_prop->value.length = prop->value_length; -} - -tsi_peer grpc_shallow_peer_from_ssl_auth_context( - const grpc_auth_context* auth_context) { - size_t max_num_props = 0; - grpc_auth_property_iterator it; - const grpc_auth_property* prop; - tsi_peer peer; - memset(&peer, 0, sizeof(peer)); - - it = grpc_auth_context_property_iterator(auth_context); - while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++; - - if (max_num_props > 0) { - peer.properties = static_cast<tsi_peer_property*>( - gpr_malloc(max_num_props * sizeof(tsi_peer_property))); - it = grpc_auth_context_property_iterator(auth_context); - while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) { - if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer( - &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY); - } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer( - &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { - add_shallow_auth_property_to_peer(&peer, prop, - TSI_X509_PEM_CERT_PROPERTY); - } - } - } - return peer; -} - -void grpc_shallow_peer_destruct(tsi_peer* peer) { - if (peer->properties != nullptr) gpr_free(peer->properties); -} - -static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, - const char* host, - grpc_auth_context* auth_context, - grpc_closure* on_call_host_checked, - grpc_error** error) { - grpc_ssl_channel_security_connector* c = - reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); - grpc_security_status status = GRPC_SECURITY_ERROR; - tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); - if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; - /* If the target name was overridden, then the original target_name was - 'checked' transitively during the previous peer check at the end of the - handshake. */ - if (c->overridden_target_name != nullptr && - strcmp(host, c->target_name) == 0) { - status = GRPC_SECURITY_OK; - } - if (status != GRPC_SECURITY_OK) { - *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "call host does not match SSL server name"); - } - grpc_shallow_peer_destruct(&peer); - return true; -} - -static void ssl_channel_cancel_check_call_host( - grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, - grpc_error* error) { - GRPC_ERROR_UNREF(error); -} - -static grpc_security_connector_vtable ssl_channel_vtable = { - ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; - -static grpc_security_connector_vtable ssl_server_vtable = { - ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; - -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_channel_security_connector* c; - char* port; - bool has_key_cert_pair; - tsi_ssl_client_handshaker_options options; - memset(&options, 0, sizeof(options)); - options.alpn_protocols = - fill_alpn_protocol_strings(&options.num_alpn_protocols); - - if (config == nullptr || target_name == nullptr) { - gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); - goto error; - } - if (config->pem_root_certs == nullptr) { - // Use default root certificates. - options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); - options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); - if (options.pem_root_certs == nullptr) { - gpr_log(GPR_ERROR, "Could not get default pem root certs."); - goto error; - } - } else { - options.pem_root_certs = config->pem_root_certs; - } - c = static_cast<grpc_ssl_channel_security_connector*>( - gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); - - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.vtable = &ssl_channel_vtable; - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); - c->base.request_metadata_creds = - grpc_call_credentials_ref(request_metadata_creds); - c->base.check_call_host = ssl_channel_check_call_host; - c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; - c->base.add_handshakers = ssl_channel_add_handshakers; - gpr_split_host_port(target_name, &c->target_name, &port); - gpr_free(port); - if (overridden_target_name != nullptr) { - c->overridden_target_name = gpr_strdup(overridden_target_name); - } - c->verify_options = &config->verify_options; - - has_key_cert_pair = config->pem_key_cert_pair != nullptr && - config->pem_key_cert_pair->private_key != nullptr && - config->pem_key_cert_pair->cert_chain != nullptr; - if (has_key_cert_pair) { - options.pem_key_cert_pair = config->pem_key_cert_pair; - } - options.cipher_suites = ssl_cipher_suites(); - options.session_cache = ssl_session_cache; - result = tsi_create_ssl_client_handshaker_factory_with_options( - &options, &c->client_handshaker_factory); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - ssl_channel_destroy(&c->base.base); - *sc = nullptr; - goto error; - } - *sc = &c->base; - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_OK; - -error: - gpr_free((void*)options.alpn_protocols); - return GRPC_SECURITY_ERROR; -} - -static grpc_ssl_server_security_connector* -grpc_ssl_server_security_connector_initialize( - grpc_server_credentials* server_creds) { - grpc_ssl_server_security_connector* c = - static_cast<grpc_ssl_server_security_connector*>( - gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); - gpr_ref_init(&c->base.base.refcount, 1); - c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; - c->base.base.vtable = &ssl_server_vtable; - c->base.add_handshakers = ssl_server_add_handshakers; - c->base.server_creds = grpc_server_credentials_ref(server_creds); - return c; -} - -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* gsc, grpc_server_security_connector** sc) { - tsi_result result = TSI_OK; - grpc_ssl_server_credentials* server_credentials = - reinterpret_cast<grpc_ssl_server_credentials*>(gsc); - grpc_security_status retval = GRPC_SECURITY_OK; - - GPR_ASSERT(server_credentials != nullptr); - GPR_ASSERT(sc != nullptr); - - grpc_ssl_server_security_connector* c = - grpc_ssl_server_security_connector_initialize(gsc); - if (server_connector_has_cert_config_fetcher(c)) { - // Load initial credentials from certificate_config_fetcher: - if (!try_fetch_ssl_server_credentials(c)) { - gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); - retval = GRPC_SECURITY_ERROR; - } - } else { - size_t num_alpn_protocols = 0; - const char** alpn_protocol_strings = - fill_alpn_protocol_strings(&num_alpn_protocols); - result = tsi_create_ssl_server_handshaker_factory_ex( - server_credentials->config.pem_key_cert_pairs, - server_credentials->config.num_key_cert_pairs, - server_credentials->config.pem_root_certs, - get_tsi_client_certificate_request_type( - server_credentials->config.client_certificate_request), - ssl_cipher_suites(), alpn_protocol_strings, - static_cast<uint16_t>(num_alpn_protocols), - &c->server_handshaker_factory); - gpr_free((void*)alpn_protocol_strings); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", - tsi_result_to_string(result)); - retval = GRPC_SECURITY_ERROR; - } - } - - if (retval == GRPC_SECURITY_OK) { - *sc = &c->base; - } else { - if (c != nullptr) ssl_server_destroy(&c->base.base); - if (sc != nullptr) *sc = nullptr; - } - return retval; -} - -namespace grpc_core { - -tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_; -grpc_slice DefaultSslRootStore::default_pem_root_certs_; - -const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() { - InitRootStore(); - return default_root_store_; -} - -const char* DefaultSslRootStore::GetPemRootCerts() { - InitRootStore(); - return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_) - ? nullptr - : reinterpret_cast<const char*> - GRPC_SLICE_START_PTR(default_pem_root_certs_); -} - -grpc_slice DefaultSslRootStore::ComputePemRootCerts() { - grpc_slice result = grpc_empty_slice(); - char* not_use_system_roots_env_value = - gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); - const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); - gpr_free(not_use_system_roots_env_value); - // First try to load the roots from the environment. - char* default_root_certs_path = - gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); - if (default_root_certs_path != nullptr) { - GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(default_root_certs_path, 1, &result)); - gpr_free(default_root_certs_path); - } - // Try overridden roots if needed. - grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; - if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) { - char* pem_root_certs = nullptr; - ovrd_res = ssl_roots_override_cb(&pem_root_certs); - if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) { - GPR_ASSERT(pem_root_certs != nullptr); - result = grpc_slice_from_copied_buffer( - pem_root_certs, - strlen(pem_root_certs) + 1); // nullptr terminator. - } - gpr_free(pem_root_certs); - } - // Try loading roots from OS trust store if flag is enabled. - if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) { - result = LoadSystemRootCerts(); - } - // Fallback to roots manually shipped with gRPC. - if (GRPC_SLICE_IS_EMPTY(result) && - ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) { - GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(installed_roots_path, 1, &result)); - } - return result; -} - -void DefaultSslRootStore::InitRootStore() { - static gpr_once once = GPR_ONCE_INIT; - gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce); -} - -void DefaultSslRootStore::InitRootStoreOnce() { - default_pem_root_certs_ = ComputePemRootCerts(); - if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) { - default_root_store_ = - tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>( - GRPC_SLICE_START_PTR(default_pem_root_certs_))); - } -} - -} // namespace grpc_core diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h index d8df3cd72f..4c921a8793 100644 --- a/src/core/lib/security/security_connector/security_connector.h +++ b/src/core/lib/security/security_connector/security_connector.h @@ -38,11 +38,6 @@ extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount; typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status; -/* --- URL schemes. --- */ - -#define GRPC_SSL_URL_SCHEME "https" -#define GRPC_FAKE_SECURITY_URL_SCHEME "http+fake_security" - /* --- security_connector object. --- A security connector object represents away to configure the underlying @@ -179,112 +174,4 @@ void grpc_server_security_connector_add_handshakers( grpc_server_security_connector* sc, grpc_pollset_set* interested_parties, grpc_handshake_manager* handshake_mgr); -/* --- Creation security connectors. --- */ - -/* For TESTING ONLY! - Creates a fake connector that emulates real channel security. */ -grpc_channel_security_connector* grpc_fake_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, const char* target, - const grpc_channel_args* args); - -/* For TESTING ONLY! - Creates a fake connector that emulates real server security. */ -grpc_server_security_connector* grpc_fake_server_security_connector_create( - grpc_server_credentials* server_creds); - -/* Config for ssl clients. */ - -typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pair; - char* pem_root_certs; - verify_peer_options verify_options; -} grpc_ssl_config; - -/* Creates an SSL channel_security_connector. - - request_metadata_creds is the credentials object which metadata - will be sent with each request. This parameter can be NULL. - - config is the SSL config to be used for the SSL channel establishment. - - is_client should be 0 for a server or a non-0 value for a client. - - secure_peer_name is the secure peer name that should be checked in - grpc_channel_security_connector_check_peer. This parameter may be NULL in - which case the peer name will not be checked. Note that if this parameter - is not NULL, then, pem_root_certs should not be NULL either. - - sc is a pointer on the connector to be created. - This function returns GRPC_SECURITY_OK in case of success or a - specific error code otherwise. -*/ -grpc_security_status grpc_ssl_channel_security_connector_create( - grpc_channel_credentials* channel_creds, - grpc_call_credentials* request_metadata_creds, - const grpc_ssl_config* config, const char* target_name, - const char* overridden_target_name, - tsi_ssl_session_cache* ssl_session_cache, - grpc_channel_security_connector** sc); - -/* Config for ssl servers. */ -typedef struct { - tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; - size_t num_key_cert_pairs; - char* pem_root_certs; - grpc_ssl_client_certificate_request_type client_certificate_request; -} grpc_ssl_server_config; - -/* Creates an SSL server_security_connector. - - config is the SSL config to be used for the SSL channel establishment. - - sc is a pointer on the connector to be created. - This function returns GRPC_SECURITY_OK in case of success or a - specific error code otherwise. -*/ -grpc_security_status grpc_ssl_server_security_connector_create( - grpc_server_credentials* server_credentials, - grpc_server_security_connector** sc); - -/* Util. */ -const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, - const char* name); - -/* Exposed for testing only. */ -grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); -tsi_peer grpc_shallow_peer_from_ssl_auth_context( - const grpc_auth_context* auth_context); -void grpc_shallow_peer_destruct(tsi_peer* peer); -int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); - -/* --- Default SSL Root Store. --- */ -namespace grpc_core { - -// The class implements default SSL root store. -class DefaultSslRootStore { - public: - // Gets the default SSL root store. Returns nullptr if not found. - static const tsi_ssl_root_certs_store* GetRootStore(); - - // Gets the default PEM root certificate. - static const char* GetPemRootCerts(); - - protected: - // Returns default PEM root certificates in nullptr terminated grpc_slice. - // This function is protected instead of private, so that it can be tested. - static grpc_slice ComputePemRootCerts(); - - private: - // Construct me not! - DefaultSslRootStore(); - - // Initialization of default SSL root store. - static void InitRootStore(); - - // One-time initialization of default SSL root store. - static void InitRootStoreOnce(); - - // SSL root store in tsi_ssl_root_certs_store object. - static tsi_ssl_root_certs_store* default_root_store_; - - // Default PEM root certificates. - static grpc_slice default_pem_root_certs_; -}; - -} // namespace grpc_core - #endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SECURITY_CONNECTOR_H */ diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc new file mode 100644 index 0000000000..20a9533dd1 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc @@ -0,0 +1,474 @@ +/* + * + * Copyright 2018 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/lib/security/security_connector/ssl/ssl_security_connector.h" + +#include <stdbool.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/channel/handshaker.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" +#include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" +#include "src/core/lib/security/transport/security_handshaker.h" +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security.h" + +typedef struct { + grpc_channel_security_connector base; + tsi_ssl_client_handshaker_factory* client_handshaker_factory; + char* target_name; + char* overridden_target_name; + const verify_peer_options* verify_options; +} grpc_ssl_channel_security_connector; + +typedef struct { + grpc_server_security_connector base; + tsi_ssl_server_handshaker_factory* server_handshaker_factory; +} grpc_ssl_server_security_connector; + +static bool server_connector_has_cert_config_fetcher( + grpc_ssl_server_security_connector* c) { + GPR_ASSERT(c != nullptr); + grpc_ssl_server_credentials* server_creds = + reinterpret_cast<grpc_ssl_server_credentials*>(c->base.server_creds); + GPR_ASSERT(server_creds != nullptr); + return server_creds->certificate_config_fetcher.cb != nullptr; +} + +static void ssl_channel_destroy(grpc_security_connector* sc) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + grpc_channel_credentials_unref(c->base.channel_creds); + grpc_call_credentials_unref(c->base.request_metadata_creds); + tsi_ssl_client_handshaker_factory_unref(c->client_handshaker_factory); + c->client_handshaker_factory = nullptr; + if (c->target_name != nullptr) gpr_free(c->target_name); + if (c->overridden_target_name != nullptr) gpr_free(c->overridden_target_name); + gpr_free(sc); +} + +static void ssl_server_destroy(grpc_security_connector* sc) { + grpc_ssl_server_security_connector* c = + reinterpret_cast<grpc_ssl_server_security_connector*>(sc); + grpc_server_credentials_unref(c->base.server_creds); + tsi_ssl_server_handshaker_factory_unref(c->server_handshaker_factory); + c->server_handshaker_factory = nullptr; + gpr_free(sc); +} + +static void ssl_channel_add_handshakers(grpc_channel_security_connector* sc, + grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + // Instantiate TSI handshaker. + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( + c->client_handshaker_factory, + c->overridden_target_name != nullptr ? c->overridden_target_name + : c->target_name, + &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + grpc_handshake_manager_add( + handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); +} + +/* Attempts to replace the server_handshaker_factory with a new factory using + * the provided grpc_ssl_server_certificate_config. Should new factory creation + * fail, the existing factory will not be replaced. Returns true on success (new + * factory created). */ +static bool try_replace_server_handshaker_factory( + grpc_ssl_server_security_connector* sc, + const grpc_ssl_server_certificate_config* config) { + if (config == nullptr) { + gpr_log(GPR_ERROR, + "Server certificate config callback returned invalid (NULL) " + "config."); + return false; + } + gpr_log(GPR_DEBUG, "Using new server certificate config (%p).", config); + + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + tsi_ssl_pem_key_cert_pair* cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs( + config->pem_key_cert_pairs, config->num_key_cert_pairs); + tsi_ssl_server_handshaker_factory* new_handshaker_factory = nullptr; + grpc_ssl_server_credentials* server_creds = + reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); + tsi_result result = tsi_create_ssl_server_handshaker_factory_ex( + cert_pairs, config->num_key_cert_pairs, config->pem_root_certs, + grpc_get_tsi_client_certificate_request_type( + server_creds->config.client_certificate_request), + grpc_get_ssl_cipher_suites(), alpn_protocol_strings, + static_cast<uint16_t>(num_alpn_protocols), &new_handshaker_factory); + gpr_free(cert_pairs); + gpr_free((void*)alpn_protocol_strings); + + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + return false; + } + tsi_ssl_server_handshaker_factory_unref(sc->server_handshaker_factory); + sc->server_handshaker_factory = new_handshaker_factory; + return true; +} + +/* Attempts to fetch the server certificate config if a callback is available. + * Current certificate config will continue to be used if the callback returns + * an error. Returns true if new credentials were sucessfully loaded. */ +static bool try_fetch_ssl_server_credentials( + grpc_ssl_server_security_connector* sc) { + grpc_ssl_server_certificate_config* certificate_config = nullptr; + bool status; + + GPR_ASSERT(sc != nullptr); + if (!server_connector_has_cert_config_fetcher(sc)) return false; + + grpc_ssl_server_credentials* server_creds = + reinterpret_cast<grpc_ssl_server_credentials*>(sc->base.server_creds); + grpc_ssl_certificate_config_reload_status cb_result = + server_creds->certificate_config_fetcher.cb( + server_creds->certificate_config_fetcher.user_data, + &certificate_config); + if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { + gpr_log(GPR_DEBUG, "No change in SSL server credentials."); + status = false; + } else if (cb_result == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW) { + status = try_replace_server_handshaker_factory(sc, certificate_config); + } else { + // Log error, continue using previously-loaded credentials. + gpr_log(GPR_ERROR, + "Failed fetching new server credentials, continuing to " + "use previously-loaded credentials."); + status = false; + } + + if (certificate_config != nullptr) { + grpc_ssl_server_certificate_config_destroy(certificate_config); + } + return status; +} + +static void ssl_server_add_handshakers(grpc_server_security_connector* sc, + grpc_pollset_set* interested_parties, + grpc_handshake_manager* handshake_mgr) { + grpc_ssl_server_security_connector* c = + reinterpret_cast<grpc_ssl_server_security_connector*>(sc); + // Instantiate TSI handshaker. + try_fetch_ssl_server_credentials(c); + tsi_handshaker* tsi_hs = nullptr; + tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( + c->server_handshaker_factory, &tsi_hs); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", + tsi_result_to_string(result)); + return; + } + // Create handshakers. + grpc_handshake_manager_add( + handshake_mgr, grpc_security_handshaker_create(tsi_hs, &sc->base)); +} + +static grpc_error* ssl_check_peer(grpc_security_connector* sc, + const char* peer_name, const tsi_peer* peer, + grpc_auth_context** auth_context) { +#if TSI_OPENSSL_ALPN_SUPPORT + /* Check the ALPN if ALPN is supported. */ + const tsi_peer_property* p = + tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL); + if (p == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing selected ALPN property."); + } + if (!grpc_chttp2_is_alpn_version_supported(p->value.data, p->value.length)) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: invalid ALPN value."); + } +#endif /* TSI_OPENSSL_ALPN_SUPPORT */ + /* Check the peer name if specified. */ + if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) { + char* msg; + gpr_asprintf(&msg, "Peer name %s is not in peer certificate", peer_name); + grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + return error; + } + *auth_context = grpc_ssl_peer_to_auth_context(peer); + return GRPC_ERROR_NONE; +} + +static void ssl_channel_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + const char* target_name = c->overridden_target_name != nullptr + ? c->overridden_target_name + : c->target_name; + grpc_error* error = ssl_check_peer(sc, target_name, &peer, auth_context); + if (error == GRPC_ERROR_NONE && + c->verify_options->verify_peer_callback != nullptr) { + const tsi_peer_property* p = + tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); + if (p == nullptr) { + error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "Cannot check peer: missing pem cert property."); + } else { + char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1)); + memcpy(peer_pem, p->value.data, p->value.length); + peer_pem[p->value.length] = '\0'; + int callback_status = c->verify_options->verify_peer_callback( + target_name, peer_pem, + c->verify_options->verify_peer_callback_userdata); + gpr_free(peer_pem); + if (callback_status) { + char* msg; + gpr_asprintf(&msg, "Verify peer callback returned a failure (%d)", + callback_status); + error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); + gpr_free(msg); + } + } + } + GRPC_CLOSURE_SCHED(on_peer_checked, error); + tsi_peer_destruct(&peer); +} + +static void ssl_server_check_peer(grpc_security_connector* sc, tsi_peer peer, + grpc_auth_context** auth_context, + grpc_closure* on_peer_checked) { + grpc_error* error = ssl_check_peer(sc, nullptr, &peer, auth_context); + tsi_peer_destruct(&peer); + GRPC_CLOSURE_SCHED(on_peer_checked, error); +} + +static int ssl_channel_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + grpc_ssl_channel_security_connector* c1 = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc1); + grpc_ssl_channel_security_connector* c2 = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc2); + int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base); + if (c != 0) return c; + c = strcmp(c1->target_name, c2->target_name); + if (c != 0) return c; + return (c1->overridden_target_name == nullptr || + c2->overridden_target_name == nullptr) + ? GPR_ICMP(c1->overridden_target_name, c2->overridden_target_name) + : strcmp(c1->overridden_target_name, c2->overridden_target_name); +} + +static int ssl_server_cmp(grpc_security_connector* sc1, + grpc_security_connector* sc2) { + return grpc_server_security_connector_cmp( + reinterpret_cast<grpc_server_security_connector*>(sc1), + reinterpret_cast<grpc_server_security_connector*>(sc2)); +} + +static bool ssl_channel_check_call_host(grpc_channel_security_connector* sc, + const char* host, + grpc_auth_context* auth_context, + grpc_closure* on_call_host_checked, + grpc_error** error) { + grpc_ssl_channel_security_connector* c = + reinterpret_cast<grpc_ssl_channel_security_connector*>(sc); + grpc_security_status status = GRPC_SECURITY_ERROR; + tsi_peer peer = grpc_shallow_peer_from_ssl_auth_context(auth_context); + if (grpc_ssl_host_matches_name(&peer, host)) status = GRPC_SECURITY_OK; + /* If the target name was overridden, then the original target_name was + 'checked' transitively during the previous peer check at the end of the + handshake. */ + if (c->overridden_target_name != nullptr && + strcmp(host, c->target_name) == 0) { + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "call host does not match SSL server name"); + } + grpc_shallow_peer_destruct(&peer); + return true; +} + +static void ssl_channel_cancel_check_call_host( + grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked, + grpc_error* error) { + GRPC_ERROR_UNREF(error); +} + +static grpc_security_connector_vtable ssl_channel_vtable = { + ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp}; + +static grpc_security_connector_vtable ssl_server_vtable = { + ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp}; + +grpc_security_status grpc_ssl_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache, + grpc_channel_security_connector** sc) { + tsi_result result = TSI_OK; + grpc_ssl_channel_security_connector* c; + char* port; + bool has_key_cert_pair; + tsi_ssl_client_handshaker_options options; + memset(&options, 0, sizeof(options)); + options.alpn_protocols = + grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols); + + if (config == nullptr || target_name == nullptr) { + gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name."); + goto error; + } + if (config->pem_root_certs == nullptr) { + // Use default root certificates. + options.pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts(); + options.root_store = grpc_core::DefaultSslRootStore::GetRootStore(); + if (options.pem_root_certs == nullptr) { + gpr_log(GPR_ERROR, "Could not get default pem root certs."); + goto error; + } + } else { + options.pem_root_certs = config->pem_root_certs; + } + c = static_cast<grpc_ssl_channel_security_connector*>( + gpr_zalloc(sizeof(grpc_ssl_channel_security_connector))); + + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.vtable = &ssl_channel_vtable; + c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; + c->base.channel_creds = grpc_channel_credentials_ref(channel_creds); + c->base.request_metadata_creds = + grpc_call_credentials_ref(request_metadata_creds); + c->base.check_call_host = ssl_channel_check_call_host; + c->base.cancel_check_call_host = ssl_channel_cancel_check_call_host; + c->base.add_handshakers = ssl_channel_add_handshakers; + gpr_split_host_port(target_name, &c->target_name, &port); + gpr_free(port); + if (overridden_target_name != nullptr) { + c->overridden_target_name = gpr_strdup(overridden_target_name); + } + c->verify_options = &config->verify_options; + + has_key_cert_pair = config->pem_key_cert_pair != nullptr && + config->pem_key_cert_pair->private_key != nullptr && + config->pem_key_cert_pair->cert_chain != nullptr; + if (has_key_cert_pair) { + options.pem_key_cert_pair = config->pem_key_cert_pair; + } + options.cipher_suites = grpc_get_ssl_cipher_suites(); + options.session_cache = ssl_session_cache; + result = tsi_create_ssl_client_handshaker_factory_with_options( + &options, &c->client_handshaker_factory); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + ssl_channel_destroy(&c->base.base); + *sc = nullptr; + goto error; + } + *sc = &c->base; + gpr_free((void*)options.alpn_protocols); + return GRPC_SECURITY_OK; + +error: + gpr_free((void*)options.alpn_protocols); + return GRPC_SECURITY_ERROR; +} + +static grpc_ssl_server_security_connector* +grpc_ssl_server_security_connector_initialize( + grpc_server_credentials* server_creds) { + grpc_ssl_server_security_connector* c = + static_cast<grpc_ssl_server_security_connector*>( + gpr_zalloc(sizeof(grpc_ssl_server_security_connector))); + gpr_ref_init(&c->base.base.refcount, 1); + c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; + c->base.base.vtable = &ssl_server_vtable; + c->base.add_handshakers = ssl_server_add_handshakers; + c->base.server_creds = grpc_server_credentials_ref(server_creds); + return c; +} + +grpc_security_status grpc_ssl_server_security_connector_create( + grpc_server_credentials* gsc, grpc_server_security_connector** sc) { + tsi_result result = TSI_OK; + grpc_ssl_server_credentials* server_credentials = + reinterpret_cast<grpc_ssl_server_credentials*>(gsc); + grpc_security_status retval = GRPC_SECURITY_OK; + + GPR_ASSERT(server_credentials != nullptr); + GPR_ASSERT(sc != nullptr); + + grpc_ssl_server_security_connector* c = + grpc_ssl_server_security_connector_initialize(gsc); + if (server_connector_has_cert_config_fetcher(c)) { + // Load initial credentials from certificate_config_fetcher: + if (!try_fetch_ssl_server_credentials(c)) { + gpr_log(GPR_ERROR, "Failed loading SSL server credentials from fetcher."); + retval = GRPC_SECURITY_ERROR; + } + } else { + size_t num_alpn_protocols = 0; + const char** alpn_protocol_strings = + grpc_fill_alpn_protocol_strings(&num_alpn_protocols); + result = tsi_create_ssl_server_handshaker_factory_ex( + server_credentials->config.pem_key_cert_pairs, + server_credentials->config.num_key_cert_pairs, + server_credentials->config.pem_root_certs, + grpc_get_tsi_client_certificate_request_type( + server_credentials->config.client_certificate_request), + grpc_get_ssl_cipher_suites(), alpn_protocol_strings, + static_cast<uint16_t>(num_alpn_protocols), + &c->server_handshaker_factory); + gpr_free((void*)alpn_protocol_strings); + if (result != TSI_OK) { + gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", + tsi_result_to_string(result)); + retval = GRPC_SECURITY_ERROR; + } + } + + if (retval == GRPC_SECURITY_OK) { + *sc = &c->base; + } else { + if (c != nullptr) ssl_server_destroy(&c->base.base); + if (sc != nullptr) *sc = nullptr; + } + return retval; +} diff --git a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h new file mode 100644 index 0000000000..9b80590606 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h @@ -0,0 +1,77 @@ +/* + * + * Copyright 2018 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_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H + +#include <grpc/support/port_platform.h> + +#include <grpc/grpc_security.h> + +#include "src/core/lib/security/security_connector/security_connector.h" + +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security_interface.h" + +typedef struct { + tsi_ssl_pem_key_cert_pair* pem_key_cert_pair; + char* pem_root_certs; + verify_peer_options verify_options; +} grpc_ssl_config; + +/* Creates an SSL channel_security_connector. + - request_metadata_creds is the credentials object which metadata + will be sent with each request. This parameter can be NULL. + - config is the SSL config to be used for the SSL channel establishment. + - is_client should be 0 for a server or a non-0 value for a client. + - secure_peer_name is the secure peer name that should be checked in + grpc_channel_security_connector_check_peer. This parameter may be NULL in + which case the peer name will not be checked. Note that if this parameter + is not NULL, then, pem_root_certs should not be NULL either. + - sc is a pointer on the connector to be created. + This function returns GRPC_SECURITY_OK in case of success or a + specific error code otherwise. +*/ +grpc_security_status grpc_ssl_channel_security_connector_create( + grpc_channel_credentials* channel_creds, + grpc_call_credentials* request_metadata_creds, + const grpc_ssl_config* config, const char* target_name, + const char* overridden_target_name, + tsi_ssl_session_cache* ssl_session_cache, + grpc_channel_security_connector** sc); + +/* Config for ssl servers. */ +typedef struct { + tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs; + size_t num_key_cert_pairs; + char* pem_root_certs; + grpc_ssl_client_certificate_request_type client_certificate_request; +} grpc_ssl_server_config; + +/* Creates an SSL server_security_connector. + - config is the SSL config to be used for the SSL channel establishment. + - sc is a pointer on the connector to be created. + This function returns GRPC_SECURITY_OK in case of success or a + specific error code otherwise. +*/ +grpc_security_status grpc_ssl_server_security_connector_create( + grpc_server_credentials* server_credentials, + grpc_server_security_connector** sc); + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_SSL_SECURITY_CONNECTOR_H \ + */ diff --git a/src/core/lib/security/security_connector/ssl_utils.cc b/src/core/lib/security/security_connector/ssl_utils.cc new file mode 100644 index 0000000000..fbf41cfbc7 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl_utils.cc @@ -0,0 +1,345 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/security/security_connector/ssl_utils.h" + +#include <grpc/slice_buffer.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/ext/transport/chttp2/alpn/alpn.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/host_port.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/iomgr/load_file.h" +#include "src/core/lib/security/context/security_context.h" +#include "src/core/lib/security/security_connector/load_system_roots.h" +#include "src/core/tsi/ssl_transport_security.h" + +/* -- Constants. -- */ + +#ifndef INSTALL_PREFIX +static const char* installed_roots_path = "/usr/share/grpc/roots.pem"; +#else +static const char* installed_roots_path = + INSTALL_PREFIX "/share/grpc/roots.pem"; +#endif + +/** Environment variable used as a flag to enable/disable loading system root + certificates from the OS trust store. */ +#ifndef GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR +#define GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR "GRPC_NOT_USE_SYSTEM_SSL_ROOTS" +#endif + +#ifndef TSI_OPENSSL_ALPN_SUPPORT +#define TSI_OPENSSL_ALPN_SUPPORT 1 +#endif + +/* -- Overridden default roots. -- */ + +static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr; + +void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb) { + ssl_roots_override_cb = cb; +} + +/* -- Cipher suites. -- */ + +/* Defines the cipher suites that we accept by default. All these cipher suites + are compliant with HTTP2. */ +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-ECDSA-AES128-GCM-SHA256:" \ + "ECDHE-ECDSA-AES256-GCM-SHA384:" \ + "ECDHE-RSA-AES128-GCM-SHA256:" \ + "ECDHE-RSA-AES256-GCM-SHA384" + +static gpr_once cipher_suites_once = GPR_ONCE_INIT; +static const char* cipher_suites = nullptr; + +static void init_cipher_suites(void) { + char* overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); + cipher_suites = overridden != nullptr ? overridden : GRPC_SSL_CIPHER_SUITES; +} + +/* --- Util --- */ + +const char* grpc_get_ssl_cipher_suites(void) { + gpr_once_init(&cipher_suites_once, init_cipher_suites); + return cipher_suites; +} + +tsi_client_certificate_request_type +grpc_get_tsi_client_certificate_request_type( + grpc_ssl_client_certificate_request_type grpc_request_type) { + switch (grpc_request_type) { + case GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE: + return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + + case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + return TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; + + case GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY: + return TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY; + + case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY: + return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY; + + case GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY: + return TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY; + + default: + return TSI_DONT_REQUEST_CLIENT_CERTIFICATE; + } +} + +const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols) { + GPR_ASSERT(num_alpn_protocols != nullptr); + *num_alpn_protocols = grpc_chttp2_num_alpn_versions(); + const char** alpn_protocol_strings = static_cast<const char**>( + gpr_malloc(sizeof(const char*) * (*num_alpn_protocols))); + for (size_t i = 0; i < *num_alpn_protocols; i++) { + alpn_protocol_strings[i] = grpc_chttp2_get_alpn_version_index(i); + } + return alpn_protocol_strings; +} + +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) { + char* allocated_name = nullptr; + int r; + + char* ignored_port; + gpr_split_host_port(peer_name, &allocated_name, &ignored_port); + gpr_free(ignored_port); + peer_name = allocated_name; + if (!peer_name) return 0; + + // IPv6 zone-id should not be included in comparisons. + char* const zone_id = strchr(allocated_name, '%'); + if (zone_id != nullptr) *zone_id = '\0'; + + r = tsi_ssl_peer_matches_name(peer, peer_name); + gpr_free(allocated_name); + return r; +} + +grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) { + size_t i; + grpc_auth_context* ctx = nullptr; + const char* peer_identity_property_name = nullptr; + + /* The caller has checked the certificate type property. */ + GPR_ASSERT(peer->property_count >= 1); + ctx = grpc_auth_context_create(nullptr); + grpc_auth_context_add_cstring_property( + ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME, + GRPC_SSL_TRANSPORT_SECURITY_TYPE); + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property* prop = &peer->properties[i]; + if (prop->name == nullptr) continue; + if (strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { + /* If there is no subject alt name, have the CN as the identity. */ + if (peer_identity_property_name == nullptr) { + peer_identity_property_name = GRPC_X509_CN_PROPERTY_NAME; + } + grpc_auth_context_add_property(ctx, GRPC_X509_CN_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, + TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { + peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME; + grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) { + grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME, + prop->value.data, prop->value.length); + } else if (strcmp(prop->name, TSI_SSL_SESSION_REUSED_PEER_PROPERTY) == 0) { + grpc_auth_context_add_property(ctx, GRPC_SSL_SESSION_REUSED_PROPERTY, + prop->value.data, prop->value.length); + } + } + if (peer_identity_property_name != nullptr) { + GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name( + ctx, peer_identity_property_name) == 1); + } + return ctx; +} + +static void add_shallow_auth_property_to_peer(tsi_peer* peer, + const grpc_auth_property* prop, + const char* tsi_prop_name) { + tsi_peer_property* tsi_prop = &peer->properties[peer->property_count++]; + tsi_prop->name = const_cast<char*>(tsi_prop_name); + tsi_prop->value.data = prop->value; + tsi_prop->value.length = prop->value_length; +} + +tsi_peer grpc_shallow_peer_from_ssl_auth_context( + const grpc_auth_context* auth_context) { + size_t max_num_props = 0; + grpc_auth_property_iterator it; + const grpc_auth_property* prop; + tsi_peer peer; + memset(&peer, 0, sizeof(peer)); + + it = grpc_auth_context_property_iterator(auth_context); + while (grpc_auth_property_iterator_next(&it) != nullptr) max_num_props++; + + if (max_num_props > 0) { + peer.properties = static_cast<tsi_peer_property*>( + gpr_malloc(max_num_props * sizeof(tsi_peer_property))); + it = grpc_auth_context_property_iterator(auth_context); + while ((prop = grpc_auth_property_iterator_next(&it)) != nullptr) { + if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer( + &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer( + &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); + } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) { + add_shallow_auth_property_to_peer(&peer, prop, + TSI_X509_PEM_CERT_PROPERTY); + } + } + } + return peer; +} + +void grpc_shallow_peer_destruct(tsi_peer* peer) { + if (peer->properties != nullptr) gpr_free(peer->properties); +} + +/* --- Ssl cache implementation. --- */ + +grpc_ssl_session_cache* grpc_ssl_session_cache_create_lru(size_t capacity) { + tsi_ssl_session_cache* cache = tsi_ssl_session_cache_create_lru(capacity); + return reinterpret_cast<grpc_ssl_session_cache*>(cache); +} + +void grpc_ssl_session_cache_destroy(grpc_ssl_session_cache* cache) { + tsi_ssl_session_cache* tsi_cache = + reinterpret_cast<tsi_ssl_session_cache*>(cache); + tsi_ssl_session_cache_unref(tsi_cache); +} + +static void* grpc_ssl_session_cache_arg_copy(void* p) { + tsi_ssl_session_cache* tsi_cache = + reinterpret_cast<tsi_ssl_session_cache*>(p); + // destroy call below will unref the pointer. + tsi_ssl_session_cache_ref(tsi_cache); + return p; +} + +static void grpc_ssl_session_cache_arg_destroy(void* p) { + tsi_ssl_session_cache* tsi_cache = + reinterpret_cast<tsi_ssl_session_cache*>(p); + tsi_ssl_session_cache_unref(tsi_cache); +} + +static int grpc_ssl_session_cache_arg_cmp(void* p, void* q) { + return GPR_ICMP(p, q); +} + +grpc_arg grpc_ssl_session_cache_create_channel_arg( + grpc_ssl_session_cache* cache) { + static const grpc_arg_pointer_vtable vtable = { + grpc_ssl_session_cache_arg_copy, + grpc_ssl_session_cache_arg_destroy, + grpc_ssl_session_cache_arg_cmp, + }; + return grpc_channel_arg_pointer_create( + const_cast<char*>(GRPC_SSL_SESSION_CACHE_ARG), cache, &vtable); +} + +/* --- Default SSL root store implementation. --- */ + +namespace grpc_core { + +tsi_ssl_root_certs_store* DefaultSslRootStore::default_root_store_; +grpc_slice DefaultSslRootStore::default_pem_root_certs_; + +const tsi_ssl_root_certs_store* DefaultSslRootStore::GetRootStore() { + InitRootStore(); + return default_root_store_; +} + +const char* DefaultSslRootStore::GetPemRootCerts() { + InitRootStore(); + return GRPC_SLICE_IS_EMPTY(default_pem_root_certs_) + ? nullptr + : reinterpret_cast<const char*> + GRPC_SLICE_START_PTR(default_pem_root_certs_); +} + +grpc_slice DefaultSslRootStore::ComputePemRootCerts() { + grpc_slice result = grpc_empty_slice(); + char* not_use_system_roots_env_value = + gpr_getenv(GRPC_NOT_USE_SYSTEM_SSL_ROOTS_ENV_VAR); + const bool not_use_system_roots = gpr_is_true(not_use_system_roots_env_value); + gpr_free(not_use_system_roots_env_value); + // First try to load the roots from the environment. + char* default_root_certs_path = + gpr_getenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR); + if (default_root_certs_path != nullptr) { + GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(default_root_certs_path, 1, &result)); + gpr_free(default_root_certs_path); + } + // Try overridden roots if needed. + grpc_ssl_roots_override_result ovrd_res = GRPC_SSL_ROOTS_OVERRIDE_FAIL; + if (GRPC_SLICE_IS_EMPTY(result) && ssl_roots_override_cb != nullptr) { + char* pem_root_certs = nullptr; + ovrd_res = ssl_roots_override_cb(&pem_root_certs); + if (ovrd_res == GRPC_SSL_ROOTS_OVERRIDE_OK) { + GPR_ASSERT(pem_root_certs != nullptr); + result = grpc_slice_from_copied_buffer( + pem_root_certs, + strlen(pem_root_certs) + 1); // nullptr terminator. + } + gpr_free(pem_root_certs); + } + // Try loading roots from OS trust store if flag is enabled. + if (GRPC_SLICE_IS_EMPTY(result) && !not_use_system_roots) { + result = LoadSystemRootCerts(); + } + // Fallback to roots manually shipped with gRPC. + if (GRPC_SLICE_IS_EMPTY(result) && + ovrd_res != GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY) { + GRPC_LOG_IF_ERROR("load_file", + grpc_load_file(installed_roots_path, 1, &result)); + } + return result; +} + +void DefaultSslRootStore::InitRootStore() { + static gpr_once once = GPR_ONCE_INIT; + gpr_once_init(&once, DefaultSslRootStore::InitRootStoreOnce); +} + +void DefaultSslRootStore::InitRootStoreOnce() { + default_pem_root_certs_ = ComputePemRootCerts(); + if (!GRPC_SLICE_IS_EMPTY(default_pem_root_certs_)) { + default_root_store_ = + tsi_ssl_root_certs_store_create(reinterpret_cast<const char*>( + GRPC_SLICE_START_PTR(default_pem_root_certs_))); + } +} + +} // namespace grpc_core diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h new file mode 100644 index 0000000000..6f6d473311 --- /dev/null +++ b/src/core/lib/security/security_connector/ssl_utils.h @@ -0,0 +1,93 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H +#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H + +#include <grpc/support/port_platform.h> + +#include <stdbool.h> + +#include <grpc/grpc_security.h> +#include <grpc/slice_buffer.h> + +#include "src/core/tsi/ssl_transport_security.h" +#include "src/core/tsi/transport_security_interface.h" + +/* --- Util. --- */ + +/* --- URL schemes. --- */ +#define GRPC_SSL_URL_SCHEME "https" + +/* Return HTTP2-compliant cipher suites that gRPC accepts by default. */ +const char* grpc_get_ssl_cipher_suites(void); + +/* Map from grpc_ssl_client_certificate_request_type to + * tsi_client_certificate_request_type. */ +tsi_client_certificate_request_type +grpc_get_tsi_client_certificate_request_type( + grpc_ssl_client_certificate_request_type grpc_request_type); + +/* Return an array of strings containing alpn protocols. */ +const char** grpc_fill_alpn_protocol_strings(size_t* num_alpn_protocols); + +/* Exposed for testing only. */ +grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer); +tsi_peer grpc_shallow_peer_from_ssl_auth_context( + const grpc_auth_context* auth_context); +void grpc_shallow_peer_destruct(tsi_peer* peer); +int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name); + +/* --- Default SSL Root Store. --- */ +namespace grpc_core { + +// The class implements default SSL root store. +class DefaultSslRootStore { + public: + // Gets the default SSL root store. Returns nullptr if not found. + static const tsi_ssl_root_certs_store* GetRootStore(); + + // Gets the default PEM root certificate. + static const char* GetPemRootCerts(); + + protected: + // Returns default PEM root certificates in nullptr terminated grpc_slice. + // This function is protected instead of private, so that it can be tested. + static grpc_slice ComputePemRootCerts(); + + private: + // Construct me not! + DefaultSslRootStore(); + + // Initialization of default SSL root store. + static void InitRootStore(); + + // One-time initialization of default SSL root store. + static void InitRootStoreOnce(); + + // SSL root store in tsi_ssl_root_certs_store object. + static tsi_ssl_root_certs_store* default_root_store_; + + // Default PEM root certificates. + static grpc_slice default_pem_root_certs_; +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_SSL_UTILS_H \ + */ diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc index 0f125e7c26..e34eacc8d7 100644 --- a/src/core/lib/security/transport/client_auth_filter.cc +++ b/src/core/lib/security/transport/client_auth_filter.cc @@ -32,6 +32,7 @@ #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/slice/slice_internal.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/lib/surface/call.h" diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 2eff8b2916..558f1d494c 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -26,8 +26,9 @@ static grpc_error* recursively_find_error_with_field(grpc_error* error, grpc_error_ints which) { + intptr_t unused; // If the error itself has a status code, return it. - if (grpc_error_get_int(error, which, nullptr)) { + if (grpc_error_get_int(error, which, &unused)) { return error; } if (grpc_error_is_special(error)) return nullptr; @@ -102,7 +103,8 @@ void grpc_error_get_status(grpc_error* error, grpc_millis deadline, } bool grpc_error_has_clear_grpc_status(grpc_error* error) { - if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, nullptr)) { + intptr_t unused; + if (grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &unused)) { return true; } uint8_t slot = error->first_err; diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc index cdcb9a11d2..4ebe73f82a 100644 --- a/src/core/lib/transport/static_metadata.cc +++ b/src/core/lib/transport/static_metadata.cc @@ -63,51 +63,53 @@ static uint8_t g_bytes[] = { 115, 115, 97, 103, 101, 95, 98, 121, 116, 101, 115, 47, 103, 114, 112, 99, 46, 108, 98, 46, 118, 49, 46, 76, 111, 97, 100, 66, 97, 108, 97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111, - 97, 100, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, - 114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, - 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, - 116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, - 54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, - 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, - 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, - 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, - 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, - 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, - 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, - 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, - 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, - 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, - 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, - 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, - 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, - 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, - 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, - 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, - 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, - 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, - 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, - 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, - 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, - 111, 100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, - 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, - 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, - 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, - 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, - 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, - 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, - 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, - 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, - 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, - 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, - 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, - 105, 100, 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, - 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, - 112, 99, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, - 116, 45, 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, - 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, - 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, - 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, - 116, 101, 44, 103, 122, 105, 112}; + 97, 100, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46, + 118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104, + 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101, + 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, 84, 47, + 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, 116, 112, + 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51, + 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101, + 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44, + 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45, + 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45, + 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99, + 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108, + 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108, + 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, + 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111, + 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105, + 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117, + 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103, + 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116, + 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103, + 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103, + 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114, + 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111, + 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45, + 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97, + 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101, + 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100, + 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105, + 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112, + 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, + 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105, + 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101, + 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121, + 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116, + 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116, + 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105, + 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111, + 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45, + 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, 105, 100, + 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97, + 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99, + 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45, + 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, + 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122, + 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105, + 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101, + 44, 103, 122, 105, 112}; static void static_ref(void* unused) {} static void static_unref(void* unused) {} @@ -224,6 +226,7 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, {&grpc_static_metadata_vtable, &static_sub_refcnt}, + {&grpc_static_metadata_vtable, &static_sub_refcnt}, }; const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { @@ -262,76 +265,77 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = { {&grpc_static_metadata_refcounts[32], {{g_bytes + 385, 30}}}, {&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}}, {&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}, - {&grpc_static_metadata_refcounts[37], {{g_bytes + 493, 11}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}, - {&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}, - {&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}}, - {&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}}, - {&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}}, - {&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}}, - {&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}}, - {&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}}, - {&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}}, - {&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}}, - {&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}}, - {&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}}, - {&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}}, - {&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}}, - {&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}}, - {&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}}, - {&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}}, - {&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}}, - {&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}}, - {&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}}, - {&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}}, - {&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}}, - {&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}}, - {&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}}, - {&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}}, - {&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}}, - {&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}}, - {&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}}, - {&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}}, - {&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}}, - {&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}}, - {&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}}, - {&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}}, - {&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}}, - {&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}}, - {&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}}, - {&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}}, - {&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}}, - {&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}}, - {&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}}, - {&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}}, - {&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}}, - {&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}, - {&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}, + {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 28}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}, + {&grpc_static_metadata_refcounts[38], {{g_bytes + 521, 11}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}, + {&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}, + {&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, + {&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, + {&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, + {&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, + {&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, + {&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, + {&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, + {&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, + {&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, + {&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, + {&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, + {&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, + {&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, + {&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, + {&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, + {&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, + {&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, + {&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, + {&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, + {&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, + {&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, + {&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, + {&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, + {&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, + {&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, + {&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, + {&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, + {&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, + {&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, + {&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, + {&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, + {&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, + {&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, + {&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, + {&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, + {&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, + {&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, + {&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, + {&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, + {&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, + {&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}, + {&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}, + {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}, }; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { @@ -341,17 +345,17 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4}; static const int8_t elems_r[] = { - 15, 9, -8, 0, 2, -44, -78, 17, 0, 6, -8, 0, 0, 0, 6, - -5, -10, 0, 0, -2, -3, -4, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -63, 0, -46, -68, -69, -53, 0, 31, 30, - 29, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 18, - 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, - 2, 3, 3, 2, 6, 0, 0, 0, 0, 0, 0, -5, 0}; + 16, 11, -8, 0, 3, -42, -81, -43, 0, 6, -8, 0, 0, 0, -7, + -3, -10, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -63, 0, -47, -68, -69, -70, 0, 33, + 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20, + 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, + 4, 4, 4, 3, 10, 9, 0, 0, 0, 0, 0, 0, -3, 0}; static uint32_t elems_phash(uint32_t i) { - i -= 40; - uint32_t x = i % 103; - uint32_t y = i / 103; + i -= 41; + uint32_t x = i % 104; + uint32_t y = i / 104; uint32_t h = x; if (y < GPR_ARRAY_SIZE(elems_r)) { uint32_t delta = (uint32_t)elems_r[y]; @@ -361,29 +365,29 @@ static uint32_t elems_phash(uint32_t i) { } static const uint16_t elem_keys[] = { - 254, 255, 256, 257, 258, 259, 260, 1085, 1086, 143, 144, 1709, - 462, 463, 1604, 40, 41, 761, 1716, 980, 981, 1611, 621, 1499, - 760, 2024, 2129, 2234, 5384, 5699, 5804, 6014, 6119, 6224, 1732, 6329, - 6434, 6539, 6644, 6749, 6854, 6959, 7064, 7169, 7274, 7379, 7484, 7589, - 5909, 5594, 7694, 7799, 7904, 8009, 8114, 8219, 8324, 8429, 8534, 8639, - 8744, 8849, 8954, 9059, 9164, 9269, 9374, 1145, 518, 9479, 204, 9584, - 9689, 1151, 1152, 1153, 1154, 1775, 9794, 1040, 1670, 10529, 0, 0, - 1782, 829, 0, 0, 0, 0, 344, 1567, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0}; + 257, 258, 259, 260, 261, 262, 263, 1096, 1097, 1513, 1725, 145, + 146, 467, 468, 1619, 41, 42, 1733, 990, 991, 767, 768, 1627, + 627, 837, 2043, 2149, 2255, 5541, 5859, 5965, 6071, 6177, 1749, 6283, + 6389, 6495, 6601, 6707, 6813, 6919, 7025, 7131, 7237, 7343, 7449, 7555, + 7661, 5753, 7767, 7873, 7979, 8085, 8191, 8297, 8403, 8509, 8615, 8721, + 8827, 8933, 9039, 9145, 9251, 9357, 9463, 1156, 9569, 523, 9675, 9781, + 206, 1162, 1163, 1164, 1165, 1792, 1582, 1050, 9887, 9993, 1686, 10735, + 1799, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0}; static const uint8_t elem_idxs[] = { - 7, 8, 9, 10, 11, 12, 13, 77, 79, 1, 2, 71, 5, 6, 25, 3, - 4, 63, 84, 66, 65, 73, 67, 30, 62, 57, 37, 74, 14, 17, 18, 20, - 21, 22, 15, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, 36, 38, - 19, 16, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 76, 69, 56, 70, 58, 59, 78, 80, 81, 82, 83, 60, 64, - 72, 75, 255, 255, 85, 61, 255, 255, 255, 255, 0, 68}; + 7, 8, 9, 10, 11, 12, 13, 77, 79, 30, 71, 1, 2, 5, 6, 25, + 3, 4, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 17, 18, + 19, 20, 15, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35, + 36, 16, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 76, 55, 69, 56, 58, 70, 78, 80, 81, 82, 83, 68, 64, + 59, 60, 72, 75, 85, 255, 255, 255, 255, 255, 0}; grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) { if (a == -1 || b == -1) return GRPC_MDNULL; - uint32_t k = (uint32_t)(a * 105 + b); + uint32_t k = (uint32_t)(a * 106 + b); uint32_t h = elems_phash(k); return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k && elem_idxs[h] != 255 @@ -396,175 +400,175 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = { {{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[38], {{g_bytes + 504, 3}}}}, + {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[39], {{g_bytes + 507, 4}}}}, + {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[40], {{g_bytes + 511, 1}}}}, + {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}}, {{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}}, - {&grpc_static_metadata_refcounts[41], {{g_bytes + 512, 11}}}}, + {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[42], {{g_bytes + 523, 4}}}}, + {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[43], {{g_bytes + 527, 5}}}}, + {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[44], {{g_bytes + 532, 3}}}}, + {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[45], {{g_bytes + 535, 3}}}}, + {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[46], {{g_bytes + 538, 3}}}}, + {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[47], {{g_bytes + 541, 3}}}}, + {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[48], {{g_bytes + 544, 3}}}}, + {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[49], {{g_bytes + 547, 3}}}}, + {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}}, {{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}}, - {&grpc_static_metadata_refcounts[50], {{g_bytes + 550, 3}}}}, - {{&grpc_static_metadata_refcounts[51], {{g_bytes + 553, 14}}}, + {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}}, + {{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[52], {{g_bytes + 567, 13}}}}, - {{&grpc_static_metadata_refcounts[53], {{g_bytes + 580, 15}}}, + {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}}, + {{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[54], {{g_bytes + 595, 13}}}, + {{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[55], {{g_bytes + 608, 6}}}, + {{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[56], {{g_bytes + 614, 27}}}, + {{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[57], {{g_bytes + 641, 3}}}, + {{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[58], {{g_bytes + 644, 5}}}, + {{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[59], {{g_bytes + 649, 13}}}, + {{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[60], {{g_bytes + 662, 13}}}, + {{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[61], {{g_bytes + 675, 19}}}, + {{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[62], {{g_bytes + 694, 16}}}, + {{&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[63], {{g_bytes + 710, 14}}}, + {{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[64], {{g_bytes + 724, 16}}}, + {{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[65], {{g_bytes + 740, 13}}}, + {{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[66], {{g_bytes + 753, 6}}}, + {{&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[67], {{g_bytes + 759, 4}}}, + {{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[68], {{g_bytes + 763, 4}}}, + {{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[69], {{g_bytes + 767, 6}}}, + {{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[70], {{g_bytes + 773, 7}}}, + {{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[71], {{g_bytes + 780, 4}}}, + {{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[72], {{g_bytes + 784, 8}}}, + {{&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[73], {{g_bytes + 792, 17}}}, + {{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[74], {{g_bytes + 809, 13}}}, + {{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[75], {{g_bytes + 822, 8}}}, + {{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[76], {{g_bytes + 830, 19}}}, + {{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[77], {{g_bytes + 849, 13}}}, + {{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[78], {{g_bytes + 862, 4}}}, + {{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[79], {{g_bytes + 866, 8}}}, + {{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[80], {{g_bytes + 874, 12}}}, + {{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[81], {{g_bytes + 886, 18}}}, + {{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[82], {{g_bytes + 904, 19}}}, + {{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[83], {{g_bytes + 923, 5}}}, + {{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[84], {{g_bytes + 928, 7}}}, + {{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[85], {{g_bytes + 935, 7}}}, + {{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[86], {{g_bytes + 942, 11}}}, + {{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[87], {{g_bytes + 953, 6}}}, + {{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[88], {{g_bytes + 959, 10}}}, + {{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[89], {{g_bytes + 969, 25}}}, + {{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[90], {{g_bytes + 994, 17}}}, + {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1011, 4}}}, + {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1015, 3}}}, + {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1018, 16}}}, + {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, - {&grpc_static_metadata_refcounts[94], {{g_bytes + 1034, 1}}}}, + {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, {&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}}, {{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}}, {&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, {{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}}, - {&grpc_static_metadata_refcounts[96], {{g_bytes + 1043, 8}}}}, + {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}}, {{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}}, - {&grpc_static_metadata_refcounts[97], {{g_bytes + 1051, 16}}}}, + {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}}, {{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}}, - {&grpc_static_metadata_refcounts[98], {{g_bytes + 1067, 4}}}}, + {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}}, {{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}}, - {&grpc_static_metadata_refcounts[99], {{g_bytes + 1071, 3}}}}, + {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, - {{&grpc_static_metadata_refcounts[100], {{g_bytes + 1074, 11}}}, + {{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}}, {&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 7}}}}, + {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[101], {{g_bytes + 1085, 16}}}}, + {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[103], {{g_bytes + 1114, 12}}}}, + {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}}, {{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}}, - {&grpc_static_metadata_refcounts[104], {{g_bytes + 1126, 21}}}}, + {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[95], {{g_bytes + 1035, 8}}}}, + {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[36], {{g_bytes + 489, 4}}}}, + {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}}, {{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}}, - {&grpc_static_metadata_refcounts[102], {{g_bytes + 1101, 13}}}}, + {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}}, }; const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78, 79, 80, 81, 82}; diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 5e57ea5741..2bb9f72838 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -31,7 +31,7 @@ #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 105 +#define GRPC_STATIC_MDSTR_COUNT 106 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* ":path" */ #define GRPC_MDSTR_PATH (grpc_static_slice_table[0]) @@ -107,147 +107,150 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT]; /* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */ #define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \ (grpc_static_slice_table[34]) +/* "/grpc.health.v1.Health/Watch" */ +#define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \ + (grpc_static_slice_table[35]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[35]) +#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (grpc_static_slice_table[36]) +#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37]) /* "stream/gzip" */ -#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[37]) +#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38]) /* "GET" */ -#define GRPC_MDSTR_GET (grpc_static_slice_table[38]) +#define GRPC_MDSTR_GET (grpc_static_slice_table[39]) /* "POST" */ -#define GRPC_MDSTR_POST (grpc_static_slice_table[39]) +#define GRPC_MDSTR_POST (grpc_static_slice_table[40]) /* "/" */ -#define GRPC_MDSTR_SLASH (grpc_static_slice_table[40]) +#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[41]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42]) /* "http" */ -#define GRPC_MDSTR_HTTP (grpc_static_slice_table[42]) +#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43]) /* "https" */ -#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[43]) +#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44]) /* "200" */ -#define GRPC_MDSTR_200 (grpc_static_slice_table[44]) +#define GRPC_MDSTR_200 (grpc_static_slice_table[45]) /* "204" */ -#define GRPC_MDSTR_204 (grpc_static_slice_table[45]) +#define GRPC_MDSTR_204 (grpc_static_slice_table[46]) /* "206" */ -#define GRPC_MDSTR_206 (grpc_static_slice_table[46]) +#define GRPC_MDSTR_206 (grpc_static_slice_table[47]) /* "304" */ -#define GRPC_MDSTR_304 (grpc_static_slice_table[47]) +#define GRPC_MDSTR_304 (grpc_static_slice_table[48]) /* "400" */ -#define GRPC_MDSTR_400 (grpc_static_slice_table[48]) +#define GRPC_MDSTR_400 (grpc_static_slice_table[49]) /* "404" */ -#define GRPC_MDSTR_404 (grpc_static_slice_table[49]) +#define GRPC_MDSTR_404 (grpc_static_slice_table[50]) /* "500" */ -#define GRPC_MDSTR_500 (grpc_static_slice_table[50]) +#define GRPC_MDSTR_500 (grpc_static_slice_table[51]) /* "accept-charset" */ -#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[51]) +#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[52]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53]) /* "accept-language" */ -#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[53]) +#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54]) /* "accept-ranges" */ -#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[54]) +#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55]) /* "accept" */ -#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[55]) +#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56]) /* "access-control-allow-origin" */ -#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[56]) +#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57]) /* "age" */ -#define GRPC_MDSTR_AGE (grpc_static_slice_table[57]) +#define GRPC_MDSTR_AGE (grpc_static_slice_table[58]) /* "allow" */ -#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[58]) +#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59]) /* "authorization" */ -#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[59]) +#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60]) /* "cache-control" */ -#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[60]) +#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[61]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63]) +#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64]) +#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65]) +#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66]) +#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67]) /* "date" */ -#define GRPC_MDSTR_DATE (grpc_static_slice_table[67]) +#define GRPC_MDSTR_DATE (grpc_static_slice_table[68]) /* "etag" */ -#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68]) +#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69]) +#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70]) +#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71]) /* "from" */ -#define GRPC_MDSTR_FROM (grpc_static_slice_table[71]) +#define GRPC_MDSTR_FROM (grpc_static_slice_table[72]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72]) +#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74]) +#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75]) +#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77]) +#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78]) /* "link" */ -#define GRPC_MDSTR_LINK (grpc_static_slice_table[78]) +#define GRPC_MDSTR_LINK (grpc_static_slice_table[79]) /* "location" */ -#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[79]) +#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[80]) +#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[81]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[82]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83]) /* "range" */ -#define GRPC_MDSTR_RANGE (grpc_static_slice_table[83]) +#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84]) /* "referer" */ -#define GRPC_MDSTR_REFERER (grpc_static_slice_table[84]) +#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[85]) +#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[86]) +#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87]) /* "server" */ -#define GRPC_MDSTR_SERVER (grpc_static_slice_table[87]) +#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[88]) +#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[90]) +#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91]) /* "vary" */ -#define GRPC_MDSTR_VARY (grpc_static_slice_table[91]) +#define GRPC_MDSTR_VARY (grpc_static_slice_table[92]) /* "via" */ -#define GRPC_MDSTR_VIA (grpc_static_slice_table[92]) +#define GRPC_MDSTR_VIA (grpc_static_slice_table[93]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[93]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94]) /* "0" */ -#define GRPC_MDSTR_0 (grpc_static_slice_table[94]) +#define GRPC_MDSTR_0 (grpc_static_slice_table[95]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[95]) +#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[96]) +#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97]) /* "application/grpc" */ -#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[97]) +#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (grpc_static_slice_table[98]) +#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99]) /* "PUT" */ -#define GRPC_MDSTR_PUT (grpc_static_slice_table[99]) +#define GRPC_MDSTR_PUT (grpc_static_slice_table[100]) /* "lb-cost-bin" */ -#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[100]) +#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[101]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[102]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[103]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (grpc_static_slice_table[104]) + (grpc_static_slice_table[105]) extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable; extern grpc_slice_refcount diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc index fb523a173d..94c2493d5e 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_plugin_registry.cc @@ -36,6 +36,8 @@ void grpc_resolver_fake_init(void); void grpc_resolver_fake_shutdown(void); void grpc_lb_policy_grpclb_init(void); void grpc_lb_policy_grpclb_shutdown(void); +void grpc_lb_policy_xds_init(void); +void grpc_lb_policy_xds_shutdown(void); void grpc_lb_policy_pick_first_init(void); void grpc_lb_policy_pick_first_shutdown(void); void grpc_lb_policy_round_robin_init(void); @@ -72,6 +74,8 @@ void grpc_register_built_in_plugins(void) { grpc_resolver_fake_shutdown); grpc_register_plugin(grpc_lb_policy_grpclb_init, grpc_lb_policy_grpclb_shutdown); + grpc_register_plugin(grpc_lb_policy_xds_init, + grpc_lb_policy_xds_shutdown); grpc_register_plugin(grpc_lb_policy_pick_first_init, grpc_lb_policy_pick_first_shutdown); grpc_register_plugin(grpc_lb_policy_round_robin_init, diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc index 80214aebe2..5749ab6b95 100644 --- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc +++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.cc @@ -40,6 +40,8 @@ void grpc_resolver_fake_init(void); void grpc_resolver_fake_shutdown(void); void grpc_lb_policy_grpclb_init(void); void grpc_lb_policy_grpclb_shutdown(void); +void grpc_lb_policy_xds_init(void); +void grpc_lb_policy_xds_shutdown(void); void grpc_lb_policy_pick_first_init(void); void grpc_lb_policy_pick_first_shutdown(void); void grpc_lb_policy_round_robin_init(void); @@ -74,6 +76,8 @@ void grpc_register_built_in_plugins(void) { grpc_resolver_fake_shutdown); grpc_register_plugin(grpc_lb_policy_grpclb_init, grpc_lb_policy_grpclb_shutdown); + grpc_register_plugin(grpc_lb_policy_xds_init, + grpc_lb_policy_xds_shutdown); grpc_register_plugin(grpc_lb_policy_pick_first_init, grpc_lb_policy_pick_first_shutdown); grpc_register_plugin(grpc_lb_policy_round_robin_init, diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc index 99b3229e88..ca861b52de 100644 --- a/src/core/tsi/transport_security.cc +++ b/src/core/tsi/transport_security.cc @@ -338,3 +338,20 @@ tsi_result tsi_construct_peer(size_t property_count, tsi_peer* peer) { } return TSI_OK; } + +const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, + const char* name) { + size_t i; + if (peer == nullptr) return nullptr; + for (i = 0; i < peer->property_count; i++) { + const tsi_peer_property* property = &peer->properties[i]; + if (name == nullptr && property->name == nullptr) { + return property; + } + if (name != nullptr && property->name != nullptr && + strcmp(property->name, name) == 0) { + return property; + } + } + return nullptr; +} diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h index 1923a702e5..482d300a05 100644 --- a/src/core/tsi/transport_security.h +++ b/src/core/tsi/transport_security.h @@ -122,7 +122,8 @@ tsi_result tsi_construct_allocated_string_peer_property( const char* name, size_t value_length, tsi_peer_property* property); tsi_result tsi_construct_string_peer_property_from_cstring( const char* name, const char* value, tsi_peer_property* property); - +const tsi_peer_property* tsi_peer_get_property_by_name(const tsi_peer* peer, + const char* name); /* Utils. */ char* tsi_strdup(const char* src); /* Sadly, no strdup in C89. */ diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc index 79ed9102e5..428893f277 100644 --- a/src/cpp/server/channelz/channelz_service.cc +++ b/src/cpp/server/channelz/channelz_service.cc @@ -20,9 +20,6 @@ #include "src/cpp/server/channelz/channelz_service.h" -#include <google/protobuf/text_format.h> -#include <google/protobuf/util/json_util.h> - #include <grpc/grpc.h> #include <grpc/support/alloc.h> @@ -33,13 +30,14 @@ Status ChannelzService::GetTopChannels( channelz::v1::GetTopChannelsResponse* response) { char* json_str = grpc_channelz_get_top_channels(request->start_channel_id()); if (json_str == nullptr) { - return Status(INTERNAL, "grpc_channelz_get_top_channels returned null"); + return Status(StatusCode::INTERNAL, + "grpc_channelz_get_top_channels returned null"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -49,13 +47,14 @@ Status ChannelzService::GetServers( channelz::v1::GetServersResponse* response) { char* json_str = grpc_channelz_get_servers(request->start_server_id()); if (json_str == nullptr) { - return Status(INTERNAL, "grpc_channelz_get_servers returned null"); + return Status(StatusCode::INTERNAL, + "grpc_channelz_get_servers returned null"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -66,13 +65,14 @@ Status ChannelzService::GetServerSockets( char* json_str = grpc_channelz_get_server_sockets(request->server_id(), request->start_socket_id()); if (json_str == nullptr) { - return Status(INTERNAL, "grpc_channelz_get_server_sockets returned null"); + return Status(StatusCode::INTERNAL, + "grpc_channelz_get_server_sockets returned null"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -82,13 +82,13 @@ Status ChannelzService::GetChannel( channelz::v1::GetChannelResponse* response) { char* json_str = grpc_channelz_get_channel(request->channel_id()); if (json_str == nullptr) { - return Status(NOT_FOUND, "No object found for that ChannelId"); + return Status(StatusCode::NOT_FOUND, "No object found for that ChannelId"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -98,13 +98,14 @@ Status ChannelzService::GetSubchannel( channelz::v1::GetSubchannelResponse* response) { char* json_str = grpc_channelz_get_subchannel(request->subchannel_id()); if (json_str == nullptr) { - return Status(NOT_FOUND, "No object found for that SubchannelId"); + return Status(StatusCode::NOT_FOUND, + "No object found for that SubchannelId"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } @@ -114,13 +115,13 @@ Status ChannelzService::GetSocket(ServerContext* unused, channelz::v1::GetSocketResponse* response) { char* json_str = grpc_channelz_get_socket(request->socket_id()); if (json_str == nullptr) { - return Status(NOT_FOUND, "No object found for that SocketId"); + return Status(StatusCode::NOT_FOUND, "No object found for that SocketId"); } - google::protobuf::util::Status s = - google::protobuf::util::JsonStringToMessage(json_str, response); + grpc::protobuf::util::Status s = + grpc::protobuf::json::JsonStringToMessage(json_str, response); gpr_free(json_str); - if (s != google::protobuf::util::Status::OK) { - return Status(INTERNAL, s.ToString()); + if (!s.ok()) { + return Status(StatusCode::INTERNAL, s.ToString()); } return Status::OK; } diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc index bfda67d086..c951c69d51 100644 --- a/src/cpp/server/health/default_health_check_service.cc +++ b/src/cpp/server/health/default_health_check_service.cc @@ -26,79 +26,199 @@ #include "pb_decode.h" #include "pb_encode.h" +#include "src/core/ext/filters/client_channel/health/health.pb.h" #include "src/cpp/server/health/default_health_check_service.h" -#include "src/cpp/server/health/health.pb.h" namespace grpc { + +// +// DefaultHealthCheckService +// + +DefaultHealthCheckService::DefaultHealthCheckService() { + services_map_[""].SetServingStatus(SERVING); +} + +void DefaultHealthCheckService::SetServingStatus( + const grpc::string& service_name, bool serving) { + std::unique_lock<std::mutex> lock(mu_); + services_map_[service_name].SetServingStatus(serving ? SERVING : NOT_SERVING); +} + +void DefaultHealthCheckService::SetServingStatus(bool serving) { + const ServingStatus status = serving ? SERVING : NOT_SERVING; + std::unique_lock<std::mutex> lock(mu_); + for (auto& p : services_map_) { + ServiceData& service_data = p.second; + service_data.SetServingStatus(status); + } +} + +DefaultHealthCheckService::ServingStatus +DefaultHealthCheckService::GetServingStatus( + const grpc::string& service_name) const { + std::lock_guard<std::mutex> lock(mu_); + auto it = services_map_.find(service_name); + if (it == services_map_.end()) { + return NOT_FOUND; + } + const ServiceData& service_data = it->second; + return service_data.GetServingStatus(); +} + +void DefaultHealthCheckService::RegisterCallHandler( + const grpc::string& service_name, + std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler) { + std::unique_lock<std::mutex> lock(mu_); + ServiceData& service_data = services_map_[service_name]; + service_data.AddCallHandler(handler /* copies ref */); + HealthCheckServiceImpl::CallHandler* h = handler.get(); + h->SendHealth(std::move(handler), service_data.GetServingStatus()); +} + +void DefaultHealthCheckService::UnregisterCallHandler( + const grpc::string& service_name, + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler) { + std::unique_lock<std::mutex> lock(mu_); + auto it = services_map_.find(service_name); + if (it == services_map_.end()) return; + ServiceData& service_data = it->second; + service_data.RemoveCallHandler(handler); + if (service_data.Unused()) { + services_map_.erase(it); + } +} + +DefaultHealthCheckService::HealthCheckServiceImpl* +DefaultHealthCheckService::GetHealthCheckService( + std::unique_ptr<ServerCompletionQueue> cq) { + GPR_ASSERT(impl_ == nullptr); + impl_.reset(new HealthCheckServiceImpl(this, std::move(cq))); + return impl_.get(); +} + +// +// DefaultHealthCheckService::ServiceData +// + +void DefaultHealthCheckService::ServiceData::SetServingStatus( + ServingStatus status) { + status_ = status; + for (auto& call_handler : call_handlers_) { + call_handler->SendHealth(call_handler /* copies ref */, status); + } +} + +void DefaultHealthCheckService::ServiceData::AddCallHandler( + std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler) { + call_handlers_.insert(std::move(handler)); +} + +void DefaultHealthCheckService::ServiceData::RemoveCallHandler( + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler) { + call_handlers_.erase(handler); +} + +// +// DefaultHealthCheckService::HealthCheckServiceImpl +// + namespace { const char kHealthCheckMethodName[] = "/grpc.health.v1.Health/Check"; +const char kHealthWatchMethodName[] = "/grpc.health.v1.Health/Watch"; } // namespace DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl( - DefaultHealthCheckService* service) - : service_(service), method_(nullptr) { - internal::MethodHandler* handler = - new internal::RpcMethodHandler<HealthCheckServiceImpl, ByteBuffer, - ByteBuffer>( - std::mem_fn(&HealthCheckServiceImpl::Check), this); - method_ = new internal::RpcServiceMethod( - kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, handler); - AddMethod(method_); -} - -Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( - ServerContext* context, const ByteBuffer* request, ByteBuffer* response) { - // Decode request. - std::vector<Slice> slices; - if (!request->Dump(&slices).ok()) { - return Status(StatusCode::INVALID_ARGUMENT, ""); + DefaultHealthCheckService* database, + std::unique_ptr<ServerCompletionQueue> cq) + : database_(database), cq_(std::move(cq)) { + // Add Check() method. + AddMethod(new internal::RpcServiceMethod( + kHealthCheckMethodName, internal::RpcMethod::NORMAL_RPC, nullptr)); + // Add Watch() method. + AddMethod(new internal::RpcServiceMethod( + kHealthWatchMethodName, internal::RpcMethod::SERVER_STREAMING, nullptr)); + // Create serving thread. + thread_ = std::unique_ptr<::grpc_core::Thread>( + new ::grpc_core::Thread("grpc_health_check_service", Serve, this)); +} + +DefaultHealthCheckService::HealthCheckServiceImpl::~HealthCheckServiceImpl() { + // We will reach here after the server starts shutting down. + shutdown_ = true; + { + std::unique_lock<std::mutex> lock(cq_shutdown_mu_); + cq_->Shutdown(); } + thread_->Join(); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::StartServingThread() { + // Request the calls we're interested in. + // We do this before starting the serving thread, so that we know it's + // done before server startup is complete. + CheckCallHandler::CreateAndStart(cq_.get(), database_, this); + WatchCallHandler::CreateAndStart(cq_.get(), database_, this); + // Start serving thread. + thread_->Start(); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::Serve(void* arg) { + HealthCheckServiceImpl* service = + reinterpret_cast<HealthCheckServiceImpl*>(arg); + void* tag; + bool ok; + while (true) { + if (!service->cq_->Next(&tag, &ok)) { + // The completion queue is shutting down. + GPR_ASSERT(service->shutdown_); + break; + } + auto* next_step = static_cast<CallableTag*>(tag); + next_step->Run(ok); + } +} + +bool DefaultHealthCheckService::HealthCheckServiceImpl::DecodeRequest( + const ByteBuffer& request, grpc::string* service_name) { + std::vector<Slice> slices; + if (!request.Dump(&slices).ok()) return false; uint8_t* request_bytes = nullptr; - bool request_bytes_owned = false; size_t request_size = 0; grpc_health_v1_HealthCheckRequest request_struct; - if (slices.empty()) { - request_struct.has_service = false; - } else if (slices.size() == 1) { + request_struct.has_service = false; + if (slices.size() == 1) { request_bytes = const_cast<uint8_t*>(slices[0].begin()); request_size = slices[0].size(); - } else { - request_bytes_owned = true; - request_bytes = static_cast<uint8_t*>(gpr_malloc(request->Length())); + } else if (slices.size() > 1) { + request_bytes = static_cast<uint8_t*>(gpr_malloc(request.Length())); uint8_t* copy_to = request_bytes; for (size_t i = 0; i < slices.size(); i++) { memcpy(copy_to, slices[i].begin(), slices[i].size()); copy_to += slices[i].size(); } } - - if (request_bytes != nullptr) { - pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); - bool decode_status = pb_decode( - &istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct); - if (request_bytes_owned) { - gpr_free(request_bytes); - } - if (!decode_status) { - return Status(StatusCode::INVALID_ARGUMENT, ""); - } - } - - // Check status from the associated default health checking service. - DefaultHealthCheckService::ServingStatus serving_status = - service_->GetServingStatus( - request_struct.has_service ? request_struct.service : ""); - if (serving_status == DefaultHealthCheckService::NOT_FOUND) { - return Status(StatusCode::NOT_FOUND, ""); + pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size); + bool decode_status = pb_decode( + &istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct); + if (slices.size() > 1) { + gpr_free(request_bytes); } + if (!decode_status) return false; + *service_name = request_struct.has_service ? request_struct.service : ""; + return true; +} - // Encode response +bool DefaultHealthCheckService::HealthCheckServiceImpl::EncodeResponse( + ServingStatus status, ByteBuffer* response) { grpc_health_v1_HealthCheckResponse response_struct; response_struct.has_status = true; response_struct.status = - serving_status == DefaultHealthCheckService::SERVING - ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING - : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; + status == NOT_FOUND + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVICE_UNKNOWN + : status == SERVING + ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING + : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING; pb_ostream_t ostream; memset(&ostream, 0, sizeof(ostream)); pb_encode(&ostream, grpc_health_v1_HealthCheckResponse_fields, @@ -108,48 +228,253 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check( GRPC_SLICE_LENGTH(response_slice)); bool encode_status = pb_encode( &ostream, grpc_health_v1_HealthCheckResponse_fields, &response_struct); - if (!encode_status) { - return Status(StatusCode::INTERNAL, "Failed to encode response."); - } + if (!encode_status) return false; Slice encoded_response(response_slice, Slice::STEAL_REF); ByteBuffer response_buffer(&encoded_response, 1); response->Swap(&response_buffer); - return Status::OK; + return true; } -DefaultHealthCheckService::DefaultHealthCheckService() { - services_map_.emplace("", true); +// +// DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler +// + +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) { + std::shared_ptr<CallHandler> self = + std::make_shared<CheckCallHandler>(cq, database, service); + CheckCallHandler* handler = static_cast<CheckCallHandler*>(self.get()); + { + std::unique_lock<std::mutex> lock(service->cq_shutdown_mu_); + if (service->shutdown_) return; + // Request a Check() call. + handler->next_ = + CallableTag(std::bind(&CheckCallHandler::OnCallReceived, handler, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + service->RequestAsyncUnary(0, &handler->ctx_, &handler->request_, + &handler->writer_, cq, cq, &handler->next_); + } } -void DefaultHealthCheckService::SetServingStatus( - const grpc::string& service_name, bool serving) { - std::lock_guard<std::mutex> lock(mu_); - services_map_[service_name] = serving; +DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + CheckCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) + : cq_(cq), database_(database), service_(service), writer_(&ctx_) {} + +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + OnCallReceived(std::shared_ptr<CallHandler> self, bool ok) { + if (!ok) { + // The value of ok being false means that the server is shutting down. + return; + } + // Spawn a new handler instance to serve the next new client. Every handler + // instance will deallocate itself when it's done. + CreateAndStart(cq_, database_, service_); + // Process request. + gpr_log(GPR_DEBUG, "[HCS %p] Health check started for handler %p", service_, + this); + grpc::string service_name; + grpc::Status status = Status::OK; + ByteBuffer response; + if (!service_->DecodeRequest(request_, &service_name)) { + status = Status(StatusCode::INVALID_ARGUMENT, "could not parse request"); + } else { + ServingStatus serving_status = database_->GetServingStatus(service_name); + if (serving_status == NOT_FOUND) { + status = Status(StatusCode::NOT_FOUND, "service name unknown"); + } else if (!service_->EncodeResponse(serving_status, &response)) { + status = Status(StatusCode::INTERNAL, "could not encode response"); + } + } + // Send response. + { + std::unique_lock<std::mutex> lock(service_->cq_shutdown_mu_); + if (!service_->shutdown_) { + next_ = + CallableTag(std::bind(&CheckCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + if (status.ok()) { + writer_.Finish(response, status, &next_); + } else { + writer_.FinishWithError(status, &next_); + } + } + } } -void DefaultHealthCheckService::SetServingStatus(bool serving) { - std::lock_guard<std::mutex> lock(mu_); - for (auto iter = services_map_.begin(); iter != services_map_.end(); ++iter) { - iter->second = serving; +void DefaultHealthCheckService::HealthCheckServiceImpl::CheckCallHandler:: + OnFinishDone(std::shared_ptr<CallHandler> self, bool ok) { + if (ok) { + gpr_log(GPR_DEBUG, "[HCS %p] Health check call finished for handler %p", + service_, this); } + self.reset(); // To appease clang-tidy. } -DefaultHealthCheckService::ServingStatus -DefaultHealthCheckService::GetServingStatus( - const grpc::string& service_name) const { - std::lock_guard<std::mutex> lock(mu_); - const auto& iter = services_map_.find(service_name); - if (iter == services_map_.end()) { - return NOT_FOUND; +// +// DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler +// + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) { + std::shared_ptr<CallHandler> self = + std::make_shared<WatchCallHandler>(cq, database, service); + WatchCallHandler* handler = static_cast<WatchCallHandler*>(self.get()); + { + std::unique_lock<std::mutex> lock(service->cq_shutdown_mu_); + if (service->shutdown_) return; + // Request AsyncNotifyWhenDone(). + handler->on_done_notified_ = + CallableTag(std::bind(&WatchCallHandler::OnDoneNotified, handler, + std::placeholders::_1, std::placeholders::_2), + self /* copies ref */); + handler->ctx_.AsyncNotifyWhenDone(&handler->on_done_notified_); + // Request a Watch() call. + handler->next_ = + CallableTag(std::bind(&WatchCallHandler::OnCallReceived, handler, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + service->RequestAsyncServerStreaming(1, &handler->ctx_, &handler->request_, + &handler->stream_, cq, cq, + &handler->next_); } - return iter->second ? SERVING : NOT_SERVING; } -DefaultHealthCheckService::HealthCheckServiceImpl* -DefaultHealthCheckService::GetHealthCheckService() { - GPR_ASSERT(impl_ == nullptr); - impl_.reset(new HealthCheckServiceImpl(this)); - return impl_.get(); +DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + WatchCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service) + : cq_(cq), database_(database), service_(service), stream_(&ctx_) {} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnCallReceived(std::shared_ptr<CallHandler> self, bool ok) { + if (!ok) { + // Server shutting down. + // + // AsyncNotifyWhenDone() needs to be called before the call starts, but the + // tag will not pop out if the call never starts ( + // https://github.com/grpc/grpc/issues/10136). So we need to manually + // release the ownership of the handler in this case. + GPR_ASSERT(on_done_notified_.ReleaseHandler() != nullptr); + return; + } + // Spawn a new handler instance to serve the next new client. Every handler + // instance will deallocate itself when it's done. + CreateAndStart(cq_, database_, service_); + // Parse request. + if (!service_->DecodeRequest(request_, &service_name_)) { + SendFinish(std::move(self), + Status(StatusCode::INVALID_ARGUMENT, "could not parse request")); + return; + } + // Register the call for updates to the service. + gpr_log(GPR_DEBUG, + "[HCS %p] Health watch started for service \"%s\" (handler: %p)", + service_, service_name_.c_str(), this); + database_->RegisterCallHandler(service_name_, std::move(self)); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendHealth(std::shared_ptr<CallHandler> self, ServingStatus status) { + std::unique_lock<std::mutex> lock(send_mu_); + // If there's already a send in flight, cache the new status, and + // we'll start a new send for it when the one in flight completes. + if (send_in_flight_) { + pending_status_ = status; + return; + } + // Start a send. + SendHealthLocked(std::move(self), status); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendHealthLocked(std::shared_ptr<CallHandler> self, ServingStatus status) { + send_in_flight_ = true; + // Construct response. + ByteBuffer response; + bool success = service_->EncodeResponse(status, &response); + // Grab shutdown lock and send response. + std::unique_lock<std::mutex> cq_lock(service_->cq_shutdown_mu_); + if (service_->shutdown_) { + SendFinishLocked(std::move(self), Status::CANCELLED); + return; + } + if (!success) { + SendFinishLocked(std::move(self), + Status(StatusCode::INTERNAL, "could not encode response")); + return; + } + next_ = CallableTag(std::bind(&WatchCallHandler::OnSendHealthDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Write(response, &next_); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnSendHealthDone(std::shared_ptr<CallHandler> self, bool ok) { + if (!ok) { + SendFinish(std::move(self), Status::CANCELLED); + return; + } + std::unique_lock<std::mutex> lock(send_mu_); + send_in_flight_ = false; + // If we got a new status since we started the last send, start a + // new send for it. + if (pending_status_ != NOT_FOUND) { + auto status = pending_status_; + pending_status_ = NOT_FOUND; + SendHealthLocked(std::move(self), status); + } +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendFinish(std::shared_ptr<CallHandler> self, const Status& status) { + if (finish_called_) return; + std::unique_lock<std::mutex> cq_lock(service_->cq_shutdown_mu_); + if (service_->shutdown_) return; + SendFinishLocked(std::move(self), status); +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + SendFinishLocked(std::shared_ptr<CallHandler> self, const Status& status) { + on_finish_done_ = + CallableTag(std::bind(&WatchCallHandler::OnFinishDone, this, + std::placeholders::_1, std::placeholders::_2), + std::move(self)); + stream_.Finish(status, &on_finish_done_); + finish_called_ = true; +} + +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnFinishDone(std::shared_ptr<CallHandler> self, bool ok) { + if (ok) { + gpr_log(GPR_DEBUG, + "[HCS %p] Health watch call finished (service_name: \"%s\", " + "handler: %p).", + service_, service_name_.c_str(), this); + } + self.reset(); // To appease clang-tidy. +} + +// TODO(roth): This method currently assumes that there will be only one +// thread polling the cq and invoking the corresponding callbacks. If +// that changes, we will need to add synchronization here. +void DefaultHealthCheckService::HealthCheckServiceImpl::WatchCallHandler:: + OnDoneNotified(std::shared_ptr<CallHandler> self, bool ok) { + GPR_ASSERT(ok); + gpr_log(GPR_DEBUG, + "[HCS %p] Health watch call is notified done (handler: %p, " + "is_cancelled: %d).", + service_, this, static_cast<int>(ctx_.IsCancelled())); + database_->UnregisterCallHandler(service_name_, self); + SendFinish(std::move(self), Status::CANCELLED); } } // namespace grpc diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h index a1ce5aa64e..450bd543f5 100644 --- a/src/cpp/server/health/default_health_check_service.h +++ b/src/cpp/server/health/default_health_check_service.h @@ -19,42 +19,260 @@ #ifndef GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H #define GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H +#include <atomic> #include <mutex> +#include <set> +#include <grpc/support/log.h> +#include <grpcpp/grpcpp.h> #include <grpcpp/health_check_service_interface.h> +#include <grpcpp/impl/codegen/async_generic_service.h> +#include <grpcpp/impl/codegen/async_unary_call.h> #include <grpcpp/impl/codegen/service_type.h> #include <grpcpp/support/byte_buffer.h> +#include "src/core/lib/gprpp/thd.h" + namespace grpc { // Default implementation of HealthCheckServiceInterface. Server will create and // own it. class DefaultHealthCheckService final : public HealthCheckServiceInterface { public: + enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; + // The service impl to register with the server. class HealthCheckServiceImpl : public Service { public: - explicit HealthCheckServiceImpl(DefaultHealthCheckService* service); + // Base class for call handlers. + class CallHandler { + public: + virtual ~CallHandler() = default; + virtual void SendHealth(std::shared_ptr<CallHandler> self, + ServingStatus status) = 0; + }; - Status Check(ServerContext* context, const ByteBuffer* request, - ByteBuffer* response); + HealthCheckServiceImpl(DefaultHealthCheckService* database, + std::unique_ptr<ServerCompletionQueue> cq); + + ~HealthCheckServiceImpl(); + + void StartServingThread(); private: - const DefaultHealthCheckService* const service_; - internal::RpcServiceMethod* method_; + // A tag that can be called with a bool argument. It's tailored for + // CallHandler's use. Before being used, it should be constructed with a + // method of CallHandler and a shared pointer to the handler. The + // shared pointer will be moved to the invoked function and the function + // can only be invoked once. That makes ref counting of the handler easier, + // because the shared pointer is not bound to the function and can be gone + // once the invoked function returns (if not used any more). + class CallableTag { + public: + using HandlerFunction = + std::function<void(std::shared_ptr<CallHandler>, bool)>; + + CallableTag() {} + + CallableTag(HandlerFunction func, std::shared_ptr<CallHandler> handler) + : handler_function_(std::move(func)), handler_(std::move(handler)) { + GPR_ASSERT(handler_function_ != nullptr); + GPR_ASSERT(handler_ != nullptr); + } + + // Runs the tag. This should be called only once. The handler is no + // longer owned by this tag after this method is invoked. + void Run(bool ok) { + GPR_ASSERT(handler_function_ != nullptr); + GPR_ASSERT(handler_ != nullptr); + handler_function_(std::move(handler_), ok); + } + + // Releases and returns the shared pointer to the handler. + std::shared_ptr<CallHandler> ReleaseHandler() { + return std::move(handler_); + } + + private: + HandlerFunction handler_function_ = nullptr; + std::shared_ptr<CallHandler> handler_; + }; + + // Call handler for Check method. + // Each handler takes care of one call. It contains per-call data and it + // will access the members of the parent class (i.e., + // DefaultHealthCheckService) for per-service health data. + class CheckCallHandler : public CallHandler { + public: + // Instantiates a CheckCallHandler and requests the next health check + // call. The handler object will manage its own lifetime, so no action is + // needed from the caller any more regarding that object. + static void CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // This ctor is public because we want to use std::make_shared<> in + // CreateAndStart(). This ctor shouldn't be used elsewhere. + CheckCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // Not used for Check. + void SendHealth(std::shared_ptr<CallHandler> self, + ServingStatus status) override {} + + private: + // Called when we receive a call. + // Spawns a new handler so that we can keep servicing future calls. + void OnCallReceived(std::shared_ptr<CallHandler> self, bool ok); + + // Called when Finish() is done. + void OnFinishDone(std::shared_ptr<CallHandler> self, bool ok); + + // The members passed down from HealthCheckServiceImpl. + ServerCompletionQueue* cq_; + DefaultHealthCheckService* database_; + HealthCheckServiceImpl* service_; + + ByteBuffer request_; + GenericServerAsyncResponseWriter writer_; + ServerContext ctx_; + + CallableTag next_; + }; + + // Call handler for Watch method. + // Each handler takes care of one call. It contains per-call data and it + // will access the members of the parent class (i.e., + // DefaultHealthCheckService) for per-service health data. + class WatchCallHandler : public CallHandler { + public: + // Instantiates a WatchCallHandler and requests the next health check + // call. The handler object will manage its own lifetime, so no action is + // needed from the caller any more regarding that object. + static void CreateAndStart(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + // This ctor is public because we want to use std::make_shared<> in + // CreateAndStart(). This ctor shouldn't be used elsewhere. + WatchCallHandler(ServerCompletionQueue* cq, + DefaultHealthCheckService* database, + HealthCheckServiceImpl* service); + + void SendHealth(std::shared_ptr<CallHandler> self, + ServingStatus status) override; + + private: + // Called when we receive a call. + // Spawns a new handler so that we can keep servicing future calls. + void OnCallReceived(std::shared_ptr<CallHandler> self, bool ok); + + // Requires holding send_mu_. + void SendHealthLocked(std::shared_ptr<CallHandler> self, + ServingStatus status); + + // When sending a health result finishes. + void OnSendHealthDone(std::shared_ptr<CallHandler> self, bool ok); + + void SendFinish(std::shared_ptr<CallHandler> self, const Status& status); + + // Requires holding service_->cq_shutdown_mu_. + void SendFinishLocked(std::shared_ptr<CallHandler> self, + const Status& status); + + // Called when Finish() is done. + void OnFinishDone(std::shared_ptr<CallHandler> self, bool ok); + + // Called when AsyncNotifyWhenDone() notifies us. + void OnDoneNotified(std::shared_ptr<CallHandler> self, bool ok); + + // The members passed down from HealthCheckServiceImpl. + ServerCompletionQueue* cq_; + DefaultHealthCheckService* database_; + HealthCheckServiceImpl* service_; + + ByteBuffer request_; + grpc::string service_name_; + GenericServerAsyncWriter stream_; + ServerContext ctx_; + + std::mutex send_mu_; + bool send_in_flight_ = false; // Guarded by mu_. + ServingStatus pending_status_ = NOT_FOUND; // Guarded by mu_. + + bool finish_called_ = false; + CallableTag next_; + CallableTag on_done_notified_; + CallableTag on_finish_done_; + }; + + // Handles the incoming requests and drives the completion queue in a loop. + static void Serve(void* arg); + + // Returns true on success. + static bool DecodeRequest(const ByteBuffer& request, + grpc::string* service_name); + static bool EncodeResponse(ServingStatus status, ByteBuffer* response); + + // Needed to appease Windows compilers, which don't seem to allow + // nested classes to access protected members in the parent's + // superclass. + using Service::RequestAsyncServerStreaming; + using Service::RequestAsyncUnary; + + DefaultHealthCheckService* database_; + std::unique_ptr<ServerCompletionQueue> cq_; + + // To synchronize the operations related to shutdown state of cq_, so that + // we don't enqueue new tags into cq_ after it is already shut down. + std::mutex cq_shutdown_mu_; + std::atomic_bool shutdown_{false}; + std::unique_ptr<::grpc_core::Thread> thread_; }; DefaultHealthCheckService(); + void SetServingStatus(const grpc::string& service_name, bool serving) override; void SetServingStatus(bool serving) override; - enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING }; + ServingStatus GetServingStatus(const grpc::string& service_name) const; - HealthCheckServiceImpl* GetHealthCheckService(); + + HealthCheckServiceImpl* GetHealthCheckService( + std::unique_ptr<ServerCompletionQueue> cq); private: + // Stores the current serving status of a service and any call + // handlers registered for updates when the service's status changes. + class ServiceData { + public: + void SetServingStatus(ServingStatus status); + ServingStatus GetServingStatus() const { return status_; } + void AddCallHandler( + std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler); + void RemoveCallHandler( + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler); + bool Unused() const { + return call_handlers_.empty() && status_ == NOT_FOUND; + } + + private: + ServingStatus status_ = NOT_FOUND; + std::set<std::shared_ptr<HealthCheckServiceImpl::CallHandler>> + call_handlers_; + }; + + void RegisterCallHandler( + const grpc::string& service_name, + std::shared_ptr<HealthCheckServiceImpl::CallHandler> handler); + + void UnregisterCallHandler( + const grpc::string& service_name, + const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler); + mutable std::mutex mu_; - std::map<grpc::string, bool> services_map_; + std::map<grpc::string, ServiceData> services_map_; // Guarded by mu_. std::unique_ptr<HealthCheckServiceImpl> impl_; }; diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc index 7c764f4bce..7aeddff643 100644 --- a/src/cpp/server/server_cc.cc +++ b/src/cpp/server/server_cc.cc @@ -380,7 +380,6 @@ class Server::SyncRequestThreadManager : public ThreadManager { int cq_timeout_msec_; std::vector<std::unique_ptr<SyncRequest>> sync_requests_; std::unique_ptr<internal::RpcServiceMethod> unknown_method_; - std::unique_ptr<internal::RpcServiceMethod> health_check_; std::shared_ptr<Server::GlobalCallbacks> global_callbacks_; }; @@ -573,16 +572,24 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { // Only create default health check service when user did not provide an // explicit one. + ServerCompletionQueue* health_check_cq = nullptr; + DefaultHealthCheckService::HealthCheckServiceImpl* + default_health_check_service_impl = nullptr; if (health_check_service_ == nullptr && !health_check_service_disabled_ && DefaultHealthCheckServiceEnabled()) { - if (sync_server_cqs_ == nullptr || sync_server_cqs_->empty()) { - gpr_log(GPR_INFO, - "Default health check service disabled at async-only server."); - } else { - auto* default_hc_service = new DefaultHealthCheckService; - health_check_service_.reset(default_hc_service); - RegisterService(nullptr, default_hc_service->GetHealthCheckService()); - } + auto* default_hc_service = new DefaultHealthCheckService; + health_check_service_.reset(default_hc_service); + // We create a non-polling CQ to avoid impacting application + // performance. This ensures that we don't introduce thread hops + // for application requests that wind up on this CQ, which is polled + // in its own thread. + health_check_cq = new ServerCompletionQueue(GRPC_CQ_NON_POLLING); + grpc_server_register_completion_queue(server_, health_check_cq->cq(), + nullptr); + default_health_check_service_impl = + default_hc_service->GetHealthCheckService( + std::unique_ptr<ServerCompletionQueue>(health_check_cq)); + RegisterService(nullptr, default_health_check_service_impl); } grpc_server_start(server_); @@ -597,6 +604,9 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { new UnimplementedAsyncRequest(this, cqs[i]); } } + if (health_check_cq != nullptr) { + new UnimplementedAsyncRequest(this, health_check_cq); + } } // If this server has any support for synchronous methods (has any sync @@ -609,6 +619,10 @@ void Server::Start(ServerCompletionQueue** cqs, size_t num_cqs) { for (auto it = sync_req_mgrs_.begin(); it != sync_req_mgrs_.end(); it++) { (*it)->Start(); } + + if (default_health_check_service_impl != nullptr) { + default_health_check_service_impl->StartServingThread(); + } } void Server::ShutdownInternal(gpr_timespec deadline) { @@ -671,8 +685,8 @@ void Server::PerformOpsOnCall(internal::CallOpSetInterface* ops, size_t nops = 0; grpc_op cops[MAX_OPS]; ops->FillOps(call->call(), cops, &nops); - // TODO(vjpai): Use ops->cq_tag once this case supports callbacks - auto result = grpc_call_start_batch(call->call(), cops, nops, ops, nullptr); + auto result = + grpc_call_start_batch(call->call(), cops, nops, ops->cq_tag(), nullptr); if (result != GRPC_CALL_OK) { gpr_log(GPR_ERROR, "Fatal: grpc_call_start_batch returned %d", result); grpc_call_log_batch(__FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR, diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index b7254b6bb9..bd532a968d 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -40,13 +40,29 @@ namespace grpc { class ServerContext::CompletionOp final : public internal::CallOpSetInterface { public: // initial refs: one in the server context, one in the cq - CompletionOp() - : has_tag_(false), + // must ref the call before calling constructor and after deleting this + CompletionOp(grpc_call* call) + : call_(call), + has_tag_(false), tag_(nullptr), refs_(2), finalized_(false), cancelled_(0) {} + // This should always be arena allocated in the call, so override delete. + // But this class is not trivially destructible, so must actually call delete + // before allowing the arena to be freed + static void operator delete(void* ptr, std::size_t size) { + assert(size == sizeof(CompletionOp)); + } + + // This operator should never be called as the memory should be freed as part + // of the arena destruction. It only exists to provide a matching operator + // delete to the operator new so that some compilers will not complain (see + // https://github.com/grpc/grpc/issues/11301) Note at the time of adding this + // there are no tests catching the compiler warning. + static void operator delete(void*, void*) { assert(0); } + void FillOps(grpc_call* call, grpc_op* ops, size_t* nops) override; bool FinalizeResult(void** tag, bool* status) override; @@ -72,6 +88,7 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface { return finalized_ ? (cancelled_ != 0) : false; } + grpc_call* call_; bool has_tag_; void* tag_; std::mutex mu_; @@ -84,7 +101,10 @@ void ServerContext::CompletionOp::Unref() { std::unique_lock<std::mutex> lock(mu_); if (--refs_ == 0) { lock.unlock(); + // Save aside the call pointer before deleting for later unref + grpc_call* call = call_; delete this; + grpc_call_unref(call); } } @@ -108,7 +128,10 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) { if (!*status) cancelled_ = 1; if (--refs_ == 0) { lock.unlock(); + // Save aside the call pointer before deleting for later unref + grpc_call* call = call_; delete this; + grpc_call_unref(call); } return ret; } @@ -150,7 +173,10 @@ ServerContext::~ServerContext() { void ServerContext::BeginCompletionOp(internal::Call* call) { GPR_ASSERT(!completion_op_); - completion_op_ = new CompletionOp(); + grpc_call_ref(call->call()); + completion_op_ = + new (grpc_call_arena_alloc(call->call(), sizeof(CompletionOp))) + CompletionOp(call->call()); if (has_notify_when_done_tag_) { completion_op_->set_tag(async_notify_when_done_tag_); } diff --git a/src/proto/grpc/health/v1/health.proto b/src/proto/grpc/health/v1/health.proto index 4b4677b8a4..38843ff1e7 100644 --- a/src/proto/grpc/health/v1/health.proto +++ b/src/proto/grpc/health/v1/health.proto @@ -34,10 +34,30 @@ message HealthCheckResponse { UNKNOWN = 0; SERVING = 1; NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; // Used only by the Watch method. } ServingStatus status = 1; } service Health { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 932621a38d..cb48b9f62c 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -254,11 +254,14 @@ CORE_SOURCE_FILES = [ 'src/core/lib/security/credentials/oauth2/oauth2_credentials.cc', 'src/core/lib/security/credentials/plugin/plugin_credentials.cc', 'src/core/lib/security/credentials/ssl/ssl_credentials.cc', - 'src/core/lib/security/security_connector/alts_security_connector.cc', + 'src/core/lib/security/security_connector/alts/alts_security_connector.cc', + 'src/core/lib/security/security_connector/fake/fake_security_connector.cc', 'src/core/lib/security/security_connector/load_system_roots_fallback.cc', 'src/core/lib/security/security_connector/load_system_roots_linux.cc', - 'src/core/lib/security/security_connector/local_security_connector.cc', + 'src/core/lib/security/security_connector/local/local_security_connector.cc', 'src/core/lib/security/security_connector/security_connector.cc', + 'src/core/lib/security/security_connector/ssl/ssl_security_connector.cc', + 'src/core/lib/security/security_connector/ssl_utils.cc', 'src/core/lib/security/transport/client_auth_filter.cc', 'src/core/lib/security/transport/secure_endpoint.cc', 'src/core/lib/security/transport/security_handshaker.cc', @@ -313,6 +316,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/client_channel_factory.cc', 'src/core/ext/filters/client_channel/client_channel_plugin.cc', 'src/core/ext/filters/client_channel/connector.cc', + 'src/core/ext/filters/client_channel/health/health_check_client.cc', 'src/core/ext/filters/client_channel/http_connect_handshaker.cc', 'src/core/ext/filters/client_channel/http_proxy.cc', 'src/core/ext/filters/client_channel/lb_policy.cc', @@ -329,6 +333,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/subchannel_index.cc', 'src/core/ext/filters/client_channel/uri_parser.cc', 'src/core/ext/filters/deadline/deadline_filter.cc', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/tsi/alts_transport_security.cc', 'src/core/tsi/fake_transport_security.cc', 'src/core/tsi/local_transport_security.cc', @@ -348,10 +353,14 @@ CORE_SOURCE_FILES = [ 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc', + 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', - 'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc', + 'src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc', 'src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc', 'src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc', 'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc', diff --git a/src/proto/grpc/testing/package_options.proto b/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto index e7ecf8c196..e7ecf8c196 100644 --- a/src/proto/grpc/testing/package_options.proto +++ b/src/ruby/spec/pb/codegen/grpc/testing/package_options.proto diff --git a/src/ruby/spec/pb/codegen/package_option_spec.rb b/src/ruby/spec/pb/codegen/package_option_spec.rb index 46d23cd651..0ebd503d79 100644 --- a/src/ruby/spec/pb/codegen/package_option_spec.rb +++ b/src/ruby/spec/pb/codegen/package_option_spec.rb @@ -21,9 +21,8 @@ describe 'Code Generation Options' do fail 'CONFIG env variable unexpectedly unset' unless ENV['CONFIG'] bins_sub_dir = ENV['CONFIG'] - src_dir = File.join(File.dirname(__FILE__), '..', '..', '..', '..') - pb_dir = File.join(src_dir, 'proto') - bins_dir = File.join(src_dir, '..', 'bins', bins_sub_dir) + pb_dir = File.dirname(__FILE__) + bins_dir = File.join('..', '..', '..', '..', '..', 'bins', bins_sub_dir) plugin = File.join(bins_dir, 'grpc_ruby_plugin') protoc = File.join(bins_dir, 'protobuf', 'protoc') diff --git a/templates/tools/dockerfile/apt_get_python_27.include b/templates/tools/dockerfile/apt_get_python_27.include new file mode 100644 index 0000000000..4ee37ef11f --- /dev/null +++ b/templates/tools/dockerfile/apt_get_python_27.include @@ -0,0 +1,3 @@ +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 diff --git a/templates/tools/dockerfile/debian_testing_repo.include b/templates/tools/dockerfile/debian_testing_repo.include new file mode 100644 index 0000000000..1a5248e226 --- /dev/null +++ b/templates/tools/dockerfile/debian_testing_repo.include @@ -0,0 +1,3 @@ +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local diff --git a/templates/tools/dockerfile/java_build_interop.sh.include b/templates/tools/dockerfile/java_build_interop.sh.include index 895b86ace0..16d5fb65cf 100755 --- a/templates/tools/dockerfile/java_build_interop.sh.include +++ b/templates/tools/dockerfile/java_build_interop.sh.include @@ -25,3 +25,11 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true + +# enable extra java logging +mkdir -p /var/local/grpc_java_logging +echo "handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL +.level = FINE +io.grpc.netty.NettyClientHandler = ALL +io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt diff --git a/templates/tools/dockerfile/python_stretch.include b/templates/tools/dockerfile/python_stretch.include new file mode 100644 index 0000000000..45bafe5184 --- /dev/null +++ b/templates/tools/dockerfile/python_stretch.include @@ -0,0 +1,9 @@ +FROM debian:stretch + +<%include file="./apt_get_basic.include"/> +<%include file="./gcp_api_libraries.include"/> +<%include file="./apt_get_python_27.include"/> +<%include file="./debian_testing_repo.include"/> +<%include file="./run_tests_addons.include"/> +# Define the default command. +CMD ["bash"] diff --git a/templates/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile.template new file mode 100644 index 0000000000..a1c9d9f84d --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile.template @@ -0,0 +1,17 @@ +%YAML 1.2 +--- | + # Copyright 2018 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> diff --git a/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile.template index 1e013b742c..93b655ea0d 100644 --- a/templates/tools/dockerfile/test/python_pyenv_x64/Dockerfile.template +++ b/templates/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2016 gRPC authors. + # Copyright 2018 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. @@ -13,17 +13,8 @@ # 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. - - FROM debian:stretch - - <%include file="../../apt_get_basic.include"/> - <%include file="../../gcp_api_libraries.include"/> - <%include file="../../python_deps.include"/> - <%include file="../../apt_get_pyenv.include"/> - # Install pip and virtualenv for Python 3.5 - RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 - RUN python3.5 -m pip install virtualenv - <%include file="../../run_tests_addons.include"/> - # Define the default command. - CMD ["bash"] + <%include file="../../python_stretch.include"/> + + RUN apt-get update && apt-get install -y python3.5 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 diff --git a/templates/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile.template new file mode 100644 index 0000000000..a5dcf196f2 --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile.template @@ -0,0 +1,20 @@ +%YAML 1.2 +--- | + # Copyright 2018 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> + + RUN apt-get update && apt-get -t testing install -y python3.6 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 diff --git a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template new file mode 100644 index 0000000000..ff342db493 --- /dev/null +++ b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template @@ -0,0 +1,20 @@ +%YAML 1.2 +--- | + # Copyright 2018 The gRPC Authors + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + <%include file="../../python_stretch.include"/> + + RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev + RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template b/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template new file mode 100644 index 0000000000..18d71a7c84 --- /dev/null +++ b/templates/tools/run_tests/generated/lb_interop_test_scenarios.json.template @@ -0,0 +1,6 @@ +%YAML 1.2 +--- | + <%! + import json + %> + ${json.dumps(lb_interop_test_scenarios, indent=4, sort_keys=True)} diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc index 5ead12e870..5f27320512 100644 --- a/test/core/channel/channelz_test.cc +++ b/test/core/channel/channelz_test.cc @@ -85,6 +85,19 @@ void ValidateJsonArraySize(grpc_json* json, const char* key, EXPECT_EQ(count, expected_size); } +std::vector<intptr_t> GetUuidListFromArray(grpc_json* arr) { + EXPECT_EQ(arr->type, GRPC_JSON_ARRAY); + std::vector<intptr_t> uuids; + for (grpc_json* child = arr->child; child != nullptr; child = child->next) { + grpc_json* it = GetJsonChild(child, "ref"); + EXPECT_NE(it, nullptr); + it = GetJsonChild(it, "channelId"); + EXPECT_NE(it, nullptr); + uuids.push_back(atoi(it->value)); + } + return uuids; +} + void ValidateGetTopChannels(size_t expected_channels) { char* json_str = ChannelzRegistry::GetTopChannels(0); grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(json_str); @@ -226,19 +239,7 @@ void ChannelzSleep(int64_t sleep_us) { } // anonymous namespace -class ChannelzChannelTest : public ::testing::TestWithParam<size_t> { - protected: - // ensure we always have a fresh registry for tests. - void SetUp() override { - ChannelzRegistry::Shutdown(); - ChannelzRegistry::Init(); - } - - void TearDown() override { - ChannelzRegistry::Shutdown(); - ChannelzRegistry::Init(); - } -}; +class ChannelzChannelTest : public ::testing::TestWithParam<size_t> {}; TEST_P(ChannelzChannelTest, BasicChannel) { grpc_core::ExecCtx exec_ctx; @@ -307,25 +308,39 @@ TEST_P(ChannelzChannelTest, LastCallStartedMillis) { EXPECT_NE(millis1, millis4); } -TEST(ChannelzGetTopChannelsTest, BasicGetTopChannelsTest) { +class ChannelzRegistryBasedTest : public ::testing::TestWithParam<size_t> { + protected: + // ensure we always have a fresh registry for tests. + void SetUp() override { + ChannelzRegistry::Shutdown(); + ChannelzRegistry::Init(); + } + + void TearDown() override { + ChannelzRegistry::Shutdown(); + ChannelzRegistry::Init(); + } +}; + +TEST_F(ChannelzRegistryBasedTest, BasicGetTopChannelsTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channel; ValidateGetTopChannels(1); } -TEST(ChannelzGetTopChannelsTest, NoChannelsTest) { +TEST_F(ChannelzRegistryBasedTest, NoChannelsTest) { grpc_core::ExecCtx exec_ctx; ValidateGetTopChannels(0); } -TEST(ChannelzGetTopChannelsTest, ManyChannelsTest) { +TEST_F(ChannelzRegistryBasedTest, ManyChannelsTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channels[10]; (void)channels; // suppress unused variable error ValidateGetTopChannels(10); } -TEST(ChannelzGetTopChannelsTest, GetTopChannelsPagination) { +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsPagination) { grpc_core::ExecCtx exec_ctx; // this is over the pagination limit. ChannelFixture channels[150]; @@ -351,7 +366,116 @@ TEST(ChannelzGetTopChannelsTest, GetTopChannelsPagination) { gpr_free(json_str); } -TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidCheck) { + const intptr_t kNumChannels = 50; + grpc_core::ExecCtx exec_ctx; + ChannelFixture channels[kNumChannels]; + (void)channels; // suppress unused variable error + char* json_str = ChannelzRegistry::GetTopChannels(0); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", kNumChannels); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (int i = 0; i < kNumChannels; ++i) { + EXPECT_EQ(i + 1, uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsMiddleUuidCheck) { + const intptr_t kNumChannels = 50; + const intptr_t kMidQuery = 40; + grpc_core::ExecCtx exec_ctx; + ChannelFixture channels[kNumChannels]; + (void)channels; // suppress unused variable error + // only query for the end of the channels + char* json_str = ChannelzRegistry::GetTopChannels(kMidQuery); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", kNumChannels - kMidQuery + 1); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (size_t i = 0; i < uuids.size(); ++i) { + EXPECT_EQ(static_cast<intptr_t>(kMidQuery + i), uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsNoHitUuid) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture pre_channels[40]; // will take uuid[1, 40] + (void)pre_channels; // suppress unused variable error + ServerFixture servers[10]; // will take uuid[41, 50] + (void)servers; // suppress unused variable error + ChannelFixture channels[10]; // will take uuid[51, 60] + (void)channels; // suppress unused variable error + // query in the middle of the server channels + char* json_str = ChannelzRegistry::GetTopChannels(45); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", 10); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (size_t i = 0; i < uuids.size(); ++i) { + EXPECT_EQ(static_cast<intptr_t>(51 + i), uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsMoreGaps) { + grpc_core::ExecCtx exec_ctx; + ChannelFixture channel_with_uuid1; + { ServerFixture channel_with_uuid2; } + ChannelFixture channel_with_uuid3; + { ServerFixture server_with_uuid4; } + ChannelFixture channel_with_uuid5; + // Current state of list: [1, NULL, 3, NULL, 5] + char* json_str = ChannelzRegistry::GetTopChannels(2); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", 2); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + EXPECT_EQ(static_cast<intptr_t>(3), uuids[0]); + EXPECT_EQ(static_cast<intptr_t>(5), uuids[1]); + grpc_json_destroy(parsed_json); + gpr_free(json_str); + json_str = ChannelzRegistry::GetTopChannels(4); + parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", 1); + json_channels = GetJsonChild(parsed_json, "channel"); + uuids = GetUuidListFromArray(json_channels); + EXPECT_EQ(static_cast<intptr_t>(5), uuids[0]); + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, GetTopChannelsUuidAfterCompaction) { + const intptr_t kLoopIterations = 50; + grpc_core::ExecCtx exec_ctx; + std::vector<UniquePtr<ChannelFixture>> even_channels; + { + // these will delete and unregister themselves after this block. + std::vector<UniquePtr<ChannelFixture>> odd_channels; + for (int i = 0; i < kLoopIterations; i++) { + odd_channels.push_back(MakeUnique<ChannelFixture>()); + even_channels.push_back(MakeUnique<ChannelFixture>()); + } + } + char* json_str = ChannelzRegistry::GetTopChannels(0); + grpc_json* parsed_json = grpc_json_parse_string(json_str); + ValidateJsonArraySize(parsed_json, "channel", kLoopIterations); + grpc_json* json_channels = GetJsonChild(parsed_json, "channel"); + std::vector<intptr_t> uuids = GetUuidListFromArray(json_channels); + for (int i = 0; i < kLoopIterations; ++i) { + // only the even uuids will still be present. + EXPECT_EQ((i + 1) * 2, uuids[i]); + } + grpc_json_destroy(parsed_json); + gpr_free(json_str); +} + +TEST_F(ChannelzRegistryBasedTest, InternalChannelTest) { grpc_core::ExecCtx exec_ctx; ChannelFixture channels[10]; (void)channels; // suppress unused variable error @@ -369,9 +493,7 @@ TEST(ChannelzGetTopChannelsTest, InternalChannelTest) { grpc_channel_destroy(internal_channel); } -class ChannelzServerTest : public ::testing::TestWithParam<size_t> {}; - -TEST_P(ChannelzServerTest, BasicServerAPIFunctionality) { +TEST(ChannelzServerTest, BasicServerAPIFunctionality) { grpc_core::ExecCtx exec_ctx; ServerFixture server(10); ServerNode* channelz_server = grpc_server_get_channelz_node(server.server()); @@ -388,18 +510,18 @@ TEST_P(ChannelzServerTest, BasicServerAPIFunctionality) { ValidateServer(channelz_server, {3, 3, 3}); } -TEST(ChannelzGetServersTest, BasicGetServersTest) { +TEST_F(ChannelzRegistryBasedTest, BasicGetServersTest) { grpc_core::ExecCtx exec_ctx; ServerFixture server; ValidateGetServers(1); } -TEST(ChannelzGetServersTest, NoServersTest) { +TEST_F(ChannelzRegistryBasedTest, NoServersTest) { grpc_core::ExecCtx exec_ctx; ValidateGetServers(0); } -TEST(ChannelzGetServersTest, ManyServersTest) { +TEST_F(ChannelzRegistryBasedTest, ManyServersTest) { grpc_core::ExecCtx exec_ctx; ServerFixture servers[10]; (void)servers; // suppress unused variable error @@ -409,9 +531,6 @@ TEST(ChannelzGetServersTest, ManyServersTest) { INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest, ::testing::Values(0, 8, 64, 1024, 1024 * 1024)); -INSTANTIATE_TEST_CASE_P(ChannelzServerTestSweep, ChannelzServerTest, - ::testing::Values(0, 8, 64, 1024, 1024 * 1024)); - } // namespace testing } // namespace channelz } // namespace grpc_core diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc index 1c8d0775ab..eb5a911748 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc @@ -82,6 +82,10 @@ static grpc_ares_request* my_dns_lookup_ares_locked( return nullptr; } +static void my_cancel_ares_request_locked(grpc_ares_request* request) { + GPR_ASSERT(request == nullptr); +} + static grpc_core::OrphanablePtr<grpc_core::Resolver> create_resolver( const char* name) { grpc_core::ResolverFactory* factory = @@ -148,6 +152,7 @@ int main(int argc, char** argv) { g_combiner = grpc_combiner_create(); grpc_set_resolver_impl(&test_resolver); grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; + grpc_cancel_ares_request_locked = my_cancel_ares_request_locked; grpc_channel_args* result = (grpc_channel_args*)1; { diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index 37999a98d1..398e8a2d9a 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -18,7 +18,7 @@ licenses(["notice"]) # Apache v2 grpc_package(name = "test/core/end2end") -load(":generate_tests.bzl", "grpc_end2end_tests") +load(":generate_tests.bzl", "grpc_end2end_tests", "grpc_end2end_nosec_tests") grpc_cc_library( name = "cq_verifier", @@ -46,7 +46,6 @@ grpc_cc_library( visibility = ["//test:__subpackages__"], ) - grpc_cc_library( name = "http_proxy", srcs = ["fixtures/http_proxy_fixture.cc"], @@ -128,7 +127,7 @@ grpc_cc_test( srcs = ["inproc_callback_test.cc"], language = "C++", deps = [ - ':end2end_tests', + ":end2end_tests", "//:gpr", "//:grpc", "//test/core/util:gpr_test_util", @@ -177,6 +176,8 @@ grpc_cc_test( grpc_end2end_tests() +grpc_end2end_nosec_tests() + grpc_cc_test( name = "h2_ssl_session_reuse_test", srcs = ["h2_ssl_session_reuse_test.cc"], @@ -185,11 +186,11 @@ grpc_cc_test( ], language = "C++", deps = [ - ':end2end_tests', - '//:gpr', - '//:grpc', - '//:tsi', - '//test/core/util:gpr_test_util', - '//test/core/util:grpc_test_util', + ":end2end_tests", + "//:gpr", + "//:grpc", + "//:tsi", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", ], ) diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc index 9544adb912..e97a544e12 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.cc +++ b/test/core/end2end/fuzzers/api_fuzzer.cc @@ -390,6 +390,10 @@ grpc_ares_request* my_dns_lookup_ares_locked( return nullptr; } +static void my_cancel_ares_request_locked(grpc_ares_request* request) { + GPR_ASSERT(request == nullptr); +} + //////////////////////////////////////////////////////////////////////////////// // client connection @@ -705,6 +709,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } grpc_set_resolver_impl(&fuzzer_resolver); grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; + grpc_cancel_ares_request_locked = my_cancel_ares_request_locked; GPR_ASSERT(g_channel == nullptr); GPR_ASSERT(g_server == nullptr); diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index 569e744a6b..a79fe5ad95 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -34,6 +34,7 @@ "\x1Egrpc.max_request_message_bytes" "\x1Fgrpc.max_response_message_bytes" "$/grpc.lb.v1.LoadBalancer/BalanceLoad" +"\x1C/grpc.health.v1.Health/Watch" "\x07deflate" "\x04gzip" "\x0Bstream/gzip" diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 39b9ba4a19..601d3bac38 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -41,7 +41,7 @@ local_fixture_options = default_secure_fixture_options._replace( fd_unsecure_fixture_options = default_unsecure_fixture_options._replace( dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'], exclude_iomgrs=['uv'], client_channel=False) -inproc_fixture_options = default_unsecure_fixture_options._replace( +inproc_fixture_options = default_secure_fixture_options._replace( dns_resolver=False, fullstack=False, name_resolution=False, supports_compression=False, is_inproc=True, is_http2=False, supports_write_buffering=False, client_channel=False) diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 6d9ffcfb91..81956db841 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -92,6 +92,7 @@ END2END_FIXTURES = { _platforms = ["linux", "mac", "posix"], ), "inproc": _fixture_options( + secure = True, fullstack = False, dns_resolver = False, name_resolution = False, @@ -102,6 +103,55 @@ END2END_FIXTURES = { ), } +# maps fixture name to whether it requires the security library +END2END_NOSEC_FIXTURES = { + "h2_compress": _fixture_options(secure = False), + "h2_census": _fixture_options(secure = False), + # TODO(juanlishen): This is disabled for now, but should be considered to re-enable once we have + # decided how the load reporting service should be enabled. + #'h2_load_reporting': _fixture_options(), + "h2_fakesec": _fixture_options(), + "h2_fd": _fixture_options( + dns_resolver = False, + fullstack = False, + client_channel = False, + secure = False, + _platforms = ["linux", "mac", "posix"], + ), + "h2_full": _fixture_options(secure = False), + "h2_full+pipe": _fixture_options(secure = False, _platforms = ["linux"]), + "h2_full+trace": _fixture_options(secure = False, tracing = True), + "h2_full+workarounds": _fixture_options(secure = False), + "h2_http_proxy": _fixture_options(secure = False, supports_proxy_auth = True), + "h2_proxy": _fixture_options(secure = False, includes_proxy = True), + "h2_sockpair_1byte": _fixture_options( + fullstack = False, + dns_resolver = False, + client_channel = False, + secure = False, + ), + "h2_sockpair": _fixture_options( + fullstack = False, + dns_resolver = False, + client_channel = False, + secure = False, + ), + "h2_sockpair+trace": _fixture_options( + fullstack = False, + dns_resolver = False, + tracing = True, + secure = False, + client_channel = False, + ), + "h2_ssl": _fixture_options(secure = False), + "h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = False), + "h2_uds": _fixture_options( + dns_resolver = False, + _platforms = ["linux", "mac", "posix"], + secure = False, + ), +} + def _test_options( needs_fullstack = False, needs_dns = False, @@ -357,3 +407,57 @@ def grpc_end2end_tests(): poller, ], ) + +def grpc_end2end_nosec_tests(): + grpc_cc_library( + name = "end2end_nosec_tests", + srcs = ["end2end_nosec_tests.cc", "end2end_test_utils.cc"] + [ + "tests/%s.cc" % t + for t in sorted(END2END_TESTS.keys()) + if not END2END_TESTS[t].secure + ], + hdrs = [ + "tests/cancel_test_helpers.h", + "end2end_tests.h", + ], + language = "C++", + deps = [ + ":cq_verifier", + ":ssl_test_data", + ":http_proxy", + ":proxy", + ], + ) + + for f, fopt in END2END_NOSEC_FIXTURES.items(): + if fopt.secure: + continue + grpc_cc_binary( + name = "%s_nosec_test" % f, + srcs = ["fixtures/%s.cc" % f], + language = "C++", + deps = [ + ":end2end_nosec_tests", + "//test/core/util:grpc_test_util_unsecure", + "//:grpc_unsecure", + "//test/core/util:gpr_test_util", + "//:gpr", + ], + ) + for t, topt in END2END_TESTS.items(): + #print(_compatible(fopt, topt), f, t, fopt, topt) + if not _compatible(fopt, topt): + continue + if topt.secure: + continue + for poller in POLLERS: + native.sh_test( + name = "%s_nosec_test@%s@poller=%s" % (f, t, poller), + data = [":%s_nosec_test" % f], + srcs = ["end2end_test.sh"], + args = [ + "$(location %s_nosec_test)" % f, + t, + poller, + ], + ) diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc index 8904c3d325..3f1c5596ad 100644 --- a/test/core/end2end/goaway_server_test.cc +++ b/test/core/end2end/goaway_server_test.cc @@ -50,6 +50,8 @@ static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)( grpc_lb_addresses** addresses, bool check_grpclb, char** service_config_json, grpc_combiner* combiner); +static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request); + static void set_resolve_port(int port) { gpr_mu_lock(&g_mu); g_resolve_port = port; @@ -130,6 +132,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked( return nullptr; } +static void my_cancel_ares_request_locked(grpc_ares_request* request) { + if (request != nullptr) { + iomgr_cancel_ares_request_locked(request); + } +} + int main(int argc, char** argv) { grpc_completion_queue* cq; cq_verifier* cqv; @@ -143,7 +151,9 @@ int main(int argc, char** argv) { default_resolver = grpc_resolve_address_impl; grpc_set_resolver_impl(&test_resolver); iomgr_dns_lookup_ares_locked = grpc_dns_lookup_ares_locked; + iomgr_cancel_ares_request_locked = grpc_cancel_ares_request_locked; grpc_dns_lookup_ares_locked = my_dns_lookup_ares_locked; + grpc_cancel_ares_request_locked = my_cancel_ares_request_locked; int was_cancelled1; int was_cancelled2; diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc index a812994435..7c61b7910b 100644 --- a/test/core/end2end/tests/channelz.cc +++ b/test/core/end2end/tests/channelz.cc @@ -288,6 +288,8 @@ static void test_channelz_with_channel_trace(grpc_end2end_test_config config) { grpc_server_get_channelz_node(f.server); GPR_ASSERT(channelz_server != nullptr); + run_one_request(config, f, true); + char* json = channelz_channel->RenderJsonString(); GPR_ASSERT(json != nullptr); gpr_log(GPR_INFO, "%s", json); diff --git a/test/core/end2end/tests/retry_streaming.cc b/test/core/end2end/tests/retry_streaming.cc index d06d124ca4..94a27faf7b 100644 --- a/test/core/end2end/tests/retry_streaming.cc +++ b/test/core/end2end/tests/retry_streaming.cc @@ -28,6 +28,9 @@ #include <grpc/support/string_util.h> #include <grpc/support/time.h> +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" + #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/gpr/string.h" #include "src/core/lib/gpr/useful.h" @@ -133,25 +136,30 @@ static void test_retry_streaming(grpc_end2end_test_config config) { int was_cancelled = 2; char* peer; - grpc_arg arg; - arg.type = GRPC_ARG_STRING; - arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); - arg.value.string = const_cast<char*>( - "{\n" - " \"methodConfig\": [ {\n" - " \"name\": [\n" - " { \"service\": \"service\", \"method\": \"method\" }\n" - " ],\n" - " \"retryPolicy\": {\n" - " \"maxAttempts\": 3,\n" - " \"initialBackoff\": \"1s\",\n" - " \"maxBackoff\": \"120s\",\n" - " \"backoffMultiplier\": 1.6,\n" - " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" - " }\n" - " } ]\n" - "}"); - grpc_channel_args client_args = {1, &arg}; + grpc_arg args[] = { + grpc_channel_arg_integer_create( + const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE), + 1024 * 8), + grpc_channel_arg_integer_create( + const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true), + grpc_channel_arg_string_create( + const_cast<char*>(GRPC_ARG_SERVICE_CONFIG), + const_cast<char*>( + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"retryPolicy\": {\n" + " \"maxAttempts\": 3,\n" + " \"initialBackoff\": \"1s\",\n" + " \"maxBackoff\": \"120s\",\n" + " \"backoffMultiplier\": 1.6,\n" + " \"retryableStatusCodes\": [ \"ABORTED\" ]\n" + " }\n" + " } ]\n" + "}"))}; + grpc_channel_args client_args = {GPR_ARRAY_SIZE(args), args}; grpc_end2end_test_fixture f = begin_test(config, "retry_streaming", &client_args, nullptr); @@ -161,6 +169,9 @@ static void test_retry_streaming(grpc_end2end_test_config config) { c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, grpc_slice_from_static_string("/service/method"), nullptr, deadline, nullptr); + grpc_core::channelz::ChannelNode* channelz_channel = + grpc_channel_get_channelz_node(f.client); + GPR_ASSERT(c); peer = grpc_call_get_peer(c); @@ -384,6 +395,20 @@ static void test_retry_streaming(grpc_end2end_test_config config) { GPR_ASSERT(0 == call_details.flags); GPR_ASSERT(was_cancelled == 1); + GPR_ASSERT(channelz_channel != nullptr); + char* json = channelz_channel->RenderJsonString(); + GPR_ASSERT(json != nullptr); + gpr_log(GPR_INFO, "%s", json); + GPR_ASSERT(nullptr != strstr(json, "\"trace\"")); + GPR_ASSERT(nullptr != strstr(json, "\"description\":\"Channel created\"")); + GPR_ASSERT(nullptr != strstr(json, "\"severity\":\"CT_INFO\"")); + GPR_ASSERT(nullptr != strstr(json, "Resolution event")); + GPR_ASSERT(nullptr != strstr(json, "Created new LB policy")); + GPR_ASSERT(nullptr != strstr(json, "Service config changed")); + GPR_ASSERT(nullptr != strstr(json, "Address list became non-empty")); + GPR_ASSERT(nullptr != strstr(json, "Channel state change to CONNECTING")); + gpr_free(json); + grpc_slice_unref(details); grpc_metadata_array_destroy(&initial_metadata_recv); grpc_metadata_array_destroy(&trailing_metadata_recv); @@ -414,6 +439,7 @@ static void test_retry_streaming(grpc_end2end_test_config config) { void retry_streaming(grpc_end2end_test_config config) { GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL); + test_retry_streaming(config); } diff --git a/test/core/iomgr/tcp_client_uv_test.cc b/test/core/iomgr/tcp_client_uv_test.cc index ffcc7937c7..27f894e3f3 100644 --- a/test/core/iomgr/tcp_client_uv_test.cc +++ b/test/core/iomgr/tcp_client_uv_test.cc @@ -129,6 +129,7 @@ void test_succeeds(void) { uv_close((uv_handle_t*)svr_handle, close_cb); gpr_mu_unlock(g_mu); + grpc_core::ExecCtx::Get()->Flush(); } void test_fails(void) { @@ -178,6 +179,7 @@ void test_fails(void) { } gpr_mu_unlock(g_mu); + grpc_core::ExecCtx::Get()->Flush(); } static void destroy_pollset(void* p, grpc_error* error) { @@ -186,21 +188,22 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_core::ExecCtx exec_ctx; grpc_test_init(argc, argv); grpc_init(); - g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); - grpc_pollset_init(g_pollset, &g_mu); - - test_succeeds(); - gpr_log(GPR_ERROR, "End of first test"); - test_fails(); - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(g_pollset, &destroyed); - + { + grpc_core::ExecCtx exec_ctx; + g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); + grpc_pollset_init(g_pollset, &g_mu); + + test_succeeds(); + gpr_log(GPR_ERROR, "End of first test"); + test_fails(); + GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(g_pollset, &destroyed); + gpr_free(g_pollset); + } grpc_shutdown(); - gpr_free(g_pollset); return 0; } diff --git a/test/core/iomgr/tcp_server_uv_test.cc b/test/core/iomgr/tcp_server_uv_test.cc index 35d62b51b7..e99fa79bfd 100644 --- a/test/core/iomgr/tcp_server_uv_test.cc +++ b/test/core/iomgr/tcp_server_uv_test.cc @@ -119,6 +119,7 @@ static void test_no_op(void) { grpc_tcp_server* s; GPR_ASSERT(GRPC_ERROR_NONE == grpc_tcp_server_create(NULL, NULL, &s)); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void test_no_op_with_start(void) { @@ -128,6 +129,7 @@ static void test_no_op_with_start(void) { LOG_TEST("test_no_op_with_start"); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void test_no_op_with_port(void) { @@ -147,6 +149,7 @@ static void test_no_op_with_port(void) { port > 0); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void test_no_op_with_port_and_start(void) { @@ -168,6 +171,7 @@ static void test_no_op_with_port_and_start(void) { grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_unref(s); + grpc_core::ExecCtx::Get()->Flush(); } static void connect_cb(uv_connect_t* req, int status) { @@ -273,7 +277,7 @@ static void test_connect(unsigned n) { GPR_ASSERT(weak_ref.server != NULL); grpc_tcp_server_unref(s); - + grpc_core::ExecCtx::Get()->Flush(); /* Weak ref lost. */ GPR_ASSERT(weak_ref.server == NULL); } @@ -284,25 +288,27 @@ static void destroy_pollset(void* p, grpc_error* error) { int main(int argc, char** argv) { grpc_closure destroyed; - grpc_core::ExecCtx exec_ctx; grpc_test_init(argc, argv); grpc_init(); - g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); - grpc_pollset_init(g_pollset, &g_mu); - - test_no_op(); - test_no_op_with_start(); - test_no_op_with_port(); - test_no_op_with_port_and_start(); - test_connect(1); - test_connect(10); - - GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, - grpc_schedule_on_exec_ctx); - grpc_pollset_shutdown(g_pollset, &destroyed); - + { + grpc_core::ExecCtx exec_ctx; + g_pollset = static_cast<grpc_pollset*>(gpr_malloc(grpc_pollset_size())); + grpc_pollset_init(g_pollset, &g_mu); + + test_no_op(); + test_no_op_with_start(); + test_no_op_with_port(); + test_no_op_with_port_and_start(); + test_connect(1); + test_connect(10); + + GRPC_CLOSURE_INIT(&destroyed, destroy_pollset, g_pollset, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(g_pollset, &destroyed); + + gpr_free(g_pollset); + } grpc_shutdown(); - gpr_free(g_pollset); return 0; } diff --git a/test/core/security/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc index 103a493526..9378236338 100644 --- a/test/core/security/alts_security_connector_test.cc +++ b/test/core/security/alts_security_connector_test.cc @@ -24,7 +24,7 @@ #include <grpc/support/alloc.h> #include <grpc/support/log.h> -#include "src/core/lib/security/security_connector/alts_security_connector.h" +#include "src/core/lib/security/security_connector/alts/alts_security_connector.h" #include "src/core/lib/transport/transport.h" #include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h" #include "src/core/tsi/transport_security.h" diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc index 9dd37b975b..fef0ea71f7 100644 --- a/test/core/security/security_connector_test.cc +++ b/test/core/security/security_connector_test.cc @@ -29,6 +29,7 @@ #include "src/core/lib/gpr/tmpfile.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/security_connector/security_connector.h" +#include "src/core/lib/security/security_connector/ssl_utils.h" #include "src/core/lib/slice/slice_string_helpers.h" #include "src/core/tsi/ssl_transport_security.h" #include "src/core/tsi/transport_security.h" diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc index 1e04691ce2..d2bbb7c1c2 100644 --- a/test/core/security/ssl_server_fuzzer.cc +++ b/test/core/security/ssl_server_fuzzer.cc @@ -93,9 +93,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create(); grpc_server_security_connector_add_handshakers(sc, nullptr, handshake_mgr); grpc_handshake_manager_do_handshake( - handshake_mgr, nullptr /* interested_parties */, mock_endpoint, - nullptr /* channel_args */, deadline, nullptr /* acceptor */, - on_handshake_done, &state); + handshake_mgr, mock_endpoint, nullptr /* channel_args */, deadline, + nullptr /* acceptor */, on_handshake_done, &state); grpc_core::ExecCtx::Get()->Flush(); // If the given string happens to be part of the correct client hello, the diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc index 5e6671965d..587d8f5dda 100644 --- a/test/core/tsi/fake_transport_security_test.cc +++ b/test/core/tsi/fake_transport_security_test.cc @@ -22,6 +22,7 @@ #include "src/core/lib/security/security_connector/security_connector.h" #include "src/core/tsi/fake_transport_security.h" +#include "src/core/tsi/transport_security.h" #include "test/core/tsi/transport_security_test_lib.h" #include "test/core/util/test_config.h" diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt index 2268adc169..63898ea3b1 100644 --- a/test/core/util/ubsan_suppressions.txt +++ b/test/core/util/ubsan_suppressions.txt @@ -15,3 +15,17 @@ enum:message_compress_test enum:transport_security_test enum:algorithm_test alignment:transport_security_test +# TODO(jtattermusch): address issues and remove the supressions +nonnull-attribute:gsec_aes_gcm_aead_crypter_decrypt_iovec +nonnull-attribute:gsec_test_random_encrypt_decrypt +nonnull-attribute:gsec_test_multiple_random_encrypt_decrypt +nonnull-attribute:gsec_test_copy +nonnull-attribute:gsec_test_encrypt_decrypt_test_vector +alignment:absl::little_endian::Store64 +alignment:absl::little_endian::Load64 +float-divide-by-zero:grpc::testing::postprocess_scenario_result +enum:grpc_op_string +nonnull-attribute:grpc_lb_addresses_copy +signed-integer-overflow:chrono +enum:grpc_http2_error_to_grpc_status +enum:grpc_chttp2_cancel_stream
\ No newline at end of file diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc index a9d68ab058..77c25c1416 100644 --- a/test/cpp/end2end/client_lb_end2end_test.cc +++ b/test/cpp/end2end/client_lb_end2end_test.cc @@ -31,6 +31,7 @@ #include <grpcpp/channel.h> #include <grpcpp/client_context.h> #include <grpcpp/create_channel.h> +#include <grpcpp/health_check_service_interface.h> #include <grpcpp/server.h> #include <grpcpp/server_builder.h> @@ -287,6 +288,10 @@ class ClientLbEnd2endTest : public ::testing::Test { server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); if (join) thread_->join(); } + + void SetServingStatus(const grpc::string& service, bool serving) { + server_->GetHealthCheckService()->SetServingStatus(service, serving); + } }; void ResetCounters() { @@ -318,6 +323,17 @@ class ClientLbEnd2endTest : public ::testing::Test { return true; } + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + bool SeenAllServers() { for (const auto& server : servers_) { if (server->service_.request_count() == 0) return false; @@ -357,11 +373,7 @@ TEST_F(ClientLbEnd2endTest, PickFirst) { StartServers(kNumServers); auto channel = BuildChannel(""); // test that pick first is the default. auto stub = BuildStub(channel); - std::vector<int> ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } - SetNextResolution(ports); + SetNextResolution(GetServersPorts()); for (size_t i = 0; i < servers_.size(); ++i) { CheckRpcSendOk(stub, DEBUG_LOCATION); } @@ -584,10 +596,7 @@ TEST_P(ClientLbEnd2endWithParamTest, PickFirstManyUpdates) { StartServers(kNumServers); auto channel = BuildChannel("pick_first"); auto stub = BuildStub(channel); - std::vector<int> ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } + std::vector<int> ports = GetServersPorts(); for (size_t i = 0; i < 1000; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); @@ -717,11 +726,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobin) { StartServers(kNumServers); auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); - std::vector<int> ports; - for (const auto& server : servers_) { - ports.emplace_back(server->port_); - } - SetNextResolution(ports); + SetNextResolution(GetServersPorts()); // Wait until all backends are ready. do { CheckRpcSendOk(stub, DEBUG_LOCATION); @@ -883,10 +888,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinManyUpdates) { StartServers(kNumServers); auto channel = BuildChannel("round_robin"); auto stub = BuildStub(channel); - std::vector<int> ports; - for (size_t i = 0; i < servers_.size(); ++i) { - ports.emplace_back(servers_[i]->port_); - } + std::vector<int> ports = GetServersPorts(); for (size_t i = 0; i < 1000; ++i) { std::shuffle(ports.begin(), ports.end(), std::mt19937(std::random_device()())); @@ -996,6 +998,125 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) { WaitForServer(stub, 0, DEBUG_LOCATION); } +// If health checking is required by client but health checking service +// is not running on the server, the channel should be treated as healthy. +TEST_F(ClientLbEnd2endTest, + RoundRobinServersHealthCheckingUnimplementedTreatedAsHealthy) { + StartServers(1); // Single server + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel = BuildChannel("round_robin", args); + auto stub = BuildStub(channel); + SetNextResolution({servers_[0]->port_}); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthChecking) { + EnableDefaultHealthCheckService(true); + // Start servers. + const int kNumServers = 3; + StartServers(kNumServers); + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel = BuildChannel("round_robin", args); + auto stub = BuildStub(channel); + SetNextResolution(GetServersPorts()); + // Channel should not become READY, because health checks should be failing. + gpr_log(GPR_INFO, + "*** initial state: unknown health check service name for " + "all servers"); + EXPECT_FALSE(WaitForChannelReady(channel.get(), 1)); + // Now set one of the servers to be healthy. + // The channel should become healthy and all requests should go to + // the healthy server. + gpr_log(GPR_INFO, "*** server 0 healthy"); + servers_[0]->SetServingStatus("health_check_service_name", true); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + for (int i = 0; i < 10; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + EXPECT_EQ(10, servers_[0]->service_.request_count()); + EXPECT_EQ(0, servers_[1]->service_.request_count()); + EXPECT_EQ(0, servers_[2]->service_.request_count()); + // Now set a second server to be healthy. + gpr_log(GPR_INFO, "*** server 2 healthy"); + servers_[2]->SetServingStatus("health_check_service_name", true); + WaitForServer(stub, 2, DEBUG_LOCATION); + for (int i = 0; i < 10; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + EXPECT_EQ(5, servers_[0]->service_.request_count()); + EXPECT_EQ(0, servers_[1]->service_.request_count()); + EXPECT_EQ(5, servers_[2]->service_.request_count()); + // Now set the remaining server to be healthy. + gpr_log(GPR_INFO, "*** server 1 healthy"); + servers_[1]->SetServingStatus("health_check_service_name", true); + WaitForServer(stub, 1, DEBUG_LOCATION); + for (int i = 0; i < 9; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + EXPECT_EQ(3, servers_[0]->service_.request_count()); + EXPECT_EQ(3, servers_[1]->service_.request_count()); + EXPECT_EQ(3, servers_[2]->service_.request_count()); + // Now set one server to be unhealthy again. Then wait until the + // unhealthiness has hit the client. We know that the client will see + // this when we send kNumServers requests and one of the remaining servers + // sees two of the requests. + gpr_log(GPR_INFO, "*** server 0 unhealthy"); + servers_[0]->SetServingStatus("health_check_service_name", false); + do { + ResetCounters(); + for (int i = 0; i < kNumServers; ++i) { + CheckRpcSendOk(stub, DEBUG_LOCATION); + } + } while (servers_[1]->service_.request_count() != 2 && + servers_[2]->service_.request_count() != 2); + // Now set the remaining two servers to be unhealthy. Make sure the + // channel leaves READY state and that RPCs fail. + gpr_log(GPR_INFO, "*** all servers unhealthy"); + servers_[1]->SetServingStatus("health_check_service_name", false); + servers_[2]->SetServingStatus("health_check_service_name", false); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + CheckRpcSendFailure(stub); + // Clean up. + EnableDefaultHealthCheckService(false); +} + +TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) { + EnableDefaultHealthCheckService(true); + // Start server. + const int kNumServers = 1; + StartServers(kNumServers); + // Create a channel with health-checking enabled. + ChannelArguments args; + args.SetServiceConfigJSON( + "{\"healthCheckConfig\": " + "{\"serviceName\": \"health_check_service_name\"}}"); + auto channel1 = BuildChannel("round_robin", args); + auto stub1 = BuildStub(channel1); + std::vector<int> ports = GetServersPorts(); + SetNextResolution(ports); + // Create a channel with health checking enabled but inhibited. + args.SetInt(GRPC_ARG_INHIBIT_HEALTH_CHECKING, 1); + auto channel2 = BuildChannel("round_robin", args); + auto stub2 = BuildStub(channel2); + SetNextResolution(ports); + // First channel should not become READY, because health checks should be + // failing. + EXPECT_FALSE(WaitForChannelReady(channel1.get(), 1)); + CheckRpcSendFailure(stub1); + // Second channel should be READY. + EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1)); + CheckRpcSendOk(stub2, DEBUG_LOCATION); + // Clean up. + EnableDefaultHealthCheckService(false); +} + } // namespace } // namespace testing } // namespace grpc diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc index 1c48b9d151..fca65dfc13 100644 --- a/test/cpp/end2end/health_service_end2end_test.cc +++ b/test/cpp/end2end/health_service_end2end_test.cc @@ -64,6 +64,29 @@ class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service { return Status::OK; } + Status Watch(ServerContext* context, const HealthCheckRequest* request, + ::grpc::ServerWriter<HealthCheckResponse>* writer) override { + auto last_state = HealthCheckResponse::UNKNOWN; + while (!context->IsCancelled()) { + { + std::lock_guard<std::mutex> lock(mu_); + HealthCheckResponse response; + auto iter = status_map_.find(request->service()); + if (iter == status_map_.end()) { + response.set_status(response.SERVICE_UNKNOWN); + } else { + response.set_status(iter->second); + } + if (response.status() != last_state) { + writer->Write(response, ::grpc::WriteOptions()); + } + } + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_millis(1000, GPR_TIMESPAN))); + } + return Status::OK; + } + void SetStatus(const grpc::string& service_name, HealthCheckResponse::ServingStatus status) { std::lock_guard<std::mutex> lock(mu_); @@ -106,14 +129,6 @@ class CustomHealthCheckService : public HealthCheckServiceInterface { HealthCheckServiceImpl* impl_; // not owned }; -void LoopCompletionQueue(ServerCompletionQueue* cq) { - void* tag; - bool ok; - while (cq->Next(&tag, &ok)) { - abort(); // Nothing should come out of the cq. - } -} - class HealthServiceEnd2endTest : public ::testing::Test { protected: HealthServiceEnd2endTest() {} @@ -218,6 +233,33 @@ class HealthServiceEnd2endTest : public ::testing::Test { Status(StatusCode::NOT_FOUND, "")); } + void VerifyHealthCheckServiceStreaming() { + const grpc::string kServiceName("service_name"); + HealthCheckServiceInterface* service = server_->GetHealthCheckService(); + // Start Watch for service. + ClientContext context; + HealthCheckRequest request; + request.set_service(kServiceName); + std::unique_ptr<::grpc::ClientReaderInterface<HealthCheckResponse>> reader = + hc_stub_->Watch(&context, request); + // Initial response will be SERVICE_UNKNOWN. + HealthCheckResponse response; + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVICE_UNKNOWN, response.status()); + response.Clear(); + // Now set service to NOT_SERVING and make sure we get an update. + service->SetServingStatus(kServiceName, false); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.NOT_SERVING, response.status()); + response.Clear(); + // Now set service to SERVING and make sure we get another update. + service->SetServingStatus(kServiceName, true); + EXPECT_TRUE(reader->Read(&response)); + EXPECT_EQ(response.SERVING, response.status()); + // Finish call. + context.TryCancel(); + } + TestServiceImpl echo_test_service_; HealthCheckServiceImpl health_check_service_impl_; std::unique_ptr<Health::Stub> hc_stub_; @@ -245,6 +287,7 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); SetUpServer(true, false, false, nullptr); VerifyHealthCheckService(); + VerifyHealthCheckServiceStreaming(); // The default service has a size limit of the service name. const grpc::string kTooLongServiceName(201, 'x'); @@ -252,22 +295,6 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) { Status(StatusCode::INVALID_ARGUMENT, "")); } -// The server has no sync service. -TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceAsyncOnly) { - EnableDefaultHealthCheckService(true); - EXPECT_TRUE(DefaultHealthCheckServiceEnabled()); - SetUpServer(false, true, false, nullptr); - cq_thread_ = std::thread(LoopCompletionQueue, cq_.get()); - - HealthCheckServiceInterface* default_service = - server_->GetHealthCheckService(); - EXPECT_TRUE(default_service == nullptr); - - ResetStubs(); - - SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, "")); -} - // Provide an empty service to disable the default service. TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) { EnableDefaultHealthCheckService(true); @@ -296,6 +323,7 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) { ResetStubs(); VerifyHealthCheckService(); + VerifyHealthCheckServiceStreaming(); } } // namespace diff --git a/test/cpp/interop/BUILD b/test/cpp/interop/BUILD index 4f21551ff4..0f81305405 100644 --- a/test/cpp/interop/BUILD +++ b/test/cpp/interop/BUILD @@ -142,3 +142,24 @@ grpc_cc_binary( "//test/cpp/util:test_config", ], ) + +grpc_cc_test( + name = "interop_test", + srcs = ["interop_test.cc"], + data = [ + ":interop_client", + ":interop_server", + ], + external_deps = [ + "gflags", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:grpc++", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + "//test/cpp/util:test_config", + "//test/cpp/util:test_util", + ], +) diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 6c1859ff4f..097e92f583 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -41,7 +41,6 @@ grpc_cc_library( ], deps = [ "//:grpc++_unsecure", - "//:lb_server_load_reporting_filter", "//src/proto/grpc/testing:echo_proto", "//test/core/util:grpc_test_util_unsecure", "//test/cpp/util:test_config", diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index 389b888084..1f7831096c 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -34,7 +34,6 @@ #include "src/core/ext/filters/http/client/http_client_filter.h" #include "src/core/ext/filters/http/message_compress/message_compress_filter.h" #include "src/core/ext/filters/http/server/http_server_filter.h" -#include "src/core/ext/filters/load_reporting/server_load_reporting_filter.h" #include "src/core/ext/filters/message_size/message_size_filter.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/channel/connected_channel.h" diff --git a/test/cpp/naming/utils/dns_server.py b/test/cpp/naming/utils/dns_server.py index 1e8e2e3287..bf11d14c30 100755 --- a/test/cpp/naming/utils/dns_server.py +++ b/test/cpp/naming/utils/dns_server.py @@ -93,6 +93,10 @@ def start_local_dns_server(args): _push_record(record_full_name, dns.Record_SRV(p, w, port, target_full_name, ttl=r_ttl)) if r_type == 'TXT': _maybe_split_up_txt_data(record_full_name, r_data, r_ttl) + # Add an optional IPv4 record is specified + if args.add_a_record: + extra_host, extra_host_ipv4 = args.add_a_record.split(':') + _push_record(extra_host, dns.Record_A(extra_host_ipv4, ttl=0)) # Server health check record _push_record(_SERVER_HEALTH_CHECK_RECORD_NAME, dns.Record_A(_SERVER_HEALTH_CHECK_RECORD_DATA, ttl=0)) soa_record = dns.Record_SOA(mname = common_zone_name) @@ -122,7 +126,7 @@ def flush_stdout_loop(): num_timeouts_so_far = 0 sleep_time = 1 # Prevent zombies. Tests that use this server are short-lived. - max_timeouts = 60 * 2 + max_timeouts = 60 * 10 while num_timeouts_so_far < max_timeouts: sys.stdout.flush() time.sleep(sleep_time) @@ -136,7 +140,14 @@ def main(): help='Port for DNS server to listen on for TCP and UDP.') argp.add_argument('-r', '--records_config_path', default=None, type=str, help=('Directory of resolver_test_record_groups.yaml file. ' - 'Defauls to path needed when the test is invoked as part of run_tests.py.')) + 'Defaults to path needed when the test is invoked as part ' + 'of run_tests.py.')) + argp.add_argument('--add_a_record', default=None, type=str, + help=('Add an A record via the command line. Useful for when we ' + 'need to serve a one-off A record that is under a ' + 'different domain then the rest the records configured in ' + '--records_config_path (which all need to be under the ' + 'same domain). Format: <name>:<ipv4 address>')) args = argp.parse_args() signal.signal(signal.SIGTERM, _quit_on_signal) signal.signal(signal.SIGINT, _quit_on_signal) diff --git a/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py b/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py new file mode 100755 index 0000000000..97171e21da --- /dev/null +++ b/test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python2.7 +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import argparse +import subprocess +import os +import tempfile +import sys +import time +import signal +import yaml + +argp = argparse.ArgumentParser(description='Runs a DNS server for LB interop tests') +argp.add_argument('-l', '--grpclb_ips', default=None, type=str, + help='Comma-separated list of IP addresses of balancers') +argp.add_argument('-f', '--fallback_ips', default=None, type=str, + help='Comma-separated list of IP addresses of fallback servers') +argp.add_argument('-c', '--cause_no_error_no_data_for_balancer_a_record', + default=False, action='store_const', const=True, + help=('Used for testing the case in which the grpclb ' + 'balancer A record lookup results in a DNS NOERROR response ' + 'but with no ANSWER section i.e. no addresses')) +args = argp.parse_args() + +balancer_records = [] +grpclb_ips = args.grpclb_ips.split(',') +if grpclb_ips[0]: + for ip in grpclb_ips: + balancer_records.append({ + 'TTL': '2100', + 'data': ip, + 'type': 'A', + }) +fallback_records = [] +fallback_ips = args.fallback_ips.split(',') +if fallback_ips[0]: + for ip in fallback_ips: + fallback_records.append({ + 'TTL': '2100', + 'data': ip, + 'type': 'A', + }) +records_config_yaml = { + 'resolver_tests_common_zone_name': + 'test.google.fr.', + 'resolver_component_tests': [{ + 'records': { + '_grpclb._tcp.server': [ + { + 'TTL': '2100', + 'data': '0 0 12000 balancer', + 'type': 'SRV' + }, + ], + 'balancer': + balancer_records, + 'server': + fallback_records, + } + }] +} +if args.cause_no_error_no_data_for_balancer_a_record: + balancer_records = records_config_yaml[ + 'resolver_component_tests'][0]['records']['balancer'] + assert not balancer_records + # Insert a TXT record at the balancer.test.google.fr. domain. + # This TXT record won't actually be resolved or used by gRPC clients; + # inserting this record is just a way get the balancer.test.google.fr. + # A record queries to return NOERROR DNS responses that also have no + # ANSWER section, in order to simulate this failure case. + balancer_records.append({ + 'TTL': '2100', + 'data': 'arbitrary string that wont actually be resolved', + 'type': 'TXT', + }) +# Generate the actual DNS server records config file +records_config_path = tempfile.mktemp() +with open(records_config_path, 'w') as records_config_generated: + records_config_generated.write(yaml.dump(records_config_yaml)) + +with open(records_config_path, 'r') as records_config_generated: + sys.stderr.write('===== DNS server records config: =====\n') + sys.stderr.write(records_config_generated.read()) + sys.stderr.write('======================================\n') + +# Run the DNS server +# Note that we need to add the extra +# A record for metadata.google.internal in order for compute engine +# OAuth creds and ALTS creds to work. +# TODO(apolcyn): should metadata.google.internal always resolve +# to 169.254.169.254? +subprocess.check_output([ + '/var/local/git/grpc/test/cpp/naming/utils/dns_server.py', '--port=53', + '--records_config_path', records_config_path, + '--add_a_record=metadata.google.internal:169.254.169.254', +]) diff --git a/test/cpp/naming/utils/tcp_connect.py b/test/cpp/naming/utils/tcp_connect.py index 5773c7cae8..f3ad5891fd 100755 --- a/test/cpp/naming/utils/tcp_connect.py +++ b/test/cpp/naming/utils/tcp_connect.py @@ -31,7 +31,8 @@ def main(): argp.add_argument('-t', '--timeout', default=1, type=int, help='Force process exit after this number of seconds.') args = argp.parse_args() - socket.create_connection([args.server_host, args.server_port]) + socket.create_connection([args.server_host, args.server_port], + timeout=args.timeout) if __name__ == '__main__': main() diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index ccc60cca27..80eaf4f727 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -57,6 +57,8 @@ DEFINE_string(proto_path, ".", "Path to look for the proto file."); DEFINE_string(protofiles, "", "Name of the proto file."); DEFINE_bool(binary_input, false, "Input in binary format"); DEFINE_bool(binary_output, false, "Output in binary format"); +DEFINE_bool(json_input, false, "Input in json format"); +DEFINE_bool(json_output, false, "Output in json format"); DEFINE_string(infile, "", "Input file (default is stdin)"); DEFINE_bool(batch, false, "Input contains multiple requests. Please do not use this to send " @@ -88,6 +90,8 @@ class GrpcTool { GrpcToolOutputCallback callback); bool ToText(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback); + bool ToJson(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); bool ToBinary(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback); @@ -189,8 +193,9 @@ void ReadResponse(CliCall* call, const grpc::string& method_name, fprintf(stderr, "got response.\n"); if (!FLAGS_binary_output) { gpr_mu_lock(parser_mu); - serialized_response_proto = parser->GetTextFormatFromMethod( - method_name, serialized_response_proto, false /* is_request */); + serialized_response_proto = parser->GetFormattedStringFromMethod( + method_name, serialized_response_proto, false /* is_request */, + FLAGS_json_output); if (parser->HasError() && print_mode) { fprintf(stderr, "Failed to parse response.\n"); } @@ -233,6 +238,7 @@ const Command ops[] = { {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3}, {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3}, {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3}, + {"tojson", BindWith5Args(&GrpcTool::ToJson), 2, 3}, }; void Usage(const grpc::string& msg) { @@ -244,6 +250,7 @@ void Usage(const grpc::string& msg) { " grpc_cli type ... ; Print type\n" " grpc_cli parse ... ; Parse message\n" " grpc_cli totext ... ; Convert binary message to text\n" + " grpc_cli tojson ... ; Convert binary message to json\n" " grpc_cli tobinary ... ; Convert text message to binary\n" " grpc_cli help ... ; Print this message, or per-command usage\n" "\n", @@ -465,7 +472,9 @@ bool GrpcTool::CallMethod(int argc, const char** argv, " --infile ; Input filename (defaults to stdin)\n" " --outfile ; Output filename (defaults to stdout)\n" " --binary_input ; Input in binary format\n" - " --binary_output ; Output in binary format\n" + + " --binary_output ; Output in binary format\n" + " --json_input ; Input in json format\n" + " --json_output ; Output in json format\n" + cred.GetCredentialUsage()); std::stringstream output_ss; @@ -548,7 +557,8 @@ bool GrpcTool::CallMethod(int argc, const char** argv, } else { gpr_mu_lock(&parser_mu); serialized_request_proto = parser->GetSerializedProtoFromMethod( - method_name, request_text, true /* is_request */); + method_name, request_text, true /* is_request */, + FLAGS_json_input); request_text.clear(); if (parser->HasError()) { if (print_mode) { @@ -632,7 +642,8 @@ bool GrpcTool::CallMethod(int argc, const char** argv, request_text.clear(); } else { serialized_request_proto = parser->GetSerializedProtoFromMethod( - method_name, request_text, true /* is_request */); + method_name, request_text, true /* is_request */, + FLAGS_json_input); request_text.clear(); if (parser->HasError()) { if (print_mode) { @@ -668,9 +679,10 @@ bool GrpcTool::CallMethod(int argc, const char** argv, break; } } else { - grpc::string response_text = parser->GetTextFormatFromMethod( + grpc::string response_text = parser->GetFormattedStringFromMethod( method_name, serialized_response_proto, - false /* is_request */); + false /* is_request */, FLAGS_json_output); + if (parser->HasError() && print_mode) { fprintf(stderr, "Failed to parse response.\n"); } else { @@ -727,7 +739,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv, serialized_request_proto = request_text; } else { serialized_request_proto = parser->GetSerializedProtoFromMethod( - method_name, request_text, true /* is_request */); + method_name, request_text, true /* is_request */, FLAGS_json_input); if (parser->HasError()) { fprintf(stderr, "Failed to parse request.\n"); return false; @@ -751,13 +763,15 @@ bool GrpcTool::CallMethod(int argc, const char** argv, receive_initial_metadata ? &server_initial_metadata : nullptr); receive_initial_metadata = false) { if (!FLAGS_binary_output) { - serialized_response_proto = parser->GetTextFormatFromMethod( - method_name, serialized_response_proto, false /* is_request */); + serialized_response_proto = parser->GetFormattedStringFromMethod( + method_name, serialized_response_proto, false /* is_request */, + FLAGS_json_output); if (parser->HasError()) { fprintf(stderr, "Failed to parse response.\n"); return false; } } + if (receive_initial_metadata) { PrintMetadata(server_initial_metadata, "Received initial metadata from server:"); @@ -797,7 +811,9 @@ bool GrpcTool::ParseMessage(int argc, const char** argv, " --infile ; Input filename (defaults to stdin)\n" " --outfile ; Output filename (defaults to stdout)\n" " --binary_input ; Input in binary format\n" - " --binary_output ; Output in binary format\n" + + " --binary_output ; Output in binary format\n" + " --json_input ; Input in json format\n" + " --json_output ; Output in json format\n" + cred.GetCredentialUsage()); std::stringstream output_ss; @@ -844,8 +860,8 @@ bool GrpcTool::ParseMessage(int argc, const char** argv, if (FLAGS_binary_input) { serialized_request_proto = message_text; } else { - serialized_request_proto = - parser->GetSerializedProtoFromMessageType(type_name, message_text); + serialized_request_proto = parser->GetSerializedProtoFromMessageType( + type_name, message_text, FLAGS_json_input); if (parser->HasError()) { fprintf(stderr, "Failed to serialize the message.\n"); return false; @@ -855,12 +871,14 @@ bool GrpcTool::ParseMessage(int argc, const char** argv, if (FLAGS_binary_output) { output_ss << serialized_request_proto; } else { - grpc::string output_text = parser->GetTextFormatFromMessageType( - type_name, serialized_request_proto); + grpc::string output_text; + output_text = parser->GetFormattedStringFromMessageType( + type_name, serialized_request_proto, FLAGS_json_output); if (parser->HasError()) { fprintf(stderr, "Failed to deserialize the message.\n"); return false; } + output_ss << output_text << std::endl; } @@ -885,6 +903,25 @@ bool GrpcTool::ToText(int argc, const char** argv, const CliCredentials& cred, return ParseMessage(argc, argv, cred, callback); } +bool GrpcTool::ToJson(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Convert binary message to json\n" + " grpc_cli tojson <protofiles> <type>\n" + " <protofiles> ; Comma separated list of proto files\n" + " <type> ; Protocol buffer type name\n" + " --proto_path ; The search path of proto files\n" + " --infile ; Input filename (defaults to stdin)\n" + " --outfile ; Output filename (defaults to stdout)\n"); + + FLAGS_protofiles = argv[0]; + FLAGS_remotedb = false; + FLAGS_binary_input = true; + FLAGS_binary_output = false; + FLAGS_json_output = true; + return ParseMessage(argc, argv, cred, callback); +} + bool GrpcTool::ToBinary(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback) { CommandUsage( diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index 3aae090e81..be9a624a2c 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -74,11 +74,20 @@ using grpc::testing::EchoResponse; " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ "{}\n" -#define ECHO_RESPONSE_MESSAGE \ - "message: \"echo\"\n" \ - "param {\n" \ - " host: \"localhost\"\n" \ - " peer: \"peer\"\n" \ +#define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT \ + "message: \"echo\"\n" \ + "param {\n" \ + " host: \"localhost\"\n" \ + " peer: \"peer\"\n" \ + "}\n\n" + +#define ECHO_RESPONSE_MESSAGE_JSON_FORMAT \ + "{\n" \ + " \"message\": \"echo\",\n" \ + " \"param\": {\n" \ + " \"host\": \"localhost\",\n" \ + " \"peer\": \"peer\"\n" \ + " }\n" \ "}\n\n" DECLARE_string(channel_creds_type); @@ -89,6 +98,8 @@ namespace testing { DECLARE_bool(binary_input); DECLARE_bool(binary_output); +DECLARE_bool(json_input); +DECLARE_bool(json_output); DECLARE_bool(l); DECLARE_bool(batch); DECLARE_string(metadata); @@ -426,6 +437,61 @@ TEST_F(GrpcToolTest, CallCommand) { // Expected output: "message: \"Hello\"" EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), "message: \"Hello\"")); + + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + + // Expected output: + // { + // "message": "Hello" + // } + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "{\n \"message\": \"Hello\"\n}")); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandJsonInput) { + // Test input "grpc_cli call localhost:<port> Echo "{ \"message\": \"Hello\"}" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "{ \"message\": \"Hello\"}"}; + + FLAGS_json_input = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); + + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + FLAGS_json_input = false; + + // Expected output: + // { + // "message": "Hello" + // } + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "{\n \"message\": \"Hello\"\n}")); + ShutdownServer(); } @@ -453,6 +519,101 @@ TEST_F(GrpcToolTest, CallCommandBatch) { EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), "message: \"Hello0\"\nmessage: " "\"Hello1\"\nmessage: \"Hello2\"\n")); + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + ss.clear(); + ss.seekg(0); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + FLAGS_batch = false; + + // Expected output: + // { + // "message": "Hello0" + // } + // { + // "message": "Hello1" + // } + // { + // "message": "Hello2" + // } + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "{\n \"message\": \"Hello0\"\n}\n" + "{\n \"message\": \"Hello1\"\n}\n" + "{\n \"message\": \"Hello2\"\n}\n")); + + std::cin.rdbuf(orig); + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandBatchJsonInput) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "{\"message\": \"Hello0\"}"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss( + "{\"message\": \"Hello1\"}\n\n{\"message\": \"Hello2\" }\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_json_input = true; + FLAGS_batch = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_batch = false; + + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: " + "\"Hello1\"\nmessage: \"Hello2\"\n")); + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + ss.clear(); + ss.seekg(0); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + FLAGS_batch = false; + FLAGS_json_input = false; + + // Expected output: + // { + // "message": "Hello0" + // } + // { + // "message": "Hello1" + // } + // { + // "message": "Hello2" + // } + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "{\n \"message\": \"Hello0\"\n}\n" + "{\n \"message\": \"Hello1\"\n}\n" + "{\n \"message\": \"Hello2\"\n}\n")); + std::cin.rdbuf(orig); ShutdownServer(); } @@ -479,6 +640,95 @@ TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) { // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), "message: \"Hello0\"\nmessage: \"Hello2\"\n")); + + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + ss.clear(); + ss.seekg(0); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + FLAGS_batch = false; + + // Expected output: + // { + // "message": "Hello0" + // } + // { + // "message": "Hello2" + // } + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "{\n \"message\": \"Hello0\"\n}\n" + "{\n \"message\": \"Hello2\"\n}\n")); + + std::cin.rdbuf(orig); + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "{ \"message\": \"Hello0\"}"}; + + // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss( + "{ \"message\": 1 }\n\n { \"message\": \"Hello2\" }\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + FLAGS_json_input = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_input = false; + FLAGS_batch = false; + + // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: \"Hello2\"\n")); + + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + ss.clear(); + ss.seekg(0); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + FLAGS_json_input = true; + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + FLAGS_json_input = false; + FLAGS_batch = false; + + // Expected output: + // { + // "message": "Hello0" + // } + // { + // "message": "Hello2" + // } + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "{\n \"message\": \"Hello0\"\n}\n" + "{\n \"message\": \"Hello2\"\n}\n")); + std::cin.rdbuf(orig); ShutdownServer(); } @@ -508,6 +758,34 @@ TEST_F(GrpcToolTest, CallCommandRequestStream) { ShutdownServer(); } +TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) { + // Test input: grpc_cli call localhost:<port> RequestStream "{ \"message\": + // \"Hello0\"}" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "RequestStream", "{ \"message\": \"Hello0\" }"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss( + "{ \"message\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_json_input = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_input = false; + + // Expected output: "message: \"Hello0Hello1Hello2\"" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0Hello1Hello2\"")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) { // Test input: grpc_cli call localhost:<port> RequestStream "message: // 'Hello0'" @@ -533,6 +811,34 @@ TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) { ShutdownServer(); } +TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequestJsonInput) { + // Test input: grpc_cli call localhost:<port> RequestStream "message: + // 'Hello0'" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "RequestStream", "{ \"message\": \"Hello0\" }"}; + + // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss( + "{ \"bad_field\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_json_input = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_input = false; + + // Expected output: "message: \"Hello0Hello2\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\"")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandResponseStream) { // Test input: grpc_cli call localhost:<port> ResponseStream "message: // 'Hello'" @@ -554,6 +860,24 @@ TEST_F(GrpcToolTest, CallCommandResponseStream) { expected_response_text.c_str())); } + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + + // Expected output: "{\n \"message\": \"Hello{n}\"\n}\n" + for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { + grpc::string expected_response_text = + "{\n \"message\": \"Hello" + grpc::to_string(i) + "\"\n}\n"; + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + expected_response_text.c_str())); + } + ShutdownServer(); } @@ -617,15 +941,31 @@ TEST_F(GrpcToolTest, ParseCommand) { const grpc::string server_address = SetUpServer(); const char* argv[] = {"grpc_cli", "parse", server_address.c_str(), - "grpc.testing.EchoResponse", ECHO_RESPONSE_MESSAGE}; + "grpc.testing.EchoResponse", + ECHO_RESPONSE_MESSAGE_TEXT_FORMAT}; FLAGS_binary_input = false; FLAGS_binary_output = false; EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), std::bind(PrintStream, &output_stream, std::placeholders::_1))); - // Expected output: ECHO_RESPONSE_MESSAGE - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE)); + // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); + + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + + // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + ECHO_RESPONSE_MESSAGE_JSON_FORMAT)); // Parse text message to binary message and then parse it back to text message output_stream.str(grpc::string()); @@ -645,13 +985,52 @@ TEST_F(GrpcToolTest, ParseCommand) { std::placeholders::_1))); // Expected output: ECHO_RESPONSE_MESSAGE - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE)); + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); FLAGS_binary_input = false; FLAGS_binary_output = false; ShutdownServer(); } +TEST_F(GrpcToolTest, ParseCommandJsonFormat) { + // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse + // ECHO_RESPONSE_MESSAGE_JSON_FORMAT" + std::stringstream output_stream; + std::stringstream binary_output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "parse", server_address.c_str(), + "grpc.testing.EchoResponse", + ECHO_RESPONSE_MESSAGE_JSON_FORMAT}; + + FLAGS_json_input = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); + + // with json_output + output_stream.str(grpc::string()); + output_stream.clear(); + + FLAGS_json_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_json_output = false; + FLAGS_json_input = false; + + // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + ECHO_RESPONSE_MESSAGE_JSON_FORMAT)); + + ShutdownServer(); +} + TEST_F(GrpcToolTest, TooFewArguments) { // Test input "grpc_cli call Echo" std::stringstream output_stream; diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index a530ed1ffc..68ecfeae2c 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -217,31 +217,32 @@ bool ProtoFileParser::IsStreaming(const grpc::string& method, bool is_request) { } grpc::string ProtoFileParser::GetSerializedProtoFromMethod( - const grpc::string& method, const grpc::string& text_format_proto, - bool is_request) { + const grpc::string& method, const grpc::string& formatted_proto, + bool is_request, bool is_json_format) { has_error_ = false; grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request); if (has_error_) { return ""; } - return GetSerializedProtoFromMessageType(message_type_name, - text_format_proto); + return GetSerializedProtoFromMessageType(message_type_name, formatted_proto, + is_json_format); } -grpc::string ProtoFileParser::GetTextFormatFromMethod( +grpc::string ProtoFileParser::GetFormattedStringFromMethod( const grpc::string& method, const grpc::string& serialized_proto, - bool is_request) { + bool is_request, bool is_json_format) { has_error_ = false; grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request); if (has_error_) { return ""; } - return GetTextFormatFromMessageType(message_type_name, serialized_proto); + return GetFormattedStringFromMessageType(message_type_name, serialized_proto, + is_json_format); } grpc::string ProtoFileParser::GetSerializedProtoFromMessageType( - const grpc::string& message_type_name, - const grpc::string& text_format_proto) { + const grpc::string& message_type_name, const grpc::string& formatted_proto, + bool is_json_format) { has_error_ = false; grpc::string serialized; const protobuf::Descriptor* desc = @@ -252,11 +253,23 @@ grpc::string ProtoFileParser::GetSerializedProtoFromMessageType( } std::unique_ptr<grpc::protobuf::Message> msg( dynamic_factory_->GetPrototype(desc)->New()); - bool ok = protobuf::TextFormat::ParseFromString(text_format_proto, msg.get()); - if (!ok) { - LogError("Failed to parse text format to proto."); - return ""; + + bool ok; + if (is_json_format) { + ok = grpc::protobuf::json::JsonStringToMessage(formatted_proto, msg.get()) + .ok(); + if (!ok) { + LogError("Failed to convert json format to proto."); + return ""; + } + } else { + ok = protobuf::TextFormat::ParseFromString(formatted_proto, msg.get()); + if (!ok) { + LogError("Failed to convert text format to proto."); + return ""; + } } + ok = msg->SerializeToString(&serialized); if (!ok) { LogError("Failed to serialize proto."); @@ -265,9 +278,9 @@ grpc::string ProtoFileParser::GetSerializedProtoFromMessageType( return serialized; } -grpc::string ProtoFileParser::GetTextFormatFromMessageType( - const grpc::string& message_type_name, - const grpc::string& serialized_proto) { +grpc::string ProtoFileParser::GetFormattedStringFromMessageType( + const grpc::string& message_type_name, const grpc::string& serialized_proto, + bool is_json_format) { has_error_ = false; const protobuf::Descriptor* desc = desc_pool_->FindMessageTypeByName(message_type_name); @@ -281,12 +294,24 @@ grpc::string ProtoFileParser::GetTextFormatFromMessageType( LogError("Failed to deserialize proto."); return ""; } - grpc::string text_format; - if (!protobuf::TextFormat::PrintToString(*msg.get(), &text_format)) { - LogError("Failed to print proto message to text format"); - return ""; + grpc::string formatted_string; + + if (is_json_format) { + grpc::protobuf::json::JsonPrintOptions jsonPrintOptions; + jsonPrintOptions.add_whitespace = true; + if (!grpc::protobuf::json::MessageToJsonString( + *msg.get(), &formatted_string, jsonPrintOptions) + .ok()) { + LogError("Failed to print proto message to json format"); + return ""; + } + } else { + if (!protobuf::TextFormat::PrintToString(*msg.get(), &formatted_string)) { + LogError("Failed to print proto message to text format"); + return ""; + } } - return text_format; + return formatted_string; } void ProtoFileParser::LogError(const grpc::string& error_msg) { diff --git a/test/cpp/util/proto_file_parser.h b/test/cpp/util/proto_file_parser.h index eb1d793c2b..1e49c98daf 100644 --- a/test/cpp/util/proto_file_parser.h +++ b/test/cpp/util/proto_file_parser.h @@ -53,21 +53,49 @@ class ProtoFileParser { // used as the argument of Stub::Call() grpc::string GetFormattedMethodName(const grpc::string& method); - grpc::string GetSerializedProtoFromMethod( - const grpc::string& method, const grpc::string& text_format_proto, - bool is_request); - - grpc::string GetTextFormatFromMethod(const grpc::string& method, - const grpc::string& serialized_proto, - bool is_request); - + /// Converts a text or json string to its binary proto representation for the + /// given method's input or return type. + /// \param method the name of the method (does not need to be fully qualified + /// name) + /// \param formatted_proto the text- or json-formatted proto string + /// \param is_request if \c true the resolved type is that of the input + /// parameter of the method, otherwise it is the output type + /// \param is_json_format if \c true the \c formatted_proto is treated as a + /// json-formatted proto, otherwise it is treated as a text-formatted + /// proto + /// \return the serialised binary proto represenation of \c formatted_proto + grpc::string GetSerializedProtoFromMethod(const grpc::string& method, + const grpc::string& formatted_proto, + bool is_request, + bool is_json_format); + + /// Converts a text or json string to its proto representation for the given + /// message type. + /// \param formatted_proto the text- or json-formatted proto string + /// \return the serialised binary proto represenation of \c formatted_proto grpc::string GetSerializedProtoFromMessageType( const grpc::string& message_type_name, - const grpc::string& text_format_proto); - - grpc::string GetTextFormatFromMessageType( + const grpc::string& formatted_proto, bool is_json_format); + + /// Converts a binary proto string to its text or json string representation + /// for the given method's input or return type. + /// \param method the name of the method (does not need to be a fully + /// qualified name) + /// \param the serialised binary proto representation of type + /// \c message_type_name + /// \return the text- or json-formatted proto string of \c serialized_proto + grpc::string GetFormattedStringFromMethod( + const grpc::string& method, const grpc::string& serialized_proto, + bool is_request, bool is_json_format); + + /// Converts a binary proto string to its text or json string representation + /// for the given message type. + /// \param the serialised binary proto representation of type + /// \c message_type_name + /// \return the text- or json-formatted proto string of \c serialized_proto + grpc::string GetFormattedStringFromMessageType( const grpc::string& message_type_name, - const grpc::string& serialized_proto); + const grpc::string& serialized_proto, bool is_json_format); bool IsStreaming(const grpc::string& method, bool is_request); diff --git a/tools/bazel.rc b/tools/bazel.rc index 39f8071535..088c9da63c 100644 --- a/tools/bazel.rc +++ b/tools/bazel.rc @@ -1,51 +1,54 @@ +# bazelrc file +# bazel >= 0.18 looks for %workspace%/.bazelrc (which redirects here) +# Older bazel versions look for %workspace%/tools/bazel.rc (this file) +# See https://github.com/bazelbuild/bazel/issues/6319 + build --client_env=CC=clang -build --copt -DGRPC_BAZEL_BUILD +build --copt=-DGRPC_BAZEL_BUILD -build:opt --copt -Wframe-larger-than=16384 +build:opt --copt=-Wframe-larger-than=16384 build:asan --strip=never -build:asan --copt -fsanitize-coverage=edge -build:asan --copt -fsanitize=address -build:asan --copt -O0 -build:asan --copt -fno-omit-frame-pointer -build:asan --copt -DGPR_NO_DIRECT_SYSCALLS -build:asan --linkopt -fsanitize=address +build:asan --copt=-fsanitize=address +build:asan --copt=-O0 +build:asan --copt=-fno-omit-frame-pointer +build:asan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:asan --linkopt=-fsanitize=address build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1 build:msan --strip=never -build:msan --copt -fsanitize-coverage=edge -build:msan --copt -fsanitize=memory -build:msan --copt -O0 -build:msan --copt -fsanitize-memory-track-origins -build:msan --copt -fsanitize-memory-use-after-dtor -build:msan --copt -fno-omit-frame-pointer -build:msan --copt -fPIE -build:msan --copt -DGPR_NO_DIRECT_SYSCALLS -build:msan --linkopt -fsanitize=memory -build:msan --linkopt -fPIE +build:msan --copt=-fsanitize-coverage=edge +build:msan --copt=-fsanitize=memory +build:msan --copt=-O0 +build:msan --copt=-fsanitize-memory-track-origins +build:msan --copt=-fsanitize-memory-use-after-dtor +build:msan --copt=-fno-omit-frame-pointer +build:msan --copt=-fPIE +build:msan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:msan --linkopt=-fsanitize=memory +build:msan --linkopt=-fPIE build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1 build:tsan --strip=never -build:tsan --copt -fsanitize=thread -build:tsan --copt -fno-omit-frame-pointer -build:tsan --copt -DGPR_NO_DIRECT_SYSCALLS -build:tsan --copt -DGRPC_TSAN -build:tsan --linkopt -fsanitize=thread +build:tsan --copt=-fsanitize=thread +build:tsan --copt=-fno-omit-frame-pointer +build:tsan --copt=-DGPR_NO_DIRECT_SYSCALLS +build:tsan --copt=-DGRPC_TSAN +build:tsan --linkopt=-fsanitize=thread build:tsan --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 build:ubsan --strip=never -build:ubsan --copt -fsanitize-coverage=edge -build:ubsan --copt -fsanitize=undefined -build:ubsan --copt -fno-omit-frame-pointer -build:ubsan --copt -DGRPC_UBSAN -build:ubsan --copt -DNDEBUG -build:ubsan --copt -fno-sanitize=function,vptr -build:ubsan --linkopt -fsanitize=undefined +build:ubsan --copt=-fsanitize=undefined +build:ubsan --copt=-fno-omit-frame-pointer +build:ubsan --copt=-DGRPC_UBSAN +build:ubsan --copt=-DNDEBUG +build:ubsan --copt=-fno-sanitize=function,vptr +build:ubsan --linkopt=-fsanitize=undefined build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1:suppressions=test/core/util/ubsan_suppressions.txt build:basicprof --strip=never -build:basicprof --copt -DNDEBUG -build:basicprof --copt -O2 -build:basicprof --copt -DGRPC_BASIC_PROFILER -build:basicprof --copt -DGRPC_TIMERS_RDTSC +build:basicprof --copt=-DNDEBUG +build:basicprof --copt=-O2 +build:basicprof --copt=-DGRPC_BASIC_PROFILER +build:basicprof --copt=-DGRPC_TIMERS_RDTSC diff --git a/tools/buildgen/generate_build_additions.sh b/tools/buildgen/generate_build_additions.sh index 693c02fdb2..5a1f4a598a 100755 --- a/tools/buildgen/generate_build_additions.sh +++ b/tools/buildgen/generate_build_additions.sh @@ -25,7 +25,8 @@ gen_build_yaml_dirs=" \ test/core/bad_ssl \ test/core/end2end \ test/cpp/naming \ - test/cpp/qps" + test/cpp/qps \ + tools/run_tests/lb_interop_tests" gen_build_files="" for gen_build_yaml in $gen_build_yaml_dirs do diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py index f705a9bd41..adfd4a24f9 100755 --- a/tools/codegen/core/gen_static_metadata.py +++ b/tools/codegen/core/gen_static_metadata.py @@ -63,6 +63,7 @@ CONFIG = [ 'grpc.max_response_message_bytes', # well known method names '/grpc.lb.v1.LoadBalancer/BalanceLoad', + '/grpc.health.v1.Health/Watch', # compression algorithm names 'deflate', 'gzip', diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py index 77f602ad1f..787bef1778 100755 --- a/tools/distrib/check_copyright.py +++ b/tools/distrib/check_copyright.py @@ -75,6 +75,8 @@ _EXEMPT = frozenset(( 'examples/python/multiplex/route_guide_pb2_grpc.py', 'examples/python/route_guide/route_guide_pb2.py', 'examples/python/route_guide/route_guide_pb2_grpc.py', + 'src/core/ext/filters/client_channel/health/health.pb.h', + 'src/core/ext/filters/client_channel/health/health.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', @@ -87,8 +89,6 @@ _EXEMPT = frozenset(( 'src/core/tsi/alts/handshaker/handshaker.pb.c', 'src/core/tsi/alts/handshaker/transport_security_common.pb.h', 'src/core/tsi/alts/handshaker/transport_security_common.pb.c', - 'src/cpp/server/health/health.pb.h', - 'src/cpp/server/health/health.pb.c', # An older file originally from outside gRPC. 'src/php/tests/bootstrap.php', diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py index 56f48af56a..b8d530cce0 100755 --- a/tools/distrib/check_include_guards.py +++ b/tools/distrib/check_include_guards.py @@ -156,6 +156,7 @@ argp.add_argument('--precommit', default=False, action='store_true') args = argp.parse_args() KNOWN_BAD = set([ + 'src/core/ext/filters/client_channel/health/health.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h', 'src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h', diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh index 6b98619c32..018cbb7b66 100755 --- a/tools/distrib/check_nanopb_output.sh +++ b/tools/distrib/check_nanopb_output.sh @@ -16,6 +16,7 @@ set -ex readonly NANOPB_ALTS_TMP_OUTPUT="$(mktemp -d)" +readonly NANOPB_HEALTH_TMP_OUTPUT="$(mktemp -d)" readonly NANOPB_TMP_OUTPUT="$(mktemp -d)" readonly PROTOBUF_INSTALL_PREFIX="$(mktemp -d)" @@ -68,6 +69,23 @@ if ! diff -r "$NANOPB_TMP_OUTPUT" src/core/ext/filters/client_channel/lb_policy/ fi # +# checks for health.proto +# +readonly HEALTH_GRPC_OUTPUT_PATH='src/core/ext/filters/client_channel/health' +# nanopb-compile the proto to a temp location +./tools/codegen/core/gen_nano_proto.sh \ + src/proto/grpc/health/v1/health.proto \ + "$NANOPB_HEALTH_TMP_OUTPUT" \ + "$HEALTH_GRPC_OUTPUT_PATH" +# compare outputs to checked compiled code +for NANOPB_OUTPUT_FILE in $NANOPB_HEALTH_TMP_OUTPUT/*.pb.*; do + if ! diff "$NANOPB_OUTPUT_FILE" "${HEALTH_GRPC_OUTPUT_PATH}/$(basename $NANOPB_OUTPUT_FILE)"; then + echo "Outputs differ: $NANOPB_HEALTH_TMP_OUTPUT vs $HEALTH_GRPC_OUTPUT_PATH" + exit 2 + fi +done + +# # Checks for handshaker.proto and transport_security_common.proto # readonly HANDSHAKER_GRPC_OUTPUT_PATH='src/core/tsi/alts/handshaker' diff --git a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh index 2f31bea69b..fd549fb9e5 100755 --- a/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_cxx/build_interop.sh @@ -31,7 +31,7 @@ cd /var/local/git/grpc make install-certs # build C++ interop client & server -make interop_client interop_server +make interop_client interop_server -j2 # build C++ http2 client make http2_client diff --git a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh index b651ac5b88..0e36c193c9 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java/build_interop.sh @@ -26,3 +26,11 @@ cd /var/local/git/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true +# enable extra java logging +mkdir -p /var/local/grpc_java_logging +echo "handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL +.level = FINE +io.grpc.netty.NettyClientHandler = ALL +io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt + diff --git a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh index 521111acaa..4c5ba4b7a3 100644 --- a/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh +++ b/tools/dockerfile/interoptest/grpc_interop_java_oracle8/build_interop.sh @@ -25,4 +25,12 @@ cp -r /var/local/jenkins/service_account $HOME || true cd /var/local/git/grpc-java ./gradlew :grpc-interop-testing:installDist -PskipCodegen=true + +# enable extra java logging +mkdir -p /var/local/grpc_java_logging +echo "handlers = java.util.logging.ConsoleHandler +java.util.logging.ConsoleHandler.level = ALL +.level = FINE +io.grpc.netty.NettyClientHandler = ALL +io.grpc.netty.NettyServerHandler = ALL" > /var/local/grpc_java_logging/logconf.txt diff --git a/tools/dockerfile/interoptest/lb_interop_fake_servers/Dockerfile b/tools/dockerfile/interoptest/lb_interop_fake_servers/Dockerfile new file mode 100644 index 0000000000..22963f7f83 --- /dev/null +++ b/tools/dockerfile/interoptest/lb_interop_fake_servers/Dockerfile @@ -0,0 +1,34 @@ +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM golang:1.10 + +RUN apt-get update && apt-get install -y \ + dnsutils \ + git \ + vim \ + curl \ + python-pip \ + python-yaml \ + make && apt-get clean + +RUN ln -s /usr/local/go/bin/go /usr/local/bin + +# Install Python packages from PyPI +RUN pip install --upgrade pip==10.0.1 +RUN pip install virtualenv +RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 + +# Define the default command. +CMD ["bash"] diff --git a/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh b/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh new file mode 100644 index 0000000000..1846d51753 --- /dev/null +++ b/tools/dockerfile/interoptest/lb_interop_fake_servers/build_interop.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Gets a built Go interop server, fake balancer server, and python +# DNS server into a base image. +set -e + +# Clone just the grpc-go source code without any dependencies. +# We are cloning from a local git repo that contains the right revision +# to test instead of using "go get" to download from Github directly. +git clone --recursive /var/local/jenkins/grpc-go src/google.golang.org/grpc + +# Get all gRPC Go dependencies +(cd src/google.golang.org/grpc && make deps && make testdeps) + +# Build the interop server and fake balancer +(cd src/google.golang.org/grpc/interop/server && go install) +(cd src/google.golang.org/grpc/interop/fake_grpclb && go install) + +# Clone the grpc/grpc repo to get the python DNS server. +# Hack: we don't need to init submodules for the scripts we need. +mkdir -p /var/local/git/grpc +git clone /var/local/jenkins/grpc /var/local/git/grpc diff --git a/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile new file mode 100644 index 0000000000..a7a8174db4 --- /dev/null +++ b/tools/dockerfile/test/python_stretch_2.7_x64/Dockerfile @@ -0,0 +1,69 @@ +# Copyright 2018 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. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile index d94ccc8c74..0e97e77e2f 100644 --- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile +++ b/tools/dockerfile/test/python_stretch_3.5_x64/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2016 gRPC authors. +# Copyright 2018 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. @@ -13,7 +13,7 @@ # limitations under the License. FROM debian:stretch - + # Install Git and basic packages. RUN apt-get update && apt-get install -y \ autoconf \ @@ -53,51 +53,20 @@ RUN apt-get update && apt-get install -y time && apt-get clean RUN apt-get update && apt-get install -y python-pip && apt-get clean RUN pip install --upgrade google-api-python-client oauth2client -#==================== -# Python dependencies - -# Install dependencies - -RUN apt-get update && apt-get install -y \ - python-all-dev \ - python3-all-dev \ - python-pip - -# Install Python packages from PyPI -RUN pip install --upgrade pip==10.0.1 -RUN pip install virtualenv -RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0 - -# Install dependencies for pyenv -RUN apt-get update && apt-get install -y \ - libbz2-dev \ - libncurses5-dev \ - libncursesw5-dev \ - libreadline-dev \ - libsqlite3-dev \ - libssl-dev \ - llvm \ - mercurial \ - zlib1g-dev && apt-get clean - -# Install Pyenv and dev Python versions 3.{5,6,7} -RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash -ENV PATH /root/.pyenv/bin:$PATH -RUN eval "$(pyenv init -)" -RUN eval "$(pyenv virtualenv-init -)" -RUN pyenv update -RUN pyenv install 3.5-dev -RUN pyenv install 3.6-dev -RUN pyenv install 3.7-dev -RUN pyenv install pypy-5.3.1 -RUN pyenv local 3.5-dev 3.6-dev 3.7-dev pypy-5.3.1 +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 -# Install pip and virtualenv for Python 3.5 -RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 -RUN python3.5 -m pip install virtualenv +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local RUN mkdir /var/local/jenkins # Define the default command. CMD ["bash"] + + +RUN apt-get update && apt-get install -y python3.5 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.5 diff --git a/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile new file mode 100644 index 0000000000..9b16b2d3a1 --- /dev/null +++ b/tools/dockerfile/test/python_stretch_3.6_x64/Dockerfile @@ -0,0 +1,72 @@ +# Copyright 2018 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. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + + +RUN apt-get update && apt-get -t testing install -y python3.6 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.6 diff --git a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile new file mode 100644 index 0000000000..add1cc509d --- /dev/null +++ b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile @@ -0,0 +1,72 @@ +# Copyright 2018 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. + +FROM debian:stretch + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y \ + autoconf \ + autotools-dev \ + build-essential \ + bzip2 \ + ccache \ + curl \ + dnsutils \ + gcc \ + gcc-multilib \ + git \ + golang \ + gyp \ + lcov \ + libc6 \ + libc6-dbg \ + libc6-dev \ + libgtest-dev \ + libtool \ + make \ + perl \ + strace \ + python-dev \ + python-setuptools \ + python-yaml \ + telnet \ + unzip \ + wget \ + zip && apt-get clean + +#================ +# Build profiling +RUN apt-get update && apt-get install -y time && apt-get clean + +# Google Cloud platform API libraries +RUN apt-get update && apt-get install -y python-pip && apt-get clean +RUN pip install --upgrade google-api-python-client oauth2client + +# Install Python 2.7 +RUN apt-get update && apt-get install -y python2.7 python-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7 + +# Add Debian 'testing' repository +RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list +RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local + + +RUN mkdir /var/local/jenkins + +# Define the default command. +CMD ["bash"] + + +RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev +RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7 diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 40abd726c4..1abf6bddce 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -764,7 +764,6 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ @@ -775,7 +774,6 @@ doc/cpp-style-guide.md \ doc/cpp/pending_api_cleanups.md \ doc/cpp/perf_notes.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 8fed272159..26e671668e 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -764,7 +764,6 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ @@ -775,7 +774,6 @@ doc/cpp-style-guide.md \ doc/cpp/pending_api_cleanups.md \ doc/cpp/perf_notes.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ @@ -1014,6 +1012,8 @@ include/grpcpp/support/string_ref.h \ include/grpcpp/support/stub_options.h \ include/grpcpp/support/sync_stream.h \ include/grpcpp/support/time.h \ +src/core/ext/filters/client_channel/health/health.pb.c \ +src/core/ext/filters/client_channel/health/health.pb.h \ src/core/ext/transport/inproc/inproc_transport.h \ src/core/lib/avl/avl.h \ src/core/lib/backoff/backoff.h \ @@ -1210,8 +1210,6 @@ src/cpp/server/dynamic_thread_pool.cc \ src/cpp/server/dynamic_thread_pool.h \ src/cpp/server/health/default_health_check_service.cc \ src/cpp/server/health/default_health_check_service.h \ -src/cpp/server/health/health.pb.c \ -src/cpp/server/health/health.pb.h \ src/cpp/server/health/health_check_service.cc \ src/cpp/server/health/health_check_service_server_builder_option.cc \ src/cpp/server/insecure_server_credentials.cc \ @@ -1230,8 +1228,11 @@ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time_cc.cc \ third_party/nanopb/pb.h \ +third_party/nanopb/pb_common.c \ third_party/nanopb/pb_common.h \ +third_party/nanopb/pb_decode.c \ third_party/nanopb/pb_decode.h \ +third_party/nanopb/pb_encode.c \ third_party/nanopb/pb_encode.h # This tag can be used to specify the character encoding of the source files diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 973975ae28..b78fb607ad 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -764,13 +764,14 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/combiner-explainer.md \ +doc/core/epoll-polling-engine.md \ doc/core/grpc-client-server-polling-engine-usage.md \ doc/core/grpc-cq.md \ doc/core/grpc-error.md \ @@ -780,7 +781,6 @@ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ doc/cpp-style-guide.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index d5986fde90..437253c01b 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -764,13 +764,14 @@ INPUT = doc/PROTOCOL-HTTP2.md \ doc/PROTOCOL-WEB.md \ doc/binary-logging.md \ doc/c-style-guide.md \ -doc/combiner-explainer.md \ doc/command_line_tool.md \ doc/compression.md \ doc/compression_cookbook.md \ doc/connection-backoff-interop-test-description.md \ doc/connection-backoff.md \ doc/connectivity-semantics-and-api.md \ +doc/core/combiner-explainer.md \ +doc/core/epoll-polling-engine.md \ doc/core/grpc-client-server-polling-engine-usage.md \ doc/core/grpc-cq.md \ doc/core/grpc-error.md \ @@ -780,7 +781,6 @@ doc/core/pending_api_cleanups.md \ doc/core/transport_explainer.md \ doc/cpp-style-guide.md \ doc/environment_variables.md \ -doc/epoll-polling-engine.md \ doc/fail_fast.md \ doc/fork_support.md \ doc/g_stands_for.md \ @@ -885,6 +885,10 @@ src/core/ext/filters/client_channel/client_channel_factory.h \ src/core/ext/filters/client_channel/client_channel_plugin.cc \ src/core/ext/filters/client_channel/connector.cc \ src/core/ext/filters/client_channel/connector.h \ +src/core/ext/filters/client_channel/health/health.pb.c \ +src/core/ext/filters/client_channel/health/health.pb.h \ +src/core/ext/filters/client_channel/health/health_check_client.cc \ +src/core/ext/filters/client_channel/health/health_check_client.h \ src/core/ext/filters/client_channel/http_connect_handshaker.cc \ src/core/ext/filters/client_channel/http_connect_handshaker.h \ src/core/ext/filters/client_channel/http_proxy.cc \ @@ -910,6 +914,14 @@ src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balan src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc \ src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc \ src/core/ext/filters/client_channel/lb_policy/subchannel_list.h \ +src/core/ext/filters/client_channel/lb_policy/xds/xds.cc \ +src/core/ext/filters/client_channel/lb_policy/xds/xds.h \ +src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h \ +src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc \ +src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc \ +src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h \ +src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc \ +src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h \ src/core/ext/filters/client_channel/lb_policy_factory.cc \ src/core/ext/filters/client_channel/lb_policy_factory.h \ src/core/ext/filters/client_channel/lb_policy_registry.cc \ @@ -1361,16 +1373,22 @@ src/core/lib/security/credentials/plugin/plugin_credentials.cc \ src/core/lib/security/credentials/plugin/plugin_credentials.h \ src/core/lib/security/credentials/ssl/ssl_credentials.cc \ src/core/lib/security/credentials/ssl/ssl_credentials.h \ -src/core/lib/security/security_connector/alts_security_connector.cc \ -src/core/lib/security/security_connector/alts_security_connector.h \ +src/core/lib/security/security_connector/alts/alts_security_connector.cc \ +src/core/lib/security/security_connector/alts/alts_security_connector.h \ +src/core/lib/security/security_connector/fake/fake_security_connector.cc \ +src/core/lib/security/security_connector/fake/fake_security_connector.h \ src/core/lib/security/security_connector/load_system_roots.h \ src/core/lib/security/security_connector/load_system_roots_fallback.cc \ src/core/lib/security/security_connector/load_system_roots_linux.cc \ src/core/lib/security/security_connector/load_system_roots_linux.h \ -src/core/lib/security/security_connector/local_security_connector.cc \ -src/core/lib/security/security_connector/local_security_connector.h \ +src/core/lib/security/security_connector/local/local_security_connector.cc \ +src/core/lib/security/security_connector/local/local_security_connector.h \ src/core/lib/security/security_connector/security_connector.cc \ src/core/lib/security/security_connector/security_connector.h \ +src/core/lib/security/security_connector/ssl/ssl_security_connector.cc \ +src/core/lib/security/security_connector/ssl/ssl_security_connector.h \ +src/core/lib/security/security_connector/ssl_utils.cc \ +src/core/lib/security/security_connector/ssl_utils.h \ src/core/lib/security/transport/auth_filters.h \ src/core/lib/security/transport/client_auth_filter.cc \ src/core/lib/security/transport/secure_endpoint.cc \ diff --git a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh new file mode 100755 index 0000000000..0f7939be4c --- /dev/null +++ b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# Copyright 2018 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. + +# Creates a performance worker on GCE from an image that's used for kokoro +# perf workers. + +set -ex + +cd "$(dirname "$0")" + +CLOUD_PROJECT=grpc-testing +ZONE=us-central1-b # this zone allows 32core machines +LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v2 # update if newer image exists + +INSTANCE_NAME="${1:-grpc-kokoro-performance-server}" +MACHINE_TYPE="${2:-n1-standard-32}" + +gcloud compute instances create "$INSTANCE_NAME" \ + --project="$CLOUD_PROJECT" \ + --zone "$ZONE" \ + --machine-type "$MACHINE_TYPE" \ + --image-project "$CLOUD_PROJECT" \ + --image "$LATEST_PERF_WORKER_IMAGE" \ + --boot-disk-size 300 \ + --scopes https://www.googleapis.com/auth/bigquery \ + --tags=allow-ssh diff --git a/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc b/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc new file mode 100644 index 0000000000..a8e350be58 --- /dev/null +++ b/tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc @@ -0,0 +1,33 @@ +#!/bin/bash +# Copyright 2017 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. + +# Source this rc script to prepare the environment for interop builds +# This rc script must be used in the root directory of gRPC + +export LANG=en_US.UTF-8 + +# Download Docker images from DockerHub +export DOCKERHUB_ORGANIZATION=grpctesting + +git submodule update --init + +# Set up gRPC-Go and gRPC-Java to test +git clone --recursive https://github.com/grpc/grpc-go ./../grpc-go +git clone --recursive https://github.com/grpc/grpc-java ./../grpc-java + +# TODO(apolcyn): move to kokoro image? +virtualenv env +source env/bin/activate +pip install twisted diff --git a/tools/internal_ci/linux/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/grpc_asan_on_foundry.sh index dfef004a60..24fbdf74c2 100755 --- a/tools/internal_ci/linux/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_asan_on_foundry.sh @@ -14,7 +14,5 @@ # limitations under the License. export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600 --cache_test_results=no" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=asan --cache_test_results=no diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh index bb2a85138c..768e15b380 100755 --- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh +++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh @@ -38,28 +38,8 @@ export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instan # TODO(adelez): implement size for test targets and change test_timeout back "${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ - --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ - test --jobs="200" \ - --test_output=errors \ - --verbose_failures=true \ - --keep_going \ - --remote_accept_cached=true \ - --spawn_strategy=remote \ - --remote_local_fallback=false \ - --remote_timeout=3600 \ - --strategy=Javac=remote \ - --strategy=Closure=remote \ - --genrule_strategy=remote \ - --experimental_strict_action_env=true \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain \ - --define GRPC_PORT_ISOLATED_RUNTIME=1 \ - --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ - --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ - --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --test_env=GRPC_VERBOSITY=debug \ - --remote_instance_name=projects/grpc-testing/instances/default_instance \ + --bazelrc=tools/remote_build/kokoro.bazelrc \ + test \ $@ \ -- //test/... || FAILED="true" diff --git a/tools/internal_ci/linux/grpc_e2e_performance_singlevm.sh b/tools/internal_ci/linux/grpc_e2e_performance_singlevm.sh index 86d669be33..3c9798d375 100755 --- a/tools/internal_ci/linux/grpc_e2e_performance_singlevm.sh +++ b/tools/internal_ci/linux/grpc_e2e_performance_singlevm.sh @@ -25,4 +25,5 @@ tools/run_tests/run_performance_tests.py \ --netperf \ --category smoketest \ -u kbuilder \ + --bq_result_table performance_test.performance_experiment_singlevm \ --xml_report reports/singlemachine/sponge_log.xml diff --git a/tools/internal_ci/linux/grpc_interop_matrix.cfg b/tools/internal_ci/linux/grpc_interop_matrix.cfg index 696a55c0df..e13c26e8ba 100644 --- a/tools/internal_ci/linux/grpc_interop_matrix.cfg +++ b/tools/internal_ci/linux/grpc_interop_matrix.cfg @@ -16,7 +16,6 @@ # Location of the continuous shell script in repository. build_file: "grpc/tools/internal_ci/linux/grpc_interop_matrix.sh" -# grpc_interop tests can take 1 hours to complete. timeout_mins: 300 action { define_artifacts { @@ -24,3 +23,8 @@ action { regex: "github/grpc/reports/**" } } + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "--language=all --release=all --allow_flakes --report_file=sponge_log.xml --bq_result_table interop_results" +} diff --git a/tools/internal_ci/linux/grpc_interop_matrix.sh b/tools/internal_ci/linux/grpc_interop_matrix.sh index 4c24c43488..a5220ea087 100755 --- a/tools/internal_ci/linux/grpc_interop_matrix.sh +++ b/tools/internal_ci/linux/grpc_interop_matrix.sh @@ -22,4 +22,4 @@ cd $(dirname $0)/../../.. source tools/internal_ci/helper_scripts/prepare_build_linux_rc -tools/interop_matrix/run_interop_matrix_tests.py --language=all --release=all --allow_flakes --report_file=sponge_log.xml --bq_result_table interop_results $@ +tools/interop_matrix/run_interop_matrix_tests.py $RUN_TESTS_FLAGS diff --git a/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh b/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh new file mode 100755 index 0000000000..806b5c947e --- /dev/null +++ b/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -ex + +export LANG=en_US.UTF-8 + +# Enter the gRPC repo root +cd $(dirname $0)/../../.. + +source tools/internal_ci/helper_scripts/prepare_build_linux_rc +source tools/internal_ci/helper_scripts/prepare_build_grpclb_interop_rc + +tools/run_tests/run_grpclb_interop_tests.py -l all --scenarios_file=tools/run_tests/generated/lb_interop_test_scenarios.json diff --git a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh index 366b5cbe34..7686794784 100644 --- a/tools/internal_ci/linux/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_tsan_on_foundry.sh @@ -14,6 +14,4 @@ # limitations under the License. export UPLOAD_TEST_RESULTS=true -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1 --cache_test_results=no" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=tsan --cache_test_results=no diff --git a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh index e0ae9103c4..4350cb1ba5 100644 --- a/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/grpc_ubsan_on_foundry.sh @@ -13,66 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -ex - -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in -# the build config. -# TODO: Use keystore. -mkdir -p ${KOKORO_KEYSTORE_DIR} -cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service - -temp_dir=$(mktemp -d) -ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" -export PATH="${temp_dir}:${PATH}" -# This should show ${temp_dir}/bazel -which bazel -chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py" - -# change to grpc repo root -cd $(dirname $0)/../../.. - -source tools/internal_ci/helper_scripts/prepare_build_linux_rc - -export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" - -"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ - --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ - test --jobs="200" \ - --test_timeout="3600,3600,3600,3600" \ - --test_output=errors \ - --verbose_failures=true \ - --keep_going \ - --remote_accept_cached=true \ - --spawn_strategy=remote \ - --remote_local_fallback=false \ - --remote_timeout=3600 \ - --strategy=Javac=remote \ - --strategy=Closure=remote \ - --genrule_strategy=remote \ - --experimental_strict_action_env=true \ - --define GRPC_PORT_ISOLATED_RUNTIME=1 \ - --copt=-gmlt \ - --strip=never \ - --copt=-fsanitize=undefined \ - --linkopt=-fsanitize=undefined \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain \ - --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ - --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ - --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --cache_test_results=no \ - --test_env=GRPC_VERBOSITY=debug \ - --remote_instance_name=projects/grpc-testing/instances/default_instance \ - -- //test/... || FAILED="true" - -# Sleep to let ResultStore finish writing results before querying -sleep 60 -python ./tools/run_tests/python_utils/upload_rbe_results.py - -if [ "$FAILED" != "" ] -then - exit 1 -fi +export UPLOAD_TEST_RESULTS=true +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=ubsan --cache_test_results=no diff --git a/tools/internal_ci/linux/grpclb_in_dns_interop.cfg b/tools/internal_ci/linux/grpclb_in_dns_interop.cfg new file mode 100644 index 0000000000..6cd5f2e21a --- /dev/null +++ b/tools/internal_ci/linux/grpclb_in_dns_interop.cfg @@ -0,0 +1,25 @@ +# Copyright 2017 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_run_grpclb_interop_tests.sh" +timeout_mins: 60 +action { + define_artifacts { + regex: "**/sponge_log.xml" + regex: "github/grpc/reports/**" + } +} diff --git a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh index 39c991f291..84b65a3eb1 100644 --- a/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_asan_on_foundry.sh @@ -13,7 +13,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=address --linkopt=-fsanitize=address --test_timeout=3600" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=asan diff --git a/tools/internal_ci/linux/pull_request/grpc_interop_matrix_adhoc.cfg b/tools/internal_ci/linux/pull_request/grpc_interop_matrix_adhoc.cfg new file mode 100644 index 0000000000..6726384f18 --- /dev/null +++ b/tools/internal_ci/linux/pull_request/grpc_interop_matrix_adhoc.cfg @@ -0,0 +1,30 @@ +# Copyright 2017 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. + +# Config file for the internal CI (in protobuf text format) + +# Location of the continuous shell script in repository. +build_file: "grpc/tools/internal_ci/linux/grpc_interop_matrix.sh" +timeout_mins: 300 +action { + define_artifacts { + regex: "**/sponge_log.xml" + regex: "github/grpc/reports/**" + } +} + +env_vars { + key: "RUN_TESTS_FLAGS" + value: "--language=all --release=all --allow_flakes --report_file=sponge_log.xml" +} diff --git a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh index 3dee115300..4a9687f7e2 100644 --- a/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_tsan_on_foundry.sh @@ -13,6 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -EXTRA_FLAGS="--copt=-gmlt --strip=never --copt=-fsanitize=thread --linkopt=-fsanitize=thread --test_timeout=3600 --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1" -EXCLUDE_TESTS="--test_tag_filters=-qps_json_driver,-json_run_localhost" -github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}" "${EXCLUDE_TESTS}" +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=tsan diff --git a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh index 8547fa4d93..fb69d73635 100644 --- a/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh +++ b/tools/internal_ci/linux/pull_request/grpc_ubsan_on_foundry.sh @@ -13,61 +13,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -set -ex - -# A temporary solution to give Kokoro credentials. -# The file name 4321_grpc-testing-service needs to match auth_credential in -# the build config. -# TODO: Use keystore. -mkdir -p ${KOKORO_KEYSTORE_DIR} -cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service - -temp_dir=$(mktemp -d) -ln -f "${KOKORO_GFILE_DIR}/bazel-latest-release" ${temp_dir}/bazel -chmod 755 "${KOKORO_GFILE_DIR}/bazel-latest-release" -export PATH="${temp_dir}:${PATH}" -# This should show ${temp_dir}/bazel -which bazel -chmod +x "${KOKORO_GFILE_DIR}/bazel_wrapper.py" - -# change to grpc repo root -cd $(dirname $0)/../../../.. - -source tools/internal_ci/helper_scripts/prepare_build_linux_rc - -export KOKORO_FOUNDRY_PROJECT_ID="projects/grpc-testing/instances/default_instance" - -"${KOKORO_GFILE_DIR}/bazel_wrapper.py" \ - --host_jvm_args=-Dbazel.DigestFunction=SHA256 \ - test --jobs="200" \ - --test_timeout="3600,3600,3600,3600" \ - --test_output=errors \ - --verbose_failures=true \ - --keep_going \ - --remote_accept_cached=true \ - --spawn_strategy=remote \ - --remote_local_fallback=false \ - --remote_timeout=3600 \ - --strategy=Javac=remote \ - --strategy=Closure=remote \ - --genrule_strategy=remote \ - --experimental_strict_action_env=true \ - --define GRPC_PORT_ISOLATED_RUNTIME=1 \ - --copt=-gmlt \ - --strip=never \ - --copt=-fsanitize=undefined \ - --linkopt=-fsanitize=undefined \ - --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain \ - --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 \ - --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default \ - --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --host_platform=//third_party/toolchains:rbe_ubuntu1604 \ - --platforms=//third_party/toolchains:rbe_ubuntu1604 \ - --test_env=GRPC_VERBOSITY=debug \ - --remote_instance_name=projects/grpc-testing/instances/default_instance \ - -- //test/... || FAILED="true" - -if [ "$FAILED" != "" ] -then - exit 1 -fi +github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=ubsan diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index 15b53d1716..c4935e8eee 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -# Dictionaries used for client matrix testing. +# Defines languages, runtimes and releases for backward compatibility testing def get_github_repo(lang): @@ -53,8 +53,7 @@ LANG_RUNTIME_MATRIX = { 'csharp': ['csharp', 'csharpcoreclr'], } -# Dictionary of releases per language. For each language, we need to provide -# a release tag pointing to the latest build of the branch. +# Dictionary of known releases for given language. LANG_RELEASE_MATRIX = { 'cxx': [ { @@ -102,6 +101,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'go': [ { @@ -138,7 +140,19 @@ LANG_RELEASE_MATRIX = { 'v1.11.3': None }, { - 'v1.12.0': None + 'v1.12.2': None + }, + { + 'v1.13.0': None + }, + { + 'v1.14.0': None + }, + { + 'v1.15.0': None + }, + { + 'v1.16.0': None }, ], 'java': [ @@ -237,6 +251,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'node': [ { @@ -328,6 +345,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'php': [ { @@ -375,6 +395,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], 'csharp': [ { @@ -427,6 +450,9 @@ LANG_RELEASE_MATRIX = { { 'v1.15.0': None }, + { + 'v1.16.0': None + }, ], } diff --git a/tools/interop_matrix/run_interop_matrix_tests.py b/tools/interop_matrix/run_interop_matrix_tests.py index 6cd6f43167..6cf2a9b036 100755 --- a/tools/interop_matrix/run_interop_matrix_tests.py +++ b/tools/interop_matrix/run_interop_matrix_tests.py @@ -26,7 +26,7 @@ import subprocess import sys import uuid -# Langauage Runtime Matrix +# Language Runtime Matrix import client_matrix python_util_dir = os.path.abspath( @@ -37,6 +37,9 @@ import jobset import report_utils import upload_test_results +_TEST_TIMEOUT_SECONDS = 60 +_PULL_IMAGE_TIMEOUT_SECONDS = 15 * 60 +_MAX_PARALLEL_DOWNLOADS = 6 _LANGUAGES = client_matrix.LANG_RUNTIME_MATRIX.keys() # All gRPC release tags, flattened, deduped and sorted. _RELEASES = sorted( @@ -45,7 +48,6 @@ _RELEASES = sorted( client_matrix.get_release_tag_name(info) for lang in client_matrix.LANG_RELEASE_MATRIX.values() for info in lang))) -_TEST_TIMEOUT = 60 argp = argparse.ArgumentParser(description='Run interop tests.') argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) @@ -56,7 +58,7 @@ argp.add_argument( argp.add_argument( '--release', default='all', - choices=['all', 'master'] + _RELEASES, + choices=['all'] + _RELEASES, help='Release tags to test. When testing all ' 'releases defined in client_matrix.py, use "all".') argp.add_argument( @@ -92,136 +94,154 @@ argp.add_argument( nargs='?', help='The gateway to backend services.') -args = argp.parse_args() - -print(str(args)) - -def find_all_images_for_lang(lang): +def _get_test_images_for_lang(lang, release_arg, image_path_prefix): """Find docker images for a language across releases and runtimes. Returns dictionary of list of (<tag>, <image-full-path>) keyed by runtime. """ - # Find all defined releases. - if args.release == 'all': - releases = ['master'] + client_matrix.get_release_tags(lang) + if release_arg == 'all': + # Use all defined releases for given language + releases = client_matrix.get_release_tags(lang) else: # Look for a particular release. - if args.release not in ['master' - ] + client_matrix.get_release_tags(lang): + if release_arg not in client_matrix.get_release_tags(lang): jobset.message( 'SKIPPED', - '%s for %s is not defined' % (args.release, lang), + 'release %s for %s is not defined' % (release_arg, lang), do_newline=True) return {} - releases = [args.release] + releases = [release_arg] - # TODO(jtattermusch): why do we need to query the existing images/tags? - # From LANG_RUNTIME_MATRIX and LANG_RELEASE_MATRIX it should be obvious - # which tags we want to test - and it should be an error if they are - # missing. # Images tuples keyed by runtime. images = {} for runtime in client_matrix.LANG_RUNTIME_MATRIX[lang]: - image_path = '%s/grpc_interop_%s' % (args.gcr_path, runtime) - output = subprocess.check_output([ - 'gcloud', 'beta', 'container', 'images', 'list-tags', - '--format=json', image_path - ]) - docker_image_list = json.loads(output) - # All images should have a single tag or no tag. - # TODO(adelez): Remove tagless images. - tags = [i['tags'][0] for i in docker_image_list if i['tags']] - jobset.message( - 'START', - 'Found images for %s: %s' % (image_path, tags), - do_newline=True) - skipped = len(docker_image_list) - len(tags) - jobset.message( - 'SKIPPED', - 'Skipped images (no-tag/unknown-tag): %d' % skipped, - do_newline=True) - # Filter tags based on the releases. - images[runtime] = [(tag, '%s:%s' % (image_path, tag)) - for tag in tags - if tag in releases] + image_path = '%s/grpc_interop_%s' % (image_path_prefix, runtime) + images[runtime] = [ + (tag, '%s:%s' % (image_path, tag)) for tag in releases + ] return images -# caches test cases (list of JobSpec) loaded from file. Keyed by lang and runtime. -def find_test_cases(lang, runtime, release, suite_name): - """Returns the list of test cases from testcase files per lang/release.""" +def _read_test_cases_file(lang, runtime, release): + """Read test cases from a bash-like file and return a list of commands""" testcase_dir = os.path.join(os.path.dirname(__file__), 'testcases') filename_prefix = lang if lang == 'csharp': + # TODO(jtattermusch): remove this odd specialcase filename_prefix = runtime # Check to see if we need to use a particular version of test cases. lang_version = '%s_%s' % (filename_prefix, release) if lang_version in client_matrix.TESTCASES_VERSION_MATRIX: - testcases = os.path.join( + testcase_file = os.path.join( testcase_dir, client_matrix.TESTCASES_VERSION_MATRIX[lang_version]) else: - testcases = os.path.join(testcase_dir, '%s__master' % filename_prefix) + # TODO(jtattermusch): remove the double-underscore, it is pointless + testcase_file = os.path.join(testcase_dir, + '%s__master' % filename_prefix) + + lines = [] + with open(testcase_file) as f: + for line in f.readlines(): + line = re.sub('\\#.*$', '', line) # remove hash comments + line = line.strip() + if line and not line.startswith('echo'): + # Each non-empty line is a treated as a test case command + lines.append(line) + return lines + + +def _cleanup_docker_image(image): + jobset.message('START', 'Cleanup docker image %s' % image, do_newline=True) + dockerjob.remove_image(image, skip_nonexistent=True) + + +args = argp.parse_args() + + +# caches test cases (list of JobSpec) loaded from file. Keyed by lang and runtime. +def _generate_test_case_jobspecs(lang, runtime, release, suite_name): + """Returns the list of test cases from testcase files per lang/release.""" + testcase_lines = _read_test_cases_file(lang, runtime, release) job_spec_list = [] - try: - with open(testcases) as f: - # Only line start with 'docker run' are test cases. - for line in f.readlines(): - if line.startswith('docker run'): - m = re.search('--test_case=(.*)"', line) - shortname = m.group(1) if m else 'unknown_test' - m = re.search( - '--server_host_override=(.*).sandbox.googleapis.com', - line) - server = m.group(1) if m else 'unknown_server' - - # If server_host arg is not None, replace the original - # server_host with the one provided or append to the end of - # the command if server_host does not appear originally. - if args.server_host: - if line.find('--server_host=') > -1: - line = re.sub('--server_host=[^ ]*', - '--server_host=%s' % args.server_host, - line) - else: - line = '%s --server_host=%s"' % (line[:-1], - args.server_host) - print(line) - - spec = jobset.JobSpec( - cmdline=line, - shortname='%s:%s:%s:%s' % (suite_name, lang, server, - shortname), - timeout_seconds=_TEST_TIMEOUT, - shell=True, - flake_retries=5 if args.allow_flakes else 0) - job_spec_list.append(spec) - jobset.message( - 'START', - 'Loaded %s tests from %s' % (len(job_spec_list), testcases), - do_newline=True) - except IOError as err: - jobset.message('FAILED', err, do_newline=True) + for line in testcase_lines: + # TODO(jtattermusch): revisit the logic for updating test case commands + # what it currently being done seems fragile. + m = re.search('--test_case=(.*)"', line) + shortname = m.group(1) if m else 'unknown_test' + m = re.search('--server_host_override=(.*).sandbox.googleapis.com', + line) + server = m.group(1) if m else 'unknown_server' + + # If server_host arg is not None, replace the original + # server_host with the one provided or append to the end of + # the command if server_host does not appear originally. + if args.server_host: + if line.find('--server_host=') > -1: + line = re.sub('--server_host=[^ ]*', + '--server_host=%s' % args.server_host, line) + else: + line = '%s --server_host=%s"' % (line[:-1], args.server_host) + + spec = jobset.JobSpec( + cmdline=line, + shortname='%s:%s:%s:%s' % (suite_name, lang, server, shortname), + timeout_seconds=_TEST_TIMEOUT_SECONDS, + shell=True, + flake_retries=5 if args.allow_flakes else 0) + job_spec_list.append(spec) return job_spec_list -_xml_report_tree = report_utils.new_junit_xml_tree() +def _pull_images_for_lang(lang, images): + """Pull all images for given lang from container registry.""" + jobset.message( + 'START', 'Downloading images for language "%s"' % lang, do_newline=True) + download_specs = [] + for release, image in images: + # Pull the image and warm it up. + # First time we use an image with "docker run", it takes time to unpack + # the image and later this delay would fail our test cases. + cmdline = [ + 'time gcloud docker -- pull %s && time docker run --rm=true %s /bin/true' + % (image, image) + ] + spec = jobset.JobSpec( + cmdline=cmdline, + shortname='pull_image_%s' % (image), + timeout_seconds=_PULL_IMAGE_TIMEOUT_SECONDS, + shell=True) + download_specs.append(spec) + # too many image downloads at once tend to get stuck + max_pull_jobs = min(args.jobs, _MAX_PARALLEL_DOWNLOADS) + num_failures, resultset = jobset.run( + download_specs, newline_on_success=True, maxjobs=max_pull_jobs) + if num_failures: + jobset.message( + 'FAILED', 'Failed to download some images', do_newline=True) + return False + else: + jobset.message( + 'SUCCESS', 'All images downloaded successfully.', do_newline=True) + return True -def run_tests_for_lang(lang, runtime, images): +def _run_tests_for_lang(lang, runtime, images, xml_report_tree): """Find and run all test cases for a language. images is a list of (<release-tag>, <image-full-path>) tuple. """ + if not _pull_images_for_lang(lang, images): + jobset.message( + 'FAILED', 'Image download failed. Exiting.', do_newline=True) + return 1 + total_num_failures = 0 - for image_tuple in images: - release, image = image_tuple - jobset.message('START', 'Testing %s' % image, do_newline=True) - # Download the docker image before running each test case. - subprocess.check_call(['gcloud', 'docker', '--', 'pull', image]) + for release, image in images: suite_name = '%s__%s_%s' % (lang, runtime, release) - job_spec_list = find_test_cases(lang, runtime, release, suite_name) + job_spec_list = _generate_test_case_jobspecs(lang, runtime, release, + suite_name) if not job_spec_list: jobset.message( @@ -242,28 +262,24 @@ def run_tests_for_lang(lang, runtime, images): else: jobset.message('SUCCESS', 'All tests passed', do_newline=True) - report_utils.append_junit_xml_results(_xml_report_tree, resultset, + report_utils.append_junit_xml_results(xml_report_tree, resultset, 'grpc_interop_matrix', suite_name, str(uuid.uuid4())) if not args.keep: - cleanup(image) + _cleanup_docker_image(image) return total_num_failures -def cleanup(image): - jobset.message('START', 'Cleanup docker image %s' % image, do_newline=True) - dockerjob.remove_image(image, skip_nonexistent=True) - - languages = args.language if args.language != ['all'] else _LANGUAGES total_num_failures = 0 +_xml_report_tree = report_utils.new_junit_xml_tree() for lang in languages: - docker_images = find_all_images_for_lang(lang) + docker_images = _get_test_images_for_lang(lang, args.release, args.gcr_path) for runtime in sorted(docker_images.keys()): - total_num_failures += run_tests_for_lang(lang, runtime, - docker_images[runtime]) + total_num_failures += _run_tests_for_lang( + lang, runtime, docker_images[runtime], _xml_report_tree) report_utils.create_xml_report_file(_xml_report_tree, args.report_file) diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md new file mode 100644 index 0000000000..7492de75a5 --- /dev/null +++ b/tools/remote_build/README.md @@ -0,0 +1,30 @@ +# Running Remote Builds with bazel + +This allows you to spawn gRPC C/C++ remote build and tests from your workstation with +configuration that's very similar to what's used by our CI Kokoro. + +Note that this will only work for gRPC team members (it requires access to the +remote build and execution cluster), others will need to rely on local test runs +and tests run by Kokoro CI. + + +## Prerequisites + +- See [Installing Bazel](https://docs.bazel.build/versions/master/install.html) for instructions how to install bazel on your system. + +- Setup application default credentials for running remote builds by following [RBE Credentials Setup](https://cloud.google.com/remote-build-execution/docs/getting-started#set_credentials) + + +## Running remote build manually from dev workstation + +Run from repository root: +``` +# manual run of bazel tests remotely on Foundry +bazel --bazelrc=tools/remote_build/manual.bazelrc test -c opt //test/... +``` + +Sanitizer runs (asan, msan, tsan, ubsan): +``` +# manual run of bazel tests remotely on Foundry with given sanitizer +bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=asan //test/... +``` diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc new file mode 100644 index 0000000000..0aacddf663 --- /dev/null +++ b/tools/remote_build/kokoro.bazelrc @@ -0,0 +1,23 @@ +# Copyright 2018 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. + +# bazelrc file for running gRPC tests on Kokoro using Foundry + +import %workspace%/tools/remote_build/rbe_common.bazelrc + +build --jobs=200 +build --test_output=errors +build --keep_going +build --remote_accept_cached=true +build --remote_local_fallback=true diff --git a/tools/remote_build/manual.bazelrc b/tools/remote_build/manual.bazelrc new file mode 100644 index 0000000000..d67bafedf3 --- /dev/null +++ b/tools/remote_build/manual.bazelrc @@ -0,0 +1,42 @@ +# Copyright 2018 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. + +# bazelrc file for running gRPC tests with Foundry (remote build execution) +# manually from developer's workstation + +import %workspace%/tools/remote_build/rbe_common.bazelrc + +build --remote_cache=remotebuildexecution.googleapis.com +build --remote_executor=remotebuildexecution.googleapis.com +build --tls_enabled=true + +# Enable authentication. This will pick up application default credentials by +# default. You can use --auth_credentials=some_file.json to use a service +# account credential instead. +# How to setup credentials: +# See https://cloud.google.com/remote-build-execution/docs/getting-started#set_credentials +build --auth_enabled=true + +# Set flags for uploading to BES in order to view results in the Bazel Build +# Results UI. +build --bes_backend="buildeventservice.googleapis.com" +build --bes_timeout=60s +build --bes_results_url="https://source.cloud.google.com/results/invocations/" +build --project_id=grpc-testing + +build --jobs=100 + +# TODO(jtattermusch): this should be part of the common config +# but currently sanitizers use different test_timeout values +build --test_timeout=300,450,1200,3600 diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc new file mode 100644 index 0000000000..cdf492a2cc --- /dev/null +++ b/tools/remote_build/rbe_common.bazelrc @@ -0,0 +1,88 @@ +# Copyright 2018 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. + +# bazelrc with Foundry setting common to both manual run and runs started by Kokoro +# see https://github.com/bazelbuild/bazel-toolchains/tree/master/bazelrc +# for examples and more documentation + +startup --host_jvm_args=-Dbazel.DigestFunction=SHA256 + +build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain +build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default +# Use custom execution platforms defined in third_party/toolchains +build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604 +build --host_platform=//third_party/toolchains:rbe_ubuntu1604 +build --platforms=//third_party/toolchains:rbe_ubuntu1604 + +build --spawn_strategy=remote +build --strategy=Javac=remote +build --strategy=Closure=remote +build --genrule_strategy=remote +build --remote_timeout=3600 + +build --remote_instance_name=projects/grpc-testing/instances/default_instance + +build --verbose_failures=true + +build --experimental_strict_action_env=true +build --action_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 + +# don't use port server +build --define GRPC_PORT_ISOLATED_RUNTIME=1 +# without verbose gRPC logs the test outputs are not very useful +test --test_env=GRPC_VERBOSITY=debug + +# address sanitizer: most settings are already in %workspace%/.bazelrc +# we only need a few additional ones that are Foundry specific +build:asan --copt=-gmlt +# TODO(jtattermusch): use more reasonable test timeout +build:asan --test_timeout=3600 +build:asan --test_tag_filters=-qps_json_driver,-json_run_localhost +# TODO: revisit these from bazel.rc: +#build:asan --copt=-O0 +#build:asan --copt=-fno-omit-frame-pointer +#build:asan --copt=-DGPR_NO_DIRECT_SYSCALLS +#build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always +#build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1 + +# TODO(jtattermusch): align msan settings from tools/bazel.rc +# and grpc_msan_on_foundry.sh + +# thread sanitizer: most settings are already in %workspace%/.bazelrc +# we only need a few additional ones that are Foundry specific +build:tsan --copt=-gmlt +# TODO(jtattermusch): use more reasonable test timeout +build:tsan --test_timeout=3600 +build:tsan --test_tag_filters=-qps_json_driver,-json_run_localhost +# TODO: revisit these from bazel.rc: +#build:tsan --copt=-fno-omit-frame-pointer +#build:tsan --copt=-DGPR_NO_DIRECT_SYSCALLS +#build:tsan --copt=-DGRPC_TSAN + +# undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc +# we only need a few additional ones that are Foundry specific +build:ubsan --copt=-gmlt +# TODO(jtattermusch): use more reasonable test timeout +build:ubsan --test_timeout=3600 +# TODO: revisit these from bazel.rc: +#build:ubsan --copt=-fno-omit-frame-pointer +#build:ubsan --copt=-DGRPC_UBSAN +#build:ubsan --copt=-DNDEBUG +#build:ubsan --copt=-fno-sanitize=function,vptr +# TODO: revisit this from grpc_ubsan_on_foundry.sh: +#--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.15.0/ubsan:toolchain +# TODO(jtattermusch): remove this once Foundry adds the env to the docker image. +# ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work +# and we get test failures. +build:ubsan --action_env=UBSAN_SYMBOLIZER_PATH=/usr/local/bin/llvm-symbolizer diff --git a/tools/run_tests/generated/lb_interop_test_scenarios.json b/tools/run_tests/generated/lb_interop_test_scenarios.json new file mode 100644 index 0000000000..4f956c568a --- /dev/null +++ b/tools/run_tests/generated/lb_interop_test_scenarios.json @@ -0,0 +1,1167 @@ + +[ + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_insecure", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_alts", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_tls", + "skip_langs": [], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_nx_domain_google_default_credentials", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_insecure", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_alts", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_tls", + "skip_langs": [], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [], + "cause_no_error_no_data_for_balancer_a_record": true, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "no_balancer_because_lb_a_record_returns_no_data_google_default_credentials", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_insecure_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_insecure_short_stream_False", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_referred_to_backend_fallback_broken_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_insecure_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + }, + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_insecure_short_stream_False", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + }, + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + }, + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_backends_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_falls_back_because_no_backends_insecure_short_stream_True", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "client_falls_back_because_no_backends_alts_short_stream_True", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_tls_short_stream_True", + "skip_langs": [ + "go", + "java", + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_google_default_credentials_short_stream_True", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "insecure" + } + ], + "name": "client_falls_back_because_no_backends_insecure_short_stream_False", + "skip_langs": [ + "go", + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "client_falls_back_because_no_backends_alts_short_stream_False", + "skip_langs": [ + "go", + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_tls_short_stream_False", + "skip_langs": [ + "go", + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_no_backends_google_default_credentials_short_stream_False", + "skip_langs": [ + "go", + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "alts" + } + ], + "name": "client_falls_back_because_balancer_connection_broken_alts", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_balancer_connection_broken_tls", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [ + { + "transport_sec": "tls" + } + ], + "name": "client_falls_back_because_balancer_connection_broken_google_default_credentials", + "skip_langs": [], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + }, + { + "short_stream": true, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_insecure_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_alts_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + }, + { + "short_stream": true, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_tls_short_stream_True", + "skip_langs": [ + "java", + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + }, + { + "short_stream": true, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_google_default_credentials_short_stream_True", + "skip_langs": [ + "java" + ], + "transport_sec": "google_default_credentials" + }, + { + "backend_configs": [ + { + "transport_sec": "insecure" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + }, + { + "short_stream": false, + "transport_sec": "insecure" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_insecure_short_stream_False", + "skip_langs": [], + "transport_sec": "insecure" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_alts_short_stream_False", + "skip_langs": [], + "transport_sec": "alts" + }, + { + "backend_configs": [ + { + "transport_sec": "tls" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + }, + { + "short_stream": false, + "transport_sec": "tls" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_tls_short_stream_False", + "skip_langs": [ + "java" + ], + "transport_sec": "tls" + }, + { + "backend_configs": [ + { + "transport_sec": "alts" + } + ], + "balancer_configs": [ + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + }, + { + "short_stream": false, + "transport_sec": "alts" + } + ], + "cause_no_error_no_data_for_balancer_a_record": false, + "fallback_configs": [], + "name": "client_referred_to_backend_multiple_balancers_google_default_credentials_short_stream_False", + "skip_langs": [], + "transport_sec": "google_default_credentials" + } +] diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 6e1eb6e3c0..3a442864e8 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -6557,24 +6557,6 @@ }, { "deps": [ - "end2end_nosec_tests", - "gpr", - "gpr_test_util", - "grpc_test_util_unsecure", - "grpc_unsecure" - ], - "headers": [], - "is_filegroup": false, - "language": "c", - "name": "inproc_nosec_test", - "src": [ - "test/core/end2end/fixtures/inproc.cc" - ], - "third_party": false, - "type": "target" - }, - { - "deps": [ "gpr", "gpr_test_util", "grpc++_test_config", @@ -7047,6 +7029,7 @@ "grpc_lb_policy_grpclb_secure", "grpc_lb_policy_pick_first", "grpc_lb_policy_round_robin", + "grpc_lb_policy_xds_secure", "grpc_max_age_filter", "grpc_message_size_filter", "grpc_resolver_dns_ares", @@ -7140,6 +7123,7 @@ "grpc_lb_policy_grpclb", "grpc_lb_policy_pick_first", "grpc_lb_policy_round_robin", + "grpc_lb_policy_xds", "grpc_max_age_filter", "grpc_message_size_filter", "grpc_resolver_dns_ares", @@ -9982,7 +9966,8 @@ "deps": [ "gpr", "grpc_base", - "grpc_deadline_filter" + "grpc_deadline_filter", + "health_proto" ], "headers": [ "src/core/ext/filters/client_channel/backup_poller.h", @@ -9990,6 +9975,7 @@ "src/core/ext/filters/client_channel/client_channel_channelz.h", "src/core/ext/filters/client_channel/client_channel_factory.h", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.h", "src/core/ext/filters/client_channel/lb_policy.h", @@ -10023,6 +10009,8 @@ "src/core/ext/filters/client_channel/client_channel_plugin.cc", "src/core/ext/filters/client_channel/connector.cc", "src/core/ext/filters/client_channel/connector.h", + "src/core/ext/filters/client_channel/health/health_check_client.cc", + "src/core/ext/filters/client_channel/health/health_check_client.h", "src/core/ext/filters/client_channel/http_connect_handshaker.cc", "src/core/ext/filters/client_channel/http_connect_handshaker.h", "src/core/ext/filters/client_channel/http_proxy.cc", @@ -10137,6 +10125,7 @@ "grpc_base", "grpc_client_channel", "grpc_resolver_fake", + "grpclb_proto", "nanopb" ], "headers": [ @@ -10144,10 +10133,7 @@ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" ], "is_filegroup": true, "language": "c", @@ -10162,13 +10148,7 @@ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" ], "third_party": false, "type": "filegroup" @@ -10180,6 +10160,7 @@ "grpc_client_channel", "grpc_resolver_fake", "grpc_secure", + "grpclb_proto", "nanopb" ], "headers": [ @@ -10187,10 +10168,7 @@ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" ], "is_filegroup": true, "language": "c", @@ -10205,13 +10183,7 @@ "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" + "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h" ], "third_party": false, "type": "filegroup" @@ -10256,38 +10228,27 @@ "grpc_base", "grpc_client_channel", "grpc_resolver_fake", + "grpclb_proto", "nanopb" ], "headers": [ - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", - "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h" ], "is_filegroup": true, "language": "c", "name": "grpc_lb_policy_xds", "src": [ - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h" ], "third_party": false, "type": "filegroup" @@ -10299,38 +10260,27 @@ "grpc_client_channel", "grpc_resolver_fake", "grpc_secure", + "grpclb_proto", "nanopb" ], "headers": [ - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", - "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h" ], "is_filegroup": true, "language": "c", "name": "grpc_lb_policy_xds_secure", "src": [ - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", - "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/client_load_reporting_filter.h", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/load_balancer_api.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h", "src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc", "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.cc", - "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h" + "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc", + "src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h" ], "third_party": false, "type": "filegroup" @@ -10480,6 +10430,7 @@ "headers": [ "include/grpc/grpc_security.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/lib/security/context/security_context.h", "src/core/lib/security/credentials/alts/alts_credentials.h", "src/core/lib/security/credentials/composite/composite_credentials.h", @@ -10494,11 +10445,14 @@ "src/core/lib/security/credentials/oauth2/oauth2_credentials.h", "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.h", - "src/core/lib/security/security_connector/alts_security_connector.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_linux.h", - "src/core/lib/security/security_connector/local_security_connector.h", + "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/secure_endpoint.h", "src/core/lib/security/transport/security_handshaker.h", @@ -10512,6 +10466,7 @@ "src": [ "include/grpc/grpc_security.h", "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h", + "src/core/ext/filters/client_channel/lb_policy/xds/xds.h", "src/core/lib/http/httpcli_security_connector.cc", "src/core/lib/security/context/security_context.cc", "src/core/lib/security/context/security_context.h", @@ -10543,16 +10498,22 @@ "src/core/lib/security/credentials/plugin/plugin_credentials.h", "src/core/lib/security/credentials/ssl/ssl_credentials.cc", "src/core/lib/security/credentials/ssl/ssl_credentials.h", - "src/core/lib/security/security_connector/alts_security_connector.cc", - "src/core/lib/security/security_connector/alts_security_connector.h", + "src/core/lib/security/security_connector/alts/alts_security_connector.cc", + "src/core/lib/security/security_connector/alts/alts_security_connector.h", + "src/core/lib/security/security_connector/fake/fake_security_connector.cc", + "src/core/lib/security/security_connector/fake/fake_security_connector.h", "src/core/lib/security/security_connector/load_system_roots.h", "src/core/lib/security/security_connector/load_system_roots_fallback.cc", "src/core/lib/security/security_connector/load_system_roots_linux.cc", "src/core/lib/security/security_connector/load_system_roots_linux.h", - "src/core/lib/security/security_connector/local_security_connector.cc", - "src/core/lib/security/security_connector/local_security_connector.h", + "src/core/lib/security/security_connector/local/local_security_connector.cc", + "src/core/lib/security/security_connector/local/local_security_connector.h", "src/core/lib/security/security_connector/security_connector.cc", "src/core/lib/security/security_connector/security_connector.h", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.cc", + "src/core/lib/security/security_connector/ssl/ssl_security_connector.h", + "src/core/lib/security/security_connector/ssl_utils.cc", + "src/core/lib/security/security_connector/ssl_utils.h", "src/core/lib/security/transport/auth_filters.h", "src/core/lib/security/transport/client_auth_filter.cc", "src/core/lib/security/transport/secure_endpoint.cc", @@ -11008,6 +10969,46 @@ }, { "deps": [ + "nanopb" + ], + "headers": [ + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" + ], + "is_filegroup": true, + "language": "c", + "name": "grpclb_proto", + "src": [ + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/duration.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/google/protobuf/timestamp.pb.h", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", + "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" + ], + "third_party": false, + "type": "filegroup" + }, + { + "deps": [ + "nanopb" + ], + "headers": [ + "src/core/ext/filters/client_channel/health/health.pb.h" + ], + "is_filegroup": true, + "language": "c", + "name": "health_proto", + "src": [ + "src/core/ext/filters/client_channel/health/health.pb.c", + "src/core/ext/filters/client_channel/health/health.pb.h" + ], + "third_party": false, + "type": "filegroup" + }, + { + "deps": [ "nanopb_headers" ], "headers": [], @@ -11300,6 +11301,7 @@ "grpc++_codegen_base", "grpc_base_headers", "grpc_transport_inproc_headers", + "health_proto", "nanopb_headers" ], "headers": [ @@ -11400,7 +11402,6 @@ "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/health/default_health_check_service.h", - "src/cpp/server/health/health.pb.h", "src/cpp/server/thread_pool_interface.h", "src/cpp/thread_manager/thread_manager.h" ], @@ -11525,8 +11526,6 @@ "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/health/default_health_check_service.cc", "src/cpp/server/health/default_health_check_service.h", - "src/cpp/server/health/health.pb.c", - "src/cpp/server/health/health.pb.h", "src/cpp/server/health/health_check_service.cc", "src/cpp/server/health/health_check_service_server_builder_option.cc", "src/cpp/server/server_builder.cc", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 4ab410a4a1..145d2526e8 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -56266,949 +56266,6 @@ }, { "args": [ - "authority_not_supported" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "binary_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_accept" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_client_done" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_after_round_trip" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_before_invoke" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_in_a_vacuum" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "cancel_with_status" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "channelz" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "empty_batch" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_call_init_fails" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_causes_close" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_latency" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "filter_status_code" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "high_initial_seqno" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "hpack_size" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "idempotent_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "invoke_large_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "large_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "max_message_length" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "negative_deadline" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "network_status_change" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_error_on_hotpath" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_logging" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "no_op" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "ping_pong_streaming" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "registered_call" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_flags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "request_with_payload" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "resource_quota_server" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "server_finishes_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "shutdown_finishes_calls" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "shutdown_finishes_tags" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_cacheable_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "simple_request" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "streaming_error_response" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 0.1, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "trailing_metadata" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ - "workaround_cronet_compression" - ], - "ci_platforms": [ - "windows", - "linux", - "mac", - "posix" - ], - "cpu_cost": 1.0, - "exclude_configs": [], - "exclude_iomgrs": [], - "flaky": false, - "language": "c", - "name": "inproc_nosec_test", - "platforms": [ - "windows", - "linux", - "mac", - "posix" - ] - }, - { - "args": [ "--scenarios_json", "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_1channel_100rpcs_1MB\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"security_params\": null, \"threads_per_cq\": 0, \"server_type\": \"ASYNC_SERVER\"}, \"num_clients\": 1, \"client_config\": {\"security_params\": null, \"channel_args\": [{\"str_value\": \"throughput\", \"name\": \"grpc.optimization_target\"}], \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"payload_config\": {\"simple_params\": {\"resp_size\": 1048576, \"req_size\": 1048576}}, \"client_channels\": 1, \"threads_per_cq\": 0, \"load_params\": {\"closed_loop\": {}}, \"client_type\": \"ASYNC_CLIENT\", \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}}]}" ], diff --git a/tools/run_tests/lb_interop_tests/gen_build_yaml.py b/tools/run_tests/lb_interop_tests/gen_build_yaml.py new file mode 100755 index 0000000000..b7d655b75b --- /dev/null +++ b/tools/run_tests/lb_interop_tests/gen_build_yaml.py @@ -0,0 +1,347 @@ +#!/usr/bin/env python2.7 +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Generates the appropriate JSON data for LB interop test scenarios.""" + +import json +import os +import yaml + +all_scenarios = [] + +# TODO(https://github.com/grpc/grpc-go/issues/2347): enable +# client_falls_back_because_no_backends_* scenarios for Java/Go. + +# TODO(https://github.com/grpc/grpc-java/issues/4887): enable +# *short_stream* scenarios for Java. + +# TODO(https://github.com/grpc/grpc-java/issues/4912): enable +# Java TLS tests involving TLS to the balancer. + + +def server_sec(transport_sec): + if transport_sec == 'google_default_credentials': + return 'alts', 'alts', 'tls' + return transport_sec, transport_sec, transport_sec + + +def generate_no_balancer_because_lb_a_record_returns_nx_domain(): + all_configs = [] + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + config = { + 'name': + 'no_balancer_because_lb_a_record_returns_nx_domain_%s' % + transport_sec, + 'skip_langs': [], + 'transport_sec': + transport_sec, + 'balancer_configs': [], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_no_balancer_because_lb_a_record_returns_nx_domain() + + +def generate_no_balancer_because_lb_a_record_returns_no_data(): + all_configs = [] + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + config = { + 'name': + 'no_balancer_because_lb_a_record_returns_no_data_%s' % + transport_sec, + 'skip_langs': [], + 'transport_sec': + transport_sec, + 'balancer_configs': [], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + True, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_no_balancer_because_lb_a_record_returns_no_data() + + +def generate_client_referred_to_backend(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_%s_short_stream_%s' % + (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [{ + 'transport_sec': backend_sec, + }], + 'fallback_configs': [], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend() + + +def generate_client_referred_to_backend_fallback_broken(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in ['alts', 'tls', 'google_default_credentials']: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_fallback_broken_%s_short_stream_%s' + % (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [{ + 'transport_sec': backend_sec, + }], + 'fallback_configs': [{ + 'transport_sec': 'insecure', + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend_fallback_broken() + + +def generate_client_referred_to_backend_multiple_backends(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_multiple_backends_%s_short_stream_%s' + % (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [{ + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }, { + 'transport_sec': backend_sec, + }], + 'fallback_configs': [], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend_multiple_backends() + + +def generate_client_falls_back_because_no_backends(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = ['go', 'java'] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_falls_back_because_no_backends_%s_short_stream_%s' % + (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_falls_back_because_no_backends() + + +def generate_client_falls_back_because_balancer_connection_broken(): + all_configs = [] + for transport_sec in ['alts', 'tls', 'google_default_credentials']: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs = ['java'] + config = { + 'name': + 'client_falls_back_because_balancer_connection_broken_%s' % + transport_sec, + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [{ + 'transport_sec': 'insecure', + 'short_stream': False, + }], + 'backend_configs': [], + 'fallback_configs': [{ + 'transport_sec': fallback_sec, + }], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_falls_back_because_balancer_connection_broken() + + +def generate_client_referred_to_backend_multiple_balancers(): + all_configs = [] + for balancer_short_stream in [True, False]: + for transport_sec in [ + 'insecure', 'alts', 'tls', 'google_default_credentials' + ]: + balancer_sec, backend_sec, fallback_sec = server_sec(transport_sec) + skip_langs = [] + if transport_sec == 'tls': + skip_langs += ['java'] + if balancer_short_stream: + skip_langs += ['java'] + config = { + 'name': + 'client_referred_to_backend_multiple_balancers_%s_short_stream_%s' + % (transport_sec, balancer_short_stream), + 'skip_langs': + skip_langs, + 'transport_sec': + transport_sec, + 'balancer_configs': [ + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + { + 'transport_sec': balancer_sec, + 'short_stream': balancer_short_stream, + }, + ], + 'backend_configs': [ + { + 'transport_sec': backend_sec, + }, + ], + 'fallback_configs': [], + 'cause_no_error_no_data_for_balancer_a_record': + False, + } + all_configs.append(config) + return all_configs + + +all_scenarios += generate_client_referred_to_backend_multiple_balancers() + +print(yaml.dump({ + 'lb_interop_test_scenarios': all_scenarios, +})) diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 9e6e72d97b..ab6bffdc34 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -25,10 +25,16 @@ CONFIG=${CONFIG:-opt} # TODO(jtattermusch): C++ worker and driver are not buildable on Windows yet if [ "$OSTYPE" != "msys" ] then - # TODO(jtattermusch): not embedding OpenSSL breaks the C# build because - # grpc_csharp_ext needs OpenSSL embedded and some intermediate files from - # this build will be reused. - make CONFIG="${CONFIG}" EMBED_OPENSSL=true EMBED_ZLIB=true qps_worker qps_json_driver -j8 + # build C++ with cmake as building with "make" disables boringssl assembly + # optimizations that can have huge impact on secure channel throughput. + mkdir -p cmake/build + cd cmake/build + cmake -DgRPC_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Release ../.. + make qps_worker qps_json_driver -j8 + cd ../.. + # unbreak subsequent make builds by restoring zconf.h (previously renamed by cmake build) + # See https://github.com/grpc/grpc/issues/11581 + (cd third_party/zlib; git checkout zconf.h) fi PHP_ALREADY_BUILT="" diff --git a/tools/run_tests/performance/run_qps_driver.sh b/tools/run_tests/performance/run_qps_driver.sh index 2d9e310dec..47a03db026 100755 --- a/tools/run_tests/performance/run_qps_driver.sh +++ b/tools/run_tests/performance/run_qps_driver.sh @@ -17,7 +17,7 @@ set -ex cd "$(dirname "$0")/../../.." -bins/opt/qps_json_driver "$@" +cmake/build/qps_json_driver "$@" if [ "$BQ_RESULT_TABLE" != "" ] then diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 2e78bd07fb..481918c52e 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -231,7 +231,7 @@ class CXXLanguage: self.safename = 'cxx' def worker_cmdline(self): - return ['bins/opt/qps_worker'] + return ['cmake/build/qps_worker'] def worker_port_offset(self): return 0 @@ -250,7 +250,7 @@ class CXXLanguage: channels=1, num_clients=1, secure=False, - categories=[SMOKETEST] + [INPROC] + [SCALABLE]) + categories=[INPROC] + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_streaming_from_client_1channel_1MB', @@ -280,12 +280,12 @@ class CXXLanguage: secure=False, async_server_threads=16, server_threads_per_cq=1, - categories=[SMOKETEST] + [SCALABLE]) + categories=[SCALABLE]) for secure in [True, False]: secstr = 'secure' if secure else 'insecure' - smoketest_categories = ([SMOKETEST] - if secure else [INPROC]) + [SCALABLE] + smoketest_categories = ([SMOKETEST] if secure else []) + inproc_categories = ([INPROC] if not secure else []) yield _ping_pong_scenario( 'cpp_generic_async_streaming_ping_pong_%s' % secstr, @@ -295,7 +295,8 @@ class CXXLanguage: use_generic_payload=True, async_server_threads=1, secure=secure, - categories=smoketest_categories) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_unconstrained_%s' % secstr, @@ -306,7 +307,8 @@ class CXXLanguage: use_generic_payload=True, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) for mps in geometric_progression(1, 20, 10): yield _ping_pong_scenario( @@ -320,7 +322,8 @@ class CXXLanguage: secure=secure, messages_per_stream=mps, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) for mps in geometric_progression(1, 200, math.sqrt(10)): yield _ping_pong_scenario( @@ -347,7 +350,7 @@ class CXXLanguage: use_generic_payload=True, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE], + categories=inproc_categories + [SCALABLE], channels=1, outstanding=100) @@ -363,7 +366,7 @@ class CXXLanguage: use_generic_payload=True, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_unconstrained_1cq_%s' % secstr, @@ -375,7 +378,8 @@ class CXXLanguage: secure=secure, client_threads_per_cq=1000000, server_threads_per_cq=1000000, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_unconstrained_2waysharedcq_%s' @@ -388,7 +392,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=2, server_threads_per_cq=2, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_streaming_qps_unconstrained_1cq_%s' % @@ -400,7 +404,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=1000000, server_threads_per_cq=1000000, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_streaming_qps_unconstrained_2waysharedcq_%s' @@ -412,7 +416,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=2, server_threads_per_cq=2, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_unary_qps_unconstrained_1cq_%s' % secstr, @@ -423,7 +427,8 @@ class CXXLanguage: secure=secure, client_threads_per_cq=1000000, server_threads_per_cq=1000000, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_unary_qps_unconstrained_2waysharedcq_%s' % @@ -435,7 +440,7 @@ class CXXLanguage: secure=secure, client_threads_per_cq=2, server_threads_per_cq=2, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_generic_async_streaming_qps_one_server_core_%s' % secstr, @@ -457,7 +462,8 @@ class CXXLanguage: unconstrained_client='async', secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE], + categories=smoketest_categories + inproc_categories + + [SCALABLE], excluded_poll_engines=['poll-cv']) yield _ping_pong_scenario( @@ -472,7 +478,7 @@ class CXXLanguage: resp_size=8 * 1024 * 1024, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) yield _ping_pong_scenario( 'cpp_protobuf_async_client_sync_server_streaming_qps_unconstrained_%s' @@ -483,7 +489,8 @@ class CXXLanguage: unconstrained_client='async', secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE], + categories=smoketest_categories + inproc_categories + + [SCALABLE], excluded_poll_engines=['poll-cv']) yield _ping_pong_scenario( @@ -495,7 +502,8 @@ class CXXLanguage: resp_size=1024 * 1024, secure=secure, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=smoketest_categories + inproc_categories + + [SCALABLE]) for rpc_type in [ 'unary', 'streaming', 'streaming_from_client', @@ -538,7 +546,7 @@ class CXXLanguage: minimal_stack=not secure, server_threads_per_cq=3, client_threads_per_cq=3, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) # TODO(vjpai): Re-enable this test. It has a lot of timeouts # and hasn't yet been conclusively identified as a test failure @@ -565,7 +573,7 @@ class CXXLanguage: secure=secure, messages_per_stream=mps, minimal_stack=not secure, - categories=smoketest_categories + [SCALABLE]) + categories=inproc_categories + [SCALABLE]) for mps in geometric_progression(1, 200, math.sqrt(10)): yield _ping_pong_scenario( diff --git a/tools/run_tests/python_utils/dockerjob.py b/tools/run_tests/python_utils/dockerjob.py index 2d22dc13a0..5260f7b44b 100755 --- a/tools/run_tests/python_utils/dockerjob.py +++ b/tools/run_tests/python_utils/dockerjob.py @@ -20,6 +20,7 @@ import time import uuid import os import subprocess +import json import jobset @@ -54,6 +55,25 @@ def docker_mapped_port(cid, port, timeout_seconds=15): cid)) +def docker_ip_address(cid, timeout_seconds=15): + """Get port mapped to internal given internal port for given container.""" + started = time.time() + while time.time() - started < timeout_seconds: + cmd = 'docker inspect %s' % cid + try: + output = subprocess.check_output(cmd, stderr=_DEVNULL, shell=True) + json_info = json.loads(output) + assert len(json_info) == 1 + out = json_info[0]['NetworkSettings']['IPAddress'] + if not out: + continue + return out + except subprocess.CalledProcessError as e: + pass + raise Exception( + 'Non-retryable error: Failed to get ip address of container %s.' % cid) + + def wait_for_healthy(cid, shortname, timeout_seconds): """Wait timeout_seconds for the container to become healthy""" started = time.time() @@ -74,10 +94,10 @@ def wait_for_healthy(cid, shortname, timeout_seconds): (shortname, cid)) -def finish_jobs(jobs): +def finish_jobs(jobs, suppress_failure=True): """Kills given docker containers and waits for corresponding jobs to finish""" for job in jobs: - job.kill(suppress_failure=True) + job.kill(suppress_failure=suppress_failure) while any(job.is_running() for job in jobs): time.sleep(1) @@ -120,6 +140,9 @@ class DockerJob: def mapped_port(self, port): return docker_mapped_port(self._container_name, port) + def ip_address(self): + return docker_ip_address(self._container_name) + def wait_for_healthy(self, timeout_seconds): wait_for_healthy(self._container_name, self._spec.shortname, timeout_seconds) diff --git a/tools/run_tests/run_grpclb_interop_tests.py b/tools/run_tests/run_grpclb_interop_tests.py new file mode 100755 index 0000000000..3bfbcecf06 --- /dev/null +++ b/tools/run_tests/run_grpclb_interop_tests.py @@ -0,0 +1,609 @@ +#!/usr/bin/env python +# Copyright 2015 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Run interop (cross-language) tests in parallel.""" + +from __future__ import print_function + +import argparse +import atexit +import itertools +import json +import multiprocessing +import os +import re +import subprocess +import sys +import tempfile +import time +import uuid +import six +import traceback + +import python_utils.dockerjob as dockerjob +import python_utils.jobset as jobset +import python_utils.report_utils as report_utils + +# Docker doesn't clean up after itself, so we do it on exit. +atexit.register(lambda: subprocess.call(['stty', 'echo'])) + +ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..')) +os.chdir(ROOT) + +_FALLBACK_SERVER_PORT = 443 +_BALANCER_SERVER_PORT = 12000 +_BACKEND_SERVER_PORT = 8080 + +_TEST_TIMEOUT = 30 + +_FAKE_SERVERS_SAFENAME = 'fake_servers' + +# Use a name that's verified by the test certs +_SERVICE_NAME = 'server.test.google.fr' + + +class CXXLanguage: + + def __init__(self): + self.client_cwd = '/var/local/git/grpc' + self.safename = 'cxx' + + def client_cmd(self, args): + return ['bins/opt/interop_client'] + args + + def global_env(self): + # 1) Set c-ares as the resolver, to + # enable grpclb. + # 2) Turn on verbose logging. + # 3) Set the ROOTS_PATH env variable + # to the test CA in order for + # GoogleDefaultCredentials to be + # able to use the test CA. + return { + 'GRPC_DNS_RESOLVER': + 'ares', + 'GRPC_VERBOSITY': + 'DEBUG', + 'GRPC_TRACE': + 'client_channel,glb', + 'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH': + '/var/local/git/grpc/src/core/tsi/test_creds/ca.pem', + } + + def __str__(self): + return 'c++' + + +class JavaLanguage: + + def __init__(self): + self.client_cwd = '/var/local/git/grpc-java' + self.safename = str(self) + + def client_cmd(self, args): + # Take necessary steps to import our test CA into + # the set of test CA's that the Java runtime of the + # docker container will pick up, so that + # Java GoogleDefaultCreds can use it. + pem_to_der_cmd = ('openssl x509 -outform der ' + '-in /external_mount/src/core/tsi/test_creds/ca.pem ' + '-out /tmp/test_ca.der') + keystore_import_cmd = ( + 'keytool -import ' + '-keystore /usr/lib/jvm/java-8-oracle/jre/lib/security/cacerts ' + '-file /tmp/test_ca.der ' + '-deststorepass changeit ' + '-noprompt') + return [ + 'bash', '-c', ('{pem_to_der_cmd} && ' + '{keystore_import_cmd} && ' + './run-test-client.sh {java_client_args}').format( + pem_to_der_cmd=pem_to_der_cmd, + keystore_import_cmd=keystore_import_cmd, + java_client_args=' '.join(args)) + ] + + def global_env(self): + # 1) Enable grpclb + # 2) Enable verbose logging + return { + 'JAVA_OPTS': + ('-Dio.grpc.internal.DnsNameResolverProvider.enable_grpclb=true ' + '-Djava.util.logging.config.file=/var/local/grpc_java_logging/logconf.txt' + ) + } + + def __str__(self): + return 'java' + + +class GoLanguage: + + def __init__(self): + self.client_cwd = '/go/src/google.golang.org/grpc/interop/client' + self.safename = str(self) + + def client_cmd(self, args): + # Copy the test CA file into the path that + # the Go runtime in the docker container will use, so + # that Go's GoogleDefaultCredentials can use it. + # See https://golang.org/src/crypto/x509/root_linux.go. + return [ + 'bash', '-c', ('cp /external_mount/src/core/tsi/test_creds/ca.pem ' + '/etc/ssl/certs/ca-certificates.crt && ' + '/go/bin/client {go_client_args}' + ).format(go_client_args=' '.join(args)) + ] + + def global_env(self): + return { + 'GRPC_GO_LOG_VERBOSITY_LEVEL': '3', + 'GRPC_GO_LOG_SEVERITY_LEVEL': 'INFO' + } + + def __str__(self): + return 'go' + + +_LANGUAGES = { + 'c++': CXXLanguage(), + 'go': GoLanguage(), + 'java': JavaLanguage(), +} + + +def docker_run_cmdline(cmdline, image, docker_args, cwd, environ=None): + """Wraps given cmdline array to create 'docker run' cmdline from it.""" + # turn environ into -e docker args + docker_cmdline = 'docker run -i --rm=true'.split() + if environ: + for k, v in environ.items(): + docker_cmdline += ['-e', '%s=%s' % (k, v)] + return docker_cmdline + ['-w', cwd] + docker_args + [image] + cmdline + + +def _job_kill_handler(job): + assert job._spec.container_name + dockerjob.docker_kill(job._spec.container_name) + + +def transport_security_to_args(transport_security): + args = [] + if transport_security == 'tls': + args += ['--use_tls=true'] + elif transport_security == 'alts': + args += ['--use_tls=false', '--use_alts=true'] + elif transport_security == 'insecure': + args += ['--use_tls=false'] + elif transport_security == 'google_default_credentials': + args += ['--custom_credentials_type=google_default_credentials'] + else: + print('Invalid transport security option.') + sys.exit(1) + return args + + +def lb_client_interop_jobspec(language, + dns_server_ip, + docker_image, + transport_security='tls'): + """Runs a gRPC client under test in a docker container""" + interop_only_options = [ + '--server_host=%s' % _SERVICE_NAME, + '--server_port=%d' % _FALLBACK_SERVER_PORT + ] + transport_security_to_args(transport_security) + # Don't set the server host override in any client; + # Go and Java default to no override. + # We're using a DNS server so there's no need. + if language.safename == 'c++': + interop_only_options += ['--server_host_override=""'] + # Don't set --use_test_ca; we're configuring + # clients to use test CA's via alternate means. + interop_only_options += ['--use_test_ca=false'] + client_args = language.client_cmd(interop_only_options) + container_name = dockerjob.random_name( + 'lb_interop_client_%s' % language.safename) + docker_cmdline = docker_run_cmdline( + client_args, + environ=language.global_env(), + image=docker_image, + cwd=language.client_cwd, + docker_args=[ + '--dns=%s' % dns_server_ip, + '--net=host', + '--name=%s' % container_name, + '-v', + '{grpc_grpc_root_dir}:/external_mount:ro'.format( + grpc_grpc_root_dir=ROOT), + ]) + jobset.message( + 'IDLE', + 'docker_cmdline:\b|%s|' % ' '.join(docker_cmdline), + do_newline=True) + test_job = jobset.JobSpec( + cmdline=docker_cmdline, + shortname=('lb_interop_client:%s' % language), + timeout_seconds=_TEST_TIMEOUT, + kill_handler=_job_kill_handler) + test_job.container_name = container_name + return test_job + + +def fallback_server_jobspec(transport_security, shortname): + """Create jobspec for running a fallback server""" + cmdline = [ + 'bin/server', + '--port=%d' % _FALLBACK_SERVER_PORT, + ] + transport_security_to_args(transport_security) + return grpc_server_in_docker_jobspec( + server_cmdline=cmdline, shortname=shortname) + + +def backend_server_jobspec(transport_security, shortname): + """Create jobspec for running a backend server""" + cmdline = [ + 'bin/server', + '--port=%d' % _BACKEND_SERVER_PORT, + ] + transport_security_to_args(transport_security) + return grpc_server_in_docker_jobspec( + server_cmdline=cmdline, shortname=shortname) + + +def grpclb_jobspec(transport_security, short_stream, backend_addrs, shortname): + """Create jobspec for running a balancer server""" + cmdline = [ + 'bin/fake_grpclb', + '--backend_addrs=%s' % ','.join(backend_addrs), + '--port=%d' % _BALANCER_SERVER_PORT, + '--short_stream=%s' % short_stream, + '--service_name=%s' % _SERVICE_NAME, + ] + transport_security_to_args(transport_security) + return grpc_server_in_docker_jobspec( + server_cmdline=cmdline, shortname=shortname) + + +def grpc_server_in_docker_jobspec(server_cmdline, shortname): + container_name = dockerjob.random_name(shortname) + environ = { + 'GRPC_GO_LOG_VERBOSITY_LEVEL': '3', + 'GRPC_GO_LOG_SEVERITY_LEVEL': 'INFO ', + } + docker_cmdline = docker_run_cmdline( + server_cmdline, + cwd='/go', + image=docker_images.get(_FAKE_SERVERS_SAFENAME), + environ=environ, + docker_args=['--name=%s' % container_name]) + jobset.message( + 'IDLE', + 'docker_cmdline:\b|%s|' % ' '.join(docker_cmdline), + do_newline=True) + server_job = jobset.JobSpec( + cmdline=docker_cmdline, shortname=shortname, timeout_seconds=30 * 60) + server_job.container_name = container_name + return server_job + + +def dns_server_in_docker_jobspec(grpclb_ips, fallback_ips, shortname, + cause_no_error_no_data_for_balancer_a_record): + container_name = dockerjob.random_name(shortname) + run_dns_server_cmdline = [ + 'python', + 'test/cpp/naming/utils/run_dns_server_for_lb_interop_tests.py', + '--grpclb_ips=%s' % ','.join(grpclb_ips), + '--fallback_ips=%s' % ','.join(fallback_ips), + ] + if cause_no_error_no_data_for_balancer_a_record: + run_dns_server_cmdline.append( + '--cause_no_error_no_data_for_balancer_a_record') + docker_cmdline = docker_run_cmdline( + run_dns_server_cmdline, + cwd='/var/local/git/grpc', + image=docker_images.get(_FAKE_SERVERS_SAFENAME), + docker_args=['--name=%s' % container_name]) + jobset.message( + 'IDLE', + 'docker_cmdline:\b|%s|' % ' '.join(docker_cmdline), + do_newline=True) + server_job = jobset.JobSpec( + cmdline=docker_cmdline, shortname=shortname, timeout_seconds=30 * 60) + server_job.container_name = container_name + return server_job + + +def build_interop_image_jobspec(lang_safename, basename_prefix='grpc_interop'): + """Creates jobspec for building interop docker image for a language""" + tag = '%s_%s:%s' % (basename_prefix, lang_safename, uuid.uuid4()) + env = { + 'INTEROP_IMAGE': tag, + 'BASE_NAME': '%s_%s' % (basename_prefix, lang_safename), + } + build_job = jobset.JobSpec( + cmdline=['tools/run_tests/dockerize/build_interop_image.sh'], + environ=env, + shortname='build_docker_%s' % lang_safename, + timeout_seconds=30 * 60) + build_job.tag = tag + return build_job + + +argp = argparse.ArgumentParser(description='Run interop tests.') +argp.add_argument( + '-l', + '--language', + choices=['all'] + sorted(_LANGUAGES), + nargs='+', + default=['all'], + help='Clients to run.') +argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int) +argp.add_argument( + '-s', + '--scenarios_file', + default=None, + type=str, + help='File containing test scenarios as JSON configs.') +argp.add_argument( + '-n', + '--scenario_name', + default=None, + type=str, + help=( + 'Useful for manual runs: specify the name of ' + 'the scenario to run from scenarios_file. Run all scenarios if unset.')) +argp.add_argument( + '--cxx_image_tag', + default=None, + type=str, + help=('Setting this skips the clients docker image ' + 'build step and runs the client from the named ' + 'image. Only supports running a one client language.')) +argp.add_argument( + '--go_image_tag', + default=None, + type=str, + help=('Setting this skips the clients docker image build ' + 'step and runs the client from the named image. Only ' + 'supports running a one client language.')) +argp.add_argument( + '--java_image_tag', + default=None, + type=str, + help=('Setting this skips the clients docker image build ' + 'step and runs the client from the named image. Only ' + 'supports running a one client language.')) +argp.add_argument( + '--servers_image_tag', + default=None, + type=str, + help=('Setting this skips the fake servers docker image ' + 'build step and runs the servers from the named image.')) +argp.add_argument( + '--no_skips', + default=False, + type=bool, + nargs='?', + const=True, + help=('Useful for manual runs. Setting this overrides test ' + '"skips" configured in test scenarios.')) +argp.add_argument( + '--verbose', + default=False, + type=bool, + nargs='?', + const=True, + help='Increase logging.') +args = argp.parse_args() + +docker_images = {} + +build_jobs = [] +if len(args.language) and args.language[0] == 'all': + languages = _LANGUAGES.keys() +else: + languages = args.language +for lang_name in languages: + l = _LANGUAGES[lang_name] + # First check if a pre-built image was supplied, and avoid + # rebuilding the particular docker image if so. + if lang_name == 'c++' and args.cxx_image_tag: + docker_images[str(l.safename)] = args.cxx_image_tag + elif lang_name == 'go' and args.go_image_tag: + docker_images[str(l.safename)] = args.go_image_tag + elif lang_name == 'java' and args.java_image_tag: + docker_images[str(l.safename)] = args.java_image_tag + else: + # Build the test client in docker and save the fully + # built image. + job = build_interop_image_jobspec(l.safename) + build_jobs.append(job) + docker_images[str(l.safename)] = job.tag + +# First check if a pre-built image was supplied. +if args.servers_image_tag: + docker_images[_FAKE_SERVERS_SAFENAME] = args.servers_image_tag +else: + # Build the test servers in docker and save the fully + # built image. + job = build_interop_image_jobspec( + _FAKE_SERVERS_SAFENAME, basename_prefix='lb_interop') + build_jobs.append(job) + docker_images[_FAKE_SERVERS_SAFENAME] = job.tag + +if build_jobs: + jobset.message('START', 'Building interop docker images.', do_newline=True) + print('Jobs to run: \n%s\n' % '\n'.join(str(j) for j in build_jobs)) + num_failures, _ = jobset.run( + build_jobs, newline_on_success=True, maxjobs=args.jobs) + if num_failures == 0: + jobset.message( + 'SUCCESS', 'All docker images built successfully.', do_newline=True) + else: + jobset.message( + 'FAILED', 'Failed to build interop docker images.', do_newline=True) + sys.exit(1) + + +def wait_until_dns_server_is_up(dns_server_ip): + """Probes the DNS server until it's running and safe for tests.""" + for i in range(0, 30): + print('Health check: attempt to connect to DNS server over TCP.') + tcp_connect_subprocess = subprocess.Popen([ + os.path.join(os.getcwd(), 'test/cpp/naming/utils/tcp_connect.py'), + '--server_host', dns_server_ip, '--server_port', + str(53), '--timeout', + str(1) + ]) + tcp_connect_subprocess.communicate() + if tcp_connect_subprocess.returncode == 0: + print(('Health check: attempt to make an A-record ' + 'query to DNS server.')) + dns_resolver_subprocess = subprocess.Popen( + [ + os.path.join(os.getcwd(), + 'test/cpp/naming/utils/dns_resolver.py'), + '--qname', ('health-check-local-dns-server-is-alive.' + 'resolver-tests.grpctestingexp'), + '--server_host', dns_server_ip, '--server_port', + str(53) + ], + stdout=subprocess.PIPE) + dns_resolver_stdout, _ = dns_resolver_subprocess.communicate() + if dns_resolver_subprocess.returncode == 0: + if '123.123.123.123' in dns_resolver_stdout: + print(('DNS server is up! ' + 'Successfully reached it over UDP and TCP.')) + return + time.sleep(0.1) + raise Exception(('Failed to reach DNS server over TCP and/or UDP. ' + 'Exitting without running tests.')) + + +def shortname(shortname_prefix, shortname, index): + return '%s_%s_%d' % (shortname_prefix, shortname, index) + + +def run_one_scenario(scenario_config): + jobset.message('START', 'Run scenario: %s' % scenario_config['name']) + server_jobs = {} + server_addresses = {} + suppress_server_logs = True + try: + backend_addrs = [] + fallback_ips = [] + grpclb_ips = [] + shortname_prefix = scenario_config['name'] + # Start backends + for i in xrange(len(scenario_config['backend_configs'])): + backend_config = scenario_config['backend_configs'][i] + backend_shortname = shortname(shortname_prefix, 'backend_server', i) + backend_spec = backend_server_jobspec( + backend_config['transport_sec'], backend_shortname) + backend_job = dockerjob.DockerJob(backend_spec) + server_jobs[backend_shortname] = backend_job + backend_addrs.append('%s:%d' % (backend_job.ip_address(), + _BACKEND_SERVER_PORT)) + # Start fallbacks + for i in xrange(len(scenario_config['fallback_configs'])): + fallback_config = scenario_config['fallback_configs'][i] + fallback_shortname = shortname(shortname_prefix, 'fallback_server', + i) + fallback_spec = fallback_server_jobspec( + fallback_config['transport_sec'], fallback_shortname) + fallback_job = dockerjob.DockerJob(fallback_spec) + server_jobs[fallback_shortname] = fallback_job + fallback_ips.append(fallback_job.ip_address()) + # Start balancers + for i in xrange(len(scenario_config['balancer_configs'])): + balancer_config = scenario_config['balancer_configs'][i] + grpclb_shortname = shortname(shortname_prefix, 'grpclb_server', i) + grpclb_spec = grpclb_jobspec(balancer_config['transport_sec'], + balancer_config['short_stream'], + backend_addrs, grpclb_shortname) + grpclb_job = dockerjob.DockerJob(grpclb_spec) + server_jobs[grpclb_shortname] = grpclb_job + grpclb_ips.append(grpclb_job.ip_address()) + # Start DNS server + dns_server_shortname = shortname(shortname_prefix, 'dns_server', 0) + dns_server_spec = dns_server_in_docker_jobspec( + grpclb_ips, fallback_ips, dns_server_shortname, + scenario_config['cause_no_error_no_data_for_balancer_a_record']) + dns_server_job = dockerjob.DockerJob(dns_server_spec) + server_jobs[dns_server_shortname] = dns_server_job + # Get the IP address of the docker container running the DNS server. + # The DNS server is running on port 53 of that IP address. Note we will + # point the DNS resolvers of grpc clients under test to our controlled + # DNS server by effectively modifying the /etc/resolve.conf "nameserver" + # lists of their docker containers. + dns_server_ip = dns_server_job.ip_address() + wait_until_dns_server_is_up(dns_server_ip) + # Run clients + jobs = [] + for lang_name in languages: + # Skip languages that are known to not currently + # work for this test. + if not args.no_skips and lang_name in scenario_config.get( + 'skip_langs', []): + jobset.message('IDLE', + 'Skipping scenario: %s for language: %s\n' % + (scenario_config['name'], lang_name)) + continue + lang = _LANGUAGES[lang_name] + test_job = lb_client_interop_jobspec( + lang, + dns_server_ip, + docker_image=docker_images.get(lang.safename), + transport_security=scenario_config['transport_sec']) + jobs.append(test_job) + jobset.message('IDLE', 'Jobs to run: \n%s\n' % '\n'.join( + str(job) for job in jobs)) + num_failures, resultset = jobset.run( + jobs, newline_on_success=True, maxjobs=args.jobs) + report_utils.render_junit_xml_report(resultset, 'sponge_log.xml') + if num_failures: + suppress_server_logs = False + jobset.message( + 'FAILED', + 'Scenario: %s. Some tests failed' % scenario_config['name'], + do_newline=True) + else: + jobset.message( + 'SUCCESS', + 'Scenario: %s. All tests passed' % scenario_config['name'], + do_newline=True) + return num_failures + finally: + # Check if servers are still running. + for server, job in server_jobs.items(): + if not job.is_running(): + print('Server "%s" has exited prematurely.' % server) + suppress_failure = suppress_server_logs and not args.verbose + dockerjob.finish_jobs( + [j for j in six.itervalues(server_jobs)], + suppress_failure=suppress_failure) + + +num_failures = 0 +with open(args.scenarios_file, 'r') as scenarios_input: + all_scenarios = json.loads(scenarios_input.read()) + for scenario in all_scenarios: + if args.scenario_name: + if args.scenario_name != scenario['name']: + jobset.message('IDLE', + 'Skipping scenario: %s' % scenario['name']) + continue + num_failures += run_one_scenario(scenario) +if num_failures == 0: + sys.exit(0) +else: + sys.exit(1) diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py index 1d639edb82..5722a88182 100755 --- a/tools/run_tests/run_interop_tests.py +++ b/tools/run_tests/run_interop_tests.py @@ -688,6 +688,10 @@ def write_cmdlog_maybe(cmdlog, filename): if cmdlog: with open(filename, 'w') as logfile: logfile.write('#!/bin/bash\n') + logfile.write('# DO NOT MODIFY\n') + logfile.write( + '# This file is generated by run_interop_tests.py/create_testcases.sh\n' + ) logfile.writelines("%s\n" % line for line in cmdlog) print('Command log written to file %s' % filename) diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index a746d531a1..c6e67eaf56 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -41,6 +41,11 @@ os.chdir(_ROOT) _REMOTE_HOST_USERNAME = 'jenkins' +_SCENARIO_TIMEOUT = 3 * 60 +_WORKER_TIMEOUT = 3 * 60 +_NETPERF_TIMEOUT = 60 +_QUIT_WORKER_TIMEOUT = 2 * 60 + class QpsWorkerJob: """Encapsulates a qps worker server job.""" @@ -85,7 +90,7 @@ def create_qpsworker_job(language, cmdline = perf_cmd + ['-o', '%s-perf.data' % perf_file_base_name ] + cmdline - worker_timeout = 3 * 60 + worker_timeout = _WORKER_TIMEOUT if remote_host: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host) ssh_cmd = ['ssh'] @@ -131,7 +136,7 @@ def create_scenario_jobspec(scenario_json, return jobset.JobSpec( cmdline=[cmd], shortname='qps_json_driver.%s' % scenario_json['name'], - timeout_seconds=12 * 60, + timeout_seconds=_SCENARIO_TIMEOUT, shell=True, verbose_success=True) @@ -139,7 +144,7 @@ def create_scenario_jobspec(scenario_json, def create_quit_jobspec(workers, remote_host=None): """Runs quit using QPS driver.""" # setting QPS_WORKERS env variable here makes sure it works with SSH too. - cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver --quit' % ','.join( + cmd = 'QPS_WORKERS="%s" cmake/build/qps_json_driver --quit' % ','.join( w.host_and_port for w in workers) if remote_host: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host) @@ -149,7 +154,7 @@ def create_quit_jobspec(workers, remote_host=None): return jobset.JobSpec( cmdline=[cmd], shortname='qps_json_driver.quit', - timeout_seconds=3 * 60, + timeout_seconds=_QUIT_WORKER_TIMEOUT, shell=True, verbose_success=True) @@ -181,7 +186,7 @@ def create_netperf_jobspec(server_host='localhost', return jobset.JobSpec( cmdline=[cmd], shortname='netperf', - timeout_seconds=60, + timeout_seconds=_NETPERF_TIMEOUT, shell=True, verbose_success=True) diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 48c40ad724..44151f49fb 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -759,8 +759,10 @@ class PythonLanguage(object): self.python_manager_name(), _docker_arch_suffix(self.args.arch)) def python_manager_name(self): - if self.args.compiler in ['python3.5', 'python3.6']: - return 'pyenv' + if self.args.compiler in [ + 'python2.7', 'python3.5', 'python3.6', 'python3.7' + ]: + return 'stretch_' + self.args.compiler[len('python'):] elif self.args.compiler == 'python_alpine': return 'alpine' else: @@ -1515,7 +1517,7 @@ else: lang_list = args.language # We don't support code coverage on some languages if 'gcov' in args.config: - for bad in ['grpc-node', 'objc', 'sanity']: + for bad in ['csharp', 'grpc-node', 'objc', 'sanity']: if bad in lang_list: lang_list.remove(bad) |