aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Yash Tibrewal <yashkt@google.com>2018-12-18 11:40:52 -0800
committerGravatar Yash Tibrewal <yashkt@google.com>2018-12-18 11:40:52 -0800
commitbb303513dce4e78d898035b9f7f5ae11b7b452dd (patch)
tree708cacfd6a93bdfff3fa76e813afe909f3e62fe6
parent00c9c40004d011f01c72d253a530edb3364992bf (diff)
parentd198607457a6f5d47e8c134277ebfe3706f9476b (diff)
Merge master
-rw-r--r--.gitmodules12
-rw-r--r--AUTHORS1
-rw-r--r--BUILD24
-rw-r--r--CMakeLists.txt238
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Makefile293
-rw-r--r--PYTHON-MANIFEST.in1
-rw-r--r--README.md20
-rw-r--r--WORKSPACE49
-rw-r--r--bazel/grpc_build_system.bzl4
-rw-r--r--bazel/grpc_deps.bzl47
-rw-r--r--build.yaml57
-rw-r--r--cmake/cares.cmake4
-rw-r--r--config.m48
-rw-r--r--config.w325
-rw-r--r--doc/g_stands_for.md3
-rw-r--r--doc/grpc_release_schedule.md22
-rw-r--r--doc/naming.md4
-rw-r--r--doc/python/sphinx/conf.py3
-rw-r--r--doc/python/sphinx/grpc_channelz.rst12
-rw-r--r--doc/python/sphinx/index.rst1
-rw-r--r--etc/roots.pem272
-rw-r--r--examples/BUILD15
-rw-r--r--examples/cpp/compression/Makefile110
-rw-r--r--examples/cpp/compression/README.md84
-rw-r--r--examples/cpp/compression/greeter_client.cc93
-rw-r--r--examples/cpp/compression/greeter_server.cc76
-rw-r--r--examples/cpp/metadata/Makefile96
-rw-r--r--examples/cpp/metadata/README.md66
-rw-r--r--examples/cpp/metadata/greeter_client.cc95
-rw-r--r--examples/cpp/metadata/greeter_server.cc94
-rw-r--r--examples/csharp/.gitignore2
-rw-r--r--examples/csharp/Helloworld/Greeter.sln2
-rw-r--r--examples/csharp/Helloworld/Greeter/Greeter.csproj17
-rw-r--r--examples/csharp/Helloworld/Greeter/Helloworld.cs312
-rw-r--r--examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs149
-rw-r--r--examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj8
-rw-r--r--examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj8
-rw-r--r--examples/csharp/Helloworld/README.md32
-rw-r--r--examples/csharp/Helloworld/generate_protos.bat28
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter.sln2
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj23
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs312
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs149
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config10
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj8
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config6
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj8
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config6
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/README.md27
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/generate_protos.bat26
-rw-r--r--examples/csharp/RouteGuide/RouteGuide.sln2
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs981
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj21
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs331
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs2
-rw-r--r--examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj8
-rw-r--r--examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj8
-rw-r--r--examples/csharp/RouteGuide/generate_protos.bat28
-rw-r--r--examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj8
-rw-r--r--examples/python/helloworld/greeter_client.py2
-rw-r--r--examples/python/helloworld/greeter_client_with_options.py2
-rw-r--r--examples/python/helloworld/greeter_server.py2
-rw-r--r--examples/python/helloworld/greeter_server_with_reflection.py2
-rw-r--r--examples/python/interceptors/default_value/greeter_client.py2
-rw-r--r--examples/python/interceptors/headers/greeter_client.py2
-rw-r--r--examples/python/interceptors/headers/greeter_server.py2
-rw-r--r--examples/python/metadata/README.md6
-rw-r--r--examples/python/metadata/helloworld_pb2.py134
-rw-r--r--examples/python/metadata/helloworld_pb2_grpc.py46
-rw-r--r--examples/python/metadata/metadata_client.py48
-rw-r--r--examples/python/metadata/metadata_server.py56
-rw-r--r--examples/python/multiplex/multiplex_client.py2
-rw-r--r--examples/python/multiplex/multiplex_server.py2
-rw-r--r--examples/python/route_guide/route_guide_client.py2
-rw-r--r--examples/python/route_guide/route_guide_server.py2
-rw-r--r--gRPC-C++.podspec13
-rw-r--r--gRPC-Core.podspec19
-rw-r--r--gRPC-ProtoRPC.podspec2
-rw-r--r--gRPC-RxLibrary.podspec2
-rw-r--r--gRPC.podspec2
-rw-r--r--grpc.gemspec10
-rw-r--r--grpc.gyp26
-rw-r--r--include/grpc/grpc.h3
-rw-r--r--include/grpc/grpc_security_constants.h6
-rw-r--r--include/grpc/impl/codegen/atm_gcc_sync.h2
-rw-r--r--include/grpc/impl/codegen/atm_windows.h2
-rw-r--r--include/grpc/impl/codegen/grpc_types.h7
-rw-r--r--include/grpc/impl/codegen/port_platform.h9
-rw-r--r--include/grpcpp/alarm.h93
-rw-r--r--include/grpcpp/alarm_impl.h116
-rw-r--r--include/grpcpp/channel.h8
-rw-r--r--include/grpcpp/create_channel.h4
-rw-r--r--include/grpcpp/generic/generic_stub.h5
-rw-r--r--include/grpcpp/health_check_service_interface.h4
-rw-r--r--include/grpcpp/impl/codegen/byte_buffer.h19
-rw-r--r--include/grpcpp/impl/codegen/call_op_set.h3
-rw-r--r--include/grpcpp/impl/codegen/callback_common.h27
-rw-r--r--include/grpcpp/impl/codegen/channel_interface.h13
-rw-r--r--include/grpcpp/impl/codegen/client_callback.h655
-rw-r--r--include/grpcpp/impl/codegen/client_context.h20
-rw-r--r--include/grpcpp/impl/codegen/client_interceptor.h48
-rw-r--r--include/grpcpp/impl/codegen/client_unary_call.h18
-rw-r--r--include/grpcpp/impl/codegen/completion_queue.h3
-rw-r--r--include/grpcpp/impl/codegen/server_callback.h774
-rw-r--r--include/grpcpp/impl/codegen/server_context.h25
-rw-r--r--include/grpcpp/impl/codegen/server_interceptor.h29
-rw-r--r--include/grpcpp/impl/codegen/server_interface.h18
-rw-r--r--include/grpcpp/security/credentials.h12
-rw-r--r--include/grpcpp/server.h4
-rw-r--r--package.xml14
-rw-r--r--requirements.bazel.txt3
-rw-r--r--setup.cfg3
-rw-r--r--setup.py18
-rw-r--r--src/compiler/cpp_generator.cc147
-rw-r--r--src/compiler/csharp_generator.cc37
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc193
-rw-r--r--src/core/ext/filters/client_channel/health/health_check_client.cc6
-rw-r--r--src/core/ext/filters/client_channel/health/health_check_client.h5
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.cc2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h21
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc334
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc43
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc101
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc48
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h61
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds.cc298
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc43
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h2
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.cc163
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_factory.h86
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.cc5
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.h4
-rw-r--r--src/core/ext/filters/client_channel/method_params.cc178
-rw-r--r--src/core/ext/filters/client_channel/method_params.h78
-rw-r--r--src/core/ext/filters/client_channel/resolver.cc2
-rw-r--r--src/core/ext/filters/client_channel/resolver.h2
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc96
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc74
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h1
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc225
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h15
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc6
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc3
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc26
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc14
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc20
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h7
-rw-r--r--src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc34
-rw-r--r--src/core/ext/filters/client_channel/resolver_result_parsing.cc377
-rw-r--r--src/core/ext/filters/client_channel/resolver_result_parsing.h146
-rw-r--r--src/core/ext/filters/client_channel/server_address.cc103
-rw-r--r--src/core/ext/filters/client_channel/server_address.h108
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc18
-rw-r--r--src/core/ext/filters/client_channel/subchannel.h15
-rw-r--r--src/core/ext/filters/client_channel/subchannel_index.cc47
-rw-r--r--src/core/ext/transport/chttp2/client/chttp2_connector.cc5
-rw-r--r--src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc17
-rw-r--r--src/core/ext/transport/chttp2/server/chttp2_server.cc2
-rw-r--r--src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc2
-rw-r--r--src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc19
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc73
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.h4
-rw-r--r--src/core/ext/transport/chttp2/transport/context_list.cc51
-rw-r--r--src/core/ext/transport/chttp2/transport/context_list.h72
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h49
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.cc5
-rw-r--r--src/core/ext/transport/inproc/inproc_transport.cc2
-rw-r--r--src/core/lib/channel/channelz.cc37
-rw-r--r--src/core/lib/channel/channelz.h8
-rw-r--r--src/core/lib/channel/channelz_registry.cc5
-rw-r--r--src/core/lib/debug/trace.cc3
-rw-r--r--src/core/lib/debug/trace.h8
-rw-r--r--src/core/lib/gpr/sync_posix.cc100
-rw-r--r--src/core/lib/gprpp/inlined_vector.h44
-rw-r--r--src/core/lib/gprpp/memory.h13
-rw-r--r--src/core/lib/gprpp/orphanable.h100
-rw-r--r--src/core/lib/gprpp/ref_counted.h204
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h39
-rw-r--r--src/core/lib/http/httpcli_security_connector.cc195
-rw-r--r--src/core/lib/http/parser.h10
-rw-r--r--src/core/lib/iomgr/buffer_list.cc21
-rw-r--r--src/core/lib/iomgr/buffer_list.h13
-rw-r--r--src/core/lib/iomgr/call_combiner.cc52
-rw-r--r--src/core/lib/iomgr/call_combiner.h31
-rw-r--r--src/core/lib/iomgr/dynamic_annotations.h67
-rw-r--r--src/core/lib/iomgr/endpoint.cc4
-rw-r--r--src/core/lib/iomgr/endpoint.h3
-rw-r--r--src/core/lib/iomgr/endpoint_cfstream.cc5
-rw-r--r--src/core/lib/iomgr/endpoint_pair_posix.cc4
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc4
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc4
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.cc4
-rw-r--r--src/core/lib/iomgr/ev_posix.cc22
-rw-r--r--src/core/lib/iomgr/ev_posix.h10
-rw-r--r--src/core/lib/iomgr/exec_ctx.cc13
-rw-r--r--src/core/lib/iomgr/fork_posix.cc2
-rw-r--r--src/core/lib/iomgr/internal_errqueue.cc39
-rw-r--r--src/core/lib/iomgr/internal_errqueue.h8
-rw-r--r--src/core/lib/iomgr/iomgr.cc7
-rw-r--r--src/core/lib/iomgr/iomgr.h4
-rw-r--r--src/core/lib/iomgr/iomgr_custom.cc4
-rw-r--r--src/core/lib/iomgr/iomgr_internal.cc4
-rw-r--r--src/core/lib/iomgr/iomgr_internal.h4
-rw-r--r--src/core/lib/iomgr/iomgr_posix.cc7
-rw-r--r--src/core/lib/iomgr/iomgr_posix_cfstream.cc7
-rw-r--r--src/core/lib/iomgr/iomgr_windows.cc5
-rw-r--r--src/core/lib/iomgr/port.h3
-rw-r--r--src/core/lib/iomgr/resolve_address.h2
-rw-r--r--src/core/lib/iomgr/sockaddr_utils.cc1
-rw-r--r--src/core/lib/iomgr/tcp_custom.cc5
-rw-r--r--src/core/lib/iomgr/tcp_posix.cc105
-rw-r--r--src/core/lib/iomgr/tcp_windows.cc5
-rw-r--r--src/core/lib/iomgr/timer_manager.cc6
-rw-r--r--src/core/lib/security/context/security_context.cc183
-rw-r--r--src/core/lib/security/context/security_context.h94
-rw-r--r--src/core/lib/security/credentials/alts/alts_credentials.cc84
-rw-r--r--src/core/lib/security/credentials/alts/alts_credentials.h47
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.cc297
-rw-r--r--src/core/lib/security/credentials/composite/composite_credentials.h111
-rw-r--r--src/core/lib/security/credentials/credentials.cc160
-rw-r--r--src/core/lib/security/credentials/credentials.h214
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.cc117
-rw-r--r--src/core/lib/security/credentials/fake/fake_credentials.h28
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.cc195
-rw-r--r--src/core/lib/security/credentials/google_default/google_default_credentials.h33
-rw-r--r--src/core/lib/security/credentials/iam/iam_credentials.cc62
-rw-r--r--src/core/lib/security/credentials/iam/iam_credentials.h22
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.cc129
-rw-r--r--src/core/lib/security/credentials/jwt/jwt_credentials.h39
-rw-r--r--src/core/lib/security/credentials/local/local_credentials.cc51
-rw-r--r--src/core/lib/security/credentials/local/local_credentials.h43
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.cc279
-rw-r--r--src/core/lib/security/credentials/oauth2/oauth2_credentials.h103
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.cc136
-rw-r--r--src/core/lib/security/credentials/plugin/plugin_credentials.h57
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.cc149
-rw-r--r--src/core/lib/security/credentials/ssl/ssl_credentials.h73
-rw-r--r--src/core/lib/security/security_connector/alts/alts_security_connector.cc329
-rw-r--r--src/core/lib/security/security_connector/alts/alts_security_connector.h22
-rw-r--r--src/core/lib/security/security_connector/fake/fake_security_connector.cc425
-rw-r--r--src/core/lib/security/security_connector/fake/fake_security_connector.h15
-rw-r--r--src/core/lib/security/security_connector/local/local_security_connector.cc345
-rw-r--r--src/core/lib/security/security_connector/local/local_security_connector.h19
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc165
-rw-r--r--src/core/lib/security/security_connector/security_connector.h207
-rw-r--r--src/core/lib/security/security_connector/ssl/ssl_security_connector.cc718
-rw-r--r--src/core/lib/security/security_connector/ssl/ssl_security_connector.h26
-rw-r--r--src/core/lib/security/security_connector/ssl_utils.cc22
-rw-r--r--src/core/lib/security/security_connector/ssl_utils.h4
-rw-r--r--src/core/lib/security/transport/client_auth_filter.cc100
-rw-r--r--src/core/lib/security/transport/secure_endpoint.cc8
-rw-r--r--src/core/lib/security/transport/security_handshaker.cc148
-rw-r--r--src/core/lib/security/transport/server_auth_filter.cc28
-rw-r--r--src/core/lib/surface/init.cc1
-rw-r--r--src/core/lib/surface/server.cc128
-rw-r--r--src/core/lib/surface/server.h12
-rw-r--r--src/core/lib/surface/version.cc2
-rw-r--r--src/core/lib/transport/static_metadata.cc449
-rw-r--r--src/core/lib/transport/static_metadata.h146
-rw-r--r--src/core/lib/transport/transport.cc3
-rw-r--r--src/core/lib/transport/transport.h6
-rw-r--r--src/core/tsi/alts/handshaker/alts_handshaker_client.cc11
-rw-r--r--src/core/tsi/ssl_transport_security.cc47
-rw-r--r--src/cpp/client/channel_cc.cc13
-rw-r--r--src/cpp/client/client_context.cc9
-rw-r--r--src/cpp/client/create_channel.cc36
-rw-r--r--src/cpp/client/create_channel_internal.cc4
-rw-r--r--src/cpp/client/create_channel_internal.h4
-rw-r--r--src/cpp/client/create_channel_posix.cc10
-rw-r--r--src/cpp/client/cronet_credentials.cc9
-rw-r--r--src/cpp/client/generic_stub.cc9
-rw-r--r--src/cpp/client/insecure_credentials.cc9
-rw-r--r--src/cpp/client/secure_credentials.cc15
-rw-r--r--src/cpp/client/secure_credentials.h13
-rw-r--r--src/cpp/common/alarm.cc13
-rw-r--r--src/cpp/common/secure_auth_context.cc38
-rw-r--r--src/cpp/common/secure_auth_context.h11
-rw-r--r--src/cpp/common/secure_create_auth_context.cc5
-rw-r--r--src/cpp/common/version_cc.cc2
-rw-r--r--src/cpp/server/channelz/channelz_service.cc4
-rw-r--r--src/cpp/server/health/default_health_check_service.cc19
-rw-r--r--src/cpp/server/health/default_health_check_service.h3
-rw-r--r--src/cpp/server/secure_server_credentials.cc2
-rw-r--r--src/cpp/server/server_cc.cc36
-rw-r--r--src/cpp/server/server_context.cc47
-rw-r--r--src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs2
-rwxr-xr-xsrc/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj2
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs2
-rw-r--r--src/csharp/Grpc.Core.Tests/MarshallerTest.cs7
-rw-r--r--src/csharp/Grpc.Core.Tests/NUnitMain.cs6
-rw-r--r--src/csharp/Grpc.Core.Tests/SanityTest.cs4
-rw-r--r--src/csharp/Grpc.Core/DeserializationContext.cs7
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs27
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs66
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs62
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeExtension.cs4
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCallHandler.cs16
-rw-r--r--src/csharp/Grpc.Core/Marshaller.cs67
-rw-r--r--src/csharp/Grpc.Core/SerializationContext.cs7
-rw-r--r--src/csharp/Grpc.Core/ServerServiceDefinition.cs8
-rw-r--r--src/csharp/Grpc.Core/ServiceBinderBase.cs101
-rwxr-xr-xsrc/csharp/Grpc.Core/Version.csproj.include2
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs4
-rwxr-xr-xsrc/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj2
-rwxr-xr-xsrc/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj2
-rwxr-xr-xsrc/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj2
-rw-r--r--src/csharp/Grpc.Examples.Tests/NUnitMain.cs6
-rwxr-xr-xsrc/csharp/Grpc.Examples/Grpc.Examples.csproj2
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs12
-rwxr-xr-xsrc/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj2
-rw-r--r--src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs6
-rw-r--r--src/csharp/Grpc.HealthCheck/Health.cs20
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs135
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj2
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj2
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj4
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs13
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Control.cs144
-rw-r--r--src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs8
-rwxr-xr-xsrc/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj2
-rw-r--r--src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs10
-rw-r--r--src/csharp/Grpc.IntegrationTesting/NUnitMain.cs6
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs9
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestGrpc.cs35
-rw-r--r--src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs12
-rw-r--r--src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj2
-rwxr-xr-xsrc/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj2
-rw-r--r--src/csharp/Grpc.Reflection.Tests/NUnitMain.cs6
-rw-r--r--src/csharp/Grpc.Reflection/ReflectionGrpc.cs9
-rw-r--r--src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj2
-rw-r--r--src/csharp/Grpc.Tools.Tests/NUnitMain.cs4
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat2
-rw-r--r--src/csharp/build_unitypackage.bat2
-rw-r--r--src/objective-c/!ProtoCompiler-gRPCPlugin.podspec2
-rw-r--r--src/objective-c/GRPCClient/GRPCCall.h3
-rw-r--r--src/objective-c/GRPCClient/private/version.h2
-rw-r--r--src/objective-c/tests/version.h2
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/channel.c2
-rw-r--r--src/php/ext/grpc/channel.h3
-rwxr-xr-xsrc/php/ext/grpc/config.m42
-rw-r--r--src/php/ext/grpc/php_grpc.c122
-rw-r--r--src/php/ext/grpc/version.h2
-rw-r--r--src/proto/grpc/channelz/BUILD7
-rw-r--r--src/proto/grpc/channelz/channelz.proto36
-rw-r--r--src/proto/grpc/health/v1/BUILD1
-rw-r--r--src/proto/grpc/testing/BUILD9
-rw-r--r--src/proto/grpc/testing/compiler_test.proto3
-rw-r--r--src/proto/grpc/testing/echo.proto4
-rw-r--r--src/proto/grpc/testing/simple_messages.proto24
-rw-r--r--src/python/grpcio/grpc/BUILD.bazel1
-rw-r--r--src/python/grpcio/grpc/__init__.py38
-rw-r--r--src/python/grpcio/grpc/_channel.py41
-rw-r--r--src/python/grpcio/grpc/_cython/BUILD.bazel46
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi15
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi27
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi71
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi12
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi16
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi18
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi36
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi36
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi20
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi20
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi4
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pxd1
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pyx2
-rw-r--r--src/python/grpcio/grpc/_grpcio_metadata.py2
-rw-r--r--src/python/grpcio/grpc/_interceptor.py13
-rw-r--r--src/python/grpcio/grpc/_server.py76
-rw-r--r--src/python/grpcio/grpc/beta/BUILD.bazel58
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py5
-rw-r--r--src/python/grpcio/grpc_version.py2
-rw-r--r--src/python/grpcio_channelz/.gitignore6
-rw-r--r--src/python/grpcio_channelz/MANIFEST.in4
-rw-r--r--src/python/grpcio_channelz/README.rst9
-rw-r--r--src/python/grpcio_channelz/channelz_commands.py67
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/__init__.py13
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel38
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/__init__.py13
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/channelz.py142
-rw-r--r--src/python/grpcio_channelz/grpc_version.py17
-rw-r--r--src/python/grpcio_channelz/setup.py96
-rw-r--r--src/python/grpcio_health_checking/MANIFEST.in1
-rw-r--r--src/python/grpcio_health_checking/grpc_version.py2
-rw-r--r--src/python/grpcio_health_checking/health_commands.py8
-rw-r--r--src/python/grpcio_health_checking/setup.py2
-rw-r--r--src/python/grpcio_reflection/MANIFEST.in1
-rw-r--r--src/python/grpcio_reflection/grpc_version.py2
-rw-r--r--src/python/grpcio_reflection/reflection_commands.py8
-rw-r--r--src/python/grpcio_reflection/setup.py2
-rw-r--r--src/python/grpcio_status/.gitignore3
-rw-r--r--src/python/grpcio_status/MANIFEST.in4
-rw-r--r--src/python/grpcio_status/README.rst9
-rw-r--r--src/python/grpcio_status/grpc_status/BUILD.bazel14
-rw-r--r--src/python/grpcio_status/grpc_status/__init__.py13
-rw-r--r--src/python/grpcio_status/grpc_status/rpc_status.py92
-rw-r--r--src/python/grpcio_status/grpc_version.py17
-rw-r--r--src/python/grpcio_status/setup.py93
-rw-r--r--src/python/grpcio_status/status_commands.py39
-rw-r--r--src/python/grpcio_testing/MANIFEST.in1
-rw-r--r--src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py3
-rw-r--r--src/python/grpcio_testing/grpc_version.py2
-rw-r--r--src/python/grpcio_testing/setup.py33
-rw-r--r--src/python/grpcio_testing/testing_commands.py39
-rw-r--r--src/python/grpcio_tests/commands.py15
-rw-r--r--src/python/grpcio_tests/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/setup.py2
-rw-r--r--src/python/grpcio_tests/tests/channelz/BUILD.bazel15
-rw-r--r--src/python/grpcio_tests/tests/channelz/__init__.py13
-rw-r--r--src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py470
-rw-r--r--src/python/grpcio_tests/tests/interop/methods.py11
-rw-r--r--src/python/grpcio_tests/tests/qps/worker_server.py4
-rw-r--r--src/python/grpcio_tests/tests/status/BUILD.bazel19
-rw-r--r--src/python/grpcio_tests/tests/status/__init__.py13
-rw-r--r--src/python/grpcio_tests/tests/status/_grpc_status_test.py173
-rw-r--r--src/python/grpcio_tests/tests/tests.json3
-rw-r--r--src/python/grpcio_tests/tests/unit/BUILD.bazel1
-rw-r--r--src/python/grpcio_tests/tests/unit/_abort_test.py124
-rw-r--r--src/python/grpcio_tests/tests/unit/_api_test.py1
-rw-r--r--src/python/grpcio_tests/tests/unit/_credentials_test.py11
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_scenarios.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/_exit_test.py15
-rw-r--r--src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py3
-rw-r--r--src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py51
-rw-r--r--src/python/grpcio_tests/tests/unit/beta/BUILD.bazel75
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h2
-rw-r--r--src/ruby/lib/grpc/generic/service.rb2
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/pb/grpc/health/checker.rb5
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb22
-rw-r--r--src/ruby/spec/support/services.rb1
-rw-r--r--src/ruby/tools/version.rb2
-rw-r--r--templates/Makefile.template2
-rw-r--r--templates/config.m4.template3
-rw-r--r--templates/gRPC-C++.podspec.template10
-rw-r--r--templates/src/python/grpcio_channelz/grpc_version.py.template19
-rw-r--r--templates/src/python/grpcio_status/grpc_version.py.template19
-rw-r--r--templates/tools/dockerfile/csharp_deps.include25
-rw-r--r--templates/tools/dockerfile/csharp_dotnetcli_deps.include26
-rw-r--r--templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template2
-rw-r--r--templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template2
-rw-r--r--templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template14
-rw-r--r--templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template (renamed from templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template)4
-rw-r--r--templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template41
-rw-r--r--templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template3
-rw-r--r--test/core/avl/avl_test.cc2
-rw-r--r--test/core/backoff/backoff_test.cc2
-rw-r--r--test/core/bad_client/bad_client.cc2
-rw-r--r--test/core/bad_client/tests/badreq.cc2
-rw-r--r--test/core/bad_client/tests/connection_prefix.cc2
-rw-r--r--test/core/bad_client/tests/duplicate_header.cc2
-rw-r--r--test/core/bad_client/tests/head_of_line_blocking.cc2
-rw-r--r--test/core/bad_client/tests/headers.cc2
-rw-r--r--test/core/bad_client/tests/initial_settings_frame.cc2
-rw-r--r--test/core/bad_client/tests/large_metadata.cc2
-rw-r--r--test/core/bad_client/tests/server_registered_method.cc2
-rw-r--r--test/core/bad_client/tests/simple_request.cc2
-rw-r--r--test/core/bad_client/tests/unknown_frame.cc2
-rw-r--r--test/core/bad_client/tests/window_overflow.cc2
-rw-r--r--test/core/channel/channel_args_test.cc2
-rw-r--r--test/core/channel/channel_stack_builder_test.cc2
-rw-r--r--test/core/channel/channel_stack_test.cc2
-rw-r--r--test/core/channel/channel_trace_test.cc2
-rw-r--r--test/core/channel/channelz_registry_test.cc2
-rw-r--r--test/core/channel/channelz_test.cc2
-rw-r--r--test/core/channel/minimal_stack_is_minimal_test.cc2
-rw-r--r--test/core/client_channel/parse_address_test.cc2
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc15
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc13
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_test.cc2
-rw-r--r--test/core/client_channel/resolvers/fake_resolver_test.cc44
-rw-r--r--test/core/client_channel/resolvers/sockaddr_resolver_test.cc2
-rw-r--r--test/core/client_channel/retry_throttle_test.cc2
-rw-r--r--test/core/client_channel/uri_parser_test.cc2
-rw-r--r--test/core/compression/algorithm_test.cc2
-rw-r--r--test/core/compression/message_compress_test.cc2
-rw-r--r--test/core/end2end/BUILD13
-rw-r--r--test/core/end2end/bad_server_response_test.cc2
-rw-r--r--test/core/end2end/connection_refused_test.cc2
-rw-r--r--test/core/end2end/dualstack_socket_test.cc2
-rw-r--r--test/core/end2end/fixtures/h2_census.cc2
-rw-r--r--test/core/end2end/fixtures/h2_compress.cc2
-rw-r--r--test/core/end2end/fixtures/h2_fakesec.cc2
-rw-r--r--test/core/end2end/fixtures/h2_fd.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full+pipe.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full+trace.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full+workarounds.cc2
-rw-r--r--test/core/end2end/fixtures/h2_full.cc2
-rw-r--r--test/core/end2end/fixtures/h2_http_proxy.cc2
-rw-r--r--test/core/end2end/fixtures/h2_local_ipv4.cc72
-rw-r--r--test/core/end2end/fixtures/h2_local_ipv6.cc72
-rw-r--r--test/core/end2end/fixtures/h2_local_uds.cc71
-rw-r--r--test/core/end2end/fixtures/h2_oauth2.cc2
-rw-r--r--test/core/end2end/fixtures/h2_proxy.cc2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.cc4
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.cc4
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.cc4
-rw-r--r--test/core/end2end/fixtures/h2_ssl.cc2
-rw-r--r--test/core/end2end/fixtures/h2_ssl_proxy.cc2
-rw-r--r--test/core/end2end/fixtures/h2_uds.cc2
-rw-r--r--test/core/end2end/fixtures/inproc.cc2
-rw-r--r--test/core/end2end/fixtures/local_util.cc (renamed from test/core/end2end/fixtures/h2_local.cc)84
-rw-r--r--test/core/end2end/fixtures/local_util.h41
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.cc31
-rw-r--r--test/core/end2end/fuzzers/hpack.dictionary1
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer.cc2
-rwxr-xr-xtest/core/end2end/gen_build_yaml.py4
-rwxr-xr-xtest/core/end2end/generate_tests.bzl6
-rw-r--r--test/core/end2end/goaway_server_test.cc31
-rw-r--r--test/core/end2end/h2_ssl_cert_test.cc2
-rw-r--r--test/core/end2end/h2_ssl_session_reuse_test.cc2
-rw-r--r--test/core/end2end/inproc_callback_test.cc2
-rw-r--r--test/core/end2end/invalid_call_argument_test.cc2
-rw-r--r--test/core/end2end/multiple_server_queues_test.cc2
-rw-r--r--test/core/end2end/no_server_test.cc3
-rw-r--r--test/core/end2end/tests/channelz.cc4
-rw-r--r--test/core/fling/client.cc6
-rw-r--r--test/core/gpr/BUILD2
-rw-r--r--test/core/gpr/alloc_test.cc2
-rw-r--r--test/core/gpr/arena_test.cc2
-rw-r--r--test/core/gpr/cpu_test.cc2
-rw-r--r--test/core/gpr/env_test.cc2
-rw-r--r--test/core/gpr/host_port_test.cc2
-rw-r--r--test/core/gpr/log_test.cc2
-rw-r--r--test/core/gpr/mpscq_test.cc2
-rw-r--r--test/core/gpr/murmur_hash_test.cc2
-rw-r--r--test/core/gpr/spinlock_test.cc2
-rw-r--r--test/core/gpr/string_test.cc2
-rw-r--r--test/core/gpr/sync_test.cc2
-rw-r--r--test/core/gpr/time_test.cc2
-rw-r--r--test/core/gpr/tls_test.cc2
-rw-r--r--test/core/gpr/useful_test.cc2
-rw-r--r--test/core/gprpp/fork_test.cc2
-rw-r--r--test/core/gprpp/inlined_vector_test.cc166
-rw-r--r--test/core/gprpp/manual_constructor_test.cc2
-rw-r--r--test/core/gprpp/memory_test.cc2
-rw-r--r--test/core/gprpp/orphanable_test.cc6
-rw-r--r--test/core/gprpp/ref_counted_ptr_test.cc6
-rw-r--r--test/core/gprpp/ref_counted_test.cc11
-rw-r--r--test/core/gprpp/thd_test.cc2
-rw-r--r--test/core/http/format_request_test.cc2
-rw-r--r--test/core/http/httpcli_test.cc2
-rw-r--r--test/core/http/httpscli_test.cc2
-rw-r--r--test/core/http/parser_test.cc2
-rw-r--r--test/core/iomgr/BUILD2
-rw-r--r--test/core/iomgr/buffer_list_test.cc6
-rw-r--r--test/core/iomgr/combiner_test.cc2
-rw-r--r--test/core/iomgr/endpoint_pair_test.cc2
-rw-r--r--test/core/iomgr/error_test.cc2
-rw-r--r--test/core/iomgr/ev_epollex_linux_test.cc2
-rw-r--r--test/core/iomgr/fd_conservation_posix_test.cc2
-rw-r--r--test/core/iomgr/fd_posix_test.cc2
-rw-r--r--test/core/iomgr/grpc_ipv6_loopback_available_test.cc2
-rw-r--r--test/core/iomgr/load_file_test.cc2
-rw-r--r--test/core/iomgr/resolve_address_posix_test.cc15
-rw-r--r--test/core/iomgr/resolve_address_test.cc2
-rw-r--r--test/core/iomgr/resource_quota_test.cc2
-rw-r--r--test/core/iomgr/sockaddr_utils_test.cc2
-rw-r--r--test/core/iomgr/socket_utils_test.cc2
-rw-r--r--test/core/iomgr/tcp_client_posix_test.cc2
-rw-r--r--test/core/iomgr/tcp_client_uv_test.cc2
-rw-r--r--test/core/iomgr/tcp_posix_test.cc2
-rw-r--r--test/core/iomgr/tcp_server_posix_test.cc2
-rw-r--r--test/core/iomgr/tcp_server_uv_test.cc2
-rw-r--r--test/core/iomgr/time_averaged_stats_test.cc2
-rw-r--r--test/core/iomgr/timer_heap_test.cc2
-rw-r--r--test/core/iomgr/timer_list_test.cc4
-rw-r--r--test/core/iomgr/udp_server_test.cc2
-rw-r--r--test/core/json/json_rewrite_test.cc2
-rw-r--r--test/core/json/json_stream_error_test.cc2
-rw-r--r--test/core/json/json_test.cc2
-rw-r--r--test/core/memory_usage/client.cc6
-rw-r--r--test/core/memory_usage/server.cc2
-rw-r--r--test/core/security/alts_security_connector_test.cc41
-rw-r--r--test/core/security/auth_context_test.cc118
-rw-r--r--test/core/security/credentials_test.cc304
-rw-r--r--test/core/security/json_token_test.cc2
-rw-r--r--test/core/security/jwt_verifier_test.cc2
-rw-r--r--test/core/security/linux_system_roots_test.cc2
-rw-r--r--test/core/security/oauth2_utils.cc5
-rw-r--r--test/core/security/print_google_default_creds_token.cc9
-rw-r--r--test/core/security/secure_endpoint_test.cc2
-rw-r--r--test/core/security/security_connector_test.cc97
-rw-r--r--test/core/security/ssl_credentials_test.cc2
-rw-r--r--test/core/security/ssl_server_fuzzer.cc11
-rw-r--r--test/core/slice/b64_test.cc2
-rw-r--r--test/core/slice/percent_encoding_test.cc2
-rw-r--r--test/core/slice/slice_buffer_test.cc2
-rw-r--r--test/core/slice/slice_hash_table_test.cc2
-rw-r--r--test/core/slice/slice_string_helpers_test.cc2
-rw-r--r--test/core/slice/slice_test.cc2
-rw-r--r--test/core/slice/slice_weak_hash_table_test.cc2
-rw-r--r--test/core/surface/byte_buffer_reader_test.cc2
-rw-r--r--test/core/surface/channel_create_test.cc2
-rw-r--r--test/core/surface/completion_queue_test.cc2
-rw-r--r--test/core/surface/completion_queue_threading_test.cc2
-rw-r--r--test/core/surface/concurrent_connectivity_test.cc2
-rw-r--r--test/core/surface/init_test.cc2
-rw-r--r--test/core/surface/lame_client_test.cc2
-rw-r--r--test/core/surface/num_external_connectivity_watchers_test.cc2
-rw-r--r--test/core/surface/secure_channel_create_test.cc4
-rw-r--r--test/core/surface/sequential_connectivity_test.cc2
-rw-r--r--test/core/surface/server_chttp2_test.cc2
-rw-r--r--test/core/surface/server_test.cc2
-rw-r--r--test/core/transport/bdp_estimator_test.cc2
-rw-r--r--test/core/transport/byte_stream_test.cc2
-rw-r--r--test/core/transport/chttp2/BUILD16
-rw-r--r--test/core/transport/chttp2/alpn_test.cc2
-rw-r--r--test/core/transport/chttp2/context_list_test.cc102
-rw-r--r--test/core/transport/chttp2/hpack_encoder_test.cc2
-rw-r--r--test/core/transport/chttp2/hpack_parser_test.cc2
-rw-r--r--test/core/transport/chttp2/hpack_table_test.cc2
-rw-r--r--test/core/transport/chttp2/settings_timeout_test.cc2
-rw-r--r--test/core/transport/chttp2/stream_map_test.cc2
-rw-r--r--test/core/transport/chttp2/varint_test.cc2
-rw-r--r--test/core/transport/connectivity_state_test.cc2
-rw-r--r--test/core/transport/metadata_test.cc2
-rw-r--r--test/core/transport/pid_controller_test.cc2
-rw-r--r--test/core/transport/status_conversion_test.cc2
-rw-r--r--test/core/transport/stream_owned_slice_test.cc2
-rw-r--r--test/core/transport/timeout_encoding_test.cc2
-rw-r--r--test/core/tsi/fake_transport_security_test.cc2
-rw-r--r--test/core/tsi/ssl_session_cache_test.cc2
-rw-r--r--test/core/tsi/ssl_transport_security_test.cc2
-rw-r--r--test/core/tsi/transport_security_test.cc2
-rw-r--r--test/core/util/cmdline_test.cc2
-rw-r--r--test/core/util/fuzzer_corpus_test.cc2
-rw-r--r--test/core/util/memory_counters.cc32
-rw-r--r--test/core/util/mock_endpoint.cc25
-rw-r--r--test/core/util/passthru_endpoint.cc3
-rw-r--r--test/core/util/test_config.cc12
-rw-r--r--test/core/util/test_config.h15
-rw-r--r--test/core/util/trickle_endpoint.cc5
-rw-r--r--test/core/util/ubsan_suppressions.txt3
-rw-r--r--test/cpp/client/client_channel_stress_test.cc30
-rw-r--r--test/cpp/codegen/compiler_test_golden63
-rw-r--r--test/cpp/common/alarm_test.cc2
-rw-r--r--test/cpp/common/auth_property_iterator_test.cc17
-rw-r--r--test/cpp/common/secure_auth_context_test.cc14
-rw-r--r--test/cpp/end2end/BUILD14
-rw-r--r--test/cpp/end2end/async_end2end_test.cc2
-rw-r--r--test/cpp/end2end/channelz_service_test.cc84
-rw-r--r--test/cpp/end2end/client_callback_end2end_test.cc254
-rw-r--r--test/cpp/end2end/client_crash_test.cc2
-rw-r--r--test/cpp/end2end/client_interceptors_end2end_test.cc116
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc135
-rw-r--r--test/cpp/end2end/end2end_test.cc92
-rw-r--r--test/cpp/end2end/exception_test.cc2
-rw-r--r--test/cpp/end2end/filter_end2end_test.cc2
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc2
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc51
-rw-r--r--test/cpp/end2end/health_service_end2end_test.cc151
-rw-r--r--test/cpp/end2end/hybrid_end2end_test.cc2
-rw-r--r--test/cpp/end2end/interceptors_util.cc12
-rw-r--r--test/cpp/end2end/interceptors_util.h3
-rw-r--r--test/cpp/end2end/mock_test.cc2
-rw-r--r--test/cpp/end2end/nonblocking_test.cc2
-rw-r--r--test/cpp/end2end/proto_server_reflection_test.cc2
-rw-r--r--test/cpp/end2end/raw_end2end_test.cc2
-rw-r--r--test/cpp/end2end/server_builder_plugin_test.cc2
-rw-r--r--test/cpp/end2end/server_crash_test.cc2
-rw-r--r--test/cpp/end2end/server_early_return_test.cc2
-rw-r--r--test/cpp/end2end/server_interceptors_end2end_test.cc31
-rw-r--r--test/cpp/end2end/shutdown_test.cc2
-rw-r--r--test/cpp/end2end/streaming_throughput_test.cc2
-rw-r--r--test/cpp/end2end/test_health_check_service_impl.cc97
-rw-r--r--test/cpp/end2end/test_health_check_service_impl.h58
-rw-r--r--test/cpp/end2end/test_service_impl.cc356
-rw-r--r--test/cpp/end2end/test_service_impl.h32
-rw-r--r--test/cpp/end2end/thread_stress_test.cc2
-rw-r--r--test/cpp/ext/filters/census/stats_plugin_end2end_test.cc2
-rw-r--r--test/cpp/microbenchmarks/BUILD7
-rw-r--r--test/cpp/microbenchmarks/bm_byte_buffer.cc65
-rw-r--r--test/cpp/microbenchmarks/bm_call_create.cc3
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_transport.cc4
-rw-r--r--test/cpp/microbenchmarks/bm_cq_multiple_threads.cc1
-rw-r--r--test/cpp/microbenchmarks/fullstack_fixtures.h7
-rw-r--r--test/cpp/naming/address_sorting_test.cc129
-rw-r--r--test/cpp/naming/cancel_ares_query_test.cc61
-rw-r--r--test/cpp/naming/resolver_component_test.cc23
-rw-r--r--test/cpp/performance/writes_per_rpc_test.cc9
-rw-r--r--test/cpp/qps/BUILD2
-rw-r--r--test/cpp/qps/driver.cc36
-rw-r--r--test/cpp/qps/driver.h9
-rw-r--r--test/cpp/qps/inproc_sync_unary_ping_pong_test.cc2
-rw-r--r--test/cpp/qps/qps_json_driver.cc111
-rw-r--r--test/cpp/qps/qps_openloop_test.cc2
-rw-r--r--test/cpp/qps/secure_sync_unary_ping_pong_test.cc2
-rw-r--r--test/cpp/qps/server_callback.cc46
-rw-r--r--test/cpp/server/load_reporter/get_cpu_stats_test.cc2
-rw-r--r--test/cpp/server/load_reporter/load_data_store_test.cc2
-rw-r--r--test/cpp/server/load_reporter/load_reporter_test.cc2
-rw-r--r--test/cpp/util/BUILD2
-rw-r--r--test/cpp/util/cli_call_test.cc2
-rw-r--r--test/cpp/util/grpc_tool_test.cc5
m---------third_party/data-plane-api0
m---------third_party/googleapis0
m---------third_party/protoc-gen-validate0
-rw-r--r--third_party/toolchains/BUILD51
-rw-r--r--third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE1
-rw-r--r--[-rwxr-xr-x]third_party/toolchains/machine_size/BUILD (renamed from tools/run_tests/helper_scripts/run_lcov.sh)32
m---------third_party/upb0
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py1
-rwxr-xr-xtools/distrib/pylint_code.sh2
-rwxr-xr-xtools/distrib/python/docgen.py39
-rw-r--r--tools/distrib/python/grpcio_tools/grpc_version.py2
-rw-r--r--tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile45
-rw-r--r--tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile45
-rw-r--r--tools/dockerfile/interoptest/grpc_interop_python/Dockerfile33
-rwxr-xr-xtools/dockerfile/interoptest/grpc_interop_python/build_interop.sh4
-rw-r--r--tools/dockerfile/test/csharp_stretch_x64/Dockerfile (renamed from tools/dockerfile/test/csharp_jessie_x64/Dockerfile)47
-rw-r--r--tools/dockerfile/test/multilang_jessie_x64/Dockerfile170
-rw-r--r--tools/dockerfile/test/python_alpine_x64/Dockerfile8
-rw-r--r--tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile3
-rw-r--r--tools/doxygen/Doxyfile.c++4
-rw-r--r--tools/doxygen/Doxyfile.c++.internal5
-rw-r--r--tools/doxygen/Doxyfile.core1
-rw-r--r--tools/doxygen/Doxyfile.core.internal11
-rwxr-xr-xtools/gce/create_linux_kokoro_performance_worker_from_image.sh2
-rwxr-xr-xtools/gce/linux_kokoro_performance_worker_init.sh6
-rw-r--r--tools/internal_ci/helper_scripts/prepare_build_macos_rc8
-rwxr-xr-xtools/internal_ci/linux/grpc_bazel_on_foundry_base.sh13
-rwxr-xr-xtools/internal_ci/linux/grpc_coverage.sh20
-rwxr-xr-xtools/internal_ci/linux/grpc_run_tests_matrix.sh1
-rw-r--r--tools/interop_matrix/client_matrix.py3
-rw-r--r--tools/remote_build/kokoro.bazelrc1
-rw-r--r--tools/remote_build/rbe_common.bazelrc13
-rwxr-xr-xtools/run_tests/artifacts/build_artifact_python.sh13
-rwxr-xr-xtools/run_tests/artifacts/build_package_python.sh14
-rwxr-xr-xtools/run_tests/dockerize/build_docker_and_run_tests.sh5
-rwxr-xr-xtools/run_tests/dockerize/build_interop_image.sh4
-rwxr-xr-xtools/run_tests/dockerize/docker_run_tests.sh12
-rw-r--r--tools/run_tests/generated/sources_and_headers.json111
-rw-r--r--tools/run_tests/generated/tests.json3646
-rwxr-xr-xtools/run_tests/helper_scripts/build_python.sh13
-rwxr-xr-xtools/run_tests/performance/run_worker_csharp.sh2
-rwxr-xr-xtools/run_tests/run_interop_tests.py10
-rwxr-xr-xtools/run_tests/run_tests.py41
-rwxr-xr-xtools/run_tests/sanity/check_bazel_workspace.py5
-rwxr-xr-xtools/run_tests/sanity/check_submodules.sh4
754 files changed, 19830 insertions, 10156 deletions
diff --git a/.gitmodules b/.gitmodules
index afde4d34f3..06f1394df6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -42,3 +42,15 @@
path = third_party/libcxx
url = https://github.com/llvm-mirror/libcxx.git
branch = release_60
+[submodule "third_party/data-plane-api"]
+ path = third_party/data-plane-api
+ url = https://github.com/envoyproxy/data-plane-api.git
+[submodule "third_party/googleapis"]
+ path = third_party/googleapis
+ url = https://github.com/googleapis/googleapis.git
+[submodule "third_party/protoc-gen-validate"]
+ path = third_party/protoc-gen-validate
+ url = https://github.com/lyft/protoc-gen-validate.git
+[submodule "third_party/upb"]
+ path = third_party/upb
+ url = https://github.com/google/upb.git
diff --git a/AUTHORS b/AUTHORS
index 3e130afda2..0e8797391f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
+Dropbox, Inc.
Google Inc.
WeWork Companies Inc.
diff --git a/BUILD b/BUILD
index d572285233..fe93f1281e 100644
--- a/BUILD
+++ b/BUILD
@@ -64,11 +64,11 @@ config_setting(
)
# This should be updated along with build.yaml
-g_stands_for = "gizmo"
+g_stands_for = "goose"
-core_version = "6.0.0-dev"
+core_version = "7.0.0-dev"
-version = "1.17.0-dev"
+version = "1.18.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@@ -204,6 +204,7 @@ GRPCXX_PUBLIC_HDRS = [
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
"include/grpcpp/alarm.h",
+ "include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
@@ -647,6 +648,7 @@ grpc_cc_library(
"debug_location",
"gpr_base",
"grpc_trace",
+ "ref_counted",
"ref_counted_ptr",
],
)
@@ -855,6 +857,7 @@ grpc_cc_library(
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/closure.h",
"src/core/lib/iomgr/combiner.h",
+ "src/core/lib/iomgr/dynamic_annotations.h",
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
@@ -1046,15 +1049,15 @@ grpc_cc_library(
"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",
- "src/core/ext/filters/client_channel/lb_policy_factory.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
- "src/core/ext/filters/client_channel/method_params.cc",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
"src/core/ext/filters/client_channel/proxy_mapper_registry.cc",
"src/core/ext/filters/client_channel/resolver.cc",
"src/core/ext/filters/client_channel/resolver_registry.cc",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.cc",
"src/core/ext/filters/client_channel/retry_throttle.cc",
+ "src/core/ext/filters/client_channel/server_address.cc",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_index.cc",
],
@@ -1070,14 +1073,15 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
- "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
"src/core/ext/filters/client_channel/resolver.h",
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.h",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h",
],
@@ -1087,11 +1091,11 @@ grpc_cc_library(
"grpc_base",
"grpc_client_authority_filter",
"grpc_deadline_filter",
+ "health_proto",
"inlined_vector",
"orphanable",
"ref_counted",
"ref_counted_ptr",
- "health_proto",
],
)
@@ -1589,8 +1593,8 @@ grpc_cc_library(
"src/core/lib/security/security_connector/load_system_roots_linux.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/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",
@@ -1623,8 +1627,8 @@ grpc_cc_library(
"src/core/lib/security/security_connector/load_system_roots_linux.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/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",
@@ -1650,6 +1654,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/bin_encoder.cc",
"src/core/ext/transport/chttp2/transport/chttp2_plugin.cc",
"src/core/ext/transport/chttp2/transport/chttp2_transport.cc",
+ "src/core/ext/transport/chttp2/transport/context_list.cc",
"src/core/ext/transport/chttp2/transport/flow_control.cc",
"src/core/ext/transport/chttp2/transport/frame_data.cc",
"src/core/ext/transport/chttp2/transport/frame_goaway.cc",
@@ -1673,6 +1678,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/bin_decoder.h",
"src/core/ext/transport/chttp2/transport/bin_encoder.h",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/context_list.h",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/frame_data.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4cf60b1b28..b6ceb50a5f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
-set(PACKAGE_VERSION "1.17.0-dev")
+set(PACKAGE_VERSION "1.18.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -456,7 +456,13 @@ add_dependencies(buildtests_c h2_full+trace_test)
add_dependencies(buildtests_c h2_full+workarounds_test)
add_dependencies(buildtests_c h2_http_proxy_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
-add_dependencies(buildtests_c h2_local_test)
+add_dependencies(buildtests_c h2_local_ipv4_test)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_c h2_local_ipv6_test)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_c h2_local_uds_test)
endif()
add_dependencies(buildtests_c h2_oauth2_test)
add_dependencies(buildtests_c h2_proxy_test)
@@ -526,6 +532,9 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_arena)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_dependencies(buildtests_cxx bm_byte_buffer)
+endif()
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx bm_call_create)
endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
@@ -588,6 +597,7 @@ add_dependencies(buildtests_cxx client_interceptors_end2end_test)
add_dependencies(buildtests_cxx client_lb_end2end_test)
add_dependencies(buildtests_cxx codegen_test_full)
add_dependencies(buildtests_cxx codegen_test_minimal)
+add_dependencies(buildtests_cxx context_list_test)
add_dependencies(buildtests_cxx credentials_test)
add_dependencies(buildtests_cxx cxx_byte_buffer_test)
add_dependencies(buildtests_cxx cxx_slice_test)
@@ -1132,6 +1142,7 @@ add_library(grpc
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -1238,15 +1249,15 @@ add_library(grpc
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
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -1555,6 +1566,7 @@ add_library(grpc_cronet
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -1589,15 +1601,15 @@ add_library(grpc_cronet
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
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -1778,6 +1790,7 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
test/core/end2end/cq_verifier.cc
test/core/end2end/fixtures/http_proxy_fixture.cc
+ test/core/end2end/fixtures/local_util.cc
test/core/end2end/fixtures/proxy.cc
test/core/iomgr/endpoint_tests.cc
test/core/util/debugger_macros.cc
@@ -1960,15 +1973,15 @@ add_library(grpc_test_util
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
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -1980,6 +1993,7 @@ add_library(grpc_test_util
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -2097,6 +2111,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
test/core/end2end/cq_verifier.cc
test/core/end2end/fixtures/http_proxy_fixture.cc
+ test/core/end2end/fixtures/local_util.cc
test/core/end2end/fixtures/proxy.cc
test/core/iomgr/endpoint_tests.cc
test/core/util/debugger_macros.cc
@@ -2279,15 +2294,15 @@ add_library(grpc_test_util_unsecure
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
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -2299,6 +2314,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -2572,6 +2588,7 @@ add_library(grpc_unsecure
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -2611,15 +2628,15 @@ add_library(grpc_unsecure
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
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -2979,6 +2996,7 @@ foreach(_hdr
include/grpc++/support/sync_stream.h
include/grpc++/support/time.h
include/grpcpp/alarm.h
+ include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
@@ -3276,6 +3294,7 @@ add_library(grpc++_cronet
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -3462,15 +3481,15 @@ add_library(grpc++_cronet
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
- src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
+ src/core/ext/filters/client_channel/server_address.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
@@ -3562,6 +3581,7 @@ foreach(_hdr
include/grpc++/support/sync_stream.h
include/grpc++/support/time.h
include/grpcpp/alarm.h
+ include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
@@ -4013,6 +4033,11 @@ add_library(grpc++_test_util
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
+ test/cpp/end2end/test_health_check_service_impl.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/util/byte_buffer_proto_helper.cc
test/cpp/util/channel_trace_proto_helper.cc
@@ -4049,6 +4074,9 @@ protobuf_generate_grpc_cpp(
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/duplicate/echo_duplicate.proto
)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/simple_messages.proto
+)
target_include_directories(grpc++_test_util
PUBLIC $<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
@@ -4206,6 +4234,11 @@ add_library(grpc++_test_util_unsecure
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
+ test/cpp/end2end/test_health_check_service_impl.cc
test/cpp/end2end/test_service_impl.cc
test/cpp/util/byte_buffer_proto_helper.cc
test/cpp/util/string_ref_helper.cc
@@ -4236,6 +4269,9 @@ protobuf_generate_grpc_cpp(
protobuf_generate_grpc_cpp(
src/proto/grpc/testing/duplicate/echo_duplicate.proto
)
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/testing/simple_messages.proto
+)
target_include_directories(grpc++_test_util_unsecure
PUBLIC $<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
@@ -4497,6 +4533,7 @@ foreach(_hdr
include/grpc++/support/sync_stream.h
include/grpc++/support/time.h
include/grpcpp/alarm.h
+ include/grpcpp/alarm_impl.h
include/grpcpp/channel.h
include/grpcpp/client_context.h
include/grpcpp/completion_queue.h
@@ -11170,6 +11207,52 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+add_executable(bm_byte_buffer
+ test/cpp/microbenchmarks/bm_byte_buffer.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(bm_byte_buffer
+ 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}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(bm_byte_buffer
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_benchmark
+ ${_gRPC_BENCHMARK_LIBRARIES}
+ grpc++_test_util_unsecure
+ grpc_test_util_unsecure
+ grpc++_unsecure
+ grpc_unsecure
+ gpr_test_util
+ gpr
+ grpc++_test_config
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
add_executable(bm_call_create
test/cpp/microbenchmarks/bm_call_create.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -12701,6 +12784,45 @@ target_link_libraries(codegen_test_minimal
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(context_list_test
+ test/core/transport/chttp2/context_list_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(context_list_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}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(context_list_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(credentials_test
test/cpp/client/credentials_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@@ -16914,12 +17036,88 @@ endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
-add_executable(h2_local_test
- test/core/end2end/fixtures/h2_local.cc
+add_executable(h2_local_ipv4_test
+ test/core/end2end/fixtures/h2_local_ipv4.cc
+)
+
+
+target_include_directories(h2_local_ipv4_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(h2_local_ipv4_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ end2end_tests
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+)
+
+ # avoid dependency on libstdc++
+ if (_gRPC_CORE_NOSTDCXX_FLAGS)
+ set_target_properties(h2_local_ipv4_test PROPERTIES LINKER_LANGUAGE C)
+ target_compile_options(h2_local_ipv4_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
+ endif()
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(h2_local_ipv6_test
+ test/core/end2end/fixtures/h2_local_ipv6.cc
+)
+
+
+target_include_directories(h2_local_ipv6_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(h2_local_ipv6_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ end2end_tests
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+)
+
+ # avoid dependency on libstdc++
+ if (_gRPC_CORE_NOSTDCXX_FLAGS)
+ set_target_properties(h2_local_ipv6_test PROPERTIES LINKER_LANGUAGE C)
+ target_compile_options(h2_local_ipv6_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
+ endif()
+
+endif()
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
+
+add_executable(h2_local_uds_test
+ test/core/end2end/fixtures/h2_local_uds.cc
)
-target_include_directories(h2_local_test
+target_include_directories(h2_local_uds_test
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
@@ -16932,7 +17130,7 @@ target_include_directories(h2_local_test
PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
)
-target_link_libraries(h2_local_test
+target_link_libraries(h2_local_uds_test
${_gRPC_ALLTARGETS_LIBRARIES}
end2end_tests
grpc_test_util
@@ -16943,8 +17141,8 @@ target_link_libraries(h2_local_test
# avoid dependency on libstdc++
if (_gRPC_CORE_NOSTDCXX_FLAGS)
- set_target_properties(h2_local_test PROPERTIES LINKER_LANGUAGE C)
- target_compile_options(h2_local_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
+ set_target_properties(h2_local_uds_test PROPERTIES LINKER_LANGUAGE C)
+ target_compile_options(h2_local_uds_test PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${_gRPC_CORE_NOSTDCXX_FLAGS}>)
endif()
endif()
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e8582d9af5..1d14d5e0e3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -81,7 +81,7 @@ How to get your contributions merged smoothly and quickly.
copyright holder for the contribution (yourself, if you are signing the
individual CLA, or your company, for corporate CLAs) in the same PR as your
contribution. This needs to be done only once, for each company, or
- individual.
+ individual. Please keep this file in alphabetical order.
- Maintain **clean commit history** and use **meaningful commit messages**.
PRs with messy commit history are difficult to review and won't be merged.
diff --git a/Makefile b/Makefile
index 5ef7e83b11..7b4a1fb0d5 100644
--- a/Makefile
+++ b/Makefile
@@ -438,8 +438,8 @@ Q = @
endif
CORE_VERSION = 7.0.0-dev
-CPP_VERSION = 1.17.0-dev
-CSHARP_VERSION = 1.17.0-dev
+CPP_VERSION = 1.18.0-dev
+CSHARP_VERSION = 1.18.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -1135,6 +1135,7 @@ auth_property_iterator_test: $(BINDIR)/$(CONFIG)/auth_property_iterator_test
backoff_test: $(BINDIR)/$(CONFIG)/backoff_test
bdp_estimator_test: $(BINDIR)/$(CONFIG)/bdp_estimator_test
bm_arena: $(BINDIR)/$(CONFIG)/bm_arena
+bm_byte_buffer: $(BINDIR)/$(CONFIG)/bm_byte_buffer
bm_call_create: $(BINDIR)/$(CONFIG)/bm_call_create
bm_channel: $(BINDIR)/$(CONFIG)/bm_channel
bm_chttp2_hpack: $(BINDIR)/$(CONFIG)/bm_chttp2_hpack
@@ -1168,6 +1169,7 @@ client_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/client_interceptors_end2en
client_lb_end2end_test: $(BINDIR)/$(CONFIG)/client_lb_end2end_test
codegen_test_full: $(BINDIR)/$(CONFIG)/codegen_test_full
codegen_test_minimal: $(BINDIR)/$(CONFIG)/codegen_test_minimal
+context_list_test: $(BINDIR)/$(CONFIG)/context_list_test
credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test
cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
@@ -1322,7 +1324,9 @@ h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test
h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test
h2_full+workarounds_test: $(BINDIR)/$(CONFIG)/h2_full+workarounds_test
h2_http_proxy_test: $(BINDIR)/$(CONFIG)/h2_http_proxy_test
-h2_local_test: $(BINDIR)/$(CONFIG)/h2_local_test
+h2_local_ipv4_test: $(BINDIR)/$(CONFIG)/h2_local_ipv4_test
+h2_local_ipv6_test: $(BINDIR)/$(CONFIG)/h2_local_ipv6_test
+h2_local_uds_test: $(BINDIR)/$(CONFIG)/h2_local_uds_test
h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test
h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test
h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test
@@ -1580,7 +1584,9 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/h2_full+trace_test \
$(BINDIR)/$(CONFIG)/h2_full+workarounds_test \
$(BINDIR)/$(CONFIG)/h2_http_proxy_test \
- $(BINDIR)/$(CONFIG)/h2_local_test \
+ $(BINDIR)/$(CONFIG)/h2_local_ipv4_test \
+ $(BINDIR)/$(CONFIG)/h2_local_ipv6_test \
+ $(BINDIR)/$(CONFIG)/h2_local_uds_test \
$(BINDIR)/$(CONFIG)/h2_oauth2_test \
$(BINDIR)/$(CONFIG)/h2_proxy_test \
$(BINDIR)/$(CONFIG)/h2_sockpair_test \
@@ -1640,6 +1646,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/backoff_test \
$(BINDIR)/$(CONFIG)/bdp_estimator_test \
$(BINDIR)/$(CONFIG)/bm_arena \
+ $(BINDIR)/$(CONFIG)/bm_byte_buffer \
$(BINDIR)/$(CONFIG)/bm_call_create \
$(BINDIR)/$(CONFIG)/bm_channel \
$(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
@@ -1673,6 +1680,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
+ $(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/credentials_test \
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
$(BINDIR)/$(CONFIG)/cxx_slice_test \
@@ -1823,6 +1831,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/backoff_test \
$(BINDIR)/$(CONFIG)/bdp_estimator_test \
$(BINDIR)/$(CONFIG)/bm_arena \
+ $(BINDIR)/$(CONFIG)/bm_byte_buffer \
$(BINDIR)/$(CONFIG)/bm_call_create \
$(BINDIR)/$(CONFIG)/bm_channel \
$(BINDIR)/$(CONFIG)/bm_chttp2_hpack \
@@ -1856,6 +1865,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
+ $(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/credentials_test \
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
$(BINDIR)/$(CONFIG)/cxx_slice_test \
@@ -2256,6 +2266,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/bdp_estimator_test || ( echo test bdp_estimator_test failed ; exit 1 )
$(E) "[RUN] Testing bm_arena"
$(Q) $(BINDIR)/$(CONFIG)/bm_arena || ( echo test bm_arena failed ; exit 1 )
+ $(E) "[RUN] Testing bm_byte_buffer"
+ $(Q) $(BINDIR)/$(CONFIG)/bm_byte_buffer || ( echo test bm_byte_buffer failed ; exit 1 )
$(E) "[RUN] Testing bm_call_create"
$(Q) $(BINDIR)/$(CONFIG)/bm_call_create || ( echo test bm_call_create failed ; exit 1 )
$(E) "[RUN] Testing bm_channel"
@@ -2320,6 +2332,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 )
$(E) "[RUN] Testing codegen_test_minimal"
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_minimal || ( echo test codegen_test_minimal failed ; exit 1 )
+ $(E) "[RUN] Testing context_list_test"
+ $(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 )
$(E) "[RUN] Testing credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 )
$(E) "[RUN] Testing cxx_byte_buffer_test"
@@ -2738,12 +2752,12 @@ $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: protoc_dep_error
else
-$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc
+$(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc
$(E) "[PROTOC] Generating protobuf CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
-$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+$(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc: src/proto/grpc/testing/echo.proto $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
$(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
$(Q) mkdir -p `dirname $@`
$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=generate_mock_code=true:$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
@@ -2846,6 +2860,22 @@ $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc: src/pro
endif
ifeq ($(NO_PROTOC),true)
+$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: protoc_dep_error
+$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: protoc_dep_error
+else
+
+$(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc: src/proto/grpc/testing/simple_messages.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[PROTOC] Generating protobuf CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc: src/proto/grpc/testing/simple_messages.proto $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+ $(E) "[GRPC] Generating gRPC's protobuf service CC file from $<"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin$(EXECUTABLE_SUFFIX) $<
+endif
+
+ifeq ($(NO_PROTOC),true)
$(GENDIR)/src/proto/grpc/testing/stats.pb.cc: protoc_dep_error
$(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: protoc_dep_error
else
@@ -3064,7 +3094,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3073,7 +3103,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3082,7 +3112,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_error_details.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3091,7 +3121,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3100,7 +3130,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3109,7 +3139,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpcpp_channelz.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so
endif
ifneq ($(SYSTEM),MINGW32)
@@ -3126,7 +3156,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
endif
ifneq ($(SYSTEM),MINGW32)
@@ -3607,6 +3637,7 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -3713,15 +3744,15 @@ LIBGRPC_SRC = \
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4024,6 +4055,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -4058,15 +4090,15 @@ LIBGRPC_CRONET_SRC = \
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4240,6 +4272,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
test/core/end2end/cq_verifier.cc \
test/core/end2end/fixtures/http_proxy_fixture.cc \
+ test/core/end2end/fixtures/local_util.cc \
test/core/end2end/fixtures/proxy.cc \
test/core/iomgr/endpoint_tests.cc \
test/core/util/debugger_macros.cc \
@@ -4422,15 +4455,15 @@ LIBGRPC_TEST_UTIL_SRC = \
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4442,6 +4475,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -4545,6 +4579,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
test/core/end2end/cq_verifier.cc \
test/core/end2end/fixtures/http_proxy_fixture.cc \
+ test/core/end2end/fixtures/local_util.cc \
test/core/end2end/fixtures/proxy.cc \
test/core/iomgr/endpoint_tests.cc \
test/core/util/debugger_macros.cc \
@@ -4727,15 +4762,15 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -4747,6 +4782,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -4993,6 +5029,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -5032,15 +5069,15 @@ LIBGRPC_UNSECURE_SRC = \
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -5330,6 +5367,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
include/grpcpp/alarm.h \
+ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
@@ -5672,6 +5710,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -5858,15 +5897,15 @@ LIBGRPC++_CRONET_SRC = \
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -5922,6 +5961,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
include/grpcpp/alarm.h \
+ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
@@ -6411,6 +6451,8 @@ LIBGRPC++_TEST_UTIL_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \
+ test/cpp/end2end/test_health_check_service_impl.cc \
test/cpp/end2end/test_service_impl.cc \
test/cpp/util/byte_buffer_proto_helper.cc \
test/cpp/util/channel_trace_proto_helper.cc \
@@ -6563,14 +6605,15 @@ ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep)
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/channel_trace_proto_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \
@@ -6578,6 +6621,8 @@ LIBGRPC++_TEST_UTIL_UNSECURE_SRC = \
$(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
+ $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc \
+ test/cpp/end2end/test_health_check_service_impl.cc \
test/cpp/end2end/test_service_impl.cc \
test/cpp/util/byte_buffer_proto_helper.cc \
test/cpp/util/string_ref_helper.cc \
@@ -6727,11 +6772,12 @@ ifneq ($(NO_DEPS),true)
-include $(LIBGRPC++_TEST_UTIL_UNSECURE_OBJS:.o=.dep)
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_health_check_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/simple_messages.grpc.pb.cc
LIBGRPC++_UNSECURE_SRC = \
@@ -6824,6 +6870,7 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/support/sync_stream.h \
include/grpc++/support/time.h \
include/grpcpp/alarm.h \
+ include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
@@ -16048,6 +16095,50 @@ endif
endif
+BM_BYTE_BUFFER_SRC = \
+ test/cpp/microbenchmarks/bm_byte_buffer.cc \
+
+BM_BYTE_BUFFER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BM_BYTE_BUFFER_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/bm_byte_buffer: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/bm_byte_buffer: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/bm_byte_buffer: $(PROTOBUF_DEP) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(BM_BYTE_BUFFER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/bm_byte_buffer
+
+endif
+
+endif
+
+$(BM_BYTE_BUFFER_OBJS): CPPFLAGS += -Ithird_party/benchmark/include -DHAVE_POSIX_REGEX
+$(OBJDIR)/$(CONFIG)/test/cpp/microbenchmarks/bm_byte_buffer.o: $(LIBDIR)/$(CONFIG)/libgrpc_benchmark.a $(LIBDIR)/$(CONFIG)/libbenchmark.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+
+deps_bm_byte_buffer: $(BM_BYTE_BUFFER_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(BM_BYTE_BUFFER_OBJS:.o=.dep)
+endif
+endif
+
+
BM_CALL_CREATE_SRC = \
test/cpp/microbenchmarks/bm_call_create.cc \
@@ -17548,6 +17639,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto
$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+CONTEXT_LIST_TEST_SRC = \
+ test/core/transport/chttp2/context_list_test.cc \
+
+CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/context_list_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/context_list_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
CREDENTIALS_TEST_SRC = \
test/cpp/client/credentials_test.cc \
@@ -23583,34 +23717,98 @@ endif
endif
-H2_LOCAL_TEST_SRC = \
- test/core/end2end/fixtures/h2_local.cc \
+H2_LOCAL_IPV4_TEST_SRC = \
+ test/core/end2end/fixtures/h2_local_ipv4.cc \
+
+H2_LOCAL_IPV4_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV4_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV4_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv4_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv4.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_local_ipv4_test: $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_LOCAL_IPV4_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+H2_LOCAL_IPV6_TEST_SRC = \
+ test/core/end2end/fixtures/h2_local_ipv6.cc \
+
+H2_LOCAL_IPV6_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_IPV6_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_IPV6_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_ipv6_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_ipv6.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_local_ipv6_test: $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_LOCAL_IPV6_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
+H2_LOCAL_UDS_TEST_SRC = \
+ test/core/end2end/fixtures/h2_local_uds.cc \
-H2_LOCAL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_TEST_SRC))))
+H2_LOCAL_UDS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOCAL_UDS_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
-$(BINDIR)/$(CONFIG)/h2_local_test: openssl_dep_error
+$(BINDIR)/$(CONFIG)/h2_local_uds_test: openssl_dep_error
else
-$(BINDIR)/$(CONFIG)/h2_local_test: $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
- $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_test
+ $(Q) $(LD) $(LDFLAGS) $(H2_LOCAL_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_local_uds_test
endif
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_local_uds.o: $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_h2_local_test: $(H2_LOCAL_TEST_OBJS:.o=.dep)
+deps_h2_local_uds_test: $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
--include $(H2_LOCAL_TEST_OBJS:.o=.dep)
+-include $(H2_LOCAL_UDS_TEST_OBJS:.o=.dep)
endif
endif
@@ -25070,6 +25268,7 @@ test/core/tsi/alts/crypt/gsec_test_util.cc: $(OPENSSL_DEP)
test/core/tsi/alts/handshaker/alts_handshaker_service_api_test_lib.cc: $(OPENSSL_DEP)
test/core/util/reconnect_server.cc: $(OPENSSL_DEP)
test/core/util/test_tcp_server.cc: $(OPENSSL_DEP)
+test/cpp/end2end/test_health_check_service_impl.cc: $(OPENSSL_DEP)
test/cpp/end2end/test_service_impl.cc: $(OPENSSL_DEP)
test/cpp/interop/client.cc: $(OPENSSL_DEP)
test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index c0de5289ee..544fefbc48 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -20,3 +20,4 @@ include src/python/grpcio/README.rst
include requirements.txt
include etc/roots.pem
include Makefile
+include LICENSE
diff --git a/README.md b/README.md
index 1960f44137..b3a4c1f17d 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
gRPC - An RPC library and framework
===================================
-gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems.
+gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. gRPC enables client and server applications to communicate transparently, and simplifies the building of connected systems.
<table>
<tr>
@@ -18,10 +18,10 @@ gRPC is a modern, open source, high-performance remote procedure call (RPC) fram
# To start using gRPC
-To maximize usability, gRPC supports the standard way of adding dependencies in your language of choice (if there is one).
-In most languages, the gRPC runtime comes in form of a package available in your language's package manager.
+To maximize usability, gRPC supports the standard method for adding dependencies to a user's chosen language (if there is one).
+In most languages, the gRPC runtime comes as a package available in a user's language package manager.
-For instructions on how to use the language-specific gRPC runtime in your project, please refer to these documents
+For instructions on how to use the language-specific gRPC runtime for a project, please refer to these documents
* [C++](src/cpp): follow the instructions under the `src/cpp` directory
* [C#](src/csharp): NuGet package `Grpc`
@@ -35,7 +35,7 @@ For instructions on how to use the language-specific gRPC runtime in your projec
* [Ruby](src/ruby): `gem install grpc`
* [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions
-You can find per-language quickstart guides and tutorials in [Documentation section on grpc.io website](https://grpc.io/docs/). The code examples are available in the [examples](examples) directory.
+Per-language quickstart guides and tutorials can be found in the [documentation section on the grpc.io website](https://grpc.io/docs/). Code examples are available in the [examples](examples) directory.
Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are uploaded daily to [packages.grpc.io](https://packages.grpc.io).
@@ -43,9 +43,9 @@ Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are up
Contributions are welcome!
-Please read [How to contribute](CONTRIBUTING.md) which will guide you through the entire workflow of how to build the source code, how to run the tests and how to contribute your changes to
+Please read [How to contribute](CONTRIBUTING.md) which will guide you through the entire workflow of how to build the source code, how to run the tests, and how to contribute changes to
the gRPC codebase.
-The document also contains info on how the contributing process works and contains best practices for creating contributions.
+The "How to contribute" document also contains info on how the contribution process works and contains best practices for creating contributions.
# Troubleshooting
@@ -53,7 +53,7 @@ Sometimes things go wrong. Please check out the [Troubleshooting guide](TROUBLES
# Performance
-See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for the performance numbers for the latest released version.
+See the [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for performance numbers of the latest released version.
# Concepts
@@ -61,9 +61,9 @@ See [gRPC Concepts](CONCEPTS.md)
# About This Repository
-This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core](src/core).
+This repository contains source code for gRPC libraries implemented in multiple languages written on top of a shared C core library [src/core](src/core).
-Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries.
+Libraries in different languages may be in various states of development. We are seeking contributions for all of these libraries:
| Language | Source |
|-------------------------|-------------------------------------|
diff --git a/WORKSPACE b/WORKSPACE
index a547c24cbe..81371bf418 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,45 +1,62 @@
-workspace(name="com_github_grpc_grpc")
+workspace(name = "com_github_grpc_grpc")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+
grpc_deps()
+
grpc_test_only_deps()
-new_http_archive(
- name="cython",
- sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
- urls=[
+register_execution_platforms(
+ "//third_party/toolchains:rbe_ubuntu1604",
+ "//third_party/toolchains:rbe_ubuntu1604_large",
+)
+
+register_toolchains(
+ "//third_party/toolchains:cc-toolchain-clang-x86_64-default",
+)
+
+http_archive(
+ name = "cython",
+ build_file = "//third_party:cython.BUILD",
+ sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
+ strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
+ urls = [
"https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz",
],
- strip_prefix="cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
- build_file="//third_party:cython.BUILD",
)
load("//third_party/py:python_configure.bzl", "python_configure")
-python_configure(name="local_config_python")
+
+python_configure(name = "local_config_python")
git_repository(
- name="io_bazel_rules_python",
- remote="https://github.com/bazelbuild/rules_python.git",
- commit="8b5d0683a7d878b28fffe464779c8a53659fc645",
+ name = "io_bazel_rules_python",
+ commit = "8b5d0683a7d878b28fffe464779c8a53659fc645",
+ remote = "https://github.com/bazelbuild/rules_python.git",
)
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import")
pip_repositories()
+
pip_import(
- name="grpc_python_dependencies",
- requirements="//:requirements.bazel.txt",
+ name = "grpc_python_dependencies",
+ requirements = "//:requirements.bazel.txt",
)
load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
+
pip_install()
# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged.
git_repository(
- name="org_pubref_rules_protobuf",
- remote="https://github.com/ghostwriternr/rules_protobuf",
- tag="v0.8.2.1-alpha",
+ name = "org_pubref_rules_protobuf",
+ remote = "https://github.com/ghostwriternr/rules_protobuf",
+ tag = "v0.8.2.1-alpha",
)
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")
+
py_proto_repositories()
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index 159ebd5d1f..65fe5a10aa 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -131,7 +131,7 @@ def grpc_proto_library(
generate_mocks = generate_mocks,
)
-def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = []):
+def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = [], exec_compatible_with = []):
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
@@ -145,6 +145,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"linkopts": if_not_windows(["-pthread"]),
"size": size,
"timeout": timeout,
+ "exec_compatible_with": exec_compatible_with,
}
if uses_polling:
native.cc_test(testonly = True, tags = ["manual"], **args)
@@ -162,6 +163,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"$(location %s)" % name,
] + args["args"],
tags = tags,
+ exec_compatible_with = exec_compatible_with,
)
else:
native.cc_test(**args)
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index 8626817855..3eacd2b047 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -1,5 +1,8 @@
"""Load dependencies needed to compile and test the grpc library as a 3rd-party consumer."""
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+
def grpc_deps():
"""Loads dependencies need to compile and test the grpc library."""
@@ -9,6 +12,11 @@ def grpc_deps():
)
native.bind(
+ name = "upblib",
+ actual = "@upb//:upb",
+ )
+
+ native.bind(
name = "absl-base",
actual = "@com_google_absl//absl/base",
)
@@ -99,14 +107,14 @@ def grpc_deps():
)
if "boringssl" not in native.existing_rules():
- native.http_archive(
+ http_archive(
name = "boringssl",
# on the chromium-stable-with-bazel branch
url = "https://boringssl.googlesource.com/boringssl/+archive/afc30d43eef92979b05776ec0963c9cede5fb80f.tar.gz",
)
if "com_github_madler_zlib" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_madler_zlib",
build_file = "@com_github_grpc_grpc//third_party:zlib.BUILD",
strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f",
@@ -114,14 +122,14 @@ def grpc_deps():
)
if "com_google_protobuf" not in native.existing_rules():
- native.http_archive(
+ http_archive(
name = "com_google_protobuf",
strip_prefix = "protobuf-48cb18e5c419ddd23d9badcfe4e9df7bde1979b2",
url = "https://github.com/google/protobuf/archive/48cb18e5c419ddd23d9badcfe4e9df7bde1979b2.tar.gz",
)
if "com_github_nanopb_nanopb" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_nanopb_nanopb",
build_file = "@com_github_grpc_grpc//third_party:nanopb.BUILD",
strip_prefix = "nanopb-f8ac463766281625ad710900479130c7fcb4d63b",
@@ -129,7 +137,7 @@ def grpc_deps():
)
if "com_github_google_googletest" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_google_googletest",
build_file = "@com_github_grpc_grpc//third_party:gtest.BUILD",
strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780",
@@ -137,14 +145,14 @@ def grpc_deps():
)
if "com_github_gflags_gflags" not in native.existing_rules():
- native.http_archive(
+ http_archive(
name = "com_github_gflags_gflags",
strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e",
url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz",
)
if "com_github_google_benchmark" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_google_benchmark",
build_file = "@com_github_grpc_grpc//third_party:benchmark.BUILD",
strip_prefix = "benchmark-9913418d323e64a0111ca0da81388260c2bbe1e9",
@@ -152,7 +160,7 @@ def grpc_deps():
)
if "com_github_cares_cares" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_cares_cares",
build_file = "@com_github_grpc_grpc//third_party:cares/cares.BUILD",
strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce",
@@ -160,14 +168,14 @@ def grpc_deps():
)
if "com_google_absl" not in native.existing_rules():
- native.http_archive(
+ http_archive(
name = "com_google_absl",
strip_prefix = "abseil-cpp-cd95e71df6eaf8f2a282b1da556c2cf1c9b09207",
url = "https://github.com/abseil/abseil-cpp/archive/cd95e71df6eaf8f2a282b1da556c2cf1c9b09207.tar.gz",
)
if "com_github_bazelbuild_bazeltoolchains" not in native.existing_rules():
- native.http_archive(
+ http_archive(
name = "com_github_bazelbuild_bazeltoolchains",
strip_prefix = "bazel-toolchains-280edaa6f93623074513d2b426068de42e62ea4d",
urls = [
@@ -178,12 +186,19 @@ def grpc_deps():
)
if "io_opencensus_cpp" not in native.existing_rules():
- native.http_archive(
+ http_archive(
name = "io_opencensus_cpp",
strip_prefix = "opencensus-cpp-fdf0f308b1631bb4a942e32ba5d22536a6170274",
url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz",
)
+ if "upb" not in native.existing_rules():
+ http_archive(
+ name = "upb",
+ strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3",
+ url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz",
+ )
+
# TODO: move some dependencies from "grpc_deps" here?
def grpc_test_only_deps():
@@ -200,7 +215,7 @@ def grpc_test_only_deps():
)
if "com_github_twisted_twisted" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_twisted_twisted",
strip_prefix = "twisted-twisted-17.5.0",
url = "https://github.com/twisted/twisted/archive/twisted-17.5.0.zip",
@@ -208,7 +223,7 @@ def grpc_test_only_deps():
)
if "com_github_yaml_pyyaml" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_yaml_pyyaml",
strip_prefix = "pyyaml-3.12",
url = "https://github.com/yaml/pyyaml/archive/3.12.zip",
@@ -216,7 +231,7 @@ def grpc_test_only_deps():
)
if "com_github_twisted_incremental" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_twisted_incremental",
strip_prefix = "incremental-incremental-17.5.0",
url = "https://github.com/twisted/incremental/archive/incremental-17.5.0.zip",
@@ -224,7 +239,7 @@ def grpc_test_only_deps():
)
if "com_github_zopefoundation_zope_interface" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_zopefoundation_zope_interface",
strip_prefix = "zope.interface-4.4.3",
url = "https://github.com/zopefoundation/zope.interface/archive/4.4.3.zip",
@@ -232,7 +247,7 @@ def grpc_test_only_deps():
)
if "com_github_twisted_constantly" not in native.existing_rules():
- native.new_http_archive(
+ http_archive(
name = "com_github_twisted_constantly",
strip_prefix = "constantly-15.1.0",
url = "https://github.com/twisted/constantly/archive/15.1.0.zip",
diff --git a/build.yaml b/build.yaml
index 831aef419e..7f1f11a3c0 100644
--- a/build.yaml
+++ b/build.yaml
@@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 7.0.0-dev
- g_stands_for: gizmo
- version: 1.17.0-dev
+ g_stands_for: goose
+ version: 1.18.0-dev
filegroups:
- name: alts_proto
headers:
@@ -440,6 +440,7 @@ filegroups:
- src/core/lib/iomgr/call_combiner.h
- src/core/lib/iomgr/closure.h
- src/core/lib/iomgr/combiner.h
+ - src/core/lib/iomgr/dynamic_annotations.h
- src/core/lib/iomgr/endpoint.h
- src/core/lib/iomgr/endpoint_pair.h
- src/core/lib/iomgr/error.h
@@ -580,14 +581,15 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.h
- src/core/ext/filters/client_channel/lb_policy_factory.h
- src/core/ext/filters/client_channel/lb_policy_registry.h
- - src/core/ext/filters/client_channel/method_params.h
- src/core/ext/filters/client_channel/parse_address.h
- src/core/ext/filters/client_channel/proxy_mapper.h
- src/core/ext/filters/client_channel/proxy_mapper_registry.h
- src/core/ext/filters/client_channel/resolver.h
- src/core/ext/filters/client_channel/resolver_factory.h
- src/core/ext/filters/client_channel/resolver_registry.h
+ - src/core/ext/filters/client_channel/resolver_result_parsing.h
- src/core/ext/filters/client_channel/retry_throttle.h
+ - src/core/ext/filters/client_channel/server_address.h
- src/core/ext/filters/client_channel/subchannel.h
- src/core/ext/filters/client_channel/subchannel_index.h
src:
@@ -602,15 +604,15 @@ filegroups:
- 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
- - src/core/ext/filters/client_channel/lb_policy_factory.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
- - src/core/ext/filters/client_channel/method_params.cc
- src/core/ext/filters/client_channel/parse_address.cc
- src/core/ext/filters/client_channel/proxy_mapper.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver_registry.cc
+ - src/core/ext/filters/client_channel/resolver_result_parsing.cc
- src/core/ext/filters/client_channel/retry_throttle.cc
+ - src/core/ext/filters/client_channel/server_address.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_index.cc
plugin: grpc_client_channel
@@ -898,6 +900,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
- test/core/end2end/cq_verifier.h
- test/core/end2end/fixtures/http_proxy_fixture.h
+ - test/core/end2end/fixtures/local_util.h
- test/core/end2end/fixtures/proxy.h
- test/core/iomgr/endpoint_tests.h
- test/core/util/debugger_macros.h
@@ -918,6 +921,7 @@ filegroups:
- src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
- test/core/end2end/cq_verifier.cc
- test/core/end2end/fixtures/http_proxy_fixture.cc
+ - test/core/end2end/fixtures/local_util.cc
- test/core/end2end/fixtures/proxy.cc
- test/core/iomgr/endpoint_tests.cc
- test/core/util/debugger_macros.cc
@@ -962,6 +966,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/bin_decoder.h
- src/core/ext/transport/chttp2/transport/bin_encoder.h
- src/core/ext/transport/chttp2/transport/chttp2_transport.h
+ - src/core/ext/transport/chttp2/transport/context_list.h
- src/core/ext/transport/chttp2/transport/flow_control.h
- src/core/ext/transport/chttp2/transport/frame.h
- src/core/ext/transport/chttp2/transport/frame_data.h
@@ -984,6 +989,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/bin_encoder.cc
- src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
- src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ - src/core/ext/transport/chttp2/transport/context_list.cc
- src/core/ext/transport/chttp2/transport/flow_control.cc
- src/core/ext/transport/chttp2/transport/frame_data.cc
- src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -1321,6 +1327,7 @@ filegroups:
- include/grpc++/support/sync_stream.h
- include/grpc++/support/time.h
- include/grpcpp/alarm.h
+ - include/grpcpp/alarm_impl.h
- include/grpcpp/channel.h
- include/grpcpp/client_context.h
- include/grpcpp/completion_queue.h
@@ -1752,6 +1759,7 @@ libs:
build: private
language: c++
headers:
+ - test/cpp/end2end/test_health_check_service_impl.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/util/byte_buffer_proto_helper.h
- test/cpp/util/channel_trace_proto_helper.h
@@ -1765,6 +1773,8 @@ libs:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
+ - src/proto/grpc/testing/simple_messages.proto
+ - test/cpp/end2end/test_health_check_service_impl.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/util/byte_buffer_proto_helper.cc
- test/cpp/util/channel_trace_proto_helper.cc
@@ -1785,6 +1795,7 @@ libs:
build: private
language: c++
headers:
+ - test/cpp/end2end/test_health_check_service_impl.h
- test/cpp/end2end/test_service_impl.h
- test/cpp/util/byte_buffer_proto_helper.h
- test/cpp/util/string_ref_helper.h
@@ -1794,6 +1805,8 @@ libs:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/echo.proto
- src/proto/grpc/testing/duplicate/echo_duplicate.proto
+ - src/proto/grpc/testing/simple_messages.proto
+ - test/cpp/end2end/test_health_check_service_impl.cc
- test/cpp/end2end/test_service_impl.cc
- test/cpp/util/byte_buffer_proto_helper.cc
- test/cpp/util/string_ref_helper.cc
@@ -4004,6 +4017,28 @@ targets:
- linux
- posix
uses_polling: false
+- name: bm_byte_buffer
+ build: test
+ language: c++
+ src:
+ - test/cpp/microbenchmarks/bm_byte_buffer.cc
+ deps:
+ - grpc_benchmark
+ - benchmark
+ - grpc++_test_util_unsecure
+ - grpc_test_util_unsecure
+ - grpc++_unsecure
+ - grpc_unsecure
+ - gpr_test_util
+ - gpr
+ - grpc++_test_config
+ benchmark: true
+ defaults: benchmark
+ platforms:
+ - mac
+ - linux
+ - posix
+ uses_polling: false
- name: bm_call_create
build: test
language: c++
@@ -4602,6 +4637,18 @@ targets:
- grpc++_codegen_base
- grpc++_codegen_base_src
uses_polling: false
+- name: context_list_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/transport/chttp2/context_list_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ uses_polling: false
- name: credentials_test
gtest: true
build: test
diff --git a/cmake/cares.cmake b/cmake/cares.cmake
index 3d4a0cae76..4ea0d8725d 100644
--- a/cmake/cares.cmake
+++ b/cmake/cares.cmake
@@ -18,6 +18,10 @@ if("${gRPC_CARES_PROVIDER}" STREQUAL "module")
endif()
set(CARES_SHARED OFF CACHE BOOL "disable shared library")
set(CARES_STATIC ON CACHE BOOL "link cares statically")
+ if(gRPC_BACKWARDS_COMPATIBILITY_MODE)
+ # See https://github.com/grpc/grpc/issues/17255
+ set(HAVE_LIBNSL OFF CACHE BOOL "avoid cares dependency on libnsl")
+ endif()
add_subdirectory(third_party/cares/cares)
if(TARGET c-ares)
diff --git a/config.m4 b/config.m4
index d0e22a8e43..16de5204bb 100644
--- a/config.m4
+++ b/config.m4
@@ -241,6 +241,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -347,15 +348,15 @@ if test "$PHP_GRPC" != "no"; then
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 \
- src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
+ src/core/ext/filters/client_channel/server_address.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
@@ -664,7 +665,8 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/third_party/fiat/curve25519.c \
, $ext_shared, , -fvisibility=hidden \
-DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN \
- -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0)
+ -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 \
+ -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1)
PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
diff --git a/config.w32 b/config.w32
index 07473ff5a9..be10faab9c 100644
--- a/config.w32
+++ b/config.w32
@@ -216,6 +216,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_plugin.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_transport.cc " +
+ "src\\core\\ext\\transport\\chttp2\\transport\\context_list.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\flow_control.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_data.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_goaway.cc " +
@@ -322,15 +323,15 @@ if (PHP_GRPC != "no") {
"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 " +
- "src\\core\\ext\\filters\\client_channel\\lb_policy_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
- "src\\core\\ext\\filters\\client_channel\\method_params.cc " +
"src\\core\\ext\\filters\\client_channel\\parse_address.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " +
+ "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " +
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
+ "src\\core\\ext\\filters\\client_channel\\server_address.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " +
"src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index a5a8efb21c..1e49b4d3f1 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -16,4 +16,5 @@
- 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x)
- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x)
- 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x)
-- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/master)
+- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x)
+- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/master)
diff --git a/doc/grpc_release_schedule.md b/doc/grpc_release_schedule.md
new file mode 100644
index 0000000000..bacd375859
--- /dev/null
+++ b/doc/grpc_release_schedule.md
@@ -0,0 +1,22 @@
+# gRPC Release Schedule
+
+Below is the release schedule for gRPC [Java](https://github.com/grpc/grpc-java/releases), [Go](https://github.com/grpc/grpc-go/releases) and [Core](https://github.com/grpc/grpc/releases) and its dependent languages C++, C#, Objective-C, PHP, Python and Ruby.
+
+Releases are scheduled every six weeks on Tuesdays on a best effort basis. In some unavoidable situations a release may be delayed or a language may skip a release altogether and do the next release to catch up with other languages. See the past releases in the links above. A six-week cycle gives us a good balance between delivering new features/fixes quickly and keeping the release overhead low.
+
+Releases are cut from release branches. For Core and Java repos, the release branch is cut two weeks before the scheduled release date. For Go, the branch is cut just before the release. An RC (release candidate) is published for Core and its dependent languages just after the branch cut. This RC is later promoted to release version if no further changes are made to the release branch. We do our best to keep head of master branch stable at all times regardless of release schedule. Daily build packages from master branch for C#, PHP, Python, Ruby and Protoc plugins are published on [packages.grpc.io](https://packages.grpc.io/). If you depend on gRPC in production we recommend to set up your CI system to test the RCs and, if possible, the daily builds.
+
+Names of gRPC releases are [here](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md).
+
+Release |Scheduled Branch Cut|Scheduled Release Date
+--------|--------------------|-------------
+v1.17.0 |Nov 19, 2018 |Dec 4, 2018
+v1.18.0 |Jan 2, 2019 |Jan 15, 2019
+v1.19.0 |Feb 12, 2019 |Feb 26, 2019
+v1.20.0 |Mar 26, 2019 |Apr 9, 2019
+v1.21.0 |May 7, 2019 |May 21, 2019
+v1.22.0 |Jun 18, 2019 |Jul 2, 2019
+v1.23.0 |Jul 30, 2019 |Aug 13, 2019
+v1.24.0 |Sept 10, 2019 |Sept 24, 2019
+v1.25.0 |Oct 22, 2019 |Nov 5, 2019
+v1.26.0 |Dec 3, 2019 |Dec 17, 2019
diff --git a/doc/naming.md b/doc/naming.md
index 581c550567..5e54ca67b3 100644
--- a/doc/naming.md
+++ b/doc/naming.md
@@ -51,7 +51,9 @@ but may not be supported in other languages:
- `ipv6:address[:port][,address[:port],...]` -- IPv6 addresses
- Can specify multiple comma-delimited addresses of the form `address[:port]`:
- - `address` is the IPv6 address to use.
+ - `address` is the IPv6 address to use. To use with a `port` the `address`
+ must enclosed in literal square brakets (`[` and `]`). Example:
+ `ipv6:[2607:f8b0:400e:c00::ef]:443` or `ipv6:[::]:1234`
- `port` is the port to use. If not specified, 443 is used.
In the future, additional schemes such as `etcd` could be added.
diff --git a/doc/python/sphinx/conf.py b/doc/python/sphinx/conf.py
index 1eb3a5de7f..307c3bdaf6 100644
--- a/doc/python/sphinx/conf.py
+++ b/doc/python/sphinx/conf.py
@@ -19,6 +19,7 @@ import sys
PYTHON_FOLDER = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'..', '..', '..', 'src', 'python')
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio'))
+sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_channelz'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_health_checking'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_reflection'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_testing'))
@@ -63,6 +64,8 @@ autodoc_default_options = {
autodoc_mock_imports = [
'grpc._cython',
+ 'grpc_channelz.v1.channelz_pb2',
+ 'grpc_channelz.v1.channelz_pb2_grpc',
'grpc_health.v1.health_pb2',
'grpc_health.v1.health_pb2_grpc',
'grpc_reflection.v1alpha.reflection_pb2',
diff --git a/doc/python/sphinx/grpc_channelz.rst b/doc/python/sphinx/grpc_channelz.rst
new file mode 100644
index 0000000000..f65793a071
--- /dev/null
+++ b/doc/python/sphinx/grpc_channelz.rst
@@ -0,0 +1,12 @@
+gRPC Channelz
+====================
+
+What is gRPC Channelz?
+---------------------------------------------
+
+Design Document `gRPC Channelz <https://github.com/grpc/proposal/blob/master/A14-channelz.md>`_
+
+Module Contents
+---------------
+
+.. automodule:: grpc_channelz.v1.channelz
diff --git a/doc/python/sphinx/index.rst b/doc/python/sphinx/index.rst
index 322ca33e15..2f8a47a074 100644
--- a/doc/python/sphinx/index.rst
+++ b/doc/python/sphinx/index.rst
@@ -10,6 +10,7 @@ API Reference
:caption: Contents:
grpc
+ grpc_channelz
grpc_health_checking
grpc_reflection
grpc_testing
diff --git a/etc/roots.pem b/etc/roots.pem
index 3e6bbcd76e..be598710dd 100644
--- a/etc/roots.pem
+++ b/etc/roots.pem
@@ -329,36 +329,6 @@ OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
-----END CERTIFICATE-----
-# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
-# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
-# Label: "Visa eCommerce Root"
-# Serial: 25952180776285836048024890241505565794
-# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02
-# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62
-# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22
------BEGIN CERTIFICATE-----
-MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
-MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
-cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
-bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
-CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
-dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
-cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
-2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
-lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
-ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
-299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
-vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
-dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
-AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
-zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
-LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
-7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
-++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
-398znM/jra6O1I7mT1GvFpLgXPYHDw==
------END CERTIFICATE-----
-
# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
# Subject: CN=AAA Certificate Services O=Comodo CA Limited
# Label: "Comodo AAA Services root"
@@ -4340,3 +4310,245 @@ rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R1 O=Google Trust Services LLC
+# Subject: CN=GTS Root R1 O=Google Trust Services LLC
+# Label: "GTS Root R1"
+# Serial: 146587175971765017618439757810265552097
+# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85
+# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8
+# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
+MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
+cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM
+f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX
+mX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7
+zUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P
+fyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc
+vfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4
+Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp
+zBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO
+Rc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW
+k70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+
+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF
+lQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW
+Cu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1
+d5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z
+XPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR
+gyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3
+d8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv
+J4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg
+DdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM
++SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy
+F62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9
+SQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws
+E3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R2 O=Google Trust Services LLC
+# Subject: CN=GTS Root R2 O=Google Trust Services LLC
+# Label: "GTS Root R2"
+# Serial: 146587176055767053814479386953112547951
+# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b
+# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d
+# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH
+MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
+QzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy
+MDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl
+cnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv
+CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg
+GjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu
+XvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd
+re7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu
+PuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1
+mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K
+8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj
+x5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR
+nTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0
+kzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok
+twIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
+HQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp
+8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT
+vhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT
+z9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA
+pJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb
+pxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB
+R64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R
+RaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk
+0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC
+5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF
+izoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn
+yOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R3 O=Google Trust Services LLC
+# Subject: CN=GTS Root R3 O=Google Trust Services LLC
+# Label: "GTS Root R3"
+# Serial: 146587176140553309517047991083707763997
+# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25
+# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5
+# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5
+-----BEGIN CERTIFICATE-----
+MIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout
+736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A
+DDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk
+fCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA
+njWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd
+-----END CERTIFICATE-----
+
+# Issuer: CN=GTS Root R4 O=Google Trust Services LLC
+# Subject: CN=GTS Root R4 O=Google Trust Services LLC
+# Label: "GTS Root R4"
+# Serial: 146587176229350439916519468929765261721
+# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26
+# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb
+# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd
+-----BEGIN CERTIFICATE-----
+MIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw
+CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU
+MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw
+MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp
+Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu
+hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l
+xKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
+DgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0
+CMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx
+sbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==
+-----END CERTIFICATE-----
+
+# Issuer: CN=UCA Global G2 Root O=UniTrust
+# Subject: CN=UCA Global G2 Root O=UniTrust
+# Label: "UCA Global G2 Root"
+# Serial: 124779693093741543919145257850076631279
+# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8
+# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a
+# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9
+MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH
+bG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x
+CzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds
+b2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr
+b3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9
+kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm
+VHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R
+VogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc
+C/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj
+tm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY
+D0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv
+j5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl
+NaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6
+iIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP
+O6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV
+ZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj
+L3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5
+1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl
+1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU
+b3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV
+PtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj
+y88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb
+EGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg
+DMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI
++Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy
+YiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX
+UB+K+wb1whnw0A==
+-----END CERTIFICATE-----
+
+# Issuer: CN=UCA Extended Validation Root O=UniTrust
+# Subject: CN=UCA Extended Validation Root O=UniTrust
+# Label: "UCA Extended Validation Root"
+# Serial: 106100277556486529736699587978573607008
+# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2
+# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a
+# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24
+-----BEGIN CERTIFICATE-----
+MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH
+MQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF
+eHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx
+MDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV
+BAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog
+D4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS
+sPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop
+O2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk
+sHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi
+c0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj
+VMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz
+KuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/
+TuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G
+sx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs
+1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD
+fwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T
+AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN
+l8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR
+ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ
+VBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5
+c6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp
+4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s
+t2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj
+2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO
+vpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C
+xR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx
+cmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM
+fjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax
+-----END CERTIFICATE-----
+
+# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
+# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036
+# Label: "Certigna Root CA"
+# Serial: 269714418870597844693661054334862075617
+# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77
+# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43
+# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68
+-----BEGIN CERTIFICATE-----
+MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw
+WjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw
+MiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x
+MzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD
+VQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX
+BgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO
+ty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M
+CiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu
+I9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm
+TLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh
+C59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf
+ePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz
+IoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT
+Co/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k
+JWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5
+hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB
+GjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of
+1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov
+L3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo
+dHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr
+aHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq
+hkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L
+6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG
+HVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6
+0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB
+lA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi
+o2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1
+gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v
+faci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63
+Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh
+jWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw
+3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=
+-----END CERTIFICATE-----
diff --git a/examples/BUILD b/examples/BUILD
index 0f18cfa9ba..22f2f0a4f1 100644
--- a/examples/BUILD
+++ b/examples/BUILD
@@ -51,3 +51,18 @@ cc_binary(
defines = ["BAZEL_BUILD"],
deps = [":helloworld", "//:grpc++"],
)
+
+cc_binary(
+ name = "metadata_client",
+ srcs = ["cpp/metadata/greeter_client.cc"],
+ defines = ["BAZEL_BUILD"],
+ deps = [":helloworld", "//:grpc++"],
+)
+
+cc_binary(
+ name = "metadata_server",
+ srcs = ["cpp/metadata/greeter_server.cc"],
+ defines = ["BAZEL_BUILD"],
+ deps = [":helloworld", "//:grpc++"],
+)
+
diff --git a/examples/cpp/compression/Makefile b/examples/cpp/compression/Makefile
new file mode 100644
index 0000000000..47211886ff
--- /dev/null
+++ b/examples/cpp/compression/Makefile
@@ -0,0 +1,110 @@
+#
+# 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.
+#
+
+HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
+SYSTEM ?= $(HOST_SYSTEM)
+CXX = g++
+CPPFLAGS += `pkg-config --cflags protobuf grpc`
+CXXFLAGS += -std=c++11
+ifeq ($(SYSTEM),Darwin)
+LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
+ -lgrpc++_reflection\
+ -ldl
+else
+LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
+ -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
+ -ldl
+endif
+PROTOC = protoc
+GRPC_CPP_PLUGIN = grpc_cpp_plugin
+GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
+
+PROTOS_PATH = ../../protos
+
+vpath %.proto $(PROTOS_PATH)
+
+all: system-check greeter_client greeter_server
+
+greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+
+.PRECIOUS: %.grpc.pb.cc
+%.grpc.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
+
+.PRECIOUS: %.pb.cc
+%.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
+
+clean:
+ rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server
+
+
+# The following is to test your system and ensure a smoother experience.
+# They are by no means necessary to actually compile a grpc-enabled software.
+
+PROTOC_CMD = which $(PROTOC)
+PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3
+PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN)
+HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false)
+ifeq ($(HAS_PROTOC),true)
+HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
+endif
+HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false)
+
+SYSTEM_OK = false
+ifeq ($(HAS_VALID_PROTOC),true)
+ifeq ($(HAS_PLUGIN),true)
+SYSTEM_OK = true
+endif
+endif
+
+system-check:
+ifneq ($(HAS_VALID_PROTOC),true)
+ @echo " DEPENDENCY ERROR"
+ @echo
+ @echo "You don't have protoc 3.0.0 installed in your path."
+ @echo "Please install Google protocol buffers 3.0.0 and its compiler."
+ @echo "You can find it here:"
+ @echo
+ @echo " https://github.com/google/protobuf/releases/tag/v3.0.0"
+ @echo
+ @echo "Here is what I get when trying to evaluate your version of protoc:"
+ @echo
+ -$(PROTOC) --version
+ @echo
+ @echo
+endif
+ifneq ($(HAS_PLUGIN),true)
+ @echo " DEPENDENCY ERROR"
+ @echo
+ @echo "You don't have the grpc c++ protobuf plugin installed in your path."
+ @echo "Please install grpc. You can find it here:"
+ @echo
+ @echo " https://github.com/grpc/grpc"
+ @echo
+ @echo "Here is what I get when trying to detect if you have the plugin:"
+ @echo
+ -which $(GRPC_CPP_PLUGIN)
+ @echo
+ @echo
+endif
+ifneq ($(SYSTEM_OK),true)
+ @false
+endif
diff --git a/examples/cpp/compression/README.md b/examples/cpp/compression/README.md
new file mode 100644
index 0000000000..13988f2c0c
--- /dev/null
+++ b/examples/cpp/compression/README.md
@@ -0,0 +1,84 @@
+# gRPC C++ Message Compression Tutorial
+
+### Prerequisite
+Make sure you have run the [hello world example](../helloworld) or understood the basics of gRPC. We will not dive into the details that have been discussed in the hello world example.
+
+### Get the tutorial source code
+
+The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command:
+
+
+```sh
+$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
+```
+
+Change your current directory to examples/cpp/compression
+
+```sh
+$ cd examples/cpp/compression/
+```
+
+### Generating gRPC code
+
+To generate the client and server side interfaces:
+
+```sh
+$ make helloworld.grpc.pb.cc helloworld.pb.cc
+```
+Which internally invokes the proto-compiler as:
+
+```sh
+$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto
+$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto
+```
+
+### Writing a client and a server
+
+The client and the server can be based on the hello world example.
+
+Additionally, we can configure the compression settings.
+
+In the client, set the default compression algorithm of the channel via the channel arg.
+
+```cpp
+ ChannelArguments args;
+ // Set the default compression algorithm for the channel.
+ args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+ GreeterClient greeter(grpc::CreateCustomChannel(
+ "localhost:50051", grpc::InsecureChannelCredentials(), args));
+```
+
+Each call's compression configuration can be overwritten by client context.
+
+```cpp
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+```
+
+In the server, set the default compression algorithm via the server builder.
+
+```cpp
+ ServerBuilder builder;
+ // Set the default compression algorithm for the server.
+ builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+```
+
+Each call's compression configuration can be overwritten by server context.
+
+```cpp
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+```
+
+For a working example, refer to [greeter_client.cc](greeter_client.cc) and [greeter_server.cc](greeter_server.cc).
+
+Build and run the (compressing) client and the server by the following commands.
+
+```sh
+make
+./greeter_server
+```
+
+```sh
+./greeter_client
+```
diff --git a/examples/cpp/compression/greeter_client.cc b/examples/cpp/compression/greeter_client.cc
new file mode 100644
index 0000000000..a842817464
--- /dev/null
+++ b/examples/cpp/compression/greeter_client.cc
@@ -0,0 +1,93 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+using grpc::Channel;
+using grpc::ChannelArguments;
+using grpc::ClientContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class GreeterClient {
+ public:
+ GreeterClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ // Assembles the client's payload, sends it and presents the response back
+ // from the server.
+ std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context.set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+
+ // The actual RPC.
+ Status status = stub_->SayHello(&context, request, &reply);
+
+ // Act upon its status.
+ if (status.ok()) {
+ return reply.message();
+ } else {
+ std::cout << status.error_code() << ": " << status.error_message()
+ << std::endl;
+ return "RPC failed";
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+int main(int argc, char** argv) {
+ // Instantiate the client. It requires a channel, out of which the actual RPCs
+ // are created. This channel models a connection to an endpoint (in this case,
+ // localhost at port 50051). We indicate that the channel isn't authenticated
+ // (use of InsecureChannelCredentials()).
+ ChannelArguments args;
+ // Set the default compression algorithm for the channel.
+ args.SetCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+ GreeterClient greeter(grpc::CreateCustomChannel(
+ "localhost:50051", grpc::InsecureChannelCredentials(), args));
+ std::string user("world");
+ std::string reply = greeter.SayHello(user);
+ std::cout << "Greeter received: " << reply << std::endl;
+
+ return 0;
+}
diff --git a/examples/cpp/compression/greeter_server.cc b/examples/cpp/compression/greeter_server.cc
new file mode 100644
index 0000000000..7399017afb
--- /dev/null
+++ b/examples/cpp/compression/greeter_server.cc
@@ -0,0 +1,76 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+// Logic and data behind the server's behavior.
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ // Overwrite the call's compression algorithm to DEFLATE.
+ context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
+ std::string prefix("Hello ");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+void RunServer() {
+ std::string server_address("0.0.0.0:50051");
+ GreeterServiceImpl service;
+
+ ServerBuilder builder;
+ // Set the default compression algorithm for the server.
+ builder.SetDefaultCompressionAlgorithm(GRPC_COMPRESS_GZIP);
+ // Listen on the given address without any authentication mechanism.
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *synchronous* service.
+ builder.RegisterService(&service);
+ // Finally assemble the server.
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ std::cout << "Server listening on " << server_address << std::endl;
+
+ // Wait for the server to shutdown. Note that some other thread must be
+ // responsible for shutting down the server for this call to ever return.
+ server->Wait();
+}
+
+int main(int argc, char** argv) {
+ RunServer();
+
+ return 0;
+}
diff --git a/examples/cpp/metadata/Makefile b/examples/cpp/metadata/Makefile
new file mode 100644
index 0000000000..46be8bfaa3
--- /dev/null
+++ b/examples/cpp/metadata/Makefile
@@ -0,0 +1,96 @@
+#
+# 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.
+#
+ HOST_SYSTEM = $(shell uname | cut -f 1 -d_)
+SYSTEM ?= $(HOST_SYSTEM)
+CXX = g++
+CPPFLAGS += `pkg-config --cflags protobuf grpc`
+CXXFLAGS += -std=c++11
+ifeq ($(SYSTEM),Darwin)
+LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
+ -lgrpc++_reflection\
+ -ldl
+else
+LDFLAGS += -L/usr/local/lib `pkg-config --libs protobuf grpc++ grpc`\
+ -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed\
+ -ldl
+endif
+PROTOC = protoc
+GRPC_CPP_PLUGIN = grpc_cpp_plugin
+GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)`
+ PROTOS_PATH = ../../protos
+ vpath %.proto $(PROTOS_PATH)
+ all: system-check greeter_client greeter_server
+ greeter_client: helloworld.pb.o helloworld.grpc.pb.o greeter_client.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+ greeter_server: helloworld.pb.o helloworld.grpc.pb.o greeter_server.o
+ $(CXX) $^ $(LDFLAGS) -o $@
+ .PRECIOUS: %.grpc.pb.cc
+%.grpc.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --grpc_out=. --plugin=protoc-gen-grpc=$(GRPC_CPP_PLUGIN_PATH) $<
+ .PRECIOUS: %.pb.cc
+%.pb.cc: %.proto
+ $(PROTOC) -I $(PROTOS_PATH) --cpp_out=. $<
+ clean:
+ rm -f *.o *.pb.cc *.pb.h greeter_client greeter_server
+ # The following is to test your system and ensure a smoother experience.
+# They are by no means necessary to actually compile a grpc-enabled software.
+ PROTOC_CMD = which $(PROTOC)
+PROTOC_CHECK_CMD = $(PROTOC) --version | grep -q libprotoc.3
+PLUGIN_CHECK_CMD = which $(GRPC_CPP_PLUGIN)
+HAS_PROTOC = $(shell $(PROTOC_CMD) > /dev/null && echo true || echo false)
+ifeq ($(HAS_PROTOC),true)
+HAS_VALID_PROTOC = $(shell $(PROTOC_CHECK_CMD) 2> /dev/null && echo true || echo false)
+endif
+HAS_PLUGIN = $(shell $(PLUGIN_CHECK_CMD) > /dev/null && echo true || echo false)
+ SYSTEM_OK = false
+ifeq ($(HAS_VALID_PROTOC),true)
+ifeq ($(HAS_PLUGIN),true)
+SYSTEM_OK = true
+endif
+endif
+ system-check:
+ifneq ($(HAS_VALID_PROTOC),true)
+ @echo " DEPENDENCY ERROR"
+ @echo
+ @echo "You don't have protoc 3.0.0 installed in your path."
+ @echo "Please install Google protocol buffers 3.0.0 and its compiler."
+ @echo "You can find it here:"
+ @echo
+ @echo " https://github.com/google/protobuf/releases/tag/v3.0.0"
+ @echo
+ @echo "Here is what I get when trying to evaluate your version of protoc:"
+ @echo
+ -$(PROTOC) --version
+ @echo
+ @echo
+endif
+ifneq ($(HAS_PLUGIN),true)
+ @echo " DEPENDENCY ERROR"
+ @echo
+ @echo "You don't have the grpc c++ protobuf plugin installed in your path."
+ @echo "Please install grpc. You can find it here:"
+ @echo
+ @echo " https://github.com/grpc/grpc"
+ @echo
+ @echo "Here is what I get when trying to detect if you have the plugin:"
+ @echo
+ -which $(GRPC_CPP_PLUGIN)
+ @echo
+ @echo
+endif
+ifneq ($(SYSTEM_OK),true)
+ @false
+endif
diff --git a/examples/cpp/metadata/README.md b/examples/cpp/metadata/README.md
new file mode 100644
index 0000000000..96ad3d19bd
--- /dev/null
+++ b/examples/cpp/metadata/README.md
@@ -0,0 +1,66 @@
+# Metadata Example
+
+## Overview
+
+This example shows you how to add custom headers on the client and server and
+how to access them.
+
+Custom metadata must follow the "Custom-Metadata" format listed in
+https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md, with the
+exception of binary headers, which don't have to be base64 encoded.
+
+### Get the tutorial source code
+ The example code for this and our other examples lives in the `examples` directory. Clone this repository to your local machine by running the following command:
+ ```sh
+$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
+```
+ Change your current directory to examples/cpp/metadata
+ ```sh
+$ cd examples/cpp/metadata
+```
+
+### Generating gRPC code
+ To generate the client and server side interfaces:
+ ```sh
+$ make helloworld.grpc.pb.cc helloworld.pb.cc
+```
+Which internally invokes the proto-compiler as:
+ ```sh
+$ protoc -I ../../protos/ --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin ../../protos/helloworld.proto
+$ protoc -I ../../protos/ --cpp_out=. ../../protos/helloworld.proto
+```
+### Try it!
+Build client and server:
+
+```sh
+$ make
+```
+
+Run the server, which will listen on port 50051:
+
+```sh
+$ ./greeter_server
+```
+
+Run the client (in a different terminal):
+
+```sh
+$ ./greeter_client
+```
+
+If things go smoothly, you will see in the client terminal:
+
+"Client received initial metadata from server: initial metadata value"
+"Client received trailing metadata from server: trailing metadata value"
+"Client received message: Hello World"
+
+
+And in the server terminal:
+
+"Header key: custom-bin , value: 01234567"
+"Header key: custom-header , value: Custom Value"
+"Header key: user-agent , value: grpc-c++/1.16.0-dev grpc-c/6.0.0-dev (linux; chttp2; gao)"
+
+We did not add the user-agent metadata as a custom header. This shows how
+the gRPC framework adds some headers under the hood that may show up in the
+metadata map.
diff --git a/examples/cpp/metadata/greeter_client.cc b/examples/cpp/metadata/greeter_client.cc
new file mode 100644
index 0000000000..8049438993
--- /dev/null
+++ b/examples/cpp/metadata/greeter_client.cc
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+using grpc::Channel;
+using grpc::ClientContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+class CustomHeaderClient {
+ public:
+ CustomHeaderClient(std::shared_ptr<Channel> channel)
+ : stub_(Greeter::NewStub(channel)) {}
+
+ // Assembles the client's payload, sends it and presents the response back
+ // from the server.
+ std::string SayHello(const std::string& user) {
+ // Data we are sending to the server.
+ HelloRequest request;
+ request.set_name(user);
+
+ // Container for the data we expect from the server.
+ HelloReply reply;
+
+ // Context for the client. It could be used to convey extra information to
+ // the server and/or tweak certain RPC behaviors.
+ ClientContext context;
+
+ // Setting custom metadata to be sent to the server
+ context.AddMetadata("custom-header", "Custom Value");
+
+ // Setting custom binary metadata
+ char bytes[8] = {'\0', '\1', '\2', '\3',
+ '\4', '\5', '\6', '\7'};
+ context.AddMetadata("custom-bin", grpc::string(bytes, 8));
+
+ // The actual RPC.
+ Status status = stub_->SayHello(&context, request, &reply);
+
+ // Act upon its status.
+ if (status.ok()) {
+ std::cout << "Client received initial metadata from server: " << context.GetServerInitialMetadata().find("custom-server-metadata")->second << std::endl;
+ std::cout << "Client received trailing metadata from server: " << context.GetServerTrailingMetadata().find("custom-trailing-metadata")->second << std::endl;
+ return reply.message();
+ } else {
+ std::cout << status.error_code() << ": " << status.error_message()
+ << std::endl;
+ return "RPC failed";
+ }
+ }
+
+ private:
+ std::unique_ptr<Greeter::Stub> stub_;
+};
+
+int main(int argc, char** argv) {
+ // Instantiate the client. It requires a channel, out of which the actual RPCs
+ // are created. This channel models a connection to an endpoint (in this case,
+ // localhost at port 50051). We indicate that the channel isn't authenticated
+ // (use of InsecureChannelCredentials()).
+ CustomHeaderClient greeter(grpc::CreateChannel(
+ "localhost:50051", grpc::InsecureChannelCredentials()));
+ std::string user("world");
+ std::string reply = greeter.SayHello(user);
+ std::cout << "Client received message: " << reply << std::endl;
+ return 0;
+}
diff --git a/examples/cpp/metadata/greeter_server.cc b/examples/cpp/metadata/greeter_server.cc
new file mode 100644
index 0000000000..a9a4f33cb0
--- /dev/null
+++ b/examples/cpp/metadata/greeter_server.cc
@@ -0,0 +1,94 @@
+/*
+ *
+ * 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 <iostream>
+#include <memory>
+#include <string>
+
+#include <grpcpp/grpcpp.h>
+
+#ifdef BAZEL_BUILD
+#include "examples/protos/helloworld.grpc.pb.h"
+#else
+#include "helloworld.grpc.pb.h"
+#endif
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::Status;
+using helloworld::HelloRequest;
+using helloworld::HelloReply;
+using helloworld::Greeter;
+
+// Logic and data behind the server's behavior.
+class GreeterServiceImpl final : public Greeter::Service {
+ Status SayHello(ServerContext* context, const HelloRequest* request,
+ HelloReply* reply) override {
+ std::string prefix("Hello ");
+
+ // Get the client's initial metadata
+ std::cout << "Client metadata: " << std::endl;
+ const std::multimap<grpc::string_ref, grpc::string_ref> metadata = context->client_metadata();
+ for (auto iter = metadata.begin(); iter != metadata.end(); ++iter) {
+ std::cout << "Header key: " << iter->first << ", value: ";
+ // Check for binary value
+ size_t isbin = iter->first.find("-bin");
+ if ((isbin != std::string::npos) && (isbin + 4 == iter->first.size())) {
+ std::cout << std::hex;
+ for (auto c : iter->second) {
+ std::cout << static_cast<unsigned int>(c);
+ }
+ std::cout << std::dec;
+ } else {
+ std::cout << iter->second;
+ }
+ std::cout << std::endl;
+ }
+
+ context->AddInitialMetadata("custom-server-metadata", "initial metadata value");
+ context->AddTrailingMetadata("custom-trailing-metadata", "trailing metadata value");
+ reply->set_message(prefix + request->name());
+ return Status::OK;
+ }
+};
+
+void RunServer() {
+ std::string server_address("0.0.0.0:50051");
+ GreeterServiceImpl service;
+
+ ServerBuilder builder;
+ // Listen on the given address without any authentication mechanism.
+ builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+ // Register "service" as the instance through which we'll communicate with
+ // clients. In this case it corresponds to an *synchronous* service.
+ builder.RegisterService(&service);
+ // Finally assemble the server.
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ std::cout << "Server listening on " << server_address << std::endl;
+
+ // Wait for the server to shutdown. Note that some other thread must be
+ // responsible for shutting down the server for this call to ever return.
+ server->Wait();
+}
+
+int main(int argc, char** argv) {
+ RunServer();
+
+ return 0;
+}
diff --git a/examples/csharp/.gitignore b/examples/csharp/.gitignore
index 585000ea2d..11f758f5c8 100644
--- a/examples/csharp/.gitignore
+++ b/examples/csharp/.gitignore
@@ -1,5 +1,7 @@
+.vs/
bin/
obj/
packages/
*.suo
+*.user
*.userprefs
diff --git a/examples/csharp/Helloworld/Greeter.sln b/examples/csharp/Helloworld/Greeter.sln
index ca50470e66..a5ba98d0be 100644
--- a/examples/csharp/Helloworld/Greeter.sln
+++ b/examples/csharp/Helloworld/Greeter.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
diff --git a/examples/csharp/Helloworld/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj
index eba262565d..7989f79541 100644
--- a/examples/csharp/Helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj
@@ -1,18 +1,17 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>Greeter</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>Greeter</AssemblyName>
- <PackageId>Greeter</PackageId>
+ <TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
- <PackageReference Include="Google.Protobuf.Tools" Version="3.6.1" />
- <PackageReference Include="Grpc" Version="1.14.1" />
- <PackageReference Include="Grpc.Tools" Version="1.14.1" />
+ <PackageReference Include="Grpc" Version="1.17.0" />
+ <PackageReference Include="Grpc.Tools" Version="1.17.0" PrivateAssets="All" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Protobuf Include="../../../protos/helloworld.proto" Link="helloworld.proto" />
</ItemGroup>
</Project>
diff --git a/examples/csharp/Helloworld/Greeter/Helloworld.cs b/examples/csharp/Helloworld/Greeter/Helloworld.cs
deleted file mode 100644
index e008ec27e5..0000000000
--- a/examples/csharp/Helloworld/Greeter/Helloworld.cs
+++ /dev/null
@@ -1,312 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Helloworld {
-
- /// <summary>Holder for reflection information generated from helloworld.proto</summary>
- public static partial class HelloworldReflection {
-
- #region Descriptor
- /// <summary>File descriptor for helloworld.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static HelloworldReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
- "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
- "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
- "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
- "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
- "cm90bzM="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
- }));
- }
- #endregion
-
- }
- #region Messages
- /// <summary>
- /// The request message containing the user's name.
- /// </summary>
- public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
- private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest(HelloRequest other) : this() {
- name_ = other.name_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest Clone() {
- return new HelloRequest(this);
- }
-
- /// <summary>Field number for the "name" field.</summary>
- public const int NameFieldNumber = 1;
- private string name_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Name {
- get { return name_; }
- set {
- name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloRequest);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloRequest other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Name != other.Name) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Name.Length != 0) hash ^= Name.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Name.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Name);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Name.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloRequest other) {
- if (other == null) {
- return;
- }
- if (other.Name.Length != 0) {
- Name = other.Name;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Name = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// The response message containing the greetings
- /// </summary>
- public sealed partial class HelloReply : pb::IMessage<HelloReply> {
- private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply(HelloReply other) : this() {
- message_ = other.message_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply Clone() {
- return new HelloReply(this);
- }
-
- /// <summary>Field number for the "message" field.</summary>
- public const int MessageFieldNumber = 1;
- private string message_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Message {
- get { return message_; }
- set {
- message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloReply);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloReply other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Message != other.Message) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Message.Length != 0) hash ^= Message.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Message.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Message);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Message.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloReply other) {
- if (other == null) {
- return;
- }
- if (other.Message.Length != 0) {
- Message = other.Message;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Message = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- #endregion
-
-}
-
-#endregion Designer generated code
diff --git a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
deleted file mode 100644
index d6b959adc6..0000000000
--- a/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-#pragma warning disable 0414, 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Helloworld {
- /// <summary>
- /// The greeting service definition.
- /// </summary>
- public static partial class Greeter
- {
- static readonly string __ServiceName = "helloworld.Greeter";
-
- static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
- grpc::MethodType.Unary,
- __ServiceName,
- "SayHello",
- __Marshaller_helloworld_HelloRequest,
- __Marshaller_helloworld_HelloReply);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of Greeter</summary>
- public abstract partial class GreeterBase
- {
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for Greeter</summary>
- public partial class GreeterClient : grpc::ClientBase<GreeterClient>
- {
- /// <summary>Creates a new client for Greeter</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public GreeterClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected GreeterClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new GreeterClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
- }
-
- }
-}
-#endregion
diff --git a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
index 24a89d58c5..ac10d85497 100644
--- a/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>GreeterClient</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>GreeterClient</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>GreeterClient</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
index 9ea1fa3817..ac10d85497 100644
--- a/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>GreeterServer</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>GreeterServer</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>GreeterServer</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/Helloworld/README.md b/examples/csharp/Helloworld/README.md
index 4871132426..e4771ee91a 100644
--- a/examples/csharp/Helloworld/README.md
+++ b/examples/csharp/Helloworld/README.md
@@ -3,41 +3,31 @@ gRPC in 3 minutes (C#)
BACKGROUND
-------------
-For this sample, we've already generated the server and client stubs from [helloworld.proto][].
-
-Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/)
-and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
-which have been already added to the project for you.
+This is a version of the helloworld example using the dotnet SDK
+tools to compile [helloworld.proto][] in a common library, build the server
+and the client, and run them.
PREREQUISITES
-------------
- The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core)
-You can also build the example directly using Visual Studio 2017, but it's not a requirement.
-
-BUILD
--------
-
-From the `examples/csharp/Helloworld` directory:
+You can also build the solution `Greeter.sln` using Visual Studio 2017,
+but it's not a requirement.
-- `dotnet build Greeter.sln`
-
-Try it!
--------
+BUILD AND RUN
+-------------
-- Run the server
+- Build and run the server
```
- > cd GreeterServer
- > dotnet run -f netcoreapp2.1
+ > dotnet run -p GreeterServer
```
-- Run the client
+- Build and run the client
```
- > cd GreeterClient
- > dotnet run -f netcoreapp2.1
+ > dotnet run -p GreeterClient
```
Tutorial
diff --git a/examples/csharp/Helloworld/generate_protos.bat b/examples/csharp/Helloworld/generate_protos.bat
deleted file mode 100644
index ab0c0eb46a..0000000000
--- a/examples/csharp/Helloworld/generate_protos.bat
+++ /dev/null
@@ -1,28 +0,0 @@
-@rem Copyright 2016 gRPC authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-
-@rem Generate the C# code for .proto files
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore"
-set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe
-set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe
-
-%PROTOC% -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%PLUGIN%
-
-endlocal
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
index 49e364d91c..26cae7a727 100644
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
index 197a9fb625..da15ba3954 100644
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
@@ -1,5 +1,6 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props" Condition="Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -36,7 +37,7 @@
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
+ <HintPath>..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
@@ -47,25 +48,23 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Helloworld.cs" />
- <Compile Include="HelloworldGrpc.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
- <None Include="..\..\..\protos\helloworld.proto">
+ <Protobuf Include="..\..\..\protos\helloworld.proto">
<Link>protos\helloworld.proto</Link>
- </None>
- <None Include="..\generate_protos.bat">
- <Link>generate_protos.bat</Link>
- </None>
+ </Protobuf>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
- <Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
+ <Import Project="..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.props'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets'))" />
</Target>
-</Project> \ No newline at end of file
+ <Import Project="..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets" Condition="Exists('..\packages\Grpc.Tools.1.17.0\build\Grpc.Tools.targets')" />
+</Project>
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
deleted file mode 100644
index e008ec27e5..0000000000
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
+++ /dev/null
@@ -1,312 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Helloworld {
-
- /// <summary>Holder for reflection information generated from helloworld.proto</summary>
- public static partial class HelloworldReflection {
-
- #region Descriptor
- /// <summary>File descriptor for helloworld.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static HelloworldReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
- "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
- "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
- "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
- "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
- "cm90bzM="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
- }));
- }
- #endregion
-
- }
- #region Messages
- /// <summary>
- /// The request message containing the user's name.
- /// </summary>
- public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
- private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest(HelloRequest other) : this() {
- name_ = other.name_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloRequest Clone() {
- return new HelloRequest(this);
- }
-
- /// <summary>Field number for the "name" field.</summary>
- public const int NameFieldNumber = 1;
- private string name_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Name {
- get { return name_; }
- set {
- name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloRequest);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloRequest other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Name != other.Name) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Name.Length != 0) hash ^= Name.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Name.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Name);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Name.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloRequest other) {
- if (other == null) {
- return;
- }
- if (other.Name.Length != 0) {
- Name = other.Name;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Name = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// The response message containing the greetings
- /// </summary>
- public sealed partial class HelloReply : pb::IMessage<HelloReply> {
- private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply(HelloReply other) : this() {
- message_ = other.message_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public HelloReply Clone() {
- return new HelloReply(this);
- }
-
- /// <summary>Field number for the "message" field.</summary>
- public const int MessageFieldNumber = 1;
- private string message_ = "";
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Message {
- get { return message_; }
- set {
- message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as HelloReply);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(HelloReply other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Message != other.Message) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Message.Length != 0) hash ^= Message.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Message.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Message);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Message.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(HelloReply other) {
- if (other == null) {
- return;
- }
- if (other.Message.Length != 0) {
- Message = other.Message;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Message = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- #endregion
-
-}
-
-#endregion Designer generated code
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
deleted file mode 100644
index d6b959adc6..0000000000
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: helloworld.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-#pragma warning disable 0414, 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Helloworld {
- /// <summary>
- /// The greeting service definition.
- /// </summary>
- public static partial class Greeter
- {
- static readonly string __ServiceName = "helloworld.Greeter";
-
- static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_helloworld_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_helloworld_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
- grpc::MethodType.Unary,
- __ServiceName,
- "SayHello",
- __Marshaller_helloworld_HelloRequest,
- __Marshaller_helloworld_HelloReply);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of Greeter</summary>
- public abstract partial class GreeterBase
- {
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for Greeter</summary>
- public partial class GreeterClient : grpc::ClientBase<GreeterClient>
- {
- /// <summary>Creates a new client for Greeter</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public GreeterClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected GreeterClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// Sends a greeting
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new GreeterClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
- }
-
- }
-}
-#endregion
diff --git a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
index 23857be22f..154b599321 100644
--- a/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
@@ -1,8 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
- <package id="Grpc" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Tools" version="1.14.1" targetFramework="net45" />
+ <package id="Grpc" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Tools" version="1.17.0" targetFramework="net45" developmentDependency="true" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages> \ No newline at end of file
+</packages>
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
index 3bb7ff1ee1..31a3a90345 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -36,7 +36,7 @@
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
+ <HintPath>..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
@@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
+ <Import Project="..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
index df4df8282c..2fd8228689 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
- <package id="Grpc" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
+ <package id="Grpc" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.17.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
index 4396b04efe..27ca963040 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -36,7 +36,7 @@
<HintPath>..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll</HintPath>
</Reference>
<Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.14.1\lib\net45\Grpc.Core.dll</HintPath>
+ <HintPath>..\packages\Grpc.Core.1.17.0\lib\net45\Grpc.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
@@ -59,11 +59,11 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" />
+ <Import Project="..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.14.1\build\net45\Grpc.Core.targets'))" />
+ <Error Condition="!Exists('..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.17.0\build\net45\Grpc.Core.targets'))" />
</Target>
</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
index df4df8282c..2fd8228689 100644
--- a/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
@@ -1,7 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.6.1" targetFramework="net45" />
- <package id="Grpc" version="1.14.1" targetFramework="net45" />
- <package id="Grpc.Core" version="1.14.1" targetFramework="net45" />
+ <package id="Grpc" version="1.17.0" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.17.0" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/HelloworldLegacyCsproj/README.md b/examples/csharp/HelloworldLegacyCsproj/README.md
index 6d42c5ef25..60b09e0925 100644
--- a/examples/csharp/HelloworldLegacyCsproj/README.md
+++ b/examples/csharp/HelloworldLegacyCsproj/README.md
@@ -3,21 +3,21 @@ gRPC in 3 minutes (C#)
BACKGROUND
-------------
-This is a different version of the helloworld example, using the old-style .csproj
-files supported by VS2013 and VS2015 (and older versions of mono).
-You can still use gRPC with the old-style .csproj files, but [using the new-style
-.csproj projects](../helloworld/README.md) (supported by VS2017 and dotnet SDK) is recommended.
-
-For this sample, we've already generated the server and client stubs from [helloworld.proto][].
-
-Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/)
+This is a different version of the helloworld example, using the "classic" .csproj
+files, the only format supported by VS2013 (and older versions of mono).
+You can still use gRPC with the classic .csproj files, but [using the new-style
+.csproj projects](../helloworld/README.md) (supported by VS2015 Update3 and above,
+and dotnet SDK) is recommended.
+
+Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/),
+[Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/)
and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
which have been already added to the project for you.
PREREQUISITES
-------------
-- Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015
+- Windows: .NET Framework 4.5+, Visual Studio 2013 or higher
- Linux: Mono 4+, MonoDevelop 5.9+
- Mac OS X: Xamarin Studio 5.9+
@@ -28,12 +28,15 @@ BUILD
# Using Visual Studio
-* Build the solution (this will automatically download NuGet dependencies)
+* Select "Restore NuGet Packages" from the solution context menu. It is recommended
+ to close and re-open the solution after the packages have been restored from
+ Visual Studio.
+* Build the solution.
# Using Monodevelop or Xamarin Studio
-The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to
-download all of the nuget dependencies of gRPC.
+The NuGet add-in available for Xamarin Studio and Monodevelop IDEs is too old to
+download all of the NuGet dependencies of gRPC.
Using these IDEs, a workaround is as follows:
* Obtain a nuget executable for your platform and update it with
diff --git a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
deleted file mode 100644
index d1e7160f91..0000000000
--- a/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
+++ /dev/null
@@ -1,26 +0,0 @@
-@rem Copyright 2016 gRPC authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-
-@rem Generate the C# code for .proto files
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-set TOOLS_PATH=packages\Grpc.Tools.1.14.1\tools\windows_x86
-
-%TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
-
-endlocal
diff --git a/examples/csharp/RouteGuide/RouteGuide.sln b/examples/csharp/RouteGuide/RouteGuide.sln
index 73e6e306b1..5e103294a5 100644
--- a/examples/csharp/RouteGuide/RouteGuide.sln
+++ b/examples/csharp/RouteGuide/RouteGuide.sln
@@ -1,4 +1,4 @@
-
+
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26228.4
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
deleted file mode 100644
index 10c9aec5f8..0000000000
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
+++ /dev/null
@@ -1,981 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: route_guide.proto
-// </auto-generated>
-#pragma warning disable 1591, 0612, 3021
-#region Designer generated code
-
-using pb = global::Google.Protobuf;
-using pbc = global::Google.Protobuf.Collections;
-using pbr = global::Google.Protobuf.Reflection;
-using scg = global::System.Collections.Generic;
-namespace Routeguide {
-
- /// <summary>Holder for reflection information generated from route_guide.proto</summary>
- public static partial class RouteGuideReflection {
-
- #region Descriptor
- /// <summary>File descriptor for route_guide.proto</summary>
- public static pbr::FileDescriptor Descriptor {
- get { return descriptor; }
- }
- private static pbr::FileDescriptor descriptor;
-
- static RouteGuideReflection() {
- byte[] descriptorData = global::System.Convert.FromBase64String(
- string.Concat(
- "ChFyb3V0ZV9ndWlkZS5wcm90bxIKcm91dGVndWlkZSIsCgVQb2ludBIQCghs",
- "YXRpdHVkZRgBIAEoBRIRCglsb25naXR1ZGUYAiABKAUiSQoJUmVjdGFuZ2xl",
- "Eh0KAmxvGAEgASgLMhEucm91dGVndWlkZS5Qb2ludBIdCgJoaRgCIAEoCzIR",
- "LnJvdXRlZ3VpZGUuUG9pbnQiPAoHRmVhdHVyZRIMCgRuYW1lGAEgASgJEiMK",
- "CGxvY2F0aW9uGAIgASgLMhEucm91dGVndWlkZS5Qb2ludCJBCglSb3V0ZU5v",
- "dGUSIwoIbG9jYXRpb24YASABKAsyES5yb3V0ZWd1aWRlLlBvaW50Eg8KB21l",
- "c3NhZ2UYAiABKAkiYgoMUm91dGVTdW1tYXJ5EhMKC3BvaW50X2NvdW50GAEg",
- "ASgFEhUKDWZlYXR1cmVfY291bnQYAiABKAUSEAoIZGlzdGFuY2UYAyABKAUS",
- "FAoMZWxhcHNlZF90aW1lGAQgASgFMoUCCgpSb3V0ZUd1aWRlEjYKCkdldEZl",
- "YXR1cmUSES5yb3V0ZWd1aWRlLlBvaW50GhMucm91dGVndWlkZS5GZWF0dXJl",
- "IgASPgoMTGlzdEZlYXR1cmVzEhUucm91dGVndWlkZS5SZWN0YW5nbGUaEy5y",
- "b3V0ZWd1aWRlLkZlYXR1cmUiADABEj4KC1JlY29yZFJvdXRlEhEucm91dGVn",
- "dWlkZS5Qb2ludBoYLnJvdXRlZ3VpZGUuUm91dGVTdW1tYXJ5IgAoARI/CglS",
- "b3V0ZUNoYXQSFS5yb3V0ZWd1aWRlLlJvdXRlTm90ZRoVLnJvdXRlZ3VpZGUu",
- "Um91dGVOb3RlIgAoATABQjYKG2lvLmdycGMuZXhhbXBsZXMucm91dGVndWlk",
- "ZUIPUm91dGVHdWlkZVByb3RvUAGiAgNSVEdiBnByb3RvMw=="));
- descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
- new pbr::FileDescriptor[] { },
- new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Point), global::Routeguide.Point.Parser, new[]{ "Latitude", "Longitude" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Rectangle), global::Routeguide.Rectangle.Parser, new[]{ "Lo", "Hi" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.Feature), global::Routeguide.Feature.Parser, new[]{ "Name", "Location" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteNote), global::Routeguide.RouteNote.Parser, new[]{ "Location", "Message" }, null, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Routeguide.RouteSummary), global::Routeguide.RouteSummary.Parser, new[]{ "PointCount", "FeatureCount", "Distance", "ElapsedTime" }, null, null, null)
- }));
- }
- #endregion
-
- }
- #region Messages
- /// <summary>
- /// Points are represented as latitude-longitude pairs in the E7 representation
- /// (degrees multiplied by 10**7 and rounded to the nearest integer).
- /// Latitudes should be in the range +/- 90 degrees and longitude should be in
- /// the range +/- 180 degrees (inclusive).
- /// </summary>
- public sealed partial class Point : pb::IMessage<Point> {
- private static readonly pb::MessageParser<Point> _parser = new pb::MessageParser<Point>(() => new Point());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Point> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[0]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Point() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Point(Point other) : this() {
- latitude_ = other.latitude_;
- longitude_ = other.longitude_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Point Clone() {
- return new Point(this);
- }
-
- /// <summary>Field number for the "latitude" field.</summary>
- public const int LatitudeFieldNumber = 1;
- private int latitude_;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Latitude {
- get { return latitude_; }
- set {
- latitude_ = value;
- }
- }
-
- /// <summary>Field number for the "longitude" field.</summary>
- public const int LongitudeFieldNumber = 2;
- private int longitude_;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Longitude {
- get { return longitude_; }
- set {
- longitude_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as Point);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Point other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Latitude != other.Latitude) return false;
- if (Longitude != other.Longitude) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Latitude != 0) hash ^= Latitude.GetHashCode();
- if (Longitude != 0) hash ^= Longitude.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Latitude != 0) {
- output.WriteRawTag(8);
- output.WriteInt32(Latitude);
- }
- if (Longitude != 0) {
- output.WriteRawTag(16);
- output.WriteInt32(Longitude);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Latitude != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Latitude);
- }
- if (Longitude != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Longitude);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Point other) {
- if (other == null) {
- return;
- }
- if (other.Latitude != 0) {
- Latitude = other.Latitude;
- }
- if (other.Longitude != 0) {
- Longitude = other.Longitude;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 8: {
- Latitude = input.ReadInt32();
- break;
- }
- case 16: {
- Longitude = input.ReadInt32();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A latitude-longitude rectangle, represented as two diagonally opposite
- /// points "lo" and "hi".
- /// </summary>
- public sealed partial class Rectangle : pb::IMessage<Rectangle> {
- private static readonly pb::MessageParser<Rectangle> _parser = new pb::MessageParser<Rectangle>(() => new Rectangle());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Rectangle> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[1]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Rectangle() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Rectangle(Rectangle other) : this() {
- lo_ = other.lo_ != null ? other.lo_.Clone() : null;
- hi_ = other.hi_ != null ? other.hi_.Clone() : null;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Rectangle Clone() {
- return new Rectangle(this);
- }
-
- /// <summary>Field number for the "lo" field.</summary>
- public const int LoFieldNumber = 1;
- private global::Routeguide.Point lo_;
- /// <summary>
- /// One corner of the rectangle.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Lo {
- get { return lo_; }
- set {
- lo_ = value;
- }
- }
-
- /// <summary>Field number for the "hi" field.</summary>
- public const int HiFieldNumber = 2;
- private global::Routeguide.Point hi_;
- /// <summary>
- /// The other corner of the rectangle.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Hi {
- get { return hi_; }
- set {
- hi_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as Rectangle);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Rectangle other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (!object.Equals(Lo, other.Lo)) return false;
- if (!object.Equals(Hi, other.Hi)) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (lo_ != null) hash ^= Lo.GetHashCode();
- if (hi_ != null) hash ^= Hi.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (lo_ != null) {
- output.WriteRawTag(10);
- output.WriteMessage(Lo);
- }
- if (hi_ != null) {
- output.WriteRawTag(18);
- output.WriteMessage(Hi);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (lo_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Lo);
- }
- if (hi_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Hi);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Rectangle other) {
- if (other == null) {
- return;
- }
- if (other.lo_ != null) {
- if (lo_ == null) {
- lo_ = new global::Routeguide.Point();
- }
- Lo.MergeFrom(other.Lo);
- }
- if (other.hi_ != null) {
- if (hi_ == null) {
- hi_ = new global::Routeguide.Point();
- }
- Hi.MergeFrom(other.Hi);
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- if (lo_ == null) {
- lo_ = new global::Routeguide.Point();
- }
- input.ReadMessage(lo_);
- break;
- }
- case 18: {
- if (hi_ == null) {
- hi_ = new global::Routeguide.Point();
- }
- input.ReadMessage(hi_);
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A feature names something at a given point.
- ///
- /// If a feature could not be named, the name is empty.
- /// </summary>
- public sealed partial class Feature : pb::IMessage<Feature> {
- private static readonly pb::MessageParser<Feature> _parser = new pb::MessageParser<Feature>(() => new Feature());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<Feature> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[2]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Feature() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Feature(Feature other) : this() {
- name_ = other.name_;
- location_ = other.location_ != null ? other.location_.Clone() : null;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public Feature Clone() {
- return new Feature(this);
- }
-
- /// <summary>Field number for the "name" field.</summary>
- public const int NameFieldNumber = 1;
- private string name_ = "";
- /// <summary>
- /// The name of the feature.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Name {
- get { return name_; }
- set {
- name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- /// <summary>Field number for the "location" field.</summary>
- public const int LocationFieldNumber = 2;
- private global::Routeguide.Point location_;
- /// <summary>
- /// The point where the feature is detected.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Location {
- get { return location_; }
- set {
- location_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as Feature);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(Feature other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (Name != other.Name) return false;
- if (!object.Equals(Location, other.Location)) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (Name.Length != 0) hash ^= Name.GetHashCode();
- if (location_ != null) hash ^= Location.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (Name.Length != 0) {
- output.WriteRawTag(10);
- output.WriteString(Name);
- }
- if (location_ != null) {
- output.WriteRawTag(18);
- output.WriteMessage(Location);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (Name.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
- }
- if (location_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(Feature other) {
- if (other == null) {
- return;
- }
- if (other.Name.Length != 0) {
- Name = other.Name;
- }
- if (other.location_ != null) {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- Location.MergeFrom(other.Location);
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- Name = input.ReadString();
- break;
- }
- case 18: {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- input.ReadMessage(location_);
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A RouteNote is a message sent while at a given point.
- /// </summary>
- public sealed partial class RouteNote : pb::IMessage<RouteNote> {
- private static readonly pb::MessageParser<RouteNote> _parser = new pb::MessageParser<RouteNote>(() => new RouteNote());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<RouteNote> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[3]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteNote() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteNote(RouteNote other) : this() {
- location_ = other.location_ != null ? other.location_.Clone() : null;
- message_ = other.message_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteNote Clone() {
- return new RouteNote(this);
- }
-
- /// <summary>Field number for the "location" field.</summary>
- public const int LocationFieldNumber = 1;
- private global::Routeguide.Point location_;
- /// <summary>
- /// The location from which the message is sent.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public global::Routeguide.Point Location {
- get { return location_; }
- set {
- location_ = value;
- }
- }
-
- /// <summary>Field number for the "message" field.</summary>
- public const int MessageFieldNumber = 2;
- private string message_ = "";
- /// <summary>
- /// The message to be sent.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public string Message {
- get { return message_; }
- set {
- message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as RouteNote);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(RouteNote other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (!object.Equals(Location, other.Location)) return false;
- if (Message != other.Message) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (location_ != null) hash ^= Location.GetHashCode();
- if (Message.Length != 0) hash ^= Message.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (location_ != null) {
- output.WriteRawTag(10);
- output.WriteMessage(Location);
- }
- if (Message.Length != 0) {
- output.WriteRawTag(18);
- output.WriteString(Message);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (location_ != null) {
- size += 1 + pb::CodedOutputStream.ComputeMessageSize(Location);
- }
- if (Message.Length != 0) {
- size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(RouteNote other) {
- if (other == null) {
- return;
- }
- if (other.location_ != null) {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- Location.MergeFrom(other.Location);
- }
- if (other.Message.Length != 0) {
- Message = other.Message;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 10: {
- if (location_ == null) {
- location_ = new global::Routeguide.Point();
- }
- input.ReadMessage(location_);
- break;
- }
- case 18: {
- Message = input.ReadString();
- break;
- }
- }
- }
- }
-
- }
-
- /// <summary>
- /// A RouteSummary is received in response to a RecordRoute rpc.
- ///
- /// It contains the number of individual points received, the number of
- /// detected features, and the total distance covered as the cumulative sum of
- /// the distance between each point.
- /// </summary>
- public sealed partial class RouteSummary : pb::IMessage<RouteSummary> {
- private static readonly pb::MessageParser<RouteSummary> _parser = new pb::MessageParser<RouteSummary>(() => new RouteSummary());
- private pb::UnknownFieldSet _unknownFields;
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pb::MessageParser<RouteSummary> Parser { get { return _parser; } }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public static pbr::MessageDescriptor Descriptor {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.MessageTypes[4]; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- pbr::MessageDescriptor pb::IMessage.Descriptor {
- get { return Descriptor; }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteSummary() {
- OnConstruction();
- }
-
- partial void OnConstruction();
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteSummary(RouteSummary other) : this() {
- pointCount_ = other.pointCount_;
- featureCount_ = other.featureCount_;
- distance_ = other.distance_;
- elapsedTime_ = other.elapsedTime_;
- _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public RouteSummary Clone() {
- return new RouteSummary(this);
- }
-
- /// <summary>Field number for the "point_count" field.</summary>
- public const int PointCountFieldNumber = 1;
- private int pointCount_;
- /// <summary>
- /// The number of points received.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int PointCount {
- get { return pointCount_; }
- set {
- pointCount_ = value;
- }
- }
-
- /// <summary>Field number for the "feature_count" field.</summary>
- public const int FeatureCountFieldNumber = 2;
- private int featureCount_;
- /// <summary>
- /// The number of known features passed while traversing the route.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int FeatureCount {
- get { return featureCount_; }
- set {
- featureCount_ = value;
- }
- }
-
- /// <summary>Field number for the "distance" field.</summary>
- public const int DistanceFieldNumber = 3;
- private int distance_;
- /// <summary>
- /// The distance covered in metres.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int Distance {
- get { return distance_; }
- set {
- distance_ = value;
- }
- }
-
- /// <summary>Field number for the "elapsed_time" field.</summary>
- public const int ElapsedTimeFieldNumber = 4;
- private int elapsedTime_;
- /// <summary>
- /// The duration of the traversal in seconds.
- /// </summary>
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int ElapsedTime {
- get { return elapsedTime_; }
- set {
- elapsedTime_ = value;
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override bool Equals(object other) {
- return Equals(other as RouteSummary);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public bool Equals(RouteSummary other) {
- if (ReferenceEquals(other, null)) {
- return false;
- }
- if (ReferenceEquals(other, this)) {
- return true;
- }
- if (PointCount != other.PointCount) return false;
- if (FeatureCount != other.FeatureCount) return false;
- if (Distance != other.Distance) return false;
- if (ElapsedTime != other.ElapsedTime) return false;
- return Equals(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override int GetHashCode() {
- int hash = 1;
- if (PointCount != 0) hash ^= PointCount.GetHashCode();
- if (FeatureCount != 0) hash ^= FeatureCount.GetHashCode();
- if (Distance != 0) hash ^= Distance.GetHashCode();
- if (ElapsedTime != 0) hash ^= ElapsedTime.GetHashCode();
- if (_unknownFields != null) {
- hash ^= _unknownFields.GetHashCode();
- }
- return hash;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public override string ToString() {
- return pb::JsonFormatter.ToDiagnosticString(this);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void WriteTo(pb::CodedOutputStream output) {
- if (PointCount != 0) {
- output.WriteRawTag(8);
- output.WriteInt32(PointCount);
- }
- if (FeatureCount != 0) {
- output.WriteRawTag(16);
- output.WriteInt32(FeatureCount);
- }
- if (Distance != 0) {
- output.WriteRawTag(24);
- output.WriteInt32(Distance);
- }
- if (ElapsedTime != 0) {
- output.WriteRawTag(32);
- output.WriteInt32(ElapsedTime);
- }
- if (_unknownFields != null) {
- _unknownFields.WriteTo(output);
- }
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public int CalculateSize() {
- int size = 0;
- if (PointCount != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(PointCount);
- }
- if (FeatureCount != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(FeatureCount);
- }
- if (Distance != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(Distance);
- }
- if (ElapsedTime != 0) {
- size += 1 + pb::CodedOutputStream.ComputeInt32Size(ElapsedTime);
- }
- if (_unknownFields != null) {
- size += _unknownFields.CalculateSize();
- }
- return size;
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(RouteSummary other) {
- if (other == null) {
- return;
- }
- if (other.PointCount != 0) {
- PointCount = other.PointCount;
- }
- if (other.FeatureCount != 0) {
- FeatureCount = other.FeatureCount;
- }
- if (other.Distance != 0) {
- Distance = other.Distance;
- }
- if (other.ElapsedTime != 0) {
- ElapsedTime = other.ElapsedTime;
- }
- _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
- }
-
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
- public void MergeFrom(pb::CodedInputStream input) {
- uint tag;
- while ((tag = input.ReadTag()) != 0) {
- switch(tag) {
- default:
- _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
- break;
- case 8: {
- PointCount = input.ReadInt32();
- break;
- }
- case 16: {
- FeatureCount = input.ReadInt32();
- break;
- }
- case 24: {
- Distance = input.ReadInt32();
- break;
- }
- case 32: {
- ElapsedTime = input.ReadInt32();
- break;
- }
- }
- }
- }
-
- }
-
- #endregion
-
-}
-
-#endregion Designer generated code
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
index 86346d1e14..4c6949488c 100644
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
@@ -1,25 +1,22 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>RouteGuide</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>RouteGuide</AssemblyName>
- <PackageId>RouteGuide</PackageId>
+ <TargetFramework>netstandard1.5</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.6.1" />
- <PackageReference Include="Google.Protobuf.Tools" Version="3.6.1" />
- <PackageReference Include="Grpc" Version="1.14.1" />
- <PackageReference Include="Grpc.Tools" Version="1.14.1" />
+ <PackageReference Include="Grpc" Version="1.17.0" />
+ <PackageReference Include="Grpc.Tools" Version="1.17.0" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
</ItemGroup>
<ItemGroup>
- <None Include="route_guide_db.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
+ <Protobuf Include="..\..\..\protos\route_guide.proto" Link="protos\route_guide.proto" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="route_guide_db.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
</Project>
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
deleted file mode 100644
index 445708e446..0000000000
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
+++ /dev/null
@@ -1,331 +0,0 @@
-// <auto-generated>
-// Generated by the protocol buffer compiler. DO NOT EDIT!
-// source: route_guide.proto
-// </auto-generated>
-// Original file comments:
-// 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.
-//
-#pragma warning disable 0414, 1591
-#region Designer generated code
-
-using grpc = global::Grpc.Core;
-
-namespace Routeguide {
- /// <summary>
- /// Interface exported by the server.
- /// </summary>
- public static partial class RouteGuide
- {
- static readonly string __ServiceName = "routeguide.RouteGuide";
-
- static readonly grpc::Marshaller<global::Routeguide.Point> __Marshaller_routeguide_Point = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Point.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.Feature> __Marshaller_routeguide_Feature = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Feature.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.Rectangle> __Marshaller_routeguide_Rectangle = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.Rectangle.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.RouteSummary> __Marshaller_routeguide_RouteSummary = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteSummary.Parser.ParseFrom);
- static readonly grpc::Marshaller<global::Routeguide.RouteNote> __Marshaller_routeguide_RouteNote = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Routeguide.RouteNote.Parser.ParseFrom);
-
- static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.Feature> __Method_GetFeature = new grpc::Method<global::Routeguide.Point, global::Routeguide.Feature>(
- grpc::MethodType.Unary,
- __ServiceName,
- "GetFeature",
- __Marshaller_routeguide_Point,
- __Marshaller_routeguide_Feature);
-
- static readonly grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature> __Method_ListFeatures = new grpc::Method<global::Routeguide.Rectangle, global::Routeguide.Feature>(
- grpc::MethodType.ServerStreaming,
- __ServiceName,
- "ListFeatures",
- __Marshaller_routeguide_Rectangle,
- __Marshaller_routeguide_Feature);
-
- static readonly grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary> __Method_RecordRoute = new grpc::Method<global::Routeguide.Point, global::Routeguide.RouteSummary>(
- grpc::MethodType.ClientStreaming,
- __ServiceName,
- "RecordRoute",
- __Marshaller_routeguide_Point,
- __Marshaller_routeguide_RouteSummary);
-
- static readonly grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote> __Method_RouteChat = new grpc::Method<global::Routeguide.RouteNote, global::Routeguide.RouteNote>(
- grpc::MethodType.DuplexStreaming,
- __ServiceName,
- "RouteChat",
- __Marshaller_routeguide_RouteNote,
- __Marshaller_routeguide_RouteNote);
-
- /// <summary>Service descriptor</summary>
- public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
- {
- get { return global::Routeguide.RouteGuideReflection.Descriptor.Services[0]; }
- }
-
- /// <summary>Base class for server-side implementations of RouteGuide</summary>
- public abstract partial class RouteGuideBase
- {
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Routeguide.Feature> GetFeature(global::Routeguide.Point request, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// A server-to-client streaming RPC.
- ///
- /// Obtains the Features available within the given Rectangle. Results are
- /// streamed rather than returned at once (e.g. in a response message with a
- /// repeated field), as the rectangle may cover a large area and contain a
- /// huge number of features.
- /// </summary>
- /// <param name="request">The request received from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task ListFeatures(global::Routeguide.Rectangle request, grpc::IServerStreamWriter<global::Routeguide.Feature> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// A client-to-server streaming RPC.
- ///
- /// Accepts a stream of Points on a route being traversed, returning a
- /// RouteSummary when traversal is completed.
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>The response to send back to the client (wrapped by a task).</returns>
- public virtual global::System.Threading.Tasks.Task<global::Routeguide.RouteSummary> RecordRoute(grpc::IAsyncStreamReader<global::Routeguide.Point> requestStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- /// <summary>
- /// A Bidirectional streaming RPC.
- ///
- /// Accepts a stream of RouteNotes sent while a route is being traversed,
- /// while receiving other RouteNotes (e.g. from other users).
- /// </summary>
- /// <param name="requestStream">Used for reading requests from the client.</param>
- /// <param name="responseStream">Used for sending responses back to the client.</param>
- /// <param name="context">The context of the server-side call handler being invoked.</param>
- /// <returns>A task indicating completion of the handler.</returns>
- public virtual global::System.Threading.Tasks.Task RouteChat(grpc::IAsyncStreamReader<global::Routeguide.RouteNote> requestStream, grpc::IServerStreamWriter<global::Routeguide.RouteNote> responseStream, grpc::ServerCallContext context)
- {
- throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
- }
-
- }
-
- /// <summary>Client for RouteGuide</summary>
- public partial class RouteGuideClient : grpc::ClientBase<RouteGuideClient>
- {
- /// <summary>Creates a new client for RouteGuide</summary>
- /// <param name="channel">The channel to use to make remote calls.</param>
- public RouteGuideClient(grpc::Channel channel) : base(channel)
- {
- }
- /// <summary>Creates a new client for RouteGuide that uses a custom <c>CallInvoker</c>.</summary>
- /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
- public RouteGuideClient(grpc::CallInvoker callInvoker) : base(callInvoker)
- {
- }
- /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
- protected RouteGuideClient() : base()
- {
- }
- /// <summary>Protected constructor to allow creation of configured clients.</summary>
- /// <param name="configuration">The client configuration.</param>
- protected RouteGuideClient(ClientBaseConfiguration configuration) : base(configuration)
- {
- }
-
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return GetFeature(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The response received from the server.</returns>
- public virtual global::Routeguide.Feature GetFeature(global::Routeguide.Point request, grpc::CallOptions options)
- {
- return CallInvoker.BlockingUnaryCall(__Method_GetFeature, null, options, request);
- }
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return GetFeatureAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A simple RPC.
- ///
- /// Obtains the feature at a given position.
- ///
- /// A feature with an empty name is returned if there's no feature at the given
- /// position.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncUnaryCall<global::Routeguide.Feature> GetFeatureAsync(global::Routeguide.Point request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncUnaryCall(__Method_GetFeature, null, options, request);
- }
- /// <summary>
- /// A server-to-client streaming RPC.
- ///
- /// Obtains the Features available within the given Rectangle. Results are
- /// streamed rather than returned at once (e.g. in a response message with a
- /// repeated field), as the rectangle may cover a large area and contain a
- /// huge number of features.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return ListFeatures(request, new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A server-to-client streaming RPC.
- ///
- /// Obtains the Features available within the given Rectangle. Results are
- /// streamed rather than returned at once (e.g. in a response message with a
- /// repeated field), as the rectangle may cover a large area and contain a
- /// huge number of features.
- /// </summary>
- /// <param name="request">The request to send to the server.</param>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncServerStreamingCall<global::Routeguide.Feature> ListFeatures(global::Routeguide.Rectangle request, grpc::CallOptions options)
- {
- return CallInvoker.AsyncServerStreamingCall(__Method_ListFeatures, null, options, request);
- }
- /// <summary>
- /// A client-to-server streaming RPC.
- ///
- /// Accepts a stream of Points on a route being traversed, returning a
- /// RouteSummary when traversal is completed.
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return RecordRoute(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A client-to-server streaming RPC.
- ///
- /// Accepts a stream of Points on a route being traversed, returning a
- /// RouteSummary when traversal is completed.
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncClientStreamingCall<global::Routeguide.Point, global::Routeguide.RouteSummary> RecordRoute(grpc::CallOptions options)
- {
- return CallInvoker.AsyncClientStreamingCall(__Method_RecordRoute, null, options);
- }
- /// <summary>
- /// A Bidirectional streaming RPC.
- ///
- /// Accepts a stream of RouteNotes sent while a route is being traversed,
- /// while receiving other RouteNotes (e.g. from other users).
- /// </summary>
- /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
- /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
- /// <param name="cancellationToken">An optional token for canceling the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
- {
- return RouteChat(new grpc::CallOptions(headers, deadline, cancellationToken));
- }
- /// <summary>
- /// A Bidirectional streaming RPC.
- ///
- /// Accepts a stream of RouteNotes sent while a route is being traversed,
- /// while receiving other RouteNotes (e.g. from other users).
- /// </summary>
- /// <param name="options">The options for the call.</param>
- /// <returns>The call object.</returns>
- public virtual grpc::AsyncDuplexStreamingCall<global::Routeguide.RouteNote, global::Routeguide.RouteNote> RouteChat(grpc::CallOptions options)
- {
- return CallInvoker.AsyncDuplexStreamingCall(__Method_RouteChat, null, options);
- }
- /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
- protected override RouteGuideClient NewInstance(ClientBaseConfiguration configuration)
- {
- return new RouteGuideClient(configuration);
- }
- }
-
- /// <summary>Creates service definition that can be registered with a server</summary>
- /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
- public static grpc::ServerServiceDefinition BindService(RouteGuideBase serviceImpl)
- {
- return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_GetFeature, serviceImpl.GetFeature)
- .AddMethod(__Method_ListFeatures, serviceImpl.ListFeatures)
- .AddMethod(__Method_RecordRoute, serviceImpl.RecordRoute)
- .AddMethod(__Method_RouteChat, serviceImpl.RouteChat).Build();
- }
-
- }
-}
-#endregion
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
index f9af190888..96bd8ca09b 100644
--- a/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
@@ -108,6 +108,7 @@ namespace Routeguide
return features;
}
+#pragma warning disable 0649 // Suppresses "Field 'x' is never assigned to".
private class JsonFeature
{
public string name;
@@ -119,5 +120,6 @@ namespace Routeguide
public int longitude;
public int latitude;
}
+#pragma warning restore 0649
}
}
diff --git a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
index c6dadf082b..b773dd0923 100644
--- a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
+++ b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>RouteGuideClient</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>RouteGuideClient</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>RouteGuideClient</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
index 005c87ca0c..b773dd0923 100644
--- a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
+++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
@@ -1,12 +1,8 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <AssemblyTitle>RouteGuideServer</AssemblyTitle>
- <TargetFrameworks>netcoreapp2.1</TargetFrameworks>
- <DebugType>portable</DebugType>
- <AssemblyName>RouteGuideServer</AssemblyName>
+ <TargetFramework>netcoreapp2.1</TargetFramework>
<OutputType>Exe</OutputType>
- <PackageId>RouteGuideServer</PackageId>
</PropertyGroup>
<ItemGroup>
diff --git a/examples/csharp/RouteGuide/generate_protos.bat b/examples/csharp/RouteGuide/generate_protos.bat
deleted file mode 100644
index f3a4382cf1..0000000000
--- a/examples/csharp/RouteGuide/generate_protos.bat
+++ /dev/null
@@ -1,28 +0,0 @@
-@rem Copyright 2016 gRPC authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-
-@rem Generate the C# code for .proto files
-
-setlocal
-
-@rem enter this directory
-cd /d %~dp0
-
-@rem packages will be available in nuget cache directory once the project is built or after "dotnet restore"
-set PROTOC=%UserProfile%\.nuget\packages\Google.Protobuf.Tools\3.6.1\tools\windows_x64\protoc.exe
-set PLUGIN=%UserProfile%\.nuget\packages\Grpc.Tools\1.14.1\tools\windows_x64\grpc_csharp_plugin.exe
-
-%PROTOC% -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%PLUGIN%
-
-endlocal
diff --git a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj
index df5c40cda2..e067e82b3d 100644
--- a/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj
+++ b/examples/objective-c/helloworld/HelloWorld.xcodeproj/project.pbxproj
@@ -132,6 +132,8 @@
TargetAttributes = {
5E36905F1B2A23800040F884 = {
CreatedOnToolsVersion = 6.2;
+ DevelopmentTeam = EQHXZ8M8AV;
+ ProvisioningStyle = Manual;
};
};
};
@@ -321,9 +323,12 @@
baseConfigurationReference = DBDE3E48389499064CD664B8 /* Pods-HelloWorld.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Manual;
+ DEVELOPMENT_TEAM = EQHXZ8M8AV;
INFOPLIST_FILE = HelloWorld/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "Google Development";
};
name = Debug;
};
@@ -332,9 +337,12 @@
baseConfigurationReference = 0C432EF610DB15C0F47A66BB /* Pods-HelloWorld.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Manual;
+ DEVELOPMENT_TEAM = "";
INFOPLIST_FILE = HelloWorld/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
};
name = Release;
};
diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py
index 24b49ac233..ee2032a9e6 100644
--- a/examples/python/helloworld/greeter_client.py
+++ b/examples/python/helloworld/greeter_client.py
@@ -14,6 +14,7 @@
"""The Python implementation of the GRPC helloworld.Greeter client."""
from __future__ import print_function
+import logging
import grpc
@@ -32,4 +33,5 @@ def run():
if __name__ == '__main__':
+ logging.basicConfig()
run()
diff --git a/examples/python/helloworld/greeter_client_with_options.py b/examples/python/helloworld/greeter_client_with_options.py
index 7eda8c9066..d15871b519 100644
--- a/examples/python/helloworld/greeter_client_with_options.py
+++ b/examples/python/helloworld/greeter_client_with_options.py
@@ -14,6 +14,7 @@
"""The Python implementation of the GRPC helloworld.Greeter client with channel options and call timeout parameters."""
from __future__ import print_function
+import logging
import grpc
@@ -41,4 +42,5 @@ def run():
if __name__ == '__main__':
+ logging.basicConfig()
run()
diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py
index c355662ef8..e3b4f2c1ff 100644
--- a/examples/python/helloworld/greeter_server.py
+++ b/examples/python/helloworld/greeter_server.py
@@ -15,6 +15,7 @@
from concurrent import futures
import time
+import logging
import grpc
@@ -43,4 +44,5 @@ def serve():
if __name__ == '__main__':
+ logging.basicConfig()
serve()
diff --git a/examples/python/helloworld/greeter_server_with_reflection.py b/examples/python/helloworld/greeter_server_with_reflection.py
index 5ba8782dfc..5acedbcb71 100644
--- a/examples/python/helloworld/greeter_server_with_reflection.py
+++ b/examples/python/helloworld/greeter_server_with_reflection.py
@@ -15,6 +15,7 @@
from concurrent import futures
import time
+import logging
import grpc
from grpc_reflection.v1alpha import reflection
@@ -49,4 +50,5 @@ def serve():
if __name__ == '__main__':
+ logging.basicConfig()
serve()
diff --git a/examples/python/interceptors/default_value/greeter_client.py b/examples/python/interceptors/default_value/greeter_client.py
index da21ac68ec..25834c2bbd 100644
--- a/examples/python/interceptors/default_value/greeter_client.py
+++ b/examples/python/interceptors/default_value/greeter_client.py
@@ -14,6 +14,7 @@
"""The Python implementation of the gRPC helloworld.Greeter client."""
from __future__ import print_function
+import logging
import grpc
@@ -39,4 +40,5 @@ def run():
if __name__ == '__main__':
+ logging.basicConfig()
run()
diff --git a/examples/python/interceptors/headers/greeter_client.py b/examples/python/interceptors/headers/greeter_client.py
index 6a09a3b9c5..712539850d 100644
--- a/examples/python/interceptors/headers/greeter_client.py
+++ b/examples/python/interceptors/headers/greeter_client.py
@@ -14,6 +14,7 @@
"""The Python implementation of the GRPC helloworld.Greeter client."""
from __future__ import print_function
+import logging
import grpc
@@ -37,4 +38,5 @@ def run():
if __name__ == '__main__':
+ logging.basicConfig()
run()
diff --git a/examples/python/interceptors/headers/greeter_server.py b/examples/python/interceptors/headers/greeter_server.py
index 01968609b5..6b0f4058bc 100644
--- a/examples/python/interceptors/headers/greeter_server.py
+++ b/examples/python/interceptors/headers/greeter_server.py
@@ -15,6 +15,7 @@
from concurrent import futures
import time
+import logging
import grpc
@@ -49,4 +50,5 @@ def serve():
if __name__ == '__main__':
+ logging.basicConfig()
serve()
diff --git a/examples/python/metadata/README.md b/examples/python/metadata/README.md
new file mode 100644
index 0000000000..5aa75d504a
--- /dev/null
+++ b/examples/python/metadata/README.md
@@ -0,0 +1,6 @@
+An example showing how to add custom HTTP2 headers (or [metadata](https://grpc.io/grpc/python/glossary.html) in gRPC glossary)
+
+HTTP2 supports initial headers and trailing headers, which gRPC utilizes both of them ([learn more](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md)).
+
+More complete documentation lives at [grpc.io](https://grpc.io/docs/tutorials/basic/python.html).
+For API reference please see [API](https://grpc.io/grpc/python/grpc.html).
diff --git a/examples/python/metadata/helloworld_pb2.py b/examples/python/metadata/helloworld_pb2.py
new file mode 100644
index 0000000000..e18ab9acc7
--- /dev/null
+++ b/examples/python/metadata/helloworld_pb2.py
@@ -0,0 +1,134 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: helloworld.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+ name='helloworld.proto',
+ package='helloworld',
+ syntax='proto3',
+ serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
+)
+
+
+
+
+_HELLOREQUEST = _descriptor.Descriptor(
+ name='HelloRequest',
+ full_name='helloworld.HelloRequest',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='name', full_name='helloworld.HelloRequest.name', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=32,
+ serialized_end=60,
+)
+
+
+_HELLOREPLY = _descriptor.Descriptor(
+ name='HelloReply',
+ full_name='helloworld.HelloReply',
+ filename=None,
+ file=DESCRIPTOR,
+ containing_type=None,
+ fields=[
+ _descriptor.FieldDescriptor(
+ name='message', full_name='helloworld.HelloReply.message', index=0,
+ number=1, type=9, cpp_type=9, label=1,
+ has_default_value=False, default_value=_b("").decode('utf-8'),
+ message_type=None, enum_type=None, containing_type=None,
+ is_extension=False, extension_scope=None,
+ options=None),
+ ],
+ extensions=[
+ ],
+ nested_types=[],
+ enum_types=[
+ ],
+ options=None,
+ is_extendable=False,
+ syntax='proto3',
+ extension_ranges=[],
+ oneofs=[
+ ],
+ serialized_start=62,
+ serialized_end=91,
+)
+
+DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
+DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(
+ DESCRIPTOR = _HELLOREQUEST,
+ __module__ = 'helloworld_pb2'
+ # @@protoc_insertion_point(class_scope:helloworld.HelloRequest)
+ ))
+_sym_db.RegisterMessage(HelloRequest)
+
+HelloReply = _reflection.GeneratedProtocolMessageType('HelloReply', (_message.Message,), dict(
+ DESCRIPTOR = _HELLOREPLY,
+ __module__ = 'helloworld_pb2'
+ # @@protoc_insertion_point(class_scope:helloworld.HelloReply)
+ ))
+_sym_db.RegisterMessage(HelloReply)
+
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
+
+_GREETER = _descriptor.ServiceDescriptor(
+ name='Greeter',
+ full_name='helloworld.Greeter',
+ file=DESCRIPTOR,
+ index=0,
+ options=None,
+ serialized_start=93,
+ serialized_end=166,
+ methods=[
+ _descriptor.MethodDescriptor(
+ name='SayHello',
+ full_name='helloworld.Greeter.SayHello',
+ index=0,
+ containing_service=None,
+ input_type=_HELLOREQUEST,
+ output_type=_HELLOREPLY,
+ options=None,
+ ),
+])
+_sym_db.RegisterServiceDescriptor(_GREETER)
+
+DESCRIPTOR.services_by_name['Greeter'] = _GREETER
+
+# @@protoc_insertion_point(module_scope)
diff --git a/examples/python/metadata/helloworld_pb2_grpc.py b/examples/python/metadata/helloworld_pb2_grpc.py
new file mode 100644
index 0000000000..18e07d1679
--- /dev/null
+++ b/examples/python/metadata/helloworld_pb2_grpc.py
@@ -0,0 +1,46 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+import grpc
+
+import helloworld_pb2 as helloworld__pb2
+
+
+class GreeterStub(object):
+ """The greeting service definition.
+ """
+
+ def __init__(self, channel):
+ """Constructor.
+
+ Args:
+ channel: A grpc.Channel.
+ """
+ self.SayHello = channel.unary_unary(
+ '/helloworld.Greeter/SayHello',
+ request_serializer=helloworld__pb2.HelloRequest.SerializeToString,
+ response_deserializer=helloworld__pb2.HelloReply.FromString,
+ )
+
+
+class GreeterServicer(object):
+ """The greeting service definition.
+ """
+
+ def SayHello(self, request, context):
+ """Sends a greeting
+ """
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+ context.set_details('Method not implemented!')
+ raise NotImplementedError('Method not implemented!')
+
+
+def add_GreeterServicer_to_server(servicer, server):
+ rpc_method_handlers = {
+ 'SayHello': grpc.unary_unary_rpc_method_handler(
+ servicer.SayHello,
+ request_deserializer=helloworld__pb2.HelloRequest.FromString,
+ response_serializer=helloworld__pb2.HelloReply.SerializeToString,
+ ),
+ }
+ generic_handler = grpc.method_handlers_generic_handler(
+ 'helloworld.Greeter', rpc_method_handlers)
+ server.add_generic_rpc_handlers((generic_handler,))
diff --git a/examples/python/metadata/metadata_client.py b/examples/python/metadata/metadata_client.py
new file mode 100644
index 0000000000..f2a8e37cc2
--- /dev/null
+++ b/examples/python/metadata/metadata_client.py
@@ -0,0 +1,48 @@
+# 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.
+"""Example gRPC client that gets/sets metadata (HTTP2 headers)"""
+
+from __future__ import print_function
+import logging
+
+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.
+ with grpc.insecure_channel('localhost:50051') as channel:
+ stub = helloworld_pb2_grpc.GreeterStub(channel)
+ response, call = stub.SayHello.with_call(
+ helloworld_pb2.HelloRequest(name='you'),
+ metadata=(
+ ('initial-metadata-1', 'The value should be str'),
+ ('binary-metadata-bin',
+ b'With -bin surffix, the value can be bytes'),
+ ('accesstoken', 'gRPC Python is great'),
+ ))
+
+ print("Greeter client received: " + response.message)
+ for key, value in call.trailing_metadata():
+ print('Greeter client received trailing metadata: key=%s value=%s' %
+ (key, value))
+
+
+if __name__ == '__main__':
+ logging.basicConfig()
+ run()
diff --git a/examples/python/metadata/metadata_server.py b/examples/python/metadata/metadata_server.py
new file mode 100644
index 0000000000..a4329df79a
--- /dev/null
+++ b/examples/python/metadata/metadata_server.py
@@ -0,0 +1,56 @@
+# 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.
+"""Example gRPC server that gets/sets metadata (HTTP2 headers)"""
+
+from __future__ import print_function
+from concurrent import futures
+import time
+import logging
+
+import grpc
+
+import helloworld_pb2
+import helloworld_pb2_grpc
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+
+class Greeter(helloworld_pb2_grpc.GreeterServicer):
+
+ def SayHello(self, request, context):
+ for key, value in context.invocation_metadata():
+ print('Received initial metadata: key=%s value=%s' % (key, value))
+
+ context.set_trailing_metadata((
+ ('checksum-bin', b'I agree'),
+ ('retry', 'false'),
+ ))
+ return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
+
+
+def serve():
+ server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+ helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
+ server.add_insecure_port('[::]:50051')
+ server.start()
+ try:
+ while True:
+ time.sleep(_ONE_DAY_IN_SECONDS)
+ except KeyboardInterrupt:
+ server.stop(0)
+
+
+if __name__ == '__main__':
+ logging.basicConfig()
+ serve()
diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py
index 19d39ce66e..155f85c4b0 100644
--- a/examples/python/multiplex/multiplex_client.py
+++ b/examples/python/multiplex/multiplex_client.py
@@ -17,6 +17,7 @@ from __future__ import print_function
import random
import time
+import logging
import grpc
@@ -126,4 +127,5 @@ def run():
if __name__ == '__main__':
+ logging.basicConfig()
run()
diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py
index 70dec3c939..c01824b3a9 100644
--- a/examples/python/multiplex/multiplex_server.py
+++ b/examples/python/multiplex/multiplex_server.py
@@ -16,6 +16,7 @@
from concurrent import futures
import time
import math
+import logging
import grpc
@@ -136,4 +137,5 @@ def serve():
if __name__ == '__main__':
+ logging.basicConfig()
serve()
diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py
index b4ff3239ba..dc93fb4437 100644
--- a/examples/python/route_guide/route_guide_client.py
+++ b/examples/python/route_guide/route_guide_client.py
@@ -16,6 +16,7 @@
from __future__ import print_function
import random
+import logging
import grpc
@@ -116,4 +117,5 @@ def run():
if __name__ == '__main__':
+ logging.basicConfig()
run()
diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py
index 1969fdd378..e00cb69908 100644
--- a/examples/python/route_guide/route_guide_server.py
+++ b/examples/python/route_guide/route_guide_server.py
@@ -16,6 +16,7 @@
from concurrent import futures
import time
import math
+import logging
import grpc
@@ -126,4 +127,5 @@ def serve():
if __name__ == '__main__':
+ logging.basicConfig()
serve()
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index b9f5900751..414e788a96 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -23,15 +23,15 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
- # version = '1.17.0-dev'
- version = '0.0.3'
+ # version = '1.18.0-dev'
+ version = '0.0.6-dev'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
- grpc_version = '1.17.0-dev'
+ grpc_version = '1.18.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
@@ -78,6 +78,7 @@ Pod::Spec.new do |s|
ss.header_mappings_dir = 'include/grpcpp'
ss.source_files = 'include/grpcpp/alarm.h',
+ 'include/grpcpp/alarm_impl.h',
'include/grpcpp/channel.h',
'include/grpcpp/client_context.h',
'include/grpcpp/completion_queue.h',
@@ -256,6 +257,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/context_list.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
'src/core/ext/transport/chttp2/transport/frame_data.h',
@@ -347,14 +349,15 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@@ -404,6 +407,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
+ 'src/core/lib/iomgr/dynamic_annotations.h',
'src/core/lib/iomgr/endpoint.h',
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
@@ -596,6 +600,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
+ 'src/core/lib/iomgr/dynamic_annotations.h',
'src/core/lib/iomgr/endpoint.h',
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 189decc18a..4826044a3d 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -254,6 +254,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/context_list.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
'src/core/ext/transport/chttp2/transport/frame_data.h',
@@ -345,14 +346,15 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@@ -402,6 +404,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
+ 'src/core/lib/iomgr/dynamic_annotations.h',
'src/core/lib/iomgr/endpoint.h',
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
@@ -680,6 +683,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -783,15 +787,15 @@ Pod::Spec.new do |s|
'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',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -871,6 +875,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/context_list.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
'src/core/ext/transport/chttp2/transport/frame_data.h',
@@ -962,14 +967,15 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
+ 'src/core/ext/filters/client_channel/server_address.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
@@ -1019,6 +1025,7 @@ Pod::Spec.new do |s|
'src/core/lib/iomgr/call_combiner.h',
'src/core/lib/iomgr/closure.h',
'src/core/lib/iomgr/combiner.h',
+ 'src/core/lib/iomgr/dynamic_annotations.h',
'src/core/lib/iomgr/endpoint.h',
'src/core/lib/iomgr/endpoint_pair.h',
'src/core/lib/iomgr/error.h',
@@ -1200,6 +1207,7 @@ Pod::Spec.new do |s|
'test/core/security/oauth2_utils.cc',
'test/core/end2end/cq_verifier.cc',
'test/core/end2end/fixtures/http_proxy_fixture.cc',
+ 'test/core/end2end/fixtures/local_util.cc',
'test/core/end2end/fixtures/proxy.cc',
'test/core/iomgr/endpoint_tests.cc',
'test/core/util/debugger_macros.cc',
@@ -1226,6 +1234,7 @@ Pod::Spec.new do |s|
'test/core/security/oauth2_utils.h',
'test/core/end2end/cq_verifier.h',
'test/core/end2end/fixtures/http_proxy_fixture.h',
+ 'test/core/end2end/fixtures/local_util.h',
'test/core/end2end/fixtures/proxy.h',
'test/core/iomgr/endpoint_tests.h',
'test/core/util/debugger_macros.h',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 693b873d14..13fe3e0b9c 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index fd590023e1..e132ad41b4 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 5e513cb127..940a1ac621 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.gemspec b/grpc.gemspec
index d8e5aac13c..1ee7bec8e7 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -186,6 +186,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h )
s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.h )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/context_list.h )
s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.h )
s.files += %w( src/core/ext/transport/chttp2/transport/frame.h )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.h )
@@ -281,14 +282,15 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
- s.files += %w( src/core/ext/filters/client_channel/method_params.h )
s.files += %w( src/core/ext/filters/client_channel/parse_address.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h )
s.files += %w( src/core/ext/filters/client_channel/resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h )
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h )
+ s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
+ s.files += %w( src/core/ext/filters/client_channel/server_address.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
@@ -338,6 +340,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/iomgr/call_combiner.h )
s.files += %w( src/core/lib/iomgr/closure.h )
s.files += %w( src/core/lib/iomgr/combiner.h )
+ s.files += %w( src/core/lib/iomgr/dynamic_annotations.h )
s.files += %w( src/core/lib/iomgr/endpoint.h )
s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
s.files += %w( src/core/lib/iomgr/error.h )
@@ -616,6 +619,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_plugin.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.cc )
+ s.files += %w( src/core/ext/transport/chttp2/transport/context_list.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_goaway.cc )
@@ -722,15 +726,15 @@ Gem::Specification.new do |s|
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 )
- s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
- s.files += %w( src/core/ext/filters/client_channel/method_params.cc )
s.files += %w( src/core/ext/filters/client_channel/parse_address.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc )
+ s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc )
+ s.files += %w( src/core/ext/filters/client_channel/server_address.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
diff --git a/grpc.gyp b/grpc.gyp
index ae97b8b0ee..32d4bd409e 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -433,6 +433,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -539,15 +540,15 @@
'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',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -616,6 +617,7 @@
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'test/core/end2end/cq_verifier.cc',
'test/core/end2end/fixtures/http_proxy_fixture.cc',
+ 'test/core/end2end/fixtures/local_util.cc',
'test/core/end2end/fixtures/proxy.cc',
'test/core/iomgr/endpoint_tests.cc',
'test/core/util/debugger_macros.cc',
@@ -798,15 +800,15 @@
'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',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -818,6 +820,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -855,6 +858,7 @@
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
'test/core/end2end/cq_verifier.cc',
'test/core/end2end/fixtures/http_proxy_fixture.cc',
+ 'test/core/end2end/fixtures/local_util.cc',
'test/core/end2end/fixtures/proxy.cc',
'test/core/iomgr/endpoint_tests.cc',
'test/core/util/debugger_macros.cc',
@@ -1037,15 +1041,15 @@
'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',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -1057,6 +1061,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -1249,6 +1254,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -1288,15 +1294,15 @@
'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',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
@@ -1493,6 +1499,8 @@
'src/proto/grpc/testing/echo_messages.proto',
'src/proto/grpc/testing/echo.proto',
'src/proto/grpc/testing/duplicate/echo_duplicate.proto',
+ 'src/proto/grpc/testing/simple_messages.proto',
+ 'test/cpp/end2end/test_health_check_service_impl.cc',
'test/cpp/end2end/test_service_impl.cc',
'test/cpp/util/byte_buffer_proto_helper.cc',
'test/cpp/util/channel_trace_proto_helper.cc',
@@ -1516,6 +1524,8 @@
'src/proto/grpc/testing/echo_messages.proto',
'src/proto/grpc/testing/echo.proto',
'src/proto/grpc/testing/duplicate/echo_duplicate.proto',
+ 'src/proto/grpc/testing/simple_messages.proto',
+ 'test/cpp/end2end/test_health_check_service_impl.cc',
'test/cpp/end2end/test_service_impl.cc',
'test/cpp/util/byte_buffer_proto_helper.cc',
'test/cpp/util/string_ref_helper.cc',
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index d3b74cabab..fec7f5269e 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -511,7 +511,8 @@ GRPCAPI char* grpc_channelz_get_server(intptr_t server_id);
/* Gets all server sockets that exist in the server. */
GRPCAPI char* grpc_channelz_get_server_sockets(intptr_t server_id,
- intptr_t start_socket_id);
+ intptr_t start_socket_id,
+ intptr_t max_results);
/* Returns a single Channel, or else a NOT_FOUND code. The returned string
is allocated and must be freed by the application. */
diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h
index f935557f2d..a082f67010 100644
--- a/include/grpc/grpc_security_constants.h
+++ b/include/grpc/grpc_security_constants.h
@@ -106,10 +106,10 @@ typedef enum {
} grpc_ssl_client_certificate_request_type;
/**
- * Type of local connection for which local channel/server credentials will be
- * applied. It only supports UDS for now.
+ * Type of local connections for which local channel/server credentials will be
+ * applied. It supports UDS and local TCP connections.
*/
-typedef enum { UDS = 0 } grpc_local_connect_type;
+typedef enum { UDS = 0, LOCAL_TCP } grpc_local_connect_type;
#ifdef __cplusplus
}
diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h
index c0010a3469..728c3d5412 100644
--- a/include/grpc/impl/codegen/atm_gcc_sync.h
+++ b/include/grpc/impl/codegen/atm_gcc_sync.h
@@ -26,6 +26,8 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
+#define GPR_ATM_INC_CAS_THEN(blah) blah
+#define GPR_ATM_INC_ADD_THEN(blah) blah
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
diff --git a/include/grpc/impl/codegen/atm_windows.h b/include/grpc/impl/codegen/atm_windows.h
index f6b27e5df7..c016b90095 100644
--- a/include/grpc/impl/codegen/atm_windows.h
+++ b/include/grpc/impl/codegen/atm_windows.h
@@ -25,6 +25,8 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
+#define GPR_ATM_INC_CAS_THEN(blah) blah
+#define GPR_ATM_INC_ADD_THEN(blah) blah
#define gpr_atm_full_barrier MemoryBarrier
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 17a43fab0f..a9fb27946e 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -293,7 +293,7 @@ typedef struct {
"grpc.max_channel_trace_event_memory_per_node"
/** If non-zero, gRPC library will track stats and information at at per channel
* level. Disabling channelz naturally disables channel tracing. The default
- * is for channelz to be disabled. */
+ * is for channelz to be enabled. */
#define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz"
/** If non-zero, Cronet transport will coalesce packets to fewer frames
* when possible. */
@@ -350,6 +350,11 @@ typedef struct {
/** If set, inhibits health checking (which may be enabled via the
* service config.) */
#define GRPC_ARG_INHIBIT_HEALTH_CHECKING "grpc.inhibit_health_checking"
+/** If set, determines the number of milliseconds that the c-ares based
+ * DNS resolver will wait on queries before cancelling them. The default value
+ * is 10000. Setting this to "0" will disable c-ares query timeouts
+ * entirely. */
+#define GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS "grpc.dns_ares_query_timeout"
/** \} */
/** Result of a grpc call. If the caller satisfies the prerequisites of a
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index b2028a6305..031c0c36ae 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -526,6 +526,15 @@ typedef unsigned __int64 uint64_t;
#endif /* GPR_ATTRIBUTE_NO_TSAN (2) */
#endif /* GPR_ATTRIBUTE_NO_TSAN (1) */
+/* GRPC_TSAN_ENABLED will be defined, when compiled with thread sanitizer. */
+#if defined(__SANITIZE_THREAD__)
+#define GRPC_TSAN_ENABLED
+#elif defined(__has_feature)
+#if __has_feature(thread_sanitizer)
+#define GRPC_TSAN_ENABLED
+#endif
+#endif
+
/* GRPC_ALLOW_EXCEPTIONS should be 0 or 1 if exceptions are allowed or not */
#ifndef GRPC_ALLOW_EXCEPTIONS
/* If not already set, set to 1 on Windows (style guide standard) but to
diff --git a/include/grpcpp/alarm.h b/include/grpcpp/alarm.h
index 365feb4eb9..2343c1149c 100644
--- a/include/grpcpp/alarm.h
+++ b/include/grpcpp/alarm.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * 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.
@@ -16,99 +16,14 @@
*
*/
-/// An Alarm posts the user provided tag to its associated completion queue upon
-/// expiry or cancellation.
#ifndef GRPCPP_ALARM_H
#define GRPCPP_ALARM_H
-#include <functional>
-
-#include <grpc/grpc.h>
-#include <grpcpp/impl/codegen/completion_queue.h>
-#include <grpcpp/impl/codegen/completion_queue_tag.h>
-#include <grpcpp/impl/codegen/grpc_library.h>
-#include <grpcpp/impl/codegen/time.h>
-#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/alarm_impl.h>
namespace grpc {
-/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
-class Alarm : private GrpcLibraryCodegen {
- public:
- /// Create an unset completion queue alarm
- Alarm();
-
- /// Destroy the given completion queue alarm, cancelling it in the process.
- ~Alarm();
-
- /// DEPRECATED: Create and set a completion queue alarm instance associated to
- /// \a cq.
- /// This form is deprecated because it is inherently racy.
- /// \internal We rely on the presence of \a cq for grpc initialization. If \a
- /// cq were ever to be removed, a reference to a static
- /// internal::GrpcLibraryInitializer instance would need to be introduced
- /// here. \endinternal.
- template <typename T>
- Alarm(CompletionQueue* cq, const T& deadline, void* tag) : Alarm() {
- SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
- }
-
- /// Trigger an alarm instance on completion queue \a cq at the specified time.
- /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
- /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
- /// event's success bit will be true, false otherwise (ie, upon cancellation).
- template <typename T>
- void Set(CompletionQueue* cq, const T& deadline, void* tag) {
- SetInternal(cq, TimePoint<T>(deadline).raw_time(), tag);
- }
-
- /// Alarms aren't copyable.
- Alarm(const Alarm&) = delete;
- Alarm& operator=(const Alarm&) = delete;
-
- /// Alarms are movable.
- Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
- Alarm& operator=(Alarm&& rhs) {
- alarm_ = rhs.alarm_;
- rhs.alarm_ = nullptr;
- return *this;
- }
-
- /// Cancel a completion queue alarm. Calling this function over an alarm that
- /// has already fired has no effect.
- void Cancel();
-
- /// NOTE: class experimental_type is not part of the public API of this class
- /// TODO(vjpai): Move these contents to the public API of Alarm when
- /// they are no longer experimental
- class experimental_type {
- public:
- explicit experimental_type(Alarm* alarm) : alarm_(alarm) {}
-
- /// Set an alarm to invoke callback \a f. The argument to the callback
- /// states whether the alarm expired at \a deadline (true) or was cancelled
- /// (false)
- template <typename T>
- void Set(const T& deadline, std::function<void(bool)> f) {
- alarm_->SetInternal(TimePoint<T>(deadline).raw_time(), std::move(f));
- }
-
- private:
- Alarm* alarm_;
- };
-
- /// NOTE: The function experimental() is not stable public API. It is a view
- /// to the experimental components of this class. It may be changed or removed
- /// at any time.
- experimental_type experimental() { return experimental_type(this); }
-
- private:
- void SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag);
- void SetInternal(gpr_timespec deadline, std::function<void(bool)> f);
-
- internal::CompletionQueueTag* alarm_;
-};
-
-} // namespace grpc
+typedef ::grpc_impl::Alarm Alarm;
+}
#endif // GRPCPP_ALARM_H
diff --git a/include/grpcpp/alarm_impl.h b/include/grpcpp/alarm_impl.h
new file mode 100644
index 0000000000..7844e7c886
--- /dev/null
+++ b/include/grpcpp/alarm_impl.h
@@ -0,0 +1,116 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/// An Alarm posts the user provided tag to its associated completion queue upon
+/// expiry or cancellation.
+#ifndef GRPCPP_ALARM_IMPL_H
+#define GRPCPP_ALARM_IMPL_H
+
+#include <functional>
+
+#include <grpc/grpc.h>
+#include <grpcpp/impl/codegen/completion_queue.h>
+#include <grpcpp/impl/codegen/completion_queue_tag.h>
+#include <grpcpp/impl/codegen/grpc_library.h>
+#include <grpcpp/impl/codegen/time.h>
+#include <grpcpp/impl/grpc_library.h>
+
+namespace grpc_impl {
+
+/// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
+class Alarm : private ::grpc::GrpcLibraryCodegen {
+ public:
+ /// Create an unset completion queue alarm
+ Alarm();
+
+ /// Destroy the given completion queue alarm, cancelling it in the process.
+ ~Alarm();
+
+ /// DEPRECATED: Create and set a completion queue alarm instance associated to
+ /// \a cq.
+ /// This form is deprecated because it is inherently racy.
+ /// \internal We rely on the presence of \a cq for grpc initialization. If \a
+ /// cq were ever to be removed, a reference to a static
+ /// internal::GrpcLibraryInitializer instance would need to be introduced
+ /// here. \endinternal.
+ template <typename T>
+ Alarm(::grpc::CompletionQueue* cq, const T& deadline, void* tag) : Alarm() {
+ SetInternal(cq, ::grpc::TimePoint<T>(deadline).raw_time(), tag);
+ }
+
+ /// Trigger an alarm instance on completion queue \a cq at the specified time.
+ /// Once the alarm expires (at \a deadline) or it's cancelled (see \a Cancel),
+ /// an event with tag \a tag will be added to \a cq. If the alarm expired, the
+ /// event's success bit will be true, false otherwise (ie, upon cancellation).
+ template <typename T>
+ void Set(::grpc::CompletionQueue* cq, const T& deadline, void* tag) {
+ SetInternal(cq, ::grpc::TimePoint<T>(deadline).raw_time(), tag);
+ }
+
+ /// Alarms aren't copyable.
+ Alarm(const Alarm&) = delete;
+ Alarm& operator=(const Alarm&) = delete;
+
+ /// Alarms are movable.
+ Alarm(Alarm&& rhs) : alarm_(rhs.alarm_) { rhs.alarm_ = nullptr; }
+ Alarm& operator=(Alarm&& rhs) {
+ alarm_ = rhs.alarm_;
+ rhs.alarm_ = nullptr;
+ return *this;
+ }
+
+ /// Cancel a completion queue alarm. Calling this function over an alarm that
+ /// has already fired has no effect.
+ void Cancel();
+
+ /// NOTE: class experimental_type is not part of the public API of this class
+ /// TODO(vjpai): Move these contents to the public API of Alarm when
+ /// they are no longer experimental
+ class experimental_type {
+ public:
+ explicit experimental_type(Alarm* alarm) : alarm_(alarm) {}
+
+ /// Set an alarm to invoke callback \a f. The argument to the callback
+ /// states whether the alarm expired at \a deadline (true) or was cancelled
+ /// (false)
+ template <typename T>
+ void Set(const T& deadline, std::function<void(bool)> f) {
+ alarm_->SetInternal(::grpc::TimePoint<T>(deadline).raw_time(),
+ std::move(f));
+ }
+
+ private:
+ Alarm* alarm_;
+ };
+
+ /// NOTE: The function experimental() is not stable public API. It is a view
+ /// to the experimental components of this class. It may be changed or removed
+ /// at any time.
+ experimental_type experimental() { return experimental_type(this); }
+
+ private:
+ void SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline,
+ void* tag);
+ void SetInternal(gpr_timespec deadline, std::function<void(bool)> f);
+
+ ::grpc::internal::CompletionQueueTag* alarm_;
+};
+
+} // namespace grpc_impl
+
+#endif // GRPCPP_ALARM_IMPL_H
diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h
index 4502b94b17..ee83396069 100644
--- a/include/grpcpp/channel.h
+++ b/include/grpcpp/channel.h
@@ -65,13 +65,13 @@ class Channel final : public ChannelInterface,
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
internal::Call CreateCall(const internal::RpcMethod& method,
diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h
index 43188d09e7..e8a2a70581 100644
--- a/include/grpcpp/create_channel.h
+++ b/include/grpcpp/create_channel.h
@@ -70,8 +70,8 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace experimental
} // namespace grpc
diff --git a/include/grpcpp/generic/generic_stub.h b/include/grpcpp/generic/generic_stub.h
index d509d9a520..eb014184e4 100644
--- a/include/grpcpp/generic/generic_stub.h
+++ b/include/grpcpp/generic/generic_stub.h
@@ -24,6 +24,7 @@
#include <grpcpp/support/async_stream.h>
#include <grpcpp/support/async_unary_call.h>
#include <grpcpp/support/byte_buffer.h>
+#include <grpcpp/support/client_callback.h>
#include <grpcpp/support/status.h>
namespace grpc {
@@ -76,6 +77,10 @@ class GenericStub final {
const ByteBuffer* request, ByteBuffer* response,
std::function<void(Status)> on_completion);
+ void PrepareBidiStreamingCall(
+ ClientContext* context, const grpc::string& method,
+ experimental::ClientBidiReactor<ByteBuffer, ByteBuffer>* reactor);
+
private:
GenericStub* stub_;
};
diff --git a/include/grpcpp/health_check_service_interface.h b/include/grpcpp/health_check_service_interface.h
index b45a699bda..dfd4c3983a 100644
--- a/include/grpcpp/health_check_service_interface.h
+++ b/include/grpcpp/health_check_service_interface.h
@@ -37,6 +37,10 @@ class HealthCheckServiceInterface {
bool serving) = 0;
/// Apply to all registered service names.
virtual void SetServingStatus(bool serving) = 0;
+
+ /// Set all registered service names to not serving and prevent future
+ /// state changes.
+ virtual void Shutdown() {}
};
/// Enable/disable the default health checking service. This applies to all C++
diff --git a/include/grpcpp/impl/codegen/byte_buffer.h b/include/grpcpp/impl/codegen/byte_buffer.h
index abba5549b8..a77e36dfc5 100644
--- a/include/grpcpp/impl/codegen/byte_buffer.h
+++ b/include/grpcpp/impl/codegen/byte_buffer.h
@@ -45,8 +45,10 @@ template <class ServiceType, class RequestType, class ResponseType>
class RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
-template <class ServiceType, class RequestType, class ResponseType>
+template <class RequestType, class ResponseType>
class CallbackUnaryHandler;
+template <class RequestType, class ResponseType>
+class CallbackServerStreamingHandler;
template <StatusCode code>
class ErrorMethodHandler;
template <class R>
@@ -91,7 +93,9 @@ class ByteBuffer final {
}
/// Constuct a byte buffer by referencing elements of existing buffer
- /// \a buf. Wrapper of core function grpc_byte_buffer_copy
+ /// \a buf. Wrapper of core function grpc_byte_buffer_copy . This is not
+ /// a deep copy; it is just a referencing. As a result, its performance is
+ /// size-independent.
ByteBuffer(const ByteBuffer& buf);
~ByteBuffer() {
@@ -100,6 +104,9 @@ class ByteBuffer final {
}
}
+ /// Wrapper of core function grpc_byte_buffer_copy . This is not
+ /// a deep copy; it is just a referencing. As a result, its performance is
+ /// size-independent.
ByteBuffer& operator=(const ByteBuffer&);
/// Dump (read) the buffer contents into \a slices.
@@ -115,7 +122,9 @@ class ByteBuffer final {
/// Make a duplicate copy of the internals of this byte
/// buffer so that we have our own owned version of it.
- /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable
+ /// bbuf.Duplicate(); is equivalent to bbuf=bbuf; but is actually readable.
+ /// This is not a deep copy; it is a referencing and its performance
+ /// is size-independent.
void Duplicate() {
buffer_ = g_core_codegen_interface->grpc_byte_buffer_copy(buffer_);
}
@@ -156,8 +165,10 @@ class ByteBuffer final {
friend class internal::RpcMethodHandler;
template <class ServiceType, class RequestType, class ResponseType>
friend class internal::ServerStreamingHandler;
- template <class ServiceType, class RequestType, class ResponseType>
+ template <class RequestType, class ResponseType>
friend class internal::CallbackUnaryHandler;
+ template <class RequestType, class ResponseType>
+ friend class ::grpc::internal::CallbackServerStreamingHandler;
template <StatusCode code>
friend class internal::ErrorMethodHandler;
template <class R>
diff --git a/include/grpcpp/impl/codegen/call_op_set.h b/include/grpcpp/impl/codegen/call_op_set.h
index ac3ba17bd9..3db9f48bff 100644
--- a/include/grpcpp/impl/codegen/call_op_set.h
+++ b/include/grpcpp/impl/codegen/call_op_set.h
@@ -343,6 +343,9 @@ class CallOpSendMessage {
// We had already registered failed_send_ earlier. No need to do it again.
}
send_buf_.Clear();
+ // The contents of the SendMessage value that was previously set
+ // has had its references stolen by core's operations
+ interceptor_methods->SetSendMessage(nullptr);
}
void SetHijackingState(InterceptorBatchMethodsImpl* interceptor_methods) {
diff --git a/include/grpcpp/impl/codegen/callback_common.h b/include/grpcpp/impl/codegen/callback_common.h
index 51367cf550..a3c8c41246 100644
--- a/include/grpcpp/impl/codegen/callback_common.h
+++ b/include/grpcpp/impl/codegen/callback_common.h
@@ -32,6 +32,8 @@ namespace grpc {
namespace internal {
/// An exception-safe way of invoking a user-specified callback function
+// TODO(vjpai): decide whether it is better for this to take a const lvalue
+// parameter or an rvalue parameter, or if it even matters
template <class Func, class... Args>
void CatchingCallback(Func&& func, Args&&... args) {
#if GRPC_ALLOW_EXCEPTIONS
@@ -45,6 +47,20 @@ void CatchingCallback(Func&& func, Args&&... args) {
#endif // GRPC_ALLOW_EXCEPTIONS
}
+template <class ReturnType, class Func, class... Args>
+ReturnType* CatchingReactorCreator(Func&& func, Args&&... args) {
+#if GRPC_ALLOW_EXCEPTIONS
+ try {
+ return func(std::forward<Args>(args)...);
+ } catch (...) {
+ // fail the RPC, don't crash the library
+ return nullptr;
+ }
+#else // GRPC_ALLOW_EXCEPTIONS
+ return func(std::forward<Args>(args)...);
+#endif // GRPC_ALLOW_EXCEPTIONS
+}
+
// The contract on these tags is that they are single-shot. They must be
// constructed and then fired at exactly one point. There is no expectation
// that they can be reused without reconstruction.
@@ -145,18 +161,19 @@ class CallbackWithSuccessTag
// or on a tag that has been Set before unless the tag has been cleared.
void Set(grpc_call* call, std::function<void(bool)> f,
CompletionQueueTag* ops) {
+ GPR_CODEGEN_ASSERT(call_ == nullptr);
+ g_core_codegen_interface->grpc_call_ref(call);
call_ = call;
func_ = std::move(f);
ops_ = ops;
- g_core_codegen_interface->grpc_call_ref(call);
functor_run = &CallbackWithSuccessTag::StaticRun;
}
void Clear() {
if (call_ != nullptr) {
- func_ = nullptr;
grpc_call* call = call_;
call_ = nullptr;
+ func_ = nullptr;
g_core_codegen_interface->grpc_call_unref(call);
}
}
@@ -182,11 +199,11 @@ class CallbackWithSuccessTag
}
void Run(bool ok) {
void* ignored = ops_;
- bool new_ok = ok;
// Allow a "false" return value from FinalizeResult to silence the
// callback, just as it silences a CQ tag in the async cases
- bool do_callback = ops_->FinalizeResult(&ignored, &new_ok);
- GPR_CODEGEN_ASSERT(ignored == ops_);
+ auto* ops = ops_;
+ bool do_callback = ops_->FinalizeResult(&ignored, &ok);
+ GPR_CODEGEN_ASSERT(ignored == ops);
if (do_callback) {
CatchingCallback(func_, ok);
diff --git a/include/grpcpp/impl/codegen/channel_interface.h b/include/grpcpp/impl/codegen/channel_interface.h
index 6ec1ffb8c7..5353f5feaa 100644
--- a/include/grpcpp/impl/codegen/channel_interface.h
+++ b/include/grpcpp/impl/codegen/channel_interface.h
@@ -21,7 +21,6 @@
#include <grpc/impl/codegen/connectivity_state.h>
#include <grpcpp/impl/codegen/call.h>
-#include <grpcpp/impl/codegen/client_context.h>
#include <grpcpp/impl/codegen/status.h>
#include <grpcpp/impl/codegen/time.h>
@@ -53,6 +52,12 @@ template <class W, class R>
class ClientAsyncReaderWriterFactory;
template <class R>
class ClientAsyncResponseReaderFactory;
+template <class W, class R>
+class ClientCallbackReaderWriterFactory;
+template <class R>
+class ClientCallbackReaderFactory;
+template <class W>
+class ClientCallbackWriterFactory;
class InterceptedChannel;
} // namespace internal
@@ -106,6 +111,12 @@ class ChannelInterface {
friend class ::grpc::internal::ClientAsyncReaderWriterFactory;
template <class R>
friend class ::grpc::internal::ClientAsyncResponseReaderFactory;
+ template <class W, class R>
+ friend class ::grpc::internal::ClientCallbackReaderWriterFactory;
+ template <class R>
+ friend class ::grpc::internal::ClientCallbackReaderFactory;
+ template <class W>
+ friend class ::grpc::internal::ClientCallbackWriterFactory;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>
diff --git a/include/grpcpp/impl/codegen/client_callback.h b/include/grpcpp/impl/codegen/client_callback.h
index 4baa819091..66cf9b7754 100644
--- a/include/grpcpp/impl/codegen/client_callback.h
+++ b/include/grpcpp/impl/codegen/client_callback.h
@@ -22,6 +22,7 @@
#include <functional>
#include <grpcpp/impl/codegen/call.h>
+#include <grpcpp/impl/codegen/call_op_set.h>
#include <grpcpp/impl/codegen/callback_common.h>
#include <grpcpp/impl/codegen/channel_interface.h>
#include <grpcpp/impl/codegen/config.h>
@@ -88,6 +89,660 @@ class CallbackUnaryCallImpl {
call.PerformOps(ops);
}
};
+} // namespace internal
+
+namespace experimental {
+
+// Forward declarations
+template <class Request, class Response>
+class ClientBidiReactor;
+template <class Response>
+class ClientReadReactor;
+template <class Request>
+class ClientWriteReactor;
+
+// NOTE: The streaming objects are not actually implemented in the public API.
+// These interfaces are provided for mocking only. Typical applications
+// will interact exclusively with the reactors that they define.
+template <class Request, class Response>
+class ClientCallbackReaderWriter {
+ public:
+ virtual ~ClientCallbackReaderWriter() {}
+ virtual void StartCall() = 0;
+ virtual void Write(const Request* req, WriteOptions options) = 0;
+ virtual void WritesDone() = 0;
+ virtual void Read(Response* resp) = 0;
+
+ protected:
+ void BindReactor(ClientBidiReactor<Request, Response>* reactor) {
+ reactor->BindStream(this);
+ }
+};
+
+template <class Response>
+class ClientCallbackReader {
+ public:
+ virtual ~ClientCallbackReader() {}
+ virtual void StartCall() = 0;
+ virtual void Read(Response* resp) = 0;
+
+ protected:
+ void BindReactor(ClientReadReactor<Response>* reactor) {
+ reactor->BindReader(this);
+ }
+};
+
+template <class Request>
+class ClientCallbackWriter {
+ public:
+ virtual ~ClientCallbackWriter() {}
+ virtual void StartCall() = 0;
+ void Write(const Request* req) { Write(req, WriteOptions()); }
+ virtual void Write(const Request* req, WriteOptions options) = 0;
+ void WriteLast(const Request* req, WriteOptions options) {
+ Write(req, options.set_last_message());
+ }
+ virtual void WritesDone() = 0;
+
+ protected:
+ void BindReactor(ClientWriteReactor<Request>* reactor) {
+ reactor->BindWriter(this);
+ }
+};
+
+// The user must implement this reactor interface with reactions to each event
+// type that gets called by the library. An empty reaction is provided by
+// default
+template <class Request, class Response>
+class ClientBidiReactor {
+ public:
+ virtual ~ClientBidiReactor() {}
+ virtual void OnDone(const Status& s) {}
+ virtual void OnReadInitialMetadataDone(bool ok) {}
+ virtual void OnReadDone(bool ok) {}
+ virtual void OnWriteDone(bool ok) {}
+ virtual void OnWritesDoneDone(bool ok) {}
+
+ void StartCall() { stream_->StartCall(); }
+ void StartRead(Response* resp) { stream_->Read(resp); }
+ void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); }
+ void StartWrite(const Request* req, WriteOptions options) {
+ stream_->Write(req, std::move(options));
+ }
+ void StartWriteLast(const Request* req, WriteOptions options) {
+ StartWrite(req, std::move(options.set_last_message()));
+ }
+ void StartWritesDone() { stream_->WritesDone(); }
+
+ private:
+ friend class ClientCallbackReaderWriter<Request, Response>;
+ void BindStream(ClientCallbackReaderWriter<Request, Response>* stream) {
+ stream_ = stream;
+ }
+ ClientCallbackReaderWriter<Request, Response>* stream_;
+};
+
+template <class Response>
+class ClientReadReactor {
+ public:
+ virtual ~ClientReadReactor() {}
+ virtual void OnDone(const Status& s) {}
+ virtual void OnReadInitialMetadataDone(bool ok) {}
+ virtual void OnReadDone(bool ok) {}
+
+ void StartCall() { reader_->StartCall(); }
+ void StartRead(Response* resp) { reader_->Read(resp); }
+
+ private:
+ friend class ClientCallbackReader<Response>;
+ void BindReader(ClientCallbackReader<Response>* reader) { reader_ = reader; }
+ ClientCallbackReader<Response>* reader_;
+};
+
+template <class Request>
+class ClientWriteReactor {
+ public:
+ virtual ~ClientWriteReactor() {}
+ virtual void OnDone(const Status& s) {}
+ virtual void OnReadInitialMetadataDone(bool ok) {}
+ virtual void OnWriteDone(bool ok) {}
+ virtual void OnWritesDoneDone(bool ok) {}
+
+ void StartCall() { writer_->StartCall(); }
+ void StartWrite(const Request* req) { StartWrite(req, WriteOptions()); }
+ void StartWrite(const Request* req, WriteOptions options) {
+ writer_->Write(req, std::move(options));
+ }
+ void StartWriteLast(const Request* req, WriteOptions options) {
+ StartWrite(req, std::move(options.set_last_message()));
+ }
+ void StartWritesDone() { writer_->WritesDone(); }
+
+ private:
+ friend class ClientCallbackWriter<Request>;
+ void BindWriter(ClientCallbackWriter<Request>* writer) { writer_ = writer; }
+ ClientCallbackWriter<Request>* writer_;
+};
+
+} // namespace experimental
+
+namespace internal {
+
+// Forward declare factory classes for friendship
+template <class Request, class Response>
+class ClientCallbackReaderWriterFactory;
+template <class Response>
+class ClientCallbackReaderFactory;
+template <class Request>
+class ClientCallbackWriterFactory;
+
+template <class Request, class Response>
+class ClientCallbackReaderWriterImpl
+ : public ::grpc::experimental::ClientCallbackReaderWriter<Request,
+ Response> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientCallbackReaderWriterImpl));
+ }
+
+ // 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 MaybeFinish() {
+ if (--callbacks_outstanding_ == 0) {
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
+ auto* call = call_.call();
+ this->~ClientCallbackReaderWriterImpl();
+ g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
+ }
+ }
+
+ void StartCall() override {
+ // This call initiates two batches, plus any backlog, each with a callback
+ // 1. Send initial metadata (unless corked) + recv initial metadata
+ // 2. Any read backlog
+ // 3. Recv trailing metadata, on_completion callback
+ // 4. Any write backlog
+ // 5. See if the call can finish (if other callbacks were triggered already)
+ started_ = true;
+
+ start_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadInitialMetadataDone(ok);
+ MaybeFinish();
+ },
+ &start_ops_);
+ if (!start_corked_) {
+ start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ }
+ start_ops_.RecvInitialMetadata(context_);
+ start_ops_.set_core_cq_tag(&start_tag_);
+ call_.PerformOps(&start_ops_);
+
+ // Also set up the read and write tags so that they don't have to be set up
+ // each time
+ write_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnWriteDone(ok);
+ MaybeFinish();
+ },
+ &write_ops_);
+ write_ops_.set_core_cq_tag(&write_tag_);
+
+ read_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadDone(ok);
+ MaybeFinish();
+ },
+ &read_ops_);
+ read_ops_.set_core_cq_tag(&read_tag_);
+ if (read_ops_at_start_) {
+ call_.PerformOps(&read_ops_);
+ }
+
+ finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); },
+ &finish_ops_);
+ finish_ops_.ClientRecvStatus(context_, &finish_status_);
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+ call_.PerformOps(&finish_ops_);
+
+ if (write_ops_at_start_) {
+ call_.PerformOps(&write_ops_);
+ }
+
+ if (writes_done_ops_at_start_) {
+ call_.PerformOps(&writes_done_ops_);
+ }
+ MaybeFinish();
+ }
+
+ void Read(Response* msg) override {
+ read_ops_.RecvMessage(msg);
+ callbacks_outstanding_++;
+ if (started_) {
+ call_.PerformOps(&read_ops_);
+ } else {
+ read_ops_at_start_ = true;
+ }
+ }
+
+ void Write(const Request* msg, WriteOptions options) override {
+ if (start_corked_) {
+ write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ start_corked_ = false;
+ }
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok());
+
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ write_ops_.ClientSendClose();
+ }
+ callbacks_outstanding_++;
+ if (started_) {
+ call_.PerformOps(&write_ops_);
+ } else {
+ write_ops_at_start_ = true;
+ }
+ }
+ void WritesDone() override {
+ if (start_corked_) {
+ writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ start_corked_ = false;
+ }
+ writes_done_ops_.ClientSendClose();
+ writes_done_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnWritesDoneDone(ok);
+ MaybeFinish();
+ },
+ &writes_done_ops_);
+ writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
+ callbacks_outstanding_++;
+ if (started_) {
+ call_.PerformOps(&writes_done_ops_);
+ } else {
+ writes_done_ops_at_start_ = true;
+ }
+ }
+
+ private:
+ friend class ClientCallbackReaderWriterFactory<Request, Response>;
+
+ ClientCallbackReaderWriterImpl(
+ Call call, ClientContext* context,
+ ::grpc::experimental::ClientBidiReactor<Request, Response>* reactor)
+ : context_(context),
+ call_(call),
+ reactor_(reactor),
+ start_corked_(context_->initial_metadata_corked_) {
+ this->BindReactor(reactor);
+ }
+
+ ClientContext* context_;
+ Call call_;
+ ::grpc::experimental::ClientBidiReactor<Request, Response>* reactor_;
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpRecvInitialMetadata> start_ops_;
+ CallbackWithSuccessTag start_tag_;
+ bool start_corked_;
+
+ CallOpSet<CallOpClientRecvStatus> finish_ops_;
+ CallbackWithSuccessTag finish_tag_;
+ Status finish_status_;
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ write_ops_;
+ CallbackWithSuccessTag write_tag_;
+ bool write_ops_at_start_{false};
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpClientSendClose> writes_done_ops_;
+ CallbackWithSuccessTag writes_done_tag_;
+ bool writes_done_ops_at_start_{false};
+
+ CallOpSet<CallOpRecvMessage<Response>> read_ops_;
+ CallbackWithSuccessTag read_tag_;
+ bool read_ops_at_start_{false};
+
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
+ bool started_{false};
+};
+
+template <class Request, class Response>
+class ClientCallbackReaderWriterFactory {
+ public:
+ static void Create(
+ ChannelInterface* channel, const ::grpc::internal::RpcMethod& method,
+ ClientContext* context,
+ ::grpc::experimental::ClientBidiReactor<Request, Response>* reactor) {
+ Call call = channel->CreateCall(method, context, channel->CallbackCQ());
+
+ g_core_codegen_interface->grpc_call_ref(call.call());
+ new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientCallbackReaderWriterImpl<Request, Response>)))
+ ClientCallbackReaderWriterImpl<Request, Response>(call, context,
+ reactor);
+ }
+};
+
+template <class Response>
+class ClientCallbackReaderImpl
+ : public ::grpc::experimental::ClientCallbackReader<Response> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientCallbackReaderImpl));
+ }
+
+ // 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 MaybeFinish() {
+ if (--callbacks_outstanding_ == 0) {
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
+ auto* call = call_.call();
+ this->~ClientCallbackReaderImpl();
+ g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
+ }
+ }
+
+ void StartCall() override {
+ // This call initiates two batches, plus any backlog, each with a callback
+ // 1. Send initial metadata (unless corked) + recv initial metadata
+ // 2. Any backlog
+ // 3. Recv trailing metadata, on_completion callback
+ // 4. See if the call can finish (if other callbacks were triggered already)
+ started_ = true;
+
+ start_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadInitialMetadataDone(ok);
+ MaybeFinish();
+ },
+ &start_ops_);
+ start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ start_ops_.RecvInitialMetadata(context_);
+ start_ops_.set_core_cq_tag(&start_tag_);
+ call_.PerformOps(&start_ops_);
+
+ // Also set up the read tag so it doesn't have to be set up each time
+ read_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadDone(ok);
+ MaybeFinish();
+ },
+ &read_ops_);
+ read_ops_.set_core_cq_tag(&read_tag_);
+ if (read_ops_at_start_) {
+ call_.PerformOps(&read_ops_);
+ }
+
+ finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); },
+ &finish_ops_);
+ finish_ops_.ClientRecvStatus(context_, &finish_status_);
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+ call_.PerformOps(&finish_ops_);
+
+ MaybeFinish();
+ }
+
+ void Read(Response* msg) override {
+ read_ops_.RecvMessage(msg);
+ callbacks_outstanding_++;
+ if (started_) {
+ call_.PerformOps(&read_ops_);
+ } else {
+ read_ops_at_start_ = true;
+ }
+ }
+
+ private:
+ friend class ClientCallbackReaderFactory<Response>;
+
+ template <class Request>
+ ClientCallbackReaderImpl(
+ Call call, ClientContext* context, Request* request,
+ ::grpc::experimental::ClientReadReactor<Response>* reactor)
+ : context_(context), call_(call), reactor_(reactor) {
+ this->BindReactor(reactor);
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(start_ops_.SendMessage(*request).ok());
+ start_ops_.ClientSendClose();
+ }
+
+ ClientContext* context_;
+ Call call_;
+ ::grpc::experimental::ClientReadReactor<Response>* reactor_;
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose,
+ CallOpRecvInitialMetadata>
+ start_ops_;
+ CallbackWithSuccessTag start_tag_;
+
+ CallOpSet<CallOpClientRecvStatus> finish_ops_;
+ CallbackWithSuccessTag finish_tag_;
+ Status finish_status_;
+
+ CallOpSet<CallOpRecvMessage<Response>> read_ops_;
+ CallbackWithSuccessTag read_tag_;
+ bool read_ops_at_start_{false};
+
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
+ bool started_{false};
+};
+
+template <class Response>
+class ClientCallbackReaderFactory {
+ public:
+ template <class Request>
+ static void Create(
+ ChannelInterface* channel, const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, const Request* request,
+ ::grpc::experimental::ClientReadReactor<Response>* reactor) {
+ Call call = channel->CreateCall(method, context, channel->CallbackCQ());
+
+ g_core_codegen_interface->grpc_call_ref(call.call());
+ new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientCallbackReaderImpl<Response>)))
+ ClientCallbackReaderImpl<Response>(call, context, request, reactor);
+ }
+};
+
+template <class Request>
+class ClientCallbackWriterImpl
+ : public ::grpc::experimental::ClientCallbackWriter<Request> {
+ public:
+ // always allocated against a call arena, no memory free required
+ static void operator delete(void* ptr, std::size_t size) {
+ assert(size == sizeof(ClientCallbackWriterImpl));
+ }
+
+ // 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 MaybeFinish() {
+ if (--callbacks_outstanding_ == 0) {
+ Status s = std::move(finish_status_);
+ auto* reactor = reactor_;
+ auto* call = call_.call();
+ this->~ClientCallbackWriterImpl();
+ g_core_codegen_interface->grpc_call_unref(call);
+ reactor->OnDone(s);
+ }
+ }
+
+ void StartCall() override {
+ // This call initiates two batches, plus any backlog, each with a callback
+ // 1. Send initial metadata (unless corked) + recv initial metadata
+ // 2. Recv trailing metadata, on_completion callback
+ // 3. Any backlog
+ // 4. See if the call can finish (if other callbacks were triggered already)
+ started_ = true;
+
+ start_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadInitialMetadataDone(ok);
+ MaybeFinish();
+ },
+ &start_ops_);
+ if (!start_corked_) {
+ start_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ }
+ start_ops_.RecvInitialMetadata(context_);
+ start_ops_.set_core_cq_tag(&start_tag_);
+ call_.PerformOps(&start_ops_);
+
+ // Also set up the read and write tags so that they don't have to be set up
+ // each time
+ write_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnWriteDone(ok);
+ MaybeFinish();
+ },
+ &write_ops_);
+ write_ops_.set_core_cq_tag(&write_tag_);
+
+ finish_tag_.Set(call_.call(), [this](bool ok) { MaybeFinish(); },
+ &finish_ops_);
+ finish_ops_.ClientRecvStatus(context_, &finish_status_);
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+ call_.PerformOps(&finish_ops_);
+
+ if (write_ops_at_start_) {
+ call_.PerformOps(&write_ops_);
+ }
+
+ if (writes_done_ops_at_start_) {
+ call_.PerformOps(&writes_done_ops_);
+ }
+
+ MaybeFinish();
+ }
+
+ void Write(const Request* msg, WriteOptions options) override {
+ if (start_corked_) {
+ write_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ start_corked_ = false;
+ }
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*msg).ok());
+
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ write_ops_.ClientSendClose();
+ }
+ callbacks_outstanding_++;
+ if (started_) {
+ call_.PerformOps(&write_ops_);
+ } else {
+ write_ops_at_start_ = true;
+ }
+ }
+ void WritesDone() override {
+ if (start_corked_) {
+ writes_done_ops_.SendInitialMetadata(&context_->send_initial_metadata_,
+ context_->initial_metadata_flags());
+ start_corked_ = false;
+ }
+ writes_done_ops_.ClientSendClose();
+ writes_done_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnWritesDoneDone(ok);
+ MaybeFinish();
+ },
+ &writes_done_ops_);
+ writes_done_ops_.set_core_cq_tag(&writes_done_tag_);
+ callbacks_outstanding_++;
+ if (started_) {
+ call_.PerformOps(&writes_done_ops_);
+ } else {
+ writes_done_ops_at_start_ = true;
+ }
+ }
+
+ private:
+ friend class ClientCallbackWriterFactory<Request>;
+
+ template <class Response>
+ ClientCallbackWriterImpl(
+ Call call, ClientContext* context, Response* response,
+ ::grpc::experimental::ClientWriteReactor<Request>* reactor)
+ : context_(context),
+ call_(call),
+ reactor_(reactor),
+ start_corked_(context_->initial_metadata_corked_) {
+ this->BindReactor(reactor);
+ finish_ops_.RecvMessage(response);
+ finish_ops_.AllowNoMessage();
+ }
+
+ ClientContext* context_;
+ Call call_;
+ ::grpc::experimental::ClientWriteReactor<Request>* reactor_;
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpRecvInitialMetadata> start_ops_;
+ CallbackWithSuccessTag start_tag_;
+ bool start_corked_;
+
+ CallOpSet<CallOpGenericRecvMessage, CallOpClientRecvStatus> finish_ops_;
+ CallbackWithSuccessTag finish_tag_;
+ Status finish_status_;
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+ write_ops_;
+ CallbackWithSuccessTag write_tag_;
+ bool write_ops_at_start_{false};
+
+ CallOpSet<CallOpSendInitialMetadata, CallOpClientSendClose> writes_done_ops_;
+ CallbackWithSuccessTag writes_done_tag_;
+ bool writes_done_ops_at_start_{false};
+
+ // Minimum of 3 callbacks to pre-register for StartCall, start, and finish
+ std::atomic_int callbacks_outstanding_{3};
+ bool started_{false};
+};
+
+template <class Request>
+class ClientCallbackWriterFactory {
+ public:
+ template <class Response>
+ static void Create(
+ ChannelInterface* channel, const ::grpc::internal::RpcMethod& method,
+ ClientContext* context, Response* response,
+ ::grpc::experimental::ClientWriteReactor<Request>* reactor) {
+ Call call = channel->CreateCall(method, context, channel->CallbackCQ());
+
+ g_core_codegen_interface->grpc_call_ref(call.call());
+ new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call.call(), sizeof(ClientCallbackWriterImpl<Request>)))
+ ClientCallbackWriterImpl<Request>(call, context, response, reactor);
+ }
+};
} // namespace internal
} // namespace grpc
diff --git a/include/grpcpp/impl/codegen/client_context.h b/include/grpcpp/impl/codegen/client_context.h
index 75b955e760..0a71f3d9b6 100644
--- a/include/grpcpp/impl/codegen/client_context.h
+++ b/include/grpcpp/impl/codegen/client_context.h
@@ -46,6 +46,7 @@
#include <grpcpp/impl/codegen/core_codegen_interface.h>
#include <grpcpp/impl/codegen/create_auth_context.h>
#include <grpcpp/impl/codegen/metadata_map.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/security/auth_context.h>
#include <grpcpp/impl/codegen/slice.h>
#include <grpcpp/impl/codegen/status.h>
@@ -71,6 +72,12 @@ template <class InputMessage, class OutputMessage>
class BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>
class CallbackUnaryCallImpl;
+template <class Request, class Response>
+class ClientCallbackReaderWriterImpl;
+template <class Response>
+class ClientCallbackReaderImpl;
+template <class Request>
+class ClientCallbackWriterImpl;
} // namespace internal
template <class R>
@@ -162,6 +169,8 @@ class InteropClientContextInspector;
/// (see \a grpc::CreateCustomChannel).
///
/// \warning ClientContext instances should \em not be reused across rpcs.
+/// \warning The ClientContext instance used for creating an rpc must remain
+/// alive and valid for the lifetime of the rpc.
class ClientContext {
public:
ClientContext();
@@ -394,6 +403,12 @@ class ClientContext {
friend class ::grpc::internal::BlockingUnaryCallImpl;
template <class InputMessage, class OutputMessage>
friend class ::grpc::internal::CallbackUnaryCallImpl;
+ template <class Request, class Response>
+ friend class ::grpc::internal::ClientCallbackReaderWriterImpl;
+ template <class Response>
+ friend class ::grpc::internal::ClientCallbackReaderImpl;
+ template <class Request>
+ friend class ::grpc::internal::ClientCallbackWriterImpl;
// Used by friend class CallOpClientRecvStatus
void set_debug_error_string(const grpc::string& debug_error_string) {
@@ -404,12 +419,13 @@ class ClientContext {
void set_call(grpc_call* call, const std::shared_ptr<Channel>& channel);
experimental::ClientRpcInfo* set_client_rpc_info(
- const char* method, grpc::ChannelInterface* channel,
+ const char* method, internal::RpcMethod::RpcType type,
+ grpc::ChannelInterface* channel,
const std::vector<
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>&
creators,
size_t interceptor_pos) {
- rpc_info_ = experimental::ClientRpcInfo(this, method, channel);
+ rpc_info_ = experimental::ClientRpcInfo(this, type, method, channel);
rpc_info_.RegisterInterceptors(creators, interceptor_pos);
return &rpc_info_;
}
diff --git a/include/grpcpp/impl/codegen/client_interceptor.h b/include/grpcpp/impl/codegen/client_interceptor.h
index f69c99ab22..2bae11a251 100644
--- a/include/grpcpp/impl/codegen/client_interceptor.h
+++ b/include/grpcpp/impl/codegen/client_interceptor.h
@@ -23,6 +23,7 @@
#include <vector>
#include <grpcpp/impl/codegen/interceptor.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/string_ref.h>
namespace grpc {
@@ -52,23 +53,56 @@ extern experimental::ClientInterceptorFactoryInterface*
namespace experimental {
class ClientRpcInfo {
public:
- ClientRpcInfo() {}
+ // TODO(yashykt): Stop default-constructing ClientRpcInfo and remove UNKNOWN
+ // from the list of possible Types.
+ enum class Type {
+ UNARY,
+ CLIENT_STREAMING,
+ SERVER_STREAMING,
+ BIDI_STREAMING,
+ UNKNOWN // UNKNOWN is not API and will be removed later
+ };
~ClientRpcInfo(){};
ClientRpcInfo(const ClientRpcInfo&) = delete;
ClientRpcInfo(ClientRpcInfo&&) = default;
- ClientRpcInfo& operator=(ClientRpcInfo&&) = default;
// Getter methods
- const char* method() { return method_; }
+ const char* method() const { return method_; }
ChannelInterface* channel() { return channel_; }
grpc::ClientContext* client_context() { return ctx_; }
+ Type type() const { return type_; }
private:
- ClientRpcInfo(grpc::ClientContext* ctx, const char* method,
- grpc::ChannelInterface* channel)
- : ctx_(ctx), method_(method), channel_(channel) {}
+ static_assert(Type::UNARY ==
+ static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
+ "violated expectation about Type enum");
+ static_assert(Type::CLIENT_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::SERVER_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::BIDI_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
+ "violated expectation about Type enum");
+
+ // Default constructor should only be used by ClientContext
+ ClientRpcInfo() = default;
+
+ // Constructor will only be called from ClientContext
+ ClientRpcInfo(grpc::ClientContext* ctx, internal::RpcMethod::RpcType type,
+ const char* method, grpc::ChannelInterface* channel)
+ : ctx_(ctx),
+ type_(static_cast<Type>(type)),
+ method_(method),
+ channel_(channel) {}
+
+ // Move assignment should only be used by ClientContext
+ // TODO(yashykt): Delete move assignment
+ ClientRpcInfo& operator=(ClientRpcInfo&&) = default;
+
// Runs interceptor at pos \a pos.
void RunInterceptor(
experimental::InterceptorBatchMethods* interceptor_methods, size_t pos) {
@@ -97,6 +131,8 @@ class ClientRpcInfo {
}
grpc::ClientContext* ctx_ = nullptr;
+ // TODO(yashykt): make type_ const once move-assignment is deleted
+ Type type_{Type::UNKNOWN};
const char* method_ = nullptr;
grpc::ChannelInterface* channel_ = nullptr;
std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h
index b1c80764f2..5151839412 100644
--- a/include/grpcpp/impl/codegen/client_unary_call.h
+++ b/include/grpcpp/impl/codegen/client_unary_call.h
@@ -69,13 +69,17 @@ class BlockingUnaryCallImpl {
ops.ClientSendClose();
ops.ClientRecvStatus(context, &status_);
call.PerformOps(&ops);
- if (cq.Pluck(&ops)) {
- if (!ops.got_message && status_.ok()) {
- status_ = Status(StatusCode::UNIMPLEMENTED,
- "No message returned for unary request");
- }
- } else {
- GPR_CODEGEN_ASSERT(!status_.ok());
+ cq.Pluck(&ops);
+ // Some of the ops might fail. If the ops fail in the core layer, status
+ // would reflect the error. But, if the ops fail in the C++ layer, the
+ // status would still be the same as the one returned by gRPC Core. This can
+ // happen if deserialization of the message fails.
+ // TODO(yashykt): If deserialization fails, but the status received is OK,
+ // then it might be a good idea to change the status to something better
+ // than StatusCode::UNIMPLEMENTED to reflect this.
+ if (!ops.got_message && status_.ok()) {
+ status_ = Status(StatusCode::UNIMPLEMENTED,
+ "No message returned for unary request");
}
}
Status status() { return status_; }
diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h
index d603c7c700..fb38788f7d 100644
--- a/include/grpcpp/impl/codegen/completion_queue.h
+++ b/include/grpcpp/impl/codegen/completion_queue.h
@@ -307,8 +307,7 @@ class CompletionQueue : private GrpcLibraryCodegen {
void* ignored = tag;
if (tag->FinalizeResult(&ignored, &ok)) {
GPR_CODEGEN_ASSERT(ignored == tag);
- // Ignore mutations by FinalizeResult: Pluck returns the C API status
- return ev.success != 0;
+ return ok;
}
}
}
diff --git a/include/grpcpp/impl/codegen/server_callback.h b/include/grpcpp/impl/codegen/server_callback.h
index b866fc16dc..1854f6ef2f 100644
--- a/include/grpcpp/impl/codegen/server_callback.h
+++ b/include/grpcpp/impl/codegen/server_callback.h
@@ -19,7 +19,9 @@
#ifndef GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H
#define GRPCPP_IMPL_CODEGEN_SERVER_CALLBACK_H
+#include <atomic>
#include <functional>
+#include <type_traits>
#include <grpcpp/impl/codegen/call.h>
#include <grpcpp/impl/codegen/call_op_set.h>
@@ -32,19 +34,33 @@
namespace grpc {
-// forward declarations
+// Declare base class of all reactors as internal
namespace internal {
-template <class ServiceType, class RequestType, class ResponseType>
-class CallbackUnaryHandler;
+
+class ServerReactor {
+ public:
+ virtual ~ServerReactor() = default;
+ virtual void OnDone() {}
+ virtual void OnCancel() {}
+};
+
} // namespace internal
namespace experimental {
+// Forward declarations
+template <class Request, class Response>
+class ServerReadReactor;
+template <class Request, class Response>
+class ServerWriteReactor;
+template <class Request, class Response>
+class ServerBidiReactor;
+
// For unary RPCs, the exposed controller class is only an interface
// and the actual implementation is an internal class.
class ServerCallbackRpcController {
public:
- virtual ~ServerCallbackRpcController() {}
+ virtual ~ServerCallbackRpcController() = default;
// The method handler must call this function when it is done so that
// the library knows to free its resources
@@ -55,18 +71,193 @@ class ServerCallbackRpcController {
virtual void SendInitialMetadata(std::function<void(bool)>) = 0;
};
+// NOTE: The actual streaming object classes are provided
+// as API only to support mocking. There are no implementations of
+// these class interfaces in the API.
+template <class Request>
+class ServerCallbackReader {
+ public:
+ virtual ~ServerCallbackReader() {}
+ virtual void Finish(Status s) = 0;
+ virtual void SendInitialMetadata() = 0;
+ virtual void Read(Request* msg) = 0;
+
+ protected:
+ template <class Response>
+ void BindReactor(ServerReadReactor<Request, Response>* reactor) {
+ reactor->BindReader(this);
+ }
+};
+
+template <class Response>
+class ServerCallbackWriter {
+ public:
+ virtual ~ServerCallbackWriter() {}
+
+ virtual void Finish(Status s) = 0;
+ virtual void SendInitialMetadata() = 0;
+ virtual void Write(const Response* msg, WriteOptions options) = 0;
+ virtual void WriteAndFinish(const Response* msg, WriteOptions options,
+ Status s) {
+ // Default implementation that can/should be overridden
+ Write(msg, std::move(options));
+ Finish(std::move(s));
+ };
+
+ protected:
+ template <class Request>
+ void BindReactor(ServerWriteReactor<Request, Response>* reactor) {
+ reactor->BindWriter(this);
+ }
+};
+
+template <class Request, class Response>
+class ServerCallbackReaderWriter {
+ public:
+ virtual ~ServerCallbackReaderWriter() {}
+
+ virtual void Finish(Status s) = 0;
+ virtual void SendInitialMetadata() = 0;
+ virtual void Read(Request* msg) = 0;
+ virtual void Write(const Response* msg, WriteOptions options) = 0;
+ virtual void WriteAndFinish(const Response* msg, WriteOptions options,
+ Status s) {
+ // Default implementation that can/should be overridden
+ Write(msg, std::move(options));
+ Finish(std::move(s));
+ };
+
+ protected:
+ void BindReactor(ServerBidiReactor<Request, Response>* reactor) {
+ reactor->BindStream(this);
+ }
+};
+
+// The following classes are reactors that are to be implemented
+// by the user, returned as the result of the method handler for
+// a callback method, and activated by the call to OnStarted
+template <class Request, class Response>
+class ServerBidiReactor : public internal::ServerReactor {
+ public:
+ ~ServerBidiReactor() = default;
+ virtual void OnStarted(ServerContext*) {}
+ virtual void OnSendInitialMetadataDone(bool ok) {}
+ virtual void OnReadDone(bool ok) {}
+ virtual void OnWriteDone(bool ok) {}
+
+ void StartSendInitialMetadata() { stream_->SendInitialMetadata(); }
+ void StartRead(Request* msg) { stream_->Read(msg); }
+ void StartWrite(const Response* msg) { StartWrite(msg, WriteOptions()); }
+ void StartWrite(const Response* msg, WriteOptions options) {
+ stream_->Write(msg, std::move(options));
+ }
+ void StartWriteAndFinish(const Response* msg, WriteOptions options,
+ Status s) {
+ stream_->WriteAndFinish(msg, std::move(options), std::move(s));
+ }
+ void StartWriteLast(const Response* msg, WriteOptions options) {
+ StartWrite(msg, std::move(options.set_last_message()));
+ }
+ void Finish(Status s) { stream_->Finish(std::move(s)); }
+
+ private:
+ friend class ServerCallbackReaderWriter<Request, Response>;
+ void BindStream(ServerCallbackReaderWriter<Request, Response>* stream) {
+ stream_ = stream;
+ }
+
+ ServerCallbackReaderWriter<Request, Response>* stream_;
+};
+
+template <class Request, class Response>
+class ServerReadReactor : public internal::ServerReactor {
+ public:
+ ~ServerReadReactor() = default;
+ virtual void OnStarted(ServerContext*, Response* resp) {}
+ virtual void OnSendInitialMetadataDone(bool ok) {}
+ virtual void OnReadDone(bool ok) {}
+
+ void StartSendInitialMetadata() { reader_->SendInitialMetadata(); }
+ void StartRead(Request* msg) { reader_->Read(msg); }
+ void Finish(Status s) { reader_->Finish(std::move(s)); }
+
+ private:
+ friend class ServerCallbackReader<Request>;
+ void BindReader(ServerCallbackReader<Request>* reader) { reader_ = reader; }
+
+ ServerCallbackReader<Request>* reader_;
+};
+
+template <class Request, class Response>
+class ServerWriteReactor : public internal::ServerReactor {
+ public:
+ ~ServerWriteReactor() = default;
+ virtual void OnStarted(ServerContext*, const Request* req) {}
+ virtual void OnSendInitialMetadataDone(bool ok) {}
+ virtual void OnWriteDone(bool ok) {}
+
+ void StartSendInitialMetadata() { writer_->SendInitialMetadata(); }
+ void StartWrite(const Response* msg) { StartWrite(msg, WriteOptions()); }
+ void StartWrite(const Response* msg, WriteOptions options) {
+ writer_->Write(msg, std::move(options));
+ }
+ void StartWriteAndFinish(const Response* msg, WriteOptions options,
+ Status s) {
+ writer_->WriteAndFinish(msg, std::move(options), std::move(s));
+ }
+ void StartWriteLast(const Response* msg, WriteOptions options) {
+ StartWrite(msg, std::move(options.set_last_message()));
+ }
+ void Finish(Status s) { writer_->Finish(std::move(s)); }
+
+ private:
+ friend class ServerCallbackWriter<Response>;
+ void BindWriter(ServerCallbackWriter<Response>* writer) { writer_ = writer; }
+
+ ServerCallbackWriter<Response>* writer_;
+};
+
} // namespace experimental
namespace internal {
-template <class ServiceType, class RequestType, class ResponseType>
+template <class Request, class Response>
+class UnimplementedReadReactor
+ : public experimental::ServerReadReactor<Request, Response> {
+ public:
+ void OnDone() override { delete this; }
+ void OnStarted(ServerContext*, Response*) override {
+ this->Finish(Status(StatusCode::UNIMPLEMENTED, ""));
+ }
+};
+
+template <class Request, class Response>
+class UnimplementedWriteReactor
+ : public experimental::ServerWriteReactor<Request, Response> {
+ public:
+ void OnDone() override { delete this; }
+ void OnStarted(ServerContext*, const Request*) override {
+ this->Finish(Status(StatusCode::UNIMPLEMENTED, ""));
+ }
+};
+
+template <class Request, class Response>
+class UnimplementedBidiReactor
+ : public experimental::ServerBidiReactor<Request, Response> {
+ public:
+ void OnDone() override { delete this; }
+ void OnStarted(ServerContext*) override {
+ this->Finish(Status(StatusCode::UNIMPLEMENTED, ""));
+ }
+};
+
+template <class RequestType, class ResponseType>
class CallbackUnaryHandler : public MethodHandler {
public:
CallbackUnaryHandler(
std::function<void(ServerContext*, const RequestType*, ResponseType*,
experimental::ServerCallbackRpcController*)>
- func,
- ServiceType* service)
+ func)
: func_(func) {}
void RunHandler(const HandlerParameter& param) final {
// Arena allocate a controller structure (that includes request/response)
@@ -81,9 +272,8 @@ class CallbackUnaryHandler : public MethodHandler {
if (status.ok()) {
// Call the actual function handler and expect the user to call finish
- CatchingCallback(std::move(func_), param.server_context,
- controller->request(), controller->response(),
- controller);
+ CatchingCallback(func_, param.server_context, controller->request(),
+ controller->response(), controller);
} else {
// if deserialization failed, we need to fail the call
controller->Finish(status);
@@ -117,79 +307,579 @@ class CallbackUnaryHandler : public MethodHandler {
: public experimental::ServerCallbackRpcController {
public:
void Finish(Status s) override {
- finish_tag_.Set(
- call_.call(),
- [this](bool) {
- grpc_call* call = call_.call();
- auto call_requester = std::move(call_requester_);
- this->~ServerCallbackRpcControllerImpl(); // explicitly call
- // destructor
- g_core_codegen_interface->grpc_call_unref(call);
- call_requester();
- },
- &finish_buf_);
+ finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); },
+ &finish_ops_);
if (!ctx_->sent_initial_metadata_) {
- finish_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
+ finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
- finish_buf_.set_compression_level(ctx_->compression_level());
+ finish_ops_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
}
// The response is dropped if the status is not OK.
if (s.ok()) {
- finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_,
- finish_buf_.SendMessage(resp_));
+ finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_,
+ finish_ops_.SendMessage(resp_));
} else {
- finish_buf_.ServerSendStatus(&ctx_->trailing_metadata_, s);
+ finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
}
- finish_buf_.set_core_cq_tag(&finish_tag_);
- call_.PerformOps(&finish_buf_);
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+ call_.PerformOps(&finish_ops_);
}
void SendInitialMetadata(std::function<void(bool)> f) override {
GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
-
- meta_tag_.Set(call_.call(), std::move(f), &meta_buf_);
- meta_buf_.SendInitialMetadata(&ctx_->initial_metadata_,
+ callbacks_outstanding_++;
+ // TODO(vjpai): Consider taking f as a move-capture if we adopt C++14
+ // and if performance of this operation matters
+ meta_tag_.Set(call_.call(),
+ [this, f](bool ok) {
+ f(ok);
+ MaybeDone();
+ },
+ &meta_ops_);
+ meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
ctx_->initial_metadata_flags());
if (ctx_->compression_level_set()) {
- meta_buf_.set_compression_level(ctx_->compression_level());
+ meta_ops_.set_compression_level(ctx_->compression_level());
}
ctx_->sent_initial_metadata_ = true;
- meta_buf_.set_core_cq_tag(&meta_tag_);
- call_.PerformOps(&meta_buf_);
+ meta_ops_.set_core_cq_tag(&meta_tag_);
+ call_.PerformOps(&meta_ops_);
}
private:
- template <class SrvType, class ReqType, class RespType>
- friend class CallbackUnaryHandler;
+ friend class CallbackUnaryHandler<RequestType, ResponseType>;
ServerCallbackRpcControllerImpl(ServerContext* ctx, Call* call,
- RequestType* req,
+ const RequestType* req,
std::function<void()> call_requester)
: ctx_(ctx),
call_(*call),
req_(req),
- call_requester_(std::move(call_requester)) {}
+ call_requester_(std::move(call_requester)) {
+ ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, nullptr);
+ }
~ServerCallbackRpcControllerImpl() { req_->~RequestType(); }
- RequestType* request() { return req_; }
+ const RequestType* request() { return req_; }
ResponseType* response() { return &resp_; }
- CallOpSet<CallOpSendInitialMetadata> meta_buf_;
+ void MaybeDone() {
+ if (--callbacks_outstanding_ == 0) {
+ grpc_call* call = call_.call();
+ auto call_requester = std::move(call_requester_);
+ this->~ServerCallbackRpcControllerImpl(); // explicitly call destructor
+ g_core_codegen_interface->grpc_call_unref(call);
+ call_requester();
+ }
+ }
+
+ CallOpSet<CallOpSendInitialMetadata> meta_ops_;
CallbackWithSuccessTag meta_tag_;
CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
CallOpServerSendStatus>
- finish_buf_;
+ finish_ops_;
CallbackWithSuccessTag finish_tag_;
ServerContext* ctx_;
Call call_;
- RequestType* req_;
+ const RequestType* req_;
ResponseType resp_;
std::function<void()> call_requester_;
+ std::atomic_int callbacks_outstanding_{
+ 2}; // reserve for Finish and CompletionOp
+ };
+};
+
+template <class RequestType, class ResponseType>
+class CallbackClientStreamingHandler : public MethodHandler {
+ public:
+ CallbackClientStreamingHandler(
+ std::function<
+ experimental::ServerReadReactor<RequestType, ResponseType>*()>
+ func)
+ : func_(std::move(func)) {}
+ void RunHandler(const HandlerParameter& param) final {
+ // Arena allocate a reader structure (that includes response)
+ g_core_codegen_interface->grpc_call_ref(param.call->call());
+
+ experimental::ServerReadReactor<RequestType, ResponseType>* reactor =
+ param.status.ok()
+ ? CatchingReactorCreator<
+ experimental::ServerReadReactor<RequestType, ResponseType>>(
+ func_)
+ : nullptr;
+
+ if (reactor == nullptr) {
+ // if deserialization or reactor creator failed, we need to fail the call
+ reactor = new UnimplementedReadReactor<RequestType, ResponseType>;
+ }
+
+ auto* reader = new (g_core_codegen_interface->grpc_call_arena_alloc(
+ param.call->call(), sizeof(ServerCallbackReaderImpl)))
+ ServerCallbackReaderImpl(param.server_context, param.call,
+ std::move(param.call_requester), reactor);
+
+ reader->BindReactor(reactor);
+ reactor->OnStarted(param.server_context, reader->response());
+ reader->MaybeDone();
+ }
+
+ private:
+ std::function<experimental::ServerReadReactor<RequestType, ResponseType>*()>
+ func_;
+
+ class ServerCallbackReaderImpl
+ : public experimental::ServerCallbackReader<RequestType> {
+ public:
+ void Finish(Status s) override {
+ finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); },
+ &finish_ops_);
+ if (!ctx_->sent_initial_metadata_) {
+ finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ // The response is dropped if the status is not OK.
+ if (s.ok()) {
+ finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_,
+ finish_ops_.SendMessage(resp_));
+ } else {
+ finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
+ }
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ void SendInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+ callbacks_outstanding_++;
+ meta_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnSendInitialMetadataDone(ok);
+ MaybeDone();
+ },
+ &meta_ops_);
+ meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ meta_ops_.set_core_cq_tag(&meta_tag_);
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Read(RequestType* req) override {
+ callbacks_outstanding_++;
+ read_ops_.RecvMessage(req);
+ call_.PerformOps(&read_ops_);
+ }
+
+ private:
+ friend class CallbackClientStreamingHandler<RequestType, ResponseType>;
+
+ ServerCallbackReaderImpl(
+ ServerContext* ctx, Call* call, std::function<void()> call_requester,
+ experimental::ServerReadReactor<RequestType, ResponseType>* reactor)
+ : ctx_(ctx),
+ call_(*call),
+ call_requester_(std::move(call_requester)),
+ reactor_(reactor) {
+ ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor);
+ read_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadDone(ok);
+ MaybeDone();
+ },
+ &read_ops_);
+ read_ops_.set_core_cq_tag(&read_tag_);
+ }
+
+ ~ServerCallbackReaderImpl() {}
+
+ ResponseType* response() { return &resp_; }
+
+ void MaybeDone() {
+ if (--callbacks_outstanding_ == 0) {
+ reactor_->OnDone();
+ grpc_call* call = call_.call();
+ auto call_requester = std::move(call_requester_);
+ this->~ServerCallbackReaderImpl(); // explicitly call destructor
+ g_core_codegen_interface->grpc_call_unref(call);
+ call_requester();
+ }
+ }
+
+ CallOpSet<CallOpSendInitialMetadata> meta_ops_;
+ CallbackWithSuccessTag meta_tag_;
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus>
+ finish_ops_;
+ CallbackWithSuccessTag finish_tag_;
+ CallOpSet<CallOpRecvMessage<RequestType>> read_ops_;
+ CallbackWithSuccessTag read_tag_;
+
+ ServerContext* ctx_;
+ Call call_;
+ ResponseType resp_;
+ std::function<void()> call_requester_;
+ experimental::ServerReadReactor<RequestType, ResponseType>* reactor_;
+ std::atomic_int callbacks_outstanding_{
+ 3}; // reserve for OnStarted, Finish, and CompletionOp
+ };
+};
+
+template <class RequestType, class ResponseType>
+class CallbackServerStreamingHandler : public MethodHandler {
+ public:
+ CallbackServerStreamingHandler(
+ std::function<
+ experimental::ServerWriteReactor<RequestType, ResponseType>*()>
+ func)
+ : func_(std::move(func)) {}
+ void RunHandler(const HandlerParameter& param) final {
+ // Arena allocate a writer structure
+ g_core_codegen_interface->grpc_call_ref(param.call->call());
+
+ experimental::ServerWriteReactor<RequestType, ResponseType>* reactor =
+ param.status.ok()
+ ? CatchingReactorCreator<
+ experimental::ServerWriteReactor<RequestType, ResponseType>>(
+ func_)
+ : nullptr;
+
+ if (reactor == nullptr) {
+ // if deserialization or reactor creator failed, we need to fail the call
+ reactor = new UnimplementedWriteReactor<RequestType, ResponseType>;
+ }
+
+ auto* writer = new (g_core_codegen_interface->grpc_call_arena_alloc(
+ param.call->call(), sizeof(ServerCallbackWriterImpl)))
+ ServerCallbackWriterImpl(param.server_context, param.call,
+ static_cast<RequestType*>(param.request),
+ std::move(param.call_requester), reactor);
+ writer->BindReactor(reactor);
+ reactor->OnStarted(param.server_context, writer->request());
+ writer->MaybeDone();
+ }
+
+ void* Deserialize(grpc_call* call, grpc_byte_buffer* req,
+ Status* status) final {
+ ByteBuffer buf;
+ buf.set_buffer(req);
+ auto* request = new (g_core_codegen_interface->grpc_call_arena_alloc(
+ call, sizeof(RequestType))) RequestType();
+ *status = SerializationTraits<RequestType>::Deserialize(&buf, request);
+ buf.Release();
+ if (status->ok()) {
+ return request;
+ }
+ request->~RequestType();
+ return nullptr;
+ }
+
+ private:
+ std::function<experimental::ServerWriteReactor<RequestType, ResponseType>*()>
+ func_;
+
+ class ServerCallbackWriterImpl
+ : public experimental::ServerCallbackWriter<ResponseType> {
+ public:
+ void Finish(Status s) override {
+ finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); },
+ &finish_ops_);
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+
+ if (!ctx_->sent_initial_metadata_) {
+ finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ void SendInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+ callbacks_outstanding_++;
+ meta_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnSendInitialMetadataDone(ok);
+ MaybeDone();
+ },
+ &meta_ops_);
+ meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ meta_ops_.set_core_cq_tag(&meta_tag_);
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Write(const ResponseType* resp, WriteOptions options) override {
+ callbacks_outstanding_++;
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ }
+ if (!ctx_->sent_initial_metadata_) {
+ write_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ write_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void WriteAndFinish(const ResponseType* resp, WriteOptions options,
+ Status s) override {
+ // This combines the write into the finish callback
+ // Don't send any message if the status is bad
+ if (s.ok()) {
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok());
+ }
+ Finish(std::move(s));
+ }
+
+ private:
+ friend class CallbackServerStreamingHandler<RequestType, ResponseType>;
+
+ ServerCallbackWriterImpl(
+ ServerContext* ctx, Call* call, const RequestType* req,
+ std::function<void()> call_requester,
+ experimental::ServerWriteReactor<RequestType, ResponseType>* reactor)
+ : ctx_(ctx),
+ call_(*call),
+ req_(req),
+ call_requester_(std::move(call_requester)),
+ reactor_(reactor) {
+ ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor);
+ write_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnWriteDone(ok);
+ MaybeDone();
+ },
+ &write_ops_);
+ write_ops_.set_core_cq_tag(&write_tag_);
+ }
+ ~ServerCallbackWriterImpl() { req_->~RequestType(); }
+
+ const RequestType* request() { return req_; }
+
+ void MaybeDone() {
+ if (--callbacks_outstanding_ == 0) {
+ reactor_->OnDone();
+ grpc_call* call = call_.call();
+ auto call_requester = std::move(call_requester_);
+ this->~ServerCallbackWriterImpl(); // explicitly call destructor
+ g_core_codegen_interface->grpc_call_unref(call);
+ call_requester();
+ }
+ }
+
+ CallOpSet<CallOpSendInitialMetadata> meta_ops_;
+ CallbackWithSuccessTag meta_tag_;
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus>
+ finish_ops_;
+ CallbackWithSuccessTag finish_tag_;
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
+ CallbackWithSuccessTag write_tag_;
+
+ ServerContext* ctx_;
+ Call call_;
+ const RequestType* req_;
+ std::function<void()> call_requester_;
+ experimental::ServerWriteReactor<RequestType, ResponseType>* reactor_;
+ std::atomic_int callbacks_outstanding_{
+ 3}; // reserve for OnStarted, Finish, and CompletionOp
+ };
+};
+
+template <class RequestType, class ResponseType>
+class CallbackBidiHandler : public MethodHandler {
+ public:
+ CallbackBidiHandler(
+ std::function<
+ experimental::ServerBidiReactor<RequestType, ResponseType>*()>
+ func)
+ : func_(std::move(func)) {}
+ void RunHandler(const HandlerParameter& param) final {
+ g_core_codegen_interface->grpc_call_ref(param.call->call());
+
+ experimental::ServerBidiReactor<RequestType, ResponseType>* reactor =
+ param.status.ok()
+ ? CatchingReactorCreator<
+ experimental::ServerBidiReactor<RequestType, ResponseType>>(
+ func_)
+ : nullptr;
+
+ if (reactor == nullptr) {
+ // if deserialization or reactor creator failed, we need to fail the call
+ reactor = new UnimplementedBidiReactor<RequestType, ResponseType>;
+ }
+
+ auto* stream = new (g_core_codegen_interface->grpc_call_arena_alloc(
+ param.call->call(), sizeof(ServerCallbackReaderWriterImpl)))
+ ServerCallbackReaderWriterImpl(param.server_context, param.call,
+ std::move(param.call_requester),
+ reactor);
+
+ stream->BindReactor(reactor);
+ reactor->OnStarted(param.server_context);
+ stream->MaybeDone();
+ }
+
+ private:
+ std::function<experimental::ServerBidiReactor<RequestType, ResponseType>*()>
+ func_;
+
+ class ServerCallbackReaderWriterImpl
+ : public experimental::ServerCallbackReaderWriter<RequestType,
+ ResponseType> {
+ public:
+ void Finish(Status s) override {
+ finish_tag_.Set(call_.call(), [this](bool) { MaybeDone(); },
+ &finish_ops_);
+ finish_ops_.set_core_cq_tag(&finish_tag_);
+
+ if (!ctx_->sent_initial_metadata_) {
+ finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ finish_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
+ call_.PerformOps(&finish_ops_);
+ }
+
+ void SendInitialMetadata() override {
+ GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+ callbacks_outstanding_++;
+ meta_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnSendInitialMetadataDone(ok);
+ MaybeDone();
+ },
+ &meta_ops_);
+ meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ meta_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ meta_ops_.set_core_cq_tag(&meta_tag_);
+ call_.PerformOps(&meta_ops_);
+ }
+
+ void Write(const ResponseType* resp, WriteOptions options) override {
+ callbacks_outstanding_++;
+ if (options.is_last_message()) {
+ options.set_buffer_hint();
+ }
+ if (!ctx_->sent_initial_metadata_) {
+ write_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
+ ctx_->initial_metadata_flags());
+ if (ctx_->compression_level_set()) {
+ write_ops_.set_compression_level(ctx_->compression_level());
+ }
+ ctx_->sent_initial_metadata_ = true;
+ }
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(write_ops_.SendMessage(*resp, options).ok());
+ call_.PerformOps(&write_ops_);
+ }
+
+ void WriteAndFinish(const ResponseType* resp, WriteOptions options,
+ Status s) override {
+ // Don't send any message if the status is bad
+ if (s.ok()) {
+ // TODO(vjpai): don't assert
+ GPR_CODEGEN_ASSERT(finish_ops_.SendMessage(*resp, options).ok());
+ }
+ Finish(std::move(s));
+ }
+
+ void Read(RequestType* req) override {
+ callbacks_outstanding_++;
+ read_ops_.RecvMessage(req);
+ call_.PerformOps(&read_ops_);
+ }
+
+ private:
+ friend class CallbackBidiHandler<RequestType, ResponseType>;
+
+ ServerCallbackReaderWriterImpl(
+ ServerContext* ctx, Call* call, std::function<void()> call_requester,
+ experimental::ServerBidiReactor<RequestType, ResponseType>* reactor)
+ : ctx_(ctx),
+ call_(*call),
+ call_requester_(std::move(call_requester)),
+ reactor_(reactor) {
+ ctx_->BeginCompletionOp(call, [this](bool) { MaybeDone(); }, reactor);
+ write_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnWriteDone(ok);
+ MaybeDone();
+ },
+ &write_ops_);
+ write_ops_.set_core_cq_tag(&write_tag_);
+ read_tag_.Set(call_.call(),
+ [this](bool ok) {
+ reactor_->OnReadDone(ok);
+ MaybeDone();
+ },
+ &read_ops_);
+ read_ops_.set_core_cq_tag(&read_tag_);
+ }
+ ~ServerCallbackReaderWriterImpl() {}
+
+ void MaybeDone() {
+ if (--callbacks_outstanding_ == 0) {
+ reactor_->OnDone();
+ grpc_call* call = call_.call();
+ auto call_requester = std::move(call_requester_);
+ this->~ServerCallbackReaderWriterImpl(); // explicitly call destructor
+ g_core_codegen_interface->grpc_call_unref(call);
+ call_requester();
+ }
+ }
+
+ CallOpSet<CallOpSendInitialMetadata> meta_ops_;
+ CallbackWithSuccessTag meta_tag_;
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+ CallOpServerSendStatus>
+ finish_ops_;
+ CallbackWithSuccessTag finish_tag_;
+ CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
+ CallbackWithSuccessTag write_tag_;
+ CallOpSet<CallOpRecvMessage<RequestType>> read_ops_;
+ CallbackWithSuccessTag read_tag_;
+
+ ServerContext* ctx_;
+ Call call_;
+ std::function<void()> call_requester_;
+ experimental::ServerBidiReactor<RequestType, ResponseType>* reactor_;
+ std::atomic_int callbacks_outstanding_{
+ 3}; // reserve for OnStarted, Finish, and CompletionOp
};
};
diff --git a/include/grpcpp/impl/codegen/server_context.h b/include/grpcpp/impl/codegen/server_context.h
index 82ee862f61..ccb5925e7d 100644
--- a/include/grpcpp/impl/codegen/server_context.h
+++ b/include/grpcpp/impl/codegen/server_context.h
@@ -66,13 +66,20 @@ template <class ServiceType, class RequestType, class ResponseType>
class ServerStreamingHandler;
template <class ServiceType, class RequestType, class ResponseType>
class BidiStreamingHandler;
-template <class ServiceType, class RequestType, class ResponseType>
+template <class RequestType, class ResponseType>
class CallbackUnaryHandler;
+template <class RequestType, class ResponseType>
+class CallbackClientStreamingHandler;
+template <class RequestType, class ResponseType>
+class CallbackServerStreamingHandler;
+template <class RequestType, class ResponseType>
+class CallbackBidiHandler;
template <class Streamer, bool WriteNeeded>
class TemplatedBidiStreamingHandler;
template <StatusCode code>
class ErrorMethodHandler;
class Call;
+class ServerReactor;
} // namespace internal
class CompletionQueue;
@@ -270,8 +277,14 @@ class ServerContext {
friend class ::grpc::internal::ServerStreamingHandler;
template <class Streamer, bool WriteNeeded>
friend class ::grpc::internal::TemplatedBidiStreamingHandler;
- template <class ServiceType, class RequestType, class ResponseType>
+ template <class RequestType, class ResponseType>
friend class ::grpc::internal::CallbackUnaryHandler;
+ template <class RequestType, class ResponseType>
+ friend class ::grpc::internal::CallbackClientStreamingHandler;
+ template <class RequestType, class ResponseType>
+ friend class ::grpc::internal::CallbackServerStreamingHandler;
+ template <class RequestType, class ResponseType>
+ friend class ::grpc::internal::CallbackBidiHandler;
template <StatusCode code>
friend class internal::ErrorMethodHandler;
friend class ::grpc::ClientContext;
@@ -282,7 +295,9 @@ class ServerContext {
class CompletionOp;
- void BeginCompletionOp(internal::Call* call, bool callback);
+ void BeginCompletionOp(internal::Call* call,
+ std::function<void(bool)> callback,
+ internal::ServerReactor* reactor);
/// Return the tag queued by BeginCompletionOp()
internal::CompletionQueueTag* GetCompletionOpTag();
@@ -299,12 +314,12 @@ class ServerContext {
uint32_t initial_metadata_flags() const { return 0; }
experimental::ServerRpcInfo* set_server_rpc_info(
- const char* method,
+ const char* method, internal::RpcMethod::RpcType type,
const std::vector<
std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>&
creators) {
if (creators.size() != 0) {
- rpc_info_ = new experimental::ServerRpcInfo(this, method);
+ rpc_info_ = new experimental::ServerRpcInfo(this, method, type);
rpc_info_->RegisterInterceptors(creators);
}
return rpc_info_;
diff --git a/include/grpcpp/impl/codegen/server_interceptor.h b/include/grpcpp/impl/codegen/server_interceptor.h
index 5fb5df28b7..afc3c198cc 100644
--- a/include/grpcpp/impl/codegen/server_interceptor.h
+++ b/include/grpcpp/impl/codegen/server_interceptor.h
@@ -23,6 +23,7 @@
#include <vector>
#include <grpcpp/impl/codegen/interceptor.h>
+#include <grpcpp/impl/codegen/rpc_method.h>
#include <grpcpp/impl/codegen/string_ref.h>
namespace grpc {
@@ -44,19 +45,36 @@ class ServerInterceptorFactoryInterface {
class ServerRpcInfo {
public:
+ enum class Type { UNARY, CLIENT_STREAMING, SERVER_STREAMING, BIDI_STREAMING };
+
~ServerRpcInfo(){};
ServerRpcInfo(const ServerRpcInfo&) = delete;
- ServerRpcInfo(ServerRpcInfo&&) = default;
- ServerRpcInfo& operator=(ServerRpcInfo&&) = default;
+ ServerRpcInfo(ServerRpcInfo&&) = delete;
+ ServerRpcInfo& operator=(ServerRpcInfo&&) = delete;
// Getter methods
- const char* method() { return method_; }
+ const char* method() const { return method_; }
+ Type type() const { return type_; }
grpc::ServerContext* server_context() { return ctx_; }
private:
- ServerRpcInfo(grpc::ServerContext* ctx, const char* method)
- : ctx_(ctx), method_(method) {
+ static_assert(Type::UNARY ==
+ static_cast<Type>(internal::RpcMethod::NORMAL_RPC),
+ "violated expectation about Type enum");
+ static_assert(Type::CLIENT_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::CLIENT_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::SERVER_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::SERVER_STREAMING),
+ "violated expectation about Type enum");
+ static_assert(Type::BIDI_STREAMING ==
+ static_cast<Type>(internal::RpcMethod::BIDI_STREAMING),
+ "violated expectation about Type enum");
+
+ ServerRpcInfo(grpc::ServerContext* ctx, const char* method,
+ internal::RpcMethod::RpcType type)
+ : ctx_(ctx), method_(method), type_(static_cast<Type>(type)) {
ref_.store(1);
}
@@ -86,6 +104,7 @@ class ServerRpcInfo {
grpc::ServerContext* ctx_ = nullptr;
const char* method_ = nullptr;
+ const Type type_;
std::atomic_int ref_;
std::vector<std::unique_ptr<experimental::Interceptor>> interceptors_;
diff --git a/include/grpcpp/impl/codegen/server_interface.h b/include/grpcpp/impl/codegen/server_interface.h
index 55c94f4d2f..e0e2629827 100644
--- a/include/grpcpp/impl/codegen/server_interface.h
+++ b/include/grpcpp/impl/codegen/server_interface.h
@@ -174,13 +174,14 @@ class ServerInterface : public internal::CallHook {
bool done_intercepting_;
};
+ /// RegisteredAsyncRequest is not part of the C++ API
class RegisteredAsyncRequest : public BaseAsyncRequest {
public:
RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
- const char* name);
+ const char* name, internal::RpcMethod::RpcType type);
virtual bool FinalizeResult(void** tag, bool* status) override {
/* If we are done intercepting, then there is nothing more for us to do */
@@ -189,7 +190,7 @@ class ServerInterface : public internal::CallHook {
}
call_wrapper_ = internal::Call(
call_, server_, call_cq_, server_->max_receive_message_size(),
- context_->set_server_rpc_info(name_,
+ context_->set_server_rpc_info(name_, type_,
*server_->interceptor_creators()));
return BaseAsyncRequest::FinalizeResult(tag, status);
}
@@ -198,6 +199,7 @@ class ServerInterface : public internal::CallHook {
void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
ServerCompletionQueue* notification_cq);
const char* name_;
+ const internal::RpcMethod::RpcType type_;
};
class NoPayloadAsyncRequest final : public RegisteredAsyncRequest {
@@ -207,9 +209,9 @@ class ServerInterface : public internal::CallHook {
internal::ServerAsyncStreamingInterface* stream,
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag)
- : RegisteredAsyncRequest(server, context, stream, call_cq,
- notification_cq, tag,
- registered_method->name()) {
+ : RegisteredAsyncRequest(
+ server, context, stream, call_cq, notification_cq, tag,
+ registered_method->name(), registered_method->method_type()) {
IssueRequest(registered_method->server_tag(), nullptr, notification_cq);
}
@@ -225,9 +227,9 @@ class ServerInterface : public internal::CallHook {
CompletionQueue* call_cq,
ServerCompletionQueue* notification_cq, void* tag,
Message* request)
- : RegisteredAsyncRequest(server, context, stream, call_cq,
- notification_cq, tag,
- registered_method->name()),
+ : RegisteredAsyncRequest(
+ server, context, stream, call_cq, notification_cq, tag,
+ registered_method->name(), registered_method->method_type()),
registered_method_(registered_method),
server_(server),
context_(context),
diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h
index 8dfbdec3e6..d8c9e04d77 100644
--- a/include/grpcpp/security/credentials.h
+++ b/include/grpcpp/security/credentials.h
@@ -46,8 +46,8 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace experimental
@@ -80,8 +80,8 @@ class ChannelCredentials : private GrpcLibraryCodegen {
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
virtual std::shared_ptr<Channel> CreateChannel(
@@ -91,8 +91,8 @@ class ChannelCredentials : private GrpcLibraryCodegen {
// implemented as a virtual function so that it does not break API.
virtual std::shared_ptr<Channel> CreateChannelWithInterceptors(
const grpc::string& target, const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return nullptr;
};
diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h
index a14a4da578..cdcac186cb 100644
--- a/include/grpcpp/server.h
+++ b/include/grpcpp/server.h
@@ -111,8 +111,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
/// interceptors
std::shared_ptr<Channel> InProcessChannelWithInterceptors(
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
private:
diff --git a/package.xml b/package.xml
index fb41e5f34a..68fc7433cb 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
- <release>1.17.0dev</release>
- <api>1.17.0dev</api>
+ <release>1.18.0dev</release>
+ <api>1.18.0dev</api>
</version>
<stability>
<release>beta</release>
@@ -191,6 +191,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_decoder.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_encoder.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_transport.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/context_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/flow_control.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_data.h" role="src" />
@@ -286,14 +287,15 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
@@ -343,6 +345,7 @@
<file baseinstalldir="/" name="src/core/lib/iomgr/call_combiner.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/closure.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/combiner.h" role="src" />
+ <file baseinstalldir="/" name="src/core/lib/iomgr/dynamic_annotations.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/iomgr/error.h" role="src" />
@@ -621,6 +624,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_encoder.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_transport.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/context_list.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/flow_control.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_data.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_goaway.cc" role="src" />
@@ -727,15 +731,15 @@
<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" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/server_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
diff --git a/requirements.bazel.txt b/requirements.bazel.txt
index 61e529a6ec..e97843794e 100644
--- a/requirements.bazel.txt
+++ b/requirements.bazel.txt
@@ -9,7 +9,8 @@ futures>=2.2.0
google-auth>=1.0.0
oauth2client==4.1.0
requests>=2.14.2
-urllib3==1.22
+urllib3>=1.23
chardet==3.0.4
certifi==2017.4.17
idna==2.7
+googleapis-common-protos==1.5.5
diff --git a/setup.cfg b/setup.cfg
index 218792e674..125ec93491 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -15,3 +15,6 @@ exclude=.*protoc_plugin/protoc_plugin_test\.proto$
# Style settings
[yapf]
based_on_style = google
+
+[metadata]
+license_files = LICENSE
diff --git a/setup.py b/setup.py
index ae86e6c9fb..7bdfc99e24 100644
--- a/setup.py
+++ b/setup.py
@@ -87,6 +87,7 @@ CLASSIFIERS = [
# present, then it will still attempt to use Cython.
BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', False)
+
# Export this variable to use the system installation of openssl. You need to
# have the header files installed (in /usr/include/openssl) and during
# runtime, the shared library must be installed
@@ -105,6 +106,21 @@ BUILD_WITH_SYSTEM_ZLIB = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_ZLIB',
BUILD_WITH_SYSTEM_CARES = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_CARES',
False)
+# For local development use only: This skips building gRPC Core and its
+# dependencies, including protobuf and boringssl. This allows "incremental"
+# compilation by first building gRPC Core using make, then building only the
+# Python/Cython layers here.
+#
+# Note that this requires libboringssl.a in the libs/{dbg,opt}/ directory, which
+# may require configuring make to not use the system openssl implementation:
+#
+# make HAS_SYSTEM_OPENSSL_ALPN=0
+#
+# TODO(ericgribkoff) Respect the BUILD_WITH_SYSTEM_* flags alongside this option
+USE_PREBUILT_GRPC_CORE = os.environ.get(
+ 'GRPC_PYTHON_USE_PREBUILT_GRPC_CORE', False)
+
+
# If this environmental variable is set, GRPC will not try to be compatible with
# libc versions old than the one it was compiled against.
DISABLE_LIBC_COMPATIBILITY = os.environ.get('GRPC_PYTHON_DISABLE_LIBC_COMPATIBILITY', False)
@@ -249,7 +265,7 @@ def cython_extensions_and_necessity():
for name in CYTHON_EXTENSION_MODULE_NAMES]
config = os.environ.get('CONFIG', 'opt')
prefix = 'libs/' + config + '/'
- if "darwin" in sys.platform:
+ if "darwin" in sys.platform or USE_PREBUILT_GRPC_CORE:
extra_objects = [prefix + 'libares.a',
prefix + 'libboringssl.a',
prefix + 'libgpr.a',
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 7986aca696..b004687250 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -132,6 +132,7 @@ grpc::string GetHeaderIncludes(grpc_generator::File* file,
"grpcpp/impl/codegen/async_generic_service.h",
"grpcpp/impl/codegen/async_stream.h",
"grpcpp/impl/codegen/async_unary_call.h",
+ "grpcpp/impl/codegen/client_callback.h",
"grpcpp/impl/codegen/method_handler_impl.h",
"grpcpp/impl/codegen/proto_utils.h",
"grpcpp/impl/codegen/rpc_method.h",
@@ -580,11 +581,22 @@ void PrintHeaderClientMethodCallbackInterfaces(
"const $Request$* request, $Response$* response, "
"std::function<void(::grpc::Status)>) = 0;\n");
} else if (ClientOnlyStreaming(method)) {
- // TODO(vjpai): Add support for client-side streaming
+ printer->Print(*vars,
+ "virtual void $Method$(::grpc::ClientContext* context, "
+ "$Response$* response, "
+ "::grpc::experimental::ClientWriteReactor< $Request$>* "
+ "reactor) = 0;\n");
} else if (ServerOnlyStreaming(method)) {
- // TODO(vjpai): Add support for server-side streaming
+ printer->Print(*vars,
+ "virtual void $Method$(::grpc::ClientContext* context, "
+ "$Request$* request, "
+ "::grpc::experimental::ClientReadReactor< $Response$>* "
+ "reactor) = 0;\n");
} else if (method->BidiStreaming()) {
- // TODO(vjpai): Add support for bidi streaming
+ printer->Print(*vars,
+ "virtual void $Method$(::grpc::ClientContext* context, "
+ "::grpc::experimental::ClientBidiReactor< "
+ "$Request$,$Response$>* reactor) = 0;\n");
}
}
@@ -631,11 +643,23 @@ void PrintHeaderClientMethodCallback(grpc_generator::Printer* printer,
"const $Request$* request, $Response$* response, "
"std::function<void(::grpc::Status)>) override;\n");
} else if (ClientOnlyStreaming(method)) {
- // TODO(vjpai): Add support for client-side streaming
+ printer->Print(*vars,
+ "void $Method$(::grpc::ClientContext* context, "
+ "$Response$* response, "
+ "::grpc::experimental::ClientWriteReactor< $Request$>* "
+ "reactor) override;\n");
} else if (ServerOnlyStreaming(method)) {
- // TODO(vjpai): Add support for server-side streaming
+ printer->Print(*vars,
+ "void $Method$(::grpc::ClientContext* context, "
+ "$Request$* request, "
+ "::grpc::experimental::ClientReadReactor< $Response$>* "
+ "reactor) override;\n");
+
} else if (method->BidiStreaming()) {
- // TODO(vjpai): Add support for bidi streaming
+ printer->Print(*vars,
+ "void $Method$(::grpc::ClientContext* context, "
+ "::grpc::experimental::ClientBidiReactor< "
+ "$Request$,$Response$>* reactor) override;\n");
}
}
@@ -865,6 +889,11 @@ void PrintHeaderServerCallbackMethodsHelper(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
+ printer->Print(*vars,
+ "virtual ::grpc::experimental::ServerReadReactor< "
+ "$RealRequest$, $RealResponse$>* $Method$() {\n"
+ " return new ::grpc::internal::UnimplementedReadReactor<\n"
+ " $RealRequest$, $RealResponse$>;}\n");
} else if (ServerOnlyStreaming(method)) {
printer->Print(
*vars,
@@ -876,6 +905,11 @@ void PrintHeaderServerCallbackMethodsHelper(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
+ printer->Print(*vars,
+ "virtual ::grpc::experimental::ServerWriteReactor< "
+ "$RealRequest$, $RealResponse$>* $Method$() {\n"
+ " return new ::grpc::internal::UnimplementedWriteReactor<\n"
+ " $RealRequest$, $RealResponse$>;}\n");
} else if (method->BidiStreaming()) {
printer->Print(
*vars,
@@ -887,6 +921,11 @@ void PrintHeaderServerCallbackMethodsHelper(
" abort();\n"
" return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
"}\n");
+ printer->Print(*vars,
+ "virtual ::grpc::experimental::ServerBidiReactor< "
+ "$RealRequest$, $RealResponse$>* $Method$() {\n"
+ " return new ::grpc::internal::UnimplementedBidiReactor<\n"
+ " $RealRequest$, $RealResponse$>;}\n");
}
}
@@ -915,22 +954,36 @@ void PrintHeaderServerMethodCallback(
*vars,
" ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
" new ::grpc::internal::CallbackUnaryHandler< "
- "ExperimentalWithCallbackMethod_$Method$<BaseClass>, $RealRequest$, "
- "$RealResponse$>(\n"
+ "$RealRequest$, $RealResponse$>(\n"
" [this](::grpc::ServerContext* context,\n"
" const $RealRequest$* request,\n"
" $RealResponse$* response,\n"
" ::grpc::experimental::ServerCallbackRpcController* "
"controller) {\n"
- " this->$"
+ " return this->$"
"Method$(context, request, response, controller);\n"
- " }, this));\n");
+ " }));\n");
} else if (ClientOnlyStreaming(method)) {
- // TODO(vjpai): Add in code generation for all streaming methods
+ printer->Print(
+ *vars,
+ " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
+ " new ::grpc::internal::CallbackClientStreamingHandler< "
+ "$RealRequest$, $RealResponse$>(\n"
+ " [this] { return this->$Method$(); }));\n");
} else if (ServerOnlyStreaming(method)) {
- // TODO(vjpai): Add in code generation for all streaming methods
+ printer->Print(
+ *vars,
+ " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
+ " new ::grpc::internal::CallbackServerStreamingHandler< "
+ "$RealRequest$, $RealResponse$>(\n"
+ " [this] { return this->$Method$(); }));\n");
} else if (method->BidiStreaming()) {
- // TODO(vjpai): Add in code generation for all streaming methods
+ printer->Print(
+ *vars,
+ " ::grpc::Service::experimental().MarkMethodCallback($Idx$,\n"
+ " new ::grpc::internal::CallbackBidiHandler< "
+ "$RealRequest$, $RealResponse$>(\n"
+ " [this] { return this->$Method$(); }));\n");
}
printer->Print(*vars, "}\n");
printer->Print(*vars,
@@ -967,8 +1020,7 @@ void PrintHeaderServerMethodRawCallback(
*vars,
" ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
" new ::grpc::internal::CallbackUnaryHandler< "
- "ExperimentalWithRawCallbackMethod_$Method$<BaseClass>, $RealRequest$, "
- "$RealResponse$>(\n"
+ "$RealRequest$, $RealResponse$>(\n"
" [this](::grpc::ServerContext* context,\n"
" const $RealRequest$* request,\n"
" $RealResponse$* response,\n"
@@ -976,13 +1028,28 @@ void PrintHeaderServerMethodRawCallback(
"controller) {\n"
" this->$"
"Method$(context, request, response, controller);\n"
- " }, this));\n");
+ " }));\n");
} else if (ClientOnlyStreaming(method)) {
- // TODO(vjpai): Add in code generation for all streaming methods
+ printer->Print(
+ *vars,
+ " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
+ " new ::grpc::internal::CallbackClientStreamingHandler< "
+ "$RealRequest$, $RealResponse$>(\n"
+ " [this] { return this->$Method$(); }));\n");
} else if (ServerOnlyStreaming(method)) {
- // TODO(vjpai): Add in code generation for all streaming methods
+ printer->Print(
+ *vars,
+ " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
+ " new ::grpc::internal::CallbackServerStreamingHandler< "
+ "$RealRequest$, $RealResponse$>(\n"
+ " [this] { return this->$Method$(); }));\n");
} else if (method->BidiStreaming()) {
- // TODO(vjpai): Add in code generation for all streaming methods
+ printer->Print(
+ *vars,
+ " ::grpc::Service::experimental().MarkMethodRawCallback($Idx$,\n"
+ " new ::grpc::internal::CallbackBidiHandler< "
+ "$RealRequest$, $RealResponse$>(\n"
+ " [this] { return this->$Method$(); }));\n");
}
printer->Print(*vars, "}\n");
printer->Print(*vars,
@@ -1607,7 +1674,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"context, response);\n"
"}\n\n");
- // TODO(vjpai): Add callback version
+ printer->Print(
+ *vars,
+ "void $ns$$Service$::"
+ "Stub::experimental_async::$Method$(::grpc::ClientContext* context, "
+ "$Response$* response, "
+ "::grpc::experimental::ClientWriteReactor< $Request$>* reactor) {\n");
+ printer->Print(*vars,
+ " ::grpc::internal::ClientCallbackWriterFactory< "
+ "$Request$>::Create("
+ "stub_->channel_.get(), "
+ "stub_->rpcmethod_$Method$_, "
+ "context, response, reactor);\n"
+ "}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
@@ -1641,7 +1720,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"context, request);\n"
"}\n\n");
- // TODO(vjpai): Add callback version
+ printer->Print(
+ *vars,
+ "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
+ "ClientContext* context, "
+ "$Request$* request, "
+ "::grpc::experimental::ClientReadReactor< $Response$>* reactor) {\n");
+ printer->Print(*vars,
+ " ::grpc::internal::ClientCallbackReaderFactory< "
+ "$Response$>::Create("
+ "stub_->channel_.get(), "
+ "stub_->rpcmethod_$Method$_, "
+ "context, request, reactor);\n"
+ "}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
@@ -1675,7 +1766,19 @@ void PrintSourceClientMethod(grpc_generator::Printer* printer,
"context);\n"
"}\n\n");
- // TODO(vjpai): Add callback version
+ printer->Print(
+ *vars,
+ "void $ns$$Service$::Stub::experimental_async::$Method$(::grpc::"
+ "ClientContext* context, "
+ "::grpc::experimental::ClientBidiReactor< $Request$,$Response$>* "
+ "reactor) {\n");
+ printer->Print(*vars,
+ " ::grpc::internal::ClientCallbackReaderWriterFactory< "
+ "$Request$,$Response$>::Create("
+ "stub_->channel_.get(), "
+ "stub_->rpcmethod_$Method$_, "
+ "context, reactor);\n"
+ "}\n\n");
for (auto async_prefix : async_prefixes) {
(*vars)["AsyncPrefix"] = async_prefix.prefix;
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index a923ce8e38..59ddbd82f6 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -609,6 +609,42 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor* service) {
out->Print("\n");
}
+void GenerateBindServiceWithBinderMethod(Printer* out,
+ const ServiceDescriptor* service) {
+ out->Print(
+ "/// <summary>Register service method implementations with a service "
+ "binder. Useful when customizing the service binding logic.\n"
+ "/// Note: this method is part of an experimental API that can change or "
+ "be "
+ "removed without any prior notice.</summary>\n");
+ out->Print(
+ "/// <param name=\"serviceBinder\">Service methods will be bound by "
+ "calling <c>AddMethod</c> on this object."
+ "</param>\n");
+ out->Print(
+ "/// <param name=\"serviceImpl\">An object implementing the server-side"
+ " handling logic.</param>\n");
+ out->Print(
+ "public static void BindService(grpc::ServiceBinderBase serviceBinder, "
+ "$implclass$ "
+ "serviceImpl)\n",
+ "implclass", GetServerClassName(service));
+ out->Print("{\n");
+ out->Indent();
+
+ for (int i = 0; i < service->method_count(); i++) {
+ const MethodDescriptor* method = service->method(i);
+ out->Print(
+ "serviceBinder.AddMethod($methodfield$, serviceImpl.$methodname$);\n",
+ "methodfield", GetMethodFieldName(method), "methodname",
+ method->name());
+ }
+
+ out->Outdent();
+ out->Print("}\n");
+ out->Print("\n");
+}
+
void GenerateService(Printer* out, const ServiceDescriptor* service,
bool generate_client, bool generate_server,
bool internal_access) {
@@ -637,6 +673,7 @@ void GenerateService(Printer* out, const ServiceDescriptor* service,
}
if (generate_server) {
GenerateBindServiceMethod(out, service);
+ GenerateBindServiceWithBinderMethod(out, service);
}
out->Outdent();
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 8e9ee889e1..70aac47231 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -34,10 +34,11 @@
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
-#include "src/core/ext/filters/client_channel/method_params.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/deadline/deadline_filter.h"
#include "src/core/lib/backoff/backoff.h"
@@ -62,7 +63,10 @@
#include "src/core/lib/transport/static_metadata.h"
#include "src/core/lib/transport/status_metadata.h"
+using grpc_core::ServerAddressList;
using grpc_core::internal::ClientChannelMethodParams;
+using grpc_core::internal::ClientChannelMethodParamsTable;
+using grpc_core::internal::ProcessedResolverResult;
using grpc_core::internal::ServerRetryThrottleData;
/* Client channel implementation */
@@ -83,10 +87,6 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel");
struct external_connectivity_watcher;
-typedef grpc_core::SliceHashTable<
- grpc_core::RefCountedPtr<ClientChannelMethodParams>>
- MethodParamsTable;
-
typedef struct client_channel_channel_data {
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver;
bool started_resolving;
@@ -102,7 +102,7 @@ typedef struct client_channel_channel_data {
/** retry throttle data */
grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
/** maps method names to method_parameters structs */
- grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
+ grpc_core::RefCountedPtr<ClientChannelMethodParamsTable> method_params_table;
/** incoming resolver result - set by resolver.next() */
grpc_channel_args* resolver_result;
/** a list of closures that are all waiting for resolver result to come in */
@@ -251,66 +251,6 @@ static void start_resolving_locked(channel_data* chand) {
&chand->on_resolver_result_changed);
}
-typedef struct {
- char* server_name;
- grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
-} service_config_parsing_state;
-
-static void parse_retry_throttle_params(
- const grpc_json* field, service_config_parsing_state* parsing_state) {
- if (strcmp(field->key, "retryThrottling") == 0) {
- if (parsing_state->retry_throttle_data != nullptr) return; // Duplicate.
- if (field->type != GRPC_JSON_OBJECT) return;
- int max_milli_tokens = 0;
- int milli_token_ratio = 0;
- 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, "maxTokens") == 0) {
- if (max_milli_tokens != 0) return; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return;
- max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
- if (max_milli_tokens == -1) return;
- max_milli_tokens *= 1000;
- } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
- if (milli_token_ratio != 0) return; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return;
- // We support up to 3 decimal digits.
- size_t whole_len = strlen(sub_field->value);
- uint32_t multiplier = 1;
- uint32_t decimal_value = 0;
- const char* decimal_point = strchr(sub_field->value, '.');
- if (decimal_point != nullptr) {
- whole_len = static_cast<size_t>(decimal_point - sub_field->value);
- multiplier = 1000;
- size_t decimal_len = strlen(decimal_point + 1);
- if (decimal_len > 3) decimal_len = 3;
- if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
- &decimal_value)) {
- return;
- }
- uint32_t decimal_multiplier = 1;
- for (size_t i = 0; i < (3 - decimal_len); ++i) {
- decimal_multiplier *= 10;
- }
- decimal_value *= decimal_multiplier;
- }
- uint32_t whole_value;
- if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
- &whole_value)) {
- return;
- }
- milli_token_ratio =
- static_cast<int>((whole_value * multiplier) + decimal_value);
- if (milli_token_ratio <= 0) return;
- }
- }
- parsing_state->retry_throttle_data =
- grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
- parsing_state->server_name, max_milli_tokens, milli_token_ratio);
- }
-}
-
// Invoked from the resolver NextLocked() callback when the resolver
// is shutting down.
static void on_resolver_shutdown_locked(channel_data* chand,
@@ -352,37 +292,6 @@ static void on_resolver_shutdown_locked(channel_data* chand,
GRPC_ERROR_UNREF(error);
}
-// Returns the LB policy name from the resolver result.
-static grpc_core::UniquePtr<char>
-get_lb_policy_name_from_resolver_result_locked(channel_data* chand) {
- // Find LB policy name in channel args.
- const grpc_arg* channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
- const char* lb_policy_name = grpc_channel_arg_get_string(channel_arg);
- // Special case: If at least one balancer address is present, we use
- // the grpclb policy, regardless of what the resolver actually specified.
- 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 (grpc_lb_addresses_contains_balancer_address(*addresses)) {
- if (lb_policy_name != nullptr &&
- gpr_stricmp(lb_policy_name, "grpclb") != 0) {
- gpr_log(GPR_INFO,
- "resolver requested LB policy %s but provided at least one "
- "balancer address -- forcing use of grpclb LB policy",
- lb_policy_name);
- }
- lb_policy_name = "grpclb";
- }
- }
- // Use pick_first if nothing was specified and we didn't select grpclb
- // above.
- if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
- return grpc_core::UniquePtr<char>(gpr_strdup(lb_policy_name));
-}
-
static void request_reresolution_locked(void* arg, grpc_error* error) {
reresolution_request_args* args =
static_cast<reresolution_request_args*>(arg);
@@ -410,13 +319,14 @@ using TraceStringVector = grpc_core::InlinedVector<char*, 3>;
// *connectivity_error to its initial connectivity state; otherwise,
// leaves them unchanged.
static void create_new_lb_policy_locked(
- channel_data* chand, char* lb_policy_name,
+ channel_data* chand, char* lb_policy_name, grpc_json* lb_config,
grpc_connectivity_state* connectivity_state,
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;
lb_policy_args.args = chand->resolver_result;
+ lb_policy_args.lb_config = lb_config;
grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> new_lb_policy =
grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
lb_policy_name, lb_policy_args);
@@ -473,56 +383,12 @@ static void create_new_lb_policy_locked(
}
}
-// Returns the service config (as a JSON string) from the resolver result.
-// Also updates state in chand.
-static grpc_core::UniquePtr<char>
-get_service_config_from_resolver_result_locked(channel_data* chand) {
- const grpc_arg* channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG);
- const char* service_config_json = grpc_channel_arg_get_string(channel_arg);
- if (service_config_json != nullptr) {
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"",
- chand, service_config_json);
- }
- grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
- grpc_core::ServiceConfig::Create(service_config_json);
- if (service_config != nullptr) {
- if (chand->enable_retries) {
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVER_URI);
- const char* server_uri = grpc_channel_arg_get_string(channel_arg);
- GPR_ASSERT(server_uri != nullptr);
- grpc_uri* uri = grpc_uri_parse(server_uri, true);
- GPR_ASSERT(uri->path[0] != '\0');
- service_config_parsing_state parsing_state;
- parsing_state.server_name =
- uri->path[0] == '/' ? uri->path + 1 : uri->path;
- service_config->ParseGlobalParams(parse_retry_throttle_params,
- &parsing_state);
- grpc_uri_destroy(uri);
- chand->retry_throttle_data =
- std::move(parsing_state.retry_throttle_data);
- }
- chand->method_params_table = service_config->CreateMethodConfigTable(
- ClientChannelMethodParams::CreateFromJson);
- }
- }
- 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;
- }
- }
+ const ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(chand->resolver_result);
+ const bool resolution_contains_addresses =
+ addresses != nullptr && addresses->size() > 0;
if (!resolution_contains_addresses &&
chand->previous_resolution_contained_addresses) {
trace_strings->push_back(gpr_strdup("Address list became empty"));
@@ -597,36 +463,47 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO, "chand=%p: resolver transient failure", chand);
}
+ // Don't override connectivity state if we already have an LB policy.
+ if (chand->lb_policy != nullptr) set_connectivity_state = false;
} else {
+ // Parse the resolver result.
+ ProcessedResolverResult resolver_result(chand->resolver_result,
+ chand->enable_retries);
+ chand->retry_throttle_data = resolver_result.retry_throttle_data();
+ chand->method_params_table = resolver_result.method_params_table();
+ grpc_core::UniquePtr<char> service_config_json =
+ resolver_result.service_config_json();
+ if (service_config_json != nullptr && grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"",
+ chand, service_config_json.get());
+ }
grpc_core::UniquePtr<char> lb_policy_name =
- get_lb_policy_name_from_resolver_result_locked(chand);
+ resolver_result.lb_policy_name();
+ grpc_json* lb_policy_config = resolver_result.lb_policy_config();
// Check to see if we're already using the right LB policy.
// Note: It's safe to use chand->info_lb_policy_name 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.
- bool lb_policy_name_changed = chand->info_lb_policy_name == nullptr ||
- gpr_stricmp(chand->info_lb_policy_name.get(),
- lb_policy_name.get()) != 0;
+ bool lb_policy_name_changed =
+ chand->info_lb_policy_name == nullptr ||
+ strcmp(chand->info_lb_policy_name.get(), lb_policy_name.get()) != 0;
if (chand->lb_policy != nullptr && !lb_policy_name_changed) {
// Continue using the same LB policy. Update with new addresses.
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO, "chand=%p: updating existing LB policy \"%s\" (%p)",
chand, lb_policy_name.get(), chand->lb_policy.get());
}
- chand->lb_policy->UpdateLocked(*chand->resolver_result);
+ chand->lb_policy->UpdateLocked(*chand->resolver_result, lb_policy_config);
// No need to set the channel's connectivity state; the existing
// watch on the LB policy will take care of that.
set_connectivity_state = false;
} else {
// Instantiate new LB policy.
- create_new_lb_policy_locked(chand, lb_policy_name.get(),
+ create_new_lb_policy_locked(chand, lb_policy_name.get(), lb_policy_config,
&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
@@ -689,12 +566,6 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
} else {
grpc_error* error = GRPC_ERROR_NONE;
grpc_core::LoadBalancingPolicy::PickState pick_state;
- pick_state.initial_metadata = nullptr;
- pick_state.initial_metadata_flags = 0;
- pick_state.on_complete = nullptr;
- memset(&pick_state.subchannel_call_context, 0,
- sizeof(pick_state.subchannel_call_context));
- pick_state.user_data = nullptr;
// Pick must return synchronously, because pick_state.on_complete is null.
GPR_ASSERT(chand->lb_policy->PickLocked(&pick_state, &error));
if (pick_state.connected_subchannel != nullptr) {
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
index 587919596f..2232c57120 100644
--- a/src/core/ext/filters/client_channel/health/health_check_client.cc
+++ b/src/core/ext/filters/client_channel/health/health_check_client.cc
@@ -51,8 +51,7 @@ HealthCheckClient::HealthCheckClient(
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),
+ : InternallyRefCounted<HealthCheckClient>(&grpc_health_check_client_trace),
service_name_(service_name),
connected_subchannel_(std::move(connected_subchannel)),
interested_parties_(interested_parties),
@@ -281,8 +280,7 @@ bool DecodeResponse(grpc_slice_buffer* slice_buffer, grpc_error** error) {
HealthCheckClient::CallState::CallState(
RefCountedPtr<HealthCheckClient> health_check_client,
grpc_pollset_set* interested_parties)
- : InternallyRefCountedWithTracing<CallState>(
- &grpc_health_check_client_trace),
+ : InternallyRefCounted<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_
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
index f6babef7d6..2369b73fea 100644
--- a/src/core/ext/filters/client_channel/health/health_check_client.h
+++ b/src/core/ext/filters/client_channel/health/health_check_client.h
@@ -41,8 +41,7 @@
namespace grpc_core {
-class HealthCheckClient
- : public InternallyRefCountedWithTracing<HealthCheckClient> {
+class HealthCheckClient : public InternallyRefCounted<HealthCheckClient> {
public:
HealthCheckClient(const char* service_name,
RefCountedPtr<ConnectedSubchannel> connected_subchannel,
@@ -61,7 +60,7 @@ class HealthCheckClient
private:
// Contains a call to the backend and all the data related to the call.
- class CallState : public InternallyRefCountedWithTracing<CallState> {
+ class CallState : public InternallyRefCounted<CallState> {
public:
CallState(RefCountedPtr<HealthCheckClient> health_check_client,
grpc_pollset_set* interested_parties_);
diff --git a/src/core/ext/filters/client_channel/lb_policy.cc b/src/core/ext/filters/client_channel/lb_policy.cc
index e065f45639..b4e803689e 100644
--- a/src/core/ext/filters/client_channel/lb_policy.cc
+++ b/src/core/ext/filters/client_channel/lb_policy.cc
@@ -27,7 +27,7 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_lb_policy_refcount(
namespace grpc_core {
LoadBalancingPolicy::LoadBalancingPolicy(const Args& args)
- : InternallyRefCountedWithTracing(&grpc_trace_lb_policy_refcount),
+ : InternallyRefCounted(&grpc_trace_lb_policy_refcount),
combiner_(GRPC_COMBINER_REF(args.combiner, "lb_policy")),
client_channel_factory_(args.client_channel_factory),
interested_parties_(grpc_pollset_set_create()),
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index b0040457a6..6b76fe5d5d 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -42,8 +42,7 @@ namespace grpc_core {
///
/// Any I/O done by the LB policy should be done under the pollset_set
/// returned by \a interested_parties().
-class LoadBalancingPolicy
- : public InternallyRefCountedWithTracing<LoadBalancingPolicy> {
+class LoadBalancingPolicy : public InternallyRefCounted<LoadBalancingPolicy> {
public:
struct Args {
/// The combiner under which all LB policy calls will be run.
@@ -56,8 +55,10 @@ class LoadBalancingPolicy
grpc_client_channel_factory* client_channel_factory = nullptr;
/// Channel args from the resolver.
/// Note that the LB policy gets the set of addresses from the
- /// GRPC_ARG_LB_ADDRESSES channel arg.
+ /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg.
grpc_channel_args* args = nullptr;
+ /// Load balancing config from the resolver.
+ grpc_json* lb_config = nullptr;
};
/// State used for an LB pick.
@@ -79,11 +80,6 @@ class LoadBalancingPolicy
/// Will be populated with context to pass to the subchannel call, if
/// needed.
grpc_call_context_element subchannel_call_context[GRPC_CONTEXT_COUNT] = {};
- /// Upon success, \a *user_data will be set to whatever opaque information
- /// may need to be propagated from the LB policy, or nullptr if not needed.
- // TODO(roth): As part of revamping our metadata APIs, try to find a
- // way to clean this up and C++-ify it.
- void** user_data = nullptr;
/// Next pointer. For internal use by LB policy.
PickState* next = nullptr;
};
@@ -92,10 +88,11 @@ class LoadBalancingPolicy
LoadBalancingPolicy(const LoadBalancingPolicy&) = delete;
LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete;
- /// Updates the policy with a new set of \a args from the resolver.
- /// Note that the LB policy gets the set of addresses from the
- /// GRPC_ARG_LB_ADDRESSES channel arg.
- virtual void UpdateLocked(const grpc_channel_args& args) GRPC_ABSTRACT;
+ /// Updates the policy with a new set of \a args and a new \a lb_config from
+ /// the resolver. Note that the LB policy gets the set of addresses from the
+ /// GRPC_ARG_SERVER_ADDRESS_LIST channel arg.
+ virtual void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) GRPC_ABSTRACT;
/// Finds an appropriate subchannel for a call, based on data in \a pick.
/// \a pick must remain alive until the pick is complete.
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 dbb90b438c..a9a5965ed1 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
@@ -84,6 +84,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
@@ -113,6 +114,8 @@
#define GRPC_GRPCLB_RECONNECT_JITTER 0.2
#define GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS 10000
+#define GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN "grpc.grpclb_address_lb_token"
+
namespace grpc_core {
TraceFlag grpc_lb_glb_trace(false, "glb");
@@ -121,9 +124,10 @@ namespace {
class GrpcLb : public LoadBalancingPolicy {
public:
- GrpcLb(const grpc_lb_addresses* addresses, const Args& args);
+ explicit GrpcLb(const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -160,9 +164,6 @@ class GrpcLb : public LoadBalancingPolicy {
// Our on_complete closure and the original one.
grpc_closure on_complete;
grpc_closure* original_on_complete;
- // The LB token associated with the pick. This is set via user_data in
- // the pick.
- grpc_mdelem lb_token;
// Stats for client-side load reporting.
RefCountedPtr<GrpcLbClientStats> client_stats;
// Next pending pick.
@@ -170,8 +171,7 @@ class GrpcLb : public LoadBalancingPolicy {
};
/// Contains a call to the LB server and all the data related to the call.
- class BalancerCallState
- : public InternallyRefCountedWithTracing<BalancerCallState> {
+ class BalancerCallState : public InternallyRefCounted<BalancerCallState> {
public:
explicit BalancerCallState(
RefCountedPtr<LoadBalancingPolicy> parent_grpclb_policy);
@@ -329,7 +329,7 @@ class GrpcLb : public LoadBalancingPolicy {
// 0 means not using fallback.
int lb_fallback_timeout_ms_ = 0;
// The backend addresses from the resolver.
- grpc_lb_addresses* fallback_backend_addresses_ = nullptr;
+ UniquePtr<ServerAddressList> fallback_backend_addresses_;
// Fallback timer.
bool fallback_timer_callback_pending_ = false;
grpc_timer lb_fallback_timer_;
@@ -349,7 +349,7 @@ class GrpcLb : public LoadBalancingPolicy {
// serverlist parsing code
//
-// vtable for LB tokens in grpc_lb_addresses
+// vtable for LB token channel arg.
void* lb_token_copy(void* token) {
return token == nullptr
? nullptr
@@ -361,38 +361,11 @@ void lb_token_destroy(void* token) {
}
}
int lb_token_cmp(void* token1, void* token2) {
- if (token1 > token2) return 1;
- if (token1 < token2) return -1;
- return 0;
+ return GPR_ICMP(token1, token2);
}
-const grpc_lb_user_data_vtable lb_token_vtable = {
+const grpc_arg_pointer_vtable lb_token_arg_vtable = {
lb_token_copy, lb_token_destroy, lb_token_cmp};
-// Returns the backend addresses extracted from the given addresses.
-grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) {
- // First pass: count the number of backend addresses.
- size_t num_backends = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) {
- ++num_backends;
- }
- }
- // Second pass: actually populate the addresses and (empty) LB tokens.
- grpc_lb_addresses* backend_addresses =
- grpc_lb_addresses_create(num_backends, &lb_token_vtable);
- size_t num_copied = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) continue;
- const grpc_resolved_address* addr = &addresses->addresses[i].address;
- grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr,
- addr->len, false /* is_balancer */,
- nullptr /* balancer_name */,
- (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload);
- ++num_copied;
- }
- return backend_addresses;
-}
-
bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) {
if (server->drop) return false;
const grpc_grpclb_ip_address* ip = &server->ip_address;
@@ -440,30 +413,16 @@ void ParseServer(const grpc_grpclb_server* server,
}
// Returns addresses extracted from \a serverlist.
-grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
- size_t num_valid = 0;
- /* first pass: count how many are valid in order to allocate the necessary
- * memory in a single block */
+ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
+ ServerAddressList addresses;
for (size_t i = 0; i < serverlist->num_servers; ++i) {
- if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid;
- }
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_valid, &lb_token_vtable);
- /* second pass: actually populate the addresses and LB tokens (aka user data
- * to the outside world) to be read by the RR policy during its creation.
- * Given that the validity tests are very cheap, they are performed again
- * instead of marking the valid ones during the first pass, as this would
- * incurr in an allocation due to the arbitrary number of server */
- size_t addr_idx = 0;
- for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) {
- const grpc_grpclb_server* server = serverlist->servers[sl_idx];
- if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue;
- GPR_ASSERT(addr_idx < num_valid);
- /* address processing */
+ const grpc_grpclb_server* server = serverlist->servers[i];
+ if (!IsServerValid(serverlist->servers[i], i, false)) continue;
+ // Address processing.
grpc_resolved_address addr;
ParseServer(server, &addr);
- /* lb token processing */
- void* user_data;
+ // LB token processing.
+ void* lb_token;
if (server->has_load_balance_token) {
const size_t lb_token_max_length =
GPR_ARRAY_SIZE(server->load_balance_token);
@@ -471,7 +430,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
strnlen(server->load_balance_token, lb_token_max_length);
grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
server->load_balance_token, lb_token_length);
- user_data =
+ lb_token =
(void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr)
.payload;
} else {
@@ -481,15 +440,16 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
"be used instead",
uri);
gpr_free(uri);
- user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
+ lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
}
- grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
- false /* is_balancer */,
- nullptr /* balancer_name */, user_data);
- ++addr_idx;
- }
- GPR_ASSERT(addr_idx == num_valid);
- return lb_addresses;
+ // Add address.
+ grpc_arg arg = grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
+ &lb_token_arg_vtable);
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
+ addresses.emplace_back(addr, args);
+ }
+ return addresses;
}
//
@@ -498,7 +458,7 @@ grpc_lb_addresses* ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
GrpcLb::BalancerCallState::BalancerCallState(
RefCountedPtr<LoadBalancingPolicy> parent_grpclb_policy)
- : InternallyRefCountedWithTracing<BalancerCallState>(&grpc_lb_glb_trace),
+ : InternallyRefCounted<BalancerCallState>(&grpc_lb_glb_trace),
grpclb_policy_(std::move(parent_grpclb_policy)) {
GPR_ASSERT(grpclb_policy_ != nullptr);
GPR_ASSERT(!grpclb_policy()->shutting_down_);
@@ -748,7 +708,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
void* arg, grpc_error* error) {
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
- // Empty payload means the LB call was cancelled.
+ // Null payload means the LB call was cancelled.
if (lb_calld != grpclb_policy->lb_calld_.get() ||
lb_calld->recv_message_payload_ == nullptr) {
lb_calld->Unref(DEBUG_LOCATION, "on_message_received");
@@ -802,54 +762,44 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
gpr_free(ipport);
}
}
- /* update serverlist */
- if (serverlist->num_servers > 0) {
- // Start sending client load report only after we start using the
- // serverlist returned from the current LB call.
- if (lb_calld->client_stats_report_interval_ > 0 &&
- lb_calld->client_stats_ == nullptr) {
- lb_calld->client_stats_.reset(New<GrpcLbClientStats>());
- // TODO(roth): We currently track this ref manually. Once the
- // ClosureRef API is ready, we should pass the RefCountedPtr<> along
- // with the callback.
- auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
- self.release();
- lb_calld->ScheduleNextClientLoadReportLocked();
- }
- if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_,
- serverlist)) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Incoming server list identical to current, "
- "ignoring.",
- grpclb_policy);
- }
- grpc_grpclb_destroy_serverlist(serverlist);
- } else { /* new serverlist */
- if (grpclb_policy->serverlist_ != nullptr) {
- /* dispose of the old serverlist */
- grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
- } else {
- /* or dispose of the fallback */
- grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
- grpclb_policy->fallback_backend_addresses_ = nullptr;
- if (grpclb_policy->fallback_timer_callback_pending_) {
- grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
- }
- }
- // and update the copy in the GrpcLb instance. This
- // serverlist instance will be destroyed either upon the next
- // update or when the GrpcLb instance is destroyed.
- grpclb_policy->serverlist_ = serverlist;
- grpclb_policy->serverlist_index_ = 0;
- grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
- }
- } else {
+ // Start sending client load report only after we start using the
+ // serverlist returned from the current LB call.
+ if (lb_calld->client_stats_report_interval_ > 0 &&
+ lb_calld->client_stats_ == nullptr) {
+ lb_calld->client_stats_.reset(New<GrpcLbClientStats>());
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
+ self.release();
+ lb_calld->ScheduleNextClientLoadReportLocked();
+ }
+ // Check if the serverlist differs from the previous one.
+ if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) {
if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.",
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Incoming server list identical to current, "
+ "ignoring.",
grpclb_policy);
}
grpc_grpclb_destroy_serverlist(serverlist);
+ } else { // New serverlist.
+ if (grpclb_policy->serverlist_ != nullptr) {
+ // Dispose of the old serverlist.
+ grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
+ } else {
+ // Dispose of the fallback.
+ grpclb_policy->fallback_backend_addresses_.reset();
+ if (grpclb_policy->fallback_timer_callback_pending_) {
+ grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
+ }
+ }
+ // Update the serverlist in the GrpcLb instance. This serverlist
+ // instance will be destroyed either upon the next update or when the
+ // GrpcLb instance is destroyed.
+ grpclb_policy->serverlist_ = serverlist;
+ grpclb_policy->serverlist_index_ = 0;
+ grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
}
} else {
// No valid initial response or serverlist found.
@@ -919,31 +869,25 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// helper code for creating balancer channel
//
-grpc_lb_addresses* ExtractBalancerAddresses(
- const grpc_lb_addresses* addresses) {
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
- }
- // There must be at least one balancer address, or else the
- // client_channel would not have chosen this LB policy.
- GPR_ASSERT(num_grpclb_addrs > 0);
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_grpclb_addrs, nullptr);
- size_t lb_addresses_idx = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) continue;
- if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) {
- gpr_log(GPR_ERROR,
- "This LB policy doesn't support user data. It will be ignored");
+ServerAddressList ExtractBalancerAddresses(const ServerAddressList& addresses) {
+ ServerAddressList balancer_addresses;
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (addresses[i].IsBalancer()) {
+ // Strip out the is_balancer channel arg, since we don't want to
+ // recursively use the grpclb policy in the channel used to talk to
+ // the balancers. Note that we do NOT strip out the balancer_name
+ // channel arg, since we need that to set the authority correctly
+ // to talk to the balancers.
+ static const char* args_to_remove[] = {
+ GRPC_ARG_ADDRESS_IS_BALANCER,
+ };
+ balancer_addresses.emplace_back(
+ addresses[i].address(),
+ grpc_channel_args_copy_and_remove(addresses[i].args(), args_to_remove,
+ GPR_ARRAY_SIZE(args_to_remove)));
}
- grpc_lb_addresses_set_address(
- lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr,
- addresses->addresses[i].address.len, false /* is balancer */,
- addresses->addresses[i].balancer_name, nullptr /* user data */);
}
- GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx);
- return lb_addresses;
+ return balancer_addresses;
}
/* Returns the channel args for the LB channel, used to create a bidirectional
@@ -955,10 +899,10 @@ grpc_lb_addresses* ExtractBalancerAddresses(
* above the grpclb policy.
* - \a args: other args inherited from the grpclb policy. */
grpc_channel_args* BuildBalancerChannelArgs(
- const grpc_lb_addresses* addresses,
+ const ServerAddressList& addresses,
FakeResolverResponseGenerator* response_generator,
const grpc_channel_args* args) {
- grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses);
+ ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses);
// Channel args to remove.
static const char* args_to_remove[] = {
// LB policy name, since we want to use the default (pick_first) in
@@ -976,7 +920,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
// is_balancer=true. We need the LB channel to return addresses with
// is_balancer=false so that it does not wind up recursively using the
// grpclb LB policy, as per the special case logic in client_channel.c.
- GRPC_ARG_LB_ADDRESSES,
+ GRPC_ARG_SERVER_ADDRESS_LIST,
// The fake resolver response generator, because we are replacing it
// with the one from the grpclb policy, used to propagate updates to
// the LB channel.
@@ -992,10 +936,10 @@ grpc_channel_args* BuildBalancerChannelArgs(
};
// Channel args to add.
const grpc_arg args_to_add[] = {
- // New LB addresses.
+ // New address list.
// Note that we pass these in both when creating the LB channel
// and via the fake resolver. The latter is what actually gets used.
- grpc_lb_addresses_create_channel_arg(lb_addresses),
+ CreateServerAddressListChannelArg(&balancer_addresses),
// The fake resolver response generator, which we use to inject
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
@@ -1013,18 +957,14 @@ grpc_channel_args* BuildBalancerChannelArgs(
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
// Make any necessary modifications for security.
- new_args = grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
- // Clean up.
- grpc_lb_addresses_destroy(lb_addresses);
- return new_args;
+ return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
}
//
// ctor and dtor
//
-GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
- const LoadBalancingPolicy::Args& args)
+GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args)
: LoadBalancingPolicy(args),
response_generator_(MakeRefCounted<FakeResolverResponseGenerator>()),
lb_call_backoff_(
@@ -1081,9 +1021,6 @@ GrpcLb::~GrpcLb() {
if (serverlist_ != nullptr) {
grpc_grpclb_destroy_serverlist(serverlist_);
}
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
grpc_subchannel_index_unref();
}
@@ -1131,7 +1068,6 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
while ((pp = pending_picks_) != nullptr) {
pending_picks_ = pp->next;
pp->pick->on_complete = pp->original_on_complete;
- pp->pick->user_data = nullptr;
grpc_error* error = GRPC_ERROR_NONE;
if (new_policy->PickLocked(pp->pick, &error)) {
// Synchronous return; schedule closure.
@@ -1285,9 +1221,27 @@ void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
notify);
}
+// Returns the backend addresses extracted from the given addresses.
+UniquePtr<ServerAddressList> ExtractBackendAddresses(
+ const ServerAddressList& addresses) {
+ void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
+ grpc_arg arg = grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
+ &lb_token_arg_vtable);
+ auto backend_addresses = MakeUnique<ServerAddressList>();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (!addresses[i].IsBalancer()) {
+ backend_addresses->emplace_back(
+ addresses[i].address(),
+ grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1));
+ }
+ }
+ return backend_addresses;
+}
+
void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
// Ignore this update.
gpr_log(
GPR_ERROR,
@@ -1295,13 +1249,8 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
this);
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
// Update fallback address list.
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
- fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
+ fallback_backend_addresses_ = ExtractBackendAddresses(*addresses);
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
@@ -1312,7 +1261,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
// Construct args for balancer channel.
grpc_channel_args* lb_channel_args =
- BuildBalancerChannelArgs(addresses, response_generator_.get(), &args);
+ BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args);
// Create balancer channel if needed.
if (lb_channel_ == nullptr) {
char* uri_str;
@@ -1331,7 +1280,7 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
grpc_channel_args_destroy(lb_channel_args);
}
-void GrpcLb::UpdateLocked(const grpc_channel_args& args) {
+void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) {
ProcessChannelArgsLocked(args);
// Update the existing RR policy.
if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked();
@@ -1518,12 +1467,17 @@ void DestroyClientStats(void* arg) {
}
void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
- /* if connected_subchannel is nullptr, no pick has been made by the RR
- * policy (e.g., all addresses failed to connect). There won't be any
- * user_data/token available */
+ // If connected_subchannel is nullptr, no pick has been made by the RR
+ // policy (e.g., all addresses failed to connect). There won't be any
+ // LB token available.
if (pp->pick->connected_subchannel != nullptr) {
- if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) {
- AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token),
+ const grpc_arg* arg =
+ grpc_channel_args_find(pp->pick->connected_subchannel->args(),
+ GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
+ if (arg != nullptr) {
+ grpc_mdelem lb_token = {
+ reinterpret_cast<uintptr_t>(arg->value.pointer.p)};
+ AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token),
&pp->pick->lb_token_mdelem_storage,
pp->pick->initial_metadata);
} else {
@@ -1582,7 +1536,7 @@ void GrpcLb::AddPendingPick(PendingPick* pp) {
bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
grpc_error** error) {
// Check for drops if we are not using fallback backend addresses.
- if (serverlist_ != nullptr) {
+ if (serverlist_ != nullptr && serverlist_->num_servers > 0) {
// Look at the index into the serverlist to see if we should drop this call.
grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++];
if (serverlist_index_ == serverlist_->num_servers) {
@@ -1607,12 +1561,10 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
return true;
}
}
- // Set client_stats and user_data.
+ // Set client_stats.
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
pp->client_stats = lb_calld_->client_stats()->Ref();
}
- GPR_ASSERT(pp->pick->user_data == nullptr);
- pp->pick->user_data = (void**)&pp->lb_token;
// Pick via the RR policy.
bool pick_done = rr_policy_->PickLocked(pp->pick, error);
if (pick_done) {
@@ -1677,11 +1629,11 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) {
}
grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
- grpc_lb_addresses* addresses;
+ ServerAddressList tmp_addresses;
+ ServerAddressList* addresses = &tmp_addresses;
bool is_backend_from_grpclb_load_balancer = false;
if (serverlist_ != nullptr) {
- GPR_ASSERT(serverlist_->num_servers > 0);
- addresses = ProcessServerlist(serverlist_);
+ tmp_addresses = ProcessServerlist(serverlist_);
is_backend_from_grpclb_load_balancer = true;
} else {
// If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't
@@ -1690,14 +1642,14 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
// empty, in which case the new round_robin policy will keep the requested
// picks pending.
GPR_ASSERT(fallback_backend_addresses_ != nullptr);
- addresses = grpc_lb_addresses_copy(fallback_backend_addresses_);
+ addresses = fallback_backend_addresses_.get();
}
GPR_ASSERT(addresses != nullptr);
- // Replace the LB addresses in the channel args that we pass down to
+ // Replace the server address list in the channel args that we pass down to
// the subchannel.
- static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
+ static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
grpc_arg args_to_add[3] = {
- grpc_lb_addresses_create_channel_arg(addresses),
+ CreateServerAddressListChannelArg(addresses),
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
grpc_channel_arg_integer_create(
@@ -1714,7 +1666,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
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,
num_args_to_add);
- grpc_lb_addresses_destroy(addresses);
return args;
}
@@ -1727,7 +1678,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() {
gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this,
rr_policy_.get());
}
- rr_policy_->UpdateLocked(*args);
+ rr_policy_->UpdateLocked(*args, nullptr);
} else {
LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = combiner();
@@ -1847,19 +1798,18 @@ class GrpcLbFactory : public LoadBalancingPolicyFactory {
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const LoadBalancingPolicy::Args& args) const override {
/* Count the number of gRPC-LB addresses. There must be at least one. */
- const grpc_arg* arg =
- grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- return nullptr;
- }
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+ const ServerAddressList* addresses =
+ FindServerAddressListChannelArg(args.args);
+ if (addresses == nullptr) return nullptr;
+ bool found_balancer = false;
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ if ((*addresses)[i].IsBalancer()) {
+ found_balancer = true;
+ break;
+ }
}
- if (num_grpclb_addrs == 0) return nullptr;
- return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(addresses, args));
+ if (!found_balancer) return nullptr;
+ return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(args));
}
const char* name() const override { return "grpclb"; }
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
index 825065a9c3..3b2dc370eb 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h
@@ -21,7 +21,7 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include <grpc/impl/codegen/grpc_types.h>
/// Makes any necessary modifications to \a args for use in the grpclb
/// balancer channel.
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
index 441efd5e23..657ff69312 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc
@@ -26,6 +26,7 @@
#include <grpc/support/string_util.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -42,22 +43,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
}
RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
- grpc_lb_addresses* addresses) {
+ const ServerAddressList& addresses) {
TargetAuthorityTable::Entry* target_authority_entries =
- static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
- sizeof(*target_authority_entries) * addresses->num_addresses));
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ static_cast<TargetAuthorityTable::Entry*>(
+ gpr_zalloc(sizeof(*target_authority_entries) * addresses.size()));
+ for (size_t i = 0; i < addresses.size(); ++i) {
char* addr_str;
- GPR_ASSERT(grpc_sockaddr_to_string(
- &addr_str, &addresses->addresses[i].address, true) > 0);
+ GPR_ASSERT(
+ grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0);
target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
- target_authority_entries[i].value.reset(
- gpr_strdup(addresses->addresses[i].balancer_name));
gpr_free(addr_str);
+ char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find(
+ addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME));
+ target_authority_entries[i].value.reset(gpr_strdup(balancer_name));
}
RefCountedPtr<TargetAuthorityTable> target_authority_table =
- TargetAuthorityTable::Create(addresses->num_addresses,
- target_authority_entries, BalancerNameCmp);
+ TargetAuthorityTable::Create(addresses.size(), target_authority_entries,
+ BalancerNameCmp);
gpr_free(target_authority_entries);
return target_authority_table;
}
@@ -72,13 +74,12 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
- const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(arg != nullptr);
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_core::ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(args);
+ GPR_ASSERT(addresses != nullptr);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
- target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
+ target_authority_table =
+ grpc_core::CreateTargetAuthorityTable(*addresses);
args_to_add[num_args_to_add++] =
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());
@@ -87,22 +88,18 @@ grpc_channel_args* grpc_lb_policy_grpclb_modify_lb_channel_args(
// bearer token credentials.
grpc_channel_credentials* channel_credentials =
grpc_channel_credentials_find_in_args(args);
- grpc_channel_credentials* creds_sans_call_creds = nullptr;
+ grpc_core::RefCountedPtr<grpc_channel_credentials> creds_sans_call_creds;
if (channel_credentials != nullptr) {
creds_sans_call_creds =
- grpc_channel_credentials_duplicate_without_call_credentials(
- channel_credentials);
+ channel_credentials->duplicate_without_call_credentials();
GPR_ASSERT(creds_sans_call_creds != nullptr);
args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS;
args_to_add[num_args_to_add++] =
- grpc_channel_credentials_to_arg(creds_sans_call_creds);
+ grpc_channel_credentials_to_arg(creds_sans_call_creds.get());
}
grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove(
args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add);
// Clean up.
grpc_channel_args_destroy(args);
- if (creds_sans_call_creds != nullptr) {
- grpc_channel_credentials_unref(creds_sans_call_creds);
- }
return result;
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
index 9ca7b28d8e..71d371c880 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h
@@ -25,7 +25,7 @@
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h"
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
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 eb494486b9..74c17612a2 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
@@ -24,6 +24,7 @@
#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/channel/channel_args.h"
@@ -46,7 +47,8 @@ class PickFirst : public LoadBalancingPolicy {
public:
explicit PickFirst(const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -74,11 +76,9 @@ class PickFirst : public LoadBalancingPolicy {
PickFirstSubchannelData(
SubchannelList<PickFirstSubchannelList, PickFirstSubchannelData>*
subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner)
- : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
- combiner) {}
+ : SubchannelData(subchannel_list, address, subchannel, combiner) {}
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
@@ -94,7 +94,7 @@ class PickFirst : public LoadBalancingPolicy {
PickFirstSubchannelData> {
public:
PickFirstSubchannelList(PickFirst* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses,
+ const ServerAddressList& addresses,
grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
@@ -159,7 +159,7 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) {
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p created.", this);
}
- UpdateLocked(*args.args);
+ UpdateLocked(*args.args, args.lb_config);
grpc_subchannel_index_ref();
}
@@ -333,10 +333,11 @@ void PickFirst::UpdateChildRefsLocked() {
child_subchannels_ = std::move(cs);
}
-void PickFirst::UpdateLocked(const grpc_channel_args& args) {
+void PickFirst::UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) {
AutoChildRefsUpdater guard(this);
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
if (subchannel_list_ == nullptr) {
// If we don't have a current subchannel list, go into TRANSIENT FAILURE.
grpc_connectivity_state_set(
@@ -352,19 +353,17 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
}
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
"Pick First %p received update with %" PRIuPTR " addresses", this,
- addresses->num_addresses);
+ addresses->size());
}
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(),
+ this, &grpc_lb_pick_first_trace, *addresses, combiner(),
client_channel_factory(), *new_args);
grpc_channel_args_destroy(new_args);
if (subchannel_list->num_subchannels() == 0) {
@@ -378,6 +377,31 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
selected_ = nullptr;
return;
}
+ // If one of the subchannels in the new list is already in state
+ // READY, then select it immediately. This can happen when the
+ // currently selected subchannel is also present in the update. It
+ // can also happen if one of the subchannels in the update is already
+ // in the subchannel index because it's in use by another channel.
+ for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
+ PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
+ grpc_error* error = GRPC_ERROR_NONE;
+ grpc_connectivity_state state = sd->CheckConnectivityStateLocked(&error);
+ GRPC_ERROR_UNREF(error);
+ if (state == GRPC_CHANNEL_READY) {
+ subchannel_list_ = std::move(subchannel_list);
+ sd->ProcessUnselectedReadyLocked();
+ sd->StartConnectivityWatchLocked();
+ // If there was a previously pending update (which may or may
+ // not have contained the currently selected subchannel), drop
+ // it, so that it doesn't override what we've done here.
+ latest_pending_subchannel_list_.reset();
+ // Make sure that subsequent calls to ExitIdleLocked() don't cause
+ // us to start watching a subchannel other than the one we've
+ // selected.
+ started_picking_ = true;
+ return;
+ }
+ }
if (selected_ == nullptr) {
// We don't yet have a selected subchannel, so replace the current
// subchannel list immediately.
@@ -385,46 +409,14 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
// If we've started picking, start trying to connect to the first
// subchannel in the new list.
if (started_picking_) {
- subchannel_list_->subchannel(0)
- ->CheckConnectivityStateAndStartWatchingLocked();
+ // Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
+ // here, since we've already checked the initial connectivity
+ // state of all subchannels above.
+ subchannel_list_->subchannel(0)->StartConnectivityWatchLocked();
}
} else {
- // We do have a selected subchannel.
- // Check if it's present in the new list. If so, we're done.
- for (size_t i = 0; i < subchannel_list->num_subchannels(); ++i) {
- PickFirstSubchannelData* sd = subchannel_list->subchannel(i);
- if (sd->subchannel() == selected_->subchannel()) {
- // The currently selected subchannel is in the update: we are done.
- if (grpc_lb_pick_first_trace.enabled()) {
- gpr_log(GPR_INFO,
- "Pick First %p found already selected subchannel %p "
- "at update index %" PRIuPTR " of %" PRIuPTR "; update done",
- this, selected_->subchannel(), i,
- subchannel_list->num_subchannels());
- }
- // Make sure it's in state READY. It might not be if we grabbed
- // the combiner while a connectivity state notification
- // informing us otherwise is pending.
- // Note that CheckConnectivityStateLocked() also takes a ref to
- // the connected subchannel.
- grpc_error* error = GRPC_ERROR_NONE;
- if (sd->CheckConnectivityStateLocked(&error) == GRPC_CHANNEL_READY) {
- selected_ = sd;
- subchannel_list_ = std::move(subchannel_list);
- sd->StartConnectivityWatchLocked();
- // If there was a previously pending update (which may or may
- // not have contained the currently selected subchannel), drop
- // it, so that it doesn't override what we've done here.
- latest_pending_subchannel_list_.reset();
- return;
- }
- GRPC_ERROR_UNREF(error);
- }
- }
- // Not keeping the previous selected subchannel, so set the latest
- // pending subchannel list to the new subchannel list. We will wait
- // for it to report READY before swapping it into the current
- // subchannel list.
+ // We do have a selected subchannel, so keep using it until one of
+ // the subchannels in the new list reports READY.
if (latest_pending_subchannel_list_ != nullptr) {
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO,
@@ -438,8 +430,11 @@ void PickFirst::UpdateLocked(const grpc_channel_args& args) {
// If we've started picking, start trying to connect to the first
// subchannel in the new list.
if (started_picking_) {
+ // Note: No need to use CheckConnectivityStateAndStartWatchingLocked()
+ // here, since we've already checked the initial connectivity
+ // state of all subchannels above.
latest_pending_subchannel_list_->subchannel(0)
- ->CheckConnectivityStateAndStartWatchingLocked();
+ ->StartConnectivityWatchLocked();
}
}
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index e9ed85cf66..63089afbd7 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -57,7 +57,8 @@ class RoundRobin : public LoadBalancingPolicy {
public:
explicit RoundRobin(const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -81,8 +82,6 @@ class RoundRobin : public LoadBalancingPolicy {
// Data for a particular subchannel in a subchannel list.
// This subclass adds the following functionality:
- // - Tracks user_data associated with each address, which will be
- // returned along with picks that select the subchannel.
// - Tracks the previous connectivity state of the subchannel, so that
// we know how many subchannels are in each state.
class RoundRobinSubchannelData
@@ -92,26 +91,9 @@ class RoundRobin : public LoadBalancingPolicy {
RoundRobinSubchannelData(
SubchannelList<RoundRobinSubchannelList, RoundRobinSubchannelData>*
subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner)
- : SubchannelData(subchannel_list, user_data_vtable, address, subchannel,
- combiner),
- user_data_vtable_(user_data_vtable),
- user_data_(user_data_vtable_ != nullptr
- ? user_data_vtable_->copy(address.user_data)
- : nullptr) {}
-
- void UnrefSubchannelLocked(const char* reason) override {
- SubchannelData::UnrefSubchannelLocked(reason);
- if (user_data_ != nullptr) {
- GPR_ASSERT(user_data_vtable_ != nullptr);
- user_data_vtable_->destroy(user_data_);
- user_data_ = nullptr;
- }
- }
-
- void* user_data() const { return user_data_; }
+ : SubchannelData(subchannel_list, address, subchannel, combiner) {}
grpc_connectivity_state connectivity_state() const {
return last_connectivity_state_;
@@ -124,8 +106,6 @@ class RoundRobin : public LoadBalancingPolicy {
void ProcessConnectivityChangeLocked(
grpc_connectivity_state connectivity_state, grpc_error* error) override;
- const grpc_lb_user_data_vtable* user_data_vtable_;
- void* user_data_ = nullptr;
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_IDLE;
};
@@ -136,7 +116,7 @@ class RoundRobin : public LoadBalancingPolicy {
public:
RoundRobinSubchannelList(
RoundRobin* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ const ServerAddressList& addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
: SubchannelList(policy, tracer, addresses, combiner,
@@ -232,7 +212,7 @@ RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
gpr_mu_init(&child_refs_mu_);
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
"round_robin");
- UpdateLocked(*args.args);
+ UpdateLocked(*args.args, args.lb_config);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this,
subchannel_list_->num_subchannels());
@@ -353,9 +333,6 @@ bool RoundRobin::DoPickLocked(PickState* pick) {
subchannel_list_->subchannel(next_ready_index);
GPR_ASSERT(sd->connected_subchannel() != nullptr);
pick->connected_subchannel = sd->connected_subchannel()->Ref();
- if (pick->user_data != nullptr) {
- *pick->user_data = sd->user_data();
- }
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO,
"[RR %p] Picked target <-- Subchannel %p (connected %p) (sl %p, "
@@ -664,10 +641,11 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
notify);
}
-void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
+void RoundRobin::UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) {
AutoChildRefsUpdater guard(this);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
// If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
// Otherwise, keep using the current subchannel list (ignore this update).
@@ -679,11 +657,9 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
}
return;
}
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] received update with %" PRIuPTR " addresses",
- this, addresses->num_addresses);
+ this, addresses->size());
}
// Replace latest_pending_subchannel_list_.
if (latest_pending_subchannel_list_ != nullptr) {
@@ -694,7 +670,7 @@ void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
}
}
latest_pending_subchannel_list_ = MakeOrphanable<RoundRobinSubchannelList>(
- this, &grpc_lb_round_robin_trace, addresses, combiner(),
+ this, &grpc_lb_round_robin_trace, *addresses, combiner(),
client_channel_factory(), args);
// If we haven't started picking yet or the new list is empty,
// immediately promote the new list to the current list.
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 4ec9e935ed..6f31a643c1 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
@@ -26,6 +26,7 @@
#include <grpc/support/alloc.h>
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/debug/trace.h"
@@ -141,8 +142,7 @@ class SubchannelData {
protected:
SubchannelData(
SubchannelList<SubchannelListType, SubchannelDataType>* subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner);
virtual ~SubchannelData();
@@ -156,9 +156,8 @@ class SubchannelData {
grpc_connectivity_state connectivity_state,
grpc_error* error) GRPC_ABSTRACT;
- // Unrefs the subchannel. May be overridden by subclasses that need
- // to perform extra cleanup when unreffing the subchannel.
- virtual void UnrefSubchannelLocked(const char* reason);
+ // Unrefs the subchannel.
+ void UnrefSubchannelLocked(const char* reason);
private:
// Updates connected_subchannel_ based on pending_connectivity_state_unsafe_.
@@ -186,8 +185,7 @@ class SubchannelData {
// A list of subchannels.
template <typename SubchannelListType, typename SubchannelDataType>
-class SubchannelList
- : public InternallyRefCountedWithTracing<SubchannelListType> {
+class SubchannelList : public InternallyRefCounted<SubchannelListType> {
public:
typedef InlinedVector<SubchannelDataType, 10> SubchannelVector;
@@ -226,15 +224,14 @@ class SubchannelList
// Note: Caller must ensure that this is invoked inside of the combiner.
void Orphan() override {
ShutdownLocked();
- InternallyRefCountedWithTracing<SubchannelListType>::Unref(DEBUG_LOCATION,
- "shutdown");
+ InternallyRefCounted<SubchannelListType>::Unref(DEBUG_LOCATION, "shutdown");
}
GRPC_ABSTRACT_BASE_CLASS
protected:
SubchannelList(LoadBalancingPolicy* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ const ServerAddressList& addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args);
@@ -279,8 +276,7 @@ class SubchannelList
template <typename SubchannelListType, typename SubchannelDataType>
SubchannelData<SubchannelListType, SubchannelDataType>::SubchannelData(
SubchannelList<SubchannelListType, SubchannelDataType>* subchannel_list,
- const grpc_lb_user_data_vtable* user_data_vtable,
- const grpc_lb_address& address, grpc_subchannel* subchannel,
+ const ServerAddress& address, grpc_subchannel* subchannel,
grpc_combiner* combiner)
: subchannel_list_(subchannel_list),
subchannel_(subchannel),
@@ -490,19 +486,19 @@ void SubchannelData<SubchannelListType, SubchannelDataType>::ShutdownLocked() {
template <typename SubchannelListType, typename SubchannelDataType>
SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
LoadBalancingPolicy* policy, TraceFlag* tracer,
- const grpc_lb_addresses* addresses, grpc_combiner* combiner,
+ const ServerAddressList& addresses, grpc_combiner* combiner,
grpc_client_channel_factory* client_channel_factory,
const grpc_channel_args& args)
- : InternallyRefCountedWithTracing<SubchannelListType>(tracer),
+ : InternallyRefCounted<SubchannelListType>(tracer),
policy_(policy),
tracer_(tracer),
combiner_(GRPC_COMBINER_REF(combiner, "subchannel_list")) {
if (tracer_->enabled()) {
gpr_log(GPR_INFO,
"[%s %p] Creating subchannel list %p for %" PRIuPTR " subchannels",
- tracer_->name(), policy, this, addresses->num_addresses);
+ tracer_->name(), policy, this, addresses.size());
}
- subchannels_.reserve(addresses->num_addresses);
+ subchannels_.reserve(addresses.size());
// 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
@@ -510,19 +506,27 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
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_SERVER_ADDRESS_LIST,
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++) {
- // If there were any balancer, we would have chosen grpclb policy instead.
- GPR_ASSERT(!addresses->addresses[i].is_balancer);
+ for (size_t i = 0; i < addresses.size(); i++) {
+ // If there were any balancer addresses, we would have chosen grpclb
+ // policy, which does not use a SubchannelList.
+ GPR_ASSERT(!addresses[i].IsBalancer());
memset(&sc_args, 0, sizeof(grpc_subchannel_args));
- grpc_arg addr_arg =
- grpc_create_subchannel_address_arg(&addresses->addresses[i].address);
+ InlinedVector<grpc_arg, 4> args_to_add;
+ args_to_add.emplace_back(
+ grpc_create_subchannel_address_arg(&addresses[i].address()));
+ if (addresses[i].args() != nullptr) {
+ for (size_t j = 0; j < addresses[i].args()->num_args; ++j) {
+ args_to_add.emplace_back(addresses[i].args()->args[j]);
+ }
+ }
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
- &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove), &addr_arg, 1);
- gpr_free(addr_arg.value.string);
+ &args, keys_to_remove, GPR_ARRAY_SIZE(keys_to_remove),
+ args_to_add.data(), args_to_add.size());
+ gpr_free(args_to_add[0].value.string);
sc_args.args = new_args;
grpc_subchannel* subchannel = grpc_client_channel_factory_create_subchannel(
client_channel_factory, &sc_args);
@@ -530,8 +534,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
if (subchannel == nullptr) {
// Subchannel could not be created.
if (tracer_->enabled()) {
- char* address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address());
gpr_log(GPR_INFO,
"[%s %p] could not create subchannel for address uri %s, "
"ignoring",
@@ -541,8 +544,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
continue;
}
if (tracer_->enabled()) {
- char* address_uri =
- grpc_sockaddr_to_uri(&addresses->addresses[i].address);
+ char* address_uri = grpc_sockaddr_to_uri(&addresses[i].address());
gpr_log(GPR_INFO,
"[%s %p] subchannel list %p index %" PRIuPTR
": Created subchannel %p for address uri %s",
@@ -550,8 +552,7 @@ SubchannelList<SubchannelListType, SubchannelDataType>::SubchannelList(
address_uri);
gpr_free(address_uri);
}
- subchannels_.emplace_back(this, addresses->user_data_vtable,
- addresses->addresses[i], subchannel, combiner);
+ subchannels_.emplace_back(this, addresses[i], subchannel, combiner);
}
}
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 59d57295d4..3c25de2386 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
@@ -79,6 +79,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
@@ -116,9 +117,10 @@ namespace {
class XdsLb : public LoadBalancingPolicy {
public:
- XdsLb(const grpc_lb_addresses* addresses, const Args& args);
+ explicit XdsLb(const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -155,9 +157,6 @@ class XdsLb : public LoadBalancingPolicy {
// Our on_complete closure and the original one.
grpc_closure on_complete;
grpc_closure* original_on_complete;
- // The LB token associated with the pick. This is set via user_data in
- // the pick.
- grpc_mdelem lb_token;
// Stats for client-side load reporting.
RefCountedPtr<XdsLbClientStats> client_stats;
// Next pending pick.
@@ -165,8 +164,7 @@ class XdsLb : public LoadBalancingPolicy {
};
/// Contains a call to the LB server and all the data related to the call.
- class BalancerCallState
- : public InternallyRefCountedWithTracing<BalancerCallState> {
+ class BalancerCallState : public InternallyRefCounted<BalancerCallState> {
public:
explicit BalancerCallState(
RefCountedPtr<LoadBalancingPolicy> parent_xdslb_policy);
@@ -198,7 +196,6 @@ class XdsLb : public LoadBalancingPolicy {
static bool LoadReportCountersAreZero(xds_grpclb_request* request);
static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error);
- static void ClientLoadReportDoneLocked(void* arg, grpc_error* error);
static void OnInitialRequestSentLocked(void* arg, grpc_error* error);
static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error);
static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error);
@@ -257,7 +254,7 @@ class XdsLb : public LoadBalancingPolicy {
grpc_error* error);
// Pending pick methods.
- static void PendingPickSetMetadataAndContext(PendingPick* pp);
+ static void PendingPickCleanup(PendingPick* pp);
PendingPick* PendingPickCreate(PickState* pick);
void AddPendingPick(PendingPick* pp);
static void OnPendingPickComplete(void* arg, grpc_error* error);
@@ -320,7 +317,7 @@ class XdsLb : public LoadBalancingPolicy {
// 0 means not using fallback.
int lb_fallback_timeout_ms_ = 0;
// The backend addresses from the resolver.
- grpc_lb_addresses* fallback_backend_addresses_ = nullptr;
+ UniquePtr<ServerAddressList> fallback_backend_addresses_;
// Fallback timer.
bool fallback_timer_callback_pending_ = false;
grpc_timer lb_fallback_timer_;
@@ -340,47 +337,15 @@ class XdsLb : public LoadBalancingPolicy {
// serverlist parsing code
//
-// vtable for LB tokens in grpc_lb_addresses
-void* lb_token_copy(void* token) {
- return token == nullptr
- ? nullptr
- : (void*)GRPC_MDELEM_REF(grpc_mdelem{(uintptr_t)token}).payload;
-}
-void lb_token_destroy(void* token) {
- if (token != nullptr) {
- GRPC_MDELEM_UNREF(grpc_mdelem{(uintptr_t)token});
- }
-}
-int lb_token_cmp(void* token1, void* token2) {
- if (token1 > token2) return 1;
- if (token1 < token2) return -1;
- return 0;
-}
-const grpc_lb_user_data_vtable lb_token_vtable = {
- lb_token_copy, lb_token_destroy, lb_token_cmp};
-
// Returns the backend addresses extracted from the given addresses.
-grpc_lb_addresses* ExtractBackendAddresses(const grpc_lb_addresses* addresses) {
- // First pass: count the number of backend addresses.
- size_t num_backends = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) {
- ++num_backends;
+UniquePtr<ServerAddressList> ExtractBackendAddresses(
+ const ServerAddressList& addresses) {
+ auto backend_addresses = MakeUnique<ServerAddressList>();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (!addresses[i].IsBalancer()) {
+ backend_addresses->emplace_back(addresses[i]);
}
}
- // Second pass: actually populate the addresses and (empty) LB tokens.
- grpc_lb_addresses* backend_addresses =
- grpc_lb_addresses_create(num_backends, &lb_token_vtable);
- size_t num_copied = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) continue;
- const grpc_resolved_address* addr = &addresses->addresses[i].address;
- grpc_lb_addresses_set_address(backend_addresses, num_copied, &addr->addr,
- addr->len, false /* is_balancer */,
- nullptr /* balancer_name */,
- (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload);
- ++num_copied;
- }
return backend_addresses;
}
@@ -430,56 +395,17 @@ void ParseServer(const xds_grpclb_server* server, grpc_resolved_address* addr) {
}
// Returns addresses extracted from \a serverlist.
-grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) {
- size_t num_valid = 0;
- /* first pass: count how many are valid in order to allocate the necessary
- * memory in a single block */
+UniquePtr<ServerAddressList> ProcessServerlist(
+ const xds_grpclb_serverlist* serverlist) {
+ auto addresses = MakeUnique<ServerAddressList>();
for (size_t i = 0; i < serverlist->num_servers; ++i) {
- if (IsServerValid(serverlist->servers[i], i, true)) ++num_valid;
- }
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_valid, &lb_token_vtable);
- /* second pass: actually populate the addresses and LB tokens (aka user data
- * to the outside world) to be read by the child policy during its creation.
- * Given that the validity tests are very cheap, they are performed again
- * instead of marking the valid ones during the first pass, as this would
- * incurr in an allocation due to the arbitrary number of server */
- size_t addr_idx = 0;
- for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) {
- const xds_grpclb_server* server = serverlist->servers[sl_idx];
- if (!IsServerValid(serverlist->servers[sl_idx], sl_idx, false)) continue;
- GPR_ASSERT(addr_idx < num_valid);
- /* address processing */
+ const xds_grpclb_server* server = serverlist->servers[i];
+ if (!IsServerValid(serverlist->servers[i], i, false)) continue;
grpc_resolved_address addr;
ParseServer(server, &addr);
- /* lb token processing */
- void* user_data;
- if (server->has_load_balance_token) {
- const size_t lb_token_max_length =
- GPR_ARRAY_SIZE(server->load_balance_token);
- const size_t lb_token_length =
- strnlen(server->load_balance_token, lb_token_max_length);
- grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
- server->load_balance_token, lb_token_length);
- user_data =
- (void*)grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr)
- .payload;
- } else {
- char* uri = grpc_sockaddr_to_uri(&addr);
- gpr_log(GPR_INFO,
- "Missing LB token for backend address '%s'. The empty token will "
- "be used instead",
- uri);
- gpr_free(uri);
- user_data = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
- }
- grpc_lb_addresses_set_address(lb_addresses, addr_idx, &addr.addr, addr.len,
- false /* is_balancer */,
- nullptr /* balancer_name */, user_data);
- ++addr_idx;
+ addresses->emplace_back(addr, nullptr);
}
- GPR_ASSERT(addr_idx == num_valid);
- return lb_addresses;
+ return addresses;
}
//
@@ -488,7 +414,7 @@ grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) {
XdsLb::BalancerCallState::BalancerCallState(
RefCountedPtr<LoadBalancingPolicy> parent_xdslb_policy)
- : InternallyRefCountedWithTracing<BalancerCallState>(&grpc_lb_xds_trace),
+ : InternallyRefCounted<BalancerCallState>(&grpc_lb_xds_trace),
xdslb_policy_(std::move(parent_xdslb_policy)) {
GPR_ASSERT(xdslb_policy_ != nullptr);
GPR_ASSERT(!xdslb_policy()->shutting_down_);
@@ -667,6 +593,7 @@ bool XdsLb::BalancerCallState::LoadReportCountersAreZero(
(drop_entries == nullptr || drop_entries->empty());
}
+// TODO(vpowar): Use LRS to send the client Load Report.
void XdsLb::BalancerCallState::SendClientLoadReportLocked() {
// Construct message payload.
GPR_ASSERT(send_message_payload_ == nullptr);
@@ -684,38 +611,8 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() {
} else {
last_client_load_report_counters_were_zero_ = false;
}
- grpc_slice request_payload_slice = xds_grpclb_request_encode(request);
- send_message_payload_ =
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
- grpc_slice_unref_internal(request_payload_slice);
+ // TODO(vpowar): Send the report on LRS stream.
xds_grpclb_request_destroy(request);
- // Send the report.
- grpc_op op;
- memset(&op, 0, sizeof(op));
- op.op = GRPC_OP_SEND_MESSAGE;
- op.data.send_message.send_message = send_message_payload_;
- GRPC_CLOSURE_INIT(&client_load_report_closure_, ClientLoadReportDoneLocked,
- this, grpc_combiner_scheduler(xdslb_policy()->combiner()));
- grpc_call_error call_error = grpc_call_start_batch_and_execute(
- lb_call_, &op, 1, &client_load_report_closure_);
- if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
- gpr_log(GPR_ERROR, "[xdslb %p] call_error=%d", xdslb_policy_.get(),
- call_error);
- GPR_ASSERT(GRPC_CALL_OK == call_error);
- }
-}
-
-void XdsLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg,
- grpc_error* error) {
- BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
- XdsLb* xdslb_policy = lb_calld->xdslb_policy();
- grpc_byte_buffer_destroy(lb_calld->send_message_payload_);
- lb_calld->send_message_payload_ = nullptr;
- if (error != GRPC_ERROR_NONE || lb_calld != xdslb_policy->lb_calld_.get()) {
- lb_calld->Unref(DEBUG_LOCATION, "client_load_report");
- return;
- }
- lb_calld->ScheduleNextClientLoadReportLocked();
}
void XdsLb::BalancerCallState::OnInitialRequestSentLocked(void* arg,
@@ -819,8 +716,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked(
xds_grpclb_destroy_serverlist(xdslb_policy->serverlist_);
} else {
/* or dispose of the fallback */
- grpc_lb_addresses_destroy(xdslb_policy->fallback_backend_addresses_);
- xdslb_policy->fallback_backend_addresses_ = nullptr;
+ xdslb_policy->fallback_backend_addresses_.reset();
if (xdslb_policy->fallback_timer_callback_pending_) {
grpc_timer_cancel(&xdslb_policy->lb_fallback_timer_);
}
@@ -906,31 +802,15 @@ void XdsLb::BalancerCallState::OnBalancerStatusReceivedLocked(
// helper code for creating balancer channel
//
-grpc_lb_addresses* ExtractBalancerAddresses(
- const grpc_lb_addresses* addresses) {
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
- }
- // There must be at least one balancer address, or else the
- // client_channel would not have chosen this LB policy.
- GPR_ASSERT(num_grpclb_addrs > 0);
- grpc_lb_addresses* lb_addresses =
- grpc_lb_addresses_create(num_grpclb_addrs, nullptr);
- size_t lb_addresses_idx = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (!addresses->addresses[i].is_balancer) continue;
- if (GPR_UNLIKELY(addresses->addresses[i].user_data != nullptr)) {
- gpr_log(GPR_ERROR,
- "This LB policy doesn't support user data. It will be ignored");
+UniquePtr<ServerAddressList> ExtractBalancerAddresses(
+ const ServerAddressList& addresses) {
+ auto balancer_addresses = MakeUnique<ServerAddressList>();
+ for (size_t i = 0; i < addresses.size(); ++i) {
+ if (addresses[i].IsBalancer()) {
+ balancer_addresses->emplace_back(addresses[i]);
}
- grpc_lb_addresses_set_address(
- lb_addresses, lb_addresses_idx++, addresses->addresses[i].address.addr,
- addresses->addresses[i].address.len, false /* is balancer */,
- addresses->addresses[i].balancer_name, nullptr /* user data */);
}
- GPR_ASSERT(num_grpclb_addrs == lb_addresses_idx);
- return lb_addresses;
+ return balancer_addresses;
}
/* Returns the channel args for the LB channel, used to create a bidirectional
@@ -942,10 +822,11 @@ grpc_lb_addresses* ExtractBalancerAddresses(
* above the grpclb policy.
* - \a args: other args inherited from the xds policy. */
grpc_channel_args* BuildBalancerChannelArgs(
- const grpc_lb_addresses* addresses,
+ const ServerAddressList& addresses,
FakeResolverResponseGenerator* response_generator,
const grpc_channel_args* args) {
- grpc_lb_addresses* lb_addresses = ExtractBalancerAddresses(addresses);
+ UniquePtr<ServerAddressList> balancer_addresses =
+ ExtractBalancerAddresses(addresses);
// Channel args to remove.
static const char* args_to_remove[] = {
// LB policy name, since we want to use the default (pick_first) in
@@ -963,7 +844,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
// is_balancer=true. We need the LB channel to return addresses with
// is_balancer=false so that it does not wind up recursively using the
// xds LB policy, as per the special case logic in client_channel.c.
- GRPC_ARG_LB_ADDRESSES,
+ GRPC_ARG_SERVER_ADDRESS_LIST,
// The fake resolver response generator, because we are replacing it
// with the one from the xds policy, used to propagate updates to
// the LB channel.
@@ -979,10 +860,10 @@ grpc_channel_args* BuildBalancerChannelArgs(
};
// Channel args to add.
const grpc_arg args_to_add[] = {
- // New LB addresses.
+ // New server address list.
// Note that we pass these in both when creating the LB channel
// and via the fake resolver. The latter is what actually gets used.
- grpc_lb_addresses_create_channel_arg(lb_addresses),
+ CreateServerAddressListChannelArg(balancer_addresses.get()),
// The fake resolver response generator, which we use to inject
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
@@ -1000,18 +881,15 @@ grpc_channel_args* BuildBalancerChannelArgs(
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
GPR_ARRAY_SIZE(args_to_add));
// Make any necessary modifications for security.
- new_args = grpc_lb_policy_xds_modify_lb_channel_args(new_args);
- // Clean up.
- grpc_lb_addresses_destroy(lb_addresses);
- return new_args;
+ return grpc_lb_policy_xds_modify_lb_channel_args(new_args);
}
//
// ctor and dtor
//
-XdsLb::XdsLb(const grpc_lb_addresses* addresses,
- const LoadBalancingPolicy::Args& args)
+// TODO(vishalpowar): Use lb_config in args to configure LB policy.
+XdsLb::XdsLb(const LoadBalancingPolicy::Args& args)
: LoadBalancingPolicy(args),
response_generator_(MakeRefCounted<FakeResolverResponseGenerator>()),
lb_call_backoff_(
@@ -1067,9 +945,6 @@ XdsLb::~XdsLb() {
if (serverlist_ != nullptr) {
xds_grpclb_destroy_serverlist(serverlist_);
}
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
grpc_subchannel_index_unref();
}
@@ -1117,7 +992,6 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
while ((pp = pending_picks_) != nullptr) {
pending_picks_ = pp->next;
pp->pick->on_complete = pp->original_on_complete;
- pp->pick->user_data = nullptr;
grpc_error* error = GRPC_ERROR_NONE;
if (new_policy->PickLocked(pp->pick, &error)) {
// Synchronous return; schedule closure.
@@ -1270,21 +1144,16 @@ void XdsLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
}
void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
- const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
- if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
+ const ServerAddressList* addresses = FindServerAddressListChannelArg(&args);
+ if (addresses == nullptr) {
// Ignore this update.
gpr_log(GPR_ERROR,
"[xdslb %p] No valid LB addresses channel arg in update, ignoring.",
this);
return;
}
- const grpc_lb_addresses* addresses =
- static_cast<const grpc_lb_addresses*>(arg->value.pointer.p);
// Update fallback address list.
- if (fallback_backend_addresses_ != nullptr) {
- grpc_lb_addresses_destroy(fallback_backend_addresses_);
- }
- fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
+ fallback_backend_addresses_ = ExtractBackendAddresses(*addresses);
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
// since we use this to trigger the client_load_reporting filter.
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
@@ -1295,7 +1164,7 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
// Construct args for balancer channel.
grpc_channel_args* lb_channel_args =
- BuildBalancerChannelArgs(addresses, response_generator_.get(), &args);
+ BuildBalancerChannelArgs(*addresses, response_generator_.get(), &args);
// Create balancer channel if needed.
if (lb_channel_ == nullptr) {
char* uri_str;
@@ -1314,7 +1183,8 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
grpc_channel_args_destroy(lb_channel_args);
}
-void XdsLb::UpdateLocked(const grpc_channel_args& args) {
+// TODO(vishalpowar): Use lb_config to configure LB policy.
+void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) {
ProcessChannelArgsLocked(args);
// Update the existing child policy.
// Note: We have disabled fallback mode in the code, so this child policy must
@@ -1485,37 +1355,15 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
// PendingPick
//
-// Adds lb_token of selected subchannel (address) to the call's initial
-// metadata.
-grpc_error* AddLbTokenToInitialMetadata(
- grpc_mdelem lb_token, grpc_linked_mdelem* lb_token_mdelem_storage,
- grpc_metadata_batch* initial_metadata) {
- GPR_ASSERT(lb_token_mdelem_storage != nullptr);
- GPR_ASSERT(!GRPC_MDISNULL(lb_token));
- return grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
- lb_token);
-}
-
// Destroy function used when embedding client stats in call context.
void DestroyClientStats(void* arg) {
static_cast<XdsLbClientStats*>(arg)->Unref();
}
-void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
- /* if connected_subchannel is nullptr, no pick has been made by the
- * child policy (e.g., all addresses failed to connect). There won't be any
- * user_data/token available */
+void XdsLb::PendingPickCleanup(PendingPick* pp) {
+ // If connected_subchannel is nullptr, no pick has been made by the
+ // child policy (e.g., all addresses failed to connect).
if (pp->pick->connected_subchannel != nullptr) {
- if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) {
- AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(pp->lb_token),
- &pp->pick->lb_token_mdelem_storage,
- pp->pick->initial_metadata);
- } else {
- gpr_log(GPR_ERROR,
- "[xdslb %p] No LB token for connected subchannel pick %p",
- pp->xdslb_policy, pp->pick);
- abort();
- }
// Pass on client stats via context. Passes ownership of the reference.
if (pp->client_stats != nullptr) {
pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
@@ -1533,7 +1381,7 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
* order to unref the child policy instance upon its invocation */
void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) {
PendingPick* pp = static_cast<PendingPick*>(arg);
- PendingPickSetMetadataAndContext(pp);
+ PendingPickCleanup(pp);
GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_REF(error));
Delete(pp);
}
@@ -1565,16 +1413,14 @@ void XdsLb::AddPendingPick(PendingPick* pp) {
// completion callback even if the pick is available immediately.
bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp,
grpc_error** error) {
- // Set client_stats and user_data.
+ // Set client_stats.
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
pp->client_stats = lb_calld_->client_stats()->Ref();
}
- GPR_ASSERT(pp->pick->user_data == nullptr);
- pp->pick->user_data = (void**)&pp->lb_token;
// Pick via the child policy.
bool pick_done = child_policy_->PickLocked(pp->pick, error);
if (pick_done) {
- PendingPickSetMetadataAndContext(pp);
+ PendingPickCleanup(pp);
if (force_async) {
GRPC_CLOSURE_SCHED(pp->original_on_complete, *error);
*error = GRPC_ERROR_NONE;
@@ -1636,20 +1482,19 @@ void XdsLb::CreateChildPolicyLocked(const Args& args) {
}
grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
- grpc_lb_addresses* addresses;
bool is_backend_from_grpclb_load_balancer = false;
// This should never be invoked if we do not have serverlist_, as fallback
// mode is disabled for xDS plugin.
GPR_ASSERT(serverlist_ != nullptr);
GPR_ASSERT(serverlist_->num_servers > 0);
- addresses = ProcessServerlist(serverlist_);
- is_backend_from_grpclb_load_balancer = true;
+ UniquePtr<ServerAddressList> addresses = ProcessServerlist(serverlist_);
GPR_ASSERT(addresses != nullptr);
- // Replace the LB addresses in the channel args that we pass down to
+ is_backend_from_grpclb_load_balancer = true;
+ // Replace the server address list in the channel args that we pass down to
// the subchannel.
- static const char* keys_to_remove[] = {GRPC_ARG_LB_ADDRESSES};
+ static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
const grpc_arg args_to_add[] = {
- grpc_lb_addresses_create_channel_arg(addresses),
+ CreateServerAddressListChannelArg(addresses.get()),
// A channel arg indicating if the target is a backend inferred from a
// grpclb load balancer.
grpc_channel_arg_integer_create(
@@ -1659,7 +1504,6 @@ grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
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));
- grpc_lb_addresses_destroy(addresses);
return args;
}
@@ -1672,7 +1516,8 @@ void XdsLb::CreateOrUpdateChildPolicyLocked() {
gpr_log(GPR_INFO, "[xdslb %p] Updating the child policy %p", this,
child_policy_.get());
}
- child_policy_->UpdateLocked(*args);
+ // TODO(vishalpowar): Pass the correct LB config.
+ child_policy_->UpdateLocked(*args, nullptr);
} else {
LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = combiner();
@@ -1792,22 +1637,21 @@ class XdsFactory : public LoadBalancingPolicyFactory {
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const LoadBalancingPolicy::Args& args) const override {
/* Count the number of gRPC-LB addresses. There must be at least one. */
- const grpc_arg* arg =
- grpc_channel_args_find(args.args, GRPC_ARG_LB_ADDRESSES);
- if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
- return nullptr;
- }
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
- size_t num_grpclb_addrs = 0;
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (addresses->addresses[i].is_balancer) ++num_grpclb_addrs;
+ const ServerAddressList* addresses =
+ FindServerAddressListChannelArg(args.args);
+ if (addresses == nullptr) return nullptr;
+ bool found_balancer_address = false;
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ if ((*addresses)[i].IsBalancer()) {
+ found_balancer_address = true;
+ break;
+ }
}
- if (num_grpclb_addrs == 0) return nullptr;
- return OrphanablePtr<LoadBalancingPolicy>(New<XdsLb>(addresses, args));
+ if (!found_balancer_address) return nullptr;
+ return OrphanablePtr<LoadBalancingPolicy>(New<XdsLb>(args));
}
- const char* name() const override { return "xds"; }
+ const char* name() const override { return "xds_experimental"; }
};
} // namespace
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
index 32c4acc8a3..f713b7f563 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel.h
@@ -21,7 +21,7 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include <grpc/impl/codegen/grpc_types.h>
/// Makes any necessary modifications to \a args for use in the xds
/// balancer channel.
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
index 5ab72efce4..55c646e6ee 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc
@@ -25,6 +25,7 @@
#include <string.h>
#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -41,22 +42,23 @@ int BalancerNameCmp(const grpc_core::UniquePtr<char>& a,
}
RefCountedPtr<TargetAuthorityTable> CreateTargetAuthorityTable(
- grpc_lb_addresses* addresses) {
+ const ServerAddressList& addresses) {
TargetAuthorityTable::Entry* target_authority_entries =
- static_cast<TargetAuthorityTable::Entry*>(gpr_zalloc(
- sizeof(*target_authority_entries) * addresses->num_addresses));
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
+ static_cast<TargetAuthorityTable::Entry*>(
+ gpr_zalloc(sizeof(*target_authority_entries) * addresses.size()));
+ for (size_t i = 0; i < addresses.size(); ++i) {
char* addr_str;
- GPR_ASSERT(grpc_sockaddr_to_string(
- &addr_str, &addresses->addresses[i].address, true) > 0);
+ GPR_ASSERT(
+ grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true) > 0);
target_authority_entries[i].key = grpc_slice_from_copied_string(addr_str);
- target_authority_entries[i].value.reset(
- gpr_strdup(addresses->addresses[i].balancer_name));
gpr_free(addr_str);
+ char* balancer_name = grpc_channel_arg_get_string(grpc_channel_args_find(
+ addresses[i].args(), GRPC_ARG_ADDRESS_BALANCER_NAME));
+ target_authority_entries[i].value.reset(gpr_strdup(balancer_name));
}
RefCountedPtr<TargetAuthorityTable> target_authority_table =
- TargetAuthorityTable::Create(addresses->num_addresses,
- target_authority_entries, BalancerNameCmp);
+ TargetAuthorityTable::Create(addresses.size(), target_authority_entries,
+ BalancerNameCmp);
gpr_free(target_authority_entries);
return target_authority_table;
}
@@ -71,13 +73,12 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args(
grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
// Add arg for targets info table.
- const grpc_arg* arg = grpc_channel_args_find(args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(arg != nullptr);
- GPR_ASSERT(arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(arg->value.pointer.p);
+ grpc_core::ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(args);
+ GPR_ASSERT(addresses != nullptr);
grpc_core::RefCountedPtr<grpc_core::TargetAuthorityTable>
- target_authority_table = grpc_core::CreateTargetAuthorityTable(addresses);
+ target_authority_table =
+ grpc_core::CreateTargetAuthorityTable(*addresses);
args_to_add[num_args_to_add++] =
grpc_core::CreateTargetAuthorityTableChannelArg(
target_authority_table.get());
@@ -86,22 +87,18 @@ grpc_channel_args* grpc_lb_policy_xds_modify_lb_channel_args(
// bearer token credentials.
grpc_channel_credentials* channel_credentials =
grpc_channel_credentials_find_in_args(args);
- grpc_channel_credentials* creds_sans_call_creds = nullptr;
+ grpc_core::RefCountedPtr<grpc_channel_credentials> creds_sans_call_creds;
if (channel_credentials != nullptr) {
creds_sans_call_creds =
- grpc_channel_credentials_duplicate_without_call_credentials(
- channel_credentials);
+ channel_credentials->duplicate_without_call_credentials();
GPR_ASSERT(creds_sans_call_creds != nullptr);
args_to_remove[num_args_to_remove++] = GRPC_ARG_CHANNEL_CREDENTIALS;
args_to_add[num_args_to_add++] =
- grpc_channel_credentials_to_arg(creds_sans_call_creds);
+ grpc_channel_credentials_to_arg(creds_sans_call_creds.get());
}
grpc_channel_args* result = grpc_channel_args_copy_and_add_and_remove(
args, args_to_remove, num_args_to_remove, args_to_add, num_args_to_add);
// Clean up.
grpc_channel_args_destroy(args);
- if (creds_sans_call_creds != nullptr) {
- grpc_channel_credentials_unref(creds_sans_call_creds);
- }
return result;
}
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h
index 9d08defa7e..6704995641 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h
@@ -25,7 +25,7 @@
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_client_stats.h"
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#define XDS_SERVICE_NAME_MAX_LENGTH 128
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.cc b/src/core/ext/filters/client_channel/lb_policy_factory.cc
deleted file mode 100644
index 5c6363d295..0000000000
--- a/src/core/ext/filters/client_channel/lb_policy_factory.cc
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- *
- * 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 <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/lib/channel/channel_args.h"
-
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
-#include "src/core/ext/filters/client_channel/parse_address.h"
-
-grpc_lb_addresses* grpc_lb_addresses_create(
- size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable) {
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(gpr_zalloc(sizeof(grpc_lb_addresses)));
- addresses->num_addresses = num_addresses;
- addresses->user_data_vtable = user_data_vtable;
- const size_t addresses_size = sizeof(grpc_lb_address) * num_addresses;
- addresses->addresses =
- static_cast<grpc_lb_address*>(gpr_zalloc(addresses_size));
- return addresses;
-}
-
-grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses) {
- grpc_lb_addresses* new_addresses = grpc_lb_addresses_create(
- addresses->num_addresses, addresses->user_data_vtable);
- memcpy(new_addresses->addresses, addresses->addresses,
- sizeof(grpc_lb_address) * addresses->num_addresses);
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- if (new_addresses->addresses[i].balancer_name != nullptr) {
- new_addresses->addresses[i].balancer_name =
- gpr_strdup(new_addresses->addresses[i].balancer_name);
- }
- if (new_addresses->addresses[i].user_data != nullptr) {
- new_addresses->addresses[i].user_data = addresses->user_data_vtable->copy(
- new_addresses->addresses[i].user_data);
- }
- }
- return new_addresses;
-}
-
-void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
- const void* address, size_t address_len,
- bool is_balancer, const char* balancer_name,
- void* user_data) {
- GPR_ASSERT(index < addresses->num_addresses);
- if (user_data != nullptr) GPR_ASSERT(addresses->user_data_vtable != nullptr);
- grpc_lb_address* target = &addresses->addresses[index];
- memcpy(target->address.addr, address, address_len);
- target->address.len = static_cast<socklen_t>(address_len);
- target->is_balancer = is_balancer;
- target->balancer_name = gpr_strdup(balancer_name);
- target->user_data = user_data;
-}
-
-bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses,
- size_t index, const grpc_uri* uri,
- bool is_balancer,
- const char* balancer_name,
- void* user_data) {
- grpc_resolved_address address;
- if (!grpc_parse_uri(uri, &address)) return false;
- grpc_lb_addresses_set_address(addresses, index, address.addr, address.len,
- is_balancer, balancer_name, user_data);
- return true;
-}
-
-int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
- const grpc_lb_addresses* addresses2) {
- if (addresses1->num_addresses > addresses2->num_addresses) return 1;
- if (addresses1->num_addresses < addresses2->num_addresses) return -1;
- if (addresses1->user_data_vtable > addresses2->user_data_vtable) return 1;
- if (addresses1->user_data_vtable < addresses2->user_data_vtable) return -1;
- for (size_t i = 0; i < addresses1->num_addresses; ++i) {
- const grpc_lb_address* target1 = &addresses1->addresses[i];
- const grpc_lb_address* target2 = &addresses2->addresses[i];
- if (target1->address.len > target2->address.len) return 1;
- if (target1->address.len < target2->address.len) return -1;
- int retval = memcmp(target1->address.addr, target2->address.addr,
- target1->address.len);
- if (retval != 0) return retval;
- if (target1->is_balancer > target2->is_balancer) return 1;
- if (target1->is_balancer < target2->is_balancer) return -1;
- const char* balancer_name1 =
- target1->balancer_name != nullptr ? target1->balancer_name : "";
- const char* balancer_name2 =
- target2->balancer_name != nullptr ? target2->balancer_name : "";
- retval = strcmp(balancer_name1, balancer_name2);
- if (retval != 0) return retval;
- if (addresses1->user_data_vtable != nullptr) {
- retval = addresses1->user_data_vtable->cmp(target1->user_data,
- target2->user_data);
- if (retval != 0) return retval;
- }
- }
- return 0;
-}
-
-void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses) {
- for (size_t i = 0; i < addresses->num_addresses; ++i) {
- gpr_free(addresses->addresses[i].balancer_name);
- if (addresses->addresses[i].user_data != nullptr) {
- addresses->user_data_vtable->destroy(addresses->addresses[i].user_data);
- }
- }
- gpr_free(addresses->addresses);
- gpr_free(addresses);
-}
-
-static void* lb_addresses_copy(void* addresses) {
- return grpc_lb_addresses_copy(static_cast<grpc_lb_addresses*>(addresses));
-}
-static void lb_addresses_destroy(void* addresses) {
- grpc_lb_addresses_destroy(static_cast<grpc_lb_addresses*>(addresses));
-}
-static int lb_addresses_cmp(void* addresses1, void* addresses2) {
- return grpc_lb_addresses_cmp(static_cast<grpc_lb_addresses*>(addresses1),
- static_cast<grpc_lb_addresses*>(addresses2));
-}
-static const grpc_arg_pointer_vtable lb_addresses_arg_vtable = {
- lb_addresses_copy, lb_addresses_destroy, lb_addresses_cmp};
-
-grpc_arg grpc_lb_addresses_create_channel_arg(
- const grpc_lb_addresses* addresses) {
- return grpc_channel_arg_pointer_create(
- (char*)GRPC_ARG_LB_ADDRESSES, (void*)addresses, &lb_addresses_arg_vtable);
-}
-
-grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
- const grpc_channel_args* channel_args) {
- const grpc_arg* lb_addresses_arg =
- grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES);
- if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER)
- return nullptr;
- return static_cast<grpc_lb_addresses*>(lb_addresses_arg->value.pointer.p);
-}
-
-bool grpc_lb_addresses_contains_balancer_address(
- const grpc_lb_addresses& addresses) {
- for (size_t i = 0; i < addresses.num_addresses; ++i) {
- if (addresses.addresses[i].is_balancer) return true;
- }
- return false;
-}
diff --git a/src/core/ext/filters/client_channel/lb_policy_factory.h b/src/core/ext/filters/client_channel/lb_policy_factory.h
index a59deadb26..a165ebafab 100644
--- a/src/core/ext/filters/client_channel/lb_policy_factory.h
+++ b/src/core/ext/filters/client_channel/lb_policy_factory.h
@@ -21,91 +21,9 @@
#include <grpc/support/port_platform.h>
-#include "src/core/lib/iomgr/resolve_address.h"
-
-#include "src/core/ext/filters/client_channel/client_channel_factory.h"
#include "src/core/ext/filters/client_channel/lb_policy.h"
-#include "src/core/lib/uri/uri_parser.h"
-
-//
-// representation of an LB address
-//
-
-// Channel arg key for grpc_lb_addresses.
-#define GRPC_ARG_LB_ADDRESSES "grpc.lb_addresses"
-
-/** A resolved address alongside any LB related information associated with it.
- * \a user_data, if not NULL, contains opaque data meant to be consumed by the
- * gRPC LB policy. Note that no all LB policies support \a user_data as input.
- * Those who don't will simply ignore it and will correspondingly return NULL in
- * their namesake pick() output argument. */
-// TODO(roth): Once we figure out a better way of handling user_data in
-// LB policies, convert these structs to C++ classes.
-typedef struct grpc_lb_address {
- grpc_resolved_address address;
- bool is_balancer;
- char* balancer_name; /* For secure naming. */
- void* user_data;
-} grpc_lb_address;
-
-typedef struct grpc_lb_user_data_vtable {
- void* (*copy)(void*);
- void (*destroy)(void*);
- int (*cmp)(void*, void*);
-} grpc_lb_user_data_vtable;
-
-typedef struct grpc_lb_addresses {
- size_t num_addresses;
- grpc_lb_address* addresses;
- const grpc_lb_user_data_vtable* user_data_vtable;
-} grpc_lb_addresses;
-
-/** Returns a grpc_addresses struct with enough space for
- \a num_addresses addresses. The \a user_data_vtable argument may be
- NULL if no user data will be added. */
-grpc_lb_addresses* grpc_lb_addresses_create(
- size_t num_addresses, const grpc_lb_user_data_vtable* user_data_vtable);
-
-/** Creates a copy of \a addresses. */
-grpc_lb_addresses* grpc_lb_addresses_copy(const grpc_lb_addresses* addresses);
-
-/** Sets the value of the address at index \a index of \a addresses.
- * \a address is a socket address of length \a address_len. */
-void grpc_lb_addresses_set_address(grpc_lb_addresses* addresses, size_t index,
- const void* address, size_t address_len,
- bool is_balancer, const char* balancer_name,
- void* user_data);
-
-/** Sets the value of the address at index \a index of \a addresses from \a uri.
- * Returns true upon success, false otherwise. */
-bool grpc_lb_addresses_set_address_from_uri(grpc_lb_addresses* addresses,
- size_t index, const grpc_uri* uri,
- bool is_balancer,
- const char* balancer_name,
- void* user_data);
-
-/** Compares \a addresses1 and \a addresses2. */
-int grpc_lb_addresses_cmp(const grpc_lb_addresses* addresses1,
- const grpc_lb_addresses* addresses2);
-
-/** Destroys \a addresses. */
-void grpc_lb_addresses_destroy(grpc_lb_addresses* addresses);
-
-/** Returns a channel arg containing \a addresses. */
-grpc_arg grpc_lb_addresses_create_channel_arg(
- const grpc_lb_addresses* addresses);
-
-/** Returns the \a grpc_lb_addresses instance in \a channel_args or NULL */
-grpc_lb_addresses* grpc_lb_addresses_find_channel_arg(
- const grpc_channel_args* channel_args);
-
-// Returns true if addresses contains at least one balancer address.
-bool grpc_lb_addresses_contains_balancer_address(
- const grpc_lb_addresses& addresses);
-
-//
-// LB policy factory
-//
+#include "src/core/lib/gprpp/abstract.h"
+#include "src/core/lib/gprpp/orphanable.h"
namespace grpc_core {
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc
index d651b1120d..ad459c9c8c 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.cc
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc
@@ -94,4 +94,9 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
return factory->CreateLoadBalancingPolicy(args);
}
+bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) {
+ GPR_ASSERT(g_state != nullptr);
+ return g_state->GetLoadBalancingPolicyFactory(name) != nullptr;
+}
+
} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h
index 2e9bb061ed..338f7c9f69 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.h
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.h
@@ -47,6 +47,10 @@ class LoadBalancingPolicyRegistry {
/// Creates an LB policy of the type specified by \a name.
static OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const char* name, const LoadBalancingPolicy::Args& args);
+
+ /// Returns true if the LB policy factory specified by \a name exists in this
+ /// registry.
+ static bool LoadBalancingPolicyExists(const char* name);
};
} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/method_params.cc b/src/core/ext/filters/client_channel/method_params.cc
deleted file mode 100644
index 1f116bb67d..0000000000
--- a/src/core/ext/filters/client_channel/method_params.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *
- * 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 <stdio.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/ext/filters/client_channel/method_params.h"
-#include "src/core/lib/channel/status_util.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/gprpp/memory.h"
-
-// As per the retry design, we do not allow more than 5 retry attempts.
-#define MAX_MAX_RETRY_ATTEMPTS 5
-
-namespace grpc_core {
-namespace internal {
-
-namespace {
-
-bool ParseWaitForReady(
- grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
- if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
- return false;
- }
- *wait_for_ready = field->type == GRPC_JSON_TRUE
- ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
- : ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
- return true;
-}
-
-// Parses a JSON field of the form generated for a google.proto.Duration
-// proto message, as per:
-// https://developers.google.com/protocol-buffers/docs/proto3#json
-bool ParseDuration(grpc_json* field, grpc_millis* duration) {
- if (field->type != GRPC_JSON_STRING) return false;
- size_t len = strlen(field->value);
- if (field->value[len - 1] != 's') return false;
- UniquePtr<char> buf(gpr_strdup(field->value));
- *(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
- char* decimal_point = strchr(buf.get(), '.');
- int nanos = 0;
- if (decimal_point != nullptr) {
- *decimal_point = '\0';
- nanos = gpr_parse_nonnegative_int(decimal_point + 1);
- if (nanos == -1) {
- return false;
- }
- int num_digits = static_cast<int>(strlen(decimal_point + 1));
- if (num_digits > 9) { // We don't accept greater precision than nanos.
- return false;
- }
- for (int i = 0; i < (9 - num_digits); ++i) {
- nanos *= 10;
- }
- }
- int seconds =
- decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
- if (seconds == -1) return false;
- *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
- return true;
-}
-
-UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
- grpc_json* field) {
- auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
- if (field->type != GRPC_JSON_OBJECT) return nullptr;
- for (grpc_json* sub_field = field->child; sub_field != nullptr;
- sub_field = sub_field->next) {
- if (sub_field->key == nullptr) return nullptr;
- if (strcmp(sub_field->key, "maxAttempts") == 0) {
- if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
- retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
- if (retry_policy->max_attempts <= 1) return nullptr;
- if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
- gpr_log(GPR_ERROR,
- "service config: clamped retryPolicy.maxAttempts at %d",
- MAX_MAX_RETRY_ATTEMPTS);
- retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
- }
- } else if (strcmp(sub_field->key, "initialBackoff") == 0) {
- if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
- if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
- return nullptr;
- }
- if (retry_policy->initial_backoff == 0) return nullptr;
- } else if (strcmp(sub_field->key, "maxBackoff") == 0) {
- if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
- if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
- return nullptr;
- }
- if (retry_policy->max_backoff == 0) return nullptr;
- } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
- if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
- if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
- 1) {
- return nullptr;
- }
- if (retry_policy->backoff_multiplier <= 0) return nullptr;
- } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
- if (!retry_policy->retryable_status_codes.Empty()) {
- return nullptr; // Duplicate.
- }
- if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
- for (grpc_json* element = sub_field->child; element != nullptr;
- element = element->next) {
- if (element->type != GRPC_JSON_STRING) return nullptr;
- grpc_status_code status;
- if (!grpc_status_code_from_string(element->value, &status)) {
- return nullptr;
- }
- retry_policy->retryable_status_codes.Add(status);
- }
- if (retry_policy->retryable_status_codes.Empty()) return nullptr;
- }
- }
- // Make sure required fields are set.
- if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
- retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
- retry_policy->retryable_status_codes.Empty()) {
- return nullptr;
- }
- return retry_policy;
-}
-
-} // namespace
-
-RefCountedPtr<ClientChannelMethodParams>
-ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
- RefCountedPtr<ClientChannelMethodParams> method_params =
- MakeRefCounted<ClientChannelMethodParams>();
- for (grpc_json* field = json->child; field != nullptr; field = field->next) {
- if (field->key == nullptr) continue;
- if (strcmp(field->key, "waitForReady") == 0) {
- if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
- return nullptr; // Duplicate.
- }
- if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
- return nullptr;
- }
- } else if (strcmp(field->key, "timeout") == 0) {
- if (method_params->timeout_ > 0) return nullptr; // Duplicate.
- if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
- } else if (strcmp(field->key, "retryPolicy") == 0) {
- if (method_params->retry_policy_ != nullptr) {
- return nullptr; // Duplicate.
- }
- method_params->retry_policy_ = ParseRetryPolicy(field);
- if (method_params->retry_policy_ == nullptr) return nullptr;
- }
- }
- return method_params;
-}
-
-} // namespace internal
-} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/method_params.h b/src/core/ext/filters/client_channel/method_params.h
deleted file mode 100644
index a31d360f17..0000000000
--- a/src/core/ext/filters/client_channel/method_params.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *
- * 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_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
-#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/lib/channel/status_util.h"
-#include "src/core/lib/gprpp/ref_counted.h"
-#include "src/core/lib/gprpp/ref_counted_ptr.h"
-#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
-#include "src/core/lib/json/json.h"
-
-namespace grpc_core {
-namespace internal {
-
-class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
- public:
- enum WaitForReady {
- WAIT_FOR_READY_UNSET = 0,
- WAIT_FOR_READY_FALSE,
- WAIT_FOR_READY_TRUE
- };
-
- struct RetryPolicy {
- int max_attempts = 0;
- grpc_millis initial_backoff = 0;
- grpc_millis max_backoff = 0;
- float backoff_multiplier = 0;
- StatusCodeSet retryable_status_codes;
- };
-
- /// Creates a method_parameters object from \a json.
- /// Intended for use with ServiceConfig::CreateMethodConfigTable().
- static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
- const grpc_json* json);
-
- grpc_millis timeout() const { return timeout_; }
- WaitForReady wait_for_ready() const { return wait_for_ready_; }
- const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
-
- private:
- // So New() can call our private ctor.
- template <typename T, typename... Args>
- friend T* grpc_core::New(Args&&... args);
-
- // So Delete() can call our private dtor.
- template <typename T>
- friend void grpc_core::Delete(T*);
-
- ClientChannelMethodParams() {}
- virtual ~ClientChannelMethodParams() {}
-
- grpc_millis timeout_ = 0;
- WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
- UniquePtr<RetryPolicy> retry_policy_;
-};
-
-} // namespace internal
-} // namespace grpc_core
-
-#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H */
diff --git a/src/core/ext/filters/client_channel/resolver.cc b/src/core/ext/filters/client_channel/resolver.cc
index cd11eeb9e4..601b08be24 100644
--- a/src/core/ext/filters/client_channel/resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver.cc
@@ -27,7 +27,7 @@ grpc_core::DebugOnlyTraceFlag grpc_trace_resolver_refcount(false,
namespace grpc_core {
Resolver::Resolver(grpc_combiner* combiner)
- : InternallyRefCountedWithTracing(&grpc_trace_resolver_refcount),
+ : InternallyRefCounted(&grpc_trace_resolver_refcount),
combiner_(GRPC_COMBINER_REF(combiner, "resolver")) {}
Resolver::~Resolver() { GRPC_COMBINER_UNREF(combiner_, "resolver"); }
diff --git a/src/core/ext/filters/client_channel/resolver.h b/src/core/ext/filters/client_channel/resolver.h
index e9acbb7c41..9da849a101 100644
--- a/src/core/ext/filters/client_channel/resolver.h
+++ b/src/core/ext/filters/client_channel/resolver.h
@@ -44,7 +44,7 @@ namespace grpc_core {
///
/// Note: All methods with a "Locked" suffix must be called from the
/// combiner passed to the constructor.
-class Resolver : public InternallyRefCountedWithTracing<Resolver> {
+class Resolver : public InternallyRefCounted<Resolver> {
public:
// Not copyable nor movable.
Resolver(const Resolver&) = delete;
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 9562a3f893..abacd0c960 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
@@ -33,6 +33,7 @@
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@@ -117,11 +118,13 @@ class AresDnsResolver : public Resolver {
/// retry backoff state
BackOff backoff_;
/// currently resolving addresses
- grpc_lb_addresses* lb_addresses_ = nullptr;
+ UniquePtr<ServerAddressList> addresses_;
/// currently resolving service config
char* service_config_json_ = nullptr;
// has shutdown been initiated
bool shutdown_initiated_ = false;
+ // timeout in milliseconds for active DNS queries
+ int query_timeout_ms_;
};
AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
@@ -159,10 +162,15 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
grpc_combiner_scheduler(combiner()));
GRPC_CLOSURE_INIT(&on_resolved_, OnResolvedLocked, this,
grpc_combiner_scheduler(combiner()));
+ const grpc_arg* query_timeout_ms_arg =
+ grpc_channel_args_find(channel_args_, GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS);
+ query_timeout_ms_ = grpc_channel_arg_get_integer(
+ query_timeout_ms_arg,
+ {GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS, 0, INT_MAX});
}
AresDnsResolver::~AresDnsResolver() {
- gpr_log(GPR_DEBUG, "destroying AresDnsResolver");
+ GRPC_CARES_TRACE_LOG("resolver:%p destroying AresDnsResolver", this);
if (resolved_result_ != nullptr) {
grpc_channel_args_destroy(resolved_result_);
}
@@ -174,7 +182,8 @@ AresDnsResolver::~AresDnsResolver() {
void AresDnsResolver::NextLocked(grpc_channel_args** target_result,
grpc_closure* on_complete) {
- gpr_log(GPR_DEBUG, "AresDnsResolver::NextLocked() is called.");
+ GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::NextLocked() is called.",
+ this);
GPR_ASSERT(next_completion_ == nullptr);
next_completion_ = on_complete;
target_result_ = target_result;
@@ -217,12 +226,14 @@ void AresDnsResolver::ShutdownLocked() {
void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) {
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
GRPC_CARES_TRACE_LOG(
- "%p re-resolution timer fired. error: %s. shutdown_initiated_: %d", r,
- grpc_error_string(error), r->shutdown_initiated_);
+ "resolver:%p re-resolution timer fired. error: %s. shutdown_initiated_: "
+ "%d",
+ r, grpc_error_string(error), r->shutdown_initiated_);
r->have_next_resolution_timer_ = false;
if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) {
if (!r->resolving_) {
- GRPC_CARES_TRACE_LOG("%p start resolving due to re-resolution timer", r);
+ GRPC_CARES_TRACE_LOG(
+ "resolver:%p start resolving due to re-resolution timer", r);
r->StartResolvingLocked();
}
}
@@ -307,53 +318,40 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
r->resolving_ = false;
gpr_free(r->pending_request_);
r->pending_request_ = nullptr;
- if (r->lb_addresses_ != nullptr) {
- static const char* args_to_remove[2];
+ if (r->addresses_ != nullptr) {
+ static const char* args_to_remove[1];
size_t num_args_to_remove = 0;
- grpc_arg new_args[3];
+ grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
- new_args[num_args_to_add++] =
- grpc_lb_addresses_create_channel_arg(r->lb_addresses_);
- grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config;
+ args_to_add[num_args_to_add++] =
+ CreateServerAddressListChannelArg(r->addresses_.get());
char* service_config_string = nullptr;
if (r->service_config_json_ != nullptr) {
service_config_string = ChooseServiceConfig(r->service_config_json_);
gpr_free(r->service_config_json_);
if (service_config_string != nullptr) {
- gpr_log(GPR_INFO, "selected service config choice: %s",
- service_config_string);
+ GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s",
+ r, service_config_string);
args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
- new_args[num_args_to_add++] = grpc_channel_arg_string_create(
+ args_to_add[num_args_to_add++] = grpc_channel_arg_string_create(
(char*)GRPC_ARG_SERVICE_CONFIG, service_config_string);
- service_config =
- grpc_core::ServiceConfig::Create(service_config_string);
- if (service_config != nullptr) {
- const char* lb_policy_name =
- service_config->GetLoadBalancingPolicyName();
- if (lb_policy_name != nullptr) {
- args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME;
- new_args[num_args_to_add++] = grpc_channel_arg_string_create(
- (char*)GRPC_ARG_LB_POLICY_NAME,
- const_cast<char*>(lb_policy_name));
- }
- }
}
}
result = grpc_channel_args_copy_and_add_and_remove(
- r->channel_args_, args_to_remove, num_args_to_remove, new_args,
+ r->channel_args_, args_to_remove, num_args_to_remove, args_to_add,
num_args_to_add);
gpr_free(service_config_string);
- grpc_lb_addresses_destroy(r->lb_addresses_);
+ r->addresses_.reset();
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.
r->backoff_.Reset();
} else if (!r->shutdown_initiated_) {
const char* msg = grpc_error_string(error);
- gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
+ GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed: %s", r, msg);
grpc_millis next_try = r->backoff_.NextAttemptTime();
grpc_millis timeout = next_try - ExecCtx::Get()->Now();
- gpr_log(GPR_INFO, "dns resolution failed (will retry): %s",
- grpc_error_string(error));
+ GRPC_CARES_TRACE_LOG("resolver:%p dns resolution failed (will retry): %s",
+ r, grpc_error_string(error));
GPR_ASSERT(!r->have_next_resolution_timer_);
r->have_next_resolution_timer_ = true;
// TODO(roth): We currently deal with this ref manually. Once the
@@ -362,9 +360,10 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
RefCountedPtr<Resolver> self = r->Ref(DEBUG_LOCATION, "retry-timer");
self.release();
if (timeout > 0) {
- gpr_log(GPR_DEBUG, "retrying in %" PRId64 " milliseconds", timeout);
+ GRPC_CARES_TRACE_LOG("resolver:%p retrying in %" PRId64 " milliseconds",
+ r, timeout);
} else {
- gpr_log(GPR_DEBUG, "retrying immediately");
+ GRPC_CARES_TRACE_LOG("resolver:%p retrying immediately", r);
}
grpc_timer_init(&r->next_resolution_timer_, next_try,
&r->on_next_resolution_);
@@ -390,10 +389,10 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
if (ms_until_next_resolution > 0) {
const grpc_millis last_resolution_ago =
grpc_core::ExecCtx::Get()->Now() - last_resolution_timestamp_;
- gpr_log(GPR_DEBUG,
- "In cooldown from last resolution (from %" PRId64
- " ms ago). Will resolve again in %" PRId64 " ms",
- last_resolution_ago, ms_until_next_resolution);
+ GRPC_CARES_TRACE_LOG(
+ "resolver:%p In cooldown from last resolution (from %" PRId64
+ " ms ago). Will resolve again in %" PRId64 " ms",
+ this, last_resolution_ago, ms_until_next_resolution);
have_next_resolution_timer_ = true;
// TODO(roth): We currently deal with this ref manually. Once the
// new closure API is done, find a way to track this ref with the timer
@@ -410,7 +409,6 @@ void AresDnsResolver::MaybeStartResolvingLocked() {
}
void AresDnsResolver::StartResolvingLocked() {
- gpr_log(GPR_DEBUG, "Start resolving.");
// TODO(roth): We currently deal with this ref manually. Once the
// new closure API is done, find a way to track this ref with the timer
// callback as part of the type system.
@@ -418,13 +416,15 @@ void AresDnsResolver::StartResolvingLocked() {
self.release();
GPR_ASSERT(!resolving_);
resolving_ = true;
- lb_addresses_ = nullptr;
service_config_json_ = nullptr;
pending_request_ = grpc_dns_lookup_ares_locked(
dns_server_, name_to_resolve_, kDefaultPort, interested_parties_,
- &on_resolved_, &lb_addresses_, true /* check_grpclb */,
- request_service_config_ ? &service_config_json_ : nullptr, combiner());
+ &on_resolved_, &addresses_, true /* check_grpclb */,
+ request_service_config_ ? &service_config_json_ : nullptr,
+ query_timeout_ms_, combiner());
last_resolution_timestamp_ = grpc_core::ExecCtx::Get()->Now();
+ GRPC_CARES_TRACE_LOG("resolver:%p Started resolving. pending_request_:%p",
+ this, pending_request_);
}
void AresDnsResolver::MaybeFinishNextLocked() {
@@ -432,7 +432,8 @@ void AresDnsResolver::MaybeFinishNextLocked() {
*target_result_ = resolved_result_ == nullptr
? nullptr
: grpc_channel_args_copy(resolved_result_);
- gpr_log(GPR_DEBUG, "AresDnsResolver::MaybeFinishNextLocked()");
+ GRPC_CARES_TRACE_LOG("resolver:%p AresDnsResolver::MaybeFinishNextLocked()",
+ this);
GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE);
next_completion_ = nullptr;
published_version_ = resolved_version_;
@@ -470,11 +471,16 @@ static grpc_error* blocking_resolve_address_ares(
static grpc_address_resolver_vtable ares_resolver = {
grpc_resolve_address_ares, blocking_resolve_address_ares};
+static bool should_use_ares(const char* resolver_env) {
+ return resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0;
+}
+
void grpc_resolver_dns_ares_init() {
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
/* TODO(zyc): Turn on c-ares based resolver by default after the address
sorter and the CNAME support are added. */
- if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) {
+ if (should_use_ares(resolver_env)) {
+ gpr_log(GPR_DEBUG, "Using ares dns resolver");
address_sorting_init();
grpc_error* error = grpc_ares_init();
if (error != GRPC_ERROR_NONE) {
@@ -494,7 +500,7 @@ void grpc_resolver_dns_ares_init() {
void grpc_resolver_dns_ares_shutdown() {
char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
- if (resolver_env != nullptr && gpr_stricmp(resolver_env, "ares") == 0) {
+ if (should_use_ares(resolver_env)) {
address_sorting_shutdown();
grpc_ares_cleanup();
}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
index fdbd07ebf5..d99c2e3004 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
@@ -31,8 +31,10 @@
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/timer.h"
typedef struct fd_node {
/** the owner of this fd node */
@@ -76,21 +78,30 @@ struct grpc_ares_ev_driver {
grpc_ares_request* request;
/** Owned by the ev_driver. Creates new GrpcPolledFd's */
grpc_core::UniquePtr<grpc_core::GrpcPolledFdFactory> polled_fd_factory;
+ /** query timeout in milliseconds */
+ int query_timeout_ms;
+ /** alarm to cancel active queries */
+ grpc_timer query_timeout;
+ /** cancels queries on a timeout */
+ grpc_closure on_timeout_locked;
};
static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver);
static grpc_ares_ev_driver* grpc_ares_ev_driver_ref(
grpc_ares_ev_driver* ev_driver) {
- gpr_log(GPR_DEBUG, "Ref ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
+ GRPC_CARES_TRACE_LOG("request:%p Ref ev_driver %p", ev_driver->request,
+ ev_driver);
gpr_ref(&ev_driver->refs);
return ev_driver;
}
static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
- gpr_log(GPR_DEBUG, "Unref ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
+ GRPC_CARES_TRACE_LOG("request:%p Unref ev_driver %p", ev_driver->request,
+ ev_driver);
if (gpr_unref(&ev_driver->refs)) {
- gpr_log(GPR_DEBUG, "destroy ev_driver %" PRIuPTR, (uintptr_t)ev_driver);
+ GRPC_CARES_TRACE_LOG("request:%p destroy ev_driver %p", ev_driver->request,
+ ev_driver);
GPR_ASSERT(ev_driver->fds == nullptr);
GRPC_COMBINER_UNREF(ev_driver->combiner, "free ares event driver");
ares_destroy(ev_driver->channel);
@@ -100,7 +111,8 @@ static void grpc_ares_ev_driver_unref(grpc_ares_ev_driver* ev_driver) {
}
static void fd_node_destroy_locked(fd_node* fdn) {
- gpr_log(GPR_DEBUG, "delete fd: %s", fdn->grpc_polled_fd->GetName());
+ GRPC_CARES_TRACE_LOG("request:%p delete fd: %s", fdn->ev_driver->request,
+ fdn->grpc_polled_fd->GetName());
GPR_ASSERT(!fdn->readable_registered);
GPR_ASSERT(!fdn->writable_registered);
GPR_ASSERT(fdn->already_shutdown);
@@ -116,8 +128,11 @@ static void fd_node_shutdown_locked(fd_node* fdn, const char* reason) {
}
}
+static void on_timeout_locked(void* arg, grpc_error* error);
+
grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
grpc_pollset_set* pollset_set,
+ int query_timeout_ms,
grpc_combiner* combiner,
grpc_ares_request* request) {
*ev_driver = grpc_core::New<grpc_ares_ev_driver>();
@@ -125,7 +140,7 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
memset(&opts, 0, sizeof(opts));
opts.flags |= ARES_FLAG_STAYOPEN;
int status = ares_init_options(&(*ev_driver)->channel, &opts, ARES_OPT_FLAGS);
- gpr_log(GPR_DEBUG, "grpc_ares_ev_driver_create_locked");
+ GRPC_CARES_TRACE_LOG("request:%p grpc_ares_ev_driver_create_locked", request);
if (status != ARES_SUCCESS) {
char* err_msg;
gpr_asprintf(&err_msg, "Failed to init ares channel. C-ares error: %s",
@@ -146,6 +161,9 @@ grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
grpc_core::NewGrpcPolledFdFactory((*ev_driver)->combiner);
(*ev_driver)
->polled_fd_factory->ConfigureAresChannelLocked((*ev_driver)->channel);
+ GRPC_CLOSURE_INIT(&(*ev_driver)->on_timeout_locked, on_timeout_locked,
+ *ev_driver, grpc_combiner_scheduler(combiner));
+ (*ev_driver)->query_timeout_ms = query_timeout_ms;
return GRPC_ERROR_NONE;
}
@@ -155,6 +173,7 @@ void grpc_ares_ev_driver_on_queries_complete_locked(
// is working, grpc_ares_notify_on_event_locked will shut down the
// fds; if it's not working, there are no fds to shut down.
ev_driver->shutting_down = true;
+ grpc_timer_cancel(&ev_driver->query_timeout);
grpc_ares_ev_driver_unref(ev_driver);
}
@@ -185,12 +204,25 @@ static fd_node* pop_fd_node_locked(fd_node** head, ares_socket_t as) {
return nullptr;
}
+static void on_timeout_locked(void* arg, grpc_error* error) {
+ grpc_ares_ev_driver* driver = static_cast<grpc_ares_ev_driver*>(arg);
+ GRPC_CARES_TRACE_LOG(
+ "request:%p ev_driver=%p on_timeout_locked. driver->shutting_down=%d. "
+ "err=%s",
+ driver->request, driver, driver->shutting_down, grpc_error_string(error));
+ if (!driver->shutting_down && error == GRPC_ERROR_NONE) {
+ grpc_ares_ev_driver_shutdown_locked(driver);
+ }
+ grpc_ares_ev_driver_unref(driver);
+}
+
static void on_readable_locked(void* arg, grpc_error* error) {
fd_node* fdn = static_cast<fd_node*>(arg);
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
fdn->readable_registered = false;
- gpr_log(GPR_DEBUG, "readable on %s", fdn->grpc_polled_fd->GetName());
+ GRPC_CARES_TRACE_LOG("request:%p readable on %s", fdn->ev_driver->request,
+ fdn->grpc_polled_fd->GetName());
if (error == GRPC_ERROR_NONE) {
do {
ares_process_fd(ev_driver->channel, as, ARES_SOCKET_BAD);
@@ -213,7 +245,8 @@ static void on_writable_locked(void* arg, grpc_error* error) {
grpc_ares_ev_driver* ev_driver = fdn->ev_driver;
const ares_socket_t as = fdn->grpc_polled_fd->GetWrappedAresSocketLocked();
fdn->writable_registered = false;
- gpr_log(GPR_DEBUG, "writable on %s", fdn->grpc_polled_fd->GetName());
+ GRPC_CARES_TRACE_LOG("request:%p writable on %s", ev_driver->request,
+ fdn->grpc_polled_fd->GetName());
if (error == GRPC_ERROR_NONE) {
ares_process_fd(ev_driver->channel, ARES_SOCKET_BAD, as);
} else {
@@ -252,7 +285,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
fdn->grpc_polled_fd =
ev_driver->polled_fd_factory->NewGrpcPolledFdLocked(
socks[i], ev_driver->pollset_set, ev_driver->combiner);
- gpr_log(GPR_DEBUG, "new fd: %s", fdn->grpc_polled_fd->GetName());
+ GRPC_CARES_TRACE_LOG("request:%p new fd: %s", ev_driver->request,
+ fdn->grpc_polled_fd->GetName());
fdn->ev_driver = ev_driver;
fdn->readable_registered = false;
fdn->writable_registered = false;
@@ -269,8 +303,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
if (ARES_GETSOCK_READABLE(socks_bitmask, i) &&
!fdn->readable_registered) {
grpc_ares_ev_driver_ref(ev_driver);
- gpr_log(GPR_DEBUG, "notify read on: %s",
- fdn->grpc_polled_fd->GetName());
+ GRPC_CARES_TRACE_LOG("request:%p notify read on: %s",
+ ev_driver->request,
+ fdn->grpc_polled_fd->GetName());
fdn->grpc_polled_fd->RegisterForOnReadableLocked(&fdn->read_closure);
fdn->readable_registered = true;
}
@@ -278,8 +313,9 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
// has not been registered with this socket.
if (ARES_GETSOCK_WRITABLE(socks_bitmask, i) &&
!fdn->writable_registered) {
- gpr_log(GPR_DEBUG, "notify write on: %s",
- fdn->grpc_polled_fd->GetName());
+ GRPC_CARES_TRACE_LOG("request:%p notify write on: %s",
+ ev_driver->request,
+ fdn->grpc_polled_fd->GetName());
grpc_ares_ev_driver_ref(ev_driver);
fdn->grpc_polled_fd->RegisterForOnWriteableLocked(
&fdn->write_closure);
@@ -306,7 +342,8 @@ static void grpc_ares_notify_on_event_locked(grpc_ares_ev_driver* ev_driver) {
// If the ev driver has no working fd, all the tasks are done.
if (new_list == nullptr) {
ev_driver->working = false;
- gpr_log(GPR_DEBUG, "ev driver stop working");
+ GRPC_CARES_TRACE_LOG("request:%p ev driver stop working",
+ ev_driver->request);
}
}
@@ -314,6 +351,17 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
if (!ev_driver->working) {
ev_driver->working = true;
grpc_ares_notify_on_event_locked(ev_driver);
+ grpc_millis timeout =
+ ev_driver->query_timeout_ms == 0
+ ? GRPC_MILLIS_INF_FUTURE
+ : ev_driver->query_timeout_ms + grpc_core::ExecCtx::Get()->Now();
+ GRPC_CARES_TRACE_LOG(
+ "request:%p ev_driver=%p grpc_ares_ev_driver_start_locked. timeout in "
+ "%" PRId64 " ms",
+ ev_driver->request, ev_driver, timeout);
+ grpc_ares_ev_driver_ref(ev_driver);
+ grpc_timer_init(&ev_driver->query_timeout, timeout,
+ &ev_driver->on_timeout_locked);
}
}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
index 671c537fe7..b8cefd9470 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h
@@ -43,6 +43,7 @@ ares_channel* grpc_ares_ev_driver_get_channel_locked(
created successfully. */
grpc_error* grpc_ares_ev_driver_create_locked(grpc_ares_ev_driver** ev_driver,
grpc_pollset_set* pollset_set,
+ int query_timeout_ms,
grpc_combiner* combiner,
grpc_ares_request* request);
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 582e2203fc..1a7e5d0626 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
@@ -37,12 +37,16 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/nameser.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
+using grpc_core::ServerAddress;
+using grpc_core::ServerAddressList;
+
static gpr_once g_basic_init = GPR_ONCE_INIT;
static gpr_mu g_init_mu;
@@ -58,7 +62,7 @@ struct grpc_ares_request {
/** closure to call when the request completes */
grpc_closure* on_done;
/** the pointer to receive the resolved addresses */
- grpc_lb_addresses** lb_addrs_out;
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses_out;
/** the pointer to receive the service config in JSON */
char** service_config_json_out;
/** the evernt driver used by this request */
@@ -87,46 +91,44 @@ typedef struct grpc_ares_hostbyname_request {
static void do_basic_init(void) { gpr_mu_init(&g_init_mu); }
-static void log_address_sorting_list(grpc_lb_addresses* lb_addrs,
+static void log_address_sorting_list(const ServerAddressList& addresses,
const char* input_output_str) {
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
+ for (size_t i = 0; i < addresses.size(); i++) {
char* addr_str;
- if (grpc_sockaddr_to_string(&addr_str, &lb_addrs->addresses[i].address,
- true)) {
- gpr_log(GPR_DEBUG, "c-ares address sorting: %s[%" PRIuPTR "]=%s",
+ if (grpc_sockaddr_to_string(&addr_str, &addresses[i].address(), true)) {
+ gpr_log(GPR_INFO, "c-ares address sorting: %s[%" PRIuPTR "]=%s",
input_output_str, i, addr_str);
gpr_free(addr_str);
} else {
- gpr_log(GPR_DEBUG,
+ gpr_log(GPR_INFO,
"c-ares address sorting: %s[%" PRIuPTR "]=<unprintable>",
input_output_str, i);
}
}
}
-void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs) {
+void grpc_cares_wrapper_address_sorting_sort(ServerAddressList* addresses) {
if (grpc_trace_cares_address_sorting.enabled()) {
- log_address_sorting_list(lb_addrs, "input");
+ log_address_sorting_list(*addresses, "input");
}
address_sorting_sortable* sortables = (address_sorting_sortable*)gpr_zalloc(
- sizeof(address_sorting_sortable) * lb_addrs->num_addresses);
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
- sortables[i].user_data = &lb_addrs->addresses[i];
- memcpy(&sortables[i].dest_addr.addr, &lb_addrs->addresses[i].address.addr,
- lb_addrs->addresses[i].address.len);
- sortables[i].dest_addr.len = lb_addrs->addresses[i].address.len;
+ sizeof(address_sorting_sortable) * addresses->size());
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ sortables[i].user_data = &(*addresses)[i];
+ memcpy(&sortables[i].dest_addr.addr, &(*addresses)[i].address().addr,
+ (*addresses)[i].address().len);
+ sortables[i].dest_addr.len = (*addresses)[i].address().len;
}
- address_sorting_rfc_6724_sort(sortables, lb_addrs->num_addresses);
- grpc_lb_address* sorted_lb_addrs = (grpc_lb_address*)gpr_zalloc(
- sizeof(grpc_lb_address) * lb_addrs->num_addresses);
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
- sorted_lb_addrs[i] = *(grpc_lb_address*)sortables[i].user_data;
+ address_sorting_rfc_6724_sort(sortables, addresses->size());
+ ServerAddressList sorted;
+ sorted.reserve(addresses->size());
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ sorted.emplace_back(*static_cast<ServerAddress*>(sortables[i].user_data));
}
gpr_free(sortables);
- gpr_free(lb_addrs->addresses);
- lb_addrs->addresses = sorted_lb_addrs;
+ *addresses = std::move(sorted);
if (grpc_trace_cares_address_sorting.enabled()) {
- log_address_sorting_list(lb_addrs, "output");
+ log_address_sorting_list(*addresses, "output");
}
}
@@ -145,9 +147,9 @@ 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);
+ ServerAddressList* addresses = r->addresses_out->get();
+ if (addresses != nullptr) {
+ grpc_cares_wrapper_address_sorting_sort(addresses);
}
GRPC_CLOSURE_SCHED(r->on_done, r->error);
}
@@ -181,60 +183,53 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
GRPC_ERROR_UNREF(r->error);
r->error = GRPC_ERROR_NONE;
r->success = true;
- grpc_lb_addresses** lb_addresses = r->lb_addrs_out;
- if (*lb_addresses == nullptr) {
- *lb_addresses = grpc_lb_addresses_create(0, nullptr);
- }
- size_t prev_naddr = (*lb_addresses)->num_addresses;
- size_t i;
- for (i = 0; hostent->h_addr_list[i] != nullptr; i++) {
+ if (*r->addresses_out == nullptr) {
+ *r->addresses_out = grpc_core::MakeUnique<ServerAddressList>();
}
- (*lb_addresses)->num_addresses += i;
- (*lb_addresses)->addresses = static_cast<grpc_lb_address*>(
- gpr_realloc((*lb_addresses)->addresses,
- sizeof(grpc_lb_address) * (*lb_addresses)->num_addresses));
- for (i = prev_naddr; i < (*lb_addresses)->num_addresses; i++) {
+ ServerAddressList& addresses = **r->addresses_out;
+ for (size_t i = 0; hostent->h_addr_list[i] != nullptr; ++i) {
+ grpc_core::InlinedVector<grpc_arg, 2> args_to_add;
+ if (hr->is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME), hr->host));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
switch (hostent->h_addrtype) {
case AF_INET6: {
size_t addr_len = sizeof(struct sockaddr_in6);
struct sockaddr_in6 addr;
memset(&addr, 0, addr_len);
- memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr],
+ memcpy(&addr.sin6_addr, hostent->h_addr_list[i],
sizeof(struct in6_addr));
addr.sin6_family = static_cast<unsigned char>(hostent->h_addrtype);
addr.sin6_port = hr->port;
- grpc_lb_addresses_set_address(
- *lb_addresses, i, &addr, addr_len,
- hr->is_balancer /* is_balancer */,
- hr->is_balancer ? hr->host : nullptr /* balancer_name */,
- nullptr /* user_data */);
+ addresses.emplace_back(&addr, addr_len, args);
char output[INET6_ADDRSTRLEN];
ares_inet_ntop(AF_INET6, &addr.sin6_addr, output, INET6_ADDRSTRLEN);
- gpr_log(GPR_DEBUG,
- "c-ares resolver gets a AF_INET6 result: \n"
- " addr: %s\n port: %d\n sin6_scope_id: %d\n",
- output, ntohs(hr->port), addr.sin6_scope_id);
+ GRPC_CARES_TRACE_LOG(
+ "request:%p c-ares resolver gets a AF_INET6 result: \n"
+ " addr: %s\n port: %d\n sin6_scope_id: %d\n",
+ r, output, ntohs(hr->port), addr.sin6_scope_id);
break;
}
case AF_INET: {
size_t addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in addr;
memset(&addr, 0, addr_len);
- memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr],
+ memcpy(&addr.sin_addr, hostent->h_addr_list[i],
sizeof(struct in_addr));
addr.sin_family = static_cast<unsigned char>(hostent->h_addrtype);
addr.sin_port = hr->port;
- grpc_lb_addresses_set_address(
- *lb_addresses, i, &addr, addr_len,
- hr->is_balancer /* is_balancer */,
- hr->is_balancer ? hr->host : nullptr /* balancer_name */,
- nullptr /* user_data */);
+ addresses.emplace_back(&addr, addr_len, args);
char output[INET_ADDRSTRLEN];
ares_inet_ntop(AF_INET, &addr.sin_addr, output, INET_ADDRSTRLEN);
- gpr_log(GPR_DEBUG,
- "c-ares resolver gets a AF_INET result: \n"
- " addr: %s\n port: %d\n",
- output, ntohs(hr->port));
+ GRPC_CARES_TRACE_LOG(
+ "request:%p c-ares resolver gets a AF_INET result: \n"
+ " addr: %s\n port: %d\n",
+ r, output, ntohs(hr->port));
break;
}
}
@@ -257,9 +252,9 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
static void on_srv_query_done_locked(void* arg, int status, int timeouts,
unsigned char* abuf, int alen) {
grpc_ares_request* r = static_cast<grpc_ares_request*>(arg);
- gpr_log(GPR_DEBUG, "on_query_srv_done_locked");
+ GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked", r);
if (status == ARES_SUCCESS) {
- gpr_log(GPR_DEBUG, "on_query_srv_done_locked ARES_SUCCESS");
+ GRPC_CARES_TRACE_LOG("request:%p on_query_srv_done_locked ARES_SUCCESS", r);
struct ares_srv_reply* reply;
const int parse_status = ares_parse_srv_reply(abuf, alen, &reply);
if (parse_status == ARES_SUCCESS) {
@@ -302,9 +297,9 @@ static const char g_service_config_attribute_prefix[] = "grpc_config=";
static void on_txt_done_locked(void* arg, int status, int timeouts,
unsigned char* buf, int len) {
- gpr_log(GPR_DEBUG, "on_txt_done_locked");
char* error_msg;
grpc_ares_request* r = static_cast<grpc_ares_request*>(arg);
+ GRPC_CARES_TRACE_LOG("request:%p on_txt_done_locked", r);
const size_t prefix_len = sizeof(g_service_config_attribute_prefix) - 1;
struct ares_txt_ext* result = nullptr;
struct ares_txt_ext* reply = nullptr;
@@ -337,7 +332,8 @@ static void on_txt_done_locked(void* arg, int status, int timeouts,
service_config_len += result->length;
}
(*r->service_config_json_out)[service_config_len] = '\0';
- gpr_log(GPR_INFO, "found service config: %s", *r->service_config_json_out);
+ GRPC_CARES_TRACE_LOG("request:%p found service config: %s", r,
+ *r->service_config_json_out);
}
// Clean up.
ares_free_data(reply);
@@ -359,16 +355,10 @@ done:
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) {
+ bool check_grpclb, int query_timeout_ms, grpc_combiner* combiner) {
grpc_error* error = GRPC_ERROR_NONE;
grpc_ares_hostbyname_request* hr = nullptr;
ares_channel* channel = nullptr;
- /* TODO(zyc): Enable tracing after #9603 is checked in */
- /* if (grpc_dns_trace) {
- gpr_log(GPR_DEBUG, "resolve_address (blocking): name=%s, default_port=%s",
- name, default_port);
- } */
-
/* parse name, splitting it into host and port parts */
char* host;
char* port;
@@ -388,12 +378,12 @@ void grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
port = gpr_strdup(default_port);
}
error = grpc_ares_ev_driver_create_locked(&r->ev_driver, interested_parties,
- combiner, r);
+ query_timeout_ms, combiner, r);
if (error != GRPC_ERROR_NONE) goto error_cleanup;
channel = grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
// If dns_server is specified, use it.
if (dns_server != nullptr) {
- gpr_log(GPR_INFO, "Using DNS server %s", dns_server);
+ GRPC_CARES_TRACE_LOG("request:%p Using DNS server %s", r, dns_server);
grpc_resolved_address addr;
if (grpc_parse_ipv4_hostport(dns_server, &addr, false /* log_errors */)) {
r->dns_server_addr.family = AF_INET;
@@ -467,11 +457,10 @@ error_cleanup:
gpr_free(port);
}
-static bool inner_resolve_as_ip_literal_locked(const char* name,
- const char* default_port,
- grpc_lb_addresses** addrs,
- char** host, char** port,
- char** hostport) {
+static bool inner_resolve_as_ip_literal_locked(
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
+ char** port, char** hostport) {
gpr_split_host_port(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
@@ -495,18 +484,16 @@ static bool inner_resolve_as_ip_literal_locked(const char* name,
if (grpc_parse_ipv4_hostport(*hostport, &addr, false /* log errors */) ||
grpc_parse_ipv6_hostport(*hostport, &addr, false /* log errors */)) {
GPR_ASSERT(*addrs == nullptr);
- *addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_lb_addresses_set_address(
- *addrs, 0, addr.addr, addr.len, false /* is_balancer */,
- nullptr /* balancer_name */, nullptr /* user_data */);
+ *addrs = grpc_core::MakeUnique<ServerAddressList>();
+ (*addrs)->emplace_back(addr.addr, addr.len, nullptr /* args */);
return true;
}
return false;
}
-static bool resolve_as_ip_literal_locked(const char* name,
- const char* default_port,
- grpc_lb_addresses** addrs) {
+static bool resolve_as_ip_literal_locked(
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
char* hostport = nullptr;
@@ -518,20 +505,47 @@ static bool resolve_as_ip_literal_locked(const char* name,
return out;
}
+static bool target_matches_localhost_inner(const char* name, char** host,
+ char** port) {
+ if (!gpr_split_host_port(name, host, port)) {
+ gpr_log(GPR_ERROR, "Unable to split host and port for name: %s", name);
+ return false;
+ }
+ if (gpr_stricmp(*host, "localhost") == 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static bool target_matches_localhost(const char* name) {
+ char* host = nullptr;
+ char* port = nullptr;
+ bool out = target_matches_localhost_inner(name, &host, &port);
+ gpr_free(host);
+ gpr_free(port);
+ return out;
+}
+
static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
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_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
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->addresses_out = addrs;
r->service_config_json_out = service_config_json;
r->success = false;
r->error = GRPC_ERROR_NONE;
r->pending_queries = 0;
+ GRPC_CARES_TRACE_LOG(
+ "request:%p c-ares grpc_dns_lookup_ares_locked_impl name=%s, "
+ "default_port=%s",
+ r, name, default_port);
// 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);
@@ -543,17 +557,25 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
return r;
}
+ // Don't query for SRV and TXT records if the target is "localhost", so
+ // as to cut down on lookups over the network, especially in tests:
+ // https://github.com/grpc/proposal/pull/79
+ if (target_matches_localhost(name)) {
+ check_grpclb = false;
+ r->service_config_json_out = nullptr;
+ }
// Look up name using c-ares lib.
grpc_dns_lookup_ares_continue_after_check_localhost_and_ip_literals_locked(
r, dns_server, name, default_port, interested_parties, check_grpclb,
- combiner);
+ query_timeout_ms, combiner);
return r;
}
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,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {
@@ -598,8 +620,8 @@ typedef struct grpc_resolve_address_ares_request {
grpc_combiner* combiner;
/** the pointer to receive the resolved addresses */
grpc_resolved_addresses** addrs_out;
- /** currently resolving lb addresses */
- grpc_lb_addresses* lb_addrs;
+ /** currently resolving addresses */
+ grpc_core::UniquePtr<ServerAddressList> addresses;
/** closure to call when the resolve_address_ares request completes */
grpc_closure* on_resolve_address_done;
/** a closure wrapping on_resolve_address_done, which should be invoked when
@@ -612,7 +634,7 @@ typedef struct grpc_resolve_address_ares_request {
/* 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_ares_request* ares_request = nullptr;
} grpc_resolve_address_ares_request;
static void on_dns_lookup_done_locked(void* arg, grpc_error* error) {
@@ -620,25 +642,24 @@ static void on_dns_lookup_done_locked(void* arg, grpc_error* error) {
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) {
+ if (r->addresses == nullptr || r->addresses->empty()) {
*resolved_addresses = nullptr;
} else {
*resolved_addresses = static_cast<grpc_resolved_addresses*>(
gpr_zalloc(sizeof(grpc_resolved_addresses)));
- (*resolved_addresses)->naddrs = r->lb_addrs->num_addresses;
+ (*resolved_addresses)->naddrs = r->addresses->size();
(*resolved_addresses)->addrs =
static_cast<grpc_resolved_address*>(gpr_zalloc(
sizeof(grpc_resolved_address) * (*resolved_addresses)->naddrs));
- for (size_t i = 0; i < (*resolved_addresses)->naddrs; i++) {
- GPR_ASSERT(!r->lb_addrs->addresses[i].is_balancer);
- memcpy(&(*resolved_addresses)->addrs[i],
- &r->lb_addrs->addresses[i].address, sizeof(grpc_resolved_address));
+ for (size_t i = 0; i < (*resolved_addresses)->naddrs; ++i) {
+ GPR_ASSERT(!(*r->addresses)[i].IsBalancer());
+ memcpy(&(*resolved_addresses)->addrs[i], &(*r->addresses)[i].address(),
+ sizeof(grpc_resolved_address));
}
}
GRPC_CLOSURE_SCHED(r->on_resolve_address_done, GRPC_ERROR_REF(error));
- if (r->lb_addrs != nullptr) grpc_lb_addresses_destroy(r->lb_addrs);
GRPC_COMBINER_UNREF(r->combiner, "on_dns_lookup_done_cb");
- gpr_free(r);
+ grpc_core::Delete(r);
}
static void grpc_resolve_address_invoke_dns_lookup_ares_locked(
@@ -647,8 +668,9 @@ static void grpc_resolve_address_invoke_dns_lookup_ares_locked(
static_cast<grpc_resolve_address_ares_request*>(arg);
r->ares_request = grpc_dns_lookup_ares_locked(
nullptr /* dns_server */, r->name, r->default_port, r->interested_parties,
- &r->on_dns_lookup_done_locked, &r->lb_addrs, false /* check_grpclb */,
- nullptr /* service_config_json */, r->combiner);
+ &r->on_dns_lookup_done_locked, &r->addresses, false /* check_grpclb */,
+ nullptr /* service_config_json */, GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS,
+ r->combiner);
}
static void grpc_resolve_address_ares_impl(const char* name,
@@ -657,8 +679,7 @@ static void grpc_resolve_address_ares_impl(const char* name,
grpc_closure* on_done,
grpc_resolved_addresses** addrs) {
grpc_resolve_address_ares_request* r =
- static_cast<grpc_resolve_address_ares_request*>(
- gpr_zalloc(sizeof(grpc_resolve_address_ares_request)));
+ grpc_core::New<grpc_resolve_address_ares_request>();
r->combiner = grpc_combiner_create();
r->addrs_out = addrs;
r->on_resolve_address_done = on_done;
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 a1231cc4e0..2808250456 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
@@ -21,11 +21,13 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/iomgr/resolve_address.h"
+#define GRPC_DNS_ARES_DEFAULT_QUERY_TIMEOUT_MS 10000
+
extern grpc_core::TraceFlag grpc_trace_cares_address_sorting;
extern grpc_core::TraceFlag grpc_trace_cares_resolver;
@@ -59,8 +61,9 @@ extern void (*grpc_resolve_address_ares)(const char* name,
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,
- grpc_lb_addresses** addresses, bool check_grpclb,
- char** service_config_json, grpc_combiner* combiner);
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner);
/* Cancel the pending grpc_ares_request \a request */
extern void (*grpc_cancel_ares_request_locked)(grpc_ares_request* request);
@@ -87,10 +90,12 @@ bool grpc_ares_query_ipv6();
* Returns a bool indicating whether or not such an action was performed.
* See https://github.com/grpc/grpc/issues/15158. */
bool grpc_ares_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs);
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs);
/* Sorts destinations in lb_addrs according to RFC 6724. */
-void grpc_cares_wrapper_address_sorting_sort(grpc_lb_addresses* lb_addrs);
+void grpc_cares_wrapper_address_sorting_sort(
+ grpc_core::ServerAddressList* addresses);
#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_DNS_C_ARES_GRPC_ARES_WRAPPER_H \
*/
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 9f293c1ac0..1f4701c999 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
@@ -29,7 +29,8 @@ struct grpc_ares_request {
static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
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_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) {
return NULL;
}
@@ -37,7 +38,8 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
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,
- grpc_lb_addresses** addrs, bool check_grpclb, char** service_config_json,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) = grpc_dns_lookup_ares_locked_impl;
static void grpc_cancel_ares_request_locked_impl(grpc_ares_request* r) {}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
index 639eec2323..028d844216 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
@@ -27,7 +27,8 @@
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
bool grpc_ares_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs) {
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
return false;
}
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
index 7e34784691..202452f1b2 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -23,9 +23,9 @@
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/socket_windows.h"
@@ -33,8 +33,9 @@
bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
static bool inner_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs,
- char** host, char** port) {
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs, char** host,
+ char** port) {
gpr_split_host_port(name, host, port);
if (*host == nullptr) {
gpr_log(GPR_ERROR,
@@ -55,7 +56,7 @@ static bool inner_maybe_resolve_localhost_manually_locked(
}
if (gpr_stricmp(*host, "localhost") == 0) {
GPR_ASSERT(*addrs == nullptr);
- *addrs = grpc_lb_addresses_create(2, nullptr);
+ *addrs = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
uint16_t numeric_port = grpc_strhtons(*port);
// Append the ipv6 loopback address.
struct sockaddr_in6 ipv6_loopback_addr;
@@ -63,10 +64,8 @@ static bool inner_maybe_resolve_localhost_manually_locked(
((char*)&ipv6_loopback_addr.sin6_addr)[15] = 1;
ipv6_loopback_addr.sin6_family = AF_INET6;
ipv6_loopback_addr.sin6_port = numeric_port;
- grpc_lb_addresses_set_address(
- *addrs, 0, &ipv6_loopback_addr, sizeof(ipv6_loopback_addr),
- false /* is_balancer */, nullptr /* balancer_name */,
- nullptr /* user_data */);
+ (*addrs)->emplace_back(&ipv6_loopback_addr, sizeof(ipv6_loopback_addr),
+ nullptr /* args */);
// Append the ipv4 loopback address.
struct sockaddr_in ipv4_loopback_addr;
memset(&ipv4_loopback_addr, 0, sizeof(ipv4_loopback_addr));
@@ -74,19 +73,18 @@ static bool inner_maybe_resolve_localhost_manually_locked(
((char*)&ipv4_loopback_addr.sin_addr)[3] = 0x01;
ipv4_loopback_addr.sin_family = AF_INET;
ipv4_loopback_addr.sin_port = numeric_port;
- grpc_lb_addresses_set_address(
- *addrs, 1, &ipv4_loopback_addr, sizeof(ipv4_loopback_addr),
- false /* is_balancer */, nullptr /* balancer_name */,
- nullptr /* user_data */);
+ (*addrs)->emplace_back(&ipv4_loopback_addr, sizeof(ipv4_loopback_addr),
+ nullptr /* args */);
// Let the address sorter figure out which one should be tried first.
- grpc_cares_wrapper_address_sorting_sort(*addrs);
+ grpc_cares_wrapper_address_sorting_sort(addrs->get());
return true;
}
return false;
}
bool grpc_ares_maybe_resolve_localhost_manually_locked(
- const char* name, const char* default_port, grpc_lb_addresses** addrs) {
+ const char* name, const char* default_port,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addrs) {
char* host = nullptr;
char* port = nullptr;
bool out = inner_maybe_resolve_localhost_manually_locked(name, default_port,
diff --git a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
index 65ff1ec1a5..c365f1abfd 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
@@ -26,8 +26,8 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
-#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@@ -198,18 +198,14 @@ void NativeDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
grpc_error_set_str(error, GRPC_ERROR_STR_TARGET_ADDRESS,
grpc_slice_from_copied_string(r->name_to_resolve_));
if (r->addresses_ != nullptr) {
- grpc_lb_addresses* addresses = grpc_lb_addresses_create(
- r->addresses_->naddrs, nullptr /* user_data_vtable */);
+ ServerAddressList addresses;
for (size_t i = 0; i < r->addresses_->naddrs; ++i) {
- grpc_lb_addresses_set_address(
- addresses, i, &r->addresses_->addrs[i].addr,
- r->addresses_->addrs[i].len, false /* is_balancer */,
- nullptr /* balancer_name */, nullptr /* user_data */);
+ addresses.emplace_back(&r->addresses_->addrs[i].addr,
+ r->addresses_->addrs[i].len, nullptr /* args */);
}
- grpc_arg new_arg = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg new_arg = CreateServerAddressListChannelArg(&addresses);
result = grpc_channel_args_copy_and_add(r->channel_args_, &new_arg, 1);
grpc_resolved_addresses_destroy(r->addresses_);
- grpc_lb_addresses_destroy(addresses);
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.
r->backoff_.Reset();
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
index 144ac24a56..258339491c 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -28,12 +28,13 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
@@ -103,7 +104,7 @@ void FakeResolver::NextLocked(grpc_channel_args** target_result,
}
void FakeResolver::RequestReresolutionLocked() {
- if (reresolution_results_ != nullptr) {
+ if (reresolution_results_ != nullptr || return_failure_) {
grpc_channel_args_destroy(next_results_);
next_results_ = grpc_channel_args_copy(reresolution_results_);
MaybeFinishNextLocked();
@@ -141,6 +142,7 @@ struct SetResponseClosureArg {
grpc_closure set_response_closure;
FakeResolverResponseGenerator* generator;
grpc_channel_args* response;
+ bool immediate = true;
};
void FakeResolverResponseGenerator::SetResponseLocked(void* arg,
@@ -194,7 +196,7 @@ void FakeResolverResponseGenerator::SetFailureLocked(void* arg,
SetResponseClosureArg* closure_arg = static_cast<SetResponseClosureArg*>(arg);
FakeResolver* resolver = closure_arg->generator->resolver_;
resolver->return_failure_ = true;
- resolver->MaybeFinishNextLocked();
+ if (closure_arg->immediate) resolver->MaybeFinishNextLocked();
Delete(closure_arg);
}
@@ -209,6 +211,18 @@ void FakeResolverResponseGenerator::SetFailure() {
GRPC_ERROR_NONE);
}
+void FakeResolverResponseGenerator::SetFailureOnReresolution() {
+ GPR_ASSERT(resolver_ != nullptr);
+ SetResponseClosureArg* closure_arg = New<SetResponseClosureArg>();
+ closure_arg->generator = this;
+ closure_arg->immediate = false;
+ GRPC_CLOSURE_SCHED(
+ GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetFailureLocked,
+ closure_arg,
+ grpc_combiner_scheduler(resolver_->combiner())),
+ GRPC_ERROR_NONE);
+}
+
namespace {
static void* response_generator_arg_copy(void* p) {
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
index 74a3062e7f..d86111c382 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
@@ -19,10 +19,9 @@
#include <grpc/support/port_platform.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted.h"
-#include "src/core/lib/uri/uri_parser.h"
+#include "src/core/lib/iomgr/error.h"
#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
"grpc.fake_resolver.response_generator"
@@ -61,6 +60,10 @@ class FakeResolverResponseGenerator
// returning a null result with no error).
void SetFailure();
+ // Same as SetFailure(), but instead of returning the error
+ // immediately, waits for the next call to RequestReresolutionLocked().
+ void SetFailureOnReresolution();
+
// Returns a channel arg containing \a generator.
static grpc_arg MakeChannelArg(FakeResolverResponseGenerator* generator);
diff --git a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
index 801734764b..1654747a79 100644
--- a/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
@@ -26,9 +26,9 @@
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
@@ -45,7 +45,8 @@ namespace {
class SockaddrResolver : public Resolver {
public:
/// Takes ownership of \a addresses.
- SockaddrResolver(const ResolverArgs& args, grpc_lb_addresses* addresses);
+ SockaddrResolver(const ResolverArgs& args,
+ UniquePtr<ServerAddressList> addresses);
void NextLocked(grpc_channel_args** result,
grpc_closure* on_complete) override;
@@ -58,7 +59,7 @@ class SockaddrResolver : public Resolver {
void MaybeFinishNextLocked();
/// the addresses that we've "resolved"
- grpc_lb_addresses* addresses_ = nullptr;
+ UniquePtr<ServerAddressList> addresses_;
/// channel args
grpc_channel_args* channel_args_ = nullptr;
/// have we published?
@@ -70,13 +71,12 @@ class SockaddrResolver : public Resolver {
};
SockaddrResolver::SockaddrResolver(const ResolverArgs& args,
- grpc_lb_addresses* addresses)
+ UniquePtr<ServerAddressList> addresses)
: Resolver(args.combiner),
- addresses_(addresses),
+ addresses_(std::move(addresses)),
channel_args_(grpc_channel_args_copy(args.args)) {}
SockaddrResolver::~SockaddrResolver() {
- grpc_lb_addresses_destroy(addresses_);
grpc_channel_args_destroy(channel_args_);
}
@@ -100,7 +100,7 @@ void SockaddrResolver::ShutdownLocked() {
void SockaddrResolver::MaybeFinishNextLocked() {
if (next_completion_ != nullptr && !published_) {
published_ = true;
- grpc_arg arg = grpc_lb_addresses_create_channel_arg(addresses_);
+ grpc_arg arg = CreateServerAddressListChannelArg(addresses_.get());
*target_result_ = grpc_channel_args_copy_and_add(channel_args_, &arg, 1);
GRPC_CLOSURE_SCHED(next_completion_, GRPC_ERROR_NONE);
next_completion_ = nullptr;
@@ -127,27 +127,27 @@ OrphanablePtr<Resolver> CreateSockaddrResolver(
grpc_slice_buffer path_parts;
grpc_slice_buffer_init(&path_parts);
grpc_slice_split(path_slice, ",", &path_parts);
- grpc_lb_addresses* addresses = grpc_lb_addresses_create(
- path_parts.count, nullptr /* user_data_vtable */);
+ auto addresses = MakeUnique<ServerAddressList>();
bool errors_found = false;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
+ for (size_t i = 0; i < path_parts.count; i++) {
grpc_uri ith_uri = *args.uri;
- char* part_str = grpc_slice_to_c_string(path_parts.slices[i]);
- ith_uri.path = part_str;
- if (!parse(&ith_uri, &addresses->addresses[i].address)) {
+ UniquePtr<char> part_str(grpc_slice_to_c_string(path_parts.slices[i]));
+ ith_uri.path = part_str.get();
+ grpc_resolved_address addr;
+ if (!parse(&ith_uri, &addr)) {
errors_found = true; /* GPR_TRUE */
+ break;
}
- gpr_free(part_str);
- if (errors_found) break;
+ addresses->emplace_back(addr, nullptr /* args */);
}
grpc_slice_buffer_destroy_internal(&path_parts);
grpc_slice_unref_internal(path_slice);
if (errors_found) {
- grpc_lb_addresses_destroy(addresses);
return OrphanablePtr<Resolver>(nullptr);
}
// Instantiate resolver.
- return OrphanablePtr<Resolver>(New<SockaddrResolver>(args, addresses));
+ return OrphanablePtr<Resolver>(
+ New<SockaddrResolver>(args, std::move(addresses)));
}
class IPv4ResolverFactory : public ResolverFactory {
diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc
new file mode 100644
index 0000000000..22b06db45c
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc
@@ -0,0 +1,377 @@
+/*
+ *
+ * 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/resolver_result_parsing.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
+#include "src/core/lib/channel/status_util.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/uri/uri_parser.h"
+
+// As per the retry design, we do not allow more than 5 retry attempts.
+#define MAX_MAX_RETRY_ATTEMPTS 5
+
+namespace grpc_core {
+namespace internal {
+
+ProcessedResolverResult::ProcessedResolverResult(
+ const grpc_channel_args* resolver_result, bool parse_retry) {
+ ProcessServiceConfig(resolver_result, parse_retry);
+ // If no LB config was found above, just find the LB policy name then.
+ if (lb_policy_name_ == nullptr) ProcessLbPolicyName(resolver_result);
+}
+
+void ProcessedResolverResult::ProcessServiceConfig(
+ const grpc_channel_args* resolver_result, bool parse_retry) {
+ const grpc_arg* channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_SERVICE_CONFIG);
+ const char* service_config_json = grpc_channel_arg_get_string(channel_arg);
+ if (service_config_json != nullptr) {
+ service_config_json_.reset(gpr_strdup(service_config_json));
+ service_config_ = grpc_core::ServiceConfig::Create(service_config_json);
+ if (service_config_ != nullptr) {
+ if (parse_retry) {
+ channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_SERVER_URI);
+ const char* server_uri = grpc_channel_arg_get_string(channel_arg);
+ GPR_ASSERT(server_uri != nullptr);
+ grpc_uri* uri = grpc_uri_parse(server_uri, true);
+ GPR_ASSERT(uri->path[0] != '\0');
+ server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
+ service_config_->ParseGlobalParams(ParseServiceConfig, this);
+ grpc_uri_destroy(uri);
+ } else {
+ service_config_->ParseGlobalParams(ParseServiceConfig, this);
+ }
+ method_params_table_ = service_config_->CreateMethodConfigTable(
+ ClientChannelMethodParams::CreateFromJson);
+ }
+ }
+}
+
+void ProcessedResolverResult::ProcessLbPolicyName(
+ const grpc_channel_args* resolver_result) {
+ // Prefer the LB policy name found in the service config. Note that this is
+ // checking the deprecated loadBalancingPolicy field, rather than the new
+ // loadBalancingConfig field.
+ if (service_config_ != nullptr) {
+ lb_policy_name_.reset(
+ gpr_strdup(service_config_->GetLoadBalancingPolicyName()));
+ // Convert to lower-case.
+ if (lb_policy_name_ != nullptr) {
+ char* lb_policy_name = lb_policy_name_.get();
+ for (size_t i = 0; i < strlen(lb_policy_name); ++i) {
+ lb_policy_name[i] = tolower(lb_policy_name[i]);
+ }
+ }
+ }
+ // Otherwise, find the LB policy name set by the client API.
+ if (lb_policy_name_ == nullptr) {
+ const grpc_arg* channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME);
+ lb_policy_name_.reset(gpr_strdup(grpc_channel_arg_get_string(channel_arg)));
+ }
+ // Special case: If at least one balancer address is present, we use
+ // the grpclb policy, regardless of what the resolver has returned.
+ const ServerAddressList* addresses =
+ FindServerAddressListChannelArg(resolver_result);
+ if (addresses != nullptr) {
+ bool found_balancer_address = false;
+ for (size_t i = 0; i < addresses->size(); ++i) {
+ const ServerAddress& address = (*addresses)[i];
+ if (address.IsBalancer()) {
+ found_balancer_address = true;
+ break;
+ }
+ }
+ if (found_balancer_address) {
+ if (lb_policy_name_ != nullptr &&
+ strcmp(lb_policy_name_.get(), "grpclb") != 0) {
+ gpr_log(GPR_INFO,
+ "resolver requested LB policy %s but provided at least one "
+ "balancer address -- forcing use of grpclb LB policy",
+ lb_policy_name_.get());
+ }
+ lb_policy_name_.reset(gpr_strdup("grpclb"));
+ }
+ }
+ // Use pick_first if nothing was specified and we didn't select grpclb
+ // above.
+ if (lb_policy_name_ == nullptr) {
+ lb_policy_name_.reset(gpr_strdup("pick_first"));
+ }
+}
+
+void ProcessedResolverResult::ParseServiceConfig(
+ const grpc_json* field, ProcessedResolverResult* parsing_state) {
+ parsing_state->ParseLbConfigFromServiceConfig(field);
+ if (parsing_state->server_name_ != nullptr) {
+ parsing_state->ParseRetryThrottleParamsFromServiceConfig(field);
+ }
+}
+
+void ProcessedResolverResult::ParseLbConfigFromServiceConfig(
+ const grpc_json* field) {
+ if (lb_policy_config_ != nullptr) return; // Already found.
+ // Find the LB config global parameter.
+ if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0 ||
+ field->type != GRPC_JSON_ARRAY) {
+ return; // Not valid lb config array.
+ }
+ // Find the first LB policy that this client supports.
+ for (grpc_json* lb_config = field->child; lb_config != nullptr;
+ lb_config = lb_config->next) {
+ if (lb_config->type != GRPC_JSON_OBJECT) return;
+ // Find the policy object.
+ grpc_json* policy = nullptr;
+ for (grpc_json* field = lb_config->child; field != nullptr;
+ field = field->next) {
+ if (field->key == nullptr || strcmp(field->key, "policy") != 0 ||
+ field->type != GRPC_JSON_OBJECT) {
+ return;
+ }
+ if (policy != nullptr) return; // Duplicate.
+ policy = field;
+ }
+ // Find the specific policy content since the policy object is of type
+ // "oneof".
+ grpc_json* policy_content = nullptr;
+ for (grpc_json* field = policy->child; field != nullptr;
+ field = field->next) {
+ if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) return;
+ if (policy_content != nullptr) return; // Violate "oneof" type.
+ policy_content = field;
+ }
+ // If we support this policy, then select it.
+ if (grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
+ policy_content->key)) {
+ lb_policy_name_.reset(gpr_strdup(policy_content->key));
+ lb_policy_config_ = policy_content->child;
+ return;
+ }
+ }
+}
+
+void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig(
+ const grpc_json* field) {
+ if (strcmp(field->key, "retryThrottling") == 0) {
+ if (retry_throttle_data_ != nullptr) return; // Duplicate.
+ if (field->type != GRPC_JSON_OBJECT) return;
+ int max_milli_tokens = 0;
+ int milli_token_ratio = 0;
+ 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, "maxTokens") == 0) {
+ if (max_milli_tokens != 0) return; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return;
+ max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
+ if (max_milli_tokens == -1) return;
+ max_milli_tokens *= 1000;
+ } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
+ if (milli_token_ratio != 0) return; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return;
+ // We support up to 3 decimal digits.
+ size_t whole_len = strlen(sub_field->value);
+ uint32_t multiplier = 1;
+ uint32_t decimal_value = 0;
+ const char* decimal_point = strchr(sub_field->value, '.');
+ if (decimal_point != nullptr) {
+ whole_len = static_cast<size_t>(decimal_point - sub_field->value);
+ multiplier = 1000;
+ size_t decimal_len = strlen(decimal_point + 1);
+ if (decimal_len > 3) decimal_len = 3;
+ if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
+ &decimal_value)) {
+ return;
+ }
+ uint32_t decimal_multiplier = 1;
+ for (size_t i = 0; i < (3 - decimal_len); ++i) {
+ decimal_multiplier *= 10;
+ }
+ decimal_value *= decimal_multiplier;
+ }
+ uint32_t whole_value;
+ if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
+ &whole_value)) {
+ return;
+ }
+ milli_token_ratio =
+ static_cast<int>((whole_value * multiplier) + decimal_value);
+ if (milli_token_ratio <= 0) return;
+ }
+ }
+ retry_throttle_data_ =
+ grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
+ server_name_, max_milli_tokens, milli_token_ratio);
+ }
+}
+
+namespace {
+
+bool ParseWaitForReady(
+ grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
+ if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
+ return false;
+ }
+ *wait_for_ready = field->type == GRPC_JSON_TRUE
+ ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
+ : ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
+ return true;
+}
+
+// Parses a JSON field of the form generated for a google.proto.Duration
+// proto message, as per:
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+bool ParseDuration(grpc_json* field, grpc_millis* duration) {
+ if (field->type != GRPC_JSON_STRING) return false;
+ size_t len = strlen(field->value);
+ if (field->value[len - 1] != 's') return false;
+ UniquePtr<char> buf(gpr_strdup(field->value));
+ *(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
+ char* decimal_point = strchr(buf.get(), '.');
+ int nanos = 0;
+ if (decimal_point != nullptr) {
+ *decimal_point = '\0';
+ nanos = gpr_parse_nonnegative_int(decimal_point + 1);
+ if (nanos == -1) {
+ return false;
+ }
+ int num_digits = static_cast<int>(strlen(decimal_point + 1));
+ if (num_digits > 9) { // We don't accept greater precision than nanos.
+ return false;
+ }
+ for (int i = 0; i < (9 - num_digits); ++i) {
+ nanos *= 10;
+ }
+ }
+ int seconds =
+ decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
+ if (seconds == -1) return false;
+ *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
+ return true;
+}
+
+UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
+ grpc_json* field) {
+ auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
+ if (field->type != GRPC_JSON_OBJECT) return nullptr;
+ for (grpc_json* sub_field = field->child; sub_field != nullptr;
+ sub_field = sub_field->next) {
+ if (sub_field->key == nullptr) return nullptr;
+ if (strcmp(sub_field->key, "maxAttempts") == 0) {
+ if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
+ retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
+ if (retry_policy->max_attempts <= 1) return nullptr;
+ if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
+ gpr_log(GPR_ERROR,
+ "service config: clamped retryPolicy.maxAttempts at %d",
+ MAX_MAX_RETRY_ATTEMPTS);
+ retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
+ }
+ } else if (strcmp(sub_field->key, "initialBackoff") == 0) {
+ if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
+ return nullptr;
+ }
+ if (retry_policy->initial_backoff == 0) return nullptr;
+ } else if (strcmp(sub_field->key, "maxBackoff") == 0) {
+ if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
+ return nullptr;
+ }
+ if (retry_policy->max_backoff == 0) return nullptr;
+ } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
+ if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
+ if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
+ 1) {
+ return nullptr;
+ }
+ if (retry_policy->backoff_multiplier <= 0) return nullptr;
+ } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
+ if (!retry_policy->retryable_status_codes.Empty()) {
+ return nullptr; // Duplicate.
+ }
+ if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
+ for (grpc_json* element = sub_field->child; element != nullptr;
+ element = element->next) {
+ if (element->type != GRPC_JSON_STRING) return nullptr;
+ grpc_status_code status;
+ if (!grpc_status_code_from_string(element->value, &status)) {
+ return nullptr;
+ }
+ retry_policy->retryable_status_codes.Add(status);
+ }
+ if (retry_policy->retryable_status_codes.Empty()) return nullptr;
+ }
+ }
+ // Make sure required fields are set.
+ if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
+ retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
+ retry_policy->retryable_status_codes.Empty()) {
+ return nullptr;
+ }
+ return retry_policy;
+}
+
+} // namespace
+
+RefCountedPtr<ClientChannelMethodParams>
+ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
+ RefCountedPtr<ClientChannelMethodParams> method_params =
+ MakeRefCounted<ClientChannelMethodParams>();
+ for (grpc_json* field = json->child; field != nullptr; field = field->next) {
+ if (field->key == nullptr) continue;
+ if (strcmp(field->key, "waitForReady") == 0) {
+ if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
+ return nullptr; // Duplicate.
+ }
+ if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
+ return nullptr;
+ }
+ } else if (strcmp(field->key, "timeout") == 0) {
+ if (method_params->timeout_ > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
+ } else if (strcmp(field->key, "retryPolicy") == 0) {
+ if (method_params->retry_policy_ != nullptr) {
+ return nullptr; // Duplicate.
+ }
+ method_params->retry_policy_ = ParseRetryPolicy(field);
+ if (method_params->retry_policy_ == nullptr) return nullptr;
+ }
+ }
+ return method_params;
+}
+
+} // namespace internal
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h
new file mode 100644
index 0000000000..f1fb7406bc
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h
@@ -0,0 +1,146 @@
+/*
+ *
+ * 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_RESOLVER_RESULT_PARSING_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/retry_throttle.h"
+#include "src/core/lib/channel/status_util.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
+#include "src/core/lib/json/json.h"
+#include "src/core/lib/slice/slice_hash_table.h"
+#include "src/core/lib/transport/service_config.h"
+
+namespace grpc_core {
+namespace internal {
+
+class ClientChannelMethodParams;
+
+// A table mapping from a method name to its method parameters.
+typedef grpc_core::SliceHashTable<
+ grpc_core::RefCountedPtr<ClientChannelMethodParams>>
+ ClientChannelMethodParamsTable;
+
+// A container of processed fields from the resolver result. Simplifies the
+// usage of resolver result.
+class ProcessedResolverResult {
+ public:
+ // Processes the resolver result and populates the relative members
+ // for later consumption. Tries to parse retry parameters only if parse_retry
+ // is true.
+ ProcessedResolverResult(const grpc_channel_args* resolver_result,
+ bool parse_retry);
+
+ // Getters. Any managed object's ownership is transferred.
+ grpc_core::UniquePtr<char> service_config_json() {
+ return std::move(service_config_json_);
+ }
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() {
+ return std::move(retry_throttle_data_);
+ }
+ grpc_core::RefCountedPtr<ClientChannelMethodParamsTable>
+ method_params_table() {
+ return std::move(method_params_table_);
+ }
+ grpc_core::UniquePtr<char> lb_policy_name() {
+ return std::move(lb_policy_name_);
+ }
+ grpc_json* lb_policy_config() { return lb_policy_config_; }
+
+ private:
+ // Finds the service config; extracts LB config and (maybe) retry throttle
+ // params from it.
+ void ProcessServiceConfig(const grpc_channel_args* resolver_result,
+ bool parse_retry);
+
+ // Finds the LB policy name (when no LB config was found).
+ void ProcessLbPolicyName(const grpc_channel_args* resolver_result);
+
+ // Parses the service config. Intended to be used by
+ // ServiceConfig::ParseGlobalParams.
+ static void ParseServiceConfig(const grpc_json* field,
+ ProcessedResolverResult* parsing_state);
+ // Parses the LB config from service config.
+ void ParseLbConfigFromServiceConfig(const grpc_json* field);
+ // Parses the retry throttle parameters from service config.
+ void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field);
+
+ // Service config.
+ grpc_core::UniquePtr<char> service_config_json_;
+ grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config_;
+ // LB policy.
+ grpc_json* lb_policy_config_ = nullptr;
+ grpc_core::UniquePtr<char> lb_policy_name_;
+ // Retry throttle data.
+ char* server_name_ = nullptr;
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
+ // Method params table.
+ grpc_core::RefCountedPtr<ClientChannelMethodParamsTable> method_params_table_;
+};
+
+// The parameters of a method.
+class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
+ public:
+ enum WaitForReady {
+ WAIT_FOR_READY_UNSET = 0,
+ WAIT_FOR_READY_FALSE,
+ WAIT_FOR_READY_TRUE
+ };
+
+ struct RetryPolicy {
+ int max_attempts = 0;
+ grpc_millis initial_backoff = 0;
+ grpc_millis max_backoff = 0;
+ float backoff_multiplier = 0;
+ StatusCodeSet retryable_status_codes;
+ };
+
+ /// Creates a method_parameters object from \a json.
+ /// Intended for use with ServiceConfig::CreateMethodConfigTable().
+ static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
+ const grpc_json* json);
+
+ grpc_millis timeout() const { return timeout_; }
+ WaitForReady wait_for_ready() const { return wait_for_ready_; }
+ const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T, typename... Args>
+ friend T* grpc_core::New(Args&&... args);
+
+ // So Delete() can call our private dtor.
+ template <typename T>
+ friend void grpc_core::Delete(T*);
+
+ ClientChannelMethodParams() {}
+ virtual ~ClientChannelMethodParams() {}
+
+ grpc_millis timeout_ = 0;
+ WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
+ UniquePtr<RetryPolicy> retry_policy_;
+};
+
+} // namespace internal
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H */
diff --git a/src/core/ext/filters/client_channel/server_address.cc b/src/core/ext/filters/client_channel/server_address.cc
new file mode 100644
index 0000000000..ec33cbbd95
--- /dev/null
+++ b/src/core/ext/filters/client_channel/server_address.cc
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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/server_address.h"
+
+#include <string.h>
+
+namespace grpc_core {
+
+//
+// ServerAddress
+//
+
+ServerAddress::ServerAddress(const grpc_resolved_address& address,
+ grpc_channel_args* args)
+ : address_(address), args_(args) {}
+
+ServerAddress::ServerAddress(const void* address, size_t address_len,
+ grpc_channel_args* args)
+ : args_(args) {
+ memcpy(address_.addr, address, address_len);
+ address_.len = static_cast<socklen_t>(address_len);
+}
+
+int ServerAddress::Cmp(const ServerAddress& other) const {
+ if (address_.len > other.address_.len) return 1;
+ if (address_.len < other.address_.len) return -1;
+ int retval = memcmp(address_.addr, other.address_.addr, address_.len);
+ if (retval != 0) return retval;
+ return grpc_channel_args_compare(args_, other.args_);
+}
+
+bool ServerAddress::IsBalancer() const {
+ return grpc_channel_arg_get_bool(
+ grpc_channel_args_find(args_, GRPC_ARG_ADDRESS_IS_BALANCER), false);
+}
+
+//
+// ServerAddressList
+//
+
+namespace {
+
+void* ServerAddressListCopy(void* addresses) {
+ ServerAddressList* a = static_cast<ServerAddressList*>(addresses);
+ return New<ServerAddressList>(*a);
+}
+
+void ServerAddressListDestroy(void* addresses) {
+ ServerAddressList* a = static_cast<ServerAddressList*>(addresses);
+ Delete(a);
+}
+
+int ServerAddressListCompare(void* addresses1, void* addresses2) {
+ ServerAddressList* a1 = static_cast<ServerAddressList*>(addresses1);
+ ServerAddressList* a2 = static_cast<ServerAddressList*>(addresses2);
+ if (a1->size() > a2->size()) return 1;
+ if (a1->size() < a2->size()) return -1;
+ for (size_t i = 0; i < a1->size(); ++i) {
+ int retval = (*a1)[i].Cmp((*a2)[i]);
+ if (retval != 0) return retval;
+ }
+ return 0;
+}
+
+const grpc_arg_pointer_vtable server_addresses_arg_vtable = {
+ ServerAddressListCopy, ServerAddressListDestroy, ServerAddressListCompare};
+
+} // namespace
+
+grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses) {
+ return grpc_channel_arg_pointer_create(
+ const_cast<char*>(GRPC_ARG_SERVER_ADDRESS_LIST),
+ const_cast<ServerAddressList*>(addresses), &server_addresses_arg_vtable);
+}
+
+ServerAddressList* FindServerAddressListChannelArg(
+ const grpc_channel_args* channel_args) {
+ const grpc_arg* lb_addresses_arg =
+ grpc_channel_args_find(channel_args, GRPC_ARG_SERVER_ADDRESS_LIST);
+ if (lb_addresses_arg == nullptr || lb_addresses_arg->type != GRPC_ARG_POINTER)
+ return nullptr;
+ return static_cast<ServerAddressList*>(lb_addresses_arg->value.pointer.p);
+}
+
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/server_address.h b/src/core/ext/filters/client_channel/server_address.h
new file mode 100644
index 0000000000..3a1bf1df67
--- /dev/null
+++ b/src/core/ext/filters/client_channel/server_address.h
@@ -0,0 +1,108 @@
+/*
+ *
+ * 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_SERVER_ADDRESS_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/uri/uri_parser.h"
+
+// Channel arg key for ServerAddressList.
+#define GRPC_ARG_SERVER_ADDRESS_LIST "grpc.server_address_list"
+
+// Channel arg key for a bool indicating whether an address is a grpclb
+// load balancer (as opposed to a backend).
+#define GRPC_ARG_ADDRESS_IS_BALANCER "grpc.address_is_balancer"
+
+// Channel arg key for a string indicating an address's balancer name.
+#define GRPC_ARG_ADDRESS_BALANCER_NAME "grpc.address_balancer_name"
+
+namespace grpc_core {
+
+//
+// ServerAddress
+//
+
+// A server address is a grpc_resolved_address with an associated set of
+// channel args. Any args present here will be merged into the channel
+// args when a subchannel is created for this address.
+class ServerAddress {
+ public:
+ // Takes ownership of args.
+ ServerAddress(const grpc_resolved_address& address, grpc_channel_args* args);
+ ServerAddress(const void* address, size_t address_len,
+ grpc_channel_args* args);
+
+ ~ServerAddress() { grpc_channel_args_destroy(args_); }
+
+ // Copyable.
+ ServerAddress(const ServerAddress& other)
+ : address_(other.address_), args_(grpc_channel_args_copy(other.args_)) {}
+ ServerAddress& operator=(const ServerAddress& other) {
+ address_ = other.address_;
+ grpc_channel_args_destroy(args_);
+ args_ = grpc_channel_args_copy(other.args_);
+ return *this;
+ }
+
+ // Movable.
+ ServerAddress(ServerAddress&& other)
+ : address_(other.address_), args_(other.args_) {
+ other.args_ = nullptr;
+ }
+ ServerAddress& operator=(ServerAddress&& other) {
+ address_ = other.address_;
+ args_ = other.args_;
+ other.args_ = nullptr;
+ return *this;
+ }
+
+ bool operator==(const ServerAddress& other) const { return Cmp(other) == 0; }
+
+ int Cmp(const ServerAddress& other) const;
+
+ const grpc_resolved_address& address() const { return address_; }
+ const grpc_channel_args* args() const { return args_; }
+
+ bool IsBalancer() const;
+
+ private:
+ grpc_resolved_address address_;
+ grpc_channel_args* args_;
+};
+
+//
+// ServerAddressList
+//
+
+typedef InlinedVector<ServerAddress, 1> ServerAddressList;
+
+// Returns a channel arg containing \a addresses.
+grpc_arg CreateServerAddressListChannelArg(const ServerAddressList* addresses);
+
+// Returns the ServerListAddress instance in channel_args or NULL.
+ServerAddressList* FindServerAddressListChannelArg(
+ const grpc_channel_args* channel_args);
+
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_SERVER_ADDRESS_H */
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index a56db0201b..9077aa9753 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -153,7 +153,7 @@ struct grpc_subchannel {
/** have we started the backoff loop */
bool backoff_begun;
// reset_backoff() was called while alarm was pending
- bool deferred_reset_backoff;
+ bool retry_immediately;
/** our alarm */
grpc_timer alarm;
@@ -709,8 +709,8 @@ static void on_alarm(void* arg, grpc_error* error) {
if (c->disconnected) {
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
&error, 1);
- } else if (c->deferred_reset_backoff) {
- c->deferred_reset_backoff = false;
+ } else if (c->retry_immediately) {
+ c->retry_immediately = false;
error = GRPC_ERROR_NONE;
} else {
GRPC_ERROR_REF(error);
@@ -837,7 +837,7 @@ static bool publish_transport_locked(grpc_subchannel* c) {
/* publish */
c->connected_subchannel.reset(grpc_core::New<grpc_core::ConnectedSubchannel>(
- stk, c->channelz_subchannel, socket_uuid));
+ stk, c->args, c->channelz_subchannel, socket_uuid));
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
c->connected_subchannel.get(), c);
@@ -887,12 +887,12 @@ static void on_subchannel_connected(void* arg, grpc_error* error) {
void grpc_subchannel_reset_backoff(grpc_subchannel* subchannel) {
gpr_mu_lock(&subchannel->mu);
+ subchannel->backoff->Reset();
if (subchannel->have_alarm) {
- subchannel->deferred_reset_backoff = true;
+ subchannel->retry_immediately = true;
grpc_timer_cancel(&subchannel->alarm);
} else {
subchannel->backoff_begun = false;
- subchannel->backoff->Reset();
maybe_start_connecting_locked(subchannel);
}
gpr_mu_unlock(&subchannel->mu);
@@ -1068,16 +1068,18 @@ grpc_arg grpc_create_subchannel_address_arg(const grpc_resolved_address* addr) {
namespace grpc_core {
ConnectedSubchannel::ConnectedSubchannel(
- grpc_channel_stack* channel_stack,
+ grpc_channel_stack* channel_stack, const grpc_channel_args* args,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel,
intptr_t socket_uuid)
- : RefCountedWithTracing<ConnectedSubchannel>(&grpc_trace_stream_refcount),
+ : RefCounted<ConnectedSubchannel>(&grpc_trace_stream_refcount),
channel_stack_(channel_stack),
+ args_(grpc_channel_args_copy(args)),
channelz_subchannel_(std::move(channelz_subchannel)),
socket_uuid_(socket_uuid) {}
ConnectedSubchannel::~ConnectedSubchannel() {
+ grpc_channel_args_destroy(args_);
GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor");
}
diff --git a/src/core/ext/filters/client_channel/subchannel.h b/src/core/ext/filters/client_channel/subchannel.h
index ec3b4d86e4..14f87f2c68 100644
--- a/src/core/ext/filters/client_channel/subchannel.h
+++ b/src/core/ext/filters/client_channel/subchannel.h
@@ -72,7 +72,7 @@ typedef struct grpc_subchannel_key grpc_subchannel_key;
namespace grpc_core {
-class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
+class ConnectedSubchannel : public RefCounted<ConnectedSubchannel> {
public:
struct CallArgs {
grpc_polling_entity* pollent;
@@ -85,28 +85,31 @@ class ConnectedSubchannel : public RefCountedWithTracing<ConnectedSubchannel> {
size_t parent_data_size;
};
- explicit ConnectedSubchannel(
- grpc_channel_stack* channel_stack,
+ ConnectedSubchannel(
+ grpc_channel_stack* channel_stack, const grpc_channel_args* args,
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
channelz_subchannel,
intptr_t socket_uuid);
~ConnectedSubchannel();
- grpc_channel_stack* channel_stack() { return channel_stack_; }
void NotifyOnStateChange(grpc_pollset_set* interested_parties,
grpc_connectivity_state* state,
grpc_closure* closure);
void Ping(grpc_closure* on_initiate, grpc_closure* on_ack);
grpc_error* CreateCall(const CallArgs& args, grpc_subchannel_call** call);
- channelz::SubchannelNode* channelz_subchannel() {
+
+ grpc_channel_stack* channel_stack() const { return channel_stack_; }
+ const grpc_channel_args* args() const { return args_; }
+ channelz::SubchannelNode* channelz_subchannel() const {
return channelz_subchannel_.get();
}
- intptr_t socket_uuid() { return socket_uuid_; }
+ intptr_t socket_uuid() const { return socket_uuid_; }
size_t GetInitialCallSizeEstimate(size_t parent_data_size) const;
private:
grpc_channel_stack* channel_stack_;
+ grpc_channel_args* args_;
// ref counted pointer to the channelz node in this connected subchannel's
// owning subchannel.
grpc_core::RefCountedPtr<grpc_core::channelz::SubchannelNode>
diff --git a/src/core/ext/filters/client_channel/subchannel_index.cc b/src/core/ext/filters/client_channel/subchannel_index.cc
index 1c23a6c4be..aa8441f17b 100644
--- a/src/core/ext/filters/client_channel/subchannel_index.cc
+++ b/src/core/ext/filters/client_channel/subchannel_index.cc
@@ -91,7 +91,7 @@ void grpc_subchannel_key_destroy(grpc_subchannel_key* k) {
gpr_free(k);
}
-static void sck_avl_destroy(void* p, void* user_data) {
+static void sck_avl_destroy(void* p, void* unused) {
grpc_subchannel_key_destroy(static_cast<grpc_subchannel_key*>(p));
}
@@ -104,7 +104,7 @@ static long sck_avl_compare(void* a, void* b, void* unused) {
static_cast<grpc_subchannel_key*>(b));
}
-static void scv_avl_destroy(void* p, void* user_data) {
+static void scv_avl_destroy(void* p, void* unused) {
GRPC_SUBCHANNEL_WEAK_UNREF((grpc_subchannel*)p, "subchannel_index");
}
@@ -137,7 +137,7 @@ void grpc_subchannel_index_shutdown(void) {
void grpc_subchannel_index_unref(void) {
if (gpr_unref(&g_refcount)) {
gpr_mu_destroy(&g_mu);
- grpc_avl_unref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(g_subchannel_index, nullptr);
}
}
@@ -147,13 +147,12 @@ grpc_subchannel* grpc_subchannel_index_find(grpc_subchannel_key* key) {
// Lock, and take a reference to the subchannel index.
// We don't need to do the search under a lock as avl's are immutable.
gpr_mu_lock(&g_mu);
- grpc_avl index = grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr);
gpr_mu_unlock(&g_mu);
grpc_subchannel* c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(
- (grpc_subchannel*)grpc_avl_get(index, key, grpc_core::ExecCtx::Get()),
- "index_find");
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ (grpc_subchannel*)grpc_avl_get(index, key, nullptr), "index_find");
+ grpc_avl_unref(index, nullptr);
return c;
}
@@ -169,13 +168,11 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
// Compare and swap loop:
// - take a reference to the current index
gpr_mu_lock(&g_mu);
- grpc_avl index =
- grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr);
gpr_mu_unlock(&g_mu);
// - Check to see if a subchannel already exists
- c = static_cast<grpc_subchannel*>(
- grpc_avl_get(index, key, grpc_core::ExecCtx::Get()));
+ c = static_cast<grpc_subchannel*>(grpc_avl_get(index, key, nullptr));
if (c != nullptr) {
c = GRPC_SUBCHANNEL_REF_FROM_WEAK_REF(c, "index_register");
}
@@ -184,11 +181,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
need_to_unref_constructed = true;
} else {
// no -> update the avl and compare/swap
- grpc_avl updated =
- grpc_avl_add(grpc_avl_ref(index, grpc_core::ExecCtx::Get()),
- subchannel_key_copy(key),
- GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"),
- grpc_core::ExecCtx::Get());
+ grpc_avl updated = grpc_avl_add(
+ grpc_avl_ref(index, nullptr), subchannel_key_copy(key),
+ GRPC_SUBCHANNEL_WEAK_REF(constructed, "index_register"), nullptr);
// it may happen (but it's expected to be unlikely)
// that some other thread has changed the index:
@@ -200,9 +195,9 @@ grpc_subchannel* grpc_subchannel_index_register(grpc_subchannel_key* key,
}
gpr_mu_unlock(&g_mu);
- grpc_avl_unref(updated, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(updated, nullptr);
}
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(index, nullptr);
}
if (need_to_unref_constructed) {
@@ -219,24 +214,22 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key,
// Compare and swap loop:
// - take a reference to the current index
gpr_mu_lock(&g_mu);
- grpc_avl index =
- grpc_avl_ref(g_subchannel_index, grpc_core::ExecCtx::Get());
+ grpc_avl index = grpc_avl_ref(g_subchannel_index, nullptr);
gpr_mu_unlock(&g_mu);
// Check to see if this key still refers to the previously
// registered subchannel
- grpc_subchannel* c = static_cast<grpc_subchannel*>(
- grpc_avl_get(index, key, grpc_core::ExecCtx::Get()));
+ grpc_subchannel* c =
+ static_cast<grpc_subchannel*>(grpc_avl_get(index, key, nullptr));
if (c != constructed) {
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(index, nullptr);
break;
}
// compare and swap the update (some other thread may have
// mutated the index behind us)
grpc_avl updated =
- grpc_avl_remove(grpc_avl_ref(index, grpc_core::ExecCtx::Get()), key,
- grpc_core::ExecCtx::Get());
+ grpc_avl_remove(grpc_avl_ref(index, nullptr), key, nullptr);
gpr_mu_lock(&g_mu);
if (index.root == g_subchannel_index.root) {
@@ -245,8 +238,8 @@ void grpc_subchannel_index_unregister(grpc_subchannel_key* key,
}
gpr_mu_unlock(&g_mu);
- grpc_avl_unref(updated, grpc_core::ExecCtx::Get());
- grpc_avl_unref(index, grpc_core::ExecCtx::Get());
+ grpc_avl_unref(updated, nullptr);
+ grpc_avl_unref(index, nullptr);
}
}
diff --git a/src/core/ext/transport/chttp2/client/chttp2_connector.cc b/src/core/ext/transport/chttp2/client/chttp2_connector.cc
index 60a32022f5..42a2e2e896 100644
--- a/src/core/ext/transport/chttp2/client/chttp2_connector.cc
+++ b/src/core/ext/transport/chttp2/client/chttp2_connector.cc
@@ -117,8 +117,9 @@ static void on_handshake_done(void* arg, grpc_error* error) {
c->args.interested_parties);
c->result->transport =
grpc_create_chttp2_transport(args->args, args->endpoint, true);
- c->result->socket_uuid =
- grpc_chttp2_transport_get_socket_uuid(c->result->transport);
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node =
+ grpc_chttp2_transport_get_socket_node(c->result->transport);
+ c->result->socket_uuid = socket_node == nullptr ? 0 : socket_node->uuid();
GPR_ASSERT(c->result->transport);
// TODO(roth): We ideally want to wait until we receive HTTP/2
// settings from the server before we consider the connection
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
index e73eee4353..9612698e96 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc
@@ -110,14 +110,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
grpc_channel_args* args_with_authority =
grpc_channel_args_copy_and_add(args->args, args_to_add, num_args_to_add);
grpc_uri_destroy(server_uri);
- grpc_channel_security_connector* subchannel_security_connector = nullptr;
// Create the security connector using the credentials and target name.
grpc_channel_args* new_args_from_connector = nullptr;
- const grpc_security_status security_status =
- grpc_channel_credentials_create_security_connector(
- channel_credentials, authority.get(), args_with_authority,
- &subchannel_security_connector, &new_args_from_connector);
- if (security_status != GRPC_SECURITY_OK) {
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ subchannel_security_connector =
+ channel_credentials->create_security_connector(
+ /*call_creds=*/nullptr, authority.get(), args_with_authority,
+ &new_args_from_connector);
+ if (subchannel_security_connector == nullptr) {
gpr_log(GPR_ERROR,
"Failed to create secure subchannel for secure name '%s'",
authority.get());
@@ -125,15 +125,14 @@ static grpc_subchannel_args* get_secure_naming_subchannel_args(
return nullptr;
}
grpc_arg new_security_connector_arg =
- grpc_security_connector_to_arg(&subchannel_security_connector->base);
+ grpc_security_connector_to_arg(subchannel_security_connector.get());
grpc_channel_args* new_args = grpc_channel_args_copy_and_add(
new_args_from_connector != nullptr ? new_args_from_connector
: args_with_authority,
&new_security_connector_arg, 1);
- GRPC_SECURITY_CONNECTOR_UNREF(&subchannel_security_connector->base,
- "lb_channel_create");
+ subchannel_security_connector.reset(DEBUG_LOCATION, "lb_channel_create");
if (new_args_from_connector != nullptr) {
grpc_channel_args_destroy(new_args_from_connector);
}
diff --git a/src/core/ext/transport/chttp2/server/chttp2_server.cc b/src/core/ext/transport/chttp2/server/chttp2_server.cc
index 33d2b22aa5..3d09187b9b 100644
--- a/src/core/ext/transport/chttp2/server/chttp2_server.cc
+++ b/src/core/ext/transport/chttp2/server/chttp2_server.cc
@@ -149,7 +149,7 @@ static void on_handshake_done(void* arg, grpc_error* error) {
grpc_server_setup_transport(
connection_state->svr_state->server, transport,
connection_state->accepting_pollset, args->args,
- grpc_chttp2_transport_get_socket_uuid(transport), resource_user);
+ grpc_chttp2_transport_get_socket_node(transport), resource_user);
// Use notify_on_receive_settings callback to enforce the
// handshake deadline.
connection_state->transport =
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
index b9024a87e2..c29c1e58cd 100644
--- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.cc
@@ -61,7 +61,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server* server,
grpc_endpoint_add_to_pollset(server_endpoint, pollsets[i]);
}
- grpc_server_setup_transport(server, transport, nullptr, server_args, 0);
+ grpc_server_setup_transport(server, transport, nullptr, server_args, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
}
diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
index 6689a17da6..98fdb62070 100644
--- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
+++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.cc
@@ -31,6 +31,7 @@
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/surface/api_trace.h"
@@ -40,9 +41,8 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr,
grpc_server_credentials* creds) {
grpc_core::ExecCtx exec_ctx;
grpc_error* err = GRPC_ERROR_NONE;
- grpc_server_security_connector* sc = nullptr;
+ grpc_core::RefCountedPtr<grpc_server_security_connector> sc;
int port_num = 0;
- grpc_security_status status;
grpc_channel_args* args = nullptr;
GRPC_API_TRACE(
"grpc_server_add_secure_http2_port("
@@ -54,30 +54,27 @@ int grpc_server_add_secure_http2_port(grpc_server* server, const char* addr,
"No credentials specified for secure server port (creds==NULL)");
goto done;
}
- status = grpc_server_credentials_create_security_connector(creds, &sc);
- if (status != GRPC_SECURITY_OK) {
+ sc = creds->create_security_connector();
+ if (sc == nullptr) {
char* msg;
gpr_asprintf(&msg,
"Unable to create secure server with credentials of type %s.",
- creds->type);
- err = grpc_error_set_int(GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg),
- GRPC_ERROR_INT_SECURITY_STATUS, status);
+ creds->type());
+ err = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
gpr_free(msg);
goto done;
}
// Create channel args.
grpc_arg args_to_add[2];
args_to_add[0] = grpc_server_credentials_to_arg(creds);
- args_to_add[1] = grpc_security_connector_to_arg(&sc->base);
+ args_to_add[1] = grpc_security_connector_to_arg(sc.get());
args =
grpc_channel_args_copy_and_add(grpc_server_get_channel_args(server),
args_to_add, GPR_ARRAY_SIZE(args_to_add));
// Add server port.
err = grpc_chttp2_server_add_port(server, addr, args, &port_num);
done:
- if (sc != nullptr) {
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "server");
- }
+ sc.reset(DEBUG_LOCATION, "server");
if (err != GRPC_ERROR_NONE) {
const char* msg = grpc_error_string(err);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 978ecd59e4..9b6574b612 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * 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.
@@ -31,6 +31,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/ext/transport/chttp2/transport/frame_data.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/ext/transport/chttp2/transport/varint.h"
@@ -154,6 +155,7 @@ bool g_flow_control_enabled = true;
/*******************************************************************************
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
*/
+
grpc_chttp2_transport::~grpc_chttp2_transport() {
size_t i;
@@ -168,6 +170,9 @@ grpc_chttp2_transport::~grpc_chttp2_transport() {
grpc_slice_buffer_destroy_internal(&outbuf);
grpc_chttp2_hpack_compressor_destroy(&hpack_compressor);
+ grpc_core::ContextList::Execute(cl, nullptr, GRPC_ERROR_NONE);
+ cl = nullptr;
+
grpc_slice_buffer_destroy_internal(&read_buffer);
grpc_chttp2_hpack_parser_destroy(&hpack_parser);
grpc_chttp2_goaway_parser_destroy(&goaway_parser);
@@ -202,38 +207,6 @@ grpc_chttp2_transport::~grpc_chttp2_transport() {
gpr_free(peer_string);
}
-#ifndef NDEBUG
-void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason,
- const char* file, int line) {
- if (grpc_trace_chttp2_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
- gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
- t, val, val - 1, reason, file, line);
- }
- if (!gpr_unref(&t->refs)) return;
- t->~grpc_chttp2_transport();
- gpr_free(t);
-}
-
-void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason,
- const char* file, int line) {
- if (grpc_trace_chttp2_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
- gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
- t, val, val + 1, reason, file, line);
- }
- gpr_ref(&t->refs);
-}
-#else
-void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) {
- if (!gpr_unref(&t->refs)) return;
- t->~grpc_chttp2_transport();
- gpr_free(t);
-}
-
-void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); }
-#endif
-
static const grpc_transport_vtable* get_vtable(void);
/* Returns whether bdp is enabled */
@@ -485,7 +458,8 @@ static void init_keepalive_pings_if_enabled(grpc_chttp2_transport* t) {
grpc_chttp2_transport::grpc_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user)
- : ep(ep),
+ : refs(1, &grpc_trace_chttp2_refcount),
+ ep(ep),
peer_string(grpc_endpoint_get_peer(ep)),
resource_user(resource_user),
combiner(grpc_combiner_create()),
@@ -495,8 +469,6 @@ grpc_chttp2_transport::grpc_chttp2_transport(
GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) ==
GRPC_CHTTP2_CLIENT_CONNECT_STRLEN);
base.vtable = get_vtable();
- /* one ref is for destroy */
- gpr_ref_init(&refs, 1);
/* 8 is a random stab in the dark as to a good initial size: it's small enough
that it shouldn't waste memory for infrequently used connections, yet
large enough that the exponential growth should happen nicely when it's
@@ -1065,11 +1037,13 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) {
static void write_action(void* gt, grpc_error* error) {
GPR_TIMER_SCOPE("write_action", 0);
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(gt);
+ void* cl = t->cl;
+ t->cl = nullptr;
grpc_endpoint_write(
t->ep, &t->outbuf,
GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t,
grpc_combiner_scheduler(t->combiner)),
- nullptr);
+ cl);
}
/* Callback from the grpc_endpoint after bytes have been written by calling
@@ -1393,6 +1367,8 @@ static void perform_stream_op_locked(void* stream_op,
GRPC_STATS_INC_HTTP2_OP_BATCHES();
+ s->context = op->payload->context;
+ s->traced = op->is_traced;
if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str,
@@ -2837,8 +2813,8 @@ Chttp2IncomingByteStream::Chttp2IncomingByteStream(
: ByteStream(frame_size, flags),
transport_(transport),
stream_(stream),
+ refs_(2),
remaining_bytes_(frame_size) {
- gpr_ref_init(&refs_, 2);
GRPC_ERROR_UNREF(stream->byte_stream_error);
stream->byte_stream_error = GRPC_ERROR_NONE;
}
@@ -2863,14 +2839,6 @@ void Chttp2IncomingByteStream::Orphan() {
GRPC_ERROR_NONE);
}
-void Chttp2IncomingByteStream::Unref() {
- if (gpr_unref(&refs_)) {
- Delete(this);
- }
-}
-
-void Chttp2IncomingByteStream::Ref() { gpr_ref(&refs_); }
-
void Chttp2IncomingByteStream::NextLocked(void* arg,
grpc_error* error_ignored) {
Chttp2IncomingByteStream* bs = static_cast<Chttp2IncomingByteStream*>(arg);
@@ -3177,21 +3145,18 @@ static const grpc_transport_vtable vtable = {sizeof(grpc_chttp2_stream),
static const grpc_transport_vtable* get_vtable(void) { return &vtable; }
-intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) {
+grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>
+grpc_chttp2_transport_get_socket_node(grpc_transport* transport) {
grpc_chttp2_transport* t =
reinterpret_cast<grpc_chttp2_transport*>(transport);
- if (t->channelz_socket != nullptr) {
- return t->channelz_socket->uuid();
- } else {
- return 0;
- }
+ return t->channelz_socket;
}
grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user) {
- auto t = new (gpr_malloc(sizeof(grpc_chttp2_transport)))
- grpc_chttp2_transport(channel_args, ep, is_client, resource_user);
+ auto t = grpc_core::New<grpc_chttp2_transport>(channel_args, ep, is_client,
+ resource_user);
return &t->base;
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
index b3fe1c082e..c22cfb0ad7 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h
@@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
+#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/transport/transport.h"
@@ -35,7 +36,8 @@ grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user = nullptr);
-intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport);
+grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode>
+grpc_chttp2_transport_get_socket_node(grpc_transport* transport);
/// Takes ownership of \a read_buffer, which (if non-NULL) contains
/// leftover bytes previously read from the endpoint (e.g., by handshakers).
diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc
new file mode 100644
index 0000000000..f30d41c332
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/context_list.cc
@@ -0,0 +1,51 @@
+/*
+ *
+ * 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/transport/chttp2/transport/context_list.h"
+
+namespace {
+void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*) = nullptr;
+}
+
+namespace grpc_core {
+void ContextList::Execute(void* arg, grpc_core::Timestamps* ts,
+ grpc_error* error) {
+ ContextList* head = static_cast<ContextList*>(arg);
+ ContextList* to_be_freed;
+ while (head != nullptr) {
+ if (error == GRPC_ERROR_NONE && ts != nullptr) {
+ if (write_timestamps_callback_g) {
+ ts->byte_offset = static_cast<uint32_t>(head->byte_offset_);
+ write_timestamps_callback_g(head->s_->context, ts);
+ }
+ }
+ GRPC_CHTTP2_STREAM_UNREF(static_cast<grpc_chttp2_stream*>(head->s_),
+ "timestamp");
+ to_be_freed = head;
+ head = head->next_;
+ grpc_core::Delete(to_be_freed);
+ }
+}
+
+void grpc_http2_set_write_timestamps_callback(
+ void (*fn)(void*, grpc_core::Timestamps*)) {
+ write_timestamps_callback_g = fn;
+}
+} /* namespace grpc_core */
diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h
new file mode 100644
index 0000000000..d870107749
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/context_list.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/iomgr/buffer_list.h"
+
+#include "src/core/ext/transport/chttp2/transport/internal.h"
+
+namespace grpc_core {
+/** A list of RPC Contexts */
+class ContextList {
+ public:
+ /* Creates a new element with \a context as the value and appends it to the
+ * list. */
+ static void Append(ContextList** head, grpc_chttp2_stream* s) {
+ /* Make sure context is not already present */
+ GRPC_CHTTP2_STREAM_REF(s, "timestamp");
+
+#ifndef NDEBUG
+ ContextList* ptr = *head;
+ while (ptr != nullptr) {
+ if (ptr->s_ == s) {
+ GPR_ASSERT(
+ false &&
+ "Trying to append a stream that is already present in the list");
+ }
+ ptr = ptr->next_;
+ }
+#endif
+
+ /* Create a new element in the list and add it at the front */
+ ContextList* elem = grpc_core::New<ContextList>();
+ elem->s_ = s;
+ elem->byte_offset_ = s->byte_counter;
+ elem->next_ = *head;
+ *head = elem;
+ }
+
+ /* Executes a function \a fn with each context in the list and \a ts. It also
+ * frees up the entire list after this operation. */
+ static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error);
+
+ private:
+ grpc_chttp2_stream* s_ = nullptr;
+ ContextList* next_ = nullptr;
+ size_t byte_offset_ = 0;
+};
+
+void grpc_http2_set_write_timestamps_callback(
+ void (*fn)(void*, grpc_core::Timestamps*));
+} /* namespace grpc_core */
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 3ee408c103..341f5b3977 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -45,6 +45,10 @@
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/transport_impl.h"
+namespace grpc_core {
+class ContextList;
+}
+
/* streams are kept in various linked lists depending on what things need to
happen to them... this enum labels each list */
typedef enum {
@@ -232,8 +236,12 @@ class Chttp2IncomingByteStream : public ByteStream {
// alone for now. We can revisit this once we're able to link against
// libc++, at which point we can eliminate New<> and Delete<> and
// switch to std::shared_ptr<>.
- void Ref();
- void Unref();
+ void Ref() { refs_.Ref(); }
+ void Unref() {
+ if (refs_.Unref()) {
+ grpc_core::Delete(this);
+ }
+ }
void PublishError(grpc_error* error);
@@ -252,7 +260,7 @@ class Chttp2IncomingByteStream : public ByteStream {
grpc_chttp2_transport* transport_; // Immutable.
grpc_chttp2_stream* stream_; // Immutable.
- gpr_refcount refs_;
+ grpc_core::RefCount refs_;
/* Accessed only by transport thread when stream->pending_byte_stream == false
* Accessed only by application thread when stream->pending_byte_stream ==
@@ -286,7 +294,7 @@ struct grpc_chttp2_transport {
~grpc_chttp2_transport();
grpc_transport base; /* must be first */
- gpr_refcount refs;
+ grpc_core::RefCount refs;
grpc_endpoint* ep;
char* peer_string;
@@ -481,7 +489,7 @@ struct grpc_chttp2_transport {
bool keepalive_permit_without_calls = false;
/** keep-alive state machine state */
grpc_chttp2_keepalive_state keepalive_state;
-
+ grpc_core::ContextList* cl = nullptr;
grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> channelz_socket;
uint32_t num_messages_in_next_write = 0;
};
@@ -498,6 +506,7 @@ struct grpc_chttp2_stream {
const void* server_data, gpr_arena* arena);
~grpc_chttp2_stream();
+ void* context;
grpc_chttp2_transport* t;
grpc_stream_refcount* refcount;
@@ -633,8 +642,12 @@ struct grpc_chttp2_stream {
/** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed
*/
bool unprocessed_incoming_frames_decompressed = false;
+ /** Whether the bytes needs to be traced using Fathom */
+ bool traced = false;
/** gRPC header bytes that are already decompressed */
size_t decompressed_header_bytes = 0;
+ /** Byte counter for number of bytes written */
+ size_t byte_counter = 0;
};
/** Transport writing call flow:
@@ -779,15 +792,29 @@ void grpc_chttp2_stream_unref(grpc_chttp2_stream* s);
grpc_chttp2_ref_transport(t, r, __FILE__, __LINE__)
#define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) \
grpc_chttp2_unref_transport(t, r, __FILE__, __LINE__)
-void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason,
- const char* file, int line);
-void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason,
- const char* file, int line);
+inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t,
+ const char* reason, const char* file,
+ int line) {
+ if (t->refs.Unref(grpc_core::DebugLocation(file, line), reason)) {
+ grpc_core::Delete(t);
+ }
+}
+inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t,
+ const char* reason, const char* file,
+ int line) {
+ t->refs.Ref(grpc_core::DebugLocation(file, line), reason);
+}
#else
#define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t)
#define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) grpc_chttp2_unref_transport(t)
-void grpc_chttp2_unref_transport(grpc_chttp2_transport* t);
-void grpc_chttp2_ref_transport(grpc_chttp2_transport* t);
+inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) {
+ if (t->refs.Unref()) {
+ grpc_core::Delete(t);
+ }
+}
+inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) {
+ t->refs.Ref();
+}
#endif
void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id);
diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc
index d533989444..265d3365d3 100644
--- a/src/core/ext/transport/chttp2/transport/writing.cc
+++ b/src/core/ext/transport/chttp2/transport/writing.cc
@@ -18,6 +18,7 @@
#include <grpc/support/port_platform.h>
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include <limits.h>
@@ -362,6 +363,7 @@ class DataSendContext {
grpc_chttp2_encode_data(s_->id, &s_->compressed_data_buffer, send_bytes,
is_last_frame_, &s_->stats.outgoing, &t_->outbuf);
s_->flow_control->SentData(send_bytes);
+ s_->byte_counter += send_bytes;
if (s_->compressed_data_buffer.length == 0) {
s_->sending_bytes += s_->uncompressed_data_size;
}
@@ -496,6 +498,9 @@ class StreamWriteContext {
data_send_context.CompressMoreBytes();
}
}
+ if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) {
+ grpc_core::ContextList::Append(&t_->cl, s_);
+ }
write_context_->ResetPingClock();
if (data_send_context.is_last_frame()) {
SentLastFrame();
diff --git a/src/core/ext/transport/inproc/inproc_transport.cc b/src/core/ext/transport/inproc/inproc_transport.cc
index 61968de4d5..0b9bf5dd11 100644
--- a/src/core/ext/transport/inproc/inproc_transport.cc
+++ b/src/core/ext/transport/inproc/inproc_transport.cc
@@ -1236,7 +1236,7 @@ grpc_channel* grpc_inproc_channel_create(grpc_server* server,
// TODO(ncteisen): design and support channelz GetSocket for inproc.
grpc_server_setup_transport(server, server_transport, nullptr, server_args,
- 0);
+ nullptr);
grpc_channel* channel = grpc_channel_create(
"inproc", client_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport);
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index 8d589f5983..8a596ad460 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -203,33 +203,34 @@ ServerNode::ServerNode(grpc_server* server, size_t channel_tracer_max_nodes)
ServerNode::~ServerNode() {}
-char* ServerNode::RenderServerSockets(intptr_t start_socket_id) {
+char* ServerNode::RenderServerSockets(intptr_t start_socket_id,
+ intptr_t max_results) {
+ // if user does not set max_results, we choose 500.
+ size_t pagination_limit = max_results == 0 ? 500 : max_results;
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
grpc_json* json_iterator = nullptr;
- ChildRefsList socket_refs;
- // 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_socket_id == 0 ? 0 : start_socket_id - 1;
- grpc_server_populate_server_sockets(server_, &socket_refs, start_idx);
+ ChildSocketsList socket_refs;
+ grpc_server_populate_server_sockets(server_, &socket_refs, start_socket_id);
+ // declared early so it can be used outside of the loop.
+ size_t i = 0;
if (!socket_refs.empty()) {
// create list of socket refs
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "socketRef", nullptr, GRPC_JSON_ARRAY, false);
- for (size_t i = 0; i < socket_refs.size(); ++i) {
- json_iterator =
- grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
- GRPC_JSON_OBJECT, false);
- grpc_json_add_number_string_child(json_iterator, nullptr, "socketId",
- socket_refs[i]);
+ for (i = 0; i < GPR_MIN(socket_refs.size(), pagination_limit); ++i) {
+ grpc_json* socket_ref_json = grpc_json_create_child(
+ nullptr, array_parent, nullptr, nullptr, GRPC_JSON_OBJECT, false);
+ json_iterator = grpc_json_add_number_string_child(
+ socket_ref_json, nullptr, "socketId", socket_refs[i]->uuid());
+ grpc_json_create_child(json_iterator, socket_ref_json, "name",
+ socket_refs[i]->remote(), GRPC_JSON_STRING, false);
}
}
- // For now we do not have any pagination rules. In the future we could
- // pick a constant for max_channels_sent for a GetServers request.
- // Tracking: https://github.com/grpc/grpc/issues/16019.
- json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
- GRPC_JSON_TRUE, false);
+ if (i == socket_refs.size()) {
+ json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
+ GRPC_JSON_TRUE, false);
+ }
char* json_str = grpc_json_dump_to_string(top_level_json, 0);
grpc_json_destroy(top_level_json);
return json_str;
diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h
index 64ab5cb3a6..e43792126f 100644
--- a/src/core/lib/channel/channelz.h
+++ b/src/core/lib/channel/channelz.h
@@ -59,6 +59,9 @@ namespace channelz {
// add human readable names as in the channelz.proto
typedef InlinedVector<intptr_t, 10> ChildRefsList;
+class SocketNode;
+typedef InlinedVector<SocketNode*, 10> ChildSocketsList;
+
namespace testing {
class CallCountingHelperPeer;
class ChannelNodePeer;
@@ -207,7 +210,8 @@ class ServerNode : public BaseNode {
grpc_json* RenderJson() override;
- char* RenderServerSockets(intptr_t start_socket_id);
+ char* RenderServerSockets(intptr_t start_socket_id,
+ intptr_t pagination_limit);
// proxy methods to composed classes.
void AddTraceEvent(ChannelTrace::Severity severity, grpc_slice data) {
@@ -251,6 +255,8 @@ class SocketNode : public BaseNode {
gpr_atm_no_barrier_fetch_add(&keepalives_sent_, static_cast<gpr_atm>(1));
}
+ const char* remote() { return remote_.get(); }
+
private:
gpr_atm streams_started_ = 0;
gpr_atm streams_succeeded_ = 0;
diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc
index bc23b90a66..7cca247d64 100644
--- a/src/core/lib/channel/channelz_registry.cc
+++ b/src/core/lib/channel/channelz_registry.cc
@@ -252,7 +252,8 @@ char* grpc_channelz_get_server(intptr_t server_id) {
}
char* grpc_channelz_get_server_sockets(intptr_t server_id,
- intptr_t start_socket_id) {
+ intptr_t start_socket_id,
+ intptr_t max_results) {
grpc_core::channelz::BaseNode* base_node =
grpc_core::channelz::ChannelzRegistry::Get(server_id);
if (base_node == nullptr ||
@@ -263,7 +264,7 @@ char* grpc_channelz_get_server_sockets(intptr_t server_id,
// actually a server node
grpc_core::channelz::ServerNode* server_node =
static_cast<grpc_core::channelz::ServerNode*>(base_node);
- return server_node->RenderServerSockets(start_socket_id);
+ return server_node->RenderServerSockets(start_socket_id, max_results);
}
char* grpc_channelz_get_channel(intptr_t channel_id) {
diff --git a/src/core/lib/debug/trace.cc b/src/core/lib/debug/trace.cc
index 01c1e867d9..cafdb15c69 100644
--- a/src/core/lib/debug/trace.cc
+++ b/src/core/lib/debug/trace.cc
@@ -21,6 +21,7 @@
#include "src/core/lib/debug/trace.h"
#include <string.h>
+#include <type_traits>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
@@ -79,6 +80,8 @@ void TraceFlagList::LogAllTracers() {
// Flags register themselves on the list during construction
TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) {
+ static_assert(std::is_trivially_destructible<TraceFlag>::value,
+ "TraceFlag needs to be trivially destructible.");
set_enabled(default_enabled);
TraceFlagList::Add(this);
}
diff --git a/src/core/lib/debug/trace.h b/src/core/lib/debug/trace.h
index fe6301a3fc..4623494520 100644
--- a/src/core/lib/debug/trace.h
+++ b/src/core/lib/debug/trace.h
@@ -53,7 +53,8 @@ void grpc_tracer_enable_flag(grpc_core::TraceFlag* flag);
class TraceFlag {
public:
TraceFlag(bool default_enabled, const char* name);
- ~TraceFlag() {}
+ // This needs to be trivially destructible as it is used as global variable.
+ ~TraceFlag() = default;
const char* name() const { return name_; }
@@ -102,8 +103,9 @@ typedef TraceFlag DebugOnlyTraceFlag;
#else
class DebugOnlyTraceFlag {
public:
- DebugOnlyTraceFlag(bool default_enabled, const char* name) {}
- bool enabled() { return false; }
+ constexpr DebugOnlyTraceFlag(bool default_enabled, const char* name) {}
+ constexpr bool enabled() const { return false; }
+ constexpr const char* name() const { return "DebugOnlyTraceFlag"; }
private:
void set_enabled(bool enabled) {}
diff --git a/src/core/lib/gpr/sync_posix.cc b/src/core/lib/gpr/sync_posix.cc
index 69bd609485..c09a7598ac 100644
--- a/src/core/lib/gpr/sync_posix.cc
+++ b/src/core/lib/gpr/sync_posix.cc
@@ -30,11 +30,18 @@
// For debug of the timer manager crash only.
// TODO (mxyan): remove after bug is fixed.
#ifdef GRPC_DEBUG_TIMER_MANAGER
+#include <string.h>
void (*g_grpc_debug_timer_manager_stats)(
int64_t timer_manager_init_count, int64_t timer_manager_shutdown_count,
int64_t fork_count, int64_t timer_wait_err, int64_t timer_cv_value,
int64_t timer_mu_value, int64_t abstime_sec_value,
- int64_t abstime_nsec_value) = nullptr;
+ int64_t abstime_nsec_value, int64_t abs_deadline_sec_value,
+ int64_t abs_deadline_nsec_value, int64_t now1_sec_value,
+ int64_t now1_nsec_value, int64_t now2_sec_value, int64_t now2_nsec_value,
+ int64_t add_result_sec_value, int64_t add_result_nsec_value,
+ int64_t sub_result_sec_value, int64_t sub_result_nsec_value,
+ int64_t next_value, int64_t start_time_sec,
+ int64_t start_time_nsec) = nullptr;
int64_t g_timer_manager_init_count = 0;
int64_t g_timer_manager_shutdown_count = 0;
int64_t g_fork_count = 0;
@@ -43,6 +50,19 @@ int64_t g_timer_cv_value = 0;
int64_t g_timer_mu_value = 0;
int64_t g_abstime_sec_value = -1;
int64_t g_abstime_nsec_value = -1;
+int64_t g_abs_deadline_sec_value = -1;
+int64_t g_abs_deadline_nsec_value = -1;
+int64_t g_now1_sec_value = -1;
+int64_t g_now1_nsec_value = -1;
+int64_t g_now2_sec_value = -1;
+int64_t g_now2_nsec_value = -1;
+int64_t g_add_result_sec_value = -1;
+int64_t g_add_result_nsec_value = -1;
+int64_t g_sub_result_sec_value = -1;
+int64_t g_sub_result_nsec_value = -1;
+int64_t g_next_value = -1;
+int64_t g_start_time_sec = -1;
+int64_t g_start_time_nsec = -1;
#endif // GRPC_DEBUG_TIMER_MANAGER
#ifdef GPR_LOW_LEVEL_COUNTERS
@@ -90,17 +110,74 @@ void gpr_cv_init(gpr_cv* cv) {
void gpr_cv_destroy(gpr_cv* cv) { GPR_ASSERT(pthread_cond_destroy(cv) == 0); }
+// For debug of the timer manager crash only.
+// TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+static gpr_timespec gpr_convert_clock_type_debug_timespec(
+ gpr_timespec t, gpr_clock_type clock_type, gpr_timespec& now1,
+ gpr_timespec& now2, gpr_timespec& add_result, gpr_timespec& sub_result) {
+ if (t.clock_type == clock_type) {
+ return t;
+ }
+
+ if (t.tv_sec == INT64_MAX || t.tv_sec == INT64_MIN) {
+ t.clock_type = clock_type;
+ return t;
+ }
+
+ if (clock_type == GPR_TIMESPAN) {
+ return gpr_time_sub(t, gpr_now(t.clock_type));
+ }
+
+ if (t.clock_type == GPR_TIMESPAN) {
+ return gpr_time_add(gpr_now(clock_type), t);
+ }
+
+ now1 = gpr_now(t.clock_type);
+ sub_result = gpr_time_sub(t, now1);
+ now2 = gpr_now(clock_type);
+ add_result = gpr_time_add(now2, sub_result);
+ return add_result;
+}
+
+#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \
+ sub_result) \
+ gpr_convert_clock_type_debug_timespec((t), (clock_type), (now1), (now2), \
+ (add_result), (sub_result))
+#else
+#define gpr_convert_clock_type_debug(t, clock_type, now1, now2, add_result, \
+ sub_result) \
+ gpr_convert_clock_type((t), (clock_type))
+#endif
+
int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
int err = 0;
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+ // For debug of the timer manager crash only.
+ // TODO (mxyan): remove after bug is fixed.
+ gpr_timespec abs_deadline_copy;
+ abs_deadline_copy.tv_sec = abs_deadline.tv_sec;
+ abs_deadline_copy.tv_nsec = abs_deadline.tv_nsec;
+ gpr_timespec now1;
+ gpr_timespec now2;
+ gpr_timespec add_result;
+ gpr_timespec sub_result;
+ memset(&now1, 0, sizeof(now1));
+ memset(&now2, 0, sizeof(now2));
+ memset(&add_result, 0, sizeof(add_result));
+ memset(&sub_result, 0, sizeof(sub_result));
+#endif
if (gpr_time_cmp(abs_deadline, gpr_inf_future(abs_deadline.clock_type)) ==
0) {
err = pthread_cond_wait(cv, mu);
} else {
struct timespec abs_deadline_ts;
#if GPR_LINUX
- abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_MONOTONIC);
+ abs_deadline = gpr_convert_clock_type_debug(
+ abs_deadline, GPR_CLOCK_MONOTONIC, now1, now2, add_result, sub_result);
#else
- abs_deadline = gpr_convert_clock_type(abs_deadline, GPR_CLOCK_REALTIME);
+ abs_deadline = gpr_convert_clock_type_debug(
+ abs_deadline, GPR_CLOCK_REALTIME, now1, now2, add_result, sub_result);
#endif // GPR_LINUX
abs_deadline_ts.tv_sec = static_cast<time_t>(abs_deadline.tv_sec);
abs_deadline_ts.tv_nsec = abs_deadline.tv_nsec;
@@ -123,10 +200,25 @@ int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu, gpr_timespec abs_deadline) {
g_timer_wait_err = err;
g_timer_cv_value = (int64_t)cv;
g_timer_mu_value = (int64_t)mu;
+ g_abs_deadline_sec_value = abs_deadline_copy.tv_sec;
+ g_abs_deadline_nsec_value = abs_deadline_copy.tv_nsec;
+ g_now1_sec_value = now1.tv_sec;
+ g_now1_nsec_value = now1.tv_nsec;
+ g_now2_sec_value = now2.tv_sec;
+ g_now2_nsec_value = now2.tv_nsec;
+ g_add_result_sec_value = add_result.tv_sec;
+ g_add_result_nsec_value = add_result.tv_nsec;
+ g_sub_result_sec_value = sub_result.tv_sec;
+ g_sub_result_nsec_value = sub_result.tv_nsec;
g_grpc_debug_timer_manager_stats(
g_timer_manager_init_count, g_timer_manager_shutdown_count,
g_fork_count, g_timer_wait_err, g_timer_cv_value, g_timer_mu_value,
- g_abstime_sec_value, g_abstime_nsec_value);
+ g_abstime_sec_value, g_abstime_nsec_value, g_abs_deadline_sec_value,
+ g_abs_deadline_nsec_value, g_now1_sec_value, g_now1_nsec_value,
+ g_now2_sec_value, g_now2_nsec_value, g_add_result_sec_value,
+ g_add_result_nsec_value, g_sub_result_sec_value,
+ g_sub_result_nsec_value, g_next_value, g_start_time_sec,
+ g_start_time_nsec);
}
}
#endif
diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h
index 65c2b9634f..66dc751a56 100644
--- a/src/core/lib/gprpp/inlined_vector.h
+++ b/src/core/lib/gprpp/inlined_vector.h
@@ -100,10 +100,7 @@ class InlinedVector {
void reserve(size_t capacity) {
if (capacity > capacity_) {
T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * capacity));
- for (size_t i = 0; i < size_; ++i) {
- new (&new_dynamic[i]) T(std::move(data()[i]));
- data()[i].~T();
- }
+ move_elements(data(), new_dynamic, size_);
gpr_free(dynamic_);
dynamic_ = new_dynamic;
capacity_ = capacity;
@@ -131,13 +128,25 @@ class InlinedVector {
size_--;
}
+ size_t size() const { return size_; }
+ bool empty() const { return size_ == 0; }
+
+ size_t capacity() const { return capacity_; }
+
+ void clear() {
+ destroy_elements();
+ init_data();
+ }
+
+ private:
void copy_from(const InlinedVector& v) {
- // if v is allocated, copy over the buffer.
+ // if v is allocated, make sure we have enough capacity.
if (v.dynamic_ != nullptr) {
reserve(v.capacity_);
- memcpy(dynamic_, v.dynamic_, v.size_ * sizeof(T));
- } else {
- memcpy(inline_, v.inline_, v.size_ * sizeof(T));
+ }
+ // copy over elements
+ for (size_t i = 0; i < v.size_; ++i) {
+ new (&(data()[i])) T(v[i]);
}
// copy over metadata
size_ = v.size_;
@@ -145,11 +154,12 @@ class InlinedVector {
}
void move_from(InlinedVector& v) {
- // if v is allocated, then we steal its buffer, else we copy it.
+ // if v is allocated, then we steal its dynamic array; otherwise, we
+ // move the elements individually.
if (v.dynamic_ != nullptr) {
dynamic_ = v.dynamic_;
} else {
- memcpy(inline_, v.inline_, v.size_ * sizeof(T));
+ move_elements(v.data(), data(), v.size_);
}
// copy over metadata
size_ = v.size_;
@@ -158,17 +168,13 @@ class InlinedVector {
v.init_data();
}
- size_t size() const { return size_; }
- bool empty() const { return size_ == 0; }
-
- size_t capacity() const { return capacity_; }
-
- void clear() {
- destroy_elements();
- init_data();
+ static void move_elements(T* src, T* dst, size_t num_elements) {
+ for (size_t i = 0; i < num_elements; ++i) {
+ new (&dst[i]) T(std::move(src[i]));
+ src[i].~T();
+ }
}
- private:
void init_data() {
dynamic_ = nullptr;
size_ = 0;
diff --git a/src/core/lib/gprpp/memory.h b/src/core/lib/gprpp/memory.h
index e90bedcd9b..b4b63ae771 100644
--- a/src/core/lib/gprpp/memory.h
+++ b/src/core/lib/gprpp/memory.h
@@ -40,15 +40,10 @@
namespace grpc_core {
-// The alignment of memory returned by gpr_malloc().
-constexpr size_t kAlignmentForDefaultAllocationInBytes = 8;
-
// Alternative to new, since we cannot use it (for fear of libstdc++)
template <typename T, typename... Args>
inline T* New(Args&&... args) {
- void* p = alignof(T) > kAlignmentForDefaultAllocationInBytes
- ? gpr_malloc_aligned(sizeof(T), alignof(T))
- : gpr_malloc(sizeof(T));
+ void* p = gpr_malloc(sizeof(T));
return new (p) T(std::forward<Args>(args)...);
}
@@ -57,11 +52,7 @@ template <typename T>
inline void Delete(T* p) {
if (p == nullptr) return;
p->~T();
- if (alignof(T) > kAlignmentForDefaultAllocationInBytes) {
- gpr_free_aligned(p);
- } else {
- gpr_free(p);
- }
+ gpr_free(p);
}
template <typename T>
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index 3123e3f5a3..9053c60111 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -31,6 +31,7 @@
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
namespace grpc_core {
@@ -89,107 +90,42 @@ class InternallyRefCounted : public Orphanable {
template <typename T>
friend class RefCountedPtr;
- InternallyRefCounted() { gpr_ref_init(&refs_, 1); }
- virtual ~InternallyRefCounted() {}
+ // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag.
+ // Note: RefCount tracing is only enabled on debug builds, even when a
+ // TraceFlag is used.
+ template <typename TraceFlagT = TraceFlag>
+ explicit InternallyRefCounted(TraceFlagT* trace_flag = nullptr)
+ : refs_(1, trace_flag) {}
+ virtual ~InternallyRefCounted() = default;
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
IncrementRefCount();
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
-
- void Unref() {
- if (gpr_unref(&refs_)) {
- Delete(static_cast<Child*>(this));
- }
- }
-
- private:
- void IncrementRefCount() { gpr_ref(&refs_); }
-
- gpr_refcount refs_;
-};
-
-// An alternative version of the InternallyRefCounted base class that
-// supports tracing. This is intended to be used in cases where the
-// object will be handled both by idiomatic C++ code using smart
-// pointers and legacy code that is manually calling Ref() and Unref().
-// Once all of our code is converted to idiomatic C++, we may be able to
-// eliminate this class.
-template <typename Child>
-class InternallyRefCountedWithTracing : public Orphanable {
- public:
- // Not copyable nor movable.
- InternallyRefCountedWithTracing(const InternallyRefCountedWithTracing&) =
- delete;
- InternallyRefCountedWithTracing& operator=(
- const InternallyRefCountedWithTracing&) = delete;
-
- GRPC_ABSTRACT_BASE_CLASS
-
- protected:
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
-
- // Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
- template <typename T>
- friend class RefCountedPtr;
-
- InternallyRefCountedWithTracing()
- : InternallyRefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
-
- explicit InternallyRefCountedWithTracing(TraceFlag* trace_flag)
- : trace_flag_(trace_flag) {
- gpr_ref_init(&refs_, 1);
- }
-
-#ifdef NDEBUG
- explicit InternallyRefCountedWithTracing(DebugOnlyTraceFlag* trace_flag)
- : InternallyRefCountedWithTracing() {}
-#endif
-
- virtual ~InternallyRefCountedWithTracing() {}
-
- RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
- IncrementRefCount();
- return RefCountedPtr<Child>(static_cast<Child*>(this));
- }
-
RefCountedPtr<Child> Ref(const DebugLocation& location,
const char* reason) GRPC_MUST_USE_RESULT {
- if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
- trace_flag_->name(), this, location.file(), location.line(),
- old_refs, old_refs + 1, reason);
- }
- return Ref();
+ IncrementRefCount(location, reason);
+ return RefCountedPtr<Child>(static_cast<Child*>(this));
}
- // TODO(roth): Once all of our code is converted to C++ and can use
- // RefCountedPtr<> instead of manual ref-counting, make the Unref() methods
- // private, since they will only be used by RefCountedPtr<>, which is a
- // friend of this class.
-
void Unref() {
- if (gpr_unref(&refs_)) {
+ if (refs_.Unref()) {
Delete(static_cast<Child*>(this));
}
}
-
void Unref(const DebugLocation& location, const char* reason) {
- if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
- trace_flag_->name(), this, location.file(), location.line(),
- old_refs, old_refs - 1, reason);
+ if (refs_.Unref(location, reason)) {
+ Delete(static_cast<Child*>(this));
}
- Unref();
}
private:
- void IncrementRefCount() { gpr_ref(&refs_); }
+ void IncrementRefCount() { refs_.Ref(); }
+ void IncrementRefCount(const DebugLocation& location, const char* reason) {
+ refs_.Ref(location, reason);
+ }
- TraceFlag* trace_flag_ = nullptr;
- gpr_refcount refs_;
+ grpc_core::RefCount refs_;
};
} // namespace grpc_core
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index 81772f3403..fa97ffcfed 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -21,9 +21,12 @@
#include <grpc/support/port_platform.h>
+#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include <atomic>
+#include <cassert>
#include <cinttypes>
#include "src/core/lib/debug/trace.h"
@@ -42,7 +45,7 @@ class PolymorphicRefCount {
protected:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
- virtual ~PolymorphicRefCount() {}
+ virtual ~PolymorphicRefCount() = default;
};
// NonPolymorphicRefCount does not enforce polymorphic destruction of
@@ -55,7 +58,99 @@ class NonPolymorphicRefCount {
protected:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
- ~NonPolymorphicRefCount() {}
+ ~NonPolymorphicRefCount() = default;
+};
+
+// RefCount is a simple atomic ref-count.
+//
+// This is a C++ implementation of gpr_refcount, with inline functions. Due to
+// inline functions, this class is significantly more efficient than
+// gpr_refcount and should be preferred over gpr_refcount whenever possible.
+//
+// TODO(soheil): Remove gpr_refcount after submitting the GRFC and the paragraph
+// above.
+class RefCount {
+ public:
+ using Value = intptr_t;
+
+ // `init` is the initial refcount stored in this object.
+ //
+ // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag.
+ // Note: RefCount tracing is only enabled on debug builds, even when a
+ // TraceFlag is used.
+ template <typename TraceFlagT = TraceFlag>
+ constexpr explicit RefCount(Value init = 1, TraceFlagT* trace_flag = nullptr)
+ :
+#ifndef NDEBUG
+ trace_flag_(trace_flag),
+#endif
+ value_(init) {
+ }
+
+ // Increases the ref-count by `n`.
+ void Ref(Value n = 1) {
+ GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed));
+ }
+ void Ref(const DebugLocation& location, const char* reason, Value n = 1) {
+#ifndef NDEBUG
+ if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
+ const RefCount::Value old_refs = get();
+ gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
+ trace_flag_->name(), this, location.file(), location.line(),
+ old_refs, old_refs + n, reason);
+ }
+#endif
+ Ref(n);
+ }
+
+ // Similar to Ref() with an assert on the ref-count being non-zero.
+ void RefNonZero() {
+#ifndef NDEBUG
+ const Value prior =
+ GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed));
+ assert(prior > 0);
+#else
+ Ref();
+#endif
+ }
+ void RefNonZero(const DebugLocation& location, const char* reason) {
+#ifndef NDEBUG
+ if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
+ const RefCount::Value old_refs = get();
+ gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
+ trace_flag_->name(), this, location.file(), location.line(),
+ old_refs, old_refs + 1, reason);
+ }
+#endif
+ RefNonZero();
+ }
+
+ // Decrements the ref-count and returns true if the ref-count reaches 0.
+ bool Unref() {
+ const Value prior =
+ GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel));
+ GPR_DEBUG_ASSERT(prior > 0);
+ return prior == 1;
+ }
+ bool Unref(const DebugLocation& location, const char* reason) {
+#ifndef NDEBUG
+ if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
+ const RefCount::Value old_refs = get();
+ gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
+ trace_flag_->name(), this, location.file(), location.line(),
+ old_refs, old_refs - 1, reason);
+ }
+#endif
+ return Unref();
+ }
+
+ private:
+ Value get() const { return value_.load(std::memory_order_relaxed); }
+
+#ifndef NDEBUG
+ TraceFlag* trace_flag_;
+#endif
+ std::atomic<Value> value_;
};
// A base class for reference-counted objects.
@@ -92,120 +187,57 @@ class RefCounted : public Impl {
return RefCountedPtr<Child>(static_cast<Child*>(this));
}
- // TODO(roth): Once all of our code is converted to C++ and can use
- // RefCountedPtr<> instead of manual ref-counting, make this method
- // private, since it will only be used by RefCountedPtr<>, which is a
- // friend of this class.
- void Unref() {
- if (gpr_unref(&refs_)) {
- Delete(static_cast<Child*>(this));
- }
- }
-
- // Not copyable nor movable.
- RefCounted(const RefCounted&) = delete;
- RefCounted& operator=(const RefCounted&) = delete;
-
- GRPC_ABSTRACT_BASE_CLASS
-
- protected:
- GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
-
- RefCounted() { gpr_ref_init(&refs_, 1); }
-
- // Note: Depending on the Impl used, this dtor can be implicitly virtual.
- ~RefCounted() {}
-
- private:
- // Allow RefCountedPtr<> to access IncrementRefCount().
- template <typename T>
- friend class RefCountedPtr;
-
- void IncrementRefCount() { gpr_ref(&refs_); }
-
- gpr_refcount refs_;
-};
-
-// An alternative version of the RefCounted base class that
-// supports tracing. This is intended to be used in cases where the
-// object will be handled both by idiomatic C++ code using smart
-// pointers and legacy code that is manually calling Ref() and Unref().
-// Once all of our code is converted to idiomatic C++, we may be able to
-// eliminate this class.
-template <typename Child, typename Impl = PolymorphicRefCount>
-class RefCountedWithTracing : public Impl {
- public:
- RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
- IncrementRefCount();
- return RefCountedPtr<Child>(static_cast<Child*>(this));
- }
-
RefCountedPtr<Child> Ref(const DebugLocation& location,
const char* reason) GRPC_MUST_USE_RESULT {
- if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
- trace_flag_->name(), this, location.file(), location.line(),
- old_refs, old_refs + 1, reason);
- }
- return Ref();
+ IncrementRefCount(location, reason);
+ return RefCountedPtr<Child>(static_cast<Child*>(this));
}
// TODO(roth): Once all of our code is converted to C++ and can use
- // RefCountedPtr<> instead of manual ref-counting, make the Unref() methods
- // private, since they will only be used by RefCountedPtr<>, which is a
+ // RefCountedPtr<> instead of manual ref-counting, make this method
+ // private, since it will only be used by RefCountedPtr<>, which is a
// friend of this class.
-
void Unref() {
- if (gpr_unref(&refs_)) {
+ if (refs_.Unref()) {
Delete(static_cast<Child*>(this));
}
}
-
void Unref(const DebugLocation& location, const char* reason) {
- if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
- gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
- trace_flag_->name(), this, location.file(), location.line(),
- old_refs, old_refs - 1, reason);
+ if (refs_.Unref(location, reason)) {
+ Delete(static_cast<Child*>(this));
}
- Unref();
}
// Not copyable nor movable.
- RefCountedWithTracing(const RefCountedWithTracing&) = delete;
- RefCountedWithTracing& operator=(const RefCountedWithTracing&) = delete;
+ RefCounted(const RefCounted&) = delete;
+ RefCounted& operator=(const RefCounted&) = delete;
GRPC_ABSTRACT_BASE_CLASS
protected:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
- RefCountedWithTracing()
- : RefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
-
- explicit RefCountedWithTracing(TraceFlag* trace_flag)
- : trace_flag_(trace_flag) {
- gpr_ref_init(&refs_, 1);
- }
-
-#ifdef NDEBUG
- explicit RefCountedWithTracing(DebugOnlyTraceFlag* trace_flag)
- : RefCountedWithTracing() {}
-#endif
+ // TraceFlagT is defined to accept both DebugOnlyTraceFlag and TraceFlag.
+ // Note: RefCount tracing is only enabled on debug builds, even when a
+ // TraceFlag is used.
+ template <typename TraceFlagT = TraceFlag>
+ explicit RefCounted(TraceFlagT* trace_flag = nullptr)
+ : refs_(1, trace_flag) {}
// Note: Depending on the Impl used, this dtor can be implicitly virtual.
- ~RefCountedWithTracing() {}
+ ~RefCounted() = default;
private:
// Allow RefCountedPtr<> to access IncrementRefCount().
template <typename T>
friend class RefCountedPtr;
- void IncrementRefCount() { gpr_ref(&refs_); }
+ void IncrementRefCount() { refs_.Ref(); }
+ void IncrementRefCount(const DebugLocation& location, const char* reason) {
+ refs_.Ref(location, reason);
+ }
- TraceFlag* trace_flag_ = nullptr;
- gpr_refcount refs_;
+ RefCount refs_;
};
} // namespace grpc_core
diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index facd7c6dce..19f38d7f01 100644
--- a/src/core/lib/gprpp/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -24,6 +24,7 @@
#include <type_traits>
#include <utility>
+#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/memory.h"
namespace grpc_core {
@@ -49,21 +50,19 @@ class RefCountedPtr {
}
template <typename Y>
RefCountedPtr(RefCountedPtr<Y>&& other) {
- value_ = other.value_;
+ value_ = static_cast<T*>(other.value_);
other.value_ = nullptr;
}
// Move assignment.
RefCountedPtr& operator=(RefCountedPtr&& other) {
- if (value_ != nullptr) value_->Unref();
- value_ = other.value_;
+ reset(other.value_);
other.value_ = nullptr;
return *this;
}
template <typename Y>
RefCountedPtr& operator=(RefCountedPtr<Y>&& other) {
- if (value_ != nullptr) value_->Unref();
- value_ = other.value_;
+ reset(other.value_);
other.value_ = nullptr;
return *this;
}
@@ -78,7 +77,7 @@ class RefCountedPtr {
static_assert(std::has_virtual_destructor<T>::value,
"T does not have a virtual dtor");
if (other.value_ != nullptr) other.value_->IncrementRefCount();
- value_ = other.value_;
+ value_ = static_cast<T*>(other.value_);
}
// Copy assignment.
@@ -86,8 +85,7 @@ class RefCountedPtr {
// Note: Order of reffing and unreffing is important here in case value_
// and other.value_ are the same object.
if (other.value_ != nullptr) other.value_->IncrementRefCount();
- if (value_ != nullptr) value_->Unref();
- value_ = other.value_;
+ reset(other.value_);
return *this;
}
template <typename Y>
@@ -97,8 +95,7 @@ class RefCountedPtr {
// Note: Order of reffing and unreffing is important here in case value_
// and other.value_ are the same object.
if (other.value_ != nullptr) other.value_->IncrementRefCount();
- if (value_ != nullptr) value_->Unref();
- value_ = other.value_;
+ reset(other.value_);
return *this;
}
@@ -107,21 +104,29 @@ class RefCountedPtr {
}
// If value is non-null, we take ownership of a ref to it.
- void reset(T* value) {
+ void reset(T* value = nullptr) {
if (value_ != nullptr) value_->Unref();
value_ = value;
}
+ void reset(const DebugLocation& location, const char* reason,
+ T* value = nullptr) {
+ if (value_ != nullptr) value_->Unref(location, reason);
+ value_ = value;
+ }
template <typename Y>
- void reset(Y* value) {
+ void reset(Y* value = nullptr) {
static_assert(std::has_virtual_destructor<T>::value,
"T does not have a virtual dtor");
if (value_ != nullptr) value_->Unref();
- value_ = value;
+ value_ = static_cast<T*>(value);
}
-
- void reset() {
- if (value_ != nullptr) value_->Unref();
- value_ = nullptr;
+ template <typename Y>
+ void reset(const DebugLocation& location, const char* reason,
+ Y* value = nullptr) {
+ static_assert(std::has_virtual_destructor<T>::value,
+ "T does not have a virtual dtor");
+ if (value_ != nullptr) value_->Unref(location, reason);
+ value_ = static_cast<T*>(value);
}
// TODO(roth): This method exists solely as a transition mechanism to allow
diff --git a/src/core/lib/http/httpcli_security_connector.cc b/src/core/lib/http/httpcli_security_connector.cc
index 1c798d368b..fdea7511cc 100644
--- a/src/core/lib/http/httpcli_security_connector.cc
+++ b/src/core/lib/http/httpcli_security_connector.cc
@@ -29,119 +29,125 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker_registry.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/security/credentials/credentials.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"
-typedef struct {
- grpc_channel_security_connector base;
- tsi_ssl_client_handshaker_factory* handshaker_factory;
- char* secure_peer_name;
-} grpc_httpcli_ssl_channel_security_connector;
-
-static void httpcli_ssl_destroy(grpc_security_connector* sc) {
- grpc_httpcli_ssl_channel_security_connector* c =
- reinterpret_cast<grpc_httpcli_ssl_channel_security_connector*>(sc);
- if (c->handshaker_factory != nullptr) {
- tsi_ssl_client_handshaker_factory_unref(c->handshaker_factory);
- c->handshaker_factory = nullptr;
+class grpc_httpcli_ssl_channel_security_connector final
+ : public grpc_channel_security_connector {
+ public:
+ explicit grpc_httpcli_ssl_channel_security_connector(char* secure_peer_name)
+ : grpc_channel_security_connector(
+ /*url_scheme=*/nullptr,
+ /*channel_creds=*/nullptr,
+ /*request_metadata_creds=*/nullptr),
+ secure_peer_name_(secure_peer_name) {}
+
+ ~grpc_httpcli_ssl_channel_security_connector() override {
+ if (handshaker_factory_ != nullptr) {
+ tsi_ssl_client_handshaker_factory_unref(handshaker_factory_);
+ }
+ if (secure_peer_name_ != nullptr) {
+ gpr_free(secure_peer_name_);
+ }
+ }
+
+ tsi_result InitHandshakerFactory(const char* pem_root_certs,
+ const tsi_ssl_root_certs_store* root_store) {
+ tsi_ssl_client_handshaker_options options;
+ memset(&options, 0, sizeof(options));
+ options.pem_root_certs = pem_root_certs;
+ options.root_store = root_store;
+ return tsi_create_ssl_client_handshaker_factory_with_options(
+ &options, &handshaker_factory_);
}
- if (c->secure_peer_name != nullptr) gpr_free(c->secure_peer_name);
- gpr_free(sc);
-}
-static void httpcli_ssl_add_handshakers(grpc_channel_security_connector* sc,
- grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr) {
- grpc_httpcli_ssl_channel_security_connector* c =
- reinterpret_cast<grpc_httpcli_ssl_channel_security_connector*>(sc);
- tsi_handshaker* handshaker = nullptr;
- if (c->handshaker_factory != nullptr) {
- tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
- c->handshaker_factory, c->secure_peer_name, &handshaker);
- if (result != TSI_OK) {
- gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
- tsi_result_to_string(result));
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr) override {
+ tsi_handshaker* handshaker = nullptr;
+ if (handshaker_factory_ != nullptr) {
+ tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
+ handshaker_factory_, secure_peer_name_, &handshaker);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.",
+ tsi_result_to_string(result));
+ }
}
+ grpc_handshake_manager_add(
+ handshake_mgr, grpc_security_handshaker_create(handshaker, this));
}
- grpc_handshake_manager_add(
- handshake_mgr, grpc_security_handshaker_create(handshaker, &sc->base));
-}
-static void httpcli_ssl_check_peer(grpc_security_connector* sc, tsi_peer peer,
- grpc_auth_context** auth_context,
- grpc_closure* on_peer_checked) {
- grpc_httpcli_ssl_channel_security_connector* c =
- reinterpret_cast<grpc_httpcli_ssl_channel_security_connector*>(sc);
- grpc_error* error = GRPC_ERROR_NONE;
-
- /* Check the peer name. */
- if (c->secure_peer_name != nullptr &&
- !tsi_ssl_peer_matches_name(&peer, c->secure_peer_name)) {
- char* msg;
- gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
- c->secure_peer_name);
- error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
- gpr_free(msg);
+ tsi_ssl_client_handshaker_factory* handshaker_factory() const {
+ return handshaker_factory_;
}
- GRPC_CLOSURE_SCHED(on_peer_checked, error);
- tsi_peer_destruct(&peer);
-}
-static int httpcli_ssl_cmp(grpc_security_connector* sc1,
- grpc_security_connector* sc2) {
- grpc_httpcli_ssl_channel_security_connector* c1 =
- reinterpret_cast<grpc_httpcli_ssl_channel_security_connector*>(sc1);
- grpc_httpcli_ssl_channel_security_connector* c2 =
- reinterpret_cast<grpc_httpcli_ssl_channel_security_connector*>(sc2);
- return strcmp(c1->secure_peer_name, c2->secure_peer_name);
-}
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* /*auth_context*/,
+ grpc_closure* on_peer_checked) override {
+ grpc_error* error = GRPC_ERROR_NONE;
+
+ /* Check the peer name. */
+ if (secure_peer_name_ != nullptr &&
+ !tsi_ssl_peer_matches_name(&peer, secure_peer_name_)) {
+ char* msg;
+ gpr_asprintf(&msg, "Peer name %s is not in peer certificate",
+ secure_peer_name_);
+ error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg);
+ gpr_free(msg);
+ }
+ GRPC_CLOSURE_SCHED(on_peer_checked, error);
+ tsi_peer_destruct(&peer);
+ }
-static grpc_security_connector_vtable httpcli_ssl_vtable = {
- httpcli_ssl_destroy, httpcli_ssl_check_peer, httpcli_ssl_cmp};
+ int cmp(const grpc_security_connector* other_sc) const override {
+ auto* other =
+ reinterpret_cast<const grpc_httpcli_ssl_channel_security_connector*>(
+ other_sc);
+ return strcmp(secure_peer_name_, other->secure_peer_name_);
+ }
-static grpc_security_status httpcli_ssl_channel_security_connector_create(
- const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store,
- const char* secure_peer_name, grpc_channel_security_connector** sc) {
- tsi_result result = TSI_OK;
- grpc_httpcli_ssl_channel_security_connector* c;
+ bool check_call_host(const char* host, grpc_auth_context* auth_context,
+ grpc_closure* on_call_host_checked,
+ grpc_error** error) override {
+ *error = GRPC_ERROR_NONE;
+ return true;
+ }
- if (secure_peer_name != nullptr && pem_root_certs == nullptr) {
- gpr_log(GPR_ERROR,
- "Cannot assert a secure peer name without a trust root.");
- return GRPC_SECURITY_ERROR;
+ void cancel_check_call_host(grpc_closure* on_call_host_checked,
+ grpc_error* error) override {
+ GRPC_ERROR_UNREF(error);
}
- c = static_cast<grpc_httpcli_ssl_channel_security_connector*>(
- gpr_zalloc(sizeof(grpc_httpcli_ssl_channel_security_connector)));
+ const char* secure_peer_name() const { return secure_peer_name_; }
- gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.vtable = &httpcli_ssl_vtable;
- if (secure_peer_name != nullptr) {
- c->secure_peer_name = gpr_strdup(secure_peer_name);
+ private:
+ tsi_ssl_client_handshaker_factory* handshaker_factory_ = nullptr;
+ char* secure_peer_name_;
+};
+
+static grpc_core::RefCountedPtr<grpc_channel_security_connector>
+httpcli_ssl_channel_security_connector_create(
+ const char* pem_root_certs, const tsi_ssl_root_certs_store* root_store,
+ const char* secure_peer_name) {
+ if (secure_peer_name != nullptr && pem_root_certs == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Cannot assert a secure peer name without a trust root.");
+ return nullptr;
}
- tsi_ssl_client_handshaker_options options;
- memset(&options, 0, sizeof(options));
- options.pem_root_certs = pem_root_certs;
- options.root_store = root_store;
- result = tsi_create_ssl_client_handshaker_factory_with_options(
- &options, &c->handshaker_factory);
+ grpc_core::RefCountedPtr<grpc_httpcli_ssl_channel_security_connector> c =
+ grpc_core::MakeRefCounted<grpc_httpcli_ssl_channel_security_connector>(
+ secure_peer_name == nullptr ? nullptr : gpr_strdup(secure_peer_name));
+ tsi_result result = c->InitHandshakerFactory(pem_root_certs, root_store);
if (result != TSI_OK) {
gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
tsi_result_to_string(result));
- httpcli_ssl_destroy(&c->base.base);
- *sc = nullptr;
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- // We don't actually need a channel credentials object in this case,
- // but we set it to a non-nullptr address so that we don't trigger
- // assertions in grpc_channel_security_connector_cmp().
- c->base.channel_creds = (grpc_channel_credentials*)1;
- c->base.add_handshakers = httpcli_ssl_add_handshakers;
- *sc = &c->base;
- return GRPC_SECURITY_OK;
+ return c;
}
/* handshaker */
@@ -186,10 +192,11 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host,
}
c->func = on_done;
c->arg = arg;
- grpc_channel_security_connector* sc = nullptr;
- GPR_ASSERT(httpcli_ssl_channel_security_connector_create(
- pem_root_certs, root_store, host, &sc) == GRPC_SECURITY_OK);
- grpc_arg channel_arg = grpc_security_connector_to_arg(&sc->base);
+ grpc_core::RefCountedPtr<grpc_channel_security_connector> sc =
+ httpcli_ssl_channel_security_connector_create(pem_root_certs, root_store,
+ host);
+ GPR_ASSERT(sc != nullptr);
+ grpc_arg channel_arg = grpc_security_connector_to_arg(sc.get());
grpc_channel_args args = {1, &channel_arg};
c->handshake_mgr = grpc_handshake_manager_create();
grpc_handshakers_add(HANDSHAKER_CLIENT, &args,
@@ -197,7 +204,7 @@ static void ssl_handshake(void* arg, grpc_endpoint* tcp, const char* host,
grpc_handshake_manager_do_handshake(
c->handshake_mgr, tcp, nullptr /* channel_args */, deadline,
nullptr /* acceptor */, on_handshake_done, c /* user_data */);
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli");
+ sc.reset(DEBUG_LOCATION, "httpcli");
}
const grpc_httpcli_handshaker grpc_httpcli_ssl = {"https", ssl_handshake};
diff --git a/src/core/lib/http/parser.h b/src/core/lib/http/parser.h
index 1d2e13e831..a8f47c96c8 100644
--- a/src/core/lib/http/parser.h
+++ b/src/core/lib/http/parser.h
@@ -70,13 +70,13 @@ typedef struct grpc_http_request {
/* A response */
typedef struct grpc_http_response {
/* HTTP status code */
- int status;
+ int status = 0;
/* Headers: count and key/values */
- size_t hdr_count;
- grpc_http_header* hdrs;
+ size_t hdr_count = 0;
+ grpc_http_header* hdrs = nullptr;
/* Body: length and contents; contents are NOT null-terminated */
- size_t body_length;
- char* body;
+ size_t body_length = 0;
+ char* body = nullptr;
} grpc_http_response;
typedef struct {
diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc
index 6ada23db1c..ace17a108d 100644
--- a/src/core/lib/iomgr/buffer_list.cc
+++ b/src/core/lib/iomgr/buffer_list.cc
@@ -35,6 +35,9 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no,
TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg);
/* Store the current time as the sendmsg time. */
new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME);
+ new_elem->ts_.scheduled_time = gpr_inf_past(GPR_CLOCK_REALTIME);
+ new_elem->ts_.sent_time = gpr_inf_past(GPR_CLOCK_REALTIME);
+ new_elem->ts_.acked_time = gpr_inf_past(GPR_CLOCK_REALTIME);
if (*head == nullptr) {
*head = new_elem;
return;
@@ -55,10 +58,16 @@ void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) {
gts->clock_type = GPR_CLOCK_REALTIME;
}
+void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts,
+ grpc_error* shudown_err) {
+ gpr_log(GPR_DEBUG, "Timestamps callback has not been registered");
+}
+
/** The saved callback function that will be invoked when we get all the
* timestamps that we are going to get for a TracedBuffer. */
void (*timestamps_callback)(void*, grpc_core::Timestamps*,
- grpc_error* shutdown_err);
+ grpc_error* shutdown_err) =
+ default_timestamps_callback;
} /* namespace */
void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
@@ -99,18 +108,20 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
}
}
-void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) {
+void TracedBuffer::Shutdown(TracedBuffer** head, void* remaining,
+ grpc_error* shutdown_err) {
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* elem = *head;
while (elem != nullptr) {
- if (timestamps_callback) {
- timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err);
- }
+ timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err);
auto* next = elem->next_;
Delete<TracedBuffer>(elem);
elem = next;
}
*head = nullptr;
+ if (remaining != nullptr) {
+ timestamps_callback(remaining, nullptr, shutdown_err);
+ }
GRPC_ERROR_UNREF(shutdown_err);
}
diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h
index cbbf50a657..627f1bde99 100644
--- a/src/core/lib/iomgr/buffer_list.h
+++ b/src/core/lib/iomgr/buffer_list.h
@@ -37,6 +37,8 @@ struct Timestamps {
gpr_timespec scheduled_time;
gpr_timespec sent_time;
gpr_timespec acked_time;
+
+ uint32_t byte_offset; /* byte offset relative to the start of the RPC */
};
/** TracedBuffer is a class to keep track of timestamps for a specific buffer in
@@ -67,13 +69,13 @@ class TracedBuffer {
/** Cleans the list by calling the callback for each traced buffer in the list
* with timestamps that it has. */
- static void Shutdown(grpc_core::TracedBuffer** head,
+ static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
grpc_error* shutdown_err);
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
- TracedBuffer(int seq_no, void* arg)
+ TracedBuffer(uint32_t seq_no, void* arg)
: seq_no_(seq_no), arg_(arg), next_(nullptr) {}
uint32_t seq_no_; /* The sequence number for the last byte in the buffer */
@@ -82,7 +84,12 @@ class TracedBuffer {
grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */
};
#else /* GRPC_LINUX_ERRQUEUE */
-class TracedBuffer {};
+class TracedBuffer {
+ public:
+ /* Dummy shutdown function */
+ static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
+ grpc_error* shutdown_err) {}
+};
#endif /* GRPC_LINUX_ERRQUEUE */
/** Sets the callback function to call when timestamps for a write are
diff --git a/src/core/lib/iomgr/call_combiner.cc b/src/core/lib/iomgr/call_combiner.cc
index 90dda45ba3..6b5759a036 100644
--- a/src/core/lib/iomgr/call_combiner.cc
+++ b/src/core/lib/iomgr/call_combiner.cc
@@ -39,10 +39,57 @@ static gpr_atm encode_cancel_state_error(grpc_error* error) {
return static_cast<gpr_atm>(1) | (gpr_atm)error;
}
+#ifdef GRPC_TSAN_ENABLED
+static void tsan_closure(void* user_data, grpc_error* error) {
+ grpc_call_combiner* call_combiner =
+ static_cast<grpc_call_combiner*>(user_data);
+ // We ref-count the lock, and check if it's already taken.
+ // If it was taken, we should do nothing. Otherwise, we will mark it as
+ // locked. Note that if two different threads try to do this, only one of
+ // them will be able to mark the lock as acquired, while they both run their
+ // callbacks. In such cases (which should never happen for call_combiner),
+ // TSAN will correctly produce an error.
+ //
+ // TODO(soheil): This only covers the callbacks scheduled by
+ // grpc_call_combiner_(start|finish). If in the future, a
+ // callback gets scheduled using other mechanisms, we will need
+ // to add APIs to externally lock call combiners.
+ grpc_core::RefCountedPtr<grpc_call_combiner::TsanLock> lock =
+ call_combiner->tsan_lock;
+ bool prev = false;
+ if (lock->taken.compare_exchange_strong(prev, true)) {
+ TSAN_ANNOTATE_RWLOCK_ACQUIRED(&lock->taken, true);
+ } else {
+ lock.reset();
+ }
+ GRPC_CLOSURE_RUN(call_combiner->original_closure, GRPC_ERROR_REF(error));
+ if (lock != nullptr) {
+ TSAN_ANNOTATE_RWLOCK_RELEASED(&lock->taken, true);
+ bool prev = true;
+ GPR_ASSERT(lock->taken.compare_exchange_strong(prev, false));
+ }
+}
+#endif
+
+static void call_combiner_sched_closure(grpc_call_combiner* call_combiner,
+ grpc_closure* closure,
+ grpc_error* error) {
+#ifdef GRPC_TSAN_ENABLED
+ call_combiner->original_closure = closure;
+ GRPC_CLOSURE_SCHED(&call_combiner->tsan_closure, error);
+#else
+ GRPC_CLOSURE_SCHED(closure, error);
+#endif
+}
+
void grpc_call_combiner_init(grpc_call_combiner* call_combiner) {
gpr_atm_no_barrier_store(&call_combiner->cancel_state, 0);
gpr_atm_no_barrier_store(&call_combiner->size, 0);
gpr_mpscq_init(&call_combiner->queue);
+#ifdef GRPC_TSAN_ENABLED
+ GRPC_CLOSURE_INIT(&call_combiner->tsan_closure, tsan_closure, call_combiner,
+ grpc_schedule_on_exec_ctx);
+#endif
}
void grpc_call_combiner_destroy(grpc_call_combiner* call_combiner) {
@@ -87,7 +134,7 @@ void grpc_call_combiner_start(grpc_call_combiner* call_combiner,
gpr_log(GPR_INFO, " EXECUTING IMMEDIATELY");
}
// Queue was empty, so execute this closure immediately.
- GRPC_CLOSURE_SCHED(closure, error);
+ call_combiner_sched_closure(call_combiner, closure, error);
} else {
if (grpc_call_combiner_trace.enabled()) {
gpr_log(GPR_INFO, " QUEUING");
@@ -134,7 +181,8 @@ void grpc_call_combiner_stop(grpc_call_combiner* call_combiner DEBUG_ARGS,
gpr_log(GPR_INFO, " EXECUTING FROM QUEUE: closure=%p error=%s",
closure, grpc_error_string(closure->error_data.error));
}
- GRPC_CLOSURE_SCHED(closure, closure->error_data.error);
+ call_combiner_sched_closure(call_combiner, closure,
+ closure->error_data.error);
break;
}
} else if (grpc_call_combiner_trace.enabled()) {
diff --git a/src/core/lib/iomgr/call_combiner.h b/src/core/lib/iomgr/call_combiner.h
index c943fb1557..4ec0044f05 100644
--- a/src/core/lib/iomgr/call_combiner.h
+++ b/src/core/lib/iomgr/call_combiner.h
@@ -27,7 +27,10 @@
#include "src/core/lib/gpr/mpscq.h"
#include "src/core/lib/gprpp/inlined_vector.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/iomgr/dynamic_annotations.h"
// A simple, lock-free mechanism for serializing activity related to a
// single call. This is similar to a combiner but is more lightweight.
@@ -40,14 +43,38 @@
extern grpc_core::TraceFlag grpc_call_combiner_trace;
-typedef struct {
+struct grpc_call_combiner {
gpr_atm size = 0; // size_t, num closures in queue or currently executing
gpr_mpscq queue;
// Either 0 (if not cancelled and no cancellation closure set),
// a grpc_closure* (if the lowest bit is 0),
// or a grpc_error* (if the lowest bit is 1).
gpr_atm cancel_state = 0;
-} grpc_call_combiner;
+#ifdef GRPC_TSAN_ENABLED
+ // A fake ref-counted lock that is kept alive after the destruction of
+ // grpc_call_combiner, when we are running the original closure.
+ //
+ // Ideally we want to lock and unlock the call combiner as a pointer, when the
+ // callback is called. However, original_closure is free to trigger
+ // anything on the call combiner (including destruction of grpc_call).
+ // Thus, we need a ref-counted structure that can outlive the call combiner.
+ struct TsanLock
+ : public grpc_core::RefCounted<TsanLock,
+ grpc_core::NonPolymorphicRefCount> {
+ TsanLock() { TSAN_ANNOTATE_RWLOCK_CREATE(&taken); }
+ ~TsanLock() { TSAN_ANNOTATE_RWLOCK_DESTROY(&taken); }
+
+ // To avoid double-locking by the same thread, we should acquire/release
+ // the lock only when taken is false. On each acquire taken must be set to
+ // true.
+ std::atomic<bool> taken{false};
+ };
+ grpc_core::RefCountedPtr<TsanLock> tsan_lock =
+ grpc_core::MakeRefCounted<TsanLock>();
+ grpc_closure tsan_closure;
+ grpc_closure* original_closure;
+#endif
+};
// Assumes memory was initialized to zero.
void grpc_call_combiner_init(grpc_call_combiner* call_combiner);
diff --git a/src/core/lib/iomgr/dynamic_annotations.h b/src/core/lib/iomgr/dynamic_annotations.h
new file mode 100644
index 0000000000..713928023a
--- /dev/null
+++ b/src/core/lib/iomgr/dynamic_annotations.h
@@ -0,0 +1,67 @@
+/*
+ *
+ * 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_IOMGR_DYNAMIC_ANNOTATIONS_H
+#define GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GRPC_TSAN_ENABLED
+
+#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr) \
+ AnnotateHappensBefore(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_HAPPENS_AFTER(addr) \
+ AnnotateHappensAfter(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_RWLOCK_CREATE(addr) \
+ AnnotateRWLockCreate(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr) \
+ AnnotateRWLockDestroy(__FILE__, __LINE__, (void*)(addr))
+#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w) \
+ AnnotateRWLockAcquired(__FILE__, __LINE__, (void*)(addr), (is_w))
+#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w) \
+ AnnotateRWLockReleased(__FILE__, __LINE__, (void*)(addr), (is_w))
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+void AnnotateHappensBefore(const char* file, int line, const volatile void* cv);
+void AnnotateHappensAfter(const char* file, int line, const volatile void* cv);
+void AnnotateRWLockCreate(const char* file, int line,
+ const volatile void* lock);
+void AnnotateRWLockDestroy(const char* file, int line,
+ const volatile void* lock);
+void AnnotateRWLockAcquired(const char* file, int line,
+ const volatile void* lock, long is_w);
+void AnnotateRWLockReleased(const char* file, int line,
+ const volatile void* lock, long is_w);
+#ifdef __cplusplus
+}
+#endif
+
+#else /* GRPC_TSAN_ENABLED */
+
+#define TSAN_ANNOTATE_HAPPENS_BEFORE(addr)
+#define TSAN_ANNOTATE_HAPPENS_AFTER(addr)
+#define TSAN_ANNOTATE_RWLOCK_CREATE(addr)
+#define TSAN_ANNOTATE_RWLOCK_DESTROY(addr)
+#define TSAN_ANNOTATE_RWLOCK_ACQUIRED(addr, is_w)
+#define TSAN_ANNOTATE_RWLOCK_RELEASED(addr, is_w)
+
+#endif /* GRPC_TSAN_ENABLED */
+
+#endif /* GRPC_CORE_LIB_IOMGR_DYNAMIC_ANNOTATIONS_H */
diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc
index 44fb47e19d..06316c6031 100644
--- a/src/core/lib/iomgr/endpoint.cc
+++ b/src/core/lib/iomgr/endpoint.cc
@@ -61,3 +61,7 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); }
grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) {
return ep->vtable->get_resource_user(ep);
}
+
+bool grpc_endpoint_can_track_err(grpc_endpoint* ep) {
+ return ep->vtable->can_track_err(ep);
+}
diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h
index 1f590a80ca..79c8ece263 100644
--- a/src/core/lib/iomgr/endpoint.h
+++ b/src/core/lib/iomgr/endpoint.h
@@ -47,6 +47,7 @@ struct grpc_endpoint_vtable {
grpc_resource_user* (*get_resource_user)(grpc_endpoint* ep);
char* (*get_peer)(grpc_endpoint* ep);
int (*get_fd)(grpc_endpoint* ep);
+ bool (*can_track_err)(grpc_endpoint* ep);
};
/* When data is available on the connection, calls the callback with slices.
@@ -95,6 +96,8 @@ void grpc_endpoint_delete_from_pollset_set(grpc_endpoint* ep,
grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* endpoint);
+bool grpc_endpoint_can_track_err(grpc_endpoint* ep);
+
struct grpc_endpoint {
const grpc_endpoint_vtable* vtable;
};
diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc
index df2cf508c8..7c4bc1ace2 100644
--- a/src/core/lib/iomgr/endpoint_cfstream.cc
+++ b/src/core/lib/iomgr/endpoint_cfstream.cc
@@ -315,6 +315,8 @@ char* CFStreamGetPeer(grpc_endpoint* ep) {
int CFStreamGetFD(grpc_endpoint* ep) { return 0; }
+bool CFStreamCanTrackErr(grpc_endpoint* ep) { return false; }
+
void CFStreamAddToPollset(grpc_endpoint* ep, grpc_pollset* pollset) {}
void CFStreamAddToPollsetSet(grpc_endpoint* ep, grpc_pollset_set* pollset) {}
void CFStreamDeleteFromPollsetSet(grpc_endpoint* ep,
@@ -329,7 +331,8 @@ static const grpc_endpoint_vtable vtable = {CFStreamRead,
CFStreamDestroy,
CFStreamGetResourceUser,
CFStreamGetPeer,
- CFStreamGetFD};
+ CFStreamGetFD,
+ CFStreamCanTrackErr};
grpc_endpoint* grpc_cfstream_endpoint_create(
CFReadStreamRef read_stream, CFWriteStreamRef write_stream,
diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc
index 3afbfd7254..5c5c246f99 100644
--- a/src/core/lib/iomgr/endpoint_pair_posix.cc
+++ b/src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name,
grpc_core::ExecCtx exec_ctx;
gpr_asprintf(&final_name, "%s:client", name);
- p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args,
+ p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args,
"socketpair-server");
gpr_free(final_name);
gpr_asprintf(&final_name, "%s:server", name);
- p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args,
+ p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args,
"socketpair-client");
gpr_free(final_name);
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 38571b1957..4b8c891e9b 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -1242,6 +1242,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag,
* Event engine binding
*/
+static void shutdown_background_closure(void) {}
+
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
@@ -1255,6 +1257,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
true,
+ false,
fd_create,
fd_wrapped_fd,
@@ -1284,6 +1287,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
+ shutdown_background_closure,
shutdown_engine,
};
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 06a382c556..7a4870db78 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -1604,6 +1604,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag,
* Event engine binding
*/
+static void shutdown_background_closure(void) {}
+
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
@@ -1612,6 +1614,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
true,
+ false,
fd_create,
fd_wrapped_fd,
@@ -1641,6 +1644,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
+ shutdown_background_closure,
shutdown_engine,
};
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 16562538a6..67cbfbbd02 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() {
* event engine binding
*/
+static void shutdown_background_closure(void) {}
+
static void shutdown_engine(void) {
pollset_global_shutdown();
if (grpc_cv_wakeup_fds_enabled()) {
@@ -1796,6 +1798,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
false,
+ false,
fd_create,
fd_wrapped_fd,
@@ -1825,6 +1828,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
+ shutdown_background_closure,
shutdown_engine,
};
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 8a7dc7b004..32d1b6c43e 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -36,6 +36,7 @@
#include "src/core/lib/iomgr/ev_epoll1_linux.h"
#include "src/core/lib/iomgr/ev_epollex_linux.h"
#include "src/core/lib/iomgr/ev_poll_posix.h"
+#include "src/core/lib/iomgr/internal_errqueue.h"
grpc_core::TraceFlag grpc_polling_trace(false,
"polling"); /* Disabled by default */
@@ -236,19 +237,22 @@ void grpc_event_engine_shutdown(void) {
}
bool grpc_event_engine_can_track_errors(void) {
-/* Only track errors if platform supports errqueue. */
-#ifdef GRPC_LINUX_ERRQUEUE
- return g_event_engine->can_track_err;
-#else
+ /* Only track errors if platform supports errqueue. */
+ if (grpc_core::kernel_supports_errqueue()) {
+ return g_event_engine->can_track_err;
+ }
return false;
-#endif /* GRPC_LINUX_ERRQUEUE */
+}
+
+bool grpc_event_engine_run_in_background(void) {
+ return g_event_engine->run_in_background;
}
grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) {
GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
- return g_event_engine->fd_create(fd, name,
- track_err && g_event_engine->can_track_err);
+ return g_event_engine->fd_create(
+ fd, name, track_err && grpc_event_engine_can_track_errors());
}
int grpc_fd_wrapped_fd(grpc_fd* fd) {
@@ -395,4 +399,8 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
g_event_engine->pollset_set_del_fd(pollset_set, fd);
}
+void grpc_shutdown_background_closure(void) {
+ g_event_engine->shutdown_background_closure();
+}
+
#endif // GRPC_POSIX_SOCKET_EV
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index b8fb8f534b..812c7a0f0f 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -42,6 +42,7 @@ typedef struct grpc_fd grpc_fd;
typedef struct grpc_event_engine_vtable {
size_t pollset_size;
bool can_track_err;
+ bool run_in_background;
grpc_fd* (*fd_create)(int fd, const char* name, bool track_err);
int (*fd_wrapped_fd)(grpc_fd* fd);
@@ -79,6 +80,7 @@ typedef struct grpc_event_engine_vtable {
void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
+ void (*shutdown_background_closure)(void);
void (*shutdown_engine)(void);
} grpc_event_engine_vtable;
@@ -101,6 +103,11 @@ const char* grpc_get_poll_strategy_name();
*/
bool grpc_event_engine_can_track_errors();
+/* Returns true if polling engine runs in the background, false otherwise.
+ * Currently only 'epollbg' runs in the background.
+ */
+bool grpc_event_engine_run_in_background();
+
/* Create a wrapped file descriptor.
Requires fd is a non-blocking file descriptor.
\a track_err if true means that error events would be tracked separately
@@ -174,6 +181,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd);
void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
+/* Shut down all the closures registered in the background poller. */
+void grpc_shutdown_background_closure();
+
/* override to allow tests to hook poll() usage */
typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int);
extern grpc_poll_function_type grpc_poll_function;
diff --git a/src/core/lib/iomgr/exec_ctx.cc b/src/core/lib/iomgr/exec_ctx.cc
index d68fa0714b..683dd2f649 100644
--- a/src/core/lib/iomgr/exec_ctx.cc
+++ b/src/core/lib/iomgr/exec_ctx.cc
@@ -53,6 +53,13 @@ static void exec_ctx_sched(grpc_closure* closure, grpc_error* error) {
static gpr_timespec g_start_time;
+// For debug of the timer manager crash only.
+// TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+extern int64_t g_start_time_sec;
+extern int64_t g_start_time_nsec;
+#endif // GRPC_DEBUG_TIMER_MANAGER
+
static grpc_millis timespec_to_millis_round_down(gpr_timespec ts) {
ts = gpr_time_sub(ts, g_start_time);
double x = GPR_MS_PER_SEC * static_cast<double>(ts.tv_sec) +
@@ -117,6 +124,12 @@ void ExecCtx::TestOnlyGlobalInit(gpr_timespec new_val) {
void ExecCtx::GlobalInit(void) {
g_start_time = gpr_now(GPR_CLOCK_MONOTONIC);
+ // For debug of the timer manager crash only.
+ // TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+ g_start_time_sec = g_start_time.tv_sec;
+ g_start_time_nsec = g_start_time.tv_nsec;
+#endif
gpr_tls_init(&exec_ctx_);
}
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
index e957bad73d..05ecd2a49b 100644
--- a/src/core/lib/iomgr/fork_posix.cc
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -60,7 +60,7 @@ void grpc_prefork() {
}
if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 &&
strcmp(grpc_get_poll_strategy_name(), "poll") != 0) {
- gpr_log(GPR_ERROR,
+ gpr_log(GPR_INFO,
"Fork support is only compatible with the epoll1 and poll polling "
"strategies");
}
diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc
index 99c22e9055..982d709f09 100644
--- a/src/core/lib/iomgr/internal_errqueue.cc
+++ b/src/core/lib/iomgr/internal_errqueue.cc
@@ -20,17 +20,50 @@
#include "src/core/lib/iomgr/port.h"
+#include <grpc/impl/codegen/log.h>
#include "src/core/lib/iomgr/internal_errqueue.h"
#ifdef GRPC_POSIX_SOCKET_TCP
-bool kernel_supports_errqueue() {
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+namespace grpc_core {
+static bool errqueue_supported = false;
+
+bool kernel_supports_errqueue() { return errqueue_supported; }
+
+void grpc_errqueue_init() {
+/* Both-compile time and run-time linux kernel versions should be atleast 4.0.0
+ */
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
- return true;
+ struct utsname buffer;
+ if (uname(&buffer) != 0) {
+ gpr_log(GPR_ERROR, "uname: %s", strerror(errno));
+ return;
+ }
+ char* release = buffer.release;
+ if (release == nullptr) {
+ return;
+ }
+
+ if (strtol(release, nullptr, 10) >= 4) {
+ errqueue_supported = true;
+ } else {
+ gpr_log(GPR_DEBUG, "ERRQUEUE support not enabled");
+ }
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
- return false;
}
+} /* namespace grpc_core */
+
+#else
+
+namespace grpc_core {
+void grpc_errqueue_init() {}
+} /* namespace grpc_core */
#endif /* GRPC_POSIX_SOCKET_TCP */
diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h
index 9d122808f9..f8644c2536 100644
--- a/src/core/lib/iomgr/internal_errqueue.h
+++ b/src/core/lib/iomgr/internal_errqueue.h
@@ -76,8 +76,14 @@ constexpr uint32_t kTimestampingRecordingOptions =
* Currently allowing only linux kernels above 4.0.0
*/
bool kernel_supports_errqueue();
-} // namespace grpc_core
+
+} /* namespace grpc_core */
#endif /* GRPC_POSIX_SOCKET_TCP */
+namespace grpc_core {
+/* Initializes errqueue support */
+void grpc_errqueue_init();
+} /* namespace grpc_core */
+
#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */
diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc
index 46afda1774..eb29973514 100644
--- a/src/core/lib/iomgr/iomgr.cc
+++ b/src/core/lib/iomgr/iomgr.cc
@@ -33,8 +33,10 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/thd.h"
+#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
+#include "src/core/lib/iomgr/internal_errqueue.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/timer.h"
@@ -57,6 +59,7 @@ void grpc_iomgr_init() {
g_root_object.name = (char*)"root";
grpc_network_status_init();
grpc_iomgr_platform_init();
+ grpc_core::grpc_errqueue_init();
}
void grpc_iomgr_start() { grpc_timer_manager_init(); }
@@ -154,6 +157,10 @@ void grpc_iomgr_shutdown() {
gpr_cv_destroy(&g_rcv);
}
+void grpc_iomgr_shutdown_background_closure() {
+ grpc_iomgr_platform_shutdown_background_closure();
+}
+
void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name) {
obj->name = gpr_strdup(name);
gpr_mu_lock(&g_mu);
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index 537ef8a6ff..8ea9289e06 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -35,6 +35,10 @@ void grpc_iomgr_start();
* exec_ctx. */
void grpc_iomgr_shutdown();
+/** Signals the intention to shutdown all the closures registered in the
+ * background poller. */
+void grpc_iomgr_shutdown_background_closure();
+
/* Exposed only for testing */
size_t grpc_iomgr_count_objects_for_testing();
diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc
index d34c8e7cd1..4b112c9097 100644
--- a/src/core/lib/iomgr/iomgr_custom.cc
+++ b/src/core/lib/iomgr/iomgr_custom.cc
@@ -40,9 +40,11 @@ static void iomgr_platform_init(void) {
}
static void iomgr_platform_flush(void) {}
static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); }
+static void iomgr_platform_shutdown_background_closure(void) {}
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
grpc_custom_resolver_vtable* resolver,
diff --git a/src/core/lib/iomgr/iomgr_internal.cc b/src/core/lib/iomgr/iomgr_internal.cc
index 32dbabb79d..b6c9211865 100644
--- a/src/core/lib/iomgr/iomgr_internal.cc
+++ b/src/core/lib/iomgr/iomgr_internal.cc
@@ -41,3 +41,7 @@ void grpc_iomgr_platform_init() { iomgr_platform_vtable->init(); }
void grpc_iomgr_platform_flush() { iomgr_platform_vtable->flush(); }
void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); }
+
+void grpc_iomgr_platform_shutdown_background_closure() {
+ iomgr_platform_vtable->shutdown_background_closure();
+}
diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h
index b011d9c7b1..bca7409907 100644
--- a/src/core/lib/iomgr/iomgr_internal.h
+++ b/src/core/lib/iomgr/iomgr_internal.h
@@ -35,6 +35,7 @@ typedef struct grpc_iomgr_platform_vtable {
void (*init)(void);
void (*flush)(void);
void (*shutdown)(void);
+ void (*shutdown_background_closure)(void);
} grpc_iomgr_platform_vtable;
void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name);
@@ -52,6 +53,9 @@ void grpc_iomgr_platform_flush(void);
/** tear down all platform specific global iomgr structures */
void grpc_iomgr_platform_shutdown(void);
+/** shut down all the closures registered in the background poller */
+void grpc_iomgr_platform_shutdown_background_closure(void);
+
bool grpc_iomgr_abort_on_leaks(void);
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc
index ca7334c9a4..9386adf060 100644
--- a/src/core/lib/iomgr/iomgr_posix.cc
+++ b/src/core/lib/iomgr/iomgr_posix.cc
@@ -51,8 +51,13 @@ static void iomgr_platform_shutdown(void) {
grpc_wakeup_fd_global_destroy();
}
+static void iomgr_platform_shutdown_background_closure(void) {
+ grpc_shutdown_background_closure();
+}
+
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable);
diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc
index 235a9e0712..552ef4309c 100644
--- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc
+++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc
@@ -54,8 +54,13 @@ static void iomgr_platform_shutdown(void) {
grpc_wakeup_fd_global_destroy();
}
+static void iomgr_platform_shutdown_background_closure(void) {
+ grpc_shutdown_background_closure();
+}
+
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
char* enable_cfstream = getenv(grpc_cfstream_env_var);
diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc
index cdef89cbf0..24ef0dba7b 100644
--- a/src/core/lib/iomgr/iomgr_windows.cc
+++ b/src/core/lib/iomgr/iomgr_windows.cc
@@ -71,8 +71,11 @@ static void iomgr_platform_shutdown(void) {
winsock_shutdown();
}
+static void iomgr_platform_shutdown_background_closure(void) {}
+
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable);
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index bf56a7298d..c8046b21dc 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -62,8 +62,7 @@
#define GRPC_HAVE_UNIX_SOCKET 1
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
-/* TODO(yashykt): Re-enable once Fathom changes are commited.
-#define GRPC_LINUX_ERRQUEUE 1 */
+#define GRPC_LINUX_ERRQUEUE 1
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
#define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1
diff --git a/src/core/lib/iomgr/resolve_address.h b/src/core/lib/iomgr/resolve_address.h
index 6afe94a7a9..7016ffc31a 100644
--- a/src/core/lib/iomgr/resolve_address.h
+++ b/src/core/lib/iomgr/resolve_address.h
@@ -65,7 +65,7 @@ void grpc_set_resolver_impl(grpc_address_resolver_vtable* vtable);
/* Asynchronously resolve addr. Use default_port if a port isn't designated
in addr, otherwise use the port in addr. */
-/* TODO(ctiller): add a timeout here */
+/* TODO(apolcyn): add a timeout here */
void grpc_resolve_address(const char* addr, const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc
index 1b66dceb13..0839bdfef2 100644
--- a/src/core/lib/iomgr/sockaddr_utils.cc
+++ b/src/core/lib/iomgr/sockaddr_utils.cc
@@ -217,6 +217,7 @@ void grpc_string_to_sockaddr(grpc_resolved_address* out, char* addr, int port) {
}
char* grpc_sockaddr_to_uri(const grpc_resolved_address* resolved_addr) {
+ if (resolved_addr->len == 0) return nullptr;
grpc_resolved_address addr_normalized;
if (grpc_sockaddr_is_v4mapped(resolved_addr, &addr_normalized)) {
resolved_addr = &addr_normalized;
diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc
index e02a1898f2..f7a5f36cdc 100644
--- a/src/core/lib/iomgr/tcp_custom.cc
+++ b/src/core/lib/iomgr/tcp_custom.cc
@@ -326,6 +326,8 @@ static grpc_resource_user* endpoint_get_resource_user(grpc_endpoint* ep) {
static int endpoint_get_fd(grpc_endpoint* ep) { return -1; }
+static bool endpoint_can_track_err(grpc_endpoint* ep) { return false; }
+
static grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_write,
endpoint_add_to_pollset,
@@ -335,7 +337,8 @@ static grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_destroy,
endpoint_get_resource_user,
endpoint_get_peer,
- endpoint_get_fd};
+ endpoint_get_fd,
+ endpoint_can_track_err};
grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket,
grpc_resource_quota* resource_quota,
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index aa2704ce26..cfcb190d60 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -260,10 +260,17 @@ static void notify_on_write(grpc_tcp* tcp) {
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp);
}
- cover_self(tcp);
- GRPC_CLOSURE_INIT(&tcp->write_done_closure,
- tcp_drop_uncovered_then_handle_write, tcp,
- grpc_schedule_on_exec_ctx);
+ if (grpc_event_engine_run_in_background()) {
+ // If there is a polling engine always running in the background, there is
+ // no need to run the backup poller.
+ GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp,
+ grpc_schedule_on_exec_ctx);
+ } else {
+ cover_self(tcp);
+ GRPC_CLOSURE_INIT(&tcp->write_done_closure,
+ tcp_drop_uncovered_then_handle_write, tcp,
+ grpc_schedule_on_exec_ctx);
+ }
grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure);
}
@@ -384,6 +391,12 @@ static void tcp_destroy(grpc_endpoint* ep) {
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
+ gpr_mu_lock(&tcp->tb_mu);
+ grpc_core::TracedBuffer::Shutdown(
+ &tcp->tb_head, tcp->outgoing_buffer_arg,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed"));
+ gpr_mu_unlock(&tcp->tb_mu);
+ tcp->outgoing_buffer_arg = nullptr;
gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
grpc_fd_set_error(tcp->em_fd);
}
@@ -621,7 +634,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
if (sending_length == static_cast<size_t>(length)) {
gpr_mu_lock(&tcp->tb_mu);
grpc_core::TracedBuffer::AddNewEntry(
- &tcp->tb_head, static_cast<int>(tcp->bytes_counter + length),
+ &tcp->tb_head, static_cast<uint32_t>(tcp->bytes_counter + length),
tcp->outgoing_buffer_arg);
gpr_mu_unlock(&tcp->tb_mu);
tcp->outgoing_buffer_arg = nullptr;
@@ -673,11 +686,9 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg,
}
/** For linux platforms, reads the socket's error queue and processes error
- * messages from the queue. Returns true if all the errors processed were
- * timestamps. Returns false if any of the errors were not timestamps. For
- * non-linux platforms, error processing is not used/enabled currently.
+ * messages from the queue.
*/
-static bool process_errors(grpc_tcp* tcp) {
+static void process_errors(grpc_tcp* tcp) {
while (true) {
struct iovec iov;
iov.iov_base = nullptr;
@@ -706,10 +717,10 @@ static bool process_errors(grpc_tcp* tcp) {
} while (r < 0 && saved_errno == EINTR);
if (r == -1 && saved_errno == EAGAIN) {
- return true; /* No more errors to process */
+ return; /* No more errors to process */
}
if (r == -1) {
- return false;
+ return;
}
if (grpc_tcp_trace.enabled()) {
if ((msg.msg_flags & MSG_CTRUNC) == 1) {
@@ -719,8 +730,9 @@ static bool process_errors(grpc_tcp* tcp) {
if (msg.msg_controllen == 0) {
/* There was no control message found. It was probably spurious. */
- return true;
+ return;
}
+ bool seen = false;
for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != SOL_SOCKET ||
@@ -732,9 +744,13 @@ static bool process_errors(grpc_tcp* tcp) {
"unknown control message cmsg_level:%d cmsg_type:%d",
cmsg->cmsg_level, cmsg->cmsg_type);
}
- return false;
+ return;
}
- process_timestamp(tcp, &msg, cmsg);
+ cmsg = process_timestamp(tcp, &msg, cmsg);
+ seen = true;
+ }
+ if (!seen) {
+ return;
}
}
}
@@ -749,20 +765,17 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
static_cast<bool>(gpr_atm_acq_load(&tcp->stop_error_notification))) {
/* We aren't going to register to hear on error anymore, so it is safe to
* unref. */
- grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error));
TCP_UNREF(tcp, "error-tracking");
return;
}
/* We are still interested in collecting timestamps, so let's try reading
* them. */
- if (!process_errors(tcp)) {
- /* This was not a timestamps error. This was an actual error. Set the
- * read and write closures to be ready.
- */
- grpc_fd_set_readable(tcp->em_fd);
- grpc_fd_set_writable(tcp->em_fd);
- }
+ process_errors(tcp);
+ /* This might not a timestamps error. Set the read and write closures to be
+ * ready. */
+ grpc_fd_set_readable(tcp->em_fd);
+ grpc_fd_set_writable(tcp->em_fd);
GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure);
@@ -784,6 +797,19 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
}
#endif /* GRPC_LINUX_ERRQUEUE */
+/* If outgoing_buffer_arg is filled, shuts down the list early, so that any
+ * release operations needed can be performed on the arg */
+void tcp_shutdown_buffer_list(grpc_tcp* tcp) {
+ if (tcp->outgoing_buffer_arg) {
+ gpr_mu_lock(&tcp->tb_mu);
+ grpc_core::TracedBuffer::Shutdown(
+ &tcp->tb_head, tcp->outgoing_buffer_arg,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed"));
+ gpr_mu_unlock(&tcp->tb_mu);
+ tcp->outgoing_buffer_arg = nullptr;
+ }
+}
+
/* returns true if done, false if pending; if returning true, *error is set */
#if defined(IOV_MAX) && IOV_MAX < 1000
#define MAX_WRITE_IOVEC IOV_MAX
@@ -831,8 +857,10 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
msg.msg_flags = 0;
if (tcp->outgoing_buffer_arg != nullptr) {
if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length,
- error))
+ error)) {
+ tcp_shutdown_buffer_list(tcp);
return true; /* something went wrong with timestamps */
+ }
} else {
msg.msg_control = nullptr;
msg.msg_controllen = 0;
@@ -856,10 +884,12 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
} else if (errno == EPIPE) {
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
+ tcp_shutdown_buffer_list(tcp);
return true;
} else {
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
+ tcp_shutdown_buffer_list(tcp);
return true;
}
}
@@ -936,17 +966,18 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
GPR_ASSERT(tcp->write_cb == nullptr);
+ tcp->outgoing_buffer_arg = arg;
if (buf->length == 0) {
GRPC_CLOSURE_SCHED(
cb, grpc_fd_is_shutdown(tcp->em_fd)
? tcp_annotate_error(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF"), tcp)
: GRPC_ERROR_NONE);
+ tcp_shutdown_buffer_list(tcp);
return;
}
tcp->outgoing_buffer = buf;
tcp->outgoing_byte_idx = 0;
- tcp->outgoing_buffer_arg = arg;
if (arg) {
GPR_ASSERT(grpc_event_engine_can_track_errors());
}
@@ -999,6 +1030,22 @@ static grpc_resource_user* tcp_get_resource_user(grpc_endpoint* ep) {
return tcp->resource_user;
}
+static bool tcp_can_track_err(grpc_endpoint* ep) {
+ grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
+ if (!grpc_event_engine_can_track_errors()) {
+ return false;
+ }
+ struct sockaddr addr;
+ socklen_t len = sizeof(addr);
+ if (getsockname(tcp->fd, &addr, &len) < 0) {
+ return false;
+ }
+ if (addr.sa_family == AF_INET || addr.sa_family == AF_INET6) {
+ return true;
+ }
+ return false;
+}
+
static const grpc_endpoint_vtable vtable = {tcp_read,
tcp_write,
tcp_add_to_pollset,
@@ -1008,7 +1055,8 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
tcp_destroy,
tcp_get_resource_user,
tcp_get_peer,
- tcp_get_fd};
+ tcp_get_fd,
+ tcp_can_track_err};
#define MAX_CHUNK_SIZE 32 * 1024 * 1024
@@ -1069,6 +1117,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
tcp->is_first_read = true;
tcp->bytes_counter = -1;
tcp->socket_ts_enabled = false;
+ tcp->outgoing_buffer_arg = nullptr;
/* paired with unref in grpc_tcp_destroy */
gpr_ref_init(&tcp->refcount, 1);
gpr_atm_no_barrier_store(&tcp->shutdown_count, 0);
@@ -1113,6 +1162,12 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd,
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
/* Stop errors notification. */
+ gpr_mu_lock(&tcp->tb_mu);
+ grpc_core::TracedBuffer::Shutdown(
+ &tcp->tb_head, tcp->outgoing_buffer_arg,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed"));
+ gpr_mu_unlock(&tcp->tb_mu);
+ tcp->outgoing_buffer_arg = nullptr;
gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
grpc_fd_set_error(tcp->em_fd);
}
diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc
index 64c4a56ae9..4b5250803d 100644
--- a/src/core/lib/iomgr/tcp_windows.cc
+++ b/src/core/lib/iomgr/tcp_windows.cc
@@ -427,6 +427,8 @@ static grpc_resource_user* win_get_resource_user(grpc_endpoint* ep) {
static int win_get_fd(grpc_endpoint* ep) { return -1; }
+static bool win_can_track_err(grpc_endpoint* ep) { return false; }
+
static grpc_endpoint_vtable vtable = {win_read,
win_write,
win_add_to_pollset,
@@ -436,7 +438,8 @@ static grpc_endpoint_vtable vtable = {win_read,
win_destroy,
win_get_resource_user,
win_get_peer,
- win_get_fd};
+ win_get_fd,
+ win_can_track_err};
grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
grpc_channel_args* channel_args,
diff --git a/src/core/lib/iomgr/timer_manager.cc b/src/core/lib/iomgr/timer_manager.cc
index ceba79f678..cb123298cf 100644
--- a/src/core/lib/iomgr/timer_manager.cc
+++ b/src/core/lib/iomgr/timer_manager.cc
@@ -67,6 +67,7 @@ static void timer_thread(void* completed_thread_ptr);
extern int64_t g_timer_manager_init_count;
extern int64_t g_timer_manager_shutdown_count;
extern int64_t g_fork_count;
+extern int64_t g_next_value;
#endif // GRPC_DEBUG_TIMER_MANAGER
static void gc_completed_threads(void) {
@@ -193,6 +194,11 @@ static bool wait_until(grpc_millis next) {
gpr_log(GPR_INFO, "sleep until kicked");
}
+ // For debug of the timer manager crash only.
+ // TODO (mxyan): remove after bug is fixed.
+#ifdef GRPC_DEBUG_TIMER_MANAGER
+ g_next_value = next;
+#endif
gpr_cv_wait(&g_cv_wait, &g_mu,
grpc_millis_to_timespec(next, GPR_CLOCK_MONOTONIC));
diff --git a/src/core/lib/security/context/security_context.cc b/src/core/lib/security/context/security_context.cc
index 16f40b4f55..8443ee0695 100644
--- a/src/core/lib/security/context/security_context.cc
+++ b/src/core/lib/security/context/security_context.cc
@@ -23,6 +23,8 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/arena.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/surface/api_trace.h"
#include "src/core/lib/surface/call.h"
@@ -50,13 +52,11 @@ grpc_call_error grpc_call_set_credentials(grpc_call* call,
ctx = static_cast<grpc_client_security_context*>(
grpc_call_context_get(call, GRPC_CONTEXT_SECURITY));
if (ctx == nullptr) {
- ctx = grpc_client_security_context_create(grpc_call_get_arena(call));
- ctx->creds = grpc_call_credentials_ref(creds);
+ ctx = grpc_client_security_context_create(grpc_call_get_arena(call), creds);
grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
grpc_client_security_context_destroy);
} else {
- grpc_call_credentials_unref(ctx->creds);
- ctx->creds = grpc_call_credentials_ref(creds);
+ ctx->creds = creds != nullptr ? creds->Ref() : nullptr;
}
return GRPC_CALL_OK;
@@ -66,33 +66,45 @@ grpc_auth_context* grpc_call_auth_context(grpc_call* call) {
void* sec_ctx = grpc_call_context_get(call, GRPC_CONTEXT_SECURITY);
GRPC_API_TRACE("grpc_call_auth_context(call=%p)", 1, (call));
if (sec_ctx == nullptr) return nullptr;
- return grpc_call_is_client(call)
- ? GRPC_AUTH_CONTEXT_REF(
- ((grpc_client_security_context*)sec_ctx)->auth_context,
- "grpc_call_auth_context client")
- : GRPC_AUTH_CONTEXT_REF(
- ((grpc_server_security_context*)sec_ctx)->auth_context,
- "grpc_call_auth_context server");
+ if (grpc_call_is_client(call)) {
+ auto* sc = static_cast<grpc_client_security_context*>(sec_ctx);
+ if (sc->auth_context == nullptr) {
+ return nullptr;
+ } else {
+ return sc->auth_context
+ ->Ref(DEBUG_LOCATION, "grpc_call_auth_context client")
+ .release();
+ }
+ } else {
+ auto* sc = static_cast<grpc_server_security_context*>(sec_ctx);
+ if (sc->auth_context == nullptr) {
+ return nullptr;
+ } else {
+ return sc->auth_context
+ ->Ref(DEBUG_LOCATION, "grpc_call_auth_context server")
+ .release();
+ }
+ }
}
void grpc_auth_context_release(grpc_auth_context* context) {
GRPC_API_TRACE("grpc_auth_context_release(context=%p)", 1, (context));
- GRPC_AUTH_CONTEXT_UNREF(context, "grpc_auth_context_unref");
+ if (context == nullptr) return;
+ context->Unref(DEBUG_LOCATION, "grpc_auth_context_unref");
}
/* --- grpc_client_security_context --- */
grpc_client_security_context::~grpc_client_security_context() {
- grpc_call_credentials_unref(creds);
- GRPC_AUTH_CONTEXT_UNREF(auth_context, "client_security_context");
+ auth_context.reset(DEBUG_LOCATION, "client_security_context");
if (extension.instance != nullptr && extension.destroy != nullptr) {
extension.destroy(extension.instance);
}
}
grpc_client_security_context* grpc_client_security_context_create(
- gpr_arena* arena) {
+ gpr_arena* arena, grpc_call_credentials* creds) {
return new (gpr_arena_alloc(arena, sizeof(grpc_client_security_context)))
- grpc_client_security_context();
+ grpc_client_security_context(creds != nullptr ? creds->Ref() : nullptr);
}
void grpc_client_security_context_destroy(void* ctx) {
@@ -104,7 +116,7 @@ void grpc_client_security_context_destroy(void* ctx) {
/* --- grpc_server_security_context --- */
grpc_server_security_context::~grpc_server_security_context() {
- GRPC_AUTH_CONTEXT_UNREF(auth_context, "server_security_context");
+ auth_context.reset(DEBUG_LOCATION, "server_security_context");
if (extension.instance != nullptr && extension.destroy != nullptr) {
extension.destroy(extension.instance);
}
@@ -126,69 +138,11 @@ void grpc_server_security_context_destroy(void* ctx) {
static grpc_auth_property_iterator empty_iterator = {nullptr, 0, nullptr};
-grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained) {
- grpc_auth_context* ctx =
- static_cast<grpc_auth_context*>(gpr_zalloc(sizeof(grpc_auth_context)));
- gpr_ref_init(&ctx->refcount, 1);
- if (chained != nullptr) {
- ctx->chained = GRPC_AUTH_CONTEXT_REF(chained, "chained");
- ctx->peer_identity_property_name =
- ctx->chained->peer_identity_property_name;
- }
- return ctx;
-}
-
-#ifndef NDEBUG
-grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx,
- const char* file, int line,
- const char* reason) {
- if (ctx == nullptr) return nullptr;
- if (grpc_trace_auth_context_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count);
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "AUTH_CONTEXT:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val,
- val + 1, reason);
- }
-#else
-grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* ctx) {
- if (ctx == nullptr) return nullptr;
-#endif
- gpr_ref(&ctx->refcount);
- return ctx;
-}
-
-#ifndef NDEBUG
-void grpc_auth_context_unref(grpc_auth_context* ctx, const char* file, int line,
- const char* reason) {
- if (ctx == nullptr) return;
- if (grpc_trace_auth_context_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&ctx->refcount.count);
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "AUTH_CONTEXT:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", ctx, val,
- val - 1, reason);
- }
-#else
-void grpc_auth_context_unref(grpc_auth_context* ctx) {
- if (ctx == nullptr) return;
-#endif
- if (gpr_unref(&ctx->refcount)) {
- size_t i;
- GRPC_AUTH_CONTEXT_UNREF(ctx->chained, "chained");
- if (ctx->properties.array != nullptr) {
- for (i = 0; i < ctx->properties.count; i++) {
- grpc_auth_property_reset(&ctx->properties.array[i]);
- }
- gpr_free(ctx->properties.array);
- }
- gpr_free(ctx);
- }
-}
-
const char* grpc_auth_context_peer_identity_property_name(
const grpc_auth_context* ctx) {
GRPC_API_TRACE("grpc_auth_context_peer_identity_property_name(ctx=%p)", 1,
(ctx));
- return ctx->peer_identity_property_name;
+ return ctx->peer_identity_property_name();
}
int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx,
@@ -204,13 +158,13 @@ int grpc_auth_context_set_peer_identity_property_name(grpc_auth_context* ctx,
name != nullptr ? name : "NULL");
return 0;
}
- ctx->peer_identity_property_name = prop->name;
+ ctx->set_peer_identity_property_name(prop->name);
return 1;
}
int grpc_auth_context_peer_is_authenticated(const grpc_auth_context* ctx) {
GRPC_API_TRACE("grpc_auth_context_peer_is_authenticated(ctx=%p)", 1, (ctx));
- return ctx->peer_identity_property_name == nullptr ? 0 : 1;
+ return ctx->is_authenticated();
}
grpc_auth_property_iterator grpc_auth_context_property_iterator(
@@ -226,16 +180,17 @@ const grpc_auth_property* grpc_auth_property_iterator_next(
grpc_auth_property_iterator* it) {
GRPC_API_TRACE("grpc_auth_property_iterator_next(it=%p)", 1, (it));
if (it == nullptr || it->ctx == nullptr) return nullptr;
- while (it->index == it->ctx->properties.count) {
- if (it->ctx->chained == nullptr) return nullptr;
- it->ctx = it->ctx->chained;
+ while (it->index == it->ctx->properties().count) {
+ if (it->ctx->chained() == nullptr) return nullptr;
+ it->ctx = it->ctx->chained();
it->index = 0;
}
if (it->name == nullptr) {
- return &it->ctx->properties.array[it->index++];
+ return &it->ctx->properties().array[it->index++];
} else {
- while (it->index < it->ctx->properties.count) {
- const grpc_auth_property* prop = &it->ctx->properties.array[it->index++];
+ while (it->index < it->ctx->properties().count) {
+ const grpc_auth_property* prop =
+ &it->ctx->properties().array[it->index++];
GPR_ASSERT(prop->name != nullptr);
if (strcmp(it->name, prop->name) == 0) {
return prop;
@@ -262,49 +217,56 @@ grpc_auth_property_iterator grpc_auth_context_peer_identity(
GRPC_API_TRACE("grpc_auth_context_peer_identity(ctx=%p)", 1, (ctx));
if (ctx == nullptr) return empty_iterator;
return grpc_auth_context_find_properties_by_name(
- ctx, ctx->peer_identity_property_name);
+ ctx, ctx->peer_identity_property_name());
}
-static void ensure_auth_context_capacity(grpc_auth_context* ctx) {
- if (ctx->properties.count == ctx->properties.capacity) {
- ctx->properties.capacity =
- GPR_MAX(ctx->properties.capacity + 8, ctx->properties.capacity * 2);
- ctx->properties.array = static_cast<grpc_auth_property*>(
- gpr_realloc(ctx->properties.array,
- ctx->properties.capacity * sizeof(grpc_auth_property)));
+void grpc_auth_context::ensure_capacity() {
+ if (properties_.count == properties_.capacity) {
+ properties_.capacity =
+ GPR_MAX(properties_.capacity + 8, properties_.capacity * 2);
+ properties_.array = static_cast<grpc_auth_property*>(gpr_realloc(
+ properties_.array, properties_.capacity * sizeof(grpc_auth_property)));
}
}
+void grpc_auth_context::add_property(const char* name, const char* value,
+ size_t value_length) {
+ ensure_capacity();
+ grpc_auth_property* prop = &properties_.array[properties_.count++];
+ prop->name = gpr_strdup(name);
+ prop->value = static_cast<char*>(gpr_malloc(value_length + 1));
+ memcpy(prop->value, value, value_length);
+ prop->value[value_length] = '\0';
+ prop->value_length = value_length;
+}
+
void grpc_auth_context_add_property(grpc_auth_context* ctx, const char* name,
const char* value, size_t value_length) {
- grpc_auth_property* prop;
GRPC_API_TRACE(
"grpc_auth_context_add_property(ctx=%p, name=%s, value=%*.*s, "
"value_length=%lu)",
6,
(ctx, name, (int)value_length, (int)value_length, value,
(unsigned long)value_length));
- ensure_auth_context_capacity(ctx);
- prop = &ctx->properties.array[ctx->properties.count++];
+ ctx->add_property(name, value, value_length);
+}
+
+void grpc_auth_context::add_cstring_property(const char* name,
+ const char* value) {
+ ensure_capacity();
+ grpc_auth_property* prop = &properties_.array[properties_.count++];
prop->name = gpr_strdup(name);
- prop->value = static_cast<char*>(gpr_malloc(value_length + 1));
- memcpy(prop->value, value, value_length);
- prop->value[value_length] = '\0';
- prop->value_length = value_length;
+ prop->value = gpr_strdup(value);
+ prop->value_length = strlen(value);
}
void grpc_auth_context_add_cstring_property(grpc_auth_context* ctx,
const char* name,
const char* value) {
- grpc_auth_property* prop;
GRPC_API_TRACE(
"grpc_auth_context_add_cstring_property(ctx=%p, name=%s, value=%s)", 3,
(ctx, name, value));
- ensure_auth_context_capacity(ctx);
- prop = &ctx->properties.array[ctx->properties.count++];
- prop->name = gpr_strdup(name);
- prop->value = gpr_strdup(value);
- prop->value_length = strlen(value);
+ ctx->add_cstring_property(name, value);
}
void grpc_auth_property_reset(grpc_auth_property* property) {
@@ -314,12 +276,17 @@ void grpc_auth_property_reset(grpc_auth_property* property) {
}
static void auth_context_pointer_arg_destroy(void* p) {
- GRPC_AUTH_CONTEXT_UNREF((grpc_auth_context*)p, "auth_context_pointer_arg");
+ if (p != nullptr) {
+ static_cast<grpc_auth_context*>(p)->Unref(DEBUG_LOCATION,
+ "auth_context_pointer_arg");
+ }
}
static void* auth_context_pointer_arg_copy(void* p) {
- return GRPC_AUTH_CONTEXT_REF((grpc_auth_context*)p,
- "auth_context_pointer_arg");
+ auto* ctx = static_cast<grpc_auth_context*>(p);
+ return ctx == nullptr
+ ? nullptr
+ : ctx->Ref(DEBUG_LOCATION, "auth_context_pointer_arg").release();
}
static int auth_context_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h
index e45415f63b..b43ee5e62d 100644
--- a/src/core/lib/security/context/security_context.h
+++ b/src/core/lib/security/context/security_context.h
@@ -21,6 +21,8 @@
#include <grpc/support/port_platform.h>
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/security/credentials/credentials.h"
@@ -40,39 +42,59 @@ struct grpc_auth_property_array {
size_t capacity = 0;
};
-struct grpc_auth_context {
- grpc_auth_context() { gpr_ref_init(&refcount, 0); }
+void grpc_auth_property_reset(grpc_auth_property* property);
- struct grpc_auth_context* chained = nullptr;
- grpc_auth_property_array properties;
- gpr_refcount refcount;
- const char* peer_identity_property_name = nullptr;
- grpc_pollset* pollset = nullptr;
+// This type is forward declared as a C struct and we cannot define it as a
+// class. Otherwise, compiler will complain about type mismatch due to
+// -Wmismatched-tags.
+struct grpc_auth_context
+ : public grpc_core::RefCounted<grpc_auth_context,
+ grpc_core::NonPolymorphicRefCount> {
+ public:
+ explicit grpc_auth_context(
+ grpc_core::RefCountedPtr<grpc_auth_context> chained)
+ : grpc_core::RefCounted<grpc_auth_context,
+ grpc_core::NonPolymorphicRefCount>(
+ &grpc_trace_auth_context_refcount),
+ chained_(std::move(chained)) {
+ if (chained_ != nullptr) {
+ peer_identity_property_name_ = chained_->peer_identity_property_name_;
+ }
+ }
+
+ ~grpc_auth_context() {
+ chained_.reset(DEBUG_LOCATION, "chained");
+ if (properties_.array != nullptr) {
+ for (size_t i = 0; i < properties_.count; i++) {
+ grpc_auth_property_reset(&properties_.array[i]);
+ }
+ gpr_free(properties_.array);
+ }
+ }
+
+ const grpc_auth_context* chained() const { return chained_.get(); }
+ const grpc_auth_property_array& properties() const { return properties_; }
+
+ bool is_authenticated() const {
+ return peer_identity_property_name_ != nullptr;
+ }
+ const char* peer_identity_property_name() const {
+ return peer_identity_property_name_;
+ }
+ void set_peer_identity_property_name(const char* name) {
+ peer_identity_property_name_ = name;
+ }
+
+ void ensure_capacity();
+ void add_property(const char* name, const char* value, size_t value_length);
+ void add_cstring_property(const char* name, const char* value);
+
+ private:
+ grpc_core::RefCountedPtr<grpc_auth_context> chained_;
+ grpc_auth_property_array properties_;
+ const char* peer_identity_property_name_ = nullptr;
};
-/* Creation. */
-grpc_auth_context* grpc_auth_context_create(grpc_auth_context* chained);
-
-/* Refcounting. */
-#ifndef NDEBUG
-#define GRPC_AUTH_CONTEXT_REF(p, r) \
- grpc_auth_context_ref((p), __FILE__, __LINE__, (r))
-#define GRPC_AUTH_CONTEXT_UNREF(p, r) \
- grpc_auth_context_unref((p), __FILE__, __LINE__, (r))
-grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy,
- const char* file, int line,
- const char* reason);
-void grpc_auth_context_unref(grpc_auth_context* policy, const char* file,
- int line, const char* reason);
-#else
-#define GRPC_AUTH_CONTEXT_REF(p, r) grpc_auth_context_ref((p))
-#define GRPC_AUTH_CONTEXT_UNREF(p, r) grpc_auth_context_unref((p))
-grpc_auth_context* grpc_auth_context_ref(grpc_auth_context* policy);
-void grpc_auth_context_unref(grpc_auth_context* policy);
-#endif
-
-void grpc_auth_property_reset(grpc_auth_property* property);
-
/* --- grpc_security_context_extension ---
Extension to the security context that may be set in a filter and accessed
@@ -88,16 +110,18 @@ struct grpc_security_context_extension {
Internal client-side security context. */
struct grpc_client_security_context {
- grpc_client_security_context() = default;
+ explicit grpc_client_security_context(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds)
+ : creds(std::move(creds)) {}
~grpc_client_security_context();
- grpc_call_credentials* creds = nullptr;
- grpc_auth_context* auth_context = nullptr;
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds;
+ grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
grpc_security_context_extension extension;
};
grpc_client_security_context* grpc_client_security_context_create(
- gpr_arena* arena);
+ gpr_arena* arena, grpc_call_credentials* creds);
void grpc_client_security_context_destroy(void* ctx);
/* --- grpc_server_security_context ---
@@ -108,7 +132,7 @@ struct grpc_server_security_context {
grpc_server_security_context() = default;
~grpc_server_security_context();
- grpc_auth_context* auth_context = nullptr;
+ grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
grpc_security_context_extension extension;
};
diff --git a/src/core/lib/security/credentials/alts/alts_credentials.cc b/src/core/lib/security/credentials/alts/alts_credentials.cc
index 1fbef4ae0c..06546492bc 100644
--- a/src/core/lib/security/credentials/alts/alts_credentials.cc
+++ b/src/core/lib/security/credentials/alts/alts_credentials.cc
@@ -33,40 +33,47 @@
#define GRPC_CREDENTIALS_TYPE_ALTS "Alts"
#define GRPC_ALTS_HANDSHAKER_SERVICE_URL "metadata.google.internal:8080"
-static void alts_credentials_destruct(grpc_channel_credentials* creds) {
- grpc_alts_credentials* alts_creds =
- reinterpret_cast<grpc_alts_credentials*>(creds);
- grpc_alts_credentials_options_destroy(alts_creds->options);
- gpr_free(alts_creds->handshaker_service_url);
-}
-
-static void alts_server_credentials_destruct(grpc_server_credentials* creds) {
- grpc_alts_server_credentials* alts_creds =
- reinterpret_cast<grpc_alts_server_credentials*>(creds);
- grpc_alts_credentials_options_destroy(alts_creds->options);
- gpr_free(alts_creds->handshaker_service_url);
+grpc_alts_credentials::grpc_alts_credentials(
+ const grpc_alts_credentials_options* options,
+ const char* handshaker_service_url)
+ : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_ALTS),
+ options_(grpc_alts_credentials_options_copy(options)),
+ handshaker_service_url_(handshaker_service_url == nullptr
+ ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL)
+ : gpr_strdup(handshaker_service_url)) {}
+
+grpc_alts_credentials::~grpc_alts_credentials() {
+ grpc_alts_credentials_options_destroy(options_);
+ gpr_free(handshaker_service_url_);
}
-static grpc_security_status alts_create_security_connector(
- grpc_channel_credentials* creds,
- grpc_call_credentials* request_metadata_creds, const char* target_name,
- const grpc_channel_args* args, grpc_channel_security_connector** sc,
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_alts_credentials::create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target_name, const grpc_channel_args* args,
grpc_channel_args** new_args) {
return grpc_alts_channel_security_connector_create(
- creds, request_metadata_creds, target_name, sc);
+ this->Ref(), std::move(call_creds), target_name);
}
-static grpc_security_status alts_server_create_security_connector(
- grpc_server_credentials* creds, grpc_server_security_connector** sc) {
- return grpc_alts_server_security_connector_create(creds, sc);
+grpc_alts_server_credentials::grpc_alts_server_credentials(
+ const grpc_alts_credentials_options* options,
+ const char* handshaker_service_url)
+ : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_ALTS),
+ options_(grpc_alts_credentials_options_copy(options)),
+ handshaker_service_url_(handshaker_service_url == nullptr
+ ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL)
+ : gpr_strdup(handshaker_service_url)) {}
+
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_alts_server_credentials::create_security_connector() {
+ return grpc_alts_server_security_connector_create(this->Ref());
}
-static const grpc_channel_credentials_vtable alts_credentials_vtable = {
- alts_credentials_destruct, alts_create_security_connector,
- /*duplicate_without_call_credentials=*/nullptr};
-
-static const grpc_server_credentials_vtable alts_server_credentials_vtable = {
- alts_server_credentials_destruct, alts_server_create_security_connector};
+grpc_alts_server_credentials::~grpc_alts_server_credentials() {
+ grpc_alts_credentials_options_destroy(options_);
+ gpr_free(handshaker_service_url_);
+}
grpc_channel_credentials* grpc_alts_credentials_create_customized(
const grpc_alts_credentials_options* options,
@@ -74,17 +81,7 @@ grpc_channel_credentials* grpc_alts_credentials_create_customized(
if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) {
return nullptr;
}
- auto creds = static_cast<grpc_alts_credentials*>(
- gpr_zalloc(sizeof(grpc_alts_credentials)));
- creds->options = grpc_alts_credentials_options_copy(options);
- creds->handshaker_service_url =
- handshaker_service_url == nullptr
- ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL)
- : gpr_strdup(handshaker_service_url);
- creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS;
- creds->base.vtable = &alts_credentials_vtable;
- gpr_ref_init(&creds->base.refcount, 1);
- return &creds->base;
+ return grpc_core::New<grpc_alts_credentials>(options, handshaker_service_url);
}
grpc_server_credentials* grpc_alts_server_credentials_create_customized(
@@ -93,17 +90,8 @@ grpc_server_credentials* grpc_alts_server_credentials_create_customized(
if (!enable_untrusted_alts && !grpc_alts_is_running_on_gcp()) {
return nullptr;
}
- auto creds = static_cast<grpc_alts_server_credentials*>(
- gpr_zalloc(sizeof(grpc_alts_server_credentials)));
- creds->options = grpc_alts_credentials_options_copy(options);
- creds->handshaker_service_url =
- handshaker_service_url == nullptr
- ? gpr_strdup(GRPC_ALTS_HANDSHAKER_SERVICE_URL)
- : gpr_strdup(handshaker_service_url);
- creds->base.type = GRPC_CREDENTIALS_TYPE_ALTS;
- creds->base.vtable = &alts_server_credentials_vtable;
- gpr_ref_init(&creds->base.refcount, 1);
- return &creds->base;
+ return grpc_core::New<grpc_alts_server_credentials>(options,
+ handshaker_service_url);
}
grpc_channel_credentials* grpc_alts_credentials_create(
diff --git a/src/core/lib/security/credentials/alts/alts_credentials.h b/src/core/lib/security/credentials/alts/alts_credentials.h
index 810117f2be..cc6d5222b1 100644
--- a/src/core/lib/security/credentials/alts/alts_credentials.h
+++ b/src/core/lib/security/credentials/alts/alts_credentials.h
@@ -27,18 +27,45 @@
#include "src/core/lib/security/credentials/credentials.h"
/* Main struct for grpc ALTS channel credential. */
-typedef struct grpc_alts_credentials {
- grpc_channel_credentials base;
- grpc_alts_credentials_options* options;
- char* handshaker_service_url;
-} grpc_alts_credentials;
+class grpc_alts_credentials final : public grpc_channel_credentials {
+ public:
+ grpc_alts_credentials(const grpc_alts_credentials_options* options,
+ const char* handshaker_service_url);
+ ~grpc_alts_credentials() override;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target_name, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override;
+
+ const grpc_alts_credentials_options* options() const { return options_; }
+ grpc_alts_credentials_options* mutable_options() { return options_; }
+ const char* handshaker_service_url() const { return handshaker_service_url_; }
+
+ private:
+ grpc_alts_credentials_options* options_;
+ char* handshaker_service_url_;
+};
/* Main struct for grpc ALTS server credential. */
-typedef struct grpc_alts_server_credentials {
- grpc_server_credentials base;
- grpc_alts_credentials_options* options;
- char* handshaker_service_url;
-} grpc_alts_server_credentials;
+class grpc_alts_server_credentials final : public grpc_server_credentials {
+ public:
+ grpc_alts_server_credentials(const grpc_alts_credentials_options* options,
+ const char* handshaker_service_url);
+ ~grpc_alts_server_credentials() override;
+
+ grpc_core::RefCountedPtr<grpc_server_security_connector>
+ create_security_connector() override;
+
+ const grpc_alts_credentials_options* options() const { return options_; }
+ grpc_alts_credentials_options* mutable_options() { return options_; }
+ const char* handshaker_service_url() const { return handshaker_service_url_; }
+
+ private:
+ grpc_alts_credentials_options* options_;
+ char* handshaker_service_url_;
+};
/**
* This method creates an ALTS channel credential object with customized
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.cc b/src/core/lib/security/credentials/composite/composite_credentials.cc
index b8f409260f..85dcd4693b 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.cc
+++ b/src/core/lib/security/credentials/composite/composite_credentials.cc
@@ -20,8 +20,10 @@
#include "src/core/lib/security/credentials/composite/composite_credentials.h"
-#include <string.h>
+#include <cstring>
+#include <new>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/polling_entity.h"
#include "src/core/lib/surface/api_trace.h"
@@ -31,36 +33,83 @@
/* -- Composite call credentials. -- */
-typedef struct {
+static void composite_call_metadata_cb(void* arg, grpc_error* error);
+
+grpc_call_credentials_array::~grpc_call_credentials_array() {
+ for (size_t i = 0; i < num_creds_; ++i) {
+ creds_array_[i].~RefCountedPtr<grpc_call_credentials>();
+ }
+ if (creds_array_ != nullptr) {
+ gpr_free(creds_array_);
+ }
+}
+
+grpc_call_credentials_array::grpc_call_credentials_array(
+ const grpc_call_credentials_array& that)
+ : num_creds_(that.num_creds_) {
+ reserve(that.capacity_);
+ for (size_t i = 0; i < num_creds_; ++i) {
+ new (&creds_array_[i])
+ grpc_core::RefCountedPtr<grpc_call_credentials>(that.creds_array_[i]);
+ }
+}
+
+void grpc_call_credentials_array::reserve(size_t capacity) {
+ if (capacity_ >= capacity) {
+ return;
+ }
+ grpc_core::RefCountedPtr<grpc_call_credentials>* new_arr =
+ static_cast<grpc_core::RefCountedPtr<grpc_call_credentials>*>(gpr_malloc(
+ sizeof(grpc_core::RefCountedPtr<grpc_call_credentials>) * capacity));
+ if (creds_array_ != nullptr) {
+ for (size_t i = 0; i < num_creds_; ++i) {
+ new (&new_arr[i]) grpc_core::RefCountedPtr<grpc_call_credentials>(
+ std::move(creds_array_[i]));
+ creds_array_[i].~RefCountedPtr<grpc_call_credentials>();
+ }
+ gpr_free(creds_array_);
+ }
+ creds_array_ = new_arr;
+ capacity_ = capacity;
+}
+
+namespace {
+struct grpc_composite_call_credentials_metadata_context {
+ grpc_composite_call_credentials_metadata_context(
+ grpc_composite_call_credentials* composite_creds,
+ grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata)
+ : composite_creds(composite_creds),
+ pollent(pollent),
+ auth_md_context(auth_md_context),
+ md_array(md_array),
+ on_request_metadata(on_request_metadata) {
+ GRPC_CLOSURE_INIT(&internal_on_request_metadata, composite_call_metadata_cb,
+ this, grpc_schedule_on_exec_ctx);
+ }
+
grpc_composite_call_credentials* composite_creds;
- size_t creds_index;
+ size_t creds_index = 0;
grpc_polling_entity* pollent;
grpc_auth_metadata_context auth_md_context;
grpc_credentials_mdelem_array* md_array;
grpc_closure* on_request_metadata;
grpc_closure internal_on_request_metadata;
-} grpc_composite_call_credentials_metadata_context;
-
-static void composite_call_destruct(grpc_call_credentials* creds) {
- grpc_composite_call_credentials* c =
- reinterpret_cast<grpc_composite_call_credentials*>(creds);
- for (size_t i = 0; i < c->inner.num_creds; i++) {
- grpc_call_credentials_unref(c->inner.creds_array[i]);
- }
- gpr_free(c->inner.creds_array);
-}
+};
+} // namespace
static void composite_call_metadata_cb(void* arg, grpc_error* error) {
grpc_composite_call_credentials_metadata_context* ctx =
static_cast<grpc_composite_call_credentials_metadata_context*>(arg);
if (error == GRPC_ERROR_NONE) {
+ const grpc_call_credentials_array& inner = ctx->composite_creds->inner();
/* See if we need to get some more metadata. */
- if (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
- grpc_call_credentials* inner_creds =
- ctx->composite_creds->inner.creds_array[ctx->creds_index++];
- if (grpc_call_credentials_get_request_metadata(
- inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array,
- &ctx->internal_on_request_metadata, &error)) {
+ if (ctx->creds_index < inner.size()) {
+ if (inner.get(ctx->creds_index++)
+ ->get_request_metadata(
+ ctx->pollent, ctx->auth_md_context, ctx->md_array,
+ &ctx->internal_on_request_metadata, &error)) {
// Synchronous response, so call ourselves recursively.
composite_call_metadata_cb(arg, error);
GRPC_ERROR_UNREF(error);
@@ -73,76 +122,86 @@ static void composite_call_metadata_cb(void* arg, grpc_error* error) {
gpr_free(ctx);
}
-static bool composite_call_get_request_metadata(
- grpc_call_credentials* creds, grpc_polling_entity* pollent,
- grpc_auth_metadata_context auth_md_context,
+bool grpc_composite_call_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context auth_md_context,
grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
grpc_error** error) {
- grpc_composite_call_credentials* c =
- reinterpret_cast<grpc_composite_call_credentials*>(creds);
grpc_composite_call_credentials_metadata_context* ctx;
- ctx = static_cast<grpc_composite_call_credentials_metadata_context*>(
- gpr_zalloc(sizeof(grpc_composite_call_credentials_metadata_context)));
- ctx->composite_creds = c;
- ctx->pollent = pollent;
- ctx->auth_md_context = auth_md_context;
- ctx->md_array = md_array;
- ctx->on_request_metadata = on_request_metadata;
- GRPC_CLOSURE_INIT(&ctx->internal_on_request_metadata,
- composite_call_metadata_cb, ctx, grpc_schedule_on_exec_ctx);
+ ctx = grpc_core::New<grpc_composite_call_credentials_metadata_context>(
+ this, pollent, auth_md_context, md_array, on_request_metadata);
bool synchronous = true;
- while (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
- grpc_call_credentials* inner_creds =
- ctx->composite_creds->inner.creds_array[ctx->creds_index++];
- if (grpc_call_credentials_get_request_metadata(
- inner_creds, ctx->pollent, ctx->auth_md_context, ctx->md_array,
- &ctx->internal_on_request_metadata, error)) {
+ const grpc_call_credentials_array& inner = ctx->composite_creds->inner();
+ while (ctx->creds_index < inner.size()) {
+ if (inner.get(ctx->creds_index++)
+ ->get_request_metadata(ctx->pollent, ctx->auth_md_context,
+ ctx->md_array,
+ &ctx->internal_on_request_metadata, error)) {
if (*error != GRPC_ERROR_NONE) break;
} else {
synchronous = false; // Async return.
break;
}
}
- if (synchronous) gpr_free(ctx);
+ if (synchronous) grpc_core::Delete(ctx);
return synchronous;
}
-static void composite_call_cancel_get_request_metadata(
- grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
- grpc_composite_call_credentials* c =
- reinterpret_cast<grpc_composite_call_credentials*>(creds);
- for (size_t i = 0; i < c->inner.num_creds; ++i) {
- grpc_call_credentials_cancel_get_request_metadata(
- c->inner.creds_array[i], md_array, GRPC_ERROR_REF(error));
+void grpc_composite_call_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
+ for (size_t i = 0; i < inner_.size(); ++i) {
+ inner_.get(i)->cancel_get_request_metadata(md_array, GRPC_ERROR_REF(error));
}
GRPC_ERROR_UNREF(error);
}
-static grpc_call_credentials_vtable composite_call_credentials_vtable = {
- composite_call_destruct, composite_call_get_request_metadata,
- composite_call_cancel_get_request_metadata};
+static size_t get_creds_array_size(const grpc_call_credentials* creds,
+ bool is_composite) {
+ return is_composite
+ ? static_cast<const grpc_composite_call_credentials*>(creds)
+ ->inner()
+ .size()
+ : 1;
+}
-static grpc_call_credentials_array get_creds_array(
- grpc_call_credentials** creds_addr) {
- grpc_call_credentials_array result;
- grpc_call_credentials* creds = *creds_addr;
- result.creds_array = creds_addr;
- result.num_creds = 1;
- if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
- result = *grpc_composite_call_credentials_get_credentials(creds);
+void grpc_composite_call_credentials::push_to_inner(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds, bool is_composite) {
+ if (!is_composite) {
+ inner_.push_back(std::move(creds));
+ return;
}
- return result;
+ auto composite_creds =
+ static_cast<grpc_composite_call_credentials*>(creds.get());
+ for (size_t i = 0; i < composite_creds->inner().size(); ++i) {
+ inner_.push_back(std::move(composite_creds->inner_.get_mutable(i)));
+ }
+}
+
+grpc_composite_call_credentials::grpc_composite_call_credentials(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds1,
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds2)
+ : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) {
+ const bool creds1_is_composite =
+ strcmp(creds1->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0;
+ const bool creds2_is_composite =
+ strcmp(creds2->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0;
+ const size_t size = get_creds_array_size(creds1.get(), creds1_is_composite) +
+ get_creds_array_size(creds2.get(), creds2_is_composite);
+ inner_.reserve(size);
+ push_to_inner(std::move(creds1), creds1_is_composite);
+ push_to_inner(std::move(creds2), creds2_is_composite);
+}
+
+static grpc_core::RefCountedPtr<grpc_call_credentials>
+composite_call_credentials_create(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds1,
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds2) {
+ return grpc_core::MakeRefCounted<grpc_composite_call_credentials>(
+ std::move(creds1), std::move(creds2));
}
grpc_call_credentials* grpc_composite_call_credentials_create(
grpc_call_credentials* creds1, grpc_call_credentials* creds2,
void* reserved) {
- size_t i;
- size_t creds_array_byte_size;
- grpc_call_credentials_array creds1_array;
- grpc_call_credentials_array creds2_array;
- grpc_composite_call_credentials* c;
GRPC_API_TRACE(
"grpc_composite_call_credentials_create(creds1=%p, creds2=%p, "
"reserved=%p)",
@@ -150,120 +209,40 @@ grpc_call_credentials* grpc_composite_call_credentials_create(
GPR_ASSERT(reserved == nullptr);
GPR_ASSERT(creds1 != nullptr);
GPR_ASSERT(creds2 != nullptr);
- c = static_cast<grpc_composite_call_credentials*>(
- gpr_zalloc(sizeof(grpc_composite_call_credentials)));
- c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE;
- c->base.vtable = &composite_call_credentials_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- creds1_array = get_creds_array(&creds1);
- creds2_array = get_creds_array(&creds2);
- c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
- creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials*);
- c->inner.creds_array =
- static_cast<grpc_call_credentials**>(gpr_zalloc(creds_array_byte_size));
- for (i = 0; i < creds1_array.num_creds; i++) {
- grpc_call_credentials* cur_creds = creds1_array.creds_array[i];
- c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds);
- }
- for (i = 0; i < creds2_array.num_creds; i++) {
- grpc_call_credentials* cur_creds = creds2_array.creds_array[i];
- c->inner.creds_array[i + creds1_array.num_creds] =
- grpc_call_credentials_ref(cur_creds);
- }
- return &c->base;
-}
-const grpc_call_credentials_array*
-grpc_composite_call_credentials_get_credentials(grpc_call_credentials* creds) {
- const grpc_composite_call_credentials* c =
- reinterpret_cast<const grpc_composite_call_credentials*>(creds);
- GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
- return &c->inner;
-}
-
-grpc_call_credentials* grpc_credentials_contains_type(
- grpc_call_credentials* creds, const char* type,
- grpc_call_credentials** composite_creds) {
- size_t i;
- if (strcmp(creds->type, type) == 0) {
- if (composite_creds != nullptr) *composite_creds = nullptr;
- return creds;
- } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
- const grpc_call_credentials_array* inner_creds_array =
- grpc_composite_call_credentials_get_credentials(creds);
- for (i = 0; i < inner_creds_array->num_creds; i++) {
- if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
- if (composite_creds != nullptr) *composite_creds = creds;
- return inner_creds_array->creds_array[i];
- }
- }
- }
- return nullptr;
+ return composite_call_credentials_create(creds1->Ref(), creds2->Ref())
+ .release();
}
/* -- Composite channel credentials. -- */
-static void composite_channel_destruct(grpc_channel_credentials* creds) {
- grpc_composite_channel_credentials* c =
- reinterpret_cast<grpc_composite_channel_credentials*>(creds);
- grpc_channel_credentials_unref(c->inner_creds);
- grpc_call_credentials_unref(c->call_creds);
-}
-
-static grpc_security_status composite_channel_create_security_connector(
- grpc_channel_credentials* creds, grpc_call_credentials* call_creds,
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_composite_channel_credentials::create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
- grpc_composite_channel_credentials* c =
- reinterpret_cast<grpc_composite_channel_credentials*>(creds);
- grpc_security_status status = GRPC_SECURITY_ERROR;
-
- GPR_ASSERT(c->inner_creds != nullptr && c->call_creds != nullptr &&
- c->inner_creds->vtable != nullptr &&
- c->inner_creds->vtable->create_security_connector != nullptr);
+ grpc_channel_args** new_args) {
+ GPR_ASSERT(inner_creds_ != nullptr && call_creds_ != nullptr);
/* If we are passed a call_creds, create a call composite to pass it
downstream. */
if (call_creds != nullptr) {
- grpc_call_credentials* composite_call_creds =
- grpc_composite_call_credentials_create(c->call_creds, call_creds,
- nullptr);
- status = c->inner_creds->vtable->create_security_connector(
- c->inner_creds, composite_call_creds, target, args, sc, new_args);
- grpc_call_credentials_unref(composite_call_creds);
+ return inner_creds_->create_security_connector(
+ composite_call_credentials_create(call_creds_, std::move(call_creds)),
+ target, args, new_args);
} else {
- status = c->inner_creds->vtable->create_security_connector(
- c->inner_creds, c->call_creds, target, args, sc, new_args);
+ return inner_creds_->create_security_connector(call_creds_, target, args,
+ new_args);
}
- return status;
-}
-
-static grpc_channel_credentials*
-composite_channel_duplicate_without_call_credentials(
- grpc_channel_credentials* creds) {
- grpc_composite_channel_credentials* c =
- reinterpret_cast<grpc_composite_channel_credentials*>(creds);
- return grpc_channel_credentials_ref(c->inner_creds);
}
-static grpc_channel_credentials_vtable composite_channel_credentials_vtable = {
- composite_channel_destruct, composite_channel_create_security_connector,
- composite_channel_duplicate_without_call_credentials};
-
grpc_channel_credentials* grpc_composite_channel_credentials_create(
grpc_channel_credentials* channel_creds, grpc_call_credentials* call_creds,
void* reserved) {
- grpc_composite_channel_credentials* c =
- static_cast<grpc_composite_channel_credentials*>(gpr_zalloc(sizeof(*c)));
GPR_ASSERT(channel_creds != nullptr && call_creds != nullptr &&
reserved == nullptr);
GRPC_API_TRACE(
"grpc_composite_channel_credentials_create(channel_creds=%p, "
"call_creds=%p, reserved=%p)",
3, (channel_creds, call_creds, reserved));
- c->base.type = channel_creds->type;
- c->base.vtable = &composite_channel_credentials_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- c->inner_creds = grpc_channel_credentials_ref(channel_creds);
- c->call_creds = grpc_call_credentials_ref(call_creds);
- return &c->base;
+ return grpc_core::New<grpc_composite_channel_credentials>(
+ channel_creds->Ref(), call_creds->Ref());
}
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.h b/src/core/lib/security/credentials/composite/composite_credentials.h
index a952ad57f1..6b7fca1370 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.h
+++ b/src/core/lib/security/credentials/composite/composite_credentials.h
@@ -21,39 +21,104 @@
#include <grpc/support/port_platform.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/credentials/credentials.h"
-typedef struct {
- grpc_call_credentials** creds_array;
- size_t num_creds;
-} grpc_call_credentials_array;
+// TODO(soheil): Replace this with InlinedVector once #16032 is resolved.
+class grpc_call_credentials_array {
+ public:
+ grpc_call_credentials_array() = default;
+ grpc_call_credentials_array(const grpc_call_credentials_array& that);
-const grpc_call_credentials_array*
-grpc_composite_call_credentials_get_credentials(
- grpc_call_credentials* composite_creds);
+ ~grpc_call_credentials_array();
-/* Returns creds if creds is of the specified type or the inner creds of the
- specified type (if found), if the creds is of type COMPOSITE.
- If composite_creds is not NULL, *composite_creds will point to creds if of
- type COMPOSITE in case of success. */
-grpc_call_credentials* grpc_credentials_contains_type(
- grpc_call_credentials* creds, const char* type,
- grpc_call_credentials** composite_creds);
+ void reserve(size_t capacity);
+
+ // Must reserve before pushing any data.
+ void push_back(grpc_core::RefCountedPtr<grpc_call_credentials> cred) {
+ GPR_DEBUG_ASSERT(capacity_ > num_creds_);
+ new (&creds_array_[num_creds_++])
+ grpc_core::RefCountedPtr<grpc_call_credentials>(std::move(cred));
+ }
+
+ const grpc_core::RefCountedPtr<grpc_call_credentials>& get(size_t i) const {
+ GPR_DEBUG_ASSERT(i < num_creds_);
+ return creds_array_[i];
+ }
+ grpc_core::RefCountedPtr<grpc_call_credentials>& get_mutable(size_t i) {
+ GPR_DEBUG_ASSERT(i < num_creds_);
+ return creds_array_[i];
+ }
+
+ size_t size() const { return num_creds_; }
+
+ private:
+ grpc_core::RefCountedPtr<grpc_call_credentials>* creds_array_ = nullptr;
+ size_t num_creds_ = 0;
+ size_t capacity_ = 0;
+};
/* -- Composite channel credentials. -- */
-typedef struct {
- grpc_channel_credentials base;
- grpc_channel_credentials* inner_creds;
- grpc_call_credentials* call_creds;
-} grpc_composite_channel_credentials;
+class grpc_composite_channel_credentials : public grpc_channel_credentials {
+ public:
+ grpc_composite_channel_credentials(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds)
+ : grpc_channel_credentials(channel_creds->type()),
+ inner_creds_(std::move(channel_creds)),
+ call_creds_(std::move(call_creds)) {}
+
+ ~grpc_composite_channel_credentials() override = default;
+
+ grpc_core::RefCountedPtr<grpc_channel_credentials>
+ duplicate_without_call_credentials() override {
+ return inner_creds_;
+ }
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override;
+
+ const grpc_channel_credentials* inner_creds() const {
+ return inner_creds_.get();
+ }
+ const grpc_call_credentials* call_creds() const { return call_creds_.get(); }
+ grpc_call_credentials* mutable_call_creds() { return call_creds_.get(); }
+
+ private:
+ grpc_core::RefCountedPtr<grpc_channel_credentials> inner_creds_;
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds_;
+};
/* -- Composite call credentials. -- */
-typedef struct {
- grpc_call_credentials base;
- grpc_call_credentials_array inner;
-} grpc_composite_call_credentials;
+class grpc_composite_call_credentials : public grpc_call_credentials {
+ public:
+ grpc_composite_call_credentials(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds1,
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds2);
+ ~grpc_composite_call_credentials() override = default;
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ const grpc_call_credentials_array& inner() const { return inner_; }
+
+ private:
+ void push_to_inner(grpc_core::RefCountedPtr<grpc_call_credentials> creds,
+ bool is_composite);
+
+ grpc_call_credentials_array inner_;
+};
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_COMPOSITE_COMPOSITE_CREDENTIALS_H \
*/
diff --git a/src/core/lib/security/credentials/credentials.cc b/src/core/lib/security/credentials/credentials.cc
index c43cb440eb..90452d68d6 100644
--- a/src/core/lib/security/credentials/credentials.cc
+++ b/src/core/lib/security/credentials/credentials.cc
@@ -39,120 +39,24 @@
/* -- Common. -- */
-grpc_credentials_metadata_request* grpc_credentials_metadata_request_create(
- grpc_call_credentials* creds) {
- grpc_credentials_metadata_request* r =
- static_cast<grpc_credentials_metadata_request*>(
- gpr_zalloc(sizeof(grpc_credentials_metadata_request)));
- r->creds = grpc_call_credentials_ref(creds);
- return r;
-}
-
-void grpc_credentials_metadata_request_destroy(
- grpc_credentials_metadata_request* r) {
- grpc_call_credentials_unref(r->creds);
- grpc_http_response_destroy(&r->response);
- gpr_free(r);
-}
-
-grpc_channel_credentials* grpc_channel_credentials_ref(
- grpc_channel_credentials* creds) {
- if (creds == nullptr) return nullptr;
- gpr_ref(&creds->refcount);
- return creds;
-}
-
-void grpc_channel_credentials_unref(grpc_channel_credentials* creds) {
- if (creds == nullptr) return;
- if (gpr_unref(&creds->refcount)) {
- if (creds->vtable->destruct != nullptr) {
- creds->vtable->destruct(creds);
- }
- gpr_free(creds);
- }
-}
-
void grpc_channel_credentials_release(grpc_channel_credentials* creds) {
GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
grpc_core::ExecCtx exec_ctx;
- grpc_channel_credentials_unref(creds);
-}
-
-grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds) {
- if (creds == nullptr) return nullptr;
- gpr_ref(&creds->refcount);
- return creds;
-}
-
-void grpc_call_credentials_unref(grpc_call_credentials* creds) {
- if (creds == nullptr) return;
- if (gpr_unref(&creds->refcount)) {
- if (creds->vtable->destruct != nullptr) {
- creds->vtable->destruct(creds);
- }
- gpr_free(creds);
- }
+ if (creds) creds->Unref();
}
void grpc_call_credentials_release(grpc_call_credentials* creds) {
GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
grpc_core::ExecCtx exec_ctx;
- grpc_call_credentials_unref(creds);
-}
-
-bool grpc_call_credentials_get_request_metadata(
- grpc_call_credentials* creds, grpc_polling_entity* pollent,
- grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata, grpc_error** error) {
- if (creds == nullptr || creds->vtable->get_request_metadata == nullptr) {
- return true;
- }
- return creds->vtable->get_request_metadata(creds, pollent, context, md_array,
- on_request_metadata, error);
-}
-
-void grpc_call_credentials_cancel_get_request_metadata(
- grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
- if (creds == nullptr ||
- creds->vtable->cancel_get_request_metadata == nullptr) {
- return;
- }
- creds->vtable->cancel_get_request_metadata(creds, md_array, error);
-}
-
-grpc_security_status grpc_channel_credentials_create_security_connector(
- grpc_channel_credentials* channel_creds, const char* target,
- const grpc_channel_args* args, grpc_channel_security_connector** sc,
- grpc_channel_args** new_args) {
- *new_args = nullptr;
- if (channel_creds == nullptr) {
- return GRPC_SECURITY_ERROR;
- }
- GPR_ASSERT(channel_creds->vtable->create_security_connector != nullptr);
- return channel_creds->vtable->create_security_connector(
- channel_creds, nullptr, target, args, sc, new_args);
-}
-
-grpc_channel_credentials*
-grpc_channel_credentials_duplicate_without_call_credentials(
- grpc_channel_credentials* channel_creds) {
- if (channel_creds != nullptr && channel_creds->vtable != nullptr &&
- channel_creds->vtable->duplicate_without_call_credentials != nullptr) {
- return channel_creds->vtable->duplicate_without_call_credentials(
- channel_creds);
- } else {
- return grpc_channel_credentials_ref(channel_creds);
- }
+ if (creds) creds->Unref();
}
static void credentials_pointer_arg_destroy(void* p) {
- grpc_channel_credentials_unref(static_cast<grpc_channel_credentials*>(p));
+ static_cast<grpc_channel_credentials*>(p)->Unref();
}
static void* credentials_pointer_arg_copy(void* p) {
- return grpc_channel_credentials_ref(
- static_cast<grpc_channel_credentials*>(p));
+ return static_cast<grpc_channel_credentials*>(p)->Ref().release();
}
static int credentials_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
@@ -191,63 +95,35 @@ grpc_channel_credentials* grpc_channel_credentials_find_in_args(
return nullptr;
}
-grpc_server_credentials* grpc_server_credentials_ref(
- grpc_server_credentials* creds) {
- if (creds == nullptr) return nullptr;
- gpr_ref(&creds->refcount);
- return creds;
-}
-
-void grpc_server_credentials_unref(grpc_server_credentials* creds) {
- if (creds == nullptr) return;
- if (gpr_unref(&creds->refcount)) {
- if (creds->vtable->destruct != nullptr) {
- creds->vtable->destruct(creds);
- }
- if (creds->processor.destroy != nullptr &&
- creds->processor.state != nullptr) {
- creds->processor.destroy(creds->processor.state);
- }
- gpr_free(creds);
- }
-}
-
void grpc_server_credentials_release(grpc_server_credentials* creds) {
GRPC_API_TRACE("grpc_server_credentials_release(creds=%p)", 1, (creds));
grpc_core::ExecCtx exec_ctx;
- grpc_server_credentials_unref(creds);
+ if (creds) creds->Unref();
}
-grpc_security_status grpc_server_credentials_create_security_connector(
- grpc_server_credentials* creds, grpc_server_security_connector** sc) {
- if (creds == nullptr || creds->vtable->create_security_connector == nullptr) {
- gpr_log(GPR_ERROR, "Server credentials cannot create security context.");
- return GRPC_SECURITY_ERROR;
- }
- return creds->vtable->create_security_connector(creds, sc);
-}
-
-void grpc_server_credentials_set_auth_metadata_processor(
- grpc_server_credentials* creds, grpc_auth_metadata_processor processor) {
+void grpc_server_credentials::set_auth_metadata_processor(
+ const grpc_auth_metadata_processor& processor) {
GRPC_API_TRACE(
"grpc_server_credentials_set_auth_metadata_processor("
"creds=%p, "
"processor=grpc_auth_metadata_processor { process: %p, state: %p })",
- 3, (creds, (void*)(intptr_t)processor.process, processor.state));
- if (creds == nullptr) return;
- if (creds->processor.destroy != nullptr &&
- creds->processor.state != nullptr) {
- creds->processor.destroy(creds->processor.state);
- }
- creds->processor = processor;
+ 3, (this, (void*)(intptr_t)processor.process, processor.state));
+ DestroyProcessor();
+ processor_ = processor;
+}
+
+void grpc_server_credentials_set_auth_metadata_processor(
+ grpc_server_credentials* creds, grpc_auth_metadata_processor processor) {
+ GPR_DEBUG_ASSERT(creds != nullptr);
+ creds->set_auth_metadata_processor(processor);
}
static void server_credentials_pointer_arg_destroy(void* p) {
- grpc_server_credentials_unref(static_cast<grpc_server_credentials*>(p));
+ static_cast<grpc_server_credentials*>(p)->Unref();
}
static void* server_credentials_pointer_arg_copy(void* p) {
- return grpc_server_credentials_ref(static_cast<grpc_server_credentials*>(p));
+ return static_cast<grpc_server_credentials*>(p)->Ref().release();
}
static int server_credentials_pointer_cmp(void* a, void* b) {
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 3878958b38..4091ef3dfb 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -26,6 +26,7 @@
#include <grpc/support/sync.h>
#include "src/core/lib/transport/metadata_batch.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/polling_entity.h"
@@ -90,44 +91,46 @@ void grpc_override_well_known_credentials_path_getter(
#define GRPC_ARG_CHANNEL_CREDENTIALS "grpc.channel_credentials"
-typedef struct {
- void (*destruct)(grpc_channel_credentials* c);
-
- grpc_security_status (*create_security_connector)(
- grpc_channel_credentials* c, grpc_call_credentials* call_creds,
+// This type is forward declared as a C struct and we cannot define it as a
+// class. Otherwise, compiler will complain about type mismatch due to
+// -Wmismatched-tags.
+struct grpc_channel_credentials
+ : grpc_core::RefCounted<grpc_channel_credentials> {
+ public:
+ explicit grpc_channel_credentials(const char* type) : type_(type) {}
+ virtual ~grpc_channel_credentials() = default;
+
+ // Creates a security connector for the channel. May also create new channel
+ // args for the channel to be used in place of the passed in const args if
+ // returned non NULL. In that case the caller is responsible for destroying
+ // new_args after channel creation.
+ virtual grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args);
-
- grpc_channel_credentials* (*duplicate_without_call_credentials)(
- grpc_channel_credentials* c);
-} grpc_channel_credentials_vtable;
-
-struct grpc_channel_credentials {
- const grpc_channel_credentials_vtable* vtable;
- const char* type;
- gpr_refcount refcount;
+ grpc_channel_args** new_args) {
+ // Tell clang-tidy that call_creds cannot be passed as const-ref.
+ call_creds.reset();
+ GRPC_ABSTRACT;
+ }
+
+ // Creates a version of the channel credentials without any attached call
+ // credentials. This can be used in order to open a channel to a non-trusted
+ // gRPC load balancer.
+ virtual grpc_core::RefCountedPtr<grpc_channel_credentials>
+ duplicate_without_call_credentials() {
+ // By default we just increment the refcount.
+ return Ref();
+ }
+
+ const char* type() const { return type_; }
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ private:
+ const char* type_;
};
-grpc_channel_credentials* grpc_channel_credentials_ref(
- grpc_channel_credentials* creds);
-void grpc_channel_credentials_unref(grpc_channel_credentials* creds);
-
-/* Creates a security connector for the channel. May also create new channel
- args for the channel to be used in place of the passed in const args if
- returned non NULL. In that case the caller is responsible for destroying
- new_args after channel creation. */
-grpc_security_status grpc_channel_credentials_create_security_connector(
- grpc_channel_credentials* creds, const char* target,
- const grpc_channel_args* args, grpc_channel_security_connector** sc,
- grpc_channel_args** new_args);
-
-/* Creates a version of the channel credentials without any attached call
- credentials. This can be used in order to open a channel to a non-trusted
- gRPC load balancer. */
-grpc_channel_credentials*
-grpc_channel_credentials_duplicate_without_call_credentials(
- grpc_channel_credentials* creds);
-
/* Util to encapsulate the channel credentials in a channel arg. */
grpc_arg grpc_channel_credentials_to_arg(grpc_channel_credentials* credentials);
@@ -158,44 +161,39 @@ void grpc_credentials_mdelem_array_destroy(grpc_credentials_mdelem_array* list);
/* --- grpc_call_credentials. --- */
-typedef struct {
- void (*destruct)(grpc_call_credentials* c);
- bool (*get_request_metadata)(grpc_call_credentials* c,
- grpc_polling_entity* pollent,
- grpc_auth_metadata_context context,
- grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata,
- grpc_error** error);
- void (*cancel_get_request_metadata)(grpc_call_credentials* c,
- grpc_credentials_mdelem_array* md_array,
- grpc_error* error);
-} grpc_call_credentials_vtable;
-
-struct grpc_call_credentials {
- const grpc_call_credentials_vtable* vtable;
- const char* type;
- gpr_refcount refcount;
+// This type is forward declared as a C struct and we cannot define it as a
+// class. Otherwise, compiler will complain about type mismatch due to
+// -Wmismatched-tags.
+struct grpc_call_credentials
+ : public grpc_core::RefCounted<grpc_call_credentials> {
+ public:
+ explicit grpc_call_credentials(const char* type) : type_(type) {}
+ virtual ~grpc_call_credentials() = default;
+
+ // Returns true if completed synchronously, in which case \a error will
+ // be set to indicate the result. Otherwise, \a on_request_metadata will
+ // be invoked asynchronously when complete. \a md_array will be populated
+ // with the resulting metadata once complete.
+ virtual bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) GRPC_ABSTRACT;
+
+ // Cancels a pending asynchronous operation started by
+ // grpc_call_credentials_get_request_metadata() with the corresponding
+ // value of \a md_array.
+ virtual void cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) GRPC_ABSTRACT;
+
+ const char* type() const { return type_; }
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ private:
+ const char* type_;
};
-grpc_call_credentials* grpc_call_credentials_ref(grpc_call_credentials* creds);
-void grpc_call_credentials_unref(grpc_call_credentials* creds);
-
-/// Returns true if completed synchronously, in which case \a error will
-/// be set to indicate the result. Otherwise, \a on_request_metadata will
-/// be invoked asynchronously when complete. \a md_array will be populated
-/// with the resulting metadata once complete.
-bool grpc_call_credentials_get_request_metadata(
- grpc_call_credentials* creds, grpc_polling_entity* pollent,
- grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata, grpc_error** error);
-
-/// Cancels a pending asynchronous operation started by
-/// grpc_call_credentials_get_request_metadata() with the corresponding
-/// value of \a md_array.
-void grpc_call_credentials_cancel_get_request_metadata(
- grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array,
- grpc_error* error);
-
/* Metadata-only credentials with the specified key and value where
asynchronicity can be simulated for testing. */
grpc_call_credentials* grpc_md_only_test_credentials_create(
@@ -203,26 +201,40 @@ grpc_call_credentials* grpc_md_only_test_credentials_create(
/* --- grpc_server_credentials. --- */
-typedef struct {
- void (*destruct)(grpc_server_credentials* c);
- grpc_security_status (*create_security_connector)(
- grpc_server_credentials* c, grpc_server_security_connector** sc);
-} grpc_server_credentials_vtable;
-
-struct grpc_server_credentials {
- const grpc_server_credentials_vtable* vtable;
- const char* type;
- gpr_refcount refcount;
- grpc_auth_metadata_processor processor;
-};
+// This type is forward declared as a C struct and we cannot define it as a
+// class. Otherwise, compiler will complain about type mismatch due to
+// -Wmismatched-tags.
+struct grpc_server_credentials
+ : public grpc_core::RefCounted<grpc_server_credentials> {
+ public:
+ explicit grpc_server_credentials(const char* type) : type_(type) {}
-grpc_security_status grpc_server_credentials_create_security_connector(
- grpc_server_credentials* creds, grpc_server_security_connector** sc);
+ virtual ~grpc_server_credentials() { DestroyProcessor(); }
-grpc_server_credentials* grpc_server_credentials_ref(
- grpc_server_credentials* creds);
+ virtual grpc_core::RefCountedPtr<grpc_server_security_connector>
+ create_security_connector() GRPC_ABSTRACT;
-void grpc_server_credentials_unref(grpc_server_credentials* creds);
+ const char* type() const { return type_; }
+
+ const grpc_auth_metadata_processor& auth_metadata_processor() const {
+ return processor_;
+ }
+ void set_auth_metadata_processor(
+ const grpc_auth_metadata_processor& processor);
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ private:
+ void DestroyProcessor() {
+ if (processor_.destroy != nullptr && processor_.state != nullptr) {
+ processor_.destroy(processor_.state);
+ }
+ }
+
+ const char* type_;
+ grpc_auth_metadata_processor processor_ =
+ grpc_auth_metadata_processor(); // Zero-initialize the C struct.
+};
#define GRPC_SERVER_CREDENTIALS_ARG "grpc.server_credentials"
@@ -233,15 +245,27 @@ grpc_server_credentials* grpc_find_server_credentials_in_args(
/* -- Credentials Metadata Request. -- */
-typedef struct {
- grpc_call_credentials* creds;
+struct grpc_credentials_metadata_request {
+ explicit grpc_credentials_metadata_request(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds)
+ : creds(std::move(creds)) {}
+ ~grpc_credentials_metadata_request() {
+ grpc_http_response_destroy(&response);
+ }
+
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds;
grpc_http_response response;
-} grpc_credentials_metadata_request;
+};
-grpc_credentials_metadata_request* grpc_credentials_metadata_request_create(
- grpc_call_credentials* creds);
+inline grpc_credentials_metadata_request*
+grpc_credentials_metadata_request_create(
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds) {
+ return grpc_core::New<grpc_credentials_metadata_request>(std::move(creds));
+}
-void grpc_credentials_metadata_request_destroy(
- grpc_credentials_metadata_request* r);
+inline void grpc_credentials_metadata_request_destroy(
+ grpc_credentials_metadata_request* r) {
+ grpc_core::Delete(r);
+}
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.cc b/src/core/lib/security/credentials/fake/fake_credentials.cc
index d3e0e8c816..337dd7679f 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.cc
+++ b/src/core/lib/security/credentials/fake/fake_credentials.cc
@@ -33,49 +33,45 @@
/* -- Fake transport security credentials. -- */
-static grpc_security_status fake_transport_security_create_security_connector(
- grpc_channel_credentials* c, grpc_call_credentials* call_creds,
- const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
- *sc =
- grpc_fake_channel_security_connector_create(c, call_creds, target, args);
- return GRPC_SECURITY_OK;
-}
-
-static grpc_security_status
-fake_transport_security_server_create_security_connector(
- grpc_server_credentials* c, grpc_server_security_connector** sc) {
- *sc = grpc_fake_server_security_connector_create(c);
- return GRPC_SECURITY_OK;
-}
+namespace {
+class grpc_fake_channel_credentials final : public grpc_channel_credentials {
+ public:
+ grpc_fake_channel_credentials()
+ : grpc_channel_credentials(
+ GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {}
+ ~grpc_fake_channel_credentials() override = default;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override {
+ return grpc_fake_channel_security_connector_create(
+ this->Ref(), std::move(call_creds), target, args);
+ }
+};
+
+class grpc_fake_server_credentials final : public grpc_server_credentials {
+ public:
+ grpc_fake_server_credentials()
+ : grpc_server_credentials(
+ GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY) {}
+ ~grpc_fake_server_credentials() override = default;
+
+ grpc_core::RefCountedPtr<grpc_server_security_connector>
+ create_security_connector() override {
+ return grpc_fake_server_security_connector_create(this->Ref());
+ }
+};
+} // namespace
-static grpc_channel_credentials_vtable
- fake_transport_security_credentials_vtable = {
- nullptr, fake_transport_security_create_security_connector, nullptr};
-
-static grpc_server_credentials_vtable
- fake_transport_security_server_credentials_vtable = {
- nullptr, fake_transport_security_server_create_security_connector};
-
-grpc_channel_credentials* grpc_fake_transport_security_credentials_create(
- void) {
- grpc_channel_credentials* c = static_cast<grpc_channel_credentials*>(
- gpr_zalloc(sizeof(grpc_channel_credentials)));
- c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
- c->vtable = &fake_transport_security_credentials_vtable;
- gpr_ref_init(&c->refcount, 1);
- return c;
+grpc_channel_credentials* grpc_fake_transport_security_credentials_create() {
+ return grpc_core::New<grpc_fake_channel_credentials>();
}
-grpc_server_credentials* grpc_fake_transport_security_server_credentials_create(
- void) {
- grpc_server_credentials* c = static_cast<grpc_server_credentials*>(
- gpr_malloc(sizeof(grpc_server_credentials)));
- memset(c, 0, sizeof(grpc_server_credentials));
- c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
- gpr_ref_init(&c->refcount, 1);
- c->vtable = &fake_transport_security_server_credentials_vtable;
- return c;
+grpc_server_credentials*
+grpc_fake_transport_security_server_credentials_create() {
+ return grpc_core::New<grpc_fake_server_credentials>();
}
grpc_arg grpc_fake_transport_expected_targets_arg(char* expected_targets) {
@@ -92,46 +88,25 @@ const char* grpc_fake_transport_get_expected_targets(
/* -- Metadata-only test credentials. -- */
-static void md_only_test_destruct(grpc_call_credentials* creds) {
- grpc_md_only_test_credentials* c =
- reinterpret_cast<grpc_md_only_test_credentials*>(creds);
- GRPC_MDELEM_UNREF(c->md);
-}
-
-static bool md_only_test_get_request_metadata(
- grpc_call_credentials* creds, grpc_polling_entity* pollent,
- grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata, grpc_error** error) {
- grpc_md_only_test_credentials* c =
- reinterpret_cast<grpc_md_only_test_credentials*>(creds);
- grpc_credentials_mdelem_array_add(md_array, c->md);
- if (c->is_async) {
+bool grpc_md_only_test_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
+ grpc_error** error) {
+ grpc_credentials_mdelem_array_add(md_array, md_);
+ if (is_async_) {
GRPC_CLOSURE_SCHED(on_request_metadata, GRPC_ERROR_NONE);
return false;
}
return true;
}
-static void md_only_test_cancel_get_request_metadata(
- grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
+void grpc_md_only_test_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
GRPC_ERROR_UNREF(error);
}
-static grpc_call_credentials_vtable md_only_test_vtable = {
- md_only_test_destruct, md_only_test_get_request_metadata,
- md_only_test_cancel_get_request_metadata};
-
grpc_call_credentials* grpc_md_only_test_credentials_create(
const char* md_key, const char* md_value, bool is_async) {
- grpc_md_only_test_credentials* c =
- static_cast<grpc_md_only_test_credentials*>(
- gpr_zalloc(sizeof(grpc_md_only_test_credentials)));
- c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
- c->base.vtable = &md_only_test_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- c->md = grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key),
- grpc_slice_from_copied_string(md_value));
- c->is_async = is_async;
- return &c->base;
+ return grpc_core::New<grpc_md_only_test_credentials>(md_key, md_value,
+ is_async);
}
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.h b/src/core/lib/security/credentials/fake/fake_credentials.h
index e89e6e24cc..b7f6a1909f 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.h
+++ b/src/core/lib/security/credentials/fake/fake_credentials.h
@@ -55,10 +55,28 @@ const char* grpc_fake_transport_get_expected_targets(
/* -- Metadata-only Test credentials. -- */
-typedef struct {
- grpc_call_credentials base;
- grpc_mdelem md;
- bool is_async;
-} grpc_md_only_test_credentials;
+class grpc_md_only_test_credentials : public grpc_call_credentials {
+ public:
+ grpc_md_only_test_credentials(const char* md_key, const char* md_value,
+ bool is_async)
+ : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2),
+ md_(grpc_mdelem_from_slices(grpc_slice_from_copied_string(md_key),
+ grpc_slice_from_copied_string(md_value))),
+ is_async_(is_async) {}
+ ~grpc_md_only_test_credentials() override { GRPC_MDELEM_UNREF(md_); }
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ private:
+ grpc_mdelem md_;
+ bool is_async_;
+};
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_FAKE_FAKE_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.cc b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
index fcab252959..a86a17d586 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.cc
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.cc
@@ -30,6 +30,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/http/parser.h"
#include "src/core/lib/iomgr/load_file.h"
@@ -49,9 +50,16 @@
/* -- Default credentials. -- */
-static int g_compute_engine_detection_done = 0;
-static int g_need_compute_engine_creds = 0;
+/* A sticky bit that will be set only if the result of metadata server detection
+ * is positive. We do not set the bit if the result is negative. Because it
+ * means the detection is done via network test that is unreliable and the
+ * unreliable result should not be referred by successive calls. */
+static int g_metadata_server_available = 0;
+static int g_is_on_gce = 0;
static gpr_mu g_state_mu;
+/* Protect a metadata_server_detector instance that can be modified by more than
+ * one gRPC threads */
+static gpr_mu* g_polling_mu;
static gpr_once g_once = GPR_ONCE_INIT;
static grpc_core::internal::grpc_gce_tenancy_checker g_gce_tenancy_checker =
grpc_alts_is_running_on_gcp;
@@ -63,22 +71,13 @@ typedef struct {
int is_done;
int success;
grpc_http_response response;
-} compute_engine_detector;
-
-static void google_default_credentials_destruct(
- grpc_channel_credentials* creds) {
- grpc_google_default_channel_credentials* c =
- reinterpret_cast<grpc_google_default_channel_credentials*>(creds);
- grpc_channel_credentials_unref(c->alts_creds);
- grpc_channel_credentials_unref(c->ssl_creds);
-}
+} metadata_server_detector;
-static grpc_security_status google_default_create_security_connector(
- grpc_channel_credentials* creds, grpc_call_credentials* call_creds,
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_google_default_channel_credentials::create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
- grpc_google_default_channel_credentials* c =
- reinterpret_cast<grpc_google_default_channel_credentials*>(creds);
+ grpc_channel_args** new_args) {
bool is_grpclb_load_balancer = grpc_channel_arg_get_bool(
grpc_channel_args_find(args, GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER),
false);
@@ -88,11 +87,17 @@ static grpc_security_status google_default_create_security_connector(
false);
bool use_alts =
is_grpclb_load_balancer || is_backend_from_grpclb_load_balancer;
- grpc_security_status status = GRPC_SECURITY_ERROR;
- status = use_alts ? c->alts_creds->vtable->create_security_connector(
- c->alts_creds, call_creds, target, args, sc, new_args)
- : c->ssl_creds->vtable->create_security_connector(
- c->ssl_creds, call_creds, target, args, sc, new_args);
+ /* Return failure if ALTS is selected but not running on GCE. */
+ if (use_alts && !g_is_on_gce) {
+ gpr_log(GPR_ERROR, "ALTS is selected, but not running on GCE.");
+ return nullptr;
+ }
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector> sc =
+ use_alts ? alts_creds_->create_security_connector(call_creds, target,
+ args, new_args)
+ : ssl_creds_->create_security_connector(call_creds, target, args,
+ new_args);
/* grpclb-specific channel args are removed from the channel args set
* to ensure backends and fallback adresses will have the same set of channel
* args. By doing that, it guarantees the connections to backends will not be
@@ -106,20 +111,103 @@ static grpc_security_status google_default_create_security_connector(
*new_args = grpc_channel_args_copy_and_add_and_remove(
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), nullptr, 0);
}
- return status;
+ return sc;
+}
+
+static void on_metadata_server_detection_http_response(void* user_data,
+ grpc_error* error) {
+ metadata_server_detector* detector =
+ static_cast<metadata_server_detector*>(user_data);
+ if (error == GRPC_ERROR_NONE && detector->response.status == 200 &&
+ detector->response.hdr_count > 0) {
+ /* Internet providers can return a generic response to all requests, so
+ it is necessary to check that metadata header is present also. */
+ size_t i;
+ for (i = 0; i < detector->response.hdr_count; i++) {
+ grpc_http_header* header = &detector->response.hdrs[i];
+ if (strcmp(header->key, "Metadata-Flavor") == 0 &&
+ strcmp(header->value, "Google") == 0) {
+ detector->success = 1;
+ break;
+ }
+ }
+ }
+ gpr_mu_lock(g_polling_mu);
+ detector->is_done = 1;
+ GRPC_LOG_IF_ERROR(
+ "Pollset kick",
+ grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent),
+ nullptr));
+ gpr_mu_unlock(g_polling_mu);
}
-static grpc_channel_credentials_vtable google_default_credentials_vtable = {
- google_default_credentials_destruct,
- google_default_create_security_connector, nullptr};
+static void destroy_pollset(void* p, grpc_error* e) {
+ grpc_pollset_destroy(static_cast<grpc_pollset*>(p));
+}
+
+static int is_metadata_server_reachable() {
+ metadata_server_detector detector;
+ grpc_httpcli_request request;
+ grpc_httpcli_context context;
+ grpc_closure destroy_closure;
+ /* The http call is local. If it takes more than one sec, it is for sure not
+ on compute engine. */
+ grpc_millis max_detection_delay = GPR_MS_PER_SEC;
+ grpc_pollset* pollset =
+ static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size()));
+ grpc_pollset_init(pollset, &g_polling_mu);
+ detector.pollent = grpc_polling_entity_create_from_pollset(pollset);
+ detector.is_done = 0;
+ detector.success = 0;
+ memset(&detector.response, 0, sizeof(detector.response));
+ memset(&request, 0, sizeof(grpc_httpcli_request));
+ request.host = (char*)GRPC_COMPUTE_ENGINE_DETECTION_HOST;
+ request.http.path = (char*)"/";
+ grpc_httpcli_context_init(&context);
+ grpc_resource_quota* resource_quota =
+ grpc_resource_quota_create("google_default_credentials");
+ grpc_httpcli_get(
+ &context, &detector.pollent, resource_quota, &request,
+ grpc_core::ExecCtx::Get()->Now() + max_detection_delay,
+ GRPC_CLOSURE_CREATE(on_metadata_server_detection_http_response, &detector,
+ grpc_schedule_on_exec_ctx),
+ &detector.response);
+ grpc_resource_quota_unref_internal(resource_quota);
+ grpc_core::ExecCtx::Get()->Flush();
+ /* Block until we get the response. This is not ideal but this should only be
+ called once for the lifetime of the process by the default credentials. */
+ gpr_mu_lock(g_polling_mu);
+ while (!detector.is_done) {
+ grpc_pollset_worker* worker = nullptr;
+ if (!GRPC_LOG_IF_ERROR(
+ "pollset_work",
+ grpc_pollset_work(grpc_polling_entity_pollset(&detector.pollent),
+ &worker, GRPC_MILLIS_INF_FUTURE))) {
+ detector.is_done = 1;
+ detector.success = 0;
+ }
+ }
+ gpr_mu_unlock(g_polling_mu);
+ grpc_httpcli_context_destroy(&context);
+ GRPC_CLOSURE_INIT(&destroy_closure, destroy_pollset,
+ grpc_polling_entity_pollset(&detector.pollent),
+ grpc_schedule_on_exec_ctx);
+ grpc_pollset_shutdown(grpc_polling_entity_pollset(&detector.pollent),
+ &destroy_closure);
+ g_polling_mu = nullptr;
+ grpc_core::ExecCtx::Get()->Flush();
+ gpr_free(grpc_polling_entity_pollset(&detector.pollent));
+ grpc_http_response_destroy(&detector.response);
+ return detector.success;
+}
/* Takes ownership of creds_path if not NULL. */
static grpc_error* create_default_creds_from_path(
- char* creds_path, grpc_call_credentials** creds) {
+ char* creds_path, grpc_core::RefCountedPtr<grpc_call_credentials>* creds) {
grpc_json* json = nullptr;
grpc_auth_json_key key;
grpc_auth_refresh_token token;
- grpc_call_credentials* result = nullptr;
+ grpc_core::RefCountedPtr<grpc_call_credentials> result;
grpc_slice creds_data = grpc_empty_slice();
grpc_error* error = GRPC_ERROR_NONE;
if (creds_path == nullptr) {
@@ -176,13 +264,12 @@ end:
return error;
}
-grpc_channel_credentials* grpc_google_default_credentials_create(void) {
+grpc_channel_credentials* grpc_google_default_credentials_create() {
grpc_channel_credentials* result = nullptr;
- grpc_call_credentials* call_creds = nullptr;
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds;
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Failed to create Google credentials");
grpc_error* err;
- int need_compute_engine_creds = 0;
grpc_core::ExecCtx exec_ctx;
GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
@@ -202,17 +289,23 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) {
error = grpc_error_add_child(error, err);
gpr_mu_lock(&g_state_mu);
- /* At last try to see if we're on compute engine (do the detection only once
- since it requires a network test). */
- if (!g_compute_engine_detection_done) {
- g_need_compute_engine_creds = g_gce_tenancy_checker();
- g_compute_engine_detection_done = 1;
+
+ /* Try a platform-provided hint for GCE. */
+ if (!g_metadata_server_available) {
+ g_is_on_gce = g_gce_tenancy_checker();
+ g_metadata_server_available = g_is_on_gce;
+ }
+ /* TODO: Add a platform-provided hint for GAE. */
+
+ /* Do a network test for metadata server. */
+ if (!g_metadata_server_available) {
+ g_metadata_server_available = is_metadata_server_reachable();
}
- need_compute_engine_creds = g_need_compute_engine_creds;
gpr_mu_unlock(&g_state_mu);
- if (need_compute_engine_creds) {
- call_creds = grpc_google_compute_engine_credentials_create(nullptr);
+ if (g_metadata_server_available) {
+ call_creds = grpc_core::RefCountedPtr<grpc_call_credentials>(
+ grpc_google_compute_engine_credentials_create(nullptr));
if (call_creds == nullptr) {
error = grpc_error_add_child(
error, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
@@ -223,23 +316,23 @@ grpc_channel_credentials* grpc_google_default_credentials_create(void) {
end:
if (call_creds != nullptr) {
/* Create google default credentials. */
- auto creds = static_cast<grpc_google_default_channel_credentials*>(
- gpr_zalloc(sizeof(grpc_google_default_channel_credentials)));
- creds->base.vtable = &google_default_credentials_vtable;
- creds->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT;
- gpr_ref_init(&creds->base.refcount, 1);
- creds->ssl_creds =
+ grpc_channel_credentials* ssl_creds =
grpc_ssl_credentials_create(nullptr, nullptr, nullptr, nullptr);
- GPR_ASSERT(creds->ssl_creds != nullptr);
+ GPR_ASSERT(ssl_creds != nullptr);
grpc_alts_credentials_options* options =
grpc_alts_credentials_client_options_create();
- creds->alts_creds = grpc_alts_credentials_create(options);
+ grpc_channel_credentials* alts_creds =
+ grpc_alts_credentials_create(options);
grpc_alts_credentials_options_destroy(options);
- result = grpc_composite_channel_credentials_create(&creds->base, call_creds,
- nullptr);
+ auto creds =
+ grpc_core::MakeRefCounted<grpc_google_default_channel_credentials>(
+ alts_creds != nullptr ? alts_creds->Ref() : nullptr,
+ ssl_creds != nullptr ? ssl_creds->Ref() : nullptr);
+ if (ssl_creds) ssl_creds->Unref();
+ if (alts_creds) alts_creds->Unref();
+ result = grpc_composite_channel_credentials_create(
+ creds.get(), call_creds.get(), nullptr);
GPR_ASSERT(result != nullptr);
- grpc_channel_credentials_unref(&creds->base);
- grpc_call_credentials_unref(call_creds);
} else {
gpr_log(GPR_ERROR, "Could not create google default credentials: %s",
grpc_error_string(error));
@@ -259,7 +352,7 @@ void grpc_flush_cached_google_default_credentials(void) {
grpc_core::ExecCtx exec_ctx;
gpr_once_init(&g_once, init_default_credentials);
gpr_mu_lock(&g_state_mu);
- g_compute_engine_detection_done = 0;
+ g_metadata_server_available = 0;
gpr_mu_unlock(&g_state_mu);
}
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.h b/src/core/lib/security/credentials/google_default/google_default_credentials.h
index b9e2efb04f..bf00f7285a 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.h
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.h
@@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/credentials/credentials.h"
#define GRPC_GOOGLE_CLOUD_SDK_CONFIG_DIRECTORY "gcloud"
@@ -39,11 +40,33 @@
"/" GRPC_GOOGLE_WELL_KNOWN_CREDENTIALS_FILE
#endif
-typedef struct {
- grpc_channel_credentials base;
- grpc_channel_credentials* alts_creds;
- grpc_channel_credentials* ssl_creds;
-} grpc_google_default_channel_credentials;
+class grpc_google_default_channel_credentials
+ : public grpc_channel_credentials {
+ public:
+ grpc_google_default_channel_credentials(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> alts_creds,
+ grpc_core::RefCountedPtr<grpc_channel_credentials> ssl_creds)
+ : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_GOOGLE_DEFAULT),
+ alts_creds_(std::move(alts_creds)),
+ ssl_creds_(std::move(ssl_creds)) {}
+
+ ~grpc_google_default_channel_credentials() override = default;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override;
+
+ const grpc_channel_credentials* alts_creds() const {
+ return alts_creds_.get();
+ }
+ const grpc_channel_credentials* ssl_creds() const { return ssl_creds_.get(); }
+
+ private:
+ grpc_core::RefCountedPtr<grpc_channel_credentials> alts_creds_;
+ grpc_core::RefCountedPtr<grpc_channel_credentials> ssl_creds_;
+};
namespace grpc_core {
namespace internal {
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.cc b/src/core/lib/security/credentials/iam/iam_credentials.cc
index 5d92fa88c4..5cd561f676 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.cc
+++ b/src/core/lib/security/credentials/iam/iam_credentials.cc
@@ -22,6 +22,7 @@
#include <string.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
@@ -29,32 +30,37 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-static void iam_destruct(grpc_call_credentials* creds) {
- grpc_google_iam_credentials* c =
- reinterpret_cast<grpc_google_iam_credentials*>(creds);
- grpc_credentials_mdelem_array_destroy(&c->md_array);
+grpc_google_iam_credentials::~grpc_google_iam_credentials() {
+ grpc_credentials_mdelem_array_destroy(&md_array_);
}
-static bool iam_get_request_metadata(grpc_call_credentials* creds,
- grpc_polling_entity* pollent,
- grpc_auth_metadata_context context,
- grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata,
- grpc_error** error) {
- grpc_google_iam_credentials* c =
- reinterpret_cast<grpc_google_iam_credentials*>(creds);
- grpc_credentials_mdelem_array_append(md_array, &c->md_array);
+bool grpc_google_iam_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
+ grpc_error** error) {
+ grpc_credentials_mdelem_array_append(md_array, &md_array_);
return true;
}
-static void iam_cancel_get_request_metadata(
- grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
+void grpc_google_iam_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
GRPC_ERROR_UNREF(error);
}
-static grpc_call_credentials_vtable iam_vtable = {
- iam_destruct, iam_get_request_metadata, iam_cancel_get_request_metadata};
+grpc_google_iam_credentials::grpc_google_iam_credentials(
+ const char* token, const char* authority_selector)
+ : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_IAM) {
+ grpc_mdelem md = grpc_mdelem_from_slices(
+ grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY),
+ grpc_slice_from_copied_string(token));
+ grpc_credentials_mdelem_array_add(&md_array_, md);
+ GRPC_MDELEM_UNREF(md);
+ md = grpc_mdelem_from_slices(
+ grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY),
+ grpc_slice_from_copied_string(authority_selector));
+ grpc_credentials_mdelem_array_add(&md_array_, md);
+ GRPC_MDELEM_UNREF(md);
+}
grpc_call_credentials* grpc_google_iam_credentials_create(
const char* token, const char* authority_selector, void* reserved) {
@@ -66,21 +72,7 @@ grpc_call_credentials* grpc_google_iam_credentials_create(
GPR_ASSERT(reserved == nullptr);
GPR_ASSERT(token != nullptr);
GPR_ASSERT(authority_selector != nullptr);
- grpc_google_iam_credentials* c =
- static_cast<grpc_google_iam_credentials*>(gpr_zalloc(sizeof(*c)));
- c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM;
- c->base.vtable = &iam_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- grpc_mdelem md = grpc_mdelem_from_slices(
- grpc_slice_from_static_string(GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY),
- grpc_slice_from_copied_string(token));
- grpc_credentials_mdelem_array_add(&c->md_array, md);
- GRPC_MDELEM_UNREF(md);
- md = grpc_mdelem_from_slices(
- grpc_slice_from_static_string(GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY),
- grpc_slice_from_copied_string(authority_selector));
- grpc_credentials_mdelem_array_add(&c->md_array, md);
- GRPC_MDELEM_UNREF(md);
-
- return &c->base;
+ return grpc_core::MakeRefCounted<grpc_google_iam_credentials>(
+ token, authority_selector)
+ .release();
}
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.h b/src/core/lib/security/credentials/iam/iam_credentials.h
index a45710fe0f..36f5ee8930 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.h
+++ b/src/core/lib/security/credentials/iam/iam_credentials.h
@@ -23,9 +23,23 @@
#include "src/core/lib/security/credentials/credentials.h"
-typedef struct {
- grpc_call_credentials base;
- grpc_credentials_mdelem_array md_array;
-} grpc_google_iam_credentials;
+class grpc_google_iam_credentials : public grpc_call_credentials {
+ public:
+ grpc_google_iam_credentials(const char* token,
+ const char* authority_selector);
+ ~grpc_google_iam_credentials() override;
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ private:
+ grpc_credentials_mdelem_array md_array_;
+};
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_IAM_IAM_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.cc b/src/core/lib/security/credentials/jwt/jwt_credentials.cc
index 05c08a68b0..f2591a1ea5 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.cc
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.cc
@@ -23,6 +23,8 @@
#include <inttypes.h>
#include <string.h>
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/surface/api_trace.h"
#include <grpc/support/alloc.h>
@@ -30,71 +32,66 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
-static void jwt_reset_cache(grpc_service_account_jwt_access_credentials* c) {
- GRPC_MDELEM_UNREF(c->cached.jwt_md);
- c->cached.jwt_md = GRPC_MDNULL;
- if (c->cached.service_url != nullptr) {
- gpr_free(c->cached.service_url);
- c->cached.service_url = nullptr;
+void grpc_service_account_jwt_access_credentials::reset_cache() {
+ GRPC_MDELEM_UNREF(cached_.jwt_md);
+ cached_.jwt_md = GRPC_MDNULL;
+ if (cached_.service_url != nullptr) {
+ gpr_free(cached_.service_url);
+ cached_.service_url = nullptr;
}
- c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
+ cached_.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
}
-static void jwt_destruct(grpc_call_credentials* creds) {
- grpc_service_account_jwt_access_credentials* c =
- reinterpret_cast<grpc_service_account_jwt_access_credentials*>(creds);
- grpc_auth_json_key_destruct(&c->key);
- jwt_reset_cache(c);
- gpr_mu_destroy(&c->cache_mu);
+grpc_service_account_jwt_access_credentials::
+ ~grpc_service_account_jwt_access_credentials() {
+ grpc_auth_json_key_destruct(&key_);
+ reset_cache();
+ gpr_mu_destroy(&cache_mu_);
}
-static bool jwt_get_request_metadata(grpc_call_credentials* creds,
- grpc_polling_entity* pollent,
- grpc_auth_metadata_context context,
- grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata,
- grpc_error** error) {
- grpc_service_account_jwt_access_credentials* c =
- reinterpret_cast<grpc_service_account_jwt_access_credentials*>(creds);
+bool grpc_service_account_jwt_access_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
+ grpc_error** error) {
gpr_timespec refresh_threshold = gpr_time_from_seconds(
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS, GPR_TIMESPAN);
/* See if we can return a cached jwt. */
grpc_mdelem jwt_md = GRPC_MDNULL;
{
- gpr_mu_lock(&c->cache_mu);
- if (c->cached.service_url != nullptr &&
- strcmp(c->cached.service_url, context.service_url) == 0 &&
- !GRPC_MDISNULL(c->cached.jwt_md) &&
- (gpr_time_cmp(gpr_time_sub(c->cached.jwt_expiration,
- gpr_now(GPR_CLOCK_REALTIME)),
- refresh_threshold) > 0)) {
- jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md);
+ gpr_mu_lock(&cache_mu_);
+ if (cached_.service_url != nullptr &&
+ strcmp(cached_.service_url, context.service_url) == 0 &&
+ !GRPC_MDISNULL(cached_.jwt_md) &&
+ (gpr_time_cmp(
+ gpr_time_sub(cached_.jwt_expiration, gpr_now(GPR_CLOCK_REALTIME)),
+ refresh_threshold) > 0)) {
+ jwt_md = GRPC_MDELEM_REF(cached_.jwt_md);
}
- gpr_mu_unlock(&c->cache_mu);
+ gpr_mu_unlock(&cache_mu_);
}
if (GRPC_MDISNULL(jwt_md)) {
char* jwt = nullptr;
/* Generate a new jwt. */
- gpr_mu_lock(&c->cache_mu);
- jwt_reset_cache(c);
- jwt = grpc_jwt_encode_and_sign(&c->key, context.service_url,
- c->jwt_lifetime, nullptr);
+ gpr_mu_lock(&cache_mu_);
+ reset_cache();
+ jwt = grpc_jwt_encode_and_sign(&key_, context.service_url, jwt_lifetime_,
+ nullptr);
if (jwt != nullptr) {
char* md_value;
gpr_asprintf(&md_value, "Bearer %s", jwt);
gpr_free(jwt);
- c->cached.jwt_expiration =
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), c->jwt_lifetime);
- c->cached.service_url = gpr_strdup(context.service_url);
- c->cached.jwt_md = grpc_mdelem_from_slices(
+ cached_.jwt_expiration =
+ gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), jwt_lifetime_);
+ cached_.service_url = gpr_strdup(context.service_url);
+ cached_.jwt_md = grpc_mdelem_from_slices(
grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY),
grpc_slice_from_copied_string(md_value));
gpr_free(md_value);
- jwt_md = GRPC_MDELEM_REF(c->cached.jwt_md);
+ jwt_md = GRPC_MDELEM_REF(cached_.jwt_md);
}
- gpr_mu_unlock(&c->cache_mu);
+ gpr_mu_unlock(&cache_mu_);
}
if (!GRPC_MDISNULL(jwt_md)) {
@@ -106,29 +103,15 @@ static bool jwt_get_request_metadata(grpc_call_credentials* creds,
return true;
}
-static void jwt_cancel_get_request_metadata(
- grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
+void grpc_service_account_jwt_access_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
GRPC_ERROR_UNREF(error);
}
-static grpc_call_credentials_vtable jwt_vtable = {
- jwt_destruct, jwt_get_request_metadata, jwt_cancel_get_request_metadata};
-
-grpc_call_credentials*
-grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
- grpc_auth_json_key key, gpr_timespec token_lifetime) {
- grpc_service_account_jwt_access_credentials* c;
- if (!grpc_auth_json_key_is_valid(&key)) {
- gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
- return nullptr;
- }
- c = static_cast<grpc_service_account_jwt_access_credentials*>(
- gpr_zalloc(sizeof(grpc_service_account_jwt_access_credentials)));
- c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT;
- gpr_ref_init(&c->base.refcount, 1);
- c->base.vtable = &jwt_vtable;
- c->key = key;
+grpc_service_account_jwt_access_credentials::
+ grpc_service_account_jwt_access_credentials(grpc_auth_json_key key,
+ gpr_timespec token_lifetime)
+ : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_JWT), key_(key) {
gpr_timespec max_token_lifetime = grpc_max_auth_token_lifetime();
if (gpr_time_cmp(token_lifetime, max_token_lifetime) > 0) {
gpr_log(GPR_INFO,
@@ -136,10 +119,20 @@ grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
static_cast<int>(max_token_lifetime.tv_sec));
token_lifetime = grpc_max_auth_token_lifetime();
}
- c->jwt_lifetime = token_lifetime;
- gpr_mu_init(&c->cache_mu);
- jwt_reset_cache(c);
- return &c->base;
+ jwt_lifetime_ = token_lifetime;
+ gpr_mu_init(&cache_mu_);
+ reset_cache();
+}
+
+grpc_core::RefCountedPtr<grpc_call_credentials>
+grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
+ grpc_auth_json_key key, gpr_timespec token_lifetime) {
+ if (!grpc_auth_json_key_is_valid(&key)) {
+ gpr_log(GPR_ERROR, "Invalid input for jwt credentials creation");
+ return nullptr;
+ }
+ return grpc_core::MakeRefCounted<grpc_service_account_jwt_access_credentials>(
+ key, token_lifetime);
}
static char* redact_private_key(const char* json_key) {
@@ -182,9 +175,7 @@ grpc_call_credentials* grpc_service_account_jwt_access_credentials_create(
}
GPR_ASSERT(reserved == nullptr);
grpc_core::ExecCtx exec_ctx;
- grpc_call_credentials* creds =
- grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
- grpc_auth_json_key_create_from_string(json_key), token_lifetime);
-
- return creds;
+ return grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
+ grpc_auth_json_key_create_from_string(json_key), token_lifetime)
+ .release();
}
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.h b/src/core/lib/security/credentials/jwt/jwt_credentials.h
index 5c3d34aa56..5af909f44d 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.h
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.h
@@ -24,25 +24,44 @@
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
-typedef struct {
- grpc_call_credentials base;
+class grpc_service_account_jwt_access_credentials
+ : public grpc_call_credentials {
+ public:
+ grpc_service_account_jwt_access_credentials(grpc_auth_json_key key,
+ gpr_timespec token_lifetime);
+ ~grpc_service_account_jwt_access_credentials() override;
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ const gpr_timespec& jwt_lifetime() const { return jwt_lifetime_; }
+ const grpc_auth_json_key& key() const { return key_; }
+
+ private:
+ void reset_cache();
// Have a simple cache for now with just 1 entry. We could have a map based on
// the service_url for a more sophisticated one.
- gpr_mu cache_mu;
+ gpr_mu cache_mu_;
struct {
- grpc_mdelem jwt_md;
- char* service_url;
+ grpc_mdelem jwt_md = GRPC_MDNULL;
+ char* service_url = nullptr;
gpr_timespec jwt_expiration;
- } cached;
+ } cached_;
- grpc_auth_json_key key;
- gpr_timespec jwt_lifetime;
-} grpc_service_account_jwt_access_credentials;
+ grpc_auth_json_key key_;
+ gpr_timespec jwt_lifetime_;
+};
// Private constructor for jwt credentials from an already parsed json key.
// Takes ownership of the key.
-grpc_call_credentials*
+grpc_core::RefCountedPtr<grpc_call_credentials>
grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
grpc_auth_json_key key, gpr_timespec token_lifetime);
diff --git a/src/core/lib/security/credentials/local/local_credentials.cc b/src/core/lib/security/credentials/local/local_credentials.cc
index 3ccfa2b908..6f6f95a34a 100644
--- a/src/core/lib/security/credentials/local/local_credentials.cc
+++ b/src/core/lib/security/credentials/local/local_credentials.cc
@@ -29,49 +29,36 @@
#define GRPC_CREDENTIALS_TYPE_LOCAL "Local"
-static void local_credentials_destruct(grpc_channel_credentials* creds) {}
-
-static void local_server_credentials_destruct(grpc_server_credentials* creds) {}
-
-static grpc_security_status local_create_security_connector(
- grpc_channel_credentials* creds,
- grpc_call_credentials* request_metadata_creds, const char* target_name,
- const grpc_channel_args* args, grpc_channel_security_connector** sc,
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_local_credentials::create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target_name, const grpc_channel_args* args,
grpc_channel_args** new_args) {
return grpc_local_channel_security_connector_create(
- creds, request_metadata_creds, args, target_name, sc);
+ this->Ref(), std::move(request_metadata_creds), args, target_name);
}
-static grpc_security_status local_server_create_security_connector(
- grpc_server_credentials* creds, grpc_server_security_connector** sc) {
- return grpc_local_server_security_connector_create(creds, sc);
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_local_server_credentials::create_security_connector() {
+ return grpc_local_server_security_connector_create(this->Ref());
}
-static const grpc_channel_credentials_vtable local_credentials_vtable = {
- local_credentials_destruct, local_create_security_connector,
- /*duplicate_without_call_credentials=*/nullptr};
-
-static const grpc_server_credentials_vtable local_server_credentials_vtable = {
- local_server_credentials_destruct, local_server_create_security_connector};
+grpc_local_credentials::grpc_local_credentials(
+ grpc_local_connect_type connect_type)
+ : grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_LOCAL),
+ connect_type_(connect_type) {}
grpc_channel_credentials* grpc_local_credentials_create(
grpc_local_connect_type connect_type) {
- auto creds = static_cast<grpc_local_credentials*>(
- gpr_zalloc(sizeof(grpc_local_credentials)));
- creds->connect_type = connect_type;
- creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL;
- creds->base.vtable = &local_credentials_vtable;
- gpr_ref_init(&creds->base.refcount, 1);
- return &creds->base;
+ return grpc_core::New<grpc_local_credentials>(connect_type);
}
+grpc_local_server_credentials::grpc_local_server_credentials(
+ grpc_local_connect_type connect_type)
+ : grpc_server_credentials(GRPC_CREDENTIALS_TYPE_LOCAL),
+ connect_type_(connect_type) {}
+
grpc_server_credentials* grpc_local_server_credentials_create(
grpc_local_connect_type connect_type) {
- auto creds = static_cast<grpc_local_server_credentials*>(
- gpr_zalloc(sizeof(grpc_local_server_credentials)));
- creds->connect_type = connect_type;
- creds->base.type = GRPC_CREDENTIALS_TYPE_LOCAL;
- creds->base.vtable = &local_server_credentials_vtable;
- gpr_ref_init(&creds->base.refcount, 1);
- return &creds->base;
+ return grpc_core::New<grpc_local_server_credentials>(connect_type);
}
diff --git a/src/core/lib/security/credentials/local/local_credentials.h b/src/core/lib/security/credentials/local/local_credentials.h
index 47358b04bc..60a8a4f64c 100644
--- a/src/core/lib/security/credentials/local/local_credentials.h
+++ b/src/core/lib/security/credentials/local/local_credentials.h
@@ -25,16 +25,37 @@
#include "src/core/lib/security/credentials/credentials.h"
-/* Main struct for grpc local channel credential. */
-typedef struct grpc_local_credentials {
- grpc_channel_credentials base;
- grpc_local_connect_type connect_type;
-} grpc_local_credentials;
-
-/* Main struct for grpc local server credential. */
-typedef struct grpc_local_server_credentials {
- grpc_server_credentials base;
- grpc_local_connect_type connect_type;
-} grpc_local_server_credentials;
+/* Main class for grpc local channel credential. */
+class grpc_local_credentials final : public grpc_channel_credentials {
+ public:
+ explicit grpc_local_credentials(grpc_local_connect_type connect_type);
+ ~grpc_local_credentials() override = default;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target_name, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override;
+
+ grpc_local_connect_type connect_type() const { return connect_type_; }
+
+ private:
+ grpc_local_connect_type connect_type_;
+};
+
+/* Main class for grpc local server credential. */
+class grpc_local_server_credentials final : public grpc_server_credentials {
+ public:
+ explicit grpc_local_server_credentials(grpc_local_connect_type connect_type);
+ ~grpc_local_server_credentials() override = default;
+
+ grpc_core::RefCountedPtr<grpc_server_security_connector>
+ create_security_connector() override;
+
+ grpc_local_connect_type connect_type() const { return connect_type_; }
+
+ private:
+ grpc_local_connect_type connect_type_;
+};
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_LOCAL_LOCAL_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
index 44b093557f..ad63b01e75 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc
@@ -22,6 +22,7 @@
#include <string.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/util/json_util.h"
#include "src/core/lib/surface/api_trace.h"
@@ -105,13 +106,12 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token) {
// Oauth2 Token Fetcher credentials.
//
-static void oauth2_token_fetcher_destruct(grpc_call_credentials* creds) {
- grpc_oauth2_token_fetcher_credentials* c =
- reinterpret_cast<grpc_oauth2_token_fetcher_credentials*>(creds);
- GRPC_MDELEM_UNREF(c->access_token_md);
- gpr_mu_destroy(&c->mu);
- grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&c->pollent));
- grpc_httpcli_context_destroy(&c->httpcli_context);
+grpc_oauth2_token_fetcher_credentials::
+ ~grpc_oauth2_token_fetcher_credentials() {
+ GRPC_MDELEM_UNREF(access_token_md_);
+ gpr_mu_destroy(&mu_);
+ grpc_pollset_set_destroy(grpc_polling_entity_pollset_set(&pollent_));
+ grpc_httpcli_context_destroy(&httpcli_context_);
}
grpc_credentials_status
@@ -209,25 +209,29 @@ static void on_oauth2_token_fetcher_http_response(void* user_data,
grpc_credentials_metadata_request* r =
static_cast<grpc_credentials_metadata_request*>(user_data);
grpc_oauth2_token_fetcher_credentials* c =
- reinterpret_cast<grpc_oauth2_token_fetcher_credentials*>(r->creds);
+ reinterpret_cast<grpc_oauth2_token_fetcher_credentials*>(r->creds.get());
+ c->on_http_response(r, error);
+}
+
+void grpc_oauth2_token_fetcher_credentials::on_http_response(
+ grpc_credentials_metadata_request* r, grpc_error* error) {
grpc_mdelem access_token_md = GRPC_MDNULL;
grpc_millis token_lifetime;
grpc_credentials_status status =
grpc_oauth2_token_fetcher_credentials_parse_server_response(
&r->response, &access_token_md, &token_lifetime);
// Update cache and grab list of pending requests.
- gpr_mu_lock(&c->mu);
- c->token_fetch_pending = false;
- c->access_token_md = GRPC_MDELEM_REF(access_token_md);
- c->token_expiration =
+ gpr_mu_lock(&mu_);
+ token_fetch_pending_ = false;
+ access_token_md_ = GRPC_MDELEM_REF(access_token_md);
+ token_expiration_ =
status == GRPC_CREDENTIALS_OK
? gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
gpr_time_from_millis(token_lifetime, GPR_TIMESPAN))
: gpr_inf_past(GPR_CLOCK_MONOTONIC);
- grpc_oauth2_pending_get_request_metadata* pending_request =
- c->pending_requests;
- c->pending_requests = nullptr;
- gpr_mu_unlock(&c->mu);
+ grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_;
+ pending_requests_ = nullptr;
+ gpr_mu_unlock(&mu_);
// Invoke callbacks for all pending requests.
while (pending_request != nullptr) {
if (status == GRPC_CREDENTIALS_OK) {
@@ -239,42 +243,40 @@ static void on_oauth2_token_fetcher_http_response(void* user_data,
}
GRPC_CLOSURE_SCHED(pending_request->on_request_metadata, error);
grpc_polling_entity_del_from_pollset_set(
- pending_request->pollent, grpc_polling_entity_pollset_set(&c->pollent));
+ pending_request->pollent, grpc_polling_entity_pollset_set(&pollent_));
grpc_oauth2_pending_get_request_metadata* prev = pending_request;
pending_request = pending_request->next;
gpr_free(prev);
}
GRPC_MDELEM_UNREF(access_token_md);
- grpc_call_credentials_unref(r->creds);
+ Unref();
grpc_credentials_metadata_request_destroy(r);
}
-static bool oauth2_token_fetcher_get_request_metadata(
- grpc_call_credentials* creds, grpc_polling_entity* pollent,
- grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata, grpc_error** error) {
- grpc_oauth2_token_fetcher_credentials* c =
- reinterpret_cast<grpc_oauth2_token_fetcher_credentials*>(creds);
+bool grpc_oauth2_token_fetcher_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
+ grpc_error** error) {
// Check if we can use the cached token.
grpc_millis refresh_threshold =
GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS * GPR_MS_PER_SEC;
grpc_mdelem cached_access_token_md = GRPC_MDNULL;
- gpr_mu_lock(&c->mu);
- if (!GRPC_MDISNULL(c->access_token_md) &&
+ gpr_mu_lock(&mu_);
+ if (!GRPC_MDISNULL(access_token_md_) &&
gpr_time_cmp(
- gpr_time_sub(c->token_expiration, gpr_now(GPR_CLOCK_MONOTONIC)),
+ gpr_time_sub(token_expiration_, gpr_now(GPR_CLOCK_MONOTONIC)),
gpr_time_from_seconds(GRPC_SECURE_TOKEN_REFRESH_THRESHOLD_SECS,
GPR_TIMESPAN)) > 0) {
- cached_access_token_md = GRPC_MDELEM_REF(c->access_token_md);
+ cached_access_token_md = GRPC_MDELEM_REF(access_token_md_);
}
if (!GRPC_MDISNULL(cached_access_token_md)) {
- gpr_mu_unlock(&c->mu);
+ gpr_mu_unlock(&mu_);
grpc_credentials_mdelem_array_add(md_array, cached_access_token_md);
GRPC_MDELEM_UNREF(cached_access_token_md);
return true;
}
// Couldn't get the token from the cache.
- // Add request to c->pending_requests and start a new fetch if needed.
+ // Add request to pending_requests_ and start a new fetch if needed.
grpc_oauth2_pending_get_request_metadata* pending_request =
static_cast<grpc_oauth2_pending_get_request_metadata*>(
gpr_malloc(sizeof(*pending_request)));
@@ -282,41 +284,37 @@ static bool oauth2_token_fetcher_get_request_metadata(
pending_request->on_request_metadata = on_request_metadata;
pending_request->pollent = pollent;
grpc_polling_entity_add_to_pollset_set(
- pollent, grpc_polling_entity_pollset_set(&c->pollent));
- pending_request->next = c->pending_requests;
- c->pending_requests = pending_request;
+ pollent, grpc_polling_entity_pollset_set(&pollent_));
+ pending_request->next = pending_requests_;
+ pending_requests_ = pending_request;
bool start_fetch = false;
- if (!c->token_fetch_pending) {
- c->token_fetch_pending = true;
+ if (!token_fetch_pending_) {
+ token_fetch_pending_ = true;
start_fetch = true;
}
- gpr_mu_unlock(&c->mu);
+ gpr_mu_unlock(&mu_);
if (start_fetch) {
- grpc_call_credentials_ref(creds);
- c->fetch_func(grpc_credentials_metadata_request_create(creds),
- &c->httpcli_context, &c->pollent,
- on_oauth2_token_fetcher_http_response,
- grpc_core::ExecCtx::Get()->Now() + refresh_threshold);
+ Ref().release();
+ fetch_oauth2(grpc_credentials_metadata_request_create(this->Ref()),
+ &httpcli_context_, &pollent_,
+ on_oauth2_token_fetcher_http_response,
+ grpc_core::ExecCtx::Get()->Now() + refresh_threshold);
}
return false;
}
-static void oauth2_token_fetcher_cancel_get_request_metadata(
- grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
- grpc_oauth2_token_fetcher_credentials* c =
- reinterpret_cast<grpc_oauth2_token_fetcher_credentials*>(creds);
- gpr_mu_lock(&c->mu);
+void grpc_oauth2_token_fetcher_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
+ gpr_mu_lock(&mu_);
grpc_oauth2_pending_get_request_metadata* prev = nullptr;
- grpc_oauth2_pending_get_request_metadata* pending_request =
- c->pending_requests;
+ grpc_oauth2_pending_get_request_metadata* pending_request = pending_requests_;
while (pending_request != nullptr) {
if (pending_request->md_array == md_array) {
// Remove matching pending request from the list.
if (prev != nullptr) {
prev->next = pending_request->next;
} else {
- c->pending_requests = pending_request->next;
+ pending_requests_ = pending_request->next;
}
// Invoke the callback immediately with an error.
GRPC_CLOSURE_SCHED(pending_request->on_request_metadata,
@@ -327,96 +325,89 @@ static void oauth2_token_fetcher_cancel_get_request_metadata(
prev = pending_request;
pending_request = pending_request->next;
}
- gpr_mu_unlock(&c->mu);
+ gpr_mu_unlock(&mu_);
GRPC_ERROR_UNREF(error);
}
-static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials* c,
- grpc_fetch_oauth2_func fetch_func) {
- memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
- c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
- gpr_ref_init(&c->base.refcount, 1);
- gpr_mu_init(&c->mu);
- c->token_expiration = gpr_inf_past(GPR_CLOCK_MONOTONIC);
- c->fetch_func = fetch_func;
- c->pollent =
- grpc_polling_entity_create_from_pollset_set(grpc_pollset_set_create());
- grpc_httpcli_context_init(&c->httpcli_context);
+grpc_oauth2_token_fetcher_credentials::grpc_oauth2_token_fetcher_credentials()
+ : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2),
+ token_expiration_(gpr_inf_past(GPR_CLOCK_MONOTONIC)),
+ pollent_(grpc_polling_entity_create_from_pollset_set(
+ grpc_pollset_set_create())) {
+ gpr_mu_init(&mu_);
+ grpc_httpcli_context_init(&httpcli_context_);
}
//
// Google Compute Engine credentials.
//
-static grpc_call_credentials_vtable compute_engine_vtable = {
- oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata,
- oauth2_token_fetcher_cancel_get_request_metadata};
+namespace {
+
+class grpc_compute_engine_token_fetcher_credentials
+ : public grpc_oauth2_token_fetcher_credentials {
+ public:
+ grpc_compute_engine_token_fetcher_credentials() = default;
+ ~grpc_compute_engine_token_fetcher_credentials() override = default;
+
+ protected:
+ void fetch_oauth2(grpc_credentials_metadata_request* metadata_req,
+ grpc_httpcli_context* http_context,
+ grpc_polling_entity* pollent,
+ grpc_iomgr_cb_func response_cb,
+ grpc_millis deadline) override {
+ grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"};
+ grpc_httpcli_request request;
+ memset(&request, 0, sizeof(grpc_httpcli_request));
+ request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST;
+ request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
+ request.http.hdr_count = 1;
+ request.http.hdrs = &header;
+ /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
+ channel. This would allow us to cancel an authentication query when under
+ extreme memory pressure. */
+ grpc_resource_quota* resource_quota =
+ grpc_resource_quota_create("oauth2_credentials");
+ grpc_httpcli_get(http_context, pollent, resource_quota, &request, deadline,
+ GRPC_CLOSURE_CREATE(response_cb, metadata_req,
+ grpc_schedule_on_exec_ctx),
+ &metadata_req->response);
+ grpc_resource_quota_unref_internal(resource_quota);
+ }
+};
-static void compute_engine_fetch_oauth2(
- grpc_credentials_metadata_request* metadata_req,
- grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent,
- grpc_iomgr_cb_func response_cb, grpc_millis deadline) {
- grpc_http_header header = {(char*)"Metadata-Flavor", (char*)"Google"};
- grpc_httpcli_request request;
- memset(&request, 0, sizeof(grpc_httpcli_request));
- request.host = (char*)GRPC_COMPUTE_ENGINE_METADATA_HOST;
- request.http.path = (char*)GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
- request.http.hdr_count = 1;
- request.http.hdrs = &header;
- /* TODO(ctiller): Carry the resource_quota in ctx and share it with the host
- channel. This would allow us to cancel an authentication query when under
- extreme memory pressure. */
- grpc_resource_quota* resource_quota =
- grpc_resource_quota_create("oauth2_credentials");
- grpc_httpcli_get(
- httpcli_context, pollent, resource_quota, &request, deadline,
- GRPC_CLOSURE_CREATE(response_cb, metadata_req, grpc_schedule_on_exec_ctx),
- &metadata_req->response);
- grpc_resource_quota_unref_internal(resource_quota);
-}
+} // namespace
grpc_call_credentials* grpc_google_compute_engine_credentials_create(
void* reserved) {
- grpc_oauth2_token_fetcher_credentials* c =
- static_cast<grpc_oauth2_token_fetcher_credentials*>(
- gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials)));
GRPC_API_TRACE("grpc_compute_engine_credentials_create(reserved=%p)", 1,
(reserved));
GPR_ASSERT(reserved == nullptr);
- init_oauth2_token_fetcher(c, compute_engine_fetch_oauth2);
- c->base.vtable = &compute_engine_vtable;
- return &c->base;
+ return grpc_core::MakeRefCounted<
+ grpc_compute_engine_token_fetcher_credentials>()
+ .release();
}
//
// Google Refresh Token credentials.
//
-static void refresh_token_destruct(grpc_call_credentials* creds) {
- grpc_google_refresh_token_credentials* c =
- reinterpret_cast<grpc_google_refresh_token_credentials*>(creds);
- grpc_auth_refresh_token_destruct(&c->refresh_token);
- oauth2_token_fetcher_destruct(&c->base.base);
+grpc_google_refresh_token_credentials::
+ ~grpc_google_refresh_token_credentials() {
+ grpc_auth_refresh_token_destruct(&refresh_token_);
}
-static grpc_call_credentials_vtable refresh_token_vtable = {
- refresh_token_destruct, oauth2_token_fetcher_get_request_metadata,
- oauth2_token_fetcher_cancel_get_request_metadata};
-
-static void refresh_token_fetch_oauth2(
+void grpc_google_refresh_token_credentials::fetch_oauth2(
grpc_credentials_metadata_request* metadata_req,
grpc_httpcli_context* httpcli_context, grpc_polling_entity* pollent,
grpc_iomgr_cb_func response_cb, grpc_millis deadline) {
- grpc_google_refresh_token_credentials* c =
- reinterpret_cast<grpc_google_refresh_token_credentials*>(
- metadata_req->creds);
grpc_http_header header = {(char*)"Content-Type",
(char*)"application/x-www-form-urlencoded"};
grpc_httpcli_request request;
char* body = nullptr;
gpr_asprintf(&body, GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING,
- c->refresh_token.client_id, c->refresh_token.client_secret,
- c->refresh_token.refresh_token);
+ refresh_token_.client_id, refresh_token_.client_secret,
+ refresh_token_.refresh_token);
memset(&request, 0, sizeof(grpc_httpcli_request));
request.host = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_HOST;
request.http.path = (char*)GRPC_GOOGLE_OAUTH2_SERVICE_TOKEN_PATH;
@@ -437,20 +428,19 @@ static void refresh_token_fetch_oauth2(
gpr_free(body);
}
-grpc_call_credentials*
+grpc_google_refresh_token_credentials::grpc_google_refresh_token_credentials(
+ grpc_auth_refresh_token refresh_token)
+ : refresh_token_(refresh_token) {}
+
+grpc_core::RefCountedPtr<grpc_call_credentials>
grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token refresh_token) {
- grpc_google_refresh_token_credentials* c;
if (!grpc_auth_refresh_token_is_valid(&refresh_token)) {
gpr_log(GPR_ERROR, "Invalid input for refresh token credentials creation");
return nullptr;
}
- c = static_cast<grpc_google_refresh_token_credentials*>(
- gpr_zalloc(sizeof(grpc_google_refresh_token_credentials)));
- init_oauth2_token_fetcher(&c->base, refresh_token_fetch_oauth2);
- c->base.base.vtable = &refresh_token_vtable;
- c->refresh_token = refresh_token;
- return &c->base.base;
+ return grpc_core::MakeRefCounted<grpc_google_refresh_token_credentials>(
+ refresh_token);
}
static char* create_loggable_refresh_token(grpc_auth_refresh_token* token) {
@@ -478,59 +468,50 @@ grpc_call_credentials* grpc_google_refresh_token_credentials_create(
gpr_free(loggable_token);
}
GPR_ASSERT(reserved == nullptr);
- return grpc_refresh_token_credentials_create_from_auth_refresh_token(token);
+ return grpc_refresh_token_credentials_create_from_auth_refresh_token(token)
+ .release();
}
//
// Oauth2 Access Token credentials.
//
-static void access_token_destruct(grpc_call_credentials* creds) {
- grpc_access_token_credentials* c =
- reinterpret_cast<grpc_access_token_credentials*>(creds);
- GRPC_MDELEM_UNREF(c->access_token_md);
+grpc_access_token_credentials::~grpc_access_token_credentials() {
+ GRPC_MDELEM_UNREF(access_token_md_);
}
-static bool access_token_get_request_metadata(
- grpc_call_credentials* creds, grpc_polling_entity* pollent,
- grpc_auth_metadata_context context, grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata, grpc_error** error) {
- grpc_access_token_credentials* c =
- reinterpret_cast<grpc_access_token_credentials*>(creds);
- grpc_credentials_mdelem_array_add(md_array, c->access_token_md);
+bool grpc_access_token_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
+ grpc_error** error) {
+ grpc_credentials_mdelem_array_add(md_array, access_token_md_);
return true;
}
-static void access_token_cancel_get_request_metadata(
- grpc_call_credentials* c, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
+void grpc_access_token_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
GRPC_ERROR_UNREF(error);
}
-static grpc_call_credentials_vtable access_token_vtable = {
- access_token_destruct, access_token_get_request_metadata,
- access_token_cancel_get_request_metadata};
+grpc_access_token_credentials::grpc_access_token_credentials(
+ const char* access_token)
+ : grpc_call_credentials(GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) {
+ char* token_md_value;
+ gpr_asprintf(&token_md_value, "Bearer %s", access_token);
+ grpc_core::ExecCtx exec_ctx;
+ access_token_md_ = grpc_mdelem_from_slices(
+ grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY),
+ grpc_slice_from_copied_string(token_md_value));
+ gpr_free(token_md_value);
+}
grpc_call_credentials* grpc_access_token_credentials_create(
const char* access_token, void* reserved) {
- grpc_access_token_credentials* c =
- static_cast<grpc_access_token_credentials*>(
- gpr_zalloc(sizeof(grpc_access_token_credentials)));
GRPC_API_TRACE(
"grpc_access_token_credentials_create(access_token=<redacted>, "
"reserved=%p)",
1, (reserved));
GPR_ASSERT(reserved == nullptr);
- c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
- c->base.vtable = &access_token_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- char* token_md_value;
- gpr_asprintf(&token_md_value, "Bearer %s", access_token);
- grpc_core::ExecCtx exec_ctx;
- c->access_token_md = grpc_mdelem_from_slices(
- grpc_slice_from_static_string(GRPC_AUTHORIZATION_METADATA_KEY),
- grpc_slice_from_copied_string(token_md_value));
-
- gpr_free(token_md_value);
- return &c->base;
+ return grpc_core::MakeRefCounted<grpc_access_token_credentials>(access_token)
+ .release();
}
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index 12a1d4484f..510a78b484 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -54,46 +54,91 @@ void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token* refresh_token);
// This object is a base for credentials that need to acquire an oauth2 token
// from an http service.
-typedef void (*grpc_fetch_oauth2_func)(grpc_credentials_metadata_request* req,
- grpc_httpcli_context* http_context,
- grpc_polling_entity* pollent,
- grpc_iomgr_cb_func cb,
- grpc_millis deadline);
-
-typedef struct grpc_oauth2_pending_get_request_metadata {
+struct grpc_oauth2_pending_get_request_metadata {
grpc_credentials_mdelem_array* md_array;
grpc_closure* on_request_metadata;
grpc_polling_entity* pollent;
struct grpc_oauth2_pending_get_request_metadata* next;
-} grpc_oauth2_pending_get_request_metadata;
-
-typedef struct {
- grpc_call_credentials base;
- gpr_mu mu;
- grpc_mdelem access_token_md;
- gpr_timespec token_expiration;
- bool token_fetch_pending;
- grpc_oauth2_pending_get_request_metadata* pending_requests;
- grpc_httpcli_context httpcli_context;
- grpc_fetch_oauth2_func fetch_func;
- grpc_polling_entity pollent;
-} grpc_oauth2_token_fetcher_credentials;
+};
+
+class grpc_oauth2_token_fetcher_credentials : public grpc_call_credentials {
+ public:
+ grpc_oauth2_token_fetcher_credentials();
+ ~grpc_oauth2_token_fetcher_credentials() override;
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ void on_http_response(grpc_credentials_metadata_request* r,
+ grpc_error* error);
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ virtual void fetch_oauth2(grpc_credentials_metadata_request* req,
+ grpc_httpcli_context* httpcli_context,
+ grpc_polling_entity* pollent, grpc_iomgr_cb_func cb,
+ grpc_millis deadline) GRPC_ABSTRACT;
+
+ private:
+ gpr_mu mu_;
+ grpc_mdelem access_token_md_ = GRPC_MDNULL;
+ gpr_timespec token_expiration_;
+ bool token_fetch_pending_ = false;
+ grpc_oauth2_pending_get_request_metadata* pending_requests_ = nullptr;
+ grpc_httpcli_context httpcli_context_;
+ grpc_polling_entity pollent_;
+};
// Google refresh token credentials.
-typedef struct {
- grpc_oauth2_token_fetcher_credentials base;
- grpc_auth_refresh_token refresh_token;
-} grpc_google_refresh_token_credentials;
+class grpc_google_refresh_token_credentials final
+ : public grpc_oauth2_token_fetcher_credentials {
+ public:
+ grpc_google_refresh_token_credentials(grpc_auth_refresh_token refresh_token);
+ ~grpc_google_refresh_token_credentials() override;
+
+ const grpc_auth_refresh_token& refresh_token() const {
+ return refresh_token_;
+ }
+
+ protected:
+ void fetch_oauth2(grpc_credentials_metadata_request* req,
+ grpc_httpcli_context* httpcli_context,
+ grpc_polling_entity* pollent, grpc_iomgr_cb_func cb,
+ grpc_millis deadline) override;
+
+ private:
+ grpc_auth_refresh_token refresh_token_;
+};
// Access token credentials.
-typedef struct {
- grpc_call_credentials base;
- grpc_mdelem access_token_md;
-} grpc_access_token_credentials;
+class grpc_access_token_credentials final : public grpc_call_credentials {
+ public:
+ grpc_access_token_credentials(const char* access_token);
+ ~grpc_access_token_credentials() override;
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ private:
+ grpc_mdelem access_token_md_;
+};
// Private constructor for refresh token credentials from an already parsed
// refresh token. Takes ownership of the refresh token.
-grpc_call_credentials*
+grpc_core::RefCountedPtr<grpc_call_credentials>
grpc_refresh_token_credentials_create_from_auth_refresh_token(
grpc_auth_refresh_token token);
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.cc b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
index 4015124298..52982fdb8f 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.cc
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.cc
@@ -35,20 +35,17 @@
grpc_core::TraceFlag grpc_plugin_credentials_trace(false, "plugin_credentials");
-static void plugin_destruct(grpc_call_credentials* creds) {
- grpc_plugin_credentials* c =
- reinterpret_cast<grpc_plugin_credentials*>(creds);
- gpr_mu_destroy(&c->mu);
- if (c->plugin.state != nullptr && c->plugin.destroy != nullptr) {
- c->plugin.destroy(c->plugin.state);
+grpc_plugin_credentials::~grpc_plugin_credentials() {
+ gpr_mu_destroy(&mu_);
+ if (plugin_.state != nullptr && plugin_.destroy != nullptr) {
+ plugin_.destroy(plugin_.state);
}
}
-static void pending_request_remove_locked(
- grpc_plugin_credentials* c,
- grpc_plugin_credentials_pending_request* pending_request) {
+void grpc_plugin_credentials::pending_request_remove_locked(
+ pending_request* pending_request) {
if (pending_request->prev == nullptr) {
- c->pending_requests = pending_request->next;
+ pending_requests_ = pending_request->next;
} else {
pending_request->prev->next = pending_request->next;
}
@@ -62,17 +59,17 @@ static void pending_request_remove_locked(
// cancelled out from under us.
// When this returns, r->cancelled indicates whether the request was
// cancelled before completion.
-static void pending_request_complete(
- grpc_plugin_credentials_pending_request* r) {
- gpr_mu_lock(&r->creds->mu);
- if (!r->cancelled) pending_request_remove_locked(r->creds, r);
- gpr_mu_unlock(&r->creds->mu);
+void grpc_plugin_credentials::pending_request_complete(pending_request* r) {
+ GPR_DEBUG_ASSERT(r->creds == this);
+ gpr_mu_lock(&mu_);
+ if (!r->cancelled) pending_request_remove_locked(r);
+ gpr_mu_unlock(&mu_);
// Ref to credentials not needed anymore.
- grpc_call_credentials_unref(&r->creds->base);
+ Unref();
}
static grpc_error* process_plugin_result(
- grpc_plugin_credentials_pending_request* r, const grpc_metadata* md,
+ grpc_plugin_credentials::pending_request* r, const grpc_metadata* md,
size_t num_md, grpc_status_code status, const char* error_details) {
grpc_error* error = GRPC_ERROR_NONE;
if (status != GRPC_STATUS_OK) {
@@ -119,8 +116,8 @@ static void plugin_md_request_metadata_ready(void* request,
/* called from application code */
grpc_core::ExecCtx exec_ctx(GRPC_EXEC_CTX_FLAG_IS_FINISHED |
GRPC_EXEC_CTX_FLAG_THREAD_RESOURCE_LOOP);
- grpc_plugin_credentials_pending_request* r =
- static_cast<grpc_plugin_credentials_pending_request*>(request);
+ grpc_plugin_credentials::pending_request* r =
+ static_cast<grpc_plugin_credentials::pending_request*>(request);
if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin returned "
@@ -128,7 +125,7 @@ static void plugin_md_request_metadata_ready(void* request,
r->creds, r);
}
// Remove request from pending list if not previously cancelled.
- pending_request_complete(r);
+ r->creds->pending_request_complete(r);
// If it has not been cancelled, process it.
if (!r->cancelled) {
grpc_error* error =
@@ -143,65 +140,59 @@ static void plugin_md_request_metadata_ready(void* request,
gpr_free(r);
}
-static bool plugin_get_request_metadata(grpc_call_credentials* creds,
- grpc_polling_entity* pollent,
- grpc_auth_metadata_context context,
- grpc_credentials_mdelem_array* md_array,
- grpc_closure* on_request_metadata,
- grpc_error** error) {
- grpc_plugin_credentials* c =
- reinterpret_cast<grpc_plugin_credentials*>(creds);
+bool grpc_plugin_credentials::get_request_metadata(
+ grpc_polling_entity* pollent, grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array, grpc_closure* on_request_metadata,
+ grpc_error** error) {
bool retval = true; // Synchronous return.
- if (c->plugin.get_metadata != nullptr) {
+ if (plugin_.get_metadata != nullptr) {
// Create pending_request object.
- grpc_plugin_credentials_pending_request* pending_request =
- static_cast<grpc_plugin_credentials_pending_request*>(
- gpr_zalloc(sizeof(*pending_request)));
- pending_request->creds = c;
- pending_request->md_array = md_array;
- pending_request->on_request_metadata = on_request_metadata;
+ pending_request* request =
+ static_cast<pending_request*>(gpr_zalloc(sizeof(*request)));
+ request->creds = this;
+ request->md_array = md_array;
+ request->on_request_metadata = on_request_metadata;
// Add it to the pending list.
- gpr_mu_lock(&c->mu);
- if (c->pending_requests != nullptr) {
- c->pending_requests->prev = pending_request;
+ gpr_mu_lock(&mu_);
+ if (pending_requests_ != nullptr) {
+ pending_requests_->prev = request;
}
- pending_request->next = c->pending_requests;
- c->pending_requests = pending_request;
- gpr_mu_unlock(&c->mu);
+ request->next = pending_requests_;
+ pending_requests_ = request;
+ gpr_mu_unlock(&mu_);
// Invoke the plugin. The callback holds a ref to us.
if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO, "plugin_credentials[%p]: request %p: invoking plugin",
- c, pending_request);
+ this, request);
}
- grpc_call_credentials_ref(creds);
+ Ref().release();
grpc_metadata creds_md[GRPC_METADATA_CREDENTIALS_PLUGIN_SYNC_MAX];
size_t num_creds_md = 0;
grpc_status_code status = GRPC_STATUS_OK;
const char* error_details = nullptr;
- if (!c->plugin.get_metadata(c->plugin.state, context,
- plugin_md_request_metadata_ready,
- pending_request, creds_md, &num_creds_md,
- &status, &error_details)) {
+ if (!plugin_.get_metadata(
+ plugin_.state, context, plugin_md_request_metadata_ready, request,
+ creds_md, &num_creds_md, &status, &error_details)) {
if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin will return "
"asynchronously",
- c, pending_request);
+ this, request);
}
return false; // Asynchronous return.
}
// Returned synchronously.
// Remove request from pending list if not previously cancelled.
- pending_request_complete(pending_request);
+ request->creds->pending_request_complete(request);
// If the request was cancelled, the error will have been returned
// asynchronously by plugin_cancel_get_request_metadata(), so return
// false. Otherwise, process the result.
- if (pending_request->cancelled) {
+ if (request->cancelled) {
if (grpc_plugin_credentials_trace.enabled()) {
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p was cancelled, error "
"will be returned asynchronously",
- c, pending_request);
+ this, request);
}
retval = false;
} else {
@@ -209,10 +200,10 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds,
gpr_log(GPR_INFO,
"plugin_credentials[%p]: request %p: plugin returned "
"synchronously",
- c, pending_request);
+ this, request);
}
- *error = process_plugin_result(pending_request, creds_md, num_creds_md,
- status, error_details);
+ *error = process_plugin_result(request, creds_md, num_creds_md, status,
+ error_details);
}
// Clean up.
for (size_t i = 0; i < num_creds_md; ++i) {
@@ -220,51 +211,42 @@ static bool plugin_get_request_metadata(grpc_call_credentials* creds,
grpc_slice_unref_internal(creds_md[i].value);
}
gpr_free((void*)error_details);
- gpr_free(pending_request);
+ gpr_free(request);
}
return retval;
}
-static void plugin_cancel_get_request_metadata(
- grpc_call_credentials* creds, grpc_credentials_mdelem_array* md_array,
- grpc_error* error) {
- grpc_plugin_credentials* c =
- reinterpret_cast<grpc_plugin_credentials*>(creds);
- gpr_mu_lock(&c->mu);
- for (grpc_plugin_credentials_pending_request* pending_request =
- c->pending_requests;
+void grpc_plugin_credentials::cancel_get_request_metadata(
+ grpc_credentials_mdelem_array* md_array, grpc_error* error) {
+ gpr_mu_lock(&mu_);
+ for (pending_request* pending_request = pending_requests_;
pending_request != nullptr; pending_request = pending_request->next) {
if (pending_request->md_array == md_array) {
if (grpc_plugin_credentials_trace.enabled()) {
- gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", c,
+ gpr_log(GPR_INFO, "plugin_credentials[%p]: cancelling request %p", this,
pending_request);
}
pending_request->cancelled = true;
GRPC_CLOSURE_SCHED(pending_request->on_request_metadata,
GRPC_ERROR_REF(error));
- pending_request_remove_locked(c, pending_request);
+ pending_request_remove_locked(pending_request);
break;
}
}
- gpr_mu_unlock(&c->mu);
+ gpr_mu_unlock(&mu_);
GRPC_ERROR_UNREF(error);
}
-static grpc_call_credentials_vtable plugin_vtable = {
- plugin_destruct, plugin_get_request_metadata,
- plugin_cancel_get_request_metadata};
+grpc_plugin_credentials::grpc_plugin_credentials(
+ grpc_metadata_credentials_plugin plugin)
+ : grpc_call_credentials(plugin.type), plugin_(plugin) {
+ gpr_mu_init(&mu_);
+}
grpc_call_credentials* grpc_metadata_credentials_create_from_plugin(
grpc_metadata_credentials_plugin plugin, void* reserved) {
- grpc_plugin_credentials* c =
- static_cast<grpc_plugin_credentials*>(gpr_zalloc(sizeof(*c)));
GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1,
(reserved));
GPR_ASSERT(reserved == nullptr);
- c->base.type = plugin.type;
- c->base.vtable = &plugin_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- c->plugin = plugin;
- gpr_mu_init(&c->mu);
- return &c->base;
+ return grpc_core::New<grpc_plugin_credentials>(plugin);
}
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.h b/src/core/lib/security/credentials/plugin/plugin_credentials.h
index caf990efa1..77a957e513 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.h
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.h
@@ -25,22 +25,45 @@
extern grpc_core::TraceFlag grpc_plugin_credentials_trace;
-struct grpc_plugin_credentials;
-
-typedef struct grpc_plugin_credentials_pending_request {
- bool cancelled;
- struct grpc_plugin_credentials* creds;
- grpc_credentials_mdelem_array* md_array;
- grpc_closure* on_request_metadata;
- struct grpc_plugin_credentials_pending_request* prev;
- struct grpc_plugin_credentials_pending_request* next;
-} grpc_plugin_credentials_pending_request;
-
-typedef struct grpc_plugin_credentials {
- grpc_call_credentials base;
- grpc_metadata_credentials_plugin plugin;
- gpr_mu mu;
- grpc_plugin_credentials_pending_request* pending_requests;
-} grpc_plugin_credentials;
+// This type is forward declared as a C struct and we cannot define it as a
+// class. Otherwise, compiler will complain about type mismatch due to
+// -Wmismatched-tags.
+struct grpc_plugin_credentials final : public grpc_call_credentials {
+ public:
+ struct pending_request {
+ bool cancelled;
+ struct grpc_plugin_credentials* creds;
+ grpc_credentials_mdelem_array* md_array;
+ grpc_closure* on_request_metadata;
+ struct pending_request* prev;
+ struct pending_request* next;
+ };
+
+ explicit grpc_plugin_credentials(grpc_metadata_credentials_plugin plugin);
+ ~grpc_plugin_credentials() override;
+
+ bool get_request_metadata(grpc_polling_entity* pollent,
+ grpc_auth_metadata_context context,
+ grpc_credentials_mdelem_array* md_array,
+ grpc_closure* on_request_metadata,
+ grpc_error** error) override;
+
+ void cancel_get_request_metadata(grpc_credentials_mdelem_array* md_array,
+ grpc_error* error) override;
+
+ // Checks if the request has been cancelled.
+ // If not, removes it from the pending list, so that it cannot be
+ // cancelled out from under us.
+ // When this returns, r->cancelled indicates whether the request was
+ // cancelled before completion.
+ void pending_request_complete(pending_request* r);
+
+ private:
+ void pending_request_remove_locked(pending_request* pending_request);
+
+ grpc_metadata_credentials_plugin plugin_;
+ gpr_mu mu_;
+ pending_request* pending_requests_ = nullptr;
+};
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_PLUGIN_PLUGIN_CREDENTIALS_H */
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.cc b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
index 3d6f2f200a..83db86f1ea 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.cc
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.cc
@@ -44,22 +44,27 @@ void grpc_tsi_ssl_pem_key_cert_pairs_destroy(tsi_ssl_pem_key_cert_pair* kp,
gpr_free(kp);
}
-static void ssl_destruct(grpc_channel_credentials* creds) {
- grpc_ssl_credentials* c = reinterpret_cast<grpc_ssl_credentials*>(creds);
- gpr_free(c->config.pem_root_certs);
- grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pair, 1);
- if (c->config.verify_options.verify_peer_destruct != nullptr) {
- c->config.verify_options.verify_peer_destruct(
- c->config.verify_options.verify_peer_callback_userdata);
+grpc_ssl_credentials::grpc_ssl_credentials(
+ const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
+ const verify_peer_options* verify_options)
+ : grpc_channel_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) {
+ build_config(pem_root_certs, pem_key_cert_pair, verify_options);
+}
+
+grpc_ssl_credentials::~grpc_ssl_credentials() {
+ gpr_free(config_.pem_root_certs);
+ grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pair, 1);
+ if (config_.verify_options.verify_peer_destruct != nullptr) {
+ config_.verify_options.verify_peer_destruct(
+ config_.verify_options.verify_peer_callback_userdata);
}
}
-static grpc_security_status ssl_create_security_connector(
- grpc_channel_credentials* creds, grpc_call_credentials* call_creds,
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_ssl_credentials::create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
- grpc_ssl_credentials* c = reinterpret_cast<grpc_ssl_credentials*>(creds);
- grpc_security_status status = GRPC_SECURITY_OK;
+ grpc_channel_args** new_args) {
const char* overridden_target_name = nullptr;
tsi_ssl_session_cache* ssl_session_cache = nullptr;
for (size_t i = 0; args && i < args->num_args; i++) {
@@ -74,52 +79,47 @@ static grpc_security_status ssl_create_security_connector(
static_cast<tsi_ssl_session_cache*>(arg->value.pointer.p);
}
}
- status = grpc_ssl_channel_security_connector_create(
- creds, call_creds, &c->config, target, overridden_target_name,
- ssl_session_cache, sc);
- if (status != GRPC_SECURITY_OK) {
- return status;
+ grpc_core::RefCountedPtr<grpc_channel_security_connector> sc =
+ grpc_ssl_channel_security_connector_create(
+ this->Ref(), std::move(call_creds), &config_, target,
+ overridden_target_name, ssl_session_cache);
+ if (sc == nullptr) {
+ return sc;
}
grpc_arg new_arg = grpc_channel_arg_string_create(
(char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https");
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1);
- return status;
+ return sc;
}
-static grpc_channel_credentials_vtable ssl_vtable = {
- ssl_destruct, ssl_create_security_connector, nullptr};
-
-static void ssl_build_config(const char* pem_root_certs,
- grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
- const verify_peer_options* verify_options,
- grpc_ssl_config* config) {
- if (pem_root_certs != nullptr) {
- config->pem_root_certs = gpr_strdup(pem_root_certs);
- }
+void grpc_ssl_credentials::build_config(
+ const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
+ const verify_peer_options* verify_options) {
+ config_.pem_root_certs = gpr_strdup(pem_root_certs);
if (pem_key_cert_pair != nullptr) {
GPR_ASSERT(pem_key_cert_pair->private_key != nullptr);
GPR_ASSERT(pem_key_cert_pair->cert_chain != nullptr);
- config->pem_key_cert_pair = static_cast<tsi_ssl_pem_key_cert_pair*>(
+ config_.pem_key_cert_pair = static_cast<tsi_ssl_pem_key_cert_pair*>(
gpr_zalloc(sizeof(tsi_ssl_pem_key_cert_pair)));
- config->pem_key_cert_pair->cert_chain =
+ config_.pem_key_cert_pair->cert_chain =
gpr_strdup(pem_key_cert_pair->cert_chain);
- config->pem_key_cert_pair->private_key =
+ config_.pem_key_cert_pair->private_key =
gpr_strdup(pem_key_cert_pair->private_key);
+ } else {
+ config_.pem_key_cert_pair = nullptr;
}
if (verify_options != nullptr) {
- memcpy(&config->verify_options, verify_options,
+ memcpy(&config_.verify_options, verify_options,
sizeof(verify_peer_options));
} else {
// Otherwise set all options to default values
- memset(&config->verify_options, 0, sizeof(verify_peer_options));
+ memset(&config_.verify_options, 0, sizeof(verify_peer_options));
}
}
grpc_channel_credentials* grpc_ssl_credentials_create(
const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
const verify_peer_options* verify_options, void* reserved) {
- grpc_ssl_credentials* c = static_cast<grpc_ssl_credentials*>(
- gpr_zalloc(sizeof(grpc_ssl_credentials)));
GRPC_API_TRACE(
"grpc_ssl_credentials_create(pem_root_certs=%s, "
"pem_key_cert_pair=%p, "
@@ -127,12 +127,9 @@ grpc_channel_credentials* grpc_ssl_credentials_create(
"reserved=%p)",
4, (pem_root_certs, pem_key_cert_pair, verify_options, reserved));
GPR_ASSERT(reserved == nullptr);
- c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
- c->base.vtable = &ssl_vtable;
- gpr_ref_init(&c->base.refcount, 1);
- ssl_build_config(pem_root_certs, pem_key_cert_pair, verify_options,
- &c->config);
- return &c->base;
+
+ return grpc_core::New<grpc_ssl_credentials>(pem_root_certs, pem_key_cert_pair,
+ verify_options);
}
//
@@ -145,21 +142,29 @@ struct grpc_ssl_server_credentials_options {
grpc_ssl_server_certificate_config_fetcher* certificate_config_fetcher;
};
-static void ssl_server_destruct(grpc_server_credentials* creds) {
- grpc_ssl_server_credentials* c =
- reinterpret_cast<grpc_ssl_server_credentials*>(creds);
- grpc_tsi_ssl_pem_key_cert_pairs_destroy(c->config.pem_key_cert_pairs,
- c->config.num_key_cert_pairs);
- gpr_free(c->config.pem_root_certs);
+grpc_ssl_server_credentials::grpc_ssl_server_credentials(
+ const grpc_ssl_server_credentials_options& options)
+ : grpc_server_credentials(GRPC_CHANNEL_CREDENTIALS_TYPE_SSL) {
+ if (options.certificate_config_fetcher != nullptr) {
+ config_.client_certificate_request = options.client_certificate_request;
+ certificate_config_fetcher_ = *options.certificate_config_fetcher;
+ } else {
+ build_config(options.certificate_config->pem_root_certs,
+ options.certificate_config->pem_key_cert_pairs,
+ options.certificate_config->num_key_cert_pairs,
+ options.client_certificate_request);
+ }
}
-static grpc_security_status ssl_server_create_security_connector(
- grpc_server_credentials* creds, grpc_server_security_connector** sc) {
- return grpc_ssl_server_security_connector_create(creds, sc);
+grpc_ssl_server_credentials::~grpc_ssl_server_credentials() {
+ grpc_tsi_ssl_pem_key_cert_pairs_destroy(config_.pem_key_cert_pairs,
+ config_.num_key_cert_pairs);
+ gpr_free(config_.pem_root_certs);
+}
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_ssl_server_credentials::create_security_connector() {
+ return grpc_ssl_server_security_connector_create(this->Ref());
}
-
-static grpc_server_credentials_vtable ssl_server_vtable = {
- ssl_server_destruct, ssl_server_create_security_connector};
tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs(
const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,
@@ -179,18 +184,15 @@ tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs(
return tsi_pairs;
}
-static void ssl_build_server_config(
+void grpc_ssl_server_credentials::build_config(
const char* pem_root_certs, grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,
size_t num_key_cert_pairs,
- grpc_ssl_client_certificate_request_type client_certificate_request,
- grpc_ssl_server_config* config) {
- config->client_certificate_request = client_certificate_request;
- if (pem_root_certs != nullptr) {
- config->pem_root_certs = gpr_strdup(pem_root_certs);
- }
- config->pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
+ grpc_ssl_client_certificate_request_type client_certificate_request) {
+ config_.client_certificate_request = client_certificate_request;
+ config_.pem_root_certs = gpr_strdup(pem_root_certs);
+ config_.pem_key_cert_pairs = grpc_convert_grpc_to_tsi_cert_pairs(
pem_key_cert_pairs, num_key_cert_pairs);
- config->num_key_cert_pairs = num_key_cert_pairs;
+ config_.num_key_cert_pairs = num_key_cert_pairs;
}
grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create(
@@ -200,9 +202,7 @@ grpc_ssl_server_certificate_config* grpc_ssl_server_certificate_config_create(
grpc_ssl_server_certificate_config* config =
static_cast<grpc_ssl_server_certificate_config*>(
gpr_zalloc(sizeof(grpc_ssl_server_certificate_config)));
- if (pem_root_certs != nullptr) {
- config->pem_root_certs = gpr_strdup(pem_root_certs);
- }
+ config->pem_root_certs = gpr_strdup(pem_root_certs);
if (num_key_cert_pairs > 0) {
GPR_ASSERT(pem_key_cert_pairs != nullptr);
config->pem_key_cert_pairs = static_cast<grpc_ssl_pem_key_cert_pair*>(
@@ -311,7 +311,6 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_ex(
grpc_server_credentials* grpc_ssl_server_credentials_create_with_options(
grpc_ssl_server_credentials_options* options) {
grpc_server_credentials* retval = nullptr;
- grpc_ssl_server_credentials* c = nullptr;
if (options == nullptr) {
gpr_log(GPR_ERROR,
@@ -331,23 +330,7 @@ grpc_server_credentials* grpc_ssl_server_credentials_create_with_options(
goto done;
}
- c = static_cast<grpc_ssl_server_credentials*>(
- gpr_zalloc(sizeof(grpc_ssl_server_credentials)));
- c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
- gpr_ref_init(&c->base.refcount, 1);
- c->base.vtable = &ssl_server_vtable;
-
- if (options->certificate_config_fetcher != nullptr) {
- c->config.client_certificate_request = options->client_certificate_request;
- c->certificate_config_fetcher = *options->certificate_config_fetcher;
- } else {
- ssl_build_server_config(options->certificate_config->pem_root_certs,
- options->certificate_config->pem_key_cert_pairs,
- options->certificate_config->num_key_cert_pairs,
- options->client_certificate_request, &c->config);
- }
-
- retval = &c->base;
+ retval = grpc_core::New<grpc_ssl_server_credentials>(*options);
done:
grpc_ssl_server_credentials_options_destroy(options);
diff --git a/src/core/lib/security/credentials/ssl/ssl_credentials.h b/src/core/lib/security/credentials/ssl/ssl_credentials.h
index 0fba413876..e1174327b3 100644
--- a/src/core/lib/security/credentials/ssl/ssl_credentials.h
+++ b/src/core/lib/security/credentials/ssl/ssl_credentials.h
@@ -24,27 +24,70 @@
#include "src/core/lib/security/security_connector/ssl/ssl_security_connector.h"
-typedef struct {
- grpc_channel_credentials base;
- grpc_ssl_config config;
-} grpc_ssl_credentials;
+class grpc_ssl_credentials : public grpc_channel_credentials {
+ public:
+ grpc_ssl_credentials(const char* pem_root_certs,
+ grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
+ const verify_peer_options* verify_options);
+
+ ~grpc_ssl_credentials() override;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override;
+
+ private:
+ void build_config(const char* pem_root_certs,
+ grpc_ssl_pem_key_cert_pair* pem_key_cert_pair,
+ const verify_peer_options* verify_options);
+
+ grpc_ssl_config config_;
+};
struct grpc_ssl_server_certificate_config {
- grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs;
- size_t num_key_cert_pairs;
- char* pem_root_certs;
+ grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr;
+ size_t num_key_cert_pairs = 0;
+ char* pem_root_certs = nullptr;
};
-typedef struct {
- grpc_ssl_server_certificate_config_callback cb;
+struct grpc_ssl_server_certificate_config_fetcher {
+ grpc_ssl_server_certificate_config_callback cb = nullptr;
void* user_data;
-} grpc_ssl_server_certificate_config_fetcher;
+};
+
+class grpc_ssl_server_credentials final : public grpc_server_credentials {
+ public:
+ grpc_ssl_server_credentials(
+ const grpc_ssl_server_credentials_options& options);
+ ~grpc_ssl_server_credentials() override;
-typedef struct {
- grpc_server_credentials base;
- grpc_ssl_server_config config;
- grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher;
-} grpc_ssl_server_credentials;
+ grpc_core::RefCountedPtr<grpc_server_security_connector>
+ create_security_connector() override;
+
+ bool has_cert_config_fetcher() const {
+ return certificate_config_fetcher_.cb != nullptr;
+ }
+
+ grpc_ssl_certificate_config_reload_status FetchCertConfig(
+ grpc_ssl_server_certificate_config** config) {
+ GPR_DEBUG_ASSERT(has_cert_config_fetcher());
+ return certificate_config_fetcher_.cb(certificate_config_fetcher_.user_data,
+ config);
+ }
+
+ const grpc_ssl_server_config& config() const { return config_; }
+
+ private:
+ void build_config(
+ const char* pem_root_certs,
+ grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs, size_t num_key_cert_pairs,
+ grpc_ssl_client_certificate_request_type client_certificate_request);
+
+ grpc_ssl_server_config config_;
+ grpc_ssl_server_certificate_config_fetcher certificate_config_fetcher_;
+};
tsi_ssl_pem_key_cert_pair* grpc_convert_grpc_to_tsi_cert_pairs(
const grpc_ssl_pem_key_cert_pair* pem_key_cert_pairs,
diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.cc b/src/core/lib/security/security_connector/alts/alts_security_connector.cc
index dd71c8bc60..3ad0cc353c 100644
--- a/src/core/lib/security/security_connector/alts/alts_security_connector.cc
+++ b/src/core/lib/security/security_connector/alts/alts_security_connector.cc
@@ -28,6 +28,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/credentials/alts/alts_credentials.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -35,64 +36,9 @@
#include "src/core/tsi/alts/handshaker/alts_tsi_handshaker.h"
#include "src/core/tsi/transport_security.h"
-typedef struct {
- grpc_channel_security_connector base;
- char* target_name;
-} grpc_alts_channel_security_connector;
+namespace {
-typedef struct {
- grpc_server_security_connector base;
-} grpc_alts_server_security_connector;
-
-static void alts_channel_destroy(grpc_security_connector* sc) {
- if (sc == nullptr) {
- return;
- }
- auto c = reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
- grpc_call_credentials_unref(c->base.request_metadata_creds);
- grpc_channel_credentials_unref(c->base.channel_creds);
- gpr_free(c->target_name);
- gpr_free(sc);
-}
-
-static void alts_server_destroy(grpc_security_connector* sc) {
- if (sc == nullptr) {
- return;
- }
- auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc);
- grpc_server_credentials_unref(c->base.server_creds);
- gpr_free(sc);
-}
-
-static void alts_channel_add_handshakers(
- grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_manager) {
- tsi_handshaker* handshaker = nullptr;
- auto c = reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
- grpc_alts_credentials* creds =
- reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds);
- GPR_ASSERT(alts_tsi_handshaker_create(
- creds->options, c->target_name, creds->handshaker_service_url,
- true, interested_parties, &handshaker) == TSI_OK);
- grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
- handshaker, &sc->base));
-}
-
-static void alts_server_add_handshakers(
- grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_manager) {
- tsi_handshaker* handshaker = nullptr;
- auto c = reinterpret_cast<grpc_alts_server_security_connector*>(sc);
- grpc_alts_server_credentials* creds =
- reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds);
- GPR_ASSERT(alts_tsi_handshaker_create(
- creds->options, nullptr, creds->handshaker_service_url, false,
- interested_parties, &handshaker) == TSI_OK);
- grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
- handshaker, &sc->base));
-}
-
-static void alts_set_rpc_protocol_versions(
+void alts_set_rpc_protocol_versions(
grpc_gcp_rpc_protocol_versions* rpc_versions) {
grpc_gcp_rpc_protocol_versions_set_max(rpc_versions,
GRPC_PROTOCOL_VERSION_MAX_MAJOR,
@@ -102,17 +48,131 @@ static void alts_set_rpc_protocol_versions(
GRPC_PROTOCOL_VERSION_MIN_MINOR);
}
+void alts_check_peer(tsi_peer peer,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) {
+ *auth_context =
+ grpc_core::internal::grpc_alts_auth_context_from_tsi_peer(&peer);
+ tsi_peer_destruct(&peer);
+ grpc_error* error =
+ *auth_context != nullptr
+ ? GRPC_ERROR_NONE
+ : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Could not get ALTS auth context from TSI peer");
+ GRPC_CLOSURE_SCHED(on_peer_checked, error);
+}
+
+class grpc_alts_channel_security_connector final
+ : public grpc_channel_security_connector {
+ public:
+ grpc_alts_channel_security_connector(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target_name)
+ : grpc_channel_security_connector(/*url_scheme=*/nullptr,
+ std::move(channel_creds),
+ std::move(request_metadata_creds)),
+ target_name_(gpr_strdup(target_name)) {
+ grpc_alts_credentials* creds =
+ static_cast<grpc_alts_credentials*>(mutable_channel_creds());
+ alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions);
+ }
+
+ ~grpc_alts_channel_security_connector() override { gpr_free(target_name_); }
+
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_manager) override {
+ tsi_handshaker* handshaker = nullptr;
+ const grpc_alts_credentials* creds =
+ static_cast<const grpc_alts_credentials*>(channel_creds());
+ GPR_ASSERT(alts_tsi_handshaker_create(creds->options(), target_name_,
+ creds->handshaker_service_url(), true,
+ interested_parties,
+ &handshaker) == TSI_OK);
+ grpc_handshake_manager_add(
+ handshake_manager, grpc_security_handshaker_create(handshaker, this));
+ }
+
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ alts_check_peer(peer, auth_context, on_peer_checked);
+ }
+
+ int cmp(const grpc_security_connector* other_sc) const override {
+ auto* other =
+ reinterpret_cast<const grpc_alts_channel_security_connector*>(other_sc);
+ int c = channel_security_connector_cmp(other);
+ if (c != 0) return c;
+ return strcmp(target_name_, other->target_name_);
+ }
+
+ bool check_call_host(const char* host, grpc_auth_context* auth_context,
+ grpc_closure* on_call_host_checked,
+ grpc_error** error) override {
+ if (host == nullptr || strcmp(host, target_name_) != 0) {
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "ALTS call host does not match target name");
+ }
+ return true;
+ }
+
+ void cancel_check_call_host(grpc_closure* on_call_host_checked,
+ grpc_error* error) override {
+ GRPC_ERROR_UNREF(error);
+ }
+
+ private:
+ char* target_name_;
+};
+
+class grpc_alts_server_security_connector final
+ : public grpc_server_security_connector {
+ public:
+ grpc_alts_server_security_connector(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
+ : grpc_server_security_connector(/*url_scheme=*/nullptr,
+ std::move(server_creds)) {
+ grpc_alts_server_credentials* creds =
+ reinterpret_cast<grpc_alts_server_credentials*>(mutable_server_creds());
+ alts_set_rpc_protocol_versions(&creds->mutable_options()->rpc_versions);
+ }
+ ~grpc_alts_server_security_connector() override = default;
+
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_manager) override {
+ tsi_handshaker* handshaker = nullptr;
+ const grpc_alts_server_credentials* creds =
+ static_cast<const grpc_alts_server_credentials*>(server_creds());
+ GPR_ASSERT(alts_tsi_handshaker_create(
+ creds->options(), nullptr, creds->handshaker_service_url(),
+ false, interested_parties, &handshaker) == TSI_OK);
+ grpc_handshake_manager_add(
+ handshake_manager, grpc_security_handshaker_create(handshaker, this));
+ }
+
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ alts_check_peer(peer, auth_context, on_peer_checked);
+ }
+
+ int cmp(const grpc_security_connector* other) const override {
+ return server_security_connector_cmp(
+ static_cast<const grpc_server_security_connector*>(other));
+ }
+};
+} // namespace
+
namespace grpc_core {
namespace internal {
-
-grpc_security_status grpc_alts_auth_context_from_tsi_peer(
- const tsi_peer* peer, grpc_auth_context** ctx) {
- if (peer == nullptr || ctx == nullptr) {
+grpc_core::RefCountedPtr<grpc_auth_context>
+grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer) {
+ if (peer == nullptr) {
gpr_log(GPR_ERROR,
"Invalid arguments to grpc_alts_auth_context_from_tsi_peer()");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- *ctx = nullptr;
/* Validate certificate type. */
const tsi_peer_property* cert_type_prop =
tsi_peer_get_property_by_name(peer, TSI_CERTIFICATE_TYPE_PEER_PROPERTY);
@@ -120,14 +180,14 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer(
strncmp(cert_type_prop->value.data, TSI_ALTS_CERTIFICATE_TYPE,
cert_type_prop->value.length) != 0) {
gpr_log(GPR_ERROR, "Invalid or missing certificate type property.");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
/* Validate RPC protocol versions. */
const tsi_peer_property* rpc_versions_prop =
tsi_peer_get_property_by_name(peer, TSI_ALTS_RPC_VERSIONS);
if (rpc_versions_prop == nullptr) {
gpr_log(GPR_ERROR, "Missing rpc protocol versions property.");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
grpc_gcp_rpc_protocol_versions local_versions, peer_versions;
alts_set_rpc_protocol_versions(&local_versions);
@@ -138,19 +198,19 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer(
grpc_slice_unref_internal(slice);
if (!decode_result) {
gpr_log(GPR_ERROR, "Invalid peer rpc protocol versions.");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
/* TODO: Pass highest common rpc protocol version to grpc caller. */
bool check_result = grpc_gcp_rpc_protocol_versions_check(
&local_versions, &peer_versions, nullptr);
if (!check_result) {
gpr_log(GPR_ERROR, "Mismatch of local and peer rpc protocol versions.");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
/* Create auth context. */
- *ctx = grpc_auth_context_create(nullptr);
+ auto ctx = grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_context_add_cstring_property(
- *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+ ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_ALTS_TRANSPORT_SECURITY_TYPE);
size_t i = 0;
for (i = 0; i < peer->property_count; i++) {
@@ -158,132 +218,47 @@ grpc_security_status grpc_alts_auth_context_from_tsi_peer(
/* Add service account to auth context. */
if (strcmp(tsi_prop->name, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 0) {
grpc_auth_context_add_property(
- *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, tsi_prop->value.data,
- tsi_prop->value.length);
+ ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY,
+ tsi_prop->value.data, tsi_prop->value.length);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
- *ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1);
+ ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY) == 1);
}
}
- if (!grpc_auth_context_peer_is_authenticated(*ctx)) {
+ if (!grpc_auth_context_peer_is_authenticated(ctx.get())) {
gpr_log(GPR_ERROR, "Invalid unauthenticated peer.");
- GRPC_AUTH_CONTEXT_UNREF(*ctx, "test");
- *ctx = nullptr;
- return GRPC_SECURITY_ERROR;
+ ctx.reset(DEBUG_LOCATION, "test");
+ return nullptr;
}
- return GRPC_SECURITY_OK;
+ return ctx;
}
} // namespace internal
} // namespace grpc_core
-static void alts_check_peer(grpc_security_connector* sc, tsi_peer peer,
- grpc_auth_context** auth_context,
- grpc_closure* on_peer_checked) {
- grpc_security_status status;
- status = grpc_core::internal::grpc_alts_auth_context_from_tsi_peer(
- &peer, auth_context);
- tsi_peer_destruct(&peer);
- grpc_error* error =
- status == GRPC_SECURITY_OK
- ? GRPC_ERROR_NONE
- : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Could not get ALTS auth context from TSI peer");
- GRPC_CLOSURE_SCHED(on_peer_checked, error);
-}
-
-static int alts_channel_cmp(grpc_security_connector* sc1,
- grpc_security_connector* sc2) {
- grpc_alts_channel_security_connector* c1 =
- reinterpret_cast<grpc_alts_channel_security_connector*>(sc1);
- grpc_alts_channel_security_connector* c2 =
- reinterpret_cast<grpc_alts_channel_security_connector*>(sc2);
- int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
- if (c != 0) return c;
- return strcmp(c1->target_name, c2->target_name);
-}
-
-static int alts_server_cmp(grpc_security_connector* sc1,
- grpc_security_connector* sc2) {
- grpc_alts_server_security_connector* c1 =
- reinterpret_cast<grpc_alts_server_security_connector*>(sc1);
- grpc_alts_server_security_connector* c2 =
- reinterpret_cast<grpc_alts_server_security_connector*>(sc2);
- return grpc_server_security_connector_cmp(&c1->base, &c2->base);
-}
-
-static grpc_security_connector_vtable alts_channel_vtable = {
- alts_channel_destroy, alts_check_peer, alts_channel_cmp};
-
-static grpc_security_connector_vtable alts_server_vtable = {
- alts_server_destroy, alts_check_peer, alts_server_cmp};
-
-static bool alts_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_alts_channel_security_connector* alts_sc =
- reinterpret_cast<grpc_alts_channel_security_connector*>(sc);
- if (host == nullptr || alts_sc == nullptr ||
- strcmp(host, alts_sc->target_name) != 0) {
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "ALTS call host does not match target name");
- }
- return true;
-}
-
-static void alts_cancel_check_call_host(grpc_channel_security_connector* sc,
- grpc_closure* on_call_host_checked,
- grpc_error* error) {
- GRPC_ERROR_UNREF(error);
-}
-
-grpc_security_status grpc_alts_channel_security_connector_create(
- grpc_channel_credentials* channel_creds,
- grpc_call_credentials* request_metadata_creds, const char* target_name,
- grpc_channel_security_connector** sc) {
- if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) {
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_alts_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target_name) {
+ if (channel_creds == nullptr || target_name == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid arguments to grpc_alts_channel_security_connector_create()");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- auto c = static_cast<grpc_alts_channel_security_connector*>(
- gpr_zalloc(sizeof(grpc_alts_channel_security_connector)));
- gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.vtable = &alts_channel_vtable;
- c->base.add_handshakers = alts_channel_add_handshakers;
- 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 = alts_check_call_host;
- c->base.cancel_check_call_host = alts_cancel_check_call_host;
- grpc_alts_credentials* creds =
- reinterpret_cast<grpc_alts_credentials*>(c->base.channel_creds);
- alts_set_rpc_protocol_versions(&creds->options->rpc_versions);
- c->target_name = gpr_strdup(target_name);
- *sc = &c->base;
- return GRPC_SECURITY_OK;
+ return grpc_core::MakeRefCounted<grpc_alts_channel_security_connector>(
+ std::move(channel_creds), std::move(request_metadata_creds), target_name);
}
-grpc_security_status grpc_alts_server_security_connector_create(
- grpc_server_credentials* server_creds,
- grpc_server_security_connector** sc) {
- if (server_creds == nullptr || sc == nullptr) {
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_alts_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) {
+ if (server_creds == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid arguments to grpc_alts_server_security_connector_create()");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- auto c = static_cast<grpc_alts_server_security_connector*>(
- gpr_zalloc(sizeof(grpc_alts_server_security_connector)));
- gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.vtable = &alts_server_vtable;
- c->base.server_creds = grpc_server_credentials_ref(server_creds);
- c->base.add_handshakers = alts_server_add_handshakers;
- grpc_alts_server_credentials* creds =
- reinterpret_cast<grpc_alts_server_credentials*>(c->base.server_creds);
- alts_set_rpc_protocol_versions(&creds->options->rpc_versions);
- *sc = &c->base;
- return GRPC_SECURITY_OK;
+ return grpc_core::MakeRefCounted<grpc_alts_server_security_connector>(
+ std::move(server_creds));
}
diff --git a/src/core/lib/security/security_connector/alts/alts_security_connector.h b/src/core/lib/security/security_connector/alts/alts_security_connector.h
index d2e057a76a..b96dc36b30 100644
--- a/src/core/lib/security/security_connector/alts/alts_security_connector.h
+++ b/src/core/lib/security/security_connector/alts/alts_security_connector.h
@@ -36,12 +36,13 @@
* - sc: address of ALTS channel security connector instance to be returned from
* the method.
*
- * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure.
+ * It returns nullptr on failure.
*/
-grpc_security_status grpc_alts_channel_security_connector_create(
- grpc_channel_credentials* channel_creds,
- grpc_call_credentials* request_metadata_creds, const char* target_name,
- grpc_channel_security_connector** sc);
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_alts_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target_name);
/**
* This method creates an ALTS server security connector.
@@ -50,17 +51,18 @@ grpc_security_status grpc_alts_channel_security_connector_create(
* - sc: address of ALTS server security connector instance to be returned from
* the method.
*
- * It returns GRPC_SECURITY_OK on success, and an error status code on failure.
+ * It returns nullptr on failure.
*/
-grpc_security_status grpc_alts_server_security_connector_create(
- grpc_server_credentials* server_creds, grpc_server_security_connector** sc);
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_alts_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
namespace grpc_core {
namespace internal {
/* Exposed only for testing. */
-grpc_security_status grpc_alts_auth_context_from_tsi_peer(
- const tsi_peer* peer, grpc_auth_context** ctx);
+grpc_core::RefCountedPtr<grpc_auth_context>
+grpc_alts_auth_context_from_tsi_peer(const tsi_peer* peer);
} // namespace internal
} // namespace grpc_core
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
index 5c0c89b88f..e3b8affb36 100644
--- a/src/core/lib/security/security_connector/fake/fake_security_connector.cc
+++ b/src/core/lib/security/security_connector/fake/fake_security_connector.cc
@@ -31,6 +31,7 @@
#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/gprpp/ref_counted_ptr.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"
@@ -38,91 +39,183 @@
#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;
+namespace {
+class grpc_fake_channel_security_connector final
+ : public grpc_channel_security_connector {
+ public:
+ grpc_fake_channel_security_connector(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target, const grpc_channel_args* args)
+ : grpc_channel_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME,
+ std::move(channel_creds),
+ std::move(request_metadata_creds)),
+ target_(gpr_strdup(target)),
+ expected_targets_(
+ gpr_strdup(grpc_fake_transport_get_expected_targets(args))),
+ 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) {
+ target_name_override_ =
+ gpr_strdup(grpc_channel_arg_get_string(target_name_override_arg));
+ } else {
+ target_name_override_ = nullptr;
+ }
+ }
-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);
-}
+ ~grpc_fake_channel_security_connector() override {
+ gpr_free(target_);
+ gpr_free(expected_targets_);
+ if (target_name_override_ != nullptr) gpr_free(target_name_override_);
+ }
-static void fake_server_destroy(grpc_security_connector* sc) { gpr_free(sc); }
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override;
-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;
+ int cmp(const grpc_security_connector* other_sc) const override {
+ auto* other =
+ reinterpret_cast<const grpc_fake_channel_security_connector*>(other_sc);
+ int c = channel_security_connector_cmp(other);
+ if (c != 0) return c;
+ c = strcmp(target_, other->target_);
+ if (c != 0) return c;
+ if (expected_targets_ == nullptr || other->expected_targets_ == nullptr) {
+ c = GPR_ICMP(expected_targets_, other->expected_targets_);
+ } else {
+ c = strcmp(expected_targets_, other->expected_targets_);
+ }
+ if (c != 0) return c;
+ return GPR_ICMP(is_lb_channel_, other->is_lb_channel_);
}
- for (size_t i = 0; i < set_size; ++i) {
- gpr_free(set[i]);
+
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr) override {
+ grpc_handshake_manager_add(
+ handshake_mgr,
+ grpc_security_handshaker_create(
+ tsi_create_fake_handshaker(/*is_client=*/true), this));
}
- 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;
+ bool check_call_host(const char* host, grpc_auth_context* auth_context,
+ grpc_closure* on_call_host_checked,
+ grpc_error** error) override {
+ 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(target_, &target_hostname, &target_ignored_port);
+ if (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(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;
}
- 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;
+
+ void cancel_check_call_host(grpc_closure* on_call_host_checked,
+ grpc_error* error) override {
+ GRPC_ERROR_UNREF(error);
+ }
+
+ char* target() const { return target_; }
+ char* expected_targets() const { return expected_targets_; }
+ bool is_lb_channel() const { return is_lb_channel_; }
+ char* target_name_override() const { return target_name_override_; }
+
+ private:
+ bool fake_check_target(const char* target_type, const char* target,
+ const char* set_str) const {
+ 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;
}
- 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;
+ for (size_t i = 0; i < set_size; ++i) {
+ gpr_free(set[i]);
}
- 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]);
+ gpr_free(set);
+ return found;
+ }
+
+ void fake_secure_name_check() const {
+ 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;
}
- success = true;
- }
-done:
- for (size_t i = 0; i < lbs_and_backends_size; ++i) {
- gpr_free(lbs_and_backends[i]);
+ 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();
}
- 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) {
+ char* target_;
+ char* expected_targets_;
+ bool is_lb_channel_;
+ char* target_name_override_;
+};
+
+static void fake_check_peer(
+ grpc_security_connector* sc, tsi_peer peer,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) {
const char* prop_name;
grpc_error* error = GRPC_ERROR_NONE;
*auth_context = nullptr;
@@ -147,164 +240,66 @@ static void fake_check_peer(grpc_security_connector* sc, tsi_peer peer,
"Invalid value for cert type property.");
goto end;
}
- *auth_context = grpc_auth_context_create(nullptr);
+ *auth_context = grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_context_add_cstring_property(
- *auth_context, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+ auth_context->get(), 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);
+void grpc_fake_channel_security_connector::check_peer(
+ tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) {
+ fake_check_peer(this, peer, auth_context, on_peer_checked);
+ fake_secure_name_check();
}
-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);
-}
+class grpc_fake_server_security_connector
+ : public grpc_server_security_connector {
+ public:
+ grpc_fake_server_security_connector(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
+ : grpc_server_security_connector(GRPC_FAKE_SECURITY_URL_SCHEME,
+ std::move(server_creds)) {}
+ ~grpc_fake_server_security_connector() override = default;
-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);
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ fake_check_peer(this, peer, auth_context, on_peer_checked);
}
- 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();
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr) override {
+ grpc_handshake_manager_add(
+ handshake_mgr,
+ grpc_security_handshaker_create(
+ tsi_create_fake_handshaker(/*=is_client*/ false), this));
}
- 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));
+ int cmp(const grpc_security_connector* other) const override {
+ return server_security_connector_cmp(
+ static_cast<const grpc_server_security_connector*>(other));
}
- return &c->base;
+};
+} // namespace
+
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_fake_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target, const grpc_channel_args* args) {
+ return grpc_core::MakeRefCounted<grpc_fake_channel_security_connector>(
+ std::move(channel_creds), std::move(request_metadata_creds), target,
+ args);
}
-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;
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_fake_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) {
+ return grpc_core::MakeRefCounted<grpc_fake_server_security_connector>(
+ std::move(server_creds));
}
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
index fdfe048c6e..344a2349a4 100644
--- a/src/core/lib/security/security_connector/fake/fake_security_connector.h
+++ b/src/core/lib/security/security_connector/fake/fake_security_connector.h
@@ -24,19 +24,22 @@
#include <grpc/grpc_security.h>
#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.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);
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_fake_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<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);
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_fake_server_security_connector_create(
+ grpc_core::RefCountedPtr<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/local_security_connector.cc b/src/core/lib/security/security_connector/local/local_security_connector.cc
index 008a98df28..7cc482c16c 100644
--- a/src/core/lib/security/security_connector/local/local_security_connector.cc
+++ b/src/core/lib/security/security_connector/local/local_security_connector.cc
@@ -30,217 +30,224 @@
#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
+#include "src/core/lib/iomgr/socket_utils.h"
+#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/security/credentials/local/local_credentials.h"
#include "src/core/lib/security/transport/security_handshaker.h"
#include "src/core/tsi/local_transport_security.h"
#define GRPC_UDS_URI_PATTERN "unix:"
-#define GRPC_UDS_URL_SCHEME "unix"
#define GRPC_LOCAL_TRANSPORT_SECURITY_TYPE "local"
-typedef struct {
- grpc_channel_security_connector base;
- char* target_name;
-} grpc_local_channel_security_connector;
+namespace {
-typedef struct {
- grpc_server_security_connector base;
-} grpc_local_server_security_connector;
-
-static void local_channel_destroy(grpc_security_connector* sc) {
- if (sc == nullptr) {
- return;
- }
- auto c = reinterpret_cast<grpc_local_channel_security_connector*>(sc);
- grpc_call_credentials_unref(c->base.request_metadata_creds);
- grpc_channel_credentials_unref(c->base.channel_creds);
- gpr_free(c->target_name);
- gpr_free(sc);
-}
-
-static void local_server_destroy(grpc_security_connector* sc) {
- if (sc == nullptr) {
- return;
- }
- auto c = reinterpret_cast<grpc_local_server_security_connector*>(sc);
- grpc_server_credentials_unref(c->base.server_creds);
- gpr_free(sc);
-}
-
-static void local_channel_add_handshakers(
- grpc_channel_security_connector* sc, grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_manager) {
- tsi_handshaker* handshaker = nullptr;
- GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) ==
- TSI_OK);
- grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
- handshaker, &sc->base));
-}
-
-static void local_server_add_handshakers(
- grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_manager) {
- tsi_handshaker* handshaker = nullptr;
- GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */, &handshaker) ==
- TSI_OK);
- grpc_handshake_manager_add(handshake_manager, grpc_security_handshaker_create(
- handshaker, &sc->base));
-}
-
-static int local_channel_cmp(grpc_security_connector* sc1,
- grpc_security_connector* sc2) {
- grpc_local_channel_security_connector* c1 =
- reinterpret_cast<grpc_local_channel_security_connector*>(sc1);
- grpc_local_channel_security_connector* c2 =
- reinterpret_cast<grpc_local_channel_security_connector*>(sc2);
- int c = grpc_channel_security_connector_cmp(&c1->base, &c2->base);
- if (c != 0) return c;
- return strcmp(c1->target_name, c2->target_name);
-}
-
-static int local_server_cmp(grpc_security_connector* sc1,
- grpc_security_connector* sc2) {
- grpc_local_server_security_connector* c1 =
- reinterpret_cast<grpc_local_server_security_connector*>(sc1);
- grpc_local_server_security_connector* c2 =
- reinterpret_cast<grpc_local_server_security_connector*>(sc2);
- return grpc_server_security_connector_cmp(&c1->base, &c2->base);
-}
-
-static grpc_security_status local_auth_context_create(grpc_auth_context** ctx) {
- if (ctx == nullptr) {
- gpr_log(GPR_ERROR, "Invalid arguments to local_auth_context_create()");
- return GRPC_SECURITY_ERROR;
- }
+grpc_core::RefCountedPtr<grpc_auth_context> local_auth_context_create() {
/* Create auth context. */
- *ctx = grpc_auth_context_create(nullptr);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_context_add_cstring_property(
- *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+ ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_LOCAL_TRANSPORT_SECURITY_TYPE);
GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(
- *ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1);
- return GRPC_SECURITY_OK;
+ ctx.get(), GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME) == 1);
+ return ctx;
}
-static void local_check_peer(grpc_security_connector* sc, tsi_peer peer,
- grpc_auth_context** auth_context,
- grpc_closure* on_peer_checked) {
- grpc_security_status status;
+void local_check_peer(grpc_security_connector* sc, tsi_peer peer,
+ grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked,
+ grpc_local_connect_type type) {
+ int fd = grpc_endpoint_get_fd(ep);
+ grpc_resolved_address resolved_addr;
+ memset(&resolved_addr, 0, sizeof(resolved_addr));
+ resolved_addr.len = GRPC_MAX_SOCKADDR_SIZE;
+ bool is_endpoint_local = false;
+ if (getsockname(fd, reinterpret_cast<grpc_sockaddr*>(resolved_addr.addr),
+ &resolved_addr.len) == 0) {
+ grpc_resolved_address addr_normalized;
+ grpc_resolved_address* addr =
+ grpc_sockaddr_is_v4mapped(&resolved_addr, &addr_normalized)
+ ? &addr_normalized
+ : &resolved_addr;
+ grpc_sockaddr* sock_addr = reinterpret_cast<grpc_sockaddr*>(&addr->addr);
+ // UDS
+ if (type == UDS && grpc_is_unix_socket(addr)) {
+ is_endpoint_local = true;
+ // IPV4
+ } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET) {
+ const grpc_sockaddr_in* addr4 =
+ reinterpret_cast<const grpc_sockaddr_in*>(sock_addr);
+ if (grpc_htonl(addr4->sin_addr.s_addr) == INADDR_LOOPBACK) {
+ is_endpoint_local = true;
+ }
+ // IPv6
+ } else if (type == LOCAL_TCP && sock_addr->sa_family == GRPC_AF_INET6) {
+ const grpc_sockaddr_in6* addr6 =
+ reinterpret_cast<const grpc_sockaddr_in6*>(addr);
+ if (memcmp(&addr6->sin6_addr, &in6addr_loopback,
+ sizeof(in6addr_loopback)) == 0) {
+ is_endpoint_local = true;
+ }
+ }
+ }
+ grpc_error* error = GRPC_ERROR_NONE;
+ if (!is_endpoint_local) {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Endpoint is neither UDS or TCP loopback address.");
+ GRPC_CLOSURE_SCHED(on_peer_checked, error);
+ return;
+ }
/* Create an auth context which is necessary to pass the santiy check in
* {client, server}_auth_filter that verifies if the peer's auth context is
* obtained during handshakes. The auth context is only checked for its
* existence and not actually used.
*/
- status = local_auth_context_create(auth_context);
- grpc_error* error = status == GRPC_SECURITY_OK
- ? GRPC_ERROR_NONE
- : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Could not create local auth context");
+ *auth_context = local_auth_context_create();
+ error = *auth_context != nullptr ? GRPC_ERROR_NONE
+ : GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "Could not create local auth context");
GRPC_CLOSURE_SCHED(on_peer_checked, error);
}
-static grpc_security_connector_vtable local_channel_vtable = {
- local_channel_destroy, local_check_peer, local_channel_cmp};
-
-static grpc_security_connector_vtable local_server_vtable = {
- local_server_destroy, local_check_peer, local_server_cmp};
-
-static bool local_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_local_channel_security_connector* local_sc =
- reinterpret_cast<grpc_local_channel_security_connector*>(sc);
- if (host == nullptr || local_sc == nullptr ||
- strcmp(host, local_sc->target_name) != 0) {
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "local call host does not match target name");
+class grpc_local_channel_security_connector final
+ : public grpc_channel_security_connector {
+ public:
+ grpc_local_channel_security_connector(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const char* target_name)
+ : grpc_channel_security_connector(nullptr, std::move(channel_creds),
+ std::move(request_metadata_creds)),
+ target_name_(gpr_strdup(target_name)) {}
+
+ ~grpc_local_channel_security_connector() override { gpr_free(target_name_); }
+
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_manager) override {
+ tsi_handshaker* handshaker = nullptr;
+ GPR_ASSERT(local_tsi_handshaker_create(true /* is_client */, &handshaker) ==
+ TSI_OK);
+ grpc_handshake_manager_add(
+ handshake_manager, grpc_security_handshaker_create(handshaker, this));
}
- return true;
-}
-static void local_cancel_check_call_host(grpc_channel_security_connector* sc,
- grpc_closure* on_call_host_checked,
- grpc_error* error) {
- GRPC_ERROR_UNREF(error);
-}
+ int cmp(const grpc_security_connector* other_sc) const override {
+ auto* other =
+ reinterpret_cast<const grpc_local_channel_security_connector*>(
+ other_sc);
+ int c = channel_security_connector_cmp(other);
+ if (c != 0) return c;
+ return strcmp(target_name_, other->target_name_);
+ }
+
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ grpc_local_credentials* creds =
+ reinterpret_cast<grpc_local_credentials*>(mutable_channel_creds());
+ local_check_peer(this, peer, ep, auth_context, on_peer_checked,
+ creds->connect_type());
+ }
+
+ bool check_call_host(const char* host, grpc_auth_context* auth_context,
+ grpc_closure* on_call_host_checked,
+ grpc_error** error) override {
+ if (host == nullptr || strcmp(host, target_name_) != 0) {
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "local call host does not match target name");
+ }
+ return true;
+ }
+
+ void cancel_check_call_host(grpc_closure* on_call_host_checked,
+ grpc_error* error) override {
+ GRPC_ERROR_UNREF(error);
+ }
-grpc_security_status grpc_local_channel_security_connector_create(
- grpc_channel_credentials* channel_creds,
- grpc_call_credentials* request_metadata_creds,
- const grpc_channel_args* args, const char* target_name,
- grpc_channel_security_connector** sc) {
- if (channel_creds == nullptr || sc == nullptr || target_name == nullptr) {
+ const char* target_name() const { return target_name_; }
+
+ private:
+ char* target_name_;
+};
+
+class grpc_local_server_security_connector final
+ : public grpc_server_security_connector {
+ public:
+ grpc_local_server_security_connector(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
+ : grpc_server_security_connector(nullptr, std::move(server_creds)) {}
+ ~grpc_local_server_security_connector() override = default;
+
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_manager) override {
+ tsi_handshaker* handshaker = nullptr;
+ GPR_ASSERT(local_tsi_handshaker_create(false /* is_client */,
+ &handshaker) == TSI_OK);
+ grpc_handshake_manager_add(
+ handshake_manager, grpc_security_handshaker_create(handshaker, this));
+ }
+
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ grpc_local_server_credentials* creds =
+ static_cast<grpc_local_server_credentials*>(mutable_server_creds());
+ local_check_peer(this, peer, ep, auth_context, on_peer_checked,
+ creds->connect_type());
+ }
+
+ int cmp(const grpc_security_connector* other) const override {
+ return server_security_connector_cmp(
+ static_cast<const grpc_server_security_connector*>(other));
+ }
+};
+} // namespace
+
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_local_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const grpc_channel_args* args, const char* target_name) {
+ if (channel_creds == nullptr || target_name == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid arguments to grpc_local_channel_security_connector_create()");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- // Check if local_connect_type is UDS. Only UDS is supported for now.
+ // Perform sanity check on UDS address. For TCP local connection, the check
+ // will be done during check_peer procedure.
grpc_local_credentials* creds =
- reinterpret_cast<grpc_local_credentials*>(channel_creds);
- if (creds->connect_type != UDS) {
- gpr_log(GPR_ERROR,
- "Invalid local channel type to "
- "grpc_local_channel_security_connector_create()");
- return GRPC_SECURITY_ERROR;
- }
- // Check if target_name is a valid UDS address.
+ static_cast<grpc_local_credentials*>(channel_creds.get());
const grpc_arg* server_uri_arg =
grpc_channel_args_find(args, GRPC_ARG_SERVER_URI);
const char* server_uri_str = grpc_channel_arg_get_string(server_uri_arg);
- if (strncmp(GRPC_UDS_URI_PATTERN, server_uri_str,
+ if (creds->connect_type() == UDS &&
+ strncmp(GRPC_UDS_URI_PATTERN, server_uri_str,
strlen(GRPC_UDS_URI_PATTERN)) != 0) {
gpr_log(GPR_ERROR,
- "Invalid target_name to "
+ "Invalid UDS target name to "
"grpc_local_channel_security_connector_create()");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- auto c = static_cast<grpc_local_channel_security_connector*>(
- gpr_zalloc(sizeof(grpc_local_channel_security_connector)));
- gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.vtable = &local_channel_vtable;
- c->base.add_handshakers = local_channel_add_handshakers;
- 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 = local_check_call_host;
- c->base.cancel_check_call_host = local_cancel_check_call_host;
- c->base.base.url_scheme =
- creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr;
- c->target_name = gpr_strdup(target_name);
- *sc = &c->base;
- return GRPC_SECURITY_OK;
+ return grpc_core::MakeRefCounted<grpc_local_channel_security_connector>(
+ channel_creds, request_metadata_creds, target_name);
}
-grpc_security_status grpc_local_server_security_connector_create(
- grpc_server_credentials* server_creds,
- grpc_server_security_connector** sc) {
- if (server_creds == nullptr || sc == nullptr) {
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_local_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) {
+ if (server_creds == nullptr) {
gpr_log(
GPR_ERROR,
"Invalid arguments to grpc_local_server_security_connector_create()");
- return GRPC_SECURITY_ERROR;
- }
- // Check if local_connect_type is UDS. Only UDS is supported for now.
- grpc_local_server_credentials* creds =
- reinterpret_cast<grpc_local_server_credentials*>(server_creds);
- if (creds->connect_type != UDS) {
- gpr_log(GPR_ERROR,
- "Invalid local server type to "
- "grpc_local_server_security_connector_create()");
- return GRPC_SECURITY_ERROR;
+ return nullptr;
}
- auto c = static_cast<grpc_local_server_security_connector*>(
- gpr_zalloc(sizeof(grpc_local_server_security_connector)));
- gpr_ref_init(&c->base.base.refcount, 1);
- c->base.base.vtable = &local_server_vtable;
- c->base.server_creds = grpc_server_credentials_ref(server_creds);
- c->base.base.url_scheme =
- creds->connect_type == UDS ? GRPC_UDS_URL_SCHEME : nullptr;
- c->base.add_handshakers = local_server_add_handshakers;
- *sc = &c->base;
- return GRPC_SECURITY_OK;
+ return grpc_core::MakeRefCounted<grpc_local_server_security_connector>(
+ std::move(server_creds));
}
diff --git a/src/core/lib/security/security_connector/local/local_security_connector.h b/src/core/lib/security/security_connector/local/local_security_connector.h
index 5369a2127a..6eee0ca9a6 100644
--- a/src/core/lib/security/security_connector/local/local_security_connector.h
+++ b/src/core/lib/security/security_connector/local/local_security_connector.h
@@ -34,13 +34,13 @@
* - sc: address of local channel security connector instance to be returned
* from the method.
*
- * It returns GRPC_SECURITY_OK on success, and an error stauts code on failure.
+ * It returns nullptr on failure.
*/
-grpc_security_status grpc_local_channel_security_connector_create(
- grpc_channel_credentials* channel_creds,
- grpc_call_credentials* request_metadata_creds,
- const grpc_channel_args* args, const char* target_name,
- grpc_channel_security_connector** sc);
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_local_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const grpc_channel_args* args, const char* target_name);
/**
* This method creates a local server security connector.
@@ -49,10 +49,11 @@ grpc_security_status grpc_local_channel_security_connector_create(
* - sc: address of local server security connector instance to be returned from
* the method.
*
- * It returns GRPC_SECURITY_OK on success, and an error status code on failure.
+ * It returns nullptr on failure.
*/
-grpc_security_status grpc_local_server_security_connector_create(
- grpc_server_credentials* server_creds, grpc_server_security_connector** sc);
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_local_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
#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 02cecb0eb1..96a1960546 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -35,150 +35,67 @@
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/security_connector/load_system_roots.h"
+#include "src/core/lib/security/security_connector/security_connector.h"
#include "src/core/lib/security/transport/security_handshaker.h"
grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount(
false, "security_connector_refcount");
-void grpc_channel_security_connector_add_handshakers(
- grpc_channel_security_connector* connector,
- grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr) {
- if (connector != nullptr) {
- connector->add_handshakers(connector, interested_parties, handshake_mgr);
- }
-}
-
-void grpc_server_security_connector_add_handshakers(
- grpc_server_security_connector* connector,
- grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr) {
- if (connector != nullptr) {
- connector->add_handshakers(connector, interested_parties, handshake_mgr);
- }
-}
-
-void grpc_security_connector_check_peer(grpc_security_connector* sc,
- tsi_peer peer,
- grpc_auth_context** auth_context,
- grpc_closure* on_peer_checked) {
- if (sc == nullptr) {
- GRPC_CLOSURE_SCHED(on_peer_checked,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "cannot check peer -- no security connector"));
- tsi_peer_destruct(&peer);
- } else {
- sc->vtable->check_peer(sc, peer, auth_context, on_peer_checked);
- }
-}
-
-int grpc_security_connector_cmp(grpc_security_connector* sc,
- grpc_security_connector* other) {
+grpc_server_security_connector::grpc_server_security_connector(
+ const char* url_scheme,
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
+ : grpc_security_connector(url_scheme),
+ server_creds_(std::move(server_creds)) {}
+
+grpc_channel_security_connector::grpc_channel_security_connector(
+ const char* url_scheme,
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds)
+ : grpc_security_connector(url_scheme),
+ channel_creds_(std::move(channel_creds)),
+ request_metadata_creds_(std::move(request_metadata_creds)) {}
+grpc_channel_security_connector::~grpc_channel_security_connector() {}
+
+int grpc_security_connector_cmp(const grpc_security_connector* sc,
+ const grpc_security_connector* other) {
if (sc == nullptr || other == nullptr) return GPR_ICMP(sc, other);
- int c = GPR_ICMP(sc->vtable, other->vtable);
- if (c != 0) return c;
- return sc->vtable->cmp(sc, other);
+ return sc->cmp(other);
}
-int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1,
- grpc_channel_security_connector* sc2) {
- GPR_ASSERT(sc1->channel_creds != nullptr);
- GPR_ASSERT(sc2->channel_creds != nullptr);
- int c = GPR_ICMP(sc1->channel_creds, sc2->channel_creds);
- if (c != 0) return c;
- c = GPR_ICMP(sc1->request_metadata_creds, sc2->request_metadata_creds);
- if (c != 0) return c;
- c = GPR_ICMP((void*)sc1->check_call_host, (void*)sc2->check_call_host);
- if (c != 0) return c;
- c = GPR_ICMP((void*)sc1->cancel_check_call_host,
- (void*)sc2->cancel_check_call_host);
+int grpc_channel_security_connector::channel_security_connector_cmp(
+ const grpc_channel_security_connector* other) const {
+ const grpc_channel_security_connector* other_sc =
+ static_cast<const grpc_channel_security_connector*>(other);
+ GPR_ASSERT(channel_creds() != nullptr);
+ GPR_ASSERT(other_sc->channel_creds() != nullptr);
+ int c = GPR_ICMP(channel_creds(), other_sc->channel_creds());
if (c != 0) return c;
- return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
+ return GPR_ICMP(request_metadata_creds(), other_sc->request_metadata_creds());
}
-int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
- grpc_server_security_connector* sc2) {
- GPR_ASSERT(sc1->server_creds != nullptr);
- GPR_ASSERT(sc2->server_creds != nullptr);
- int c = GPR_ICMP(sc1->server_creds, sc2->server_creds);
- if (c != 0) return c;
- return GPR_ICMP((void*)sc1->add_handshakers, (void*)sc2->add_handshakers);
-}
-
-bool grpc_channel_security_connector_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) {
- if (sc == nullptr || sc->check_call_host == nullptr) {
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "cannot check call host -- no security connector");
- return true;
- }
- return sc->check_call_host(sc, host, auth_context, on_call_host_checked,
- error);
-}
-
-void grpc_channel_security_connector_cancel_check_call_host(
- grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
- grpc_error* error) {
- if (sc == nullptr || sc->cancel_check_call_host == nullptr) {
- GRPC_ERROR_UNREF(error);
- return;
- }
- sc->cancel_check_call_host(sc, on_call_host_checked, error);
-}
-
-#ifndef NDEBUG
-grpc_security_connector* grpc_security_connector_ref(
- grpc_security_connector* sc, const char* file, int line,
- const char* reason) {
- if (sc == nullptr) return nullptr;
- if (grpc_trace_security_connector_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "SECURITY_CONNECTOR:%p ref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
- val, val + 1, reason);
- }
-#else
-grpc_security_connector* grpc_security_connector_ref(
- grpc_security_connector* sc) {
- if (sc == nullptr) return nullptr;
-#endif
- gpr_ref(&sc->refcount);
- return sc;
-}
-
-#ifndef NDEBUG
-void grpc_security_connector_unref(grpc_security_connector* sc,
- const char* file, int line,
- const char* reason) {
- if (sc == nullptr) return;
- if (grpc_trace_security_connector_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&sc->refcount.count);
- gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
- "SECURITY_CONNECTOR:%p unref %" PRIdPTR " -> %" PRIdPTR " %s", sc,
- val, val - 1, reason);
- }
-#else
-void grpc_security_connector_unref(grpc_security_connector* sc) {
- if (sc == nullptr) return;
-#endif
- if (gpr_unref(&sc->refcount)) sc->vtable->destroy(sc);
+int grpc_server_security_connector::server_security_connector_cmp(
+ const grpc_server_security_connector* other) const {
+ const grpc_server_security_connector* other_sc =
+ static_cast<const grpc_server_security_connector*>(other);
+ GPR_ASSERT(server_creds() != nullptr);
+ GPR_ASSERT(other_sc->server_creds() != nullptr);
+ return GPR_ICMP(server_creds(), other_sc->server_creds());
}
static void connector_arg_destroy(void* p) {
- GRPC_SECURITY_CONNECTOR_UNREF((grpc_security_connector*)p,
- "connector_arg_destroy");
+ static_cast<grpc_security_connector*>(p)->Unref(DEBUG_LOCATION,
+ "connector_arg_destroy");
}
static void* connector_arg_copy(void* p) {
- return GRPC_SECURITY_CONNECTOR_REF((grpc_security_connector*)p,
- "connector_arg_copy");
+ return static_cast<grpc_security_connector*>(p)
+ ->Ref(DEBUG_LOCATION, "connector_arg_copy")
+ .release();
}
static int connector_cmp(void* a, void* b) {
- return grpc_security_connector_cmp(static_cast<grpc_security_connector*>(a),
- static_cast<grpc_security_connector*>(b));
+ return static_cast<grpc_security_connector*>(a)->cmp(
+ static_cast<grpc_security_connector*>(b));
}
static const grpc_arg_pointer_vtable connector_arg_vtable = {
diff --git a/src/core/lib/security/security_connector/security_connector.h b/src/core/lib/security/security_connector/security_connector.h
index 4c921a8793..74b0ef21a6 100644
--- a/src/core/lib/security/security_connector/security_connector.h
+++ b/src/core/lib/security/security_connector/security_connector.h
@@ -26,6 +26,7 @@
#include <grpc/grpc_security.h>
#include "src/core/lib/channel/handshaker.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/iomgr/endpoint.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/tcp_server.h"
@@ -34,8 +35,6 @@
extern grpc_core::DebugOnlyTraceFlag grpc_trace_security_connector_refcount;
-/* --- status enum. --- */
-
typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status;
/* --- security_connector object. ---
@@ -43,54 +42,34 @@ typedef enum { GRPC_SECURITY_OK = 0, GRPC_SECURITY_ERROR } grpc_security_status;
A security connector object represents away to configure the underlying
transport security mechanism and check the resulting trusted peer. */
-typedef struct grpc_security_connector grpc_security_connector;
-
#define GRPC_ARG_SECURITY_CONNECTOR "grpc.security_connector"
-typedef struct {
- void (*destroy)(grpc_security_connector* sc);
- void (*check_peer)(grpc_security_connector* sc, tsi_peer peer,
- grpc_auth_context** auth_context,
- grpc_closure* on_peer_checked);
- int (*cmp)(grpc_security_connector* sc, grpc_security_connector* other);
-} grpc_security_connector_vtable;
-
-struct grpc_security_connector {
- const grpc_security_connector_vtable* vtable;
- gpr_refcount refcount;
- const char* url_scheme;
-};
+class grpc_security_connector
+ : public grpc_core::RefCounted<grpc_security_connector> {
+ public:
+ explicit grpc_security_connector(const char* url_scheme)
+ : grpc_core::RefCounted<grpc_security_connector>(
+ &grpc_trace_security_connector_refcount),
+ url_scheme_(url_scheme) {}
+ virtual ~grpc_security_connector() = default;
+
+ /* Check the peer. Callee takes ownership of the peer object.
+ When done, sets *auth_context and invokes on_peer_checked. */
+ virtual void check_peer(
+ tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) GRPC_ABSTRACT;
+
+ /* Compares two security connectors. */
+ virtual int cmp(const grpc_security_connector* other) const GRPC_ABSTRACT;
+
+ const char* url_scheme() const { return url_scheme_; }
-/* Refcounting. */
-#ifndef NDEBUG
-#define GRPC_SECURITY_CONNECTOR_REF(p, r) \
- grpc_security_connector_ref((p), __FILE__, __LINE__, (r))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) \
- grpc_security_connector_unref((p), __FILE__, __LINE__, (r))
-grpc_security_connector* grpc_security_connector_ref(
- grpc_security_connector* policy, const char* file, int line,
- const char* reason);
-void grpc_security_connector_unref(grpc_security_connector* policy,
- const char* file, int line,
- const char* reason);
-#else
-#define GRPC_SECURITY_CONNECTOR_REF(p, r) grpc_security_connector_ref((p))
-#define GRPC_SECURITY_CONNECTOR_UNREF(p, r) grpc_security_connector_unref((p))
-grpc_security_connector* grpc_security_connector_ref(
- grpc_security_connector* policy);
-void grpc_security_connector_unref(grpc_security_connector* policy);
-#endif
-
-/* Check the peer. Callee takes ownership of the peer object.
- When done, sets *auth_context and invokes on_peer_checked. */
-void grpc_security_connector_check_peer(grpc_security_connector* sc,
- tsi_peer peer,
- grpc_auth_context** auth_context,
- grpc_closure* on_peer_checked);
-
-/* Compares two security connectors. */
-int grpc_security_connector_cmp(grpc_security_connector* sc,
- grpc_security_connector* other);
+ GRPC_ABSTRACT_BASE_CLASS
+
+ private:
+ const char* url_scheme_;
+};
/* Util to encapsulate the connector in a channel arg. */
grpc_arg grpc_security_connector_to_arg(grpc_security_connector* sc);
@@ -107,71 +86,89 @@ grpc_security_connector* grpc_security_connector_find_in_args(
A channel security connector object represents a way to configure the
underlying transport security mechanism on the client side. */
-typedef struct grpc_channel_security_connector grpc_channel_security_connector;
-
-struct grpc_channel_security_connector {
- grpc_security_connector base;
- grpc_channel_credentials* channel_creds;
- grpc_call_credentials* request_metadata_creds;
- bool (*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);
- void (*cancel_check_call_host)(grpc_channel_security_connector* sc,
- grpc_closure* on_call_host_checked,
- grpc_error* error);
- void (*add_handshakers)(grpc_channel_security_connector* sc,
- grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr);
+class grpc_channel_security_connector : public grpc_security_connector {
+ public:
+ grpc_channel_security_connector(
+ const char* url_scheme,
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds);
+ ~grpc_channel_security_connector() override;
+
+ /// Checks that the host that will be set for a call is acceptable.
+ /// Returns true if completed synchronously, in which case \a error will
+ /// be set to indicate the result. Otherwise, \a on_call_host_checked
+ /// will be invoked when complete.
+ virtual bool check_call_host(const char* host,
+ grpc_auth_context* auth_context,
+ grpc_closure* on_call_host_checked,
+ grpc_error** error) GRPC_ABSTRACT;
+ /// Cancels a pending asychronous call to
+ /// grpc_channel_security_connector_check_call_host() with
+ /// \a on_call_host_checked as its callback.
+ virtual void cancel_check_call_host(grpc_closure* on_call_host_checked,
+ grpc_error* error) GRPC_ABSTRACT;
+ /// Registers handshakers with \a handshake_mgr.
+ virtual void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr)
+ GRPC_ABSTRACT;
+
+ const grpc_channel_credentials* channel_creds() const {
+ return channel_creds_.get();
+ }
+ grpc_channel_credentials* mutable_channel_creds() {
+ return channel_creds_.get();
+ }
+ const grpc_call_credentials* request_metadata_creds() const {
+ return request_metadata_creds_.get();
+ }
+ grpc_call_credentials* mutable_request_metadata_creds() {
+ return request_metadata_creds_.get();
+ }
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ // Helper methods to be used in subclasses.
+ int channel_security_connector_cmp(
+ const grpc_channel_security_connector* other) const;
+
+ private:
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds_;
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds_;
};
-/// A helper function for use in grpc_security_connector_cmp() implementations.
-int grpc_channel_security_connector_cmp(grpc_channel_security_connector* sc1,
- grpc_channel_security_connector* sc2);
-
-/// Checks that the host that will be set for a call is acceptable.
-/// Returns true if completed synchronously, in which case \a error will
-/// be set to indicate the result. Otherwise, \a on_call_host_checked
-/// will be invoked when complete.
-bool grpc_channel_security_connector_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);
-
-/// Cancels a pending asychronous call to
-/// grpc_channel_security_connector_check_call_host() with
-/// \a on_call_host_checked as its callback.
-void grpc_channel_security_connector_cancel_check_call_host(
- grpc_channel_security_connector* sc, grpc_closure* on_call_host_checked,
- grpc_error* error);
-
-/* Registers handshakers with \a handshake_mgr. */
-void grpc_channel_security_connector_add_handshakers(
- grpc_channel_security_connector* connector,
- grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr);
-
/* --- server_security_connector object. ---
A server security connector object represents a way to configure the
underlying transport security mechanism on the server side. */
-typedef struct grpc_server_security_connector grpc_server_security_connector;
-
-struct grpc_server_security_connector {
- grpc_security_connector base;
- grpc_server_credentials* server_creds;
- void (*add_handshakers)(grpc_server_security_connector* sc,
- grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr);
+class grpc_server_security_connector : public grpc_security_connector {
+ public:
+ grpc_server_security_connector(
+ const char* url_scheme,
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds);
+ ~grpc_server_security_connector() override = default;
+
+ virtual void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr)
+ GRPC_ABSTRACT;
+
+ const grpc_server_credentials* server_creds() const {
+ return server_creds_.get();
+ }
+ grpc_server_credentials* mutable_server_creds() {
+ return server_creds_.get();
+ }
+
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ // Helper methods to be used in subclasses.
+ int server_security_connector_cmp(
+ const grpc_server_security_connector* other) const;
+
+ private:
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds_;
};
-/// A helper function for use in grpc_security_connector_cmp() implementations.
-int grpc_server_security_connector_cmp(grpc_server_security_connector* sc1,
- grpc_server_security_connector* sc2);
-
-void grpc_server_security_connector_add_handshakers(
- grpc_server_security_connector* sc, grpc_pollset_set* interested_parties,
- grpc_handshake_manager* handshake_mgr);
-
#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
index 20a9533dd1..7414ab1a37 100644
--- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc
+++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc
@@ -30,6 +30,7 @@
#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/gprpp/ref_counted_ptr.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"
@@ -39,172 +40,10 @@
#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) {
+namespace {
+grpc_error* ssl_check_peer(
+ const char* peer_name, const tsi_peer* peer,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context) {
#if TSI_OPENSSL_ALPN_SUPPORT
/* Check the ALPN if ALPN is supported. */
const tsi_peer_property* p =
@@ -230,245 +69,384 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc,
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);
- }
- }
+class grpc_ssl_channel_security_connector final
+ : public grpc_channel_security_connector {
+ public:
+ grpc_ssl_channel_security_connector(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds,
+ const grpc_ssl_config* config, const char* target_name,
+ const char* overridden_target_name)
+ : grpc_channel_security_connector(GRPC_SSL_URL_SCHEME,
+ std::move(channel_creds),
+ std::move(request_metadata_creds)),
+ overridden_target_name_(overridden_target_name == nullptr
+ ? nullptr
+ : gpr_strdup(overridden_target_name)),
+ verify_options_(&config->verify_options) {
+ char* port;
+ gpr_split_host_port(target_name, &target_name_, &port);
+ gpr_free(port);
}
- 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);
-}
+ ~grpc_ssl_channel_security_connector() override {
+ tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_);
+ if (target_name_ != nullptr) gpr_free(target_name_);
+ if (overridden_target_name_ != nullptr) gpr_free(overridden_target_name_);
+ }
-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);
-}
+ grpc_security_status InitializeHandshakerFactory(
+ const grpc_ssl_config* config, const char* pem_root_certs,
+ const tsi_ssl_root_certs_store* root_store,
+ tsi_ssl_session_cache* ssl_session_cache) {
+ bool 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;
+ tsi_ssl_client_handshaker_options options;
+ memset(&options, 0, sizeof(options));
+ GPR_DEBUG_ASSERT(pem_root_certs != nullptr);
+ options.pem_root_certs = pem_root_certs;
+ options.root_store = root_store;
+ options.alpn_protocols =
+ grpc_fill_alpn_protocol_strings(&options.num_alpn_protocols);
+ 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;
+ const tsi_result result =
+ tsi_create_ssl_client_handshaker_factory_with_options(
+ &options, &client_handshaker_factory_);
+ gpr_free((void*)options.alpn_protocols);
+ if (result != TSI_OK) {
+ gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
+ tsi_result_to_string(result));
+ return GRPC_SECURITY_ERROR;
+ }
+ return GRPC_SECURITY_OK;
+ }
-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));
-}
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr) override {
+ // Instantiate TSI handshaker.
+ tsi_handshaker* tsi_hs = nullptr;
+ tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker(
+ client_handshaker_factory_,
+ overridden_target_name_ != nullptr ? overridden_target_name_
+ : 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, this));
+ }
-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;
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ const char* target_name = overridden_target_name_ != nullptr
+ ? overridden_target_name_
+ : target_name_;
+ grpc_error* error = ssl_check_peer(target_name, &peer, auth_context);
+ if (error == GRPC_ERROR_NONE &&
+ 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 = verify_options_->verify_peer_callback(
+ target_name, peer_pem,
+ 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);
}
- if (status != GRPC_SECURITY_OK) {
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "call host does not match SSL server name");
+
+ int cmp(const grpc_security_connector* other_sc) const override {
+ auto* other =
+ reinterpret_cast<const grpc_ssl_channel_security_connector*>(other_sc);
+ int c = channel_security_connector_cmp(other);
+ if (c != 0) return c;
+ c = strcmp(target_name_, other->target_name_);
+ if (c != 0) return c;
+ return (overridden_target_name_ == nullptr ||
+ other->overridden_target_name_ == nullptr)
+ ? GPR_ICMP(overridden_target_name_,
+ other->overridden_target_name_)
+ : strcmp(overridden_target_name_,
+ other->overridden_target_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);
-}
+ bool check_call_host(const char* host, grpc_auth_context* auth_context,
+ grpc_closure* on_call_host_checked,
+ grpc_error** error) override {
+ 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 (overridden_target_name_ != nullptr && strcmp(host, 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 grpc_security_connector_vtable ssl_channel_vtable = {
- ssl_channel_destroy, ssl_channel_check_peer, ssl_channel_cmp};
+ void cancel_check_call_host(grpc_closure* on_call_host_checked,
+ grpc_error* error) override {
+ GRPC_ERROR_UNREF(error);
+ }
-static grpc_security_connector_vtable ssl_server_vtable = {
- ssl_server_destroy, ssl_server_check_peer, ssl_server_cmp};
+ private:
+ tsi_ssl_client_handshaker_factory* client_handshaker_factory_;
+ char* target_name_;
+ char* overridden_target_name_;
+ const verify_peer_options* verify_options_;
+};
+
+class grpc_ssl_server_security_connector
+ : public grpc_server_security_connector {
+ public:
+ grpc_ssl_server_security_connector(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_creds)
+ : grpc_server_security_connector(GRPC_SSL_URL_SCHEME,
+ std::move(server_creds)) {}
+
+ ~grpc_ssl_server_security_connector() override {
+ tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
+ }
-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);
+ bool has_cert_config_fetcher() const {
+ return static_cast<const grpc_ssl_server_credentials*>(server_creds())
+ ->has_cert_config_fetcher();
+ }
- if (config == nullptr || target_name == nullptr) {
- gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
- goto error;
+ const tsi_ssl_server_handshaker_factory* server_handshaker_factory() const {
+ return server_handshaker_factory_;
}
- 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;
+
+ grpc_security_status InitializeHandshakerFactory() {
+ if (has_cert_config_fetcher()) {
+ // Load initial credentials from certificate_config_fetcher:
+ if (!try_fetch_ssl_server_credentials()) {
+ gpr_log(GPR_ERROR,
+ "Failed loading SSL server credentials from fetcher.");
+ return GRPC_SECURITY_ERROR;
+ }
+ } else {
+ auto* server_credentials =
+ static_cast<const grpc_ssl_server_credentials*>(server_creds());
+ size_t num_alpn_protocols = 0;
+ const char** alpn_protocol_strings =
+ grpc_fill_alpn_protocol_strings(&num_alpn_protocols);
+ const tsi_result 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),
+ &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));
+ return GRPC_SECURITY_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);
+ return GRPC_SECURITY_OK;
}
- 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;
+ void add_handshakers(grpc_pollset_set* interested_parties,
+ grpc_handshake_manager* handshake_mgr) override {
+ // Instantiate TSI handshaker.
+ try_fetch_ssl_server_credentials();
+ tsi_handshaker* tsi_hs = nullptr;
+ tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker(
+ 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, this));
}
- 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;
+
+ void check_peer(tsi_peer peer, grpc_endpoint* ep,
+ grpc_core::RefCountedPtr<grpc_auth_context>* auth_context,
+ grpc_closure* on_peer_checked) override {
+ grpc_error* error = ssl_check_peer(nullptr, &peer, auth_context);
+ tsi_peer_destruct(&peer);
+ GRPC_CLOSURE_SCHED(on_peer_checked, 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;
-}
+ int cmp(const grpc_security_connector* other) const override {
+ return server_security_connector_cmp(
+ static_cast<const grpc_server_security_connector*>(other));
+ }
-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;
-}
+ private:
+ /* 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. */
+ bool try_fetch_ssl_server_credentials() {
+ grpc_ssl_server_certificate_config* certificate_config = nullptr;
+ bool status;
+
+ if (!has_cert_config_fetcher()) return false;
+
+ grpc_ssl_server_credentials* server_creds =
+ static_cast<grpc_ssl_server_credentials*>(this->mutable_server_creds());
+ grpc_ssl_certificate_config_reload_status cb_result =
+ server_creds->FetchCertConfig(&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(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;
+ }
-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;
+ if (certificate_config != nullptr) {
+ grpc_ssl_server_certificate_config_destroy(certificate_config);
+ }
+ return status;
+ }
- 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;
+ /* 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). */
+ bool try_replace_server_handshaker_factory(
+ const grpc_ssl_server_certificate_config* config) {
+ if (config == nullptr) {
+ gpr_log(GPR_ERROR,
+ "Server certificate config callback returned invalid (NULL) "
+ "config.");
+ return false;
}
- } else {
+ 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);
- 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,
+ 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;
+ const grpc_ssl_server_credentials* server_creds =
+ static_cast<const grpc_ssl_server_credentials*>(this->server_creds());
+ GPR_DEBUG_ASSERT(config->pem_root_certs != nullptr);
+ 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_credentials->config.client_certificate_request),
+ server_creds->config().client_certificate_request),
grpc_get_ssl_cipher_suites(), alpn_protocol_strings,
- static_cast<uint16_t>(num_alpn_protocols),
- &c->server_handshaker_factory);
+ 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));
- retval = GRPC_SECURITY_ERROR;
+ return false;
}
+ set_server_handshaker_factory(new_handshaker_factory);
+ return true;
+ }
+
+ void set_server_handshaker_factory(
+ tsi_ssl_server_handshaker_factory* new_factory) {
+ if (server_handshaker_factory_) {
+ tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_);
+ }
+ server_handshaker_factory_ = new_factory;
+ }
+
+ tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr;
+};
+} // namespace
+
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_ssl_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<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) {
+ if (config == nullptr || target_name == nullptr) {
+ gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
+ return nullptr;
}
- if (retval == GRPC_SECURITY_OK) {
- *sc = &c->base;
+ const char* pem_root_certs;
+ const tsi_ssl_root_certs_store* root_store;
+ if (config->pem_root_certs == nullptr) {
+ // Use default root certificates.
+ pem_root_certs = grpc_core::DefaultSslRootStore::GetPemRootCerts();
+ if (pem_root_certs == nullptr) {
+ gpr_log(GPR_ERROR, "Could not get default pem root certs.");
+ return nullptr;
+ }
+ root_store = grpc_core::DefaultSslRootStore::GetRootStore();
} else {
- if (c != nullptr) ssl_server_destroy(&c->base.base);
- if (sc != nullptr) *sc = nullptr;
+ pem_root_certs = config->pem_root_certs;
+ root_store = nullptr;
+ }
+
+ grpc_core::RefCountedPtr<grpc_ssl_channel_security_connector> c =
+ grpc_core::MakeRefCounted<grpc_ssl_channel_security_connector>(
+ std::move(channel_creds), std::move(request_metadata_creds), config,
+ target_name, overridden_target_name);
+ const grpc_security_status result = c->InitializeHandshakerFactory(
+ config, pem_root_certs, root_store, ssl_session_cache);
+ if (result != GRPC_SECURITY_OK) {
+ return nullptr;
}
- return retval;
+ return c;
+}
+
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_ssl_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_credentials) {
+ GPR_ASSERT(server_credentials != nullptr);
+ grpc_core::RefCountedPtr<grpc_ssl_server_security_connector> c =
+ grpc_core::MakeRefCounted<grpc_ssl_server_security_connector>(
+ std::move(server_credentials));
+ const grpc_security_status retval = c->InitializeHandshakerFactory();
+ if (retval != GRPC_SECURITY_OK) {
+ return nullptr;
+ }
+ return c;
}
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
index 9b80590606..70e26e338a 100644
--- a/src/core/lib/security/security_connector/ssl/ssl_security_connector.h
+++ b/src/core/lib/security/security_connector/ssl/ssl_security_connector.h
@@ -25,6 +25,7 @@
#include "src/core/lib/security/security_connector/security_connector.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
@@ -47,20 +48,21 @@ typedef struct {
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,
+grpc_core::RefCountedPtr<grpc_channel_security_connector>
+grpc_ssl_channel_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds,
+ grpc_core::RefCountedPtr<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_ssl_session_cache* ssl_session_cache);
/* 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;
+ tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = nullptr;
+ size_t num_key_cert_pairs = 0;
+ char* pem_root_certs = nullptr;
+ grpc_ssl_client_certificate_request_type client_certificate_request =
+ GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE;
} grpc_ssl_server_config;
/* Creates an SSL server_security_connector.
@@ -69,9 +71,9 @@ typedef struct {
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);
+grpc_core::RefCountedPtr<grpc_server_security_connector>
+grpc_ssl_server_security_connector_create(
+ grpc_core::RefCountedPtr<grpc_server_credentials> server_credentials);
#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
index fbf41cfbc7..29030f07ad 100644
--- a/src/core/lib/security/security_connector/ssl_utils.cc
+++ b/src/core/lib/security/security_connector/ssl_utils.cc
@@ -30,6 +30,7 @@
#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/gprpp/ref_counted_ptr.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"
@@ -141,16 +142,17 @@ int grpc_ssl_host_matches_name(const tsi_peer* peer, const char* peer_name) {
return r;
}
-grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) {
+grpc_core::RefCountedPtr<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_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_context_add_cstring_property(
- ctx, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
+ ctx.get(), 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];
@@ -160,24 +162,26 @@ grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) {
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,
+ grpc_auth_context_add_property(ctx.get(), 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,
+ grpc_auth_context_add_property(ctx.get(), 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,
+ grpc_auth_context_add_property(ctx.get(),
+ 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,
+ grpc_auth_context_add_property(ctx.get(),
+ 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);
+ ctx.get(), peer_identity_property_name) == 1);
}
return ctx;
}
diff --git a/src/core/lib/security/security_connector/ssl_utils.h b/src/core/lib/security/security_connector/ssl_utils.h
index 6f6d473311..c9cd1a1d9c 100644
--- a/src/core/lib/security/security_connector/ssl_utils.h
+++ b/src/core/lib/security/security_connector/ssl_utils.h
@@ -26,6 +26,7 @@
#include <grpc/grpc_security.h>
#include <grpc/slice_buffer.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/tsi/ssl_transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
@@ -47,7 +48,8 @@ grpc_get_tsi_client_certificate_request_type(
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);
+grpc_core::RefCountedPtr<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);
diff --git a/src/core/lib/security/transport/client_auth_filter.cc b/src/core/lib/security/transport/client_auth_filter.cc
index 6955e8698e..66f86b8bc5 100644
--- a/src/core/lib/security/transport/client_auth_filter.cc
+++ b/src/core/lib/security/transport/client_auth_filter.cc
@@ -55,7 +55,7 @@ struct call_data {
// that the memory is not initialized.
void destroy() {
grpc_credentials_mdelem_array_destroy(&md_array);
- grpc_call_credentials_unref(creds);
+ creds.reset();
grpc_slice_unref_internal(host);
grpc_slice_unref_internal(method);
grpc_auth_metadata_context_reset(&auth_md_context);
@@ -64,7 +64,7 @@ struct call_data {
gpr_arena* arena;
grpc_call_stack* owning_call;
grpc_call_combiner* call_combiner;
- grpc_call_credentials* creds = nullptr;
+ grpc_core::RefCountedPtr<grpc_call_credentials> creds;
grpc_slice host = grpc_empty_slice();
grpc_slice method = grpc_empty_slice();
/* pollset{_set} bound to this call; if we need to make external
@@ -83,8 +83,18 @@ struct call_data {
/* We can have a per-channel credentials. */
struct channel_data {
- grpc_channel_security_connector* security_connector;
- grpc_auth_context* auth_context;
+ channel_data(grpc_channel_security_connector* security_connector,
+ grpc_auth_context* auth_context)
+ : security_connector(
+ security_connector->Ref(DEBUG_LOCATION, "client_auth_filter")),
+ auth_context(auth_context->Ref(DEBUG_LOCATION, "client_auth_filter")) {}
+ ~channel_data() {
+ security_connector.reset(DEBUG_LOCATION, "client_auth_filter");
+ auth_context.reset(DEBUG_LOCATION, "client_auth_filter");
+ }
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector> security_connector;
+ grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
};
} // namespace
@@ -98,10 +108,11 @@ void grpc_auth_metadata_context_reset(
gpr_free(const_cast<char*>(auth_md_context->method_name));
auth_md_context->method_name = nullptr;
}
- GRPC_AUTH_CONTEXT_UNREF(
- (grpc_auth_context*)auth_md_context->channel_auth_context,
- "grpc_auth_metadata_context");
- auth_md_context->channel_auth_context = nullptr;
+ if (auth_md_context->channel_auth_context != nullptr) {
+ const_cast<grpc_auth_context*>(auth_md_context->channel_auth_context)
+ ->Unref(DEBUG_LOCATION, "grpc_auth_metadata_context");
+ auth_md_context->channel_auth_context = nullptr;
+ }
}
static void add_error(grpc_error** combined, grpc_error* error) {
@@ -175,7 +186,10 @@ void grpc_auth_metadata_context_build(
auth_md_context->service_url = service_url;
auth_md_context->method_name = method_name;
auth_md_context->channel_auth_context =
- GRPC_AUTH_CONTEXT_REF(auth_context, "grpc_auth_metadata_context");
+ auth_context == nullptr
+ ? nullptr
+ : auth_context->Ref(DEBUG_LOCATION, "grpc_auth_metadata_context")
+ .release();
gpr_free(service);
gpr_free(host_and_port);
}
@@ -184,8 +198,8 @@ static void cancel_get_request_metadata(void* arg, grpc_error* error) {
grpc_call_element* elem = static_cast<grpc_call_element*>(arg);
call_data* calld = static_cast<call_data*>(elem->call_data);
if (error != GRPC_ERROR_NONE) {
- grpc_call_credentials_cancel_get_request_metadata(
- calld->creds, &calld->md_array, GRPC_ERROR_REF(error));
+ calld->creds->cancel_get_request_metadata(&calld->md_array,
+ GRPC_ERROR_REF(error));
}
}
@@ -197,7 +211,7 @@ static void send_security_metadata(grpc_call_element* elem,
static_cast<grpc_client_security_context*>(
batch->payload->context[GRPC_CONTEXT_SECURITY].value);
grpc_call_credentials* channel_call_creds =
- chand->security_connector->request_metadata_creds;
+ chand->security_connector->mutable_request_metadata_creds();
int call_creds_has_md = (ctx != nullptr) && (ctx->creds != nullptr);
if (channel_call_creds == nullptr && !call_creds_has_md) {
@@ -207,8 +221,9 @@ static void send_security_metadata(grpc_call_element* elem,
}
if (channel_call_creds != nullptr && call_creds_has_md) {
- calld->creds = grpc_composite_call_credentials_create(channel_call_creds,
- ctx->creds, nullptr);
+ calld->creds = grpc_core::RefCountedPtr<grpc_call_credentials>(
+ grpc_composite_call_credentials_create(channel_call_creds,
+ ctx->creds.get(), nullptr));
if (calld->creds == nullptr) {
grpc_transport_stream_op_batch_finish_with_failure(
batch,
@@ -220,22 +235,22 @@ static void send_security_metadata(grpc_call_element* elem,
return;
}
} else {
- calld->creds = grpc_call_credentials_ref(
- call_creds_has_md ? ctx->creds : channel_call_creds);
+ calld->creds =
+ call_creds_has_md ? ctx->creds->Ref() : channel_call_creds->Ref();
}
grpc_auth_metadata_context_build(
- chand->security_connector->base.url_scheme, calld->host, calld->method,
- chand->auth_context, &calld->auth_md_context);
+ chand->security_connector->url_scheme(), calld->host, calld->method,
+ chand->auth_context.get(), &calld->auth_md_context);
GPR_ASSERT(calld->pollent != nullptr);
GRPC_CALL_STACK_REF(calld->owning_call, "get_request_metadata");
GRPC_CLOSURE_INIT(&calld->async_result_closure, on_credentials_metadata,
batch, grpc_schedule_on_exec_ctx);
grpc_error* error = GRPC_ERROR_NONE;
- if (grpc_call_credentials_get_request_metadata(
- calld->creds, calld->pollent, calld->auth_md_context,
- &calld->md_array, &calld->async_result_closure, &error)) {
+ if (calld->creds->get_request_metadata(
+ calld->pollent, calld->auth_md_context, &calld->md_array,
+ &calld->async_result_closure, &error)) {
// Synchronous return; invoke on_credentials_metadata() directly.
on_credentials_metadata(batch, error);
GRPC_ERROR_UNREF(error);
@@ -279,9 +294,8 @@ static void cancel_check_call_host(void* arg, grpc_error* error) {
call_data* calld = static_cast<call_data*>(elem->call_data);
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
if (error != GRPC_ERROR_NONE) {
- grpc_channel_security_connector_cancel_check_call_host(
- chand->security_connector, &calld->async_result_closure,
- GRPC_ERROR_REF(error));
+ chand->security_connector->cancel_check_call_host(
+ &calld->async_result_closure, GRPC_ERROR_REF(error));
}
}
@@ -299,16 +313,16 @@ static void auth_start_transport_stream_op_batch(
GPR_ASSERT(batch->payload->context != nullptr);
if (batch->payload->context[GRPC_CONTEXT_SECURITY].value == nullptr) {
batch->payload->context[GRPC_CONTEXT_SECURITY].value =
- grpc_client_security_context_create(calld->arena);
+ grpc_client_security_context_create(calld->arena, /*creds=*/nullptr);
batch->payload->context[GRPC_CONTEXT_SECURITY].destroy =
grpc_client_security_context_destroy;
}
grpc_client_security_context* sec_ctx =
static_cast<grpc_client_security_context*>(
batch->payload->context[GRPC_CONTEXT_SECURITY].value);
- GRPC_AUTH_CONTEXT_UNREF(sec_ctx->auth_context, "client auth filter");
+ sec_ctx->auth_context.reset(DEBUG_LOCATION, "client_auth_filter");
sec_ctx->auth_context =
- GRPC_AUTH_CONTEXT_REF(chand->auth_context, "client_auth_filter");
+ chand->auth_context->Ref(DEBUG_LOCATION, "client_auth_filter");
}
if (batch->send_initial_metadata) {
@@ -327,8 +341,8 @@ static void auth_start_transport_stream_op_batch(
grpc_schedule_on_exec_ctx);
char* call_host = grpc_slice_to_c_string(calld->host);
grpc_error* error = GRPC_ERROR_NONE;
- if (grpc_channel_security_connector_check_call_host(
- chand->security_connector, call_host, chand->auth_context,
+ if (chand->security_connector->check_call_host(
+ call_host, chand->auth_context.get(),
&calld->async_result_closure, &error)) {
// Synchronous return; invoke on_host_checked() directly.
on_host_checked(batch, error);
@@ -374,6 +388,10 @@ static void destroy_call_elem(grpc_call_element* elem,
/* Constructor for channel_data */
static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_element_args* args) {
+ /* The first and the last filters tend to be implemented differently to
+ handle the case that there's no 'next' filter to call on the up or down
+ path */
+ GPR_ASSERT(!args->is_last);
grpc_security_connector* sc =
grpc_security_connector_find_in_args(args->channel_args);
if (sc == nullptr) {
@@ -386,33 +404,15 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Auth context missing from client auth filter args");
}
-
- /* grab pointers to our data from the channel element */
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
-
- /* The first and the last filters tend to be implemented differently to
- handle the case that there's no 'next' filter to call on the up or down
- path */
- GPR_ASSERT(!args->is_last);
-
- /* initialize members */
- chand->security_connector =
- reinterpret_cast<grpc_channel_security_connector*>(
- GRPC_SECURITY_CONNECTOR_REF(sc, "client_auth_filter"));
- chand->auth_context =
- GRPC_AUTH_CONTEXT_REF(auth_context, "client_auth_filter");
+ new (elem->channel_data) channel_data(
+ static_cast<grpc_channel_security_connector*>(sc), auth_context);
return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element* elem) {
- /* grab pointers to our data from the channel element */
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- grpc_channel_security_connector* sc = chand->security_connector;
- if (sc != nullptr) {
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "client_auth_filter");
- }
- GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
+ chand->~channel_data();
}
const grpc_channel_filter grpc_client_auth_filter = {
diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc
index 34d8435907..14fb55884f 100644
--- a/src/core/lib/security/transport/secure_endpoint.cc
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -416,6 +416,11 @@ static grpc_resource_user* endpoint_get_resource_user(
return grpc_endpoint_get_resource_user(ep->wrapped_ep);
}
+static bool endpoint_can_track_err(grpc_endpoint* secure_ep) {
+ secure_endpoint* ep = reinterpret_cast<secure_endpoint*>(secure_ep);
+ return grpc_endpoint_can_track_err(ep->wrapped_ep);
+}
+
static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_write,
endpoint_add_to_pollset,
@@ -425,7 +430,8 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_destroy,
endpoint_get_resource_user,
endpoint_get_peer,
- endpoint_get_fd};
+ endpoint_get_fd,
+ endpoint_can_track_err};
grpc_endpoint* grpc_secure_endpoint_create(
struct tsi_frame_protector* protector,
diff --git a/src/core/lib/security/transport/security_handshaker.cc b/src/core/lib/security/transport/security_handshaker.cc
index 854a1c4af9..01831dab10 100644
--- a/src/core/lib/security/transport/security_handshaker.cc
+++ b/src/core/lib/security/transport/security_handshaker.cc
@@ -30,6 +30,7 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/handshaker.h"
#include "src/core/lib/channel/handshaker_registry.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/context/security_context.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/security/transport/tsi_error.h"
@@ -38,34 +39,62 @@
#define GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE 256
-typedef struct {
+namespace {
+struct security_handshaker {
+ security_handshaker(tsi_handshaker* handshaker,
+ grpc_security_connector* connector);
+ ~security_handshaker() {
+ gpr_mu_destroy(&mu);
+ tsi_handshaker_destroy(handshaker);
+ tsi_handshaker_result_destroy(handshaker_result);
+ if (endpoint_to_destroy != nullptr) {
+ grpc_endpoint_destroy(endpoint_to_destroy);
+ }
+ if (read_buffer_to_destroy != nullptr) {
+ grpc_slice_buffer_destroy_internal(read_buffer_to_destroy);
+ gpr_free(read_buffer_to_destroy);
+ }
+ gpr_free(handshake_buffer);
+ grpc_slice_buffer_destroy_internal(&outgoing);
+ auth_context.reset(DEBUG_LOCATION, "handshake");
+ connector.reset(DEBUG_LOCATION, "handshake");
+ }
+
+ void Ref() { refs.Ref(); }
+ void Unref() {
+ if (refs.Unref()) {
+ grpc_core::Delete(this);
+ }
+ }
+
grpc_handshaker base;
// State set at creation time.
tsi_handshaker* handshaker;
- grpc_security_connector* connector;
+ grpc_core::RefCountedPtr<grpc_security_connector> connector;
gpr_mu mu;
- gpr_refcount refs;
+ grpc_core::RefCount refs;
- bool shutdown;
+ bool shutdown = false;
// Endpoint and read buffer to destroy after a shutdown.
- grpc_endpoint* endpoint_to_destroy;
- grpc_slice_buffer* read_buffer_to_destroy;
+ grpc_endpoint* endpoint_to_destroy = nullptr;
+ grpc_slice_buffer* read_buffer_to_destroy = nullptr;
// State saved while performing the handshake.
- grpc_handshaker_args* args;
- grpc_closure* on_handshake_done;
+ grpc_handshaker_args* args = nullptr;
+ grpc_closure* on_handshake_done = nullptr;
- unsigned char* handshake_buffer;
size_t handshake_buffer_size;
+ unsigned char* handshake_buffer;
grpc_slice_buffer outgoing;
grpc_closure on_handshake_data_sent_to_peer;
grpc_closure on_handshake_data_received_from_peer;
grpc_closure on_peer_checked;
- grpc_auth_context* auth_context;
- tsi_handshaker_result* handshaker_result;
-} security_handshaker;
+ grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
+ tsi_handshaker_result* handshaker_result = nullptr;
+};
+} // namespace
static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) {
size_t bytes_in_read_buffer = h->args->read_buffer->length;
@@ -85,26 +114,6 @@ static size_t move_read_buffer_into_handshake_buffer(security_handshaker* h) {
return bytes_in_read_buffer;
}
-static void security_handshaker_unref(security_handshaker* h) {
- if (gpr_unref(&h->refs)) {
- gpr_mu_destroy(&h->mu);
- tsi_handshaker_destroy(h->handshaker);
- tsi_handshaker_result_destroy(h->handshaker_result);
- if (h->endpoint_to_destroy != nullptr) {
- grpc_endpoint_destroy(h->endpoint_to_destroy);
- }
- if (h->read_buffer_to_destroy != nullptr) {
- grpc_slice_buffer_destroy_internal(h->read_buffer_to_destroy);
- gpr_free(h->read_buffer_to_destroy);
- }
- gpr_free(h->handshake_buffer);
- grpc_slice_buffer_destroy_internal(&h->outgoing);
- GRPC_AUTH_CONTEXT_UNREF(h->auth_context, "handshake");
- GRPC_SECURITY_CONNECTOR_UNREF(h->connector, "handshake");
- gpr_free(h);
- }
-}
-
// Set args fields to NULL, saving the endpoint and read buffer for
// later destruction.
static void cleanup_args_for_failure_locked(security_handshaker* h) {
@@ -194,7 +203,7 @@ static void on_peer_checked_inner(security_handshaker* h, grpc_error* error) {
tsi_handshaker_result_destroy(h->handshaker_result);
h->handshaker_result = nullptr;
// Add auth context to channel args.
- grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context);
+ grpc_arg auth_context_arg = grpc_auth_context_to_arg(h->auth_context.get());
grpc_channel_args* tmp_args = h->args->args;
h->args->args =
grpc_channel_args_copy_and_add(tmp_args, &auth_context_arg, 1);
@@ -211,7 +220,7 @@ static void on_peer_checked(void* arg, grpc_error* error) {
gpr_mu_lock(&h->mu);
on_peer_checked_inner(h, error);
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
}
static grpc_error* check_peer_locked(security_handshaker* h) {
@@ -222,8 +231,8 @@ static grpc_error* check_peer_locked(security_handshaker* h) {
return grpc_set_tsi_error_result(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("Peer extraction failed"), result);
}
- grpc_security_connector_check_peer(h->connector, peer, &h->auth_context,
- &h->on_peer_checked);
+ h->connector->check_peer(peer, h->args->endpoint, &h->auth_context,
+ &h->on_peer_checked);
return GRPC_ERROR_NONE;
}
@@ -281,7 +290,7 @@ static void on_handshake_next_done_grpc_wrapper(
if (error != GRPC_ERROR_NONE) {
security_handshake_failed_locked(h, error);
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
} else {
gpr_mu_unlock(&h->mu);
}
@@ -317,7 +326,7 @@ static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) {
h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Handshake read failed", &error, 1));
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
return;
}
// Copy all slices received.
@@ -329,7 +338,7 @@ static void on_handshake_data_received_from_peer(void* arg, grpc_error* error) {
if (error != GRPC_ERROR_NONE) {
security_handshake_failed_locked(h, error);
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
} else {
gpr_mu_unlock(&h->mu);
}
@@ -343,7 +352,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) {
h, GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
"Handshake write failed", &error, 1));
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
return;
}
// We may be done.
@@ -355,7 +364,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) {
if (error != GRPC_ERROR_NONE) {
security_handshake_failed_locked(h, error);
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
return;
}
}
@@ -368,7 +377,7 @@ static void on_handshake_data_sent_to_peer(void* arg, grpc_error* error) {
static void security_handshaker_destroy(grpc_handshaker* handshaker) {
security_handshaker* h = reinterpret_cast<security_handshaker*>(handshaker);
- security_handshaker_unref(h);
+ h->Unref();
}
static void security_handshaker_shutdown(grpc_handshaker* handshaker,
@@ -393,14 +402,14 @@ static void security_handshaker_do_handshake(grpc_handshaker* handshaker,
gpr_mu_lock(&h->mu);
h->args = args;
h->on_handshake_done = on_handshake_done;
- gpr_ref(&h->refs);
+ h->Ref();
size_t bytes_received_size = move_read_buffer_into_handshake_buffer(h);
grpc_error* error =
do_handshaker_next_locked(h, h->handshake_buffer, bytes_received_size);
if (error != GRPC_ERROR_NONE) {
security_handshake_failed_locked(h, error);
gpr_mu_unlock(&h->mu);
- security_handshaker_unref(h);
+ h->Unref();
return;
}
gpr_mu_unlock(&h->mu);
@@ -410,27 +419,32 @@ static const grpc_handshaker_vtable security_handshaker_vtable = {
security_handshaker_destroy, security_handshaker_shutdown,
security_handshaker_do_handshake, "security"};
-static grpc_handshaker* security_handshaker_create(
- tsi_handshaker* handshaker, grpc_security_connector* connector) {
- security_handshaker* h = static_cast<security_handshaker*>(
- gpr_zalloc(sizeof(security_handshaker)));
- grpc_handshaker_init(&security_handshaker_vtable, &h->base);
- h->handshaker = handshaker;
- h->connector = GRPC_SECURITY_CONNECTOR_REF(connector, "handshake");
- gpr_mu_init(&h->mu);
- gpr_ref_init(&h->refs, 1);
- h->handshake_buffer_size = GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE;
- h->handshake_buffer =
- static_cast<uint8_t*>(gpr_malloc(h->handshake_buffer_size));
- GRPC_CLOSURE_INIT(&h->on_handshake_data_sent_to_peer,
- on_handshake_data_sent_to_peer, h,
+namespace {
+security_handshaker::security_handshaker(tsi_handshaker* handshaker,
+ grpc_security_connector* connector)
+ : handshaker(handshaker),
+ connector(connector->Ref(DEBUG_LOCATION, "handshake")),
+ handshake_buffer_size(GRPC_INITIAL_HANDSHAKE_BUFFER_SIZE),
+ handshake_buffer(
+ static_cast<uint8_t*>(gpr_malloc(handshake_buffer_size))) {
+ grpc_handshaker_init(&security_handshaker_vtable, &base);
+ gpr_mu_init(&mu);
+ grpc_slice_buffer_init(&outgoing);
+ GRPC_CLOSURE_INIT(&on_handshake_data_sent_to_peer,
+ ::on_handshake_data_sent_to_peer, this,
grpc_schedule_on_exec_ctx);
- GRPC_CLOSURE_INIT(&h->on_handshake_data_received_from_peer,
- on_handshake_data_received_from_peer, h,
+ GRPC_CLOSURE_INIT(&on_handshake_data_received_from_peer,
+ ::on_handshake_data_received_from_peer, this,
grpc_schedule_on_exec_ctx);
- GRPC_CLOSURE_INIT(&h->on_peer_checked, on_peer_checked, h,
+ GRPC_CLOSURE_INIT(&on_peer_checked, ::on_peer_checked, this,
grpc_schedule_on_exec_ctx);
- grpc_slice_buffer_init(&h->outgoing);
+}
+} // namespace
+
+static grpc_handshaker* security_handshaker_create(
+ tsi_handshaker* handshaker, grpc_security_connector* connector) {
+ security_handshaker* h =
+ grpc_core::New<security_handshaker>(handshaker, connector);
return &h->base;
}
@@ -477,8 +491,9 @@ static void client_handshaker_factory_add_handshakers(
grpc_channel_security_connector* security_connector =
reinterpret_cast<grpc_channel_security_connector*>(
grpc_security_connector_find_in_args(args));
- grpc_channel_security_connector_add_handshakers(
- security_connector, interested_parties, handshake_mgr);
+ if (security_connector) {
+ security_connector->add_handshakers(interested_parties, handshake_mgr);
+ }
}
static void server_handshaker_factory_add_handshakers(
@@ -488,8 +503,9 @@ static void server_handshaker_factory_add_handshakers(
grpc_server_security_connector* security_connector =
reinterpret_cast<grpc_server_security_connector*>(
grpc_security_connector_find_in_args(args));
- grpc_server_security_connector_add_handshakers(
- security_connector, interested_parties, handshake_mgr);
+ if (security_connector) {
+ security_connector->add_handshakers(interested_parties, handshake_mgr);
+ }
}
static void handshaker_factory_destroy(
diff --git a/src/core/lib/security/transport/server_auth_filter.cc b/src/core/lib/security/transport/server_auth_filter.cc
index 362f49a584..f93eb4275e 100644
--- a/src/core/lib/security/transport/server_auth_filter.cc
+++ b/src/core/lib/security/transport/server_auth_filter.cc
@@ -39,8 +39,12 @@ enum async_state {
};
struct channel_data {
- grpc_auth_context* auth_context;
- grpc_server_credentials* creds;
+ channel_data(grpc_auth_context* auth_context, grpc_server_credentials* creds)
+ : auth_context(auth_context->Ref()), creds(creds->Ref()) {}
+ ~channel_data() { auth_context.reset(DEBUG_LOCATION, "server_auth_filter"); }
+
+ grpc_core::RefCountedPtr<grpc_auth_context> auth_context;
+ grpc_core::RefCountedPtr<grpc_server_credentials> creds;
};
struct call_data {
@@ -58,7 +62,7 @@ struct call_data {
grpc_server_security_context_create(args.arena);
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
server_ctx->auth_context =
- GRPC_AUTH_CONTEXT_REF(chand->auth_context, "server_auth_filter");
+ chand->auth_context->Ref(DEBUG_LOCATION, "server_auth_filter");
if (args.context[GRPC_CONTEXT_SECURITY].value != nullptr) {
args.context[GRPC_CONTEXT_SECURITY].destroy(
args.context[GRPC_CONTEXT_SECURITY].value);
@@ -208,7 +212,8 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
call_data* calld = static_cast<call_data*>(elem->call_data);
grpc_transport_stream_op_batch* batch = calld->recv_initial_metadata_batch;
if (error == GRPC_ERROR_NONE) {
- if (chand->creds != nullptr && chand->creds->processor.process != nullptr) {
+ if (chand->creds != nullptr &&
+ chand->creds->auth_metadata_processor().process != nullptr) {
// We're calling out to the application, so we need to make sure
// to drop the call combiner early if we get cancelled.
GRPC_CLOSURE_INIT(&calld->cancel_closure, cancel_call, elem,
@@ -218,9 +223,10 @@ static void recv_initial_metadata_ready(void* arg, grpc_error* error) {
GRPC_CALL_STACK_REF(calld->owning_call, "server_auth_metadata");
calld->md = metadata_batch_to_md_array(
batch->payload->recv_initial_metadata.recv_initial_metadata);
- chand->creds->processor.process(
- chand->creds->processor.state, chand->auth_context,
- calld->md.metadata, calld->md.count, on_md_processing_done, elem);
+ chand->creds->auth_metadata_processor().process(
+ chand->creds->auth_metadata_processor().state,
+ chand->auth_context.get(), calld->md.metadata, calld->md.count,
+ on_md_processing_done, elem);
return;
}
}
@@ -290,23 +296,19 @@ static void destroy_call_elem(grpc_call_element* elem,
static grpc_error* init_channel_elem(grpc_channel_element* elem,
grpc_channel_element_args* args) {
GPR_ASSERT(!args->is_last);
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
grpc_auth_context* auth_context =
grpc_find_auth_context_in_args(args->channel_args);
GPR_ASSERT(auth_context != nullptr);
- chand->auth_context =
- GRPC_AUTH_CONTEXT_REF(auth_context, "server_auth_filter");
grpc_server_credentials* creds =
grpc_find_server_credentials_in_args(args->channel_args);
- chand->creds = grpc_server_credentials_ref(creds);
+ new (elem->channel_data) channel_data(auth_context, creds);
return GRPC_ERROR_NONE;
}
/* Destructor for channel data */
static void destroy_channel_elem(grpc_channel_element* elem) {
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "server_auth_filter");
- grpc_server_credentials_unref(chand->creds);
+ chand->~channel_data();
}
const grpc_channel_filter grpc_server_auth_filter = {
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index c6198b8ae7..67cf5d89bf 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -161,6 +161,7 @@ void grpc_shutdown(void) {
if (--g_initializations == 0) {
{
grpc_core::ExecCtx exec_ctx(0);
+ grpc_iomgr_shutdown_background_closure();
{
grpc_timer_manager_set_threading(
false); // shutdown timer_manager thread
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index 5dc81b29bb..67b38e6f0c 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -28,6 +28,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include <utility>
+
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/debug/stats.h"
@@ -109,7 +111,7 @@ struct channel_data {
uint32_t registered_method_max_probes;
grpc_closure finish_destroy_channel_closure;
grpc_closure channel_connectivity_changed;
- intptr_t socket_uuid;
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node;
};
typedef struct shutdown_tag {
@@ -192,10 +194,13 @@ struct call_data {
};
struct request_matcher {
+ request_matcher(grpc_server* server);
+ ~request_matcher();
+
grpc_server* server;
- call_data* pending_head;
- call_data* pending_tail;
- gpr_locked_mpscq* requests_per_cq;
+ std::atomic<call_data*> pending_head{nullptr};
+ call_data* pending_tail = nullptr;
+ gpr_locked_mpscq* requests_per_cq = nullptr;
};
struct registered_method {
@@ -344,22 +349,30 @@ static void channel_broadcaster_shutdown(channel_broadcaster* cb,
* request_matcher
*/
-static void request_matcher_init(request_matcher* rm, grpc_server* server) {
- memset(rm, 0, sizeof(*rm));
- rm->server = server;
- rm->requests_per_cq = static_cast<gpr_locked_mpscq*>(
- gpr_malloc(sizeof(*rm->requests_per_cq) * server->cq_count));
+namespace {
+request_matcher::request_matcher(grpc_server* server) : server(server) {
+ requests_per_cq = static_cast<gpr_locked_mpscq*>(
+ gpr_malloc(sizeof(*requests_per_cq) * server->cq_count));
for (size_t i = 0; i < server->cq_count; i++) {
- gpr_locked_mpscq_init(&rm->requests_per_cq[i]);
+ gpr_locked_mpscq_init(&requests_per_cq[i]);
}
}
-static void request_matcher_destroy(request_matcher* rm) {
- for (size_t i = 0; i < rm->server->cq_count; i++) {
- GPR_ASSERT(gpr_locked_mpscq_pop(&rm->requests_per_cq[i]) == nullptr);
- gpr_locked_mpscq_destroy(&rm->requests_per_cq[i]);
+request_matcher::~request_matcher() {
+ for (size_t i = 0; i < server->cq_count; i++) {
+ GPR_ASSERT(gpr_locked_mpscq_pop(&requests_per_cq[i]) == nullptr);
+ gpr_locked_mpscq_destroy(&requests_per_cq[i]);
}
- gpr_free(rm->requests_per_cq);
+ gpr_free(requests_per_cq);
+}
+} // namespace
+
+static void request_matcher_init(request_matcher* rm, grpc_server* server) {
+ new (rm) request_matcher(server);
+}
+
+static void request_matcher_destroy(request_matcher* rm) {
+ rm->~request_matcher();
}
static void kill_zombie(void* elem, grpc_error* error) {
@@ -368,9 +381,10 @@ static void kill_zombie(void* elem, grpc_error* error) {
}
static void request_matcher_zombify_all_pending_calls(request_matcher* rm) {
- while (rm->pending_head) {
- call_data* calld = rm->pending_head;
- rm->pending_head = calld->pending_next;
+ call_data* calld;
+ while ((calld = rm->pending_head.load(std::memory_order_relaxed)) !=
+ nullptr) {
+ rm->pending_head.store(calld->pending_next, std::memory_order_relaxed);
gpr_atm_no_barrier_store(&calld->state, ZOMBIED);
GRPC_CLOSURE_INIT(
&calld->kill_zombie_closure, kill_zombie,
@@ -568,8 +582,9 @@ static void publish_new_rpc(void* arg, grpc_error* error) {
}
gpr_atm_no_barrier_store(&calld->state, PENDING);
- if (rm->pending_head == nullptr) {
- rm->pending_tail = rm->pending_head = calld;
+ if (rm->pending_head.load(std::memory_order_relaxed) == nullptr) {
+ rm->pending_head.store(calld, std::memory_order_relaxed);
+ rm->pending_tail = calld;
} else {
rm->pending_tail->pending_next = calld;
rm->pending_tail = calld;
@@ -937,6 +952,7 @@ static grpc_error* init_channel_elem(grpc_channel_element* elem,
static void destroy_channel_elem(grpc_channel_element* elem) {
size_t i;
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
+ chand->socket_node.reset();
if (chand->registered_methods) {
for (i = 0; i < chand->registered_method_slots; i++) {
grpc_slice_unref_internal(chand->registered_methods[i].method);
@@ -1142,11 +1158,11 @@ void grpc_server_get_pollsets(grpc_server* server, grpc_pollset*** pollsets,
*pollsets = server->pollsets;
}
-void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
- grpc_pollset* accepting_pollset,
- const grpc_channel_args* args,
- intptr_t socket_uuid,
- grpc_resource_user* resource_user) {
+void grpc_server_setup_transport(
+ grpc_server* s, grpc_transport* transport, grpc_pollset* accepting_pollset,
+ const grpc_channel_args* args,
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node,
+ grpc_resource_user* resource_user) {
size_t num_registered_methods;
size_t alloc;
registered_method* rm;
@@ -1167,7 +1183,7 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
chand->server = s;
server_ref(s);
chand->channel = channel;
- chand->socket_uuid = socket_uuid;
+ chand->socket_node = std::move(socket_node);
size_t cq_idx;
for (cq_idx = 0; cq_idx < s->cq_count; cq_idx++) {
@@ -1243,14 +1259,13 @@ void grpc_server_setup_transport(grpc_server* s, grpc_transport* transport,
}
void grpc_server_populate_server_sockets(
- grpc_server* s, grpc_core::channelz::ChildRefsList* server_sockets,
+ grpc_server* s, grpc_core::channelz::ChildSocketsList* server_sockets,
intptr_t start_idx) {
gpr_mu_lock(&s->mu_global);
channel_data* c = nullptr;
for (c = s->root_channel_data.next; c != &s->root_channel_data; c = c->next) {
- intptr_t socket_uuid = c->socket_uuid;
- if (socket_uuid >= start_idx) {
- server_sockets->push_back(socket_uuid);
+ if (c->socket_node != nullptr && c->socket_node->uuid() >= start_idx) {
+ server_sockets->push_back(c->socket_node.get());
}
}
gpr_mu_unlock(&s->mu_global);
@@ -1433,30 +1448,39 @@ static grpc_call_error queue_call_request(grpc_server* server, size_t cq_idx,
rm = &rc->data.registered.method->matcher;
break;
}
- if (gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link)) {
- /* this was the first queued request: we need to lock and start
- matching calls */
- gpr_mu_lock(&server->mu_call);
- while ((calld = rm->pending_head) != nullptr) {
- rc = reinterpret_cast<requested_call*>(
- gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx]));
- if (rc == nullptr) break;
- rm->pending_head = calld->pending_next;
- gpr_mu_unlock(&server->mu_call);
- if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) {
- // Zombied Call
- GRPC_CLOSURE_INIT(
- &calld->kill_zombie_closure, kill_zombie,
- grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
- grpc_schedule_on_exec_ctx);
- GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE);
- } else {
- publish_call(server, calld, cq_idx, rc);
- }
- gpr_mu_lock(&server->mu_call);
- }
+
+ // Fast path: if there is no pending request to be processed, immediately
+ // return.
+ if (!gpr_locked_mpscq_push(&rm->requests_per_cq[cq_idx], &rc->request_link) ||
+ // Note: We are reading the pending_head without holding the server's call
+ // mutex. Even if we read a non-null value here due to reordering,
+ // we will check it below again after grabbing the lock.
+ rm->pending_head.load(std::memory_order_relaxed) == nullptr) {
+ return GRPC_CALL_OK;
+ }
+ // Slow path: This was the first queued request and there are pendings:
+ // We need to lock and start matching calls.
+ gpr_mu_lock(&server->mu_call);
+ while ((calld = rm->pending_head.load(std::memory_order_relaxed)) !=
+ nullptr) {
+ rc = reinterpret_cast<requested_call*>(
+ gpr_locked_mpscq_pop(&rm->requests_per_cq[cq_idx]));
+ if (rc == nullptr) break;
+ rm->pending_head.store(calld->pending_next, std::memory_order_relaxed);
gpr_mu_unlock(&server->mu_call);
+ if (!gpr_atm_full_cas(&calld->state, PENDING, ACTIVATED)) {
+ // Zombied Call
+ GRPC_CLOSURE_INIT(
+ &calld->kill_zombie_closure, kill_zombie,
+ grpc_call_stack_element(grpc_call_get_call_stack(calld->call), 0),
+ grpc_schedule_on_exec_ctx);
+ GRPC_CLOSURE_SCHED(&calld->kill_zombie_closure, GRPC_ERROR_NONE);
+ } else {
+ publish_call(server, calld, cq_idx, rc);
+ }
+ gpr_mu_lock(&server->mu_call);
}
+ gpr_mu_unlock(&server->mu_call);
return GRPC_CALL_OK;
}
diff --git a/src/core/lib/surface/server.h b/src/core/lib/surface/server.h
index 27038fdb7a..393bb24214 100644
--- a/src/core/lib/surface/server.h
+++ b/src/core/lib/surface/server.h
@@ -44,15 +44,15 @@ void grpc_server_add_listener(grpc_server* server, void* listener,
/* Setup a transport - creates a channel stack, binds the transport to the
server */
-void grpc_server_setup_transport(grpc_server* server, grpc_transport* transport,
- grpc_pollset* accepting_pollset,
- const grpc_channel_args* args,
- intptr_t socket_uuid,
- grpc_resource_user* resource_user = nullptr);
+void grpc_server_setup_transport(
+ grpc_server* server, grpc_transport* transport,
+ grpc_pollset* accepting_pollset, const grpc_channel_args* args,
+ grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> socket_node,
+ grpc_resource_user* resource_user = nullptr);
/* fills in the uuids of all sockets used for connections on this server */
void grpc_server_populate_server_sockets(
- grpc_server* server, grpc_core::channelz::ChildRefsList* server_sockets,
+ grpc_server* server, grpc_core::channelz::ChildSocketsList* server_sockets,
intptr_t start_idx);
/* fills in the uuids of all listen sockets on this server */
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index 66890ce65a..4829cc80a5 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -25,4 +25,4 @@
const char* grpc_version_string(void) { return "7.0.0-dev"; }
-const char* grpc_g_stands_for(void) { return "gizmo"; }
+const char* grpc_g_stands_for(void) { return "goose"; }
diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc
index 4ebe73f82a..3dfaaaad5c 100644
--- a/src/core/lib/transport/static_metadata.cc
+++ b/src/core/lib/transport/static_metadata.cc
@@ -65,51 +65,56 @@ static uint8_t g_bytes[] = {
97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111,
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};
+ 47, 101, 110, 118, 111, 121, 46, 115, 101, 114, 118, 105, 99, 101, 46,
+ 100, 105, 115, 99, 111, 118, 101, 114, 121, 46, 118, 50, 46, 65, 103,
+ 103, 114, 101, 103, 97, 116, 101, 100, 68, 105, 115, 99, 111, 118, 101,
+ 114, 121, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116, 114, 101, 97,
+ 109, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 82, 101, 115, 111,
+ 117, 114, 99, 101, 115, 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) {}
@@ -227,6 +232,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] = {
@@ -266,76 +272,77 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
{&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, 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}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 80}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 601, 11}}},
+ {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}},
+ {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}},
+ {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}},
+ {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}},
+ {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}},
+ {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}},
+ {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}},
+ {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}},
+ {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}},
+ {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}},
+ {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}},
+ {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}},
+ {&grpc_static_metadata_refcounts[52], {{g_bytes + 658, 3}}},
+ {&grpc_static_metadata_refcounts[53], {{g_bytes + 661, 14}}},
+ {&grpc_static_metadata_refcounts[54], {{g_bytes + 675, 13}}},
+ {&grpc_static_metadata_refcounts[55], {{g_bytes + 688, 15}}},
+ {&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}},
+ {&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}},
+ {&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}},
+ {&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}},
+ {&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}},
+ {&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}},
+ {&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}},
+ {&grpc_static_metadata_refcounts[63], {{g_bytes + 783, 19}}},
+ {&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}},
+ {&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}},
+ {&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}},
+ {&grpc_static_metadata_refcounts[67], {{g_bytes + 848, 13}}},
+ {&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}},
+ {&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}},
+ {&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}},
+ {&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}},
+ {&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}},
+ {&grpc_static_metadata_refcounts[73], {{g_bytes + 888, 4}}},
+ {&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}},
+ {&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}},
+ {&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}},
+ {&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}},
+ {&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}},
+ {&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}},
+ {&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}},
+ {&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}},
+ {&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}},
+ {&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}},
+ {&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}},
+ {&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}},
+ {&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}},
+ {&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}},
+ {&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}},
+ {&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}},
+ {&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}},
+ {&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}},
+ {&grpc_static_metadata_refcounts[92], {{g_bytes + 1102, 17}}},
+ {&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}},
+ {&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}},
+ {&grpc_static_metadata_refcounts[95], {{g_bytes + 1126, 16}}},
+ {&grpc_static_metadata_refcounts[96], {{g_bytes + 1142, 1}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}},
+ {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}},
+ {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}},
+ {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}},
+ {&grpc_static_metadata_refcounts[101], {{g_bytes + 1179, 3}}},
+ {&grpc_static_metadata_refcounts[102], {{g_bytes + 1182, 11}}},
+ {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}},
+ {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}},
+ {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}},
};
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
@@ -345,17 +352,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[] = {
- 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};
+ 15, 10, -8, 0, 2, -42, -81, -43, 0, 6, -8, 0, 0, 0, 2,
+ -3, -10, 0, 0, 1, 0, -1, 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, -64, 0, -67, -68, -69, -70, 0,
+ 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+ 5, 4, 5, 4, 4, 8, 8, 0, 0, 0, 0, 0, 0, -5, 0};
static uint32_t elems_phash(uint32_t i) {
- i -= 41;
- uint32_t x = i % 104;
- uint32_t y = i / 104;
+ i -= 42;
+ uint32_t x = i % 105;
+ uint32_t y = i / 105;
uint32_t h = x;
if (y < GPR_ARRAY_SIZE(elems_r)) {
uint32_t delta = (uint32_t)elems_r[y];
@@ -365,29 +372,29 @@ static uint32_t elems_phash(uint32_t i) {
}
static const uint16_t elem_keys[] = {
- 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};
+ 260, 261, 262, 263, 264, 265, 266, 1107, 1108, 1741, 147, 148,
+ 472, 473, 1634, 42, 43, 1527, 1750, 1000, 1001, 774, 775, 1643,
+ 633, 845, 2062, 2169, 2276, 5700, 5914, 6021, 6128, 6235, 1766, 6342,
+ 6449, 6556, 6663, 6770, 6877, 6984, 7091, 7198, 7305, 7412, 7519, 7626,
+ 7733, 7840, 7947, 8054, 8161, 8268, 8375, 8482, 8589, 8696, 8803, 8910,
+ 9017, 9124, 9231, 9338, 9445, 9552, 9659, 1167, 528, 9766, 9873, 208,
+ 9980, 1173, 1174, 1175, 1176, 1809, 10087, 1060, 10194, 10943, 1702, 0,
+ 1816, 0, 0, 1597, 0, 0, 350, 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, 0, 0, 0};
static const uint8_t elem_idxs[] = {
- 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};
+ 7, 8, 9, 10, 11, 12, 13, 77, 79, 71, 1, 2, 5, 6, 25, 3,
+ 4, 30, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 16, 17,
+ 18, 19, 15, 20, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34,
+ 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 76, 69, 55, 56, 70, 58, 78, 80, 81, 82, 83, 59, 64,
+ 60, 75, 72, 255, 85, 255, 255, 68, 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 * 106 + b);
+ uint32_t k = (uint32_t)(a * 107 + b);
uint32_t h = elems_phash(k);
return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
elem_idxs[h] != 255
@@ -400,175 +407,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[39], {{g_bytes + 532, 3}}}},
+ {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}},
+ {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
- {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}},
+ {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
- {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}},
+ {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}},
+ {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}},
+ {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}},
+ {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}},
+ {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}},
+ {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}},
+ {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}},
+ {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}},
+ {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}},
- {{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}},
+ {&grpc_static_metadata_refcounts[52], {{g_bytes + 658, 3}}}},
+ {{&grpc_static_metadata_refcounts[53], {{g_bytes + 661, 14}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}},
- {{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}},
+ {&grpc_static_metadata_refcounts[54], {{g_bytes + 675, 13}}}},
+ {{&grpc_static_metadata_refcounts[55], {{g_bytes + 688, 15}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}},
+ {{&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}},
+ {{&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}},
+ {{&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}},
+ {{&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}},
+ {{&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}},
+ {{&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}},
+ {{&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}},
+ {{&grpc_static_metadata_refcounts[63], {{g_bytes + 783, 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[63], {{g_bytes + 722, 16}}},
+ {{&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}},
+ {{&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}},
+ {{&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}},
+ {{&grpc_static_metadata_refcounts[67], {{g_bytes + 848, 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[67], {{g_bytes + 781, 6}}},
+ {{&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}},
+ {{&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}},
+ {{&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}},
+ {{&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}},
+ {{&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}},
+ {{&grpc_static_metadata_refcounts[73], {{g_bytes + 888, 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[73], {{g_bytes + 812, 8}}},
+ {{&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}},
+ {{&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}},
+ {{&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}},
+ {{&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}},
+ {{&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}},
+ {{&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}},
+ {{&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}},
+ {{&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}},
+ {{&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}},
+ {{&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}},
+ {{&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}},
+ {{&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}},
+ {{&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}},
+ {{&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}},
+ {{&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}},
+ {{&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}},
+ {{&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}},
+ {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}},
+ {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1102, 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[92], {{g_bytes + 1039, 4}}},
+ {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}},
+ {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}},
+ {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1126, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
- {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}},
+ {&grpc_static_metadata_refcounts[96], {{g_bytes + 1142, 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[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}},
{{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}},
- {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}},
+ {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
- {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}},
+ {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}},
+ {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}},
+ {&grpc_static_metadata_refcounts[101], {{g_bytes + 1179, 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[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}},
+ {{&grpc_static_metadata_refcounts[102], {{g_bytes + 1182, 11}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}},
+ {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}},
+ {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}},
+ {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 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 2bb9f72838..4f9670232c 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 106
+#define GRPC_STATIC_MDSTR_COUNT 107
extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* ":path" */
#define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -110,147 +110,151 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* "/grpc.health.v1.Health/Watch" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \
(grpc_static_slice_table[35])
+/* "/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources"
+ */
+#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES \
+ (grpc_static_slice_table[36])
/* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[37])
/* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[38])
/* "stream/gzip" */
-#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38])
+#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[39])
/* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[39])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[40])
/* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[40])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[41])
/* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42])
/* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43])
/* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[44])
/* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[45])
/* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[45])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[46])
/* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[46])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[47])
/* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[47])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[48])
/* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[48])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[49])
/* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[49])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[50])
/* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[50])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[51])
/* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[51])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[52])
/* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53])
/* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54])
/* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55])
/* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56])
/* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57])
/* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58])
/* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[58])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[59])
/* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60])
/* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61])
/* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62])
/* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63])
/* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64])
/* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65])
/* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66])
/* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67])
/* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68])
/* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[68])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[69])
/* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70])
/* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71])
/* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72])
/* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[72])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[73])
/* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74])
/* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75])
/* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76])
/* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77])
/* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78])
/* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79])
/* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[79])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[80])
/* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[81])
/* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[82])
/* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[83])
/* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[84])
/* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[85])
/* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[86])
/* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[87])
/* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[88])
/* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[89])
/* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[90])
/* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[91])
/* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92])
/* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[92])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[93])
/* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[93])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[94])
/* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[95])
/* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[95])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[96])
/* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[97])
/* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[98])
/* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[99])
/* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[100])
/* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[100])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[101])
/* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101])
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[102])
/* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[103])
/* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[104])
/* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[105])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (grpc_static_slice_table[105])
+ (grpc_static_slice_table[106])
extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
extern grpc_slice_refcount
diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc
index cbdb77c844..b32f9c6ec1 100644
--- a/src/core/lib/transport/transport.cc
+++ b/src/core/lib/transport/transport.cc
@@ -27,6 +27,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -149,7 +150,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from,
}
size_t grpc_transport_stream_size(grpc_transport* transport) {
- return transport->vtable->sizeof_stream;
+ return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream);
}
void grpc_transport_destroy(grpc_transport* transport) {
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index edfa7030d1..5ce568834e 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -129,7 +129,8 @@ struct grpc_transport_stream_op_batch {
recv_initial_metadata(false),
recv_message(false),
recv_trailing_metadata(false),
- cancel_stream(false) {}
+ cancel_stream(false),
+ is_traced(false) {}
/** Should be scheduled when all of the non-recv operations in the batch
are complete.
@@ -167,6 +168,9 @@ struct grpc_transport_stream_op_batch {
/** Cancel this stream with the provided error */
bool cancel_stream : 1;
+ /** Is this stream traced */
+ bool is_traced : 1;
+
/***************************************************************************
* remaining fields are initialized and used at the discretion of the
* current handler of the op */
diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
index 1de6264183..43d0979f4b 100644
--- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
+++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
@@ -116,12 +116,13 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c,
"cb is nullptr in alts_tsi_handshaker_handle_response()");
return;
}
- if (handshaker == nullptr || recv_buffer == nullptr) {
+ if (handshaker == nullptr) {
gpr_log(GPR_ERROR,
- "Invalid arguments to alts_tsi_handshaker_handle_response()");
+ "handshaker is nullptr in alts_tsi_handshaker_handle_response()");
cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
return;
}
+ /* TSI handshake has been shutdown. */
if (alts_tsi_handshaker_has_shutdown(handshaker)) {
gpr_log(GPR_ERROR, "TSI handshake shutdown");
cb(TSI_HANDSHAKE_SHUTDOWN, user_data, nullptr, 0, nullptr);
@@ -133,6 +134,12 @@ void alts_handshaker_client_handle_response(alts_handshaker_client* c,
cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
return;
}
+ if (recv_buffer == nullptr) {
+ gpr_log(GPR_ERROR,
+ "recv_buffer is nullptr in alts_tsi_handshaker_handle_response()");
+ cb(TSI_INTERNAL_ERROR, user_data, nullptr, 0, nullptr);
+ return;
+ }
grpc_gcp_handshaker_resp* resp =
alts_tsi_utils_deserialize_response(recv_buffer);
grpc_byte_buffer_destroy(client->recv_buffer);
diff --git a/src/core/tsi/ssl_transport_security.cc b/src/core/tsi/ssl_transport_security.cc
index d6a72ada0d..efaf733503 100644
--- a/src/core/tsi/ssl_transport_security.cc
+++ b/src/core/tsi/ssl_transport_security.cc
@@ -1850,31 +1850,30 @@ tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
break;
}
SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names);
- switch (options->client_certificate_request) {
- case TSI_DONT_REQUEST_CLIENT_CERTIFICATE:
- SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr);
- break;
- case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
- SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER,
- NullVerifyCallback);
- break;
- case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
- SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr);
- break;
- case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
- SSL_CTX_set_verify(
- impl->ssl_contexts[i],
- SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- NullVerifyCallback);
- break;
- case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
- SSL_CTX_set_verify(
- impl->ssl_contexts[i],
- SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
- break;
- }
- /* TODO(jboeuf): Add revocation verification. */
}
+ switch (options->client_certificate_request) {
+ case TSI_DONT_REQUEST_CLIENT_CERTIFICATE:
+ SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_NONE, nullptr);
+ break;
+ case TSI_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER,
+ NullVerifyCallback);
+ break;
+ case TSI_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY:
+ SSL_CTX_set_verify(impl->ssl_contexts[i], SSL_VERIFY_PEER, nullptr);
+ break;
+ case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY:
+ SSL_CTX_set_verify(impl->ssl_contexts[i],
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ NullVerifyCallback);
+ break;
+ case TSI_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY:
+ SSL_CTX_set_verify(impl->ssl_contexts[i],
+ SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ nullptr);
+ break;
+ }
+ /* TODO(jboeuf): Add revocation verification. */
result = extract_x509_subject_names_from_pem_cert(
options->pem_key_cert_pairs[i].cert_chain,
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index 8e1cea0269..a31d0b30b1 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -54,13 +54,11 @@ namespace grpc {
static internal::GrpcLibraryInitializer g_gli_initializer;
Channel::Channel(
const grpc::string& host, grpc_channel* channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators)
: host_(host), c_channel_(channel) {
- if (interceptor_creators != nullptr) {
- interceptor_creators_ = std::move(*interceptor_creators);
- }
+ interceptor_creators_ = std::move(interceptor_creators);
g_gli_initializer.summon();
}
@@ -151,8 +149,9 @@ internal::Call Channel::CreateCallInternal(const internal::RpcMethod& method,
// ClientRpcInfo should be set before call because set_call also checks
// whether the call has been cancelled, and if the call was cancelled, we
// should notify the interceptors too/
- auto* info = context->set_client_rpc_info(
- method.name(), this, interceptor_creators_, interceptor_pos);
+ auto* info =
+ context->set_client_rpc_info(method.name(), method.method_type(), this,
+ interceptor_creators_, interceptor_pos);
context->set_call(c_call, shared_from_this());
return internal::Call(c_call, this, cq, info);
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 50da75f09c..c9ea3e5f83 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -41,9 +41,10 @@ class DefaultGlobalClientCallbacks final
};
static internal::GrpcLibraryInitializer g_gli_initializer;
-static DefaultGlobalClientCallbacks g_default_client_callbacks;
+static DefaultGlobalClientCallbacks* g_default_client_callbacks =
+ new DefaultGlobalClientCallbacks();
static ClientContext::GlobalCallbacks* g_client_callbacks =
- &g_default_client_callbacks;
+ g_default_client_callbacks;
ClientContext::ClientContext()
: initial_metadata_received_(false),
@@ -139,9 +140,9 @@ grpc::string ClientContext::peer() const {
}
void ClientContext::SetGlobalCallbacks(GlobalCallbacks* client_callbacks) {
- GPR_ASSERT(g_client_callbacks == &g_default_client_callbacks);
+ GPR_ASSERT(g_client_callbacks == g_default_client_callbacks);
GPR_ASSERT(client_callbacks != nullptr);
- GPR_ASSERT(client_callbacks != &g_default_client_callbacks);
+ GPR_ASSERT(client_callbacks != g_default_client_callbacks);
g_client_callbacks = client_callbacks;
}
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index efdff6c265..457daa674c 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -39,13 +39,14 @@ std::shared_ptr<Channel> CreateCustomChannel(
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args) {
GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds.
- return creds
- ? creds->CreateChannel(target, args)
- : CreateChannelInternal("",
- grpc_lame_client_channel_create(
- nullptr, GRPC_STATUS_INVALID_ARGUMENT,
- "Invalid credentials."),
- nullptr);
+ return creds ? creds->CreateChannel(target, args)
+ : CreateChannelInternal(
+ "",
+ grpc_lame_client_channel_create(
+ nullptr, GRPC_STATUS_INVALID_ARGUMENT,
+ "Invalid credentials."),
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
namespace experimental {
@@ -64,17 +65,18 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
- return creds
- ? creds->CreateChannelWithInterceptors(
- target, args, std::move(interceptor_creators))
- : CreateChannelInternal("",
- grpc_lame_client_channel_create(
- nullptr, GRPC_STATUS_INVALID_ARGUMENT,
- "Invalid credentials."),
- nullptr);
+ return creds ? creds->CreateChannelWithInterceptors(
+ target, args, std::move(interceptor_creators))
+ : CreateChannelInternal(
+ "",
+ grpc_lame_client_channel_create(
+ nullptr, GRPC_STATUS_INVALID_ARGUMENT,
+ "Invalid credentials."),
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
} // namespace experimental
diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc
index 313d682aae..a0efb97f7e 100644
--- a/src/cpp/client/create_channel_internal.cc
+++ b/src/cpp/client/create_channel_internal.cc
@@ -26,8 +26,8 @@ namespace grpc {
std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return std::shared_ptr<Channel>(
new Channel(host, c_channel, std::move(interceptor_creators)));
diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h
index 512fc22866..a90c92c518 100644
--- a/src/cpp/client/create_channel_internal.h
+++ b/src/cpp/client/create_channel_internal.h
@@ -31,8 +31,8 @@ class Channel;
std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace grpc
diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc
index 8d775e7a87..3affc1ef39 100644
--- a/src/cpp/client/create_channel_posix.cc
+++ b/src/cpp/client/create_channel_posix.cc
@@ -34,7 +34,8 @@ std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
init_lib.init();
return CreateChannelInternal(
"", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr),
- nullptr);
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
@@ -46,15 +47,16 @@ std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
return CreateChannelInternal(
"",
grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args),
- nullptr);
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
namespace experimental {
std::shared_ptr<Channel> CreateCustomInsecureChannelWithInterceptorsFromFd(
const grpc::string& target, int fd, const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
internal::GrpcLibrary init_lib;
init_lib.init();
diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc
index 09a76b428c..b2801764f2 100644
--- a/src/cpp/client/cronet_credentials.cc
+++ b/src/cpp/client/cronet_credentials.cc
@@ -31,7 +31,10 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials {
std::shared_ptr<grpc::Channel> CreateChannel(
const string& target, const grpc::ChannelArguments& args) override {
- return CreateChannelWithInterceptors(target, args, nullptr);
+ return CreateChannelWithInterceptors(
+ target, args,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
SecureChannelCredentials* AsSecureCredentials() override { return nullptr; }
@@ -39,8 +42,8 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials {
private:
std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) override {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
diff --git a/src/cpp/client/generic_stub.cc b/src/cpp/client/generic_stub.cc
index 87902b26f0..f61c1b5317 100644
--- a/src/cpp/client/generic_stub.cc
+++ b/src/cpp/client/generic_stub.cc
@@ -72,4 +72,13 @@ void GenericStub::experimental_type::UnaryCall(
context, request, response, std::move(on_completion));
}
+void GenericStub::experimental_type::PrepareBidiStreamingCall(
+ ClientContext* context, const grpc::string& method,
+ experimental::ClientBidiReactor<ByteBuffer, ByteBuffer>* reactor) {
+ internal::ClientCallbackReaderWriterFactory<ByteBuffer, ByteBuffer>::Create(
+ stub_->channel_.get(),
+ internal::RpcMethod(method.c_str(), internal::RpcMethod::BIDI_STREAMING),
+ context, reactor);
+}
+
} // namespace grpc
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index b816e0c59a..241ce91803 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -32,13 +32,16 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials {
public:
std::shared_ptr<grpc::Channel> CreateChannel(
const string& target, const grpc::ChannelArguments& args) override {
- return CreateChannelWithInterceptors(target, args, nullptr);
+ return CreateChannelWithInterceptors(
+ target, args,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) override {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 7faaa20e78..4d0ed355ab 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -36,14 +36,17 @@ SecureChannelCredentials::SecureChannelCredentials(
std::shared_ptr<grpc::Channel> SecureChannelCredentials::CreateChannel(
const string& target, const grpc::ChannelArguments& args) {
- return CreateChannelWithInterceptors(target, args, nullptr);
+ return CreateChannelWithInterceptors(
+ target, args,
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<grpc::Channel>
SecureChannelCredentials::CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
@@ -258,10 +261,10 @@ void MetadataCredentialsPluginWrapper::InvokePlugin(
grpc_status_code* status_code, const char** error_details) {
std::multimap<grpc::string, grpc::string> metadata;
- // const_cast is safe since the SecureAuthContext does not take owndership and
- // the object is passed as a const ref to plugin_->GetMetadata.
+ // const_cast is safe since the SecureAuthContext only inc/dec the refcount
+ // and the object is passed as a const ref to plugin_->GetMetadata.
SecureAuthContext cpp_channel_auth_context(
- const_cast<grpc_auth_context*>(context.channel_auth_context), false);
+ const_cast<grpc_auth_context*>(context.channel_auth_context));
Status status = plugin_->GetMetadata(context.service_url, context.method_name,
cpp_channel_auth_context, &metadata);
diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h
index bfb6e17ee9..4918bd5a4d 100644
--- a/src/cpp/client/secure_credentials.h
+++ b/src/cpp/client/secure_credentials.h
@@ -24,6 +24,7 @@
#include <grpcpp/security/credentials.h>
#include <grpcpp/support/config.h>
+#include "src/core/lib/security/credentials/credentials.h"
#include "src/cpp/server/thread_pool_interface.h"
namespace grpc {
@@ -31,7 +32,9 @@ namespace grpc {
class SecureChannelCredentials final : public ChannelCredentials {
public:
explicit SecureChannelCredentials(grpc_channel_credentials* c_creds);
- ~SecureChannelCredentials() { grpc_channel_credentials_release(c_creds_); }
+ ~SecureChannelCredentials() {
+ if (c_creds_ != nullptr) c_creds_->Unref();
+ }
grpc_channel_credentials* GetRawCreds() { return c_creds_; }
std::shared_ptr<grpc::Channel> CreateChannel(
@@ -42,8 +45,8 @@ class SecureChannelCredentials final : public ChannelCredentials {
private:
std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) override;
grpc_channel_credentials* const c_creds_;
};
@@ -51,7 +54,9 @@ class SecureChannelCredentials final : public ChannelCredentials {
class SecureCallCredentials final : public CallCredentials {
public:
explicit SecureCallCredentials(grpc_call_credentials* c_creds);
- ~SecureCallCredentials() { grpc_call_credentials_release(c_creds_); }
+ ~SecureCallCredentials() {
+ if (c_creds_ != nullptr) c_creds_->Unref();
+ }
grpc_call_credentials* GetRawCreds() { return c_creds_; }
bool ApplyToCall(grpc_call* call) override;
diff --git a/src/cpp/common/alarm.cc b/src/cpp/common/alarm.cc
index 5819a4210b..148f0b9bc9 100644
--- a/src/cpp/common/alarm.cc
+++ b/src/cpp/common/alarm.cc
@@ -31,10 +31,10 @@
#include <grpc/support/log.h>
#include "src/core/lib/debug/trace.h"
-namespace grpc {
+namespace grpc_impl {
namespace internal {
-class AlarmImpl : public CompletionQueueTag {
+class AlarmImpl : public ::grpc::internal::CompletionQueueTag {
public:
AlarmImpl() : cq_(nullptr), tag_(nullptr) {
gpr_ref_init(&refs_, 1);
@@ -51,7 +51,7 @@ class AlarmImpl : public CompletionQueueTag {
Unref();
return true;
}
- void Set(CompletionQueue* cq, gpr_timespec deadline, void* tag) {
+ void Set(::grpc::CompletionQueue* cq, gpr_timespec deadline, void* tag) {
grpc_core::ExecCtx exec_ctx;
GRPC_CQ_INTERNAL_REF(cq->cq(), "alarm");
cq_ = cq->cq();
@@ -114,13 +114,14 @@ class AlarmImpl : public CompletionQueueTag {
};
} // namespace internal
-static internal::GrpcLibraryInitializer g_gli_initializer;
+static ::grpc::internal::GrpcLibraryInitializer g_gli_initializer;
Alarm::Alarm() : alarm_(new internal::AlarmImpl()) {
g_gli_initializer.summon();
}
-void Alarm::SetInternal(CompletionQueue* cq, gpr_timespec deadline, void* tag) {
+void Alarm::SetInternal(::grpc::CompletionQueue* cq, gpr_timespec deadline,
+ void* tag) {
// Note that we know that alarm_ is actually an internal::AlarmImpl
// but we declared it as the base pointer to avoid a forward declaration
// or exposing core data structures in the C++ public headers.
@@ -145,4 +146,4 @@ Alarm::~Alarm() {
}
void Alarm::Cancel() { static_cast<internal::AlarmImpl*>(alarm_)->Cancel(); }
-} // namespace grpc
+} // namespace grpc_impl
diff --git a/src/cpp/common/secure_auth_context.cc b/src/cpp/common/secure_auth_context.cc
index 1d66dd3d1f..7a2b5afed6 100644
--- a/src/cpp/common/secure_auth_context.cc
+++ b/src/cpp/common/secure_auth_context.cc
@@ -22,19 +22,12 @@
namespace grpc {
-SecureAuthContext::SecureAuthContext(grpc_auth_context* ctx,
- bool take_ownership)
- : ctx_(ctx), take_ownership_(take_ownership) {}
-
-SecureAuthContext::~SecureAuthContext() {
- if (take_ownership_) grpc_auth_context_release(ctx_);
-}
-
std::vector<grpc::string_ref> SecureAuthContext::GetPeerIdentity() const {
- if (!ctx_) {
+ if (ctx_ == nullptr) {
return std::vector<grpc::string_ref>();
}
- grpc_auth_property_iterator iter = grpc_auth_context_peer_identity(ctx_);
+ grpc_auth_property_iterator iter =
+ grpc_auth_context_peer_identity(ctx_.get());
std::vector<grpc::string_ref> identity;
const grpc_auth_property* property = nullptr;
while ((property = grpc_auth_property_iterator_next(&iter))) {
@@ -45,20 +38,20 @@ std::vector<grpc::string_ref> SecureAuthContext::GetPeerIdentity() const {
}
grpc::string SecureAuthContext::GetPeerIdentityPropertyName() const {
- if (!ctx_) {
+ if (ctx_ == nullptr) {
return "";
}
- const char* name = grpc_auth_context_peer_identity_property_name(ctx_);
+ const char* name = grpc_auth_context_peer_identity_property_name(ctx_.get());
return name == nullptr ? "" : name;
}
std::vector<grpc::string_ref> SecureAuthContext::FindPropertyValues(
const grpc::string& name) const {
- if (!ctx_) {
+ if (ctx_ == nullptr) {
return std::vector<grpc::string_ref>();
}
grpc_auth_property_iterator iter =
- grpc_auth_context_find_properties_by_name(ctx_, name.c_str());
+ grpc_auth_context_find_properties_by_name(ctx_.get(), name.c_str());
const grpc_auth_property* property = nullptr;
std::vector<grpc::string_ref> values;
while ((property = grpc_auth_property_iterator_next(&iter))) {
@@ -68,9 +61,9 @@ std::vector<grpc::string_ref> SecureAuthContext::FindPropertyValues(
}
AuthPropertyIterator SecureAuthContext::begin() const {
- if (ctx_) {
+ if (ctx_ != nullptr) {
grpc_auth_property_iterator iter =
- grpc_auth_context_property_iterator(ctx_);
+ grpc_auth_context_property_iterator(ctx_.get());
const grpc_auth_property* property =
grpc_auth_property_iterator_next(&iter);
return AuthPropertyIterator(property, &iter);
@@ -85,19 +78,20 @@ AuthPropertyIterator SecureAuthContext::end() const {
void SecureAuthContext::AddProperty(const grpc::string& key,
const grpc::string_ref& value) {
- if (!ctx_) return;
- grpc_auth_context_add_property(ctx_, key.c_str(), value.data(), value.size());
+ if (ctx_ == nullptr) return;
+ grpc_auth_context_add_property(ctx_.get(), key.c_str(), value.data(),
+ value.size());
}
bool SecureAuthContext::SetPeerIdentityPropertyName(const grpc::string& name) {
- if (!ctx_) return false;
- return grpc_auth_context_set_peer_identity_property_name(ctx_,
+ if (ctx_ == nullptr) return false;
+ return grpc_auth_context_set_peer_identity_property_name(ctx_.get(),
name.c_str()) != 0;
}
bool SecureAuthContext::IsPeerAuthenticated() const {
- if (!ctx_) return false;
- return grpc_auth_context_peer_is_authenticated(ctx_) != 0;
+ if (ctx_ == nullptr) return false;
+ return grpc_auth_context_peer_is_authenticated(ctx_.get()) != 0;
}
} // namespace grpc
diff --git a/src/cpp/common/secure_auth_context.h b/src/cpp/common/secure_auth_context.h
index 142617959c..2e8f793721 100644
--- a/src/cpp/common/secure_auth_context.h
+++ b/src/cpp/common/secure_auth_context.h
@@ -21,15 +21,17 @@
#include <grpcpp/security/auth_context.h>
-struct grpc_auth_context;
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/security/context/security_context.h"
namespace grpc {
class SecureAuthContext final : public AuthContext {
public:
- SecureAuthContext(grpc_auth_context* ctx, bool take_ownership);
+ explicit SecureAuthContext(grpc_auth_context* ctx)
+ : ctx_(ctx != nullptr ? ctx->Ref() : nullptr) {}
- ~SecureAuthContext() override;
+ ~SecureAuthContext() override = default;
bool IsPeerAuthenticated() const override;
@@ -50,8 +52,7 @@ class SecureAuthContext final : public AuthContext {
virtual bool SetPeerIdentityPropertyName(const grpc::string& name) override;
private:
- grpc_auth_context* ctx_;
- bool take_ownership_;
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx_;
};
} // namespace grpc
diff --git a/src/cpp/common/secure_create_auth_context.cc b/src/cpp/common/secure_create_auth_context.cc
index bc1387c8d7..908c46629e 100644
--- a/src/cpp/common/secure_create_auth_context.cc
+++ b/src/cpp/common/secure_create_auth_context.cc
@@ -20,6 +20,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpcpp/security/auth_context.h>
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/cpp/common/secure_auth_context.h"
namespace grpc {
@@ -28,8 +29,8 @@ std::shared_ptr<const AuthContext> CreateAuthContext(grpc_call* call) {
if (call == nullptr) {
return std::shared_ptr<const AuthContext>();
}
- return std::shared_ptr<const AuthContext>(
- new SecureAuthContext(grpc_call_auth_context(call), true));
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx(grpc_call_auth_context(call));
+ return std::make_shared<SecureAuthContext>(ctx.get());
}
} // namespace grpc
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 8abd45efb7..55da89e6c8 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
#include <grpcpp/grpcpp.h>
namespace grpc {
-grpc::string Version() { return "1.17.0-dev"; }
+grpc::string Version() { return "1.18.0-dev"; }
} // namespace grpc
diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc
index 9ecb9de7e4..c44a9ac0de 100644
--- a/src/cpp/server/channelz/channelz_service.cc
+++ b/src/cpp/server/channelz/channelz_service.cc
@@ -79,8 +79,8 @@ Status ChannelzService::GetServer(ServerContext* unused,
Status ChannelzService::GetServerSockets(
ServerContext* unused, const channelz::v1::GetServerSocketsRequest* request,
channelz::v1::GetServerSocketsResponse* response) {
- char* json_str = grpc_channelz_get_server_sockets(request->server_id(),
- request->start_socket_id());
+ char* json_str = grpc_channelz_get_server_sockets(
+ request->server_id(), request->start_socket_id(), request->max_results());
if (json_str == nullptr) {
return Status(StatusCode::INTERNAL,
"grpc_channelz_get_server_sockets returned null");
diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc
index c951c69d51..44aebd2f9d 100644
--- a/src/cpp/server/health/default_health_check_service.cc
+++ b/src/cpp/server/health/default_health_check_service.cc
@@ -42,18 +42,37 @@ DefaultHealthCheckService::DefaultHealthCheckService() {
void DefaultHealthCheckService::SetServingStatus(
const grpc::string& service_name, bool serving) {
std::unique_lock<std::mutex> lock(mu_);
+ if (shutdown_) {
+ // Set to NOT_SERVING in case service_name is not in the map.
+ serving = false;
+ }
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_);
+ if (shutdown_) {
+ return;
+ }
for (auto& p : services_map_) {
ServiceData& service_data = p.second;
service_data.SetServingStatus(status);
}
}
+void DefaultHealthCheckService::Shutdown() {
+ std::unique_lock<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
+ shutdown_ = true;
+ for (auto& p : services_map_) {
+ ServiceData& service_data = p.second;
+ service_data.SetServingStatus(NOT_SERVING);
+ }
+}
+
DefaultHealthCheckService::ServingStatus
DefaultHealthCheckService::GetServingStatus(
const grpc::string& service_name) const {
diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h
index 450bd543f5..9551cd2e2c 100644
--- a/src/cpp/server/health/default_health_check_service.h
+++ b/src/cpp/server/health/default_health_check_service.h
@@ -237,6 +237,8 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface {
bool serving) override;
void SetServingStatus(bool serving) override;
+ void Shutdown() override;
+
ServingStatus GetServingStatus(const grpc::string& service_name) const;
HealthCheckServiceImpl* GetHealthCheckService(
@@ -272,6 +274,7 @@ class DefaultHealthCheckService final : public HealthCheckServiceInterface {
const std::shared_ptr<HealthCheckServiceImpl::CallHandler>& handler);
mutable std::mutex mu_;
+ bool shutdown_ = false; // Guarded by mu_.
std::map<grpc::string, ServiceData> services_map_; // Guarded by mu_.
std::unique_ptr<HealthCheckServiceImpl> impl_;
};
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index ebb17def32..453e76eb25 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -61,7 +61,7 @@ void AuthMetadataProcessorAyncWrapper::InvokeProcessor(
metadata.insert(std::make_pair(StringRefFromSlice(&md[i].key),
StringRefFromSlice(&md[i].value)));
}
- SecureAuthContext context(ctx, false);
+ SecureAuthContext context(ctx);
AuthMetadataProcessor::OutputMetadata consumed_metadata;
AuthMetadataProcessor::OutputMetadata response_metadata;
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 7a98bce507..1e3c57446f 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -84,10 +84,7 @@ class ShutdownTag : public internal::CompletionQueueTag {
class DummyTag : public internal::CompletionQueueTag {
public:
- bool FinalizeResult(void** tag, bool* status) {
- *status = true;
- return true;
- }
+ bool FinalizeResult(void** tag, bool* status) { return true; }
};
class UnimplementedAsyncRequestContext {
@@ -239,9 +236,10 @@ class Server::SyncRequest final : public internal::CompletionQueueTag {
: nullptr),
request_(nullptr),
method_(mrd->method_),
- call_(mrd->call_, server, &cq_, server->max_receive_message_size(),
- ctx_.set_server_rpc_info(method_->name(),
- server->interceptor_creators_)),
+ call_(
+ mrd->call_, server, &cq_, server->max_receive_message_size(),
+ ctx_.set_server_rpc_info(method_->name(), method_->method_type(),
+ server->interceptor_creators_)),
server_(server),
global_callbacks_(nullptr),
resources_(false) {
@@ -294,7 +292,7 @@ class Server::SyncRequest final : public internal::CompletionQueueTag {
void ContinueRunAfterInterception() {
{
- ctx_.BeginCompletionOp(&call_, false);
+ ctx_.BeginCompletionOp(&call_, nullptr, nullptr);
global_callbacks_->PreSynchronousRequest(&ctx_);
auto* handler = resources_ ? method_->handler()
: server_->resource_exhausted_handler_.get();
@@ -430,7 +428,8 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag {
req_->call_, req_->server_, req_->cq_,
req_->server_->max_receive_message_size(),
req_->ctx_.set_server_rpc_info(
- req_->method_->name(), req_->server_->interceptor_creators_));
+ req_->method_->name(), req_->method_->method_type(),
+ req_->server_->interceptor_creators_));
req_->interceptor_methods_.SetCall(call_);
req_->interceptor_methods_.SetReverse();
@@ -459,7 +458,6 @@ class Server::CallbackRequest final : public internal::CompletionQueueTag {
}
}
void ContinueRunAfterInterception() {
- req_->ctx_.BeginCompletionOp(call_, true);
req_->method_->handler()->RunHandler(
internal::MethodHandler::HandlerParameter(
call_, &req_->ctx_, req_->request_, req_->request_status_,
@@ -732,14 +730,15 @@ std::shared_ptr<Channel> Server::InProcessChannel(
grpc_channel_args channel_args = args.c_channel_args();
return CreateChannelInternal(
"inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr),
- nullptr);
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<Channel>
Server::experimental_type::InProcessChannelWithInterceptors(
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
grpc_channel_args channel_args = args.c_channel_args();
return CreateChannelInternal(
@@ -1020,7 +1019,7 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag,
}
}
if (*status && call_) {
- context_->BeginCompletionOp(&call_wrapper_, false);
+ context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr);
}
*tag = tag_;
if (delete_on_finalize_) {
@@ -1031,7 +1030,7 @@ bool ServerInterface::BaseAsyncRequest::FinalizeResult(void** tag,
void ServerInterface::BaseAsyncRequest::
ContinueFinalizeResultAfterInterception() {
- context_->BeginCompletionOp(&call_wrapper_, false);
+ context_->BeginCompletionOp(&call_wrapper_, nullptr, nullptr);
// Queue a tag which will be returned immediately
grpc_core::ExecCtx exec_ctx;
grpc_cq_begin_op(notification_cq_->cq(), this);
@@ -1044,10 +1043,12 @@ void ServerInterface::BaseAsyncRequest::
ServerInterface::RegisteredAsyncRequest::RegisteredAsyncRequest(
ServerInterface* server, ServerContext* context,
internal::ServerAsyncStreamingInterface* stream, CompletionQueue* call_cq,
- ServerCompletionQueue* notification_cq, void* tag, const char* name)
+ ServerCompletionQueue* notification_cq, void* tag, const char* name,
+ internal::RpcMethod::RpcType type)
: BaseAsyncRequest(server, context, stream, call_cq, notification_cq, tag,
true),
- name_(name) {}
+ name_(name),
+ type_(type) {}
void ServerInterface::RegisteredAsyncRequest::IssueRequest(
void* registered_method, grpc_byte_buffer** payload,
@@ -1094,6 +1095,7 @@ bool ServerInterface::GenericAsyncRequest::FinalizeResult(void** tag,
call_, server_, call_cq_, server_->max_receive_message_size(),
context_->set_server_rpc_info(
static_cast<GenericServerContext*>(context_)->method_.c_str(),
+ internal::RpcMethod::BIDI_STREAMING,
*server_->interceptor_creators()));
return BaseAsyncRequest::FinalizeResult(tag, status);
}
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 9c01f896e6..1b524bc3e8 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -17,6 +17,7 @@
*/
#include <grpcpp/server_context.h>
+#include <grpcpp/support/server_callback.h>
#include <algorithm>
#include <mutex>
@@ -41,8 +42,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface {
public:
// initial refs: one in the server context, one in the cq
// must ref the call before calling constructor and after deleting this
- CompletionOp(internal::Call* call)
+ CompletionOp(internal::Call* call, internal::ServerReactor* reactor)
: call_(*call),
+ reactor_(reactor),
has_tag_(false),
tag_(nullptr),
core_cq_tag_(this),
@@ -124,9 +126,9 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface {
return;
}
/* Start a dummy op so that we can return the tag */
- GPR_CODEGEN_ASSERT(GRPC_CALL_OK ==
- g_core_codegen_interface->grpc_call_start_batch(
- call_.call(), nullptr, 0, this, nullptr));
+ GPR_CODEGEN_ASSERT(
+ GRPC_CALL_OK ==
+ grpc_call_start_batch(call_.call(), nullptr, 0, core_cq_tag_, nullptr));
}
private:
@@ -136,13 +138,14 @@ class ServerContext::CompletionOp final : public internal::CallOpSetInterface {
}
internal::Call call_;
+ internal::ServerReactor* reactor_;
bool has_tag_;
void* tag_;
void* core_cq_tag_;
std::mutex mu_;
int refs_;
bool finalized_;
- int cancelled_;
+ int cancelled_; // This is an int (not bool) because it is passed to core
bool done_intercepting_;
internal::InterceptorBatchMethodsImpl interceptor_methods_;
};
@@ -190,7 +193,16 @@ bool ServerContext::CompletionOp::FinalizeResult(void** tag, bool* status) {
}
finalized_ = true;
- if (!*status) cancelled_ = 1;
+ // If for some reason the incoming status is false, mark that as a
+ // cancellation.
+ // TODO(vjpai): does this ever happen?
+ if (!*status) {
+ cancelled_ = 1;
+ }
+
+ if (cancelled_ && (reactor_ != nullptr)) {
+ reactor_->OnCancel();
+ }
/* Release the lock since we are going to be running through interceptors now
*/
lock.unlock();
@@ -251,21 +263,25 @@ void ServerContext::Clear() {
initial_metadata_.clear();
trailing_metadata_.clear();
client_metadata_.Reset();
- if (call_) {
- grpc_call_unref(call_);
- }
if (completion_op_) {
completion_op_->Unref();
+ completion_op_ = nullptr;
completion_tag_.Clear();
}
if (rpc_info_) {
rpc_info_->Unref();
+ rpc_info_ = nullptr;
+ }
+ if (call_) {
+ auto* call = call_;
+ call_ = nullptr;
+ grpc_call_unref(call);
}
- // Don't need to clear out call_, completion_op_, or rpc_info_ because this is
- // either called from destructor or just before Setup
}
-void ServerContext::BeginCompletionOp(internal::Call* call, bool callback) {
+void ServerContext::BeginCompletionOp(internal::Call* call,
+ std::function<void(bool)> callback,
+ internal::ServerReactor* reactor) {
GPR_ASSERT(!completion_op_);
if (rpc_info_) {
rpc_info_->Ref();
@@ -273,10 +289,11 @@ void ServerContext::BeginCompletionOp(internal::Call* call, bool callback) {
grpc_call_ref(call->call());
completion_op_ =
new (grpc_call_arena_alloc(call->call(), sizeof(CompletionOp)))
- CompletionOp(call);
- if (callback) {
- completion_tag_.Set(call->call(), nullptr, completion_op_);
+ CompletionOp(call, reactor);
+ if (callback != nullptr) {
+ completion_tag_.Set(call->call(), std::move(callback), completion_op_);
completion_op_->set_core_cq_tag(&completion_tag_);
+ completion_op_->set_tag(completion_op_);
} else if (has_notify_when_done_tag_) {
completion_op_->set_tag(async_notify_when_done_tag_);
}
diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
index 3a161763fd..b10d7a1045 100644
--- a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
+++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
@@ -25,7 +25,7 @@ namespace Grpc.Core.Tests
{
public class AppDomainUnloadTest
{
-#if NETCOREAPP1_0
+#if NETCOREAPP1_1 || NETCOREAPP2_1
[Test]
[Ignore("Not supported for CoreCLR")]
public void AppDomainUnloadHookCanCleanupAbandonedCall()
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index d58f046824..178931a3d7 100755
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Core.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Core.Tests</PackageId>
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
index e7d8939978..5c7d48f786 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
@@ -49,7 +49,7 @@ namespace Grpc.Core.Internal.Tests
fakeCall = new FakeNativeCall();
asyncCallServer = new AsyncCallServer<string, string>(
- Marshallers.StringMarshaller.Serializer, Marshallers.StringMarshaller.Deserializer,
+ Marshallers.StringMarshaller.ContextualSerializer, Marshallers.StringMarshaller.ContextualDeserializer,
server);
asyncCallServer.InitializeForTesting(fakeCall);
}
diff --git a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs
index 97f64a0575..ad3e81d61f 100644
--- a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs
@@ -69,11 +69,8 @@ namespace Grpc.Core.Tests
Assert.AreSame(contextualSerializer, marshaller.ContextualSerializer);
Assert.AreSame(contextualDeserializer, marshaller.ContextualDeserializer);
-
- // test that emulated serializer and deserializer work
- var origMsg = "abc";
- var serialized = marshaller.Serializer(origMsg);
- Assert.AreEqual(origMsg, marshaller.Deserializer(serialized));
+ Assert.Throws(typeof(NotImplementedException), () => marshaller.Serializer("abc"));
+ Assert.Throws(typeof(NotImplementedException), () => marshaller.Deserializer(new byte[] {1, 2, 3}));
}
class FakeSerializationContext : SerializationContext
diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs
index 49cb8cd3b9..3b206603f1 100644
--- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs
@@ -34,11 +34,7 @@ namespace Grpc.Core.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new ConsoleLogger());
-#if NETCOREAPP1_0
- return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
-#else
- return new AutoRun().Execute(args);
-#endif
+ return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
}
}
}
diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs
index 0904453b6e..f785f70f4c 100644
--- a/src/csharp/Grpc.Core.Tests/SanityTest.cs
+++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs
@@ -31,7 +31,7 @@ namespace Grpc.Core.Tests
public class SanityTest
{
// TODO: make sanity test work for CoreCLR as well
-#if !NETCOREAPP1_0
+#if !NETCOREAPP1_1 && !NETCOREAPP2_1
/// <summary>
/// Because we depend on a native library, sometimes when things go wrong, the
/// entire NUnit test process crashes. To be able to track down problems better,
@@ -44,7 +44,7 @@ namespace Grpc.Core.Tests
public void TestsJsonUpToDate()
{
var discoveredTests = DiscoverAllTestClasses();
- var testsFromFile
+ var testsFromFile
= JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(ReadTestsJson());
Assert.AreEqual(discoveredTests, testsFromFile);
diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core/DeserializationContext.cs
index 5b6372ef85..d69e0db5bd 100644
--- a/src/csharp/Grpc.Core/DeserializationContext.cs
+++ b/src/csharp/Grpc.Core/DeserializationContext.cs
@@ -16,6 +16,8 @@
#endregion
+using System;
+
namespace Grpc.Core
{
/// <summary>
@@ -41,6 +43,9 @@ namespace Grpc.Core
/// (as there is no practical reason for doing so) and <c>DeserializationContext</c> implementations are free to assume so.
/// </summary>
/// <returns>byte array containing the entire payload.</returns>
- public abstract byte[] PayloadAsNewBuffer();
+ public virtual byte[] PayloadAsNewBuffer()
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 4cdf0ee6a7..b6d687f71e 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -54,7 +54,7 @@ namespace Grpc.Core.Internal
ClientSideStatus? finishedStatus;
public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails)
- : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer)
+ : base(callDetails.RequestMarshaller.ContextualSerializer, callDetails.ResponseMarshaller.ContextualDeserializer)
{
this.details = callDetails.WithOptions(callDetails.Options.Normalize());
this.initialMetadataSent = true; // we always send metadata at the very beginning of the call.
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index a93dc34620..39c9f7c616 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -40,8 +40,8 @@ namespace Grpc.Core.Internal
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCallBase<TWrite, TRead>>();
protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message.");
- readonly Func<TWrite, byte[]> serializer;
- readonly Func<byte[], TRead> deserializer;
+ readonly Action<TWrite, SerializationContext> serializer;
+ readonly Func<DeserializationContext, TRead> deserializer;
protected readonly object myLock = new object();
@@ -63,7 +63,7 @@ namespace Grpc.Core.Internal
protected bool initialMetadataSent;
protected long streamingWritesCounter; // Number of streaming send operations started so far.
- public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer)
+ public AsyncCallBase(Action<TWrite, SerializationContext> serializer, Func<DeserializationContext, TRead> deserializer)
{
this.serializer = GrpcPreconditions.CheckNotNull(serializer);
this.deserializer = GrpcPreconditions.CheckNotNull(deserializer);
@@ -215,14 +215,26 @@ namespace Grpc.Core.Internal
protected byte[] UnsafeSerialize(TWrite msg)
{
- return serializer(msg);
+ DefaultSerializationContext context = null;
+ try
+ {
+ context = DefaultSerializationContext.GetInitializedThreadLocal();
+ serializer(msg, context);
+ return context.GetPayload();
+ }
+ finally
+ {
+ context?.Reset();
+ }
}
protected Exception TryDeserialize(byte[] payload, out TRead msg)
{
+ DefaultDeserializationContext context = null;
try
{
- msg = deserializer(payload);
+ context = DefaultDeserializationContext.GetInitializedThreadLocal(payload);
+ msg = deserializer(context);
return null;
}
catch (Exception e)
@@ -230,6 +242,11 @@ namespace Grpc.Core.Internal
msg = default(TRead);
return e;
}
+ finally
+ {
+ context?.Reset();
+
+ }
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 0ceca4abb8..0bf1fb3b7d 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -37,7 +37,7 @@ namespace Grpc.Core.Internal
readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
readonly Server server;
- public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, Server server) : base(serializer, deserializer)
+ public AsyncCallServer(Action<TResponse, SerializationContext> serializer, Func<DeserializationContext, TRequest> deserializer, Server server) : base(serializer, deserializer)
{
this.server = GrpcPreconditions.CheckNotNull(server);
}
diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs
new file mode 100644
index 0000000000..7ace80e8d5
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs
@@ -0,0 +1,66 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using Grpc.Core.Utils;
+using System;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+ internal class DefaultDeserializationContext : DeserializationContext
+ {
+ static readonly ThreadLocal<DefaultDeserializationContext> threadLocalInstance =
+ new ThreadLocal<DefaultDeserializationContext>(() => new DefaultDeserializationContext(), false);
+
+ byte[] payload;
+ bool alreadyCalledPayloadAsNewBuffer;
+
+ public DefaultDeserializationContext()
+ {
+ Reset();
+ }
+
+ public override int PayloadLength => payload.Length;
+
+ public override byte[] PayloadAsNewBuffer()
+ {
+ GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer);
+ alreadyCalledPayloadAsNewBuffer = true;
+ return payload;
+ }
+
+ public void Initialize(byte[] payload)
+ {
+ this.payload = GrpcPreconditions.CheckNotNull(payload);
+ this.alreadyCalledPayloadAsNewBuffer = false;
+ }
+
+ public void Reset()
+ {
+ this.payload = null;
+ this.alreadyCalledPayloadAsNewBuffer = true; // mark payload as read
+ }
+
+ public static DefaultDeserializationContext GetInitializedThreadLocal(byte[] payload)
+ {
+ var instance = threadLocalInstance.Value;
+ instance.Initialize(payload);
+ return instance;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs
new file mode 100644
index 0000000000..cceb194879
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs
@@ -0,0 +1,62 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using Grpc.Core.Utils;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+ internal class DefaultSerializationContext : SerializationContext
+ {
+ static readonly ThreadLocal<DefaultSerializationContext> threadLocalInstance =
+ new ThreadLocal<DefaultSerializationContext>(() => new DefaultSerializationContext(), false);
+
+ bool isComplete;
+ byte[] payload;
+
+ public DefaultSerializationContext()
+ {
+ Reset();
+ }
+
+ public override void Complete(byte[] payload)
+ {
+ GrpcPreconditions.CheckState(!isComplete);
+ this.isComplete = true;
+ this.payload = payload;
+ }
+
+ internal byte[] GetPayload()
+ {
+ return this.payload;
+ }
+
+ public void Reset()
+ {
+ this.isComplete = false;
+ this.payload = null;
+ }
+
+ public static DefaultSerializationContext GetInitializedThreadLocal()
+ {
+ var instance = threadLocalInstance.Value;
+ instance.Reset();
+ return instance;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
index f526b913af..5177b69fd9 100644
--- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -83,13 +83,13 @@ namespace Grpc.Core.Internal
// See https://github.com/grpc/grpc/pull/7303 for one option.
var assemblyDirectory = Path.GetDirectoryName(GetAssemblyPath());
- // With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder
+ // With "classic" VS projects, the native libraries get copied using a .targets rule to the build output folder
// alongside the compiled assembly.
// With dotnet cli projects targeting net45 framework, the native libraries (just the required ones)
// are similarly copied to the built output folder, through the magic of Microsoft.NETCore.Platforms.
var classicPath = Path.Combine(assemblyDirectory, GetNativeLibraryFilename());
- // With dotnet cli project targeting netcoreapp1.0, projects will use Grpc.Core assembly directly in the location where it got restored
+ // With dotnet cli project targeting netcoreappX.Y, projects will use Grpc.Core assembly directly in the location where it got restored
// by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package.
// When "dotnet publish" is used, the runtimes directory is copied next to the published assemblies.
string runtimesDirectory = string.Format("runtimes/{0}/native", GetPlatformString());
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 81522cf8fe..ec732e8c7f 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -52,8 +52,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
@@ -116,8 +116,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
@@ -179,8 +179,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
@@ -242,8 +242,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs
index 0af9aa586b..34a1849cd7 100644
--- a/src/csharp/Grpc.Core/Marshaller.cs
+++ b/src/csharp/Grpc.Core/Marshaller.cs
@@ -41,6 +41,8 @@ namespace Grpc.Core
{
this.serializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer));
this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer));
+ // contextual serialization/deserialization is emulated to make the marshaller
+ // usable with the grpc library (required for backward compatibility).
this.contextualSerializer = EmulateContextualSerializer;
this.contextualDeserializer = EmulateContextualDeserializer;
}
@@ -57,10 +59,10 @@ namespace Grpc.Core
{
this.contextualSerializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer));
this.contextualDeserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer));
- // TODO(jtattermusch): once gRPC C# library switches to using contextual (de)serializer,
- // emulating the simple (de)serializer will become unnecessary.
- this.serializer = EmulateSimpleSerializer;
- this.deserializer = EmulateSimpleDeserializer;
+ // gRPC only uses contextual serializer/deserializer internally, so emulating the legacy
+ // (de)serializer is not necessary.
+ this.serializer = (msg) => { throw new NotImplementedException(); };
+ this.deserializer = (payload) => { throw new NotImplementedException(); };
}
/// <summary>
@@ -85,25 +87,6 @@ namespace Grpc.Core
/// </summary>
public Func<DeserializationContext, T> ContextualDeserializer => this.contextualDeserializer;
- // for backward compatibility, emulate the simple serializer using the contextual one
- private byte[] EmulateSimpleSerializer(T msg)
- {
- // TODO(jtattermusch): avoid the allocation by passing a thread-local instance
- // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer.
- var context = new EmulatedSerializationContext();
- this.contextualSerializer(msg, context);
- return context.GetPayload();
- }
-
- // for backward compatibility, emulate the simple deserializer using the contextual one
- private T EmulateSimpleDeserializer(byte[] payload)
- {
- // TODO(jtattermusch): avoid the allocation by passing a thread-local instance
- // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer.
- var context = new EmulatedDeserializationContext(payload);
- return this.contextualDeserializer(context);
- }
-
// for backward compatibility, emulate the contextual serializer using the simple one
private void EmulateContextualSerializer(T message, SerializationContext context)
{
@@ -116,44 +99,6 @@ namespace Grpc.Core
{
return this.deserializer(context.PayloadAsNewBuffer());
}
-
- internal class EmulatedSerializationContext : SerializationContext
- {
- bool isComplete;
- byte[] payload;
-
- public override void Complete(byte[] payload)
- {
- GrpcPreconditions.CheckState(!isComplete);
- this.isComplete = true;
- this.payload = payload;
- }
-
- internal byte[] GetPayload()
- {
- return this.payload;
- }
- }
-
- internal class EmulatedDeserializationContext : DeserializationContext
- {
- readonly byte[] payload;
- bool alreadyCalledPayloadAsNewBuffer;
-
- public EmulatedDeserializationContext(byte[] payload)
- {
- this.payload = GrpcPreconditions.CheckNotNull(payload);
- }
-
- public override int PayloadLength => payload.Length;
-
- public override byte[] PayloadAsNewBuffer()
- {
- GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer);
- alreadyCalledPayloadAsNewBuffer = true;
- return payload;
- }
- }
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/SerializationContext.cs b/src/csharp/Grpc.Core/SerializationContext.cs
index cf4d1595da..9aef2adbcd 100644
--- a/src/csharp/Grpc.Core/SerializationContext.cs
+++ b/src/csharp/Grpc.Core/SerializationContext.cs
@@ -16,6 +16,8 @@
#endregion
+using System;
+
namespace Grpc.Core
{
/// <summary>
@@ -29,6 +31,9 @@ namespace Grpc.Core
/// payload which must not be accessed afterwards.
/// </summary>
/// <param name="payload">the serialized form of current message</param>
- public abstract void Complete(byte[] payload);
+ public virtual void Complete(byte[] payload)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
index 07c6aa1796..b040ab379c 100644
--- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs
+++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
@@ -72,7 +72,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a single request - single response method.
+ /// Adds a definition for a single request - single response method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
@@ -90,7 +90,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a client streaming method.
+ /// Adds a definition for a client streaming method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
@@ -108,7 +108,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a server streaming method.
+ /// Adds a definition for a server streaming method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
@@ -126,7 +126,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a bidirectional streaming method.
+ /// Adds a definition for a bidirectional streaming method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core/ServiceBinderBase.cs
new file mode 100644
index 0000000000..d4909f4a26
--- /dev/null
+++ b/src/csharp/Grpc.Core/ServiceBinderBase.cs
@@ -0,0 +1,101 @@
+#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Grpc.Core.Interceptors;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Allows binding server-side method implementations in alternative serving stacks.
+ /// Instances of this class are usually populated by the <c>BindService</c> method
+ /// that is part of the autogenerated code for a protocol buffers service definition.
+ /// <seealso cref="ServerServiceDefinition"/>
+ /// </summary>
+ public class ServiceBinderBase
+ {
+ /// <summary>
+ /// Adds a definition for a single request - single response method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ UnaryServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Adds a definition for a client streaming method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ ClientStreamingServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Adds a definition for a server streaming method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ ServerStreamingServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Adds a definition for a bidirectional streaming method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ DuplexStreamingServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index ed0d884365..4fffe4f644 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
- <GrpcCsharpVersion>1.17.0-dev</GrpcCsharpVersion>
+ <GrpcCsharpVersion>1.18.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.6.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 14714c8c4a..633880189c 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
- public const string CurrentAssemblyFileVersion = "1.17.0.0";
+ public const string CurrentAssemblyFileVersion = "1.18.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.17.0-dev";
+ public const string CurrentVersion = "1.18.0-dev";
}
}
diff --git a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
index db4e3ef4e3..1afcd9fba0 100755
--- a/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
+++ b/src/csharp/Grpc.Examples.MathClient/Grpc.Examples.MathClient.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Examples.MathClient</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Examples.MathClient</PackageId>
diff --git a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
index b12b418d01..75ef6d1008 100755
--- a/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
+++ b/src/csharp/Grpc.Examples.MathServer/Grpc.Examples.MathServer.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Examples.MathServer</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Examples.MathServer</PackageId>
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index 7493eb8051..93d112a0c5 100755
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Examples.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Examples.Tests</PackageId>
diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs
index bcb8b46b64..107df64809 100644
--- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs
@@ -34,11 +34,7 @@ namespace Grpc.Examples.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new ConsoleLogger());
-#if NETCOREAPP1_0
- return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
-#else
- return new AutoRun().Execute(args);
-#endif
+ return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
}
}
}
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
index baa3b4ce6c..9ce2b59d03 100755
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Examples</AssemblyName>
<PackageId>Grpc.Examples</PackageId>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 9578bb4d81..e5be387e67 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -287,6 +287,18 @@ namespace Math {
.AddMethod(__Method_Sum, serviceImpl.Sum).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, MathBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_Div, serviceImpl.Div);
+ serviceBinder.AddMethod(__Method_DivMany, serviceImpl.DivMany);
+ serviceBinder.AddMethod(__Method_Fib, serviceImpl.Fib);
+ serviceBinder.AddMethod(__Method_Sum, serviceImpl.Sum);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
index 616e56df10..2a037a72e5 100755
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
+++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.HealthCheck.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.HealthCheck.Tests</PackageId>
diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
index 365551e895..db6d32a5b2 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
@@ -34,11 +34,7 @@ namespace Grpc.HealthCheck.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new ConsoleLogger());
-#if NETCOREAPP1_0
- return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
-#else
- return new AutoRun().Execute(args);
-#endif
+ return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
}
}
}
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index a90f261d28..2c3bb45c3c 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -25,15 +25,17 @@ namespace Grpc.Health.V1 {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChtncnBjL2hlYWx0aC92MS9oZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYx",
- "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNI",
+ "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIqkBChNI",
"ZWFsdGhDaGVja1Jlc3BvbnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVh",
- "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1T",
+ "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyJPCg1T",
"ZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9U",
- "X1NFUlZJTkcQAjJaCgZIZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52",
- "MS5IZWFsdGhDaGVja1JlcXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhD",
- "aGVja1Jlc3BvbnNlQmEKEWlvLmdycGMuaGVhbHRoLnYxQgtIZWFsdGhQcm90",
- "b1ABWixnb29nbGUuZ29sYW5nLm9yZy9ncnBjL2hlYWx0aC9ncnBjX2hlYWx0",
- "aF92MaoCDkdycGMuSGVhbHRoLlYxYgZwcm90bzM="));
+ "X1NFUlZJTkcQAhITCg9TRVJWSUNFX1VOS05PV04QAzKuAQoGSGVhbHRoElAK",
+ "BUNoZWNrEiIuZ3JwYy5oZWFsdGgudjEuSGVhbHRoQ2hlY2tSZXF1ZXN0GiMu",
+ "Z3JwYy5oZWFsdGgudjEuSGVhbHRoQ2hlY2tSZXNwb25zZRJSCgVXYXRjaBIi",
+ "LmdycGMuaGVhbHRoLnYxLkhlYWx0aENoZWNrUmVxdWVzdBojLmdycGMuaGVh",
+ "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UwAUJhChFpby5ncnBjLmhlYWx0",
+ "aC52MUILSGVhbHRoUHJvdG9QAVosZ29vZ2xlLmdvbGFuZy5vcmcvZ3JwYy9o",
+ "ZWFsdGgvZ3JwY19oZWFsdGhfdjGqAg5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -309,6 +311,10 @@ namespace Grpc.Health.V1 {
[pbr::OriginalName("UNKNOWN")] Unknown = 0,
[pbr::OriginalName("SERVING")] Serving = 1,
[pbr::OriginalName("NOT_SERVING")] NotServing = 2,
+ /// <summary>
+ /// Used only by the Watch method.
+ /// </summary>
+ [pbr::OriginalName("SERVICE_UNKNOWN")] ServiceUnknown = 3,
}
}
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 5e79c04d2a..51956f2f23 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -40,6 +40,13 @@ namespace Grpc.Health.V1 {
__Marshaller_grpc_health_v1_HealthCheckRequest,
__Marshaller_grpc_health_v1_HealthCheckResponse);
+ static readonly grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse> __Method_Watch = new grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse>(
+ grpc::MethodType.ServerStreaming,
+ __ServiceName,
+ "Watch",
+ __Marshaller_grpc_health_v1_HealthCheckRequest,
+ __Marshaller_grpc_health_v1_HealthCheckResponse);
+
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
{
@@ -49,11 +56,44 @@ namespace Grpc.Health.V1 {
/// <summary>Base class for server-side implementations of Health</summary>
public abstract partial class HealthBase
{
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
public virtual global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::IServerStreamWriter<global::Grpc.Health.V1.HealthCheckResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
}
/// <summary>Client for Health</summary>
@@ -79,22 +119,104 @@ namespace Grpc.Health.V1 {
{
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Check(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CheckAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
}
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Health.V1.HealthCheckResponse> Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return Watch(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Health.V1.HealthCheckResponse> Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncServerStreamingCall(__Method_Watch, null, options, request);
+ }
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
protected override HealthClient NewInstance(ClientBaseConfiguration configuration)
{
@@ -107,7 +229,18 @@ namespace Grpc.Health.V1 {
public static grpc::ServerServiceDefinition BindService(HealthBase serviceImpl)
{
return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_Check, serviceImpl.Check).Build();
+ .AddMethod(__Method_Check, serviceImpl.Check)
+ .AddMethod(__Method_Watch, serviceImpl.Watch).Build();
+ }
+
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, HealthBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_Check, serviceImpl.Check);
+ serviceBinder.AddMethod(__Method_Watch, serviceImpl.Watch);
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
index 35713156ea..1cd4b83e1e 100755
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.IntegrationTesting.Client</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.Client</PackageId>
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
index 3ecefe3bc4..2890a7df58 100755
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.IntegrationTesting.QpsWorker</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.QpsWorker</PackageId>
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
index 1092b2c21e..ee718958bc 100755
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.IntegrationTesting.Server</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.Server</PackageId>
@@ -19,7 +19,7 @@
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
-
+
<ItemGroup>
<Compile Include="..\Grpc.Core\Version.cs" />
</ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
index 22272547f6..99926497e4 100755
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/Grpc.IntegrationTesting.StressClient.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.IntegrationTesting.StressClient</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting.StressClient</PackageId>
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
index b5738593f2..3431b5fa18 100644
--- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
@@ -324,6 +324,19 @@ namespace Grpc.Testing {
.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, BenchmarkServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall);
+ serviceBinder.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall);
+ serviceBinder.AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient);
+ serviceBinder.AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer);
+ serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 6e00348451..368b86659a 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -34,7 +34,7 @@ namespace Grpc.Testing {
"U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy",
"X2hvc3Rfb3ZlcnJpZGUYAiABKAkSEQoJY3JlZF90eXBlGAMgASgJIk0KCkNo",
"YW5uZWxBcmcSDAoEbmFtZRgBIAEoCRITCglzdHJfdmFsdWUYAiABKAlIABIT",
- "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSLvBAoMQ2xpZW50Q29uZmln",
+ "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSKiBQoMQ2xpZW50Q29uZmln",
"EhYKDnNlcnZlcl90YXJnZXRzGAEgAygJEi0KC2NsaWVudF90eXBlGAIgASgO",
"MhguZ3JwYy50ZXN0aW5nLkNsaWVudFR5cGUSNQoPc2VjdXJpdHlfcGFyYW1z",
"GAMgASgLMhwuZ3JwYy50ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEiQKHG91dHN0",
@@ -48,59 +48,60 @@ namespace Grpc.Testing {
"GA4gASgFEhgKEG90aGVyX2NsaWVudF9hcGkYDyABKAkSLgoMY2hhbm5lbF9h",
"cmdzGBAgAygLMhguZ3JwYy50ZXN0aW5nLkNoYW5uZWxBcmcSFgoOdGhyZWFk",
"c19wZXJfY3EYESABKAUSGwoTbWVzc2FnZXNfcGVyX3N0cmVhbRgSIAEoBRIY",
- "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIIjgKDENsaWVudFN0YXR1cxIoCgVz",
- "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr",
- "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy",
- "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS",
- "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2VydmVyQ29u",
- "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl",
- "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n",
- "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy",
- "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk",
- "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK",
- "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhYK",
- "DnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3RhX3NpemUY",
- "6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRlc3Rpbmcu",
- "Q2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgLMhouZ3Jw",
- "Yy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBj",
- "LnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3RhdHVzEigK",
- "BXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEgwKBHBv",
- "cnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3QiHQoMQ29y",
- "ZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNjZW5hcmlv",
- "EgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIaLmdycGMu",
- "dGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyABKAUSMQoN",
- "c2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJDb25m",
- "aWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29uZHMYBiAB",
- "KAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25fbG9jYWxf",
- "d29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2VuYXJpb3MY",
- "ASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5hcmlvUmVz",
- "dWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2ZXJfY29y",
- "ZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQc2VydmVy",
- "X3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUYBSABKAES",
- "GAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUwGAcgASgB",
- "EhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEoARISCgps",
- "YXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgKEHNlcnZl",
- "cl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0c19wZXJf",
- "c2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vjb25kGA4g",
- "ASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIgChhzZXJ2",
- "ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1ZXJpZXNf",
- "cGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVyX2NwdV9z",
- "ZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlvGAEgASgL",
- "MhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgCIAEoCzIb",
- "LmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9zdGF0cxgD",
- "IAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2ZXJfc3Rh",
- "dHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoMc2VydmVy",
- "X2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRlc3Rpbmcu",
- "U2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNzGAcgAygI",
- "EhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVzdWx0cxgJ",
- "IAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQqQQoKQ2xp",
- "ZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVOVBABEhAK",
- "DE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQ",
- "ABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhAC",
- "EhAKDE9USEVSX1NFUlZFUhADKnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglT",
- "VFJFQU1JTkcQARIZChVTVFJFQU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJF",
- "QU1JTkdfRlJPTV9TRVJWRVIQAxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARi",
- "BnByb3RvMw=="));
+ "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIEjEKKW1lZGlhbl9sYXRlbmN5X2Nv",
+ "bGxlY3Rpb25faW50ZXJ2YWxfbWlsbGlzGBQgASgFIjgKDENsaWVudFN0YXR1",
+ "cxIoCgVzdGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIV",
+ "CgRNYXJrEg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAY",
+ "ASABKAsyGi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgC",
+ "IAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2Vy",
+ "dmVyQ29uZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5n",
+ "LlNlcnZlclR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50",
+ "ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNf",
+ "c2VydmVyX3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5w",
+ "YXlsb2FkX2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29u",
+ "ZmlnEhEKCWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsg",
+ "ASgJEhYKDnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3Rh",
+ "X3NpemUY6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRl",
+ "c3RpbmcuQ2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgL",
+ "MhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsy",
+ "Ei5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3Rh",
+ "dHVzEigKBXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRz",
+ "EgwKBHBvcnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3Qi",
+ "HQoMQ29yZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNj",
+ "ZW5hcmlvEgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIa",
+ "LmdycGMudGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyAB",
+ "KAUSMQoNc2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2",
+ "ZXJDb25maWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29u",
+ "ZHMYBiABKAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25f",
+ "bG9jYWxfd29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2Vu",
+ "YXJpb3MYASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5h",
+ "cmlvUmVzdWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2",
+ "ZXJfY29yZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQ",
+ "c2VydmVyX3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUY",
+ "BSABKAESGAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUw",
+ "GAcgASgBEhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEo",
+ "ARISCgpsYXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgK",
+ "EHNlcnZlcl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0",
+ "c19wZXJfc2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vj",
+ "b25kGA4gASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIg",
+ "ChhzZXJ2ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1",
+ "ZXJpZXNfcGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVy",
+ "X2NwdV9zZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlv",
+ "GAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgC",
+ "IAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9z",
+ "dGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2",
+ "ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoM",
+ "c2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRl",
+ "c3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNz",
+ "GAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVz",
+ "dWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQq",
+ "VgoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVO",
+ "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKlsK",
+ "ClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQ",
+ "ARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhAD",
+ "KnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1JTkcQARIZChVTVFJF",
+ "QU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJFQU1JTkdfRlJPTV9TRVJWRVIQ",
+ "AxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -109,7 +110,7 @@ namespace Grpc.Testing {
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride", "CredType" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi", "MedianLatencyCollectionIntervalMillis" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
@@ -140,6 +141,7 @@ namespace Grpc.Testing {
/// used for some language-specific variants
/// </summary>
[pbr::OriginalName("OTHER_CLIENT")] OtherClient = 2,
+ [pbr::OriginalName("CALLBACK_CLIENT")] CallbackClient = 3,
}
public enum ServerType {
@@ -1054,6 +1056,7 @@ namespace Grpc.Testing {
threadsPerCq_ = other.threadsPerCq_;
messagesPerStream_ = other.messagesPerStream_;
useCoalesceApi_ = other.useCoalesceApi_;
+ medianLatencyCollectionIntervalMillis_ = other.medianLatencyCollectionIntervalMillis_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@@ -1278,6 +1281,21 @@ namespace Grpc.Testing {
}
}
+ /// <summary>Field number for the "median_latency_collection_interval_millis" field.</summary>
+ public const int MedianLatencyCollectionIntervalMillisFieldNumber = 20;
+ private int medianLatencyCollectionIntervalMillis_;
+ /// <summary>
+ /// If 0, disabled. Else, specifies the period between gathering latency
+ /// medians in milliseconds.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int MedianLatencyCollectionIntervalMillis {
+ get { return medianLatencyCollectionIntervalMillis_; }
+ set {
+ medianLatencyCollectionIntervalMillis_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ClientConfig);
@@ -1308,6 +1326,7 @@ namespace Grpc.Testing {
if (ThreadsPerCq != other.ThreadsPerCq) return false;
if (MessagesPerStream != other.MessagesPerStream) return false;
if (UseCoalesceApi != other.UseCoalesceApi) return false;
+ if (MedianLatencyCollectionIntervalMillis != other.MedianLatencyCollectionIntervalMillis) return false;
return Equals(_unknownFields, other._unknownFields);
}
@@ -1331,6 +1350,7 @@ namespace Grpc.Testing {
if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
if (MessagesPerStream != 0) hash ^= MessagesPerStream.GetHashCode();
if (UseCoalesceApi != false) hash ^= UseCoalesceApi.GetHashCode();
+ if (MedianLatencyCollectionIntervalMillis != 0) hash ^= MedianLatencyCollectionIntervalMillis.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@@ -1403,6 +1423,10 @@ namespace Grpc.Testing {
output.WriteRawTag(152, 1);
output.WriteBool(UseCoalesceApi);
}
+ if (MedianLatencyCollectionIntervalMillis != 0) {
+ output.WriteRawTag(160, 1);
+ output.WriteInt32(MedianLatencyCollectionIntervalMillis);
+ }
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@@ -1456,6 +1480,9 @@ namespace Grpc.Testing {
if (UseCoalesceApi != false) {
size += 2 + 1;
}
+ if (MedianLatencyCollectionIntervalMillis != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(MedianLatencyCollectionIntervalMillis);
+ }
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@@ -1524,6 +1551,9 @@ namespace Grpc.Testing {
if (other.UseCoalesceApi != false) {
UseCoalesceApi = other.UseCoalesceApi;
}
+ if (other.MedianLatencyCollectionIntervalMillis != 0) {
+ MedianLatencyCollectionIntervalMillis = other.MedianLatencyCollectionIntervalMillis;
+ }
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@@ -1616,6 +1646,10 @@ namespace Grpc.Testing {
UseCoalesceApi = input.ReadBool();
break;
}
+ case 160: {
+ MedianLatencyCollectionIntervalMillis = input.ReadInt32();
+ break;
+ }
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs
index 2d233fbdc0..7e77f8d114 100644
--- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs
@@ -80,6 +80,14 @@ namespace Grpc.Testing {
return grpc::ServerServiceDefinition.CreateBuilder().Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, EmptyServiceBase serviceImpl)
+ {
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 8daf3fa98b..c342f8a107 100755
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.IntegrationTesting</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.IntegrationTesting</PackageId>
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index 9f16f41ac1..c66a9a9161 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -193,6 +193,16 @@ namespace Grpc.Testing {
.AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, MetricsServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges);
+ serviceBinder.AddMethod(__Method_GetGauge, serviceImpl.GetGauge);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
index 9d24762e0a..4135186275 100644
--- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
+++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
@@ -34,11 +34,7 @@ namespace Grpc.IntegrationTesting
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new ConsoleLogger());
-#if NETCOREAPP1_0
- return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
-#else
- return new AutoRun().Execute(args);
-#endif
+ return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
index 1da0548cb4..954c172272 100644
--- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
@@ -143,6 +143,15 @@ namespace Grpc.Testing {
.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, ReportQpsScenarioServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 2176916b43..d125fd5627 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -539,6 +539,22 @@ namespace Grpc.Testing {
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, TestServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall);
+ serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall);
+ serviceBinder.AddMethod(__Method_CacheableUnaryCall, serviceImpl.CacheableUnaryCall);
+ serviceBinder.AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall);
+ serviceBinder.AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall);
+ serviceBinder.AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall);
+ serviceBinder.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall);
+ serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall);
+ }
+
}
/// <summary>
/// A simple service NOT implemented at servers so clients can test for
@@ -661,6 +677,15 @@ namespace Grpc.Testing {
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, UnimplementedServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall);
+ }
+
}
/// <summary>
/// A service used to control reconnect server.
@@ -779,6 +804,16 @@ namespace Grpc.Testing {
.AddMethod(__Method_Stop, serviceImpl.Stop).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, ReconnectServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_Start, serviceImpl.Start);
+ serviceBinder.AddMethod(__Method_Stop, serviceImpl.Stop);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
index b9e8f91231..5b22337d53 100644
--- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
@@ -321,6 +321,18 @@ namespace Grpc.Testing {
.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, WorkerServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_RunServer, serviceImpl.RunServer);
+ serviceBinder.AddMethod(__Method_RunClient, serviceImpl.RunClient);
+ serviceBinder.AddMethod(__Method_CoreCount, serviceImpl.CoreCount);
+ serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
index d39d46cf1b..5b1656080a 100644
--- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
+++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Microbenchmarks</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Microbenchmarks</PackageId>
diff --git a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
index 0c12f38f25..8b586c6ecb 100755
--- a/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
+++ b/src/csharp/Grpc.Reflection.Tests/Grpc.Reflection.Tests.csproj
@@ -4,7 +4,7 @@
<Import Project="..\Grpc.Core\Common.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<AssemblyName>Grpc.Reflection.Tests</AssemblyName>
<OutputType>Exe</OutputType>
<PackageId>Grpc.Reflection.Tests</PackageId>
diff --git a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
index 49ed1cc8d4..de4b4af6cf 100644
--- a/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Reflection.Tests/NUnitMain.cs
@@ -34,11 +34,7 @@ namespace Grpc.Reflection.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new ConsoleLogger());
-#if NETCOREAPP1_0
- return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
-#else
- return new AutoRun().Execute(args);
-#endif
+ return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
}
}
}
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index c00075b7c6..ed55c2f584 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -123,6 +123,15 @@ namespace Grpc.Reflection.V1Alpha {
.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, ServerReflectionBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
index a2d4874eec..cfb40f44ae 100644
--- a/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
+++ b/src/csharp/Grpc.Tools.Tests/Grpc.Tools.Tests.csproj
@@ -3,7 +3,7 @@
<Import Project="..\Grpc.Core\Version.csproj.include" />
<PropertyGroup>
- <TargetFrameworks>net45;netcoreapp1.0</TargetFrameworks>
+ <TargetFrameworks>net45;netcoreapp1.1</TargetFrameworks>
<OutputType>Exe</OutputType>
</PropertyGroup>
diff --git a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs
index 418c33820e..d30d608aa3 100644
--- a/src/csharp/Grpc.Tools.Tests/NUnitMain.cs
+++ b/src/csharp/Grpc.Tools.Tests/NUnitMain.cs
@@ -24,10 +24,6 @@ namespace Grpc.Tools.Tests
static class NUnitMain
{
public static int Main(string[] args) =>
-#if NETCOREAPP1_0 || NETCOREAPP1_1
new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args);
-#else
- new AutoRun().Execute(args);
-#endif
};
}
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 27688360e9..76d4f14390 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.17.0-dev
+set VERSION=1.18.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat
index dd74de0491..3334d24c11 100644
--- a/src/csharp/build_unitypackage.bat
+++ b/src/csharp/build_unitypackage.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.17.0-dev
+set VERSION=1.18.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index a95a120d21..55ca6048bc 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.17.0-dev'
+ v = '1.18.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index e0ef8b1391..ddc6ae054d 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -253,7 +253,8 @@ extern id const kGRPCTrailersKey;
+ (void)setCallSafety:(GRPCCallSafety)callSafety host:(NSString *)host path:(NSString *)path;
/**
- * Set the dispatch queue to be used for callbacks.
+ * Set the dispatch queue to be used for callbacks. Current implementation requires \a queue to be a
+ * serial queue.
*
* This configuration is only effective before the call starts.
*/
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index d5463c0b4c..0be0e3c9a0 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -22,4 +22,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.17.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev"
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index ca27c03b3c..f2fd692070 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -22,5 +22,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.17.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev"
#define GRPC_C_VERSION_STRING @"7.0.0-dev"
diff --git a/src/php/composer.json b/src/php/composer.json
index d54db91b5f..9c298c0e85 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.17.0",
+ "version": "1.18.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index b17f3d9a61..c06bdea7fe 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -393,6 +393,8 @@ PHP_METHOD(Channel, __construct) {
channel->wrapper->target = strdup(target);
channel->wrapper->args_hashstr = strdup(sha1str);
channel->wrapper->creds_hashstr = NULL;
+ channel->wrapper->creds = creds;
+ channel->wrapper->args = args;
if (creds != NULL && creds->hashstr != NULL) {
php_grpc_int creds_hashstr_len = strlen(creds->hashstr);
char *channel_creds_hashstr = malloc(creds_hashstr_len + 1);
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 27752c9a3f..ce17c4a58a 100644
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -19,6 +19,7 @@
#ifndef NET_GRPC_PHP_GRPC_CHANNEL_H_
#define NET_GRPC_PHP_GRPC_CHANNEL_H_
+#include "channel_credentials.h"
#include "php_grpc.h"
/* Class entry for the PHP Channel class */
@@ -32,6 +33,8 @@ typedef struct _grpc_channel_wrapper {
char *creds_hashstr;
size_t ref_count;
gpr_mu mu;
+ grpc_channel_args args;
+ wrapped_grpc_channel_credentials *creds;
} grpc_channel_wrapper;
/* Wrapper struct for grpc_channel that can be associated with a PHP object */
diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4
index fa54ebd920..9ec2c7cf04 100755
--- a/src/php/ext/grpc/config.m4
+++ b/src/php/ext/grpc/config.m4
@@ -103,7 +103,7 @@ if test "$PHP_COVERAGE" = "yes"; then
AC_MSG_ERROR([ccache must be disabled when --enable-coverage option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
fi
- lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11"
+ lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11 1.12 1.13"
AC_CHECK_PROG(LCOV, lcov, lcov)
AC_CHECK_PROG(GENHTML, genhtml, genhtml)
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index fabd98975d..111c6f4867 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -26,6 +26,8 @@
#include "call_credentials.h"
#include "server_credentials.h"
#include "completion_queue.h"
+#include <ext/spl/spl_exceptions.h>
+#include <zend_exceptions.h>
ZEND_DECLARE_MODULE_GLOBALS(grpc)
static PHP_GINIT_FUNCTION(grpc);
@@ -86,6 +88,125 @@ ZEND_GET_MODULE(grpc)
}
*/
/* }}} */
+void create_new_channel(
+ wrapped_grpc_channel *channel,
+ char *target,
+ grpc_channel_args args,
+ wrapped_grpc_channel_credentials *creds) {
+ if (creds == NULL) {
+ channel->wrapper->wrapped = grpc_insecure_channel_create(target, &args,
+ NULL);
+ } else {
+ channel->wrapper->wrapped =
+ grpc_secure_channel_create(creds->wrapped, target, &args, NULL);
+ }
+}
+
+void acquire_persistent_locks() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ gpr_mu_lock(&le->channel->mu);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void release_persistent_locks() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ gpr_mu_unlock(&le->channel->mu);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void destroy_grpc_channels() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ wrapped_grpc_channel wrapped_channel;
+ wrapped_channel.wrapper = le->channel;
+ grpc_channel_wrapper *channel = wrapped_channel.wrapper;
+ grpc_channel_destroy(channel->wrapped);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void restart_channels() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ wrapped_grpc_channel wrapped_channel;
+ wrapped_channel.wrapper = le->channel;
+ grpc_channel_wrapper *channel = wrapped_channel.wrapper;
+ create_new_channel(&wrapped_channel, channel->target, channel->args,
+ channel->creds);
+ gpr_mu_unlock(&channel->mu);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void prefork() {
+ acquire_persistent_locks();
+}
+
+void postfork_child() {
+ TSRMLS_FETCH();
+
+ // loop through persistant list and destroy all underlying grpc_channel objs
+ destroy_grpc_channels();
+
+ // clear completion queue
+ grpc_php_shutdown_completion_queue(TSRMLS_C);
+
+ // clean-up grpc_core
+ grpc_shutdown();
+ if (grpc_is_initialized() > 0) {
+ zend_throw_exception(spl_ce_UnexpectedValueException,
+ "Oops, failed to shutdown gRPC Core after fork()",
+ 1 TSRMLS_CC);
+ }
+
+ // restart grpc_core
+ grpc_init();
+ grpc_php_init_completion_queue(TSRMLS_C);
+
+ // re-create grpc_channel and point wrapped to it
+ // unlock wrapped grpc channel mutex
+ restart_channels();
+}
+
+void postfork_parent() {
+ release_persistent_locks();
+}
+
+void register_fork_handlers() {
+ if (getenv("GRPC_ENABLE_FORK_SUPPORT")) {
+#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
+ pthread_atfork(&prefork, &postfork_parent, &postfork_child);
+#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
+ }
+}
/* {{{ PHP_MINIT_FUNCTION
*/
@@ -265,6 +386,7 @@ PHP_MINFO_FUNCTION(grpc) {
PHP_RINIT_FUNCTION(grpc) {
if (!GRPC_G(initialized)) {
grpc_init();
+ register_fork_handlers();
grpc_php_init_completion_queue(TSRMLS_C);
GRPC_G(initialized) = 1;
}
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 70f8bbbf40..1ddf90a667 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.17.0dev"
+#define PHP_GRPC_VERSION "1.18.0dev"
#endif /* VERSION_H */
diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD
index bdb03d5e2d..b6b485e3e8 100644
--- a/src/proto/grpc/channelz/BUILD
+++ b/src/proto/grpc/channelz/BUILD
@@ -24,3 +24,10 @@ grpc_proto_library(
has_services = True,
well_known_protos = True,
)
+
+filegroup(
+ name = "channelz_proto_file",
+ srcs = [
+ "channelz.proto",
+ ],
+)
diff --git a/src/proto/grpc/channelz/channelz.proto b/src/proto/grpc/channelz/channelz.proto
index 6202e5e817..20de23f7fa 100644
--- a/src/proto/grpc/channelz/channelz.proto
+++ b/src/proto/grpc/channelz/channelz.proto
@@ -177,6 +177,7 @@ message SubchannelRef {
// SocketRef is a reference to a Socket.
message SocketRef {
+ // The globally unique id for this socket. Must be a positive number.
int64 socket_id = 3;
// An optional name associated with the socket.
string name = 4;
@@ -288,7 +289,8 @@ message SocketData {
// include stream level or TCP level flow control info.
google.protobuf.Int64Value remote_flow_control_window = 12;
- // Socket options set on this socket. May be absent.
+ // Socket options set on this socket. May be absent if 'summary' is set
+ // on GetSocketRequest.
repeated SocketOption option = 13;
}
@@ -439,12 +441,21 @@ service Channelz {
message GetTopChannelsRequest {
// start_channel_id indicates that only channels at or above this id should be
// included in the results.
+ // To request the first page, this should be set to 0. To request
+ // subsequent pages, the client generates this value by adding 1 to
+ // the highest seen result ID.
int64 start_channel_id = 1;
+
+ // If non-zero, the server will return a page of results containing
+ // at most this many items. If zero, the server will choose a
+ // reasonable page size. Must never be negative.
+ int64 max_results = 2;
}
message GetTopChannelsResponse {
// list of channels that the connection detail service knows about. Sorted in
// ascending channel_id order.
+ // Must contain at least 1 result, otherwise 'end' must be true.
repeated Channel channel = 1;
// If set, indicates that the list of channels is the final list. Requesting
// more channels can only return more if they are created after this RPC
@@ -455,12 +466,21 @@ message GetTopChannelsResponse {
message GetServersRequest {
// start_server_id indicates that only servers at or above this id should be
// included in the results.
+ // To request the first page, this must be set to 0. To request
+ // subsequent pages, the client generates this value by adding 1 to
+ // the highest seen result ID.
int64 start_server_id = 1;
+
+ // If non-zero, the server will return a page of results containing
+ // at most this many items. If zero, the server will choose a
+ // reasonable page size. Must never be negative.
+ int64 max_results = 2;
}
message GetServersResponse {
// list of servers that the connection detail service knows about. Sorted in
// ascending server_id order.
+ // Must contain at least 1 result, otherwise 'end' must be true.
repeated Server server = 1;
// If set, indicates that the list of servers is the final list. Requesting
// more servers will only return more if they are created after this RPC
@@ -483,12 +503,21 @@ message GetServerSocketsRequest {
int64 server_id = 1;
// start_socket_id indicates that only sockets at or above this id should be
// included in the results.
+ // To request the first page, this must be set to 0. To request
+ // subsequent pages, the client generates this value by adding 1 to
+ // the highest seen result ID.
int64 start_socket_id = 2;
+
+ // If non-zero, the server will return a page of results containing
+ // at most this many items. If zero, the server will choose a
+ // reasonable page size. Must never be negative.
+ int64 max_results = 3;
}
message GetServerSocketsResponse {
// list of socket refs that the connection detail service knows about. Sorted in
// ascending socket_id order.
+ // Must contain at least 1 result, otherwise 'end' must be true.
repeated SocketRef socket_ref = 1;
// If set, indicates that the list of sockets is the final list. Requesting
// more sockets will only return more if they are created after this RPC
@@ -521,6 +550,11 @@ message GetSubchannelResponse {
message GetSocketRequest {
// socket_id is the identifier of the specific socket to get.
int64 socket_id = 1;
+
+ // If true, the response will contain only high level information
+ // that is inexpensive to obtain. Fields thay may be omitted are
+ // documented.
+ bool summary = 2;
}
message GetSocketResponse {
diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD
index 97642985c9..38a7d992e0 100644
--- a/src/proto/grpc/health/v1/BUILD
+++ b/src/proto/grpc/health/v1/BUILD
@@ -29,4 +29,3 @@ filegroup(
"health.proto",
],
)
-
diff --git a/src/proto/grpc/testing/BUILD b/src/proto/grpc/testing/BUILD
index 7048911b9a..9876d5160a 100644
--- a/src/proto/grpc/testing/BUILD
+++ b/src/proto/grpc/testing/BUILD
@@ -50,7 +50,8 @@ grpc_proto_library(
grpc_proto_library(
name = "echo_proto",
srcs = ["echo.proto"],
- deps = ["echo_messages_proto"],
+ deps = ["echo_messages_proto",
+ "simple_messages_proto"],
generate_mocks = True,
)
@@ -120,6 +121,12 @@ grpc_proto_library(
)
grpc_proto_library(
+ name = "simple_messages_proto",
+ srcs = ["simple_messages.proto"],
+ has_services = False,
+)
+
+grpc_proto_library(
name = "stats_proto",
srcs = ["stats.proto"],
has_services = False,
diff --git a/src/proto/grpc/testing/compiler_test.proto b/src/proto/grpc/testing/compiler_test.proto
index db5ca48331..9fa5590a59 100644
--- a/src/proto/grpc/testing/compiler_test.proto
+++ b/src/proto/grpc/testing/compiler_test.proto
@@ -20,6 +20,9 @@
syntax = "proto3";
// Ignored detached comment
+// The comments in this file are not meant for readability
+// but rather to test to make sure that the code generator
+// properly preserves comments on files, services, and RPCs
// Ignored package leading comment
package grpc.testing;
diff --git a/src/proto/grpc/testing/echo.proto b/src/proto/grpc/testing/echo.proto
index 13e28320fc..977858f6bc 100644
--- a/src/proto/grpc/testing/echo.proto
+++ b/src/proto/grpc/testing/echo.proto
@@ -16,11 +16,15 @@
syntax = "proto3";
import "src/proto/grpc/testing/echo_messages.proto";
+import "src/proto/grpc/testing/simple_messages.proto";
package grpc.testing;
service EchoTestService {
rpc Echo(EchoRequest) returns (EchoResponse);
+ // A service which checks that the initial metadata sent over contains some
+ // expected key value pair
+ rpc CheckClientInitialMetadata(SimpleRequest) returns (SimpleResponse);
rpc RequestStream(stream EchoRequest) returns (EchoResponse);
rpc ResponseStream(EchoRequest) returns (stream EchoResponse);
rpc BidiStream(stream EchoRequest) returns (stream EchoResponse);
diff --git a/src/proto/grpc/testing/simple_messages.proto b/src/proto/grpc/testing/simple_messages.proto
new file mode 100644
index 0000000000..4b65d18909
--- /dev/null
+++ b/src/proto/grpc/testing/simple_messages.proto
@@ -0,0 +1,24 @@
+
+// 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.
+
+syntax = "proto3";
+
+package grpc.testing;
+
+message SimpleRequest {
+}
+
+message SimpleResponse {
+}
diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel
index 2e6839ef2d..6958ccdfb6 100644
--- a/src/python/grpcio/grpc/BUILD.bazel
+++ b/src/python/grpcio/grpc/BUILD.bazel
@@ -13,7 +13,6 @@ py_library(
":interceptor",
":server",
"//src/python/grpcio/grpc/_cython:cygrpc",
- "//src/python/grpcio/grpc/beta",
"//src/python/grpcio/grpc/experimental",
"//src/python/grpcio/grpc/framework",
requirement('enum34'),
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 88c5b6d5be..daf869b156 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -266,6 +266,22 @@ class StatusCode(enum.Enum):
UNAUTHENTICATED = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
+############################# gRPC Status ################################
+
+
+class Status(six.with_metaclass(abc.ABCMeta)):
+ """Describes the status of an RPC.
+
+ This is an EXPERIMENTAL API.
+
+ Attributes:
+ code: A StatusCode object to be sent to the client.
+ details: An ASCII-encodable string to be sent to the client upon
+ termination of the RPC.
+ trailing_metadata: The trailing :term:`metadata` in the RPC.
+ """
+
+
############################# gRPC Exceptions ################################
@@ -1119,6 +1135,25 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
raise NotImplementedError()
@abc.abstractmethod
+ def abort_with_status(self, status):
+ """Raises an exception to terminate the RPC with a non-OK status.
+
+ The status passed as argument will supercede any existing status code,
+ status message and trailing metadata.
+
+ This is an EXPERIMENTAL API.
+
+ Args:
+ status: A grpc.Status object. The status code in it must not be
+ StatusCode.OK.
+
+ Raises:
+ Exception: An exception is always raised to signal the abortion the
+ RPC to the gRPC runtime.
+ """
+ raise NotImplementedError()
+
+ @abc.abstractmethod
def set_code(self, code):
"""Sets the value to be used as status code upon RPC completion.
@@ -1723,7 +1758,7 @@ def server(thread_pool,
handlers. The interceptors are given control in the order they are
specified. This is an EXPERIMENTAL API.
options: An optional list of key-value pairs (channel args in gRPC runtime)
- to configure the channel.
+ to configure the channel.
maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server
will service before returning RESOURCE_EXHAUSTED status, or None to
indicate no limit.
@@ -1747,6 +1782,7 @@ __all__ = (
'Future',
'ChannelConnectivity',
'StatusCode',
+ 'Status',
'RpcError',
'RpcContext',
'Call',
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index ab154d8512..96118badad 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -175,6 +175,7 @@ def _event_handler(state, response_deserializer):
return handle_event
+#pylint: disable=too-many-statements
def _consume_request_iterator(request_iterator, state, call, request_serializer,
event_handler):
if cygrpc.is_fork_support_enabled():
@@ -498,6 +499,7 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
+ self._context = cygrpc.build_context()
def _prepare(self, request, timeout, metadata, wait_for_ready):
deadline, serialized_request, rendezvous = _start_unary_request(
@@ -527,11 +529,12 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
raise rendezvous
else:
call = self._channel.segregated_call(
- 0, self._method, None, deadline, metadata, None
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
+ self._method, None, deadline, metadata, None
if credentials is None else credentials._credentials, ((
operations,
None,
- ),))
+ ),), self._context)
event = call.next_event()
_handle_event(event, state, self._response_deserializer)
return state, call,
@@ -569,9 +572,10 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
else:
event_handler = _event_handler(state, self._response_deserializer)
call = self._managed_call(
- 0, self._method, None, deadline, metadata, None
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
+ self._method, None, deadline, metadata, None
if credentials is None else credentials._credentials,
- (operations,), event_handler)
+ (operations,), event_handler, self._context)
return _Rendezvous(state, call, self._response_deserializer,
deadline)
@@ -586,6 +590,7 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
+ self._context = cygrpc.build_context()
def __call__(self,
request,
@@ -614,9 +619,10 @@ class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
)
event_handler = _event_handler(state, self._response_deserializer)
call = self._managed_call(
- 0, self._method, None, deadline, metadata, None
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS,
+ self._method, None, deadline, metadata, None
if credentials is None else credentials._credentials,
- operationses, event_handler)
+ operationses, event_handler, self._context)
return _Rendezvous(state, call, self._response_deserializer,
deadline)
@@ -631,6 +637,7 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
+ self._context = cygrpc.build_context()
def _blocking(self, request_iterator, timeout, metadata, credentials,
wait_for_ready):
@@ -639,10 +646,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
wait_for_ready)
call = self._channel.segregated_call(
- 0, self._method, None, deadline, metadata, None
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
+ None, deadline, metadata, None
if credentials is None else credentials._credentials,
_stream_unary_invocation_operationses_and_tags(
- metadata, initial_metadata_flags))
+ metadata, initial_metadata_flags), self._context)
_consume_request_iterator(request_iterator, state, call,
self._request_serializer, None)
while True:
@@ -686,10 +694,11 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
initial_metadata_flags = _InitialMetadataFlags().with_wait_for_ready(
wait_for_ready)
call = self._managed_call(
- 0, self._method, None, deadline, metadata, None
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
+ None, deadline, metadata, None
if credentials is None else credentials._credentials,
_stream_unary_invocation_operationses(
- metadata, initial_metadata_flags), event_handler)
+ metadata, initial_metadata_flags), event_handler, self._context)
_consume_request_iterator(request_iterator, state, call,
self._request_serializer, event_handler)
return _Rendezvous(state, call, self._response_deserializer, deadline)
@@ -705,6 +714,7 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
self._method = method
self._request_serializer = request_serializer
self._response_deserializer = response_deserializer
+ self._context = cygrpc.build_context()
def __call__(self,
request_iterator,
@@ -726,9 +736,10 @@ class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
)
event_handler = _event_handler(state, self._response_deserializer)
call = self._managed_call(
- 0, self._method, None, deadline, metadata, None
+ cygrpc.PropagationConstants.GRPC_PROPAGATE_DEFAULTS, self._method,
+ None, deadline, metadata, None
if credentials is None else credentials._credentials, operationses,
- event_handler)
+ event_handler, self._context)
_consume_request_iterator(request_iterator, state, call,
self._request_serializer, event_handler)
return _Rendezvous(state, call, self._response_deserializer, deadline)
@@ -788,7 +799,7 @@ def _channel_managed_call_management(state):
# pylint: disable=too-many-arguments
def create(flags, method, host, deadline, metadata, credentials,
- operationses, event_handler):
+ operationses, event_handler, context):
"""Creates a cygrpc.IntegratedCall.
Args:
@@ -803,7 +814,7 @@ def _channel_managed_call_management(state):
started on the call.
event_handler: A behavior to call to handle the events resultant from
the operations on the call.
-
+ context: Context object for distributed tracing.
Returns:
A cygrpc.IntegratedCall with which to conduct an RPC.
"""
@@ -814,7 +825,7 @@ def _channel_managed_call_management(state):
with state.lock:
call = state.channel.integrated_call(flags, method, host, deadline,
metadata, credentials,
- operationses_and_tags)
+ operationses_and_tags, context)
if state.managed_calls == 0:
state.managed_calls = 1
_run_channel_spin_thread(state)
diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel
index cfd3a51d9b..42db7b8721 100644
--- a/src/python/grpcio/grpc/_cython/BUILD.bazel
+++ b/src/python/grpcio/grpc/_cython/BUILD.bazel
@@ -6,45 +6,47 @@ pyx_library(
name = "cygrpc",
srcs = [
"__init__.py",
- "cygrpc.pxd",
- "cygrpc.pyx",
+ "_cygrpc/_hooks.pxd.pxi",
"_cygrpc/_hooks.pyx.pxi",
- "_cygrpc/grpc_string.pyx.pxi",
+ "_cygrpc/arguments.pxd.pxi",
"_cygrpc/arguments.pyx.pxi",
+ "_cygrpc/call.pxd.pxi",
"_cygrpc/call.pyx.pxi",
+ "_cygrpc/channel.pxd.pxi",
"_cygrpc/channel.pyx.pxi",
- "_cygrpc/credentials.pyx.pxi",
+ "_cygrpc/channelz.pyx.pxi",
+ "_cygrpc/completion_queue.pxd.pxi",
"_cygrpc/completion_queue.pyx.pxi",
- "_cygrpc/event.pyx.pxi",
- "_cygrpc/fork_posix.pyx.pxi",
- "_cygrpc/metadata.pyx.pxi",
- "_cygrpc/operation.pyx.pxi",
- "_cygrpc/records.pyx.pxi",
- "_cygrpc/security.pyx.pxi",
- "_cygrpc/server.pyx.pxi",
- "_cygrpc/tag.pyx.pxi",
- "_cygrpc/time.pyx.pxi",
- "_cygrpc/grpc_gevent.pyx.pxi",
- "_cygrpc/grpc.pxi",
- "_cygrpc/_hooks.pxd.pxi",
- "_cygrpc/arguments.pxd.pxi",
- "_cygrpc/call.pxd.pxi",
- "_cygrpc/channel.pxd.pxi",
"_cygrpc/credentials.pxd.pxi",
- "_cygrpc/completion_queue.pxd.pxi",
+ "_cygrpc/credentials.pyx.pxi",
"_cygrpc/event.pxd.pxi",
+ "_cygrpc/event.pyx.pxi",
"_cygrpc/fork_posix.pxd.pxi",
+ "_cygrpc/fork_posix.pyx.pxi",
+ "_cygrpc/grpc.pxi",
+ "_cygrpc/grpc_gevent.pxd.pxi",
+ "_cygrpc/grpc_gevent.pyx.pxi",
+ "_cygrpc/grpc_string.pyx.pxi",
"_cygrpc/metadata.pxd.pxi",
+ "_cygrpc/metadata.pyx.pxi",
"_cygrpc/operation.pxd.pxi",
+ "_cygrpc/operation.pyx.pxi",
+ "_cygrpc/propagation_bits.pxd.pxi",
+ "_cygrpc/propagation_bits.pyx.pxi",
"_cygrpc/records.pxd.pxi",
+ "_cygrpc/records.pyx.pxi",
"_cygrpc/security.pxd.pxi",
+ "_cygrpc/security.pyx.pxi",
"_cygrpc/server.pxd.pxi",
+ "_cygrpc/server.pyx.pxi",
"_cygrpc/tag.pxd.pxi",
+ "_cygrpc/tag.pyx.pxi",
"_cygrpc/time.pxd.pxi",
- "_cygrpc/grpc_gevent.pxd.pxi",
+ "_cygrpc/time.pyx.pxi",
+ "cygrpc.pxd",
+ "cygrpc.pyx",
],
deps = [
"//:grpc",
],
)
-
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
index 38cf629dc2..cd4a51a635 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
@@ -15,3 +15,18 @@
cdef object _custom_op_on_c_call(int op, grpc_call *call):
raise NotImplementedError("No custom hooks are implemented")
+
+def install_census_context_from_call(Call call):
+ pass
+
+def uninstall_context():
+ pass
+
+def build_context():
+ pass
+
+cdef class CensusContext:
+ pass
+
+def set_census_context_on_call(_CallState call_state, CensusContext census_ctx):
+ pass
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index a81ff4d823..135d224095 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -159,7 +159,8 @@ cdef void _call(
_ChannelState channel_state, _CallState call_state,
grpc_completion_queue *c_completion_queue, on_success, int flags, method,
host, object deadline, CallCredentials credentials,
- object operationses_and_user_tags, object metadata) except *:
+ object operationses_and_user_tags, object metadata,
+ object context) except *:
"""Invokes an RPC.
Args:
@@ -185,6 +186,7 @@ cdef void _call(
which is an object to be used as a tag. A SendInitialMetadataOperation
must be present in the first element of this value.
metadata: The metadata for this call.
+ context: Context object for distributed tracing.
"""
cdef grpc_slice method_slice
cdef grpc_slice host_slice
@@ -208,6 +210,8 @@ cdef void _call(
grpc_slice_unref(method_slice)
if host_slice_ptr:
grpc_slice_unref(host_slice)
+ if context is not None:
+ set_census_context_on_call(call_state, context)
if credentials is not None:
c_call_credentials = credentials.c()
c_call_error = grpc_call_set_credentials(
@@ -257,7 +261,8 @@ cdef class IntegratedCall:
cdef IntegratedCall _integrated_call(
_ChannelState state, int flags, method, host, object deadline,
- object metadata, CallCredentials credentials, operationses_and_user_tags):
+ object metadata, CallCredentials credentials, operationses_and_user_tags,
+ object context):
call_state = _CallState()
def on_success(started_tags):
@@ -266,7 +271,7 @@ cdef IntegratedCall _integrated_call(
_call(
state, call_state, state.c_call_completion_queue, on_success, flags,
- method, host, deadline, credentials, operationses_and_user_tags, metadata)
+ method, host, deadline, credentials, operationses_and_user_tags, metadata, context)
return IntegratedCall(state, call_state)
@@ -308,7 +313,8 @@ cdef class SegregatedCall:
cdef SegregatedCall _segregated_call(
_ChannelState state, int flags, method, host, object deadline,
- object metadata, CallCredentials credentials, operationses_and_user_tags):
+ object metadata, CallCredentials credentials, operationses_and_user_tags,
+ object context):
cdef _CallState call_state = _CallState()
cdef SegregatedCall segregated_call
cdef grpc_completion_queue *c_completion_queue
@@ -325,7 +331,8 @@ cdef SegregatedCall _segregated_call(
try:
_call(
state, call_state, c_completion_queue, on_success, flags, method, host,
- deadline, credentials, operationses_and_user_tags, metadata)
+ deadline, credentials, operationses_and_user_tags, metadata,
+ context)
except:
_destroy_c_completion_queue(c_completion_queue)
raise
@@ -443,10 +450,11 @@ cdef class Channel:
def integrated_call(
self, int flags, method, host, object deadline, object metadata,
- CallCredentials credentials, operationses_and_tags):
+ CallCredentials credentials, operationses_and_tags,
+ object context = None):
return _integrated_call(
self._state, flags, method, host, deadline, metadata, credentials,
- operationses_and_tags)
+ operationses_and_tags, context)
def next_call_event(self):
def on_success(tag):
@@ -461,10 +469,11 @@ cdef class Channel:
def segregated_call(
self, int flags, method, host, object deadline, object metadata,
- CallCredentials credentials, operationses_and_tags):
+ CallCredentials credentials, operationses_and_tags,
+ object context = None):
return _segregated_call(
self._state, flags, method, host, deadline, metadata, credentials,
- operationses_and_tags)
+ operationses_and_tags, context)
def check_connectivity_state(self, bint try_to_connect):
with self._state.condition:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
new file mode 100644
index 0000000000..36c8cd121c
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
@@ -0,0 +1,71 @@
+# 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.
+
+
+def channelz_get_top_channels(start_channel_id):
+ cdef char *c_returned_str = grpc_channelz_get_top_channels(
+ start_channel_id,
+ )
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get top channels, please ensure your' \
+ ' start_channel_id==%s is valid' % start_channel_id)
+ return c_returned_str
+
+def channelz_get_servers(start_server_id):
+ cdef char *c_returned_str = grpc_channelz_get_servers(start_server_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get servers, please ensure your' \
+ ' start_server_id==%s is valid' % start_server_id)
+ return c_returned_str
+
+def channelz_get_server(server_id):
+ cdef char *c_returned_str = grpc_channelz_get_server(server_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the server, please ensure your' \
+ ' server_id==%s is valid' % server_id)
+ return c_returned_str
+
+def channelz_get_server_sockets(server_id, start_socket_id, max_results):
+ cdef char *c_returned_str = grpc_channelz_get_server_sockets(
+ server_id,
+ start_socket_id,
+ max_results,
+ )
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get server sockets, please ensure your' \
+ ' server_id==%s and start_socket_id==%s and' \
+ ' max_results==%s is valid' %
+ (server_id, start_socket_id, max_results))
+ return c_returned_str
+
+def channelz_get_channel(channel_id):
+ cdef char *c_returned_str = grpc_channelz_get_channel(channel_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the channel, please ensure your' \
+ ' channel_id==%s is valid' % (channel_id))
+ return c_returned_str
+
+def channelz_get_subchannel(subchannel_id):
+ cdef char *c_returned_str = grpc_channelz_get_subchannel(subchannel_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the subchannel, please ensure your' \
+ ' subchannel_id==%s is valid' % (subchannel_id))
+ return c_returned_str
+
+def channelz_get_socket(socket_id):
+ cdef char *c_returned_str = grpc_channelz_get_socket(socket_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the socket, please ensure your' \
+ ' socket_id==%s is valid' % (socket_id))
+ return c_returned_str
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
index 8d73215247..1cef726970 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
@@ -15,7 +15,7 @@
cdef class CallCredentials:
- cdef grpc_call_credentials *c(self)
+ cdef grpc_call_credentials *c(self) except *
# TODO(https://github.com/grpc/grpc/issues/12531): remove.
cdef grpc_call_credentials *c_credentials
@@ -36,7 +36,7 @@ cdef class MetadataPluginCallCredentials(CallCredentials):
cdef readonly object _metadata_plugin
cdef readonly bytes _name
- cdef grpc_call_credentials *c(self)
+ cdef grpc_call_credentials *c(self) except *
cdef grpc_call_credentials *_composition(call_credentialses)
@@ -46,12 +46,12 @@ cdef class CompositeCallCredentials(CallCredentials):
cdef readonly tuple _call_credentialses
- cdef grpc_call_credentials *c(self)
+ cdef grpc_call_credentials *c(self) except *
cdef class ChannelCredentials:
- cdef grpc_channel_credentials *c(self)
+ cdef grpc_channel_credentials *c(self) except *
# TODO(https://github.com/grpc/grpc/issues/12531): remove.
cdef grpc_channel_credentials *c_credentials
@@ -68,7 +68,7 @@ cdef class SSLChannelCredentials(ChannelCredentials):
cdef readonly object _private_key
cdef readonly object _certificate_chain
- cdef grpc_channel_credentials *c(self)
+ cdef grpc_channel_credentials *c(self) except *
cdef class CompositeChannelCredentials(ChannelCredentials):
@@ -76,7 +76,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials):
cdef readonly tuple _call_credentialses
cdef readonly ChannelCredentials _channel_credentials
- cdef grpc_channel_credentials *c(self)
+ cdef grpc_channel_credentials *c(self) except *
cdef class ServerCertificateConfig:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 63048e8da0..2f51be40ce 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -35,7 +35,7 @@ def _spawn_callback_async(callback, args):
cdef class CallCredentials:
- cdef grpc_call_credentials *c(self):
+ cdef grpc_call_credentials *c(self) except *:
raise NotImplementedError()
@@ -61,6 +61,7 @@ cdef int _get_metadata(
cdef void _destroy(void *state) with gil:
cpython.Py_DECREF(<object>state)
+ grpc_shutdown()
cdef class MetadataPluginCallCredentials(CallCredentials):
@@ -69,13 +70,14 @@ cdef class MetadataPluginCallCredentials(CallCredentials):
self._metadata_plugin = metadata_plugin
self._name = name
- cdef grpc_call_credentials *c(self):
+ cdef grpc_call_credentials *c(self) except *:
cdef grpc_metadata_credentials_plugin c_metadata_plugin
c_metadata_plugin.get_metadata = _get_metadata
c_metadata_plugin.destroy = _destroy
c_metadata_plugin.state = <void *>self._metadata_plugin
c_metadata_plugin.type = self._name
cpython.Py_INCREF(self._metadata_plugin)
+ fork_handlers_and_grpc_init()
return grpc_metadata_credentials_create_from_plugin(c_metadata_plugin, NULL)
@@ -101,13 +103,13 @@ cdef class CompositeCallCredentials(CallCredentials):
def __cinit__(self, call_credentialses):
self._call_credentialses = call_credentialses
- cdef grpc_call_credentials *c(self):
+ cdef grpc_call_credentials *c(self) except *:
return _composition(self._call_credentialses)
cdef class ChannelCredentials:
- cdef grpc_channel_credentials *c(self):
+ cdef grpc_channel_credentials *c(self) except *:
raise NotImplementedError()
@@ -129,11 +131,13 @@ cdef class SSLSessionCacheLRU:
cdef class SSLChannelCredentials(ChannelCredentials):
def __cinit__(self, pem_root_certificates, private_key, certificate_chain):
+ if pem_root_certificates is not None and not isinstance(pem_root_certificates, bytes):
+ raise TypeError('expected certificate to be bytes, got %s' % (type(pem_root_certificates)))
self._pem_root_certificates = pem_root_certificates
self._private_key = private_key
self._certificate_chain = certificate_chain
- cdef grpc_channel_credentials *c(self):
+ cdef grpc_channel_credentials *c(self) except *:
cdef const char *c_pem_root_certificates
cdef grpc_ssl_pem_key_cert_pair c_pem_key_certificate_pair
if self._pem_root_certificates is None:
@@ -162,7 +166,7 @@ cdef class CompositeChannelCredentials(ChannelCredentials):
self._call_credentialses = call_credentialses
self._channel_credentials = channel_credentials
- cdef grpc_channel_credentials *c(self):
+ cdef grpc_channel_credentials *c(self) except *:
cdef grpc_channel_credentials *c_channel_credentials
c_channel_credentials = self._channel_credentials.c()
cdef grpc_call_credentials *c_call_credentials_composition = _composition(
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 23428f0b0c..fc7a9ba439 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -13,6 +13,7 @@
# limitations under the License.
cimport libc.time
+from libc.stdint cimport intptr_t
# Typedef types with approximately the same semantics to provide their names to
@@ -121,7 +122,6 @@ cdef extern from "grpc/grpc.h":
GRPC_STATUS_DATA_LOSS
GRPC_STATUS__DO_NOT_USE
- const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
const char *GRPC_ARG_ENABLE_CENSUS
const char *GRPC_ARG_MAX_CONCURRENT_STREAMS
const char *GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH
@@ -190,12 +190,6 @@ cdef extern from "grpc/grpc.h":
size_t arguments_length "num_args"
grpc_arg *arguments "args"
- ctypedef enum grpc_compression_level:
- GRPC_COMPRESS_LEVEL_NONE
- GRPC_COMPRESS_LEVEL_LOW
- GRPC_COMPRESS_LEVEL_MED
- GRPC_COMPRESS_LEVEL_HIGH
-
ctypedef enum grpc_stream_compression_level:
GRPC_STREAM_COMPRESS_LEVEL_NONE
GRPC_STREAM_COMPRESS_LEVEL_LOW
@@ -391,6 +385,16 @@ cdef extern from "grpc/grpc.h":
void grpc_server_cancel_all_calls(grpc_server *server) nogil
void grpc_server_destroy(grpc_server *server) nogil
+ char* grpc_channelz_get_top_channels(intptr_t start_channel_id)
+ char* grpc_channelz_get_servers(intptr_t start_server_id)
+ char* grpc_channelz_get_server(intptr_t server_id)
+ char* grpc_channelz_get_server_sockets(intptr_t server_id,
+ intptr_t start_socket_id,
+ intptr_t max_results)
+ char* grpc_channelz_get_channel(intptr_t channel_id)
+ char* grpc_channelz_get_subchannel(intptr_t subchannel_id)
+ char* grpc_channelz_get_socket(intptr_t socket_id)
+
cdef extern from "grpc/grpc_security.h":
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi
index f9a1b2856d..a1618d04d0 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_gevent.pyx.pxi
@@ -266,7 +266,7 @@ cdef grpc_error* socket_listen(grpc_custom_socket* socket) with gil:
(<SocketWrapper>socket.impl).socket.listen(50)
return grpc_error_none()
-cdef void accept_callback_cython(SocketWrapper s):
+cdef void accept_callback_cython(SocketWrapper s) except *:
try:
conn, address = s.socket.accept()
sw = SocketWrapper()
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi
index a18c365807..fc72ac1576 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pxd.pxi
@@ -14,10 +14,10 @@
cdef void _store_c_metadata(
- metadata, grpc_metadata **c_metadata, size_t *c_count)
+ metadata, grpc_metadata **c_metadata, size_t *c_count) except *
-cdef void _release_c_metadata(grpc_metadata *c_metadata, int count)
+cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) except *
cdef tuple _metadatum(grpc_slice key_slice, grpc_slice value_slice)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi
index 53f0c7f0bb..caf867b569 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/metadata.pyx.pxi
@@ -25,7 +25,7 @@ _Metadatum = collections.namedtuple('_Metadatum', ('key', 'value',))
cdef void _store_c_metadata(
- metadata, grpc_metadata **c_metadata, size_t *c_count):
+ metadata, grpc_metadata **c_metadata, size_t *c_count) except *:
if metadata is None:
c_count[0] = 0
c_metadata[0] = NULL
@@ -45,7 +45,7 @@ cdef void _store_c_metadata(
c_metadata[0][index].value = _slice_from_bytes(encoded_value)
-cdef void _release_c_metadata(grpc_metadata *c_metadata, int count):
+cdef void _release_c_metadata(grpc_metadata *c_metadata, int count) except *:
if 0 < count:
for index in range(count):
grpc_slice_unref(c_metadata[index].key)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi
index 69a2a4989e..c9df32dadf 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pxd.pxi
@@ -15,8 +15,8 @@
cdef class Operation:
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
# TODO(https://github.com/grpc/grpc/issues/7950): Eliminate this!
cdef grpc_op c_op
@@ -29,8 +29,8 @@ cdef class SendInitialMetadataOperation(Operation):
cdef grpc_metadata *_c_initial_metadata
cdef size_t _c_initial_metadata_count
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class SendMessageOperation(Operation):
@@ -39,16 +39,16 @@ cdef class SendMessageOperation(Operation):
cdef readonly int _flags
cdef grpc_byte_buffer *_c_message_byte_buffer
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class SendCloseFromClientOperation(Operation):
cdef readonly int _flags
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class SendStatusFromServerOperation(Operation):
@@ -61,8 +61,8 @@ cdef class SendStatusFromServerOperation(Operation):
cdef size_t _c_trailing_metadata_count
cdef grpc_slice _c_details
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class ReceiveInitialMetadataOperation(Operation):
@@ -71,8 +71,8 @@ cdef class ReceiveInitialMetadataOperation(Operation):
cdef tuple _initial_metadata
cdef grpc_metadata_array _c_initial_metadata
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class ReceiveMessageOperation(Operation):
@@ -81,8 +81,8 @@ cdef class ReceiveMessageOperation(Operation):
cdef grpc_byte_buffer *_c_message_byte_buffer
cdef bytes _message
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class ReceiveStatusOnClientOperation(Operation):
@@ -97,8 +97,8 @@ cdef class ReceiveStatusOnClientOperation(Operation):
cdef str _details
cdef str _error_string
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
cdef class ReceiveCloseOnServerOperation(Operation):
@@ -107,5 +107,5 @@ cdef class ReceiveCloseOnServerOperation(Operation):
cdef object _cancelled
cdef int _c_cancelled
- cdef void c(self)
- cdef void un_c(self)
+ cdef void c(self) except *
+ cdef void un_c(self) except *
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi
index 454627f570..c8a390106a 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/operation.pyx.pxi
@@ -15,10 +15,10 @@
cdef class Operation:
- cdef void c(self):
+ cdef void c(self) except *:
raise NotImplementedError()
- cdef void un_c(self):
+ cdef void un_c(self) except *:
raise NotImplementedError()
@@ -31,7 +31,7 @@ cdef class SendInitialMetadataOperation(Operation):
def type(self):
return GRPC_OP_SEND_INITIAL_METADATA
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_SEND_INITIAL_METADATA
self.c_op.flags = self._flags
_store_c_metadata(
@@ -41,7 +41,7 @@ cdef class SendInitialMetadataOperation(Operation):
self.c_op.data.send_initial_metadata.count = self._c_initial_metadata_count
self.c_op.data.send_initial_metadata.maybe_compression_level.is_set = 0
- cdef void un_c(self):
+ cdef void un_c(self) except *:
_release_c_metadata(
self._c_initial_metadata, self._c_initial_metadata_count)
@@ -55,7 +55,7 @@ cdef class SendMessageOperation(Operation):
def type(self):
return GRPC_OP_SEND_MESSAGE
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_SEND_MESSAGE
self.c_op.flags = self._flags
cdef grpc_slice message_slice = grpc_slice_from_copied_buffer(
@@ -65,7 +65,7 @@ cdef class SendMessageOperation(Operation):
grpc_slice_unref(message_slice)
self.c_op.data.send_message.send_message = self._c_message_byte_buffer
- cdef void un_c(self):
+ cdef void un_c(self) except *:
grpc_byte_buffer_destroy(self._c_message_byte_buffer)
@@ -77,11 +77,11 @@ cdef class SendCloseFromClientOperation(Operation):
def type(self):
return GRPC_OP_SEND_CLOSE_FROM_CLIENT
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT
self.c_op.flags = self._flags
- cdef void un_c(self):
+ cdef void un_c(self) except *:
pass
@@ -96,7 +96,7 @@ cdef class SendStatusFromServerOperation(Operation):
def type(self):
return GRPC_OP_SEND_STATUS_FROM_SERVER
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
self.c_op.flags = self._flags
_store_c_metadata(
@@ -110,7 +110,7 @@ cdef class SendStatusFromServerOperation(Operation):
self._c_details = _slice_from_bytes(_encode(self._details))
self.c_op.data.send_status_from_server.status_details = &self._c_details
- cdef void un_c(self):
+ cdef void un_c(self) except *:
grpc_slice_unref(self._c_details)
_release_c_metadata(
self._c_trailing_metadata, self._c_trailing_metadata_count)
@@ -124,14 +124,14 @@ cdef class ReceiveInitialMetadataOperation(Operation):
def type(self):
return GRPC_OP_RECV_INITIAL_METADATA
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_RECV_INITIAL_METADATA
self.c_op.flags = self._flags
grpc_metadata_array_init(&self._c_initial_metadata)
self.c_op.data.receive_initial_metadata.receive_initial_metadata = (
&self._c_initial_metadata)
- cdef void un_c(self):
+ cdef void un_c(self) except *:
self._initial_metadata = _metadata(&self._c_initial_metadata)
grpc_metadata_array_destroy(&self._c_initial_metadata)
@@ -147,13 +147,13 @@ cdef class ReceiveMessageOperation(Operation):
def type(self):
return GRPC_OP_RECV_MESSAGE
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_RECV_MESSAGE
self.c_op.flags = self._flags
self.c_op.data.receive_message.receive_message = (
&self._c_message_byte_buffer)
- cdef void un_c(self):
+ cdef void un_c(self) except *:
cdef grpc_byte_buffer_reader message_reader
cdef bint message_reader_status
cdef grpc_slice message_slice
@@ -189,7 +189,7 @@ cdef class ReceiveStatusOnClientOperation(Operation):
def type(self):
return GRPC_OP_RECV_STATUS_ON_CLIENT
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT
self.c_op.flags = self._flags
grpc_metadata_array_init(&self._c_trailing_metadata)
@@ -202,7 +202,7 @@ cdef class ReceiveStatusOnClientOperation(Operation):
self.c_op.data.receive_status_on_client.error_string = (
&self._c_error_string)
- cdef void un_c(self):
+ cdef void un_c(self) except *:
self._trailing_metadata = _metadata(&self._c_trailing_metadata)
grpc_metadata_array_destroy(&self._c_trailing_metadata)
self._code = self._c_code
@@ -235,12 +235,12 @@ cdef class ReceiveCloseOnServerOperation(Operation):
def type(self):
return GRPC_OP_RECV_CLOSE_ON_SERVER
- cdef void c(self):
+ cdef void c(self) except *:
self.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER
self.c_op.flags = self._flags
self.c_op.data.receive_close_on_server.cancelled = &self._c_cancelled
- cdef void un_c(self):
+ cdef void un_c(self) except *:
self._cancelled = bool(self._c_cancelled)
def cancelled(self):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi
new file mode 100644
index 0000000000..cd6e94c816
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pxd.pxi
@@ -0,0 +1,20 @@
+# 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.
+
+cdef extern from "grpc/impl/codegen/propagation_bits.h":
+ cdef int _GRPC_PROPAGATE_DEADLINE "GRPC_PROPAGATE_DEADLINE"
+ cdef int _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT "GRPC_PROPAGATE_CENSUS_STATS_CONTEXT"
+ cdef int _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT "GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT"
+ cdef int _GRPC_PROPAGATE_CANCELLATION "GRPC_PROPAGATE_CANCELLATION"
+ cdef int _GRPC_PROPAGATE_DEFAULTS "GRPC_PROPAGATE_DEFAULTS"
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi
new file mode 100644
index 0000000000..2dcc76a2db
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/propagation_bits.pyx.pxi
@@ -0,0 +1,20 @@
+# 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.
+
+class PropagationConstants:
+ GRPC_PROPAGATE_DEADLINE = _GRPC_PROPAGATE_DEADLINE
+ GRPC_PROPAGATE_CENSUS_STATS_CONTEXT = _GRPC_PROPAGATE_CENSUS_STATS_CONTEXT
+ GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT = _GRPC_PROPAGATE_CENSUS_TRACING_CONTEXT
+ GRPC_PROPAGATE_CANCELLATION = _GRPC_PROPAGATE_CANCELLATION
+ GRPC_PROPAGATE_DEFAULTS = _GRPC_PROPAGATE_DEFAULTS
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi
index f9a3b5e8f4..d8ba1ea9bd 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pxd.pxi
@@ -32,7 +32,7 @@ cdef class _RequestCallTag(_Tag):
cdef CallDetails call_details
cdef grpc_metadata_array c_invocation_metadata
- cdef void prepare(self)
+ cdef void prepare(self) except *
cdef RequestCallEvent event(self, grpc_event c_event)
@@ -44,7 +44,7 @@ cdef class _BatchOperationTag(_Tag):
cdef grpc_op *c_ops
cdef size_t c_nops
- cdef void prepare(self)
+ cdef void prepare(self) except *
cdef BatchOperationEvent event(self, grpc_event c_event)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi
index aaca458442..be5013c8f7 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/tag.pyx.pxi
@@ -35,7 +35,7 @@ cdef class _RequestCallTag(_Tag):
self.call = None
self.call_details = None
- cdef void prepare(self):
+ cdef void prepare(self) except *:
self.call = Call()
self.call_details = CallDetails()
grpc_metadata_array_init(&self.c_invocation_metadata)
@@ -55,7 +55,7 @@ cdef class _BatchOperationTag:
self._operations = operations
self._retained_call = call
- cdef void prepare(self):
+ cdef void prepare(self) except *:
self.c_nops = 0 if self._operations is None else len(self._operations)
if 0 < self.c_nops:
self.c_ops = <grpc_op *>gpr_malloc(sizeof(grpc_op) * self.c_nops)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi
index ce67c61eaf..1319ac0481 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pxd.pxi
@@ -16,4 +16,4 @@
cdef gpr_timespec _timespec_from_time(object time)
-cdef double _time_from_timespec(gpr_timespec timespec)
+cdef double _time_from_timespec(gpr_timespec timespec) except *
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi
index 7a668680b8..c452dd54f8 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/time.pyx.pxi
@@ -24,7 +24,7 @@ cdef gpr_timespec _timespec_from_time(object time):
return timespec
-cdef double _time_from_timespec(gpr_timespec timespec):
+cdef double _time_from_timespec(gpr_timespec timespec) except *:
cdef gpr_timespec real_timespec = gpr_convert_clock_type(
timespec, GPR_CLOCK_REALTIME)
return <double>real_timespec.seconds + <double>real_timespec.nanoseconds / 1e9
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd
index 8258b857bc..64cae6b34d 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pxd
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd
@@ -29,6 +29,7 @@ include "_cygrpc/server.pxd.pxi"
include "_cygrpc/tag.pxd.pxi"
include "_cygrpc/time.pxd.pxi"
include "_cygrpc/_hooks.pxd.pxi"
+include "_cygrpc/propagation_bits.pxd.pxi"
include "_cygrpc/grpc_gevent.pxd.pxi"
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index ae5c07bfc8..ce98fa3a8e 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -35,6 +35,8 @@ include "_cygrpc/server.pyx.pxi"
include "_cygrpc/tag.pyx.pxi"
include "_cygrpc/time.pyx.pxi"
include "_cygrpc/_hooks.pyx.pxi"
+include "_cygrpc/channelz.pyx.pxi"
+include "_cygrpc/propagation_bits.pyx.pxi"
include "_cygrpc/grpc_gevent.pyx.pxi"
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 42b3a1ad49..7a9f173947 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.17.0.dev0"""
+__version__ = """1.18.0.dev0"""
diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py
index 4345114026..fc0ad77eb9 100644
--- a/src/python/grpcio/grpc/_interceptor.py
+++ b/src/python/grpcio/grpc/_interceptor.py
@@ -135,9 +135,12 @@ class _FailureOutcome(grpc.RpcError, grpc.Future, grpc.Call):
def __iter__(self):
return self
- def next(self):
+ def __next__(self):
raise self._exception
+ def next(self):
+ return self.__next__()
+
class _UnaryOutcome(grpc.Call, grpc.Future):
@@ -232,8 +235,8 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
credentials=new_credentials,
wait_for_ready=new_wait_for_ready)
return _UnaryOutcome(response, call)
- except grpc.RpcError:
- raise
+ except grpc.RpcError as rpc_error:
+ return rpc_error
except Exception as exception: # pylint:disable=broad-except
return _FailureOutcome(exception, sys.exc_info()[2])
@@ -354,8 +357,8 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
credentials=new_credentials,
wait_for_ready=new_wait_for_ready)
return _UnaryOutcome(response, call)
- except grpc.RpcError:
- raise
+ except grpc.RpcError as rpc_error:
+ return rpc_error
except Exception as exception: # pylint:disable=broad-except
return _FailureOutcome(exception, sys.exc_info()[2])
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
index 7276a7fd90..3bbfa47da5 100644
--- a/src/python/grpcio/grpc/_server.py
+++ b/src/python/grpcio/grpc/_server.py
@@ -291,6 +291,10 @@ class _Context(grpc.ServicerContext):
self._state.abortion = Exception()
raise self._state.abortion
+ def abort_with_status(self, status):
+ self._state.trailing_metadata = status.trailing_metadata
+ self.abort(status.code, status.details)
+
def set_code(self, code):
with self._state.condition:
self._state.code = code
@@ -480,43 +484,51 @@ def _status(rpc_event, state, serialized_response):
def _unary_response_in_pool(rpc_event, state, behavior, argument_thunk,
request_deserializer, response_serializer):
- argument = argument_thunk()
- if argument is not None:
- response, proceed = _call_behavior(rpc_event, state, behavior, argument,
- request_deserializer)
- if proceed:
- serialized_response = _serialize_response(
- rpc_event, state, response, response_serializer)
- if serialized_response is not None:
- _status(rpc_event, state, serialized_response)
+ cygrpc.install_census_context_from_call(rpc_event.call)
+ try:
+ argument = argument_thunk()
+ if argument is not None:
+ response, proceed = _call_behavior(rpc_event, state, behavior,
+ argument, request_deserializer)
+ if proceed:
+ serialized_response = _serialize_response(
+ rpc_event, state, response, response_serializer)
+ if serialized_response is not None:
+ _status(rpc_event, state, serialized_response)
+ finally:
+ cygrpc.uninstall_context()
def _stream_response_in_pool(rpc_event, state, behavior, argument_thunk,
request_deserializer, response_serializer):
- argument = argument_thunk()
- if argument is not None:
- response_iterator, proceed = _call_behavior(
- rpc_event, state, behavior, argument, request_deserializer)
- if proceed:
- while True:
- response, proceed = _take_response_from_response_iterator(
- rpc_event, state, response_iterator)
- if proceed:
- if response is None:
- _status(rpc_event, state, None)
- break
- else:
- serialized_response = _serialize_response(
- rpc_event, state, response, response_serializer)
- if serialized_response is not None:
- proceed = _send_response(rpc_event, state,
- serialized_response)
- if not proceed:
- break
- else:
+ cygrpc.install_census_context_from_call(rpc_event.call)
+ try:
+ argument = argument_thunk()
+ if argument is not None:
+ response_iterator, proceed = _call_behavior(
+ rpc_event, state, behavior, argument, request_deserializer)
+ if proceed:
+ while True:
+ response, proceed = _take_response_from_response_iterator(
+ rpc_event, state, response_iterator)
+ if proceed:
+ if response is None:
+ _status(rpc_event, state, None)
break
- else:
- break
+ else:
+ serialized_response = _serialize_response(
+ rpc_event, state, response, response_serializer)
+ if serialized_response is not None:
+ proceed = _send_response(
+ rpc_event, state, serialized_response)
+ if not proceed:
+ break
+ else:
+ break
+ else:
+ break
+ finally:
+ cygrpc.uninstall_context()
def _handle_unary_unary(rpc_event, state, method_handler, thread_pool):
diff --git a/src/python/grpcio/grpc/beta/BUILD.bazel b/src/python/grpcio/grpc/beta/BUILD.bazel
deleted file mode 100644
index 731be5cb25..0000000000
--- a/src/python/grpcio/grpc/beta/BUILD.bazel
+++ /dev/null
@@ -1,58 +0,0 @@
-load("@grpc_python_dependencies//:requirements.bzl", "requirement")
-package(default_visibility = ["//visibility:public"])
-
-py_library(
- name = "beta",
- srcs = ["__init__.py",],
- deps = [
- ":client_adaptations",
- ":metadata",
- ":server_adaptations",
- ":implementations",
- ":interfaces",
- ":utilities",
- ],
-)
-
-py_library(
- name = "client_adaptations",
- srcs = ["_client_adaptations.py"],
- imports=["../../",]
-)
-
-py_library(
- name = "metadata",
- srcs = ["_metadata.py"],
-)
-
-py_library(
- name = "server_adaptations",
- srcs = ["_server_adaptations.py"],
- imports=["../../",],
-)
-
-py_library(
- name = "implementations",
- srcs = ["implementations.py"],
- imports=["../../",],
-)
-
-py_library(
- name = "interfaces",
- srcs = ["interfaces.py"],
- deps = [
- requirement("six"),
- ],
- imports=["../../",],
-)
-
-py_library(
- name = "utilities",
- srcs = ["utilities.py"],
- deps = [
- ":implementations",
- ":interfaces",
- "//src/python/grpcio/grpc/framework/foundation",
- ],
-)
-
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 53cc0736af..c6ca970bee 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -215,6 +215,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -321,15 +322,15 @@ CORE_SOURCE_FILES = [
'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',
- 'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
+ 'src/core/ext/filters/client_channel/server_address.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 71113e68d9..2e91818d2c 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_channelz/.gitignore b/src/python/grpcio_channelz/.gitignore
new file mode 100644
index 0000000000..0c5da6b5af
--- /dev/null
+++ b/src/python/grpcio_channelz/.gitignore
@@ -0,0 +1,6 @@
+*.proto
+*_pb2.py
+*_pb2_grpc.py
+build/
+grpcio_channelz.egg-info/
+dist/
diff --git a/src/python/grpcio_channelz/MANIFEST.in b/src/python/grpcio_channelz/MANIFEST.in
new file mode 100644
index 0000000000..ee93e21a69
--- /dev/null
+++ b/src/python/grpcio_channelz/MANIFEST.in
@@ -0,0 +1,4 @@
+include grpc_version.py
+recursive-include grpc_channelz *.py
+global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_channelz/README.rst b/src/python/grpcio_channelz/README.rst
new file mode 100644
index 0000000000..efeaa56064
--- /dev/null
+++ b/src/python/grpcio_channelz/README.rst
@@ -0,0 +1,9 @@
+gRPC Python Channelz package
+==============================
+
+Channelz is a live debug tool in gRPC Python.
+
+Dependencies
+------------
+
+Depends on the `grpcio` package, available from PyPI via `pip install grpcio`.
diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py
new file mode 100644
index 0000000000..7f158c2a4b
--- /dev/null
+++ b/src/python/grpcio_channelz/channelz_commands.py
@@ -0,0 +1,67 @@
+# 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.
+"""Provides distutils command classes for the GRPC Python setup process."""
+
+import os
+import shutil
+
+import setuptools
+
+ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+CHANNELZ_PROTO = os.path.join(ROOT_DIR,
+ '../../proto/grpc/channelz/channelz.proto')
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
+
+
+class Preprocess(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto and LICENSE from
+ the root directory"""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ if os.path.isfile(CHANNELZ_PROTO):
+ shutil.copyfile(CHANNELZ_PROTO,
+ os.path.join(ROOT_DIR,
+ 'grpc_channelz/v1/channelz.proto'))
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
+
+
+class BuildPackageProtos(setuptools.Command):
+ """Command to generate project *_pb2.py modules from proto files."""
+
+ description = 'build grpc protobuf modules'
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ # due to limitations of the proto generator, we require that only *one*
+ # directory is provided as an 'include' directory. We assume it's the '' key
+ # to `self.distribution.package_dir` (and get a key error if it's not
+ # there).
+ from grpc_tools import command
+ command.build_package_protos(self.distribution.package_dir[''])
diff --git a/src/python/grpcio_channelz/grpc_channelz/__init__.py b/src/python/grpcio_channelz/grpc_channelz/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/__init__.py
@@ -0,0 +1,13 @@
+# 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.
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel
new file mode 100644
index 0000000000..aae8cedb76
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel
@@ -0,0 +1,38 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library")
+
+package(default_visibility = ["//visibility:public"])
+
+genrule(
+ name = "mv_channelz_proto",
+ srcs = [
+ "//src/proto/grpc/channelz:channelz_proto_file",
+ ],
+ outs = ["channelz.proto",],
+ cmd = "cp $< $@",
+)
+
+py_proto_library(
+ name = "py_channelz_proto",
+ protos = ["mv_channelz_proto",],
+ imports = [
+ "external/com_google_protobuf/src/",
+ ],
+ inputs = [
+ "@com_google_protobuf//:well_known_protos",
+ ],
+ with_grpc = True,
+ deps = [
+ requirement('protobuf'),
+ ],
+)
+
+py_library(
+ name = "grpc_channelz",
+ srcs = ["channelz.py",],
+ deps = [
+ ":py_channelz_proto",
+ "//src/python/grpcio/grpc:grpcio",
+ ],
+ imports=["../../",],
+)
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py
@@ -0,0 +1,13 @@
+# 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.
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
new file mode 100644
index 0000000000..00eca311dc
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
@@ -0,0 +1,142 @@
+# 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.
+"""Channelz debug service implementation in gRPC Python."""
+
+import grpc
+from grpc._cython import cygrpc
+
+import grpc_channelz.v1.channelz_pb2 as _channelz_pb2
+import grpc_channelz.v1.channelz_pb2_grpc as _channelz_pb2_grpc
+
+from google.protobuf import json_format
+
+
+class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer):
+ """Servicer handling RPCs for service statuses."""
+
+ @staticmethod
+ def GetTopChannels(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_top_channels(request.start_channel_id),
+ _channelz_pb2.GetTopChannelsResponse(),
+ )
+ except (ValueError, json_format.ParseError) as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetServers(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_servers(request.start_server_id),
+ _channelz_pb2.GetServersResponse(),
+ )
+ except (ValueError, json_format.ParseError) as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetServer(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_server(request.server_id),
+ _channelz_pb2.GetServerResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetServerSockets(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_server_sockets(request.server_id,
+ request.start_socket_id,
+ request.max_results),
+ _channelz_pb2.GetServerSocketsResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetChannel(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_channel(request.channel_id),
+ _channelz_pb2.GetChannelResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetSubchannel(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_subchannel(request.subchannel_id),
+ _channelz_pb2.GetSubchannelResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetSocket(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_socket(request.socket_id),
+ _channelz_pb2.GetSocketResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+
+def add_channelz_servicer(server):
+ """Add Channelz servicer to a server. Channelz servicer is in charge of
+ pulling information from C-Core for entire process. It will allow the
+ server to response to Channelz queries.
+
+ The Channelz statistic is enabled by default inside C-Core. Whether the
+ statistic is enabled or not is isolated from adding Channelz servicer.
+ That means you can query Channelz info with a Channelz-disabled channel,
+ and you can add Channelz servicer to a Channelz-disabled server.
+
+ The Channelz statistic can be enabled or disabled by channel option
+ 'grpc.enable_channelz'. Set to 1 to enable, set to 0 to disable.
+
+ This is an EXPERIMENTAL API.
+
+ Args:
+ server: grpc.Server to which Channelz service will be added.
+ """
+ _channelz_pb2_grpc.add_ChannelzServicer_to_server(ChannelzServicer(),
+ server)
diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py
new file mode 100644
index 0000000000..16356ea402
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_version.py
@@ -0,0 +1,17 @@
+# 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.
+
+# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
+
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py
new file mode 100644
index 0000000000..f8c0e93913
--- /dev/null
+++ b/src/python/grpcio_channelz/setup.py
@@ -0,0 +1,96 @@
+# 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.
+"""Setup module for the GRPC Python package's Channelz."""
+
+import os
+import sys
+
+import setuptools
+
+# Ensure we're in the proper directory whether or not we're being used by pip.
+os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
+# Break import-style to ensure we can actually find our local modules.
+import grpc_version
+
+
+class _NoOpCommand(setuptools.Command):
+ """No-op command."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ pass
+
+
+CLASSIFIERS = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'License :: OSI Approved :: Apache Software License',
+]
+
+PACKAGE_DIRECTORIES = {
+ '': '.',
+}
+
+INSTALL_REQUIRES = (
+ 'protobuf>=3.6.0',
+ 'grpcio>={version}'.format(version=grpc_version.VERSION),
+)
+
+try:
+ import channelz_commands as _channelz_commands
+ # we are in the build environment, otherwise the above import fails
+ SETUP_REQUIRES = (
+ 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
+ COMMAND_CLASS = {
+ # Run preprocess from the repository *before* doing any packaging!
+ 'preprocess': _channelz_commands.Preprocess,
+ 'build_package_protos': _channelz_commands.BuildPackageProtos,
+ }
+except ImportError:
+ SETUP_REQUIRES = ()
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ 'build_package_protos': _NoOpCommand,
+ }
+
+setuptools.setup(
+ name='grpcio-channelz',
+ version=grpc_version.VERSION,
+ license='Apache License 2.0',
+ description='Channel Level Live Debug Information Service for gRPC',
+ author='The gRPC Authors',
+ author_email='grpc-io@googlegroups.com',
+ classifiers=CLASSIFIERS,
+ url='https://grpc.io',
+ package_dir=PACKAGE_DIRECTORIES,
+ packages=setuptools.find_packages('.'),
+ install_requires=INSTALL_REQUIRES,
+ setup_requires=SETUP_REQUIRES,
+ cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in
index 996c74a9d4..3a22311b8e 100644
--- a/src/python/grpcio_health_checking/MANIFEST.in
+++ b/src/python/grpcio_health_checking/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_health *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index a30aac2e0b..85fa762f7e 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py
index 933f965aa2..3820ef0bba 100644
--- a/src/python/grpcio_health_checking/health_commands.py
+++ b/src/python/grpcio_health_checking/health_commands.py
@@ -20,10 +20,12 @@ import setuptools
ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
HEALTH_PROTO = os.path.join(ROOT_DIR, '../../proto/grpc/health/v1/health.proto')
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
-class CopyProtoModules(setuptools.Command):
- """Command to copy proto modules from grpc/src/proto."""
+class Preprocess(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto and LICENSE from
+ the root directory"""
description = ''
user_options = []
@@ -39,6 +41,8 @@ class CopyProtoModules(setuptools.Command):
shutil.copyfile(HEALTH_PROTO,
os.path.join(ROOT_DIR,
'grpc_health/v1/health.proto'))
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
class BuildPackageProtos(setuptools.Command):
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index db2edae2ce..5a09a80f6a 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -68,7 +68,7 @@ try:
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
# Run preprocess from the repository *before* doing any packaging!
- 'preprocess': _health_commands.CopyProtoModules,
+ 'preprocess': _health_commands.Preprocess,
'build_package_protos': _health_commands.BuildPackageProtos,
}
except ImportError:
diff --git a/src/python/grpcio_reflection/MANIFEST.in b/src/python/grpcio_reflection/MANIFEST.in
index d6fb6ce73a..10b01fa41d 100644
--- a/src/python/grpcio_reflection/MANIFEST.in
+++ b/src/python/grpcio_reflection/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_reflection *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index aafea9fe76..e62ab169a2 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_reflection/reflection_commands.py b/src/python/grpcio_reflection/reflection_commands.py
index 6f91f6b875..311ca4c4db 100644
--- a/src/python/grpcio_reflection/reflection_commands.py
+++ b/src/python/grpcio_reflection/reflection_commands.py
@@ -21,10 +21,12 @@ import setuptools
ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
REFLECTION_PROTO = os.path.join(
ROOT_DIR, '../../proto/grpc/reflection/v1alpha/reflection.proto')
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
-class CopyProtoModules(setuptools.Command):
- """Command to copy proto modules from grpc/src/proto."""
+class Preprocess(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto and LICENSE from
+ the root directory"""
description = ''
user_options = []
@@ -41,6 +43,8 @@ class CopyProtoModules(setuptools.Command):
REFLECTION_PROTO,
os.path.join(ROOT_DIR,
'grpc_reflection/v1alpha/reflection.proto'))
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
class BuildPackageProtos(setuptools.Command):
diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py
index b4087d87b4..f205069acd 100644
--- a/src/python/grpcio_reflection/setup.py
+++ b/src/python/grpcio_reflection/setup.py
@@ -69,7 +69,7 @@ try:
'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
COMMAND_CLASS = {
# Run preprocess from the repository *before* doing any packaging!
- 'preprocess': _reflection_commands.CopyProtoModules,
+ 'preprocess': _reflection_commands.Preprocess,
'build_package_protos': _reflection_commands.BuildPackageProtos,
}
except ImportError:
diff --git a/src/python/grpcio_status/.gitignore b/src/python/grpcio_status/.gitignore
new file mode 100644
index 0000000000..19d1523efd
--- /dev/null
+++ b/src/python/grpcio_status/.gitignore
@@ -0,0 +1,3 @@
+build/
+grpcio_status.egg-info/
+dist/
diff --git a/src/python/grpcio_status/MANIFEST.in b/src/python/grpcio_status/MANIFEST.in
new file mode 100644
index 0000000000..09b8ea721e
--- /dev/null
+++ b/src/python/grpcio_status/MANIFEST.in
@@ -0,0 +1,4 @@
+include grpc_version.py
+recursive-include grpc_status *.py
+global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_status/README.rst b/src/python/grpcio_status/README.rst
new file mode 100644
index 0000000000..dc2f7b1dab
--- /dev/null
+++ b/src/python/grpcio_status/README.rst
@@ -0,0 +1,9 @@
+gRPC Python Status Proto
+===========================
+
+Reference package for GRPC Python status proto mapping.
+
+Dependencies
+------------
+
+Depends on the `grpcio` package, available from PyPI via `pip install grpcio`.
diff --git a/src/python/grpcio_status/grpc_status/BUILD.bazel b/src/python/grpcio_status/grpc_status/BUILD.bazel
new file mode 100644
index 0000000000..223a077c3f
--- /dev/null
+++ b/src/python/grpcio_status/grpc_status/BUILD.bazel
@@ -0,0 +1,14 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "grpc_status",
+ srcs = ["rpc_status.py",],
+ deps = [
+ "//src/python/grpcio/grpc:grpcio",
+ requirement('protobuf'),
+ requirement('googleapis-common-protos'),
+ ],
+ imports=["../",],
+)
diff --git a/src/python/grpcio_status/grpc_status/__init__.py b/src/python/grpcio_status/grpc_status/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_status/grpc_status/__init__.py
@@ -0,0 +1,13 @@
+# 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.
diff --git a/src/python/grpcio_status/grpc_status/rpc_status.py b/src/python/grpcio_status/grpc_status/rpc_status.py
new file mode 100644
index 0000000000..e23a20968e
--- /dev/null
+++ b/src/python/grpcio_status/grpc_status/rpc_status.py
@@ -0,0 +1,92 @@
+# 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.
+"""Reference implementation for status mapping in gRPC Python."""
+
+import collections
+
+import grpc
+
+# TODO(https://github.com/bazelbuild/bazel/issues/6844)
+# Due to Bazel issue, the namespace packages won't resolve correctly.
+# Adding this unused-import as a workaround to avoid module-not-found error
+# under Bazel builds.
+import google.protobuf # pylint: disable=unused-import
+from google.rpc import status_pb2
+
+_CODE_TO_GRPC_CODE_MAPPING = dict([(x.value[0], x) for x in grpc.StatusCode])
+
+_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin'
+
+
+class _Status(
+ collections.namedtuple(
+ '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status):
+ pass
+
+
+def _code_to_grpc_status_code(code):
+ try:
+ return _CODE_TO_GRPC_CODE_MAPPING[code]
+ except KeyError:
+ raise ValueError('Invalid status code %s' % code)
+
+
+def from_call(call):
+ """Returns a google.rpc.status.Status message corresponding to a given grpc.Call.
+
+ This is an EXPERIMENTAL API.
+
+ Args:
+ call: A grpc.Call instance.
+
+ Returns:
+ A google.rpc.status.Status message representing the status of the RPC.
+
+ Raises:
+ ValueError: If the gRPC call's code or details are inconsistent with the
+ status code and message inside of the google.rpc.status.Status.
+ """
+ for key, value in call.trailing_metadata():
+ if key == _GRPC_DETAILS_METADATA_KEY:
+ rich_status = status_pb2.Status.FromString(value)
+ if call.code().value[0] != rich_status.code:
+ raise ValueError(
+ 'Code in Status proto (%s) doesn\'t match status code (%s)'
+ % (_code_to_grpc_status_code(rich_status.code),
+ call.code()))
+ if call.details() != rich_status.message:
+ raise ValueError(
+ 'Message in Status proto (%s) doesn\'t match status details (%s)'
+ % (rich_status.message, call.details()))
+ return rich_status
+ return None
+
+
+def to_status(status):
+ """Convert a google.rpc.status.Status message to grpc.Status.
+
+ This is an EXPERIMENTAL API.
+
+ Args:
+ status: a google.rpc.status.Status message representing the non-OK status
+ to terminate the RPC with and communicate it to the client.
+
+ Returns:
+ A grpc.Status instance representing the input google.rpc.status.Status message.
+ """
+ return _Status(
+ code=_code_to_grpc_status_code(status.code),
+ details=status.message,
+ trailing_metadata=((_GRPC_DETAILS_METADATA_KEY,
+ status.SerializeToString()),))
diff --git a/src/python/grpcio_status/grpc_version.py b/src/python/grpcio_status/grpc_version.py
new file mode 100644
index 0000000000..e009843b94
--- /dev/null
+++ b/src/python/grpcio_status/grpc_version.py
@@ -0,0 +1,17 @@
+# 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.
+
+# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!!
+
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_status/setup.py b/src/python/grpcio_status/setup.py
new file mode 100644
index 0000000000..983d3ea430
--- /dev/null
+++ b/src/python/grpcio_status/setup.py
@@ -0,0 +1,93 @@
+# 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.
+"""Setup module for the GRPC Python package's status mapping."""
+
+import os
+
+import setuptools
+
+# Ensure we're in the proper directory whether or not we're being used by pip.
+os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
+# Break import-style to ensure we can actually find our local modules.
+import grpc_version
+
+
+class _NoOpCommand(setuptools.Command):
+ """No-op command."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ pass
+
+
+CLASSIFIERS = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ 'License :: OSI Approved :: Apache Software License',
+]
+
+PACKAGE_DIRECTORIES = {
+ '': '.',
+}
+
+INSTALL_REQUIRES = (
+ 'protobuf>=3.6.0',
+ 'grpcio>={version}'.format(version=grpc_version.VERSION),
+ 'googleapis-common-protos>=1.5.5',
+)
+
+try:
+ import status_commands as _status_commands
+ # we are in the build environment, otherwise the above import fails
+ COMMAND_CLASS = {
+ # Run preprocess from the repository *before* doing any packaging!
+ 'preprocess': _status_commands.Preprocess,
+ 'build_package_protos': _NoOpCommand,
+ }
+except ImportError:
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ 'build_package_protos': _NoOpCommand,
+ }
+
+setuptools.setup(
+ name='grpcio-status',
+ version=grpc_version.VERSION,
+ description='Status proto mapping for gRPC',
+ author='The gRPC Authors',
+ author_email='grpc-io@googlegroups.com',
+ url='https://grpc.io',
+ license='Apache License 2.0',
+ classifiers=CLASSIFIERS,
+ package_dir=PACKAGE_DIRECTORIES,
+ packages=setuptools.find_packages('.'),
+ install_requires=INSTALL_REQUIRES,
+ cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_status/status_commands.py b/src/python/grpcio_status/status_commands.py
new file mode 100644
index 0000000000..78cd497f62
--- /dev/null
+++ b/src/python/grpcio_status/status_commands.py
@@ -0,0 +1,39 @@
+# 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.
+"""Provides distutils command classes for the GRPC Python setup process."""
+
+import os
+import shutil
+
+import setuptools
+
+ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
+
+
+class Preprocess(setuptools.Command):
+ """Command to copy LICENSE from root directory."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
diff --git a/src/python/grpcio_testing/MANIFEST.in b/src/python/grpcio_testing/MANIFEST.in
index 39b3565217..559dfaf786 100644
--- a/src/python/grpcio_testing/MANIFEST.in
+++ b/src/python/grpcio_testing/MANIFEST.in
@@ -1,3 +1,4 @@
include grpc_version.py
recursive-include grpc_testing *.py
global-exclude *.pyc
+include LICENSE
diff --git a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py
index 90eeb130d3..5b1dfeacdf 100644
--- a/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py
+++ b/src/python/grpcio_testing/grpc_testing/_server/_servicer_context.py
@@ -70,6 +70,9 @@ class ServicerContext(grpc.ServicerContext):
def abort(self, code, details):
raise NotImplementedError()
+ def abort_with_status(self, status):
+ raise NotImplementedError()
+
def set_code(self, code):
self._rpc.set_code(code)
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 876acd3142..7b4c1695fa 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_testing/setup.py b/src/python/grpcio_testing/setup.py
index 6ceb1fc5c9..18db71e0f0 100644
--- a/src/python/grpcio_testing/setup.py
+++ b/src/python/grpcio_testing/setup.py
@@ -24,6 +24,23 @@ os.chdir(os.path.dirname(os.path.abspath(__file__)))
# Break import style to ensure that we can find same-directory modules.
import grpc_version
+
+class _NoOpCommand(setuptools.Command):
+ """No-op command."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ pass
+
+
PACKAGE_DIRECTORIES = {
'': '.',
}
@@ -33,6 +50,19 @@ INSTALL_REQUIRES = (
'grpcio>={version}'.format(version=grpc_version.VERSION),
)
+try:
+ import testing_commands as _testing_commands
+ # we are in the build environment, otherwise the above import fails
+ COMMAND_CLASS = {
+ # Run preprocess from the repository *before* doing any packaging!
+ 'preprocess': _testing_commands.Preprocess,
+ }
+except ImportError:
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ }
+
setuptools.setup(
name='grpcio-testing',
version=grpc_version.VERSION,
@@ -43,4 +73,5 @@ setuptools.setup(
url='https://grpc.io',
package_dir=PACKAGE_DIRECTORIES,
packages=setuptools.find_packages('.'),
- install_requires=INSTALL_REQUIRES)
+ install_requires=INSTALL_REQUIRES,
+ cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_testing/testing_commands.py b/src/python/grpcio_testing/testing_commands.py
new file mode 100644
index 0000000000..fb40d37efb
--- /dev/null
+++ b/src/python/grpcio_testing/testing_commands.py
@@ -0,0 +1,39 @@
+# 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.
+"""Provides distutils command classes for the GRPC Python setup process."""
+
+import os
+import shutil
+
+import setuptools
+
+ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+LICENSE = os.path.join(ROOT_DIR, '../../../LICENSE')
+
+
+class Preprocess(setuptools.Command):
+ """Command to copy LICENSE from root directory."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ if os.path.isfile(LICENSE):
+ shutil.copyfile(LICENSE, os.path.join(ROOT_DIR, 'LICENSE'))
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index d163f6fb68..18413abab0 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -132,7 +132,20 @@ class TestGevent(setuptools.Command):
'unit.beta._beta_features_test',
# TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version
# This test will stuck while running higher version of gevent
- 'unit._auth_context_test.AuthContextTest.testSessionResumption')
+ 'unit._auth_context_test.AuthContextTest.testSessionResumption',
+ # TODO(https://github.com/grpc/grpc/issues/15411) enable these tests
+ 'unit._exit_test.ExitTest.test_in_flight_unary_unary_call',
+ 'unit._exit_test.ExitTest.test_in_flight_unary_stream_call',
+ 'unit._exit_test.ExitTest.test_in_flight_stream_unary_call',
+ 'unit._exit_test.ExitTest.test_in_flight_stream_stream_call',
+ 'unit._exit_test.ExitTest.test_in_flight_partial_unary_stream_call',
+ 'unit._exit_test.ExitTest.test_in_flight_partial_stream_unary_call',
+ 'unit._exit_test.ExitTest.test_in_flight_partial_stream_stream_call',
+ # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests
+ 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels',
+ 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets',
+ 'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc'
+ )
description = 'run tests with gevent. Assumes grpc/gevent are installed'
user_options = []
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index cc9b41587c..2fcd1ad617 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 61c98fa038..f9cb9d0cec 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -39,6 +39,8 @@ PACKAGE_DIRECTORIES = {
INSTALL_REQUIRES = (
'coverage>=4.0', 'enum34>=1.0.4',
'grpcio>={version}'.format(version=grpc_version.VERSION),
+ 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION),
+ 'grpcio-status>={version}'.format(version=grpc_version.VERSION),
'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
'oauth2client>=1.4.7', 'protobuf>=3.6.0', 'six>=1.10', 'google-auth>=1.0.0',
diff --git a/src/python/grpcio_tests/tests/channelz/BUILD.bazel b/src/python/grpcio_tests/tests/channelz/BUILD.bazel
new file mode 100644
index 0000000000..63513616e7
--- /dev/null
+++ b/src/python/grpcio_tests/tests/channelz/BUILD.bazel
@@ -0,0 +1,15 @@
+package(default_visibility = ["//visibility:public"])
+
+py_test(
+ name = "channelz_servicer_test",
+ srcs = ["_channelz_servicer_test.py"],
+ main = "_channelz_servicer_test.py",
+ size = "small",
+ deps = [
+ "//src/python/grpcio/grpc:grpcio",
+ "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
+ "//src/python/grpcio_tests/tests/unit:test_common",
+ "//src/python/grpcio_tests/tests/unit/framework/common:common",
+ ],
+ imports = ["../../",],
+)
diff --git a/src/python/grpcio_tests/tests/channelz/__init__.py b/src/python/grpcio_tests/tests/channelz/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_tests/tests/channelz/__init__.py
@@ -0,0 +1,13 @@
+# 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.
diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
new file mode 100644
index 0000000000..8ca5189522
--- /dev/null
+++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
@@ -0,0 +1,470 @@
+# 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.
+"""Tests of grpc_channelz.v1.channelz."""
+
+import unittest
+
+from concurrent import futures
+
+import grpc
+from grpc_channelz.v1 import channelz
+from grpc_channelz.v1 import channelz_pb2
+from grpc_channelz.v1 import channelz_pb2_grpc
+
+from tests.unit import test_common
+from tests.unit.framework.common import test_constants
+
+_SUCCESSFUL_UNARY_UNARY = '/test/SuccessfulUnaryUnary'
+_FAILED_UNARY_UNARY = '/test/FailedUnaryUnary'
+_SUCCESSFUL_STREAM_STREAM = '/test/SuccessfulStreamStream'
+
+_REQUEST = b'\x00\x00\x00'
+_RESPONSE = b'\x01\x01\x01'
+
+_DISABLE_REUSE_PORT = (('grpc.so_reuseport', 0),)
+_ENABLE_CHANNELZ = (('grpc.enable_channelz', 1),)
+_DISABLE_CHANNELZ = (('grpc.enable_channelz', 0),)
+
+
+def _successful_unary_unary(request, servicer_context):
+ return _RESPONSE
+
+
+def _failed_unary_unary(request, servicer_context):
+ servicer_context.set_code(grpc.StatusCode.INTERNAL)
+ servicer_context.set_details("Channelz Test Intended Failure")
+
+
+def _successful_stream_stream(request_iterator, servicer_context):
+ for _ in request_iterator:
+ yield _RESPONSE
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+ def service(self, handler_call_details):
+ if handler_call_details.method == _SUCCESSFUL_UNARY_UNARY:
+ return grpc.unary_unary_rpc_method_handler(_successful_unary_unary)
+ elif handler_call_details.method == _FAILED_UNARY_UNARY:
+ return grpc.unary_unary_rpc_method_handler(_failed_unary_unary)
+ elif handler_call_details.method == _SUCCESSFUL_STREAM_STREAM:
+ return grpc.stream_stream_rpc_method_handler(
+ _successful_stream_stream)
+ else:
+ return None
+
+
+class _ChannelServerPair(object):
+
+ def __init__(self):
+ # Server will enable channelz service
+ self.server = grpc.server(
+ futures.ThreadPoolExecutor(max_workers=3),
+ options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ)
+ port = self.server.add_insecure_port('[::]:0')
+ self.server.add_generic_rpc_handlers((_GenericHandler(),))
+ self.server.start()
+
+ # Channel will enable channelz service...
+ self.channel = grpc.insecure_channel('localhost:%d' % port,
+ _ENABLE_CHANNELZ)
+
+
+def _generate_channel_server_pairs(n):
+ return [_ChannelServerPair() for i in range(n)]
+
+
+def _close_channel_server_pairs(pairs):
+ for pair in pairs:
+ pair.server.stop(None)
+ # TODO(ericgribkoff) This del should not be required
+ del pair.server
+ pair.channel.close()
+
+
+class ChannelzServicerTest(unittest.TestCase):
+
+ def _send_successful_unary_unary(self, idx):
+ _, r = self._pairs[idx].channel.unary_unary(
+ _SUCCESSFUL_UNARY_UNARY).with_call(_REQUEST)
+ self.assertEqual(r.code(), grpc.StatusCode.OK)
+
+ def _send_failed_unary_unary(self, idx):
+ try:
+ self._pairs[idx].channel.unary_unary(_FAILED_UNARY_UNARY).with_call(
+ _REQUEST)
+ except grpc.RpcError:
+ return
+ else:
+ self.fail("This call supposed to fail")
+
+ def _send_successful_stream_stream(self, idx):
+ response_iterator = self._pairs[idx].channel.stream_stream(
+ _SUCCESSFUL_STREAM_STREAM).__call__(
+ iter([_REQUEST] * test_constants.STREAM_LENGTH))
+ cnt = 0
+ for _ in response_iterator:
+ cnt += 1
+ self.assertEqual(cnt, test_constants.STREAM_LENGTH)
+
+ def _get_channel_id(self, idx):
+ """Channel id may not be consecutive"""
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertGreater(len(resp.channel), idx)
+ return resp.channel[idx].ref.channel_id
+
+ def setUp(self):
+ self._pairs = []
+ # This server is for Channelz info fetching only
+ # It self should not enable Channelz
+ self._server = grpc.server(
+ futures.ThreadPoolExecutor(max_workers=3),
+ options=_DISABLE_REUSE_PORT + _DISABLE_CHANNELZ)
+ port = self._server.add_insecure_port('[::]:0')
+ channelz.add_channelz_servicer(self._server)
+ self._server.start()
+
+ # This channel is used to fetch Channelz info only
+ # Channelz should not be enabled
+ self._channel = grpc.insecure_channel('localhost:%d' % port,
+ _DISABLE_CHANNELZ)
+ self._channelz_stub = channelz_pb2_grpc.ChannelzStub(self._channel)
+
+ def tearDown(self):
+ self._server.stop(None)
+ self._channel.close()
+ _close_channel_server_pairs(self._pairs)
+
+ def test_get_top_channels_basic(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(resp.channel), 1)
+ self.assertEqual(resp.end, True)
+
+ def test_get_top_channels_high_start_id(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=10000))
+ self.assertEqual(len(resp.channel), 0)
+ self.assertEqual(resp.end, True)
+
+ def test_successful_request(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ self._send_successful_unary_unary(0)
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, 1)
+ self.assertEqual(resp.channel.data.calls_succeeded, 1)
+ self.assertEqual(resp.channel.data.calls_failed, 0)
+
+ def test_failed_request(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ self._send_failed_unary_unary(0)
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, 1)
+ self.assertEqual(resp.channel.data.calls_succeeded, 0)
+ self.assertEqual(resp.channel.data.calls_failed, 1)
+
+ def test_many_requests(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ k_success = 7
+ k_failed = 9
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(0)
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, k_success + k_failed)
+ self.assertEqual(resp.channel.data.calls_succeeded, k_success)
+ self.assertEqual(resp.channel.data.calls_failed, k_failed)
+
+ def test_many_channel(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(resp.channel), k_channels)
+
+ def test_many_requests_many_channel(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ k_success = 11
+ k_failed = 13
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ self._send_successful_unary_unary(2)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(1)
+ self._send_failed_unary_unary(2)
+
+ # The first channel saw only successes
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, k_success)
+ self.assertEqual(resp.channel.data.calls_succeeded, k_success)
+ self.assertEqual(resp.channel.data.calls_failed, 0)
+
+ # The second channel saw only failures
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(1)))
+ self.assertEqual(resp.channel.data.calls_started, k_failed)
+ self.assertEqual(resp.channel.data.calls_succeeded, 0)
+ self.assertEqual(resp.channel.data.calls_failed, k_failed)
+
+ # The third channel saw both successes and failures
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(2)))
+ self.assertEqual(resp.channel.data.calls_started, k_success + k_failed)
+ self.assertEqual(resp.channel.data.calls_succeeded, k_success)
+ self.assertEqual(resp.channel.data.calls_failed, k_failed)
+
+ # The fourth channel saw nothing
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(3)))
+ self.assertEqual(resp.channel.data.calls_started, 0)
+ self.assertEqual(resp.channel.data.calls_succeeded, 0)
+ self.assertEqual(resp.channel.data.calls_failed, 0)
+
+ def test_many_subchannels(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ k_success = 17
+ k_failed = 19
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ self._send_successful_unary_unary(2)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(1)
+ self._send_failed_unary_unary(2)
+
+ gtc_resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(gtc_resp.channel), k_channels)
+ for i in range(k_channels):
+ # If no call performed in the channel, there shouldn't be any subchannel
+ if gtc_resp.channel[i].data.calls_started == 0:
+ self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0)
+ continue
+
+ # Otherwise, the subchannel should exist
+ self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0)
+ gsc_resp = self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(
+ subchannel_id=gtc_resp.channel[i].subchannel_ref[
+ 0].subchannel_id))
+ self.assertEqual(gtc_resp.channel[i].data.calls_started,
+ gsc_resp.subchannel.data.calls_started)
+ self.assertEqual(gtc_resp.channel[i].data.calls_succeeded,
+ gsc_resp.subchannel.data.calls_succeeded)
+ self.assertEqual(gtc_resp.channel[i].data.calls_failed,
+ gsc_resp.subchannel.data.calls_failed)
+
+ def test_server_basic(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(resp.server), 1)
+
+ def test_get_one_server(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ gss_resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(gss_resp.server), 1)
+ gs_resp = self._channelz_stub.GetServer(
+ channelz_pb2.GetServerRequest(
+ server_id=gss_resp.server[0].ref.server_id))
+ self.assertEqual(gss_resp.server[0].ref.server_id,
+ gs_resp.server.ref.server_id)
+
+ def test_server_call(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ k_success = 23
+ k_failed = 29
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(0)
+
+ resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(resp.server), 1)
+ self.assertEqual(resp.server[0].data.calls_started,
+ k_success + k_failed)
+ self.assertEqual(resp.server[0].data.calls_succeeded, k_success)
+ self.assertEqual(resp.server[0].data.calls_failed, k_failed)
+
+ def test_many_subchannels_and_sockets(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ k_success = 3
+ k_failed = 5
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ self._send_successful_unary_unary(2)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(1)
+ self._send_failed_unary_unary(2)
+
+ gtc_resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(gtc_resp.channel), k_channels)
+ for i in range(k_channels):
+ # If no call performed in the channel, there shouldn't be any subchannel
+ if gtc_resp.channel[i].data.calls_started == 0:
+ self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0)
+ continue
+
+ # Otherwise, the subchannel should exist
+ self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0)
+ gsc_resp = self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(
+ subchannel_id=gtc_resp.channel[i].subchannel_ref[
+ 0].subchannel_id))
+ self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1)
+
+ gs_resp = self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(
+ socket_id=gsc_resp.subchannel.socket_ref[0].socket_id))
+ self.assertEqual(gsc_resp.subchannel.data.calls_started,
+ gs_resp.socket.data.streams_started)
+ self.assertEqual(gsc_resp.subchannel.data.calls_started,
+ gs_resp.socket.data.streams_succeeded)
+ # Calls started == messages sent, only valid for unary calls
+ self.assertEqual(gsc_resp.subchannel.data.calls_started,
+ gs_resp.socket.data.messages_sent)
+ # Only receive responses when the RPC was successful
+ self.assertEqual(gsc_resp.subchannel.data.calls_succeeded,
+ gs_resp.socket.data.messages_received)
+
+ def test_streaming_rpc(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ # In C++, the argument for _send_successful_stream_stream is message length.
+ # Here the argument is still channel idx, to be consistent with the other two.
+ self._send_successful_stream_stream(0)
+
+ gc_resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(gc_resp.channel.data.calls_started, 1)
+ self.assertEqual(gc_resp.channel.data.calls_succeeded, 1)
+ self.assertEqual(gc_resp.channel.data.calls_failed, 0)
+ # Subchannel exists
+ self.assertGreater(len(gc_resp.channel.subchannel_ref), 0)
+
+ gsc_resp = self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(
+ subchannel_id=gc_resp.channel.subchannel_ref[0].subchannel_id))
+ self.assertEqual(gsc_resp.subchannel.data.calls_started, 1)
+ self.assertEqual(gsc_resp.subchannel.data.calls_succeeded, 1)
+ self.assertEqual(gsc_resp.subchannel.data.calls_failed, 0)
+ # Socket exists
+ self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1)
+
+ gs_resp = self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(
+ socket_id=gsc_resp.subchannel.socket_ref[0].socket_id))
+ self.assertEqual(gs_resp.socket.data.streams_started, 1)
+ self.assertEqual(gs_resp.socket.data.streams_succeeded, 1)
+ self.assertEqual(gs_resp.socket.data.streams_failed, 0)
+ self.assertEqual(gs_resp.socket.data.messages_sent,
+ test_constants.STREAM_LENGTH)
+ self.assertEqual(gs_resp.socket.data.messages_received,
+ test_constants.STREAM_LENGTH)
+
+ def test_server_sockets(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ self._send_successful_unary_unary(0)
+ self._send_failed_unary_unary(0)
+
+ gs_resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(gs_resp.server), 1)
+ self.assertEqual(gs_resp.server[0].data.calls_started, 2)
+ self.assertEqual(gs_resp.server[0].data.calls_succeeded, 1)
+ self.assertEqual(gs_resp.server[0].data.calls_failed, 1)
+
+ gss_resp = self._channelz_stub.GetServerSockets(
+ channelz_pb2.GetServerSocketsRequest(
+ server_id=gs_resp.server[0].ref.server_id, start_socket_id=0))
+ # If the RPC call failed, it will raise a grpc.RpcError
+ # So, if there is no exception raised, considered pass
+
+ def test_server_listen_sockets(self):
+ self._pairs = _generate_channel_server_pairs(1)
+
+ gss_resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(gss_resp.server), 1)
+ self.assertEqual(len(gss_resp.server[0].listen_socket), 1)
+
+ gs_resp = self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(
+ socket_id=gss_resp.server[0].listen_socket[0].socket_id))
+ # If the RPC call failed, it will raise a grpc.RpcError
+ # So, if there is no exception raised, considered pass
+
+ def test_invalid_query_get_server(self):
+ try:
+ self._channelz_stub.GetServer(
+ channelz_pb2.GetServerRequest(server_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_channel(self):
+ try:
+ self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_subchannel(self):
+ try:
+ self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(subchannel_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_socket(self):
+ try:
+ self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(socket_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_server_sockets(self):
+ try:
+ self._channelz_stub.GetServerSockets(
+ channelz_pb2.GetServerSocketsRequest(
+ server_id=10000,
+ start_socket_id=0,
+ ))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 721dedf0b7..c11f6c8fad 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -23,7 +23,6 @@ from google.auth import environment_vars as google_auth_environment_vars
from google.auth.transport import grpc as google_auth_transport_grpc
from google.auth.transport import requests as google_auth_transport_requests
import grpc
-from grpc.beta import implementations
from src.proto.grpc.testing import empty_pb2
from src.proto.grpc.testing import messages_pb2
@@ -377,7 +376,7 @@ def _unimplemented_service(unimplemented_service_stub):
def _custom_metadata(stub):
initial_metadata_value = "test_initial_metadata_value"
- trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b"
+ trailing_metadata_value = b"\x0a\x0b\x0a\x0b\x0a\x0b"
metadata = ((_INITIAL_METADATA_KEY, initial_metadata_value),
(_TRAILING_METADATA_KEY, trailing_metadata_value))
@@ -391,7 +390,7 @@ def _custom_metadata(stub):
if trailing_metadata[_TRAILING_METADATA_KEY] != trailing_metadata_value:
raise ValueError('expected trailing metadata %s, got %s' %
(trailing_metadata_value,
- initial_metadata[_TRAILING_METADATA_KEY]))
+ trailing_metadata[_TRAILING_METADATA_KEY]))
# Testing with UnaryCall
request = messages_pb2.SimpleRequest(
@@ -422,7 +421,7 @@ def _compute_engine_creds(stub, args):
def _oauth2_auth_token(stub, args):
json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS]
- wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ wanted_email = json.load(open(json_key_filename, 'r'))['client_email']
response = _large_unary_common_behavior(stub, True, True, None)
if wanted_email != response.username:
raise ValueError('expected username %s, got %s' % (wanted_email,
@@ -435,7 +434,7 @@ def _oauth2_auth_token(stub, args):
def _jwt_token_creds(stub, args):
json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS]
- wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ wanted_email = json.load(open(json_key_filename, 'r'))['client_email']
response = _large_unary_common_behavior(stub, True, False, None)
if wanted_email != response.username:
raise ValueError('expected username %s, got %s' % (wanted_email,
@@ -444,7 +443,7 @@ def _jwt_token_creds(stub, args):
def _per_rpc_creds(stub, args):
json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS]
- wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ wanted_email = json.load(open(json_key_filename, 'r'))['client_email']
google_credentials, unused_project_id = google_auth.default(
scopes=[args.oauth_scope])
call_credentials = grpc.metadata_call_credentials(
diff --git a/src/python/grpcio_tests/tests/qps/worker_server.py b/src/python/grpcio_tests/tests/qps/worker_server.py
index 740bdcf1eb..337a94b546 100644
--- a/src/python/grpcio_tests/tests/qps/worker_server.py
+++ b/src/python/grpcio_tests/tests/qps/worker_server.py
@@ -39,7 +39,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer):
self._quit_event = threading.Event()
def RunServer(self, request_iterator, context):
- config = next(request_iterator).setup
+ config = next(request_iterator).setup #pylint: disable=stop-iteration-return
server, port = self._create_server(config)
cores = multiprocessing.cpu_count()
server.start()
@@ -102,7 +102,7 @@ class WorkerServer(worker_service_pb2_grpc.WorkerServiceServicer):
return (server, port)
def RunClient(self, request_iterator, context):
- config = next(request_iterator).setup
+ config = next(request_iterator).setup #pylint: disable=stop-iteration-return
client_runners = []
qps_data = histogram.Histogram(config.histogram_params.resolution,
config.histogram_params.max_possible)
diff --git a/src/python/grpcio_tests/tests/status/BUILD.bazel b/src/python/grpcio_tests/tests/status/BUILD.bazel
new file mode 100644
index 0000000000..937e50498e
--- /dev/null
+++ b/src/python/grpcio_tests/tests/status/BUILD.bazel
@@ -0,0 +1,19 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+
+package(default_visibility = ["//visibility:public"])
+
+py_test(
+ name = "grpc_status_test",
+ srcs = ["_grpc_status_test.py"],
+ main = "_grpc_status_test.py",
+ size = "small",
+ deps = [
+ "//src/python/grpcio/grpc:grpcio",
+ "//src/python/grpcio_status/grpc_status:grpc_status",
+ "//src/python/grpcio_tests/tests/unit:test_common",
+ "//src/python/grpcio_tests/tests/unit/framework/common:common",
+ requirement('protobuf'),
+ requirement('googleapis-common-protos'),
+ ],
+ imports = ["../../",],
+)
diff --git a/src/python/grpcio_tests/tests/status/__init__.py b/src/python/grpcio_tests/tests/status/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_tests/tests/status/__init__.py
@@ -0,0 +1,13 @@
+# 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.
diff --git a/src/python/grpcio_tests/tests/status/_grpc_status_test.py b/src/python/grpcio_tests/tests/status/_grpc_status_test.py
new file mode 100644
index 0000000000..519c372a96
--- /dev/null
+++ b/src/python/grpcio_tests/tests/status/_grpc_status_test.py
@@ -0,0 +1,173 @@
+# 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.
+"""Tests of grpc_status."""
+
+import unittest
+
+import logging
+import traceback
+
+import grpc
+from grpc_status import rpc_status
+
+from tests.unit import test_common
+
+from google.protobuf import any_pb2
+from google.rpc import code_pb2, status_pb2, error_details_pb2
+
+_STATUS_OK = '/test/StatusOK'
+_STATUS_NOT_OK = '/test/StatusNotOk'
+_ERROR_DETAILS = '/test/ErrorDetails'
+_INCONSISTENT = '/test/Inconsistent'
+_INVALID_CODE = '/test/InvalidCode'
+
+_REQUEST = b'\x00\x00\x00'
+_RESPONSE = b'\x01\x01\x01'
+
+_GRPC_DETAILS_METADATA_KEY = 'grpc-status-details-bin'
+
+_STATUS_DETAILS = 'This is an error detail'
+_STATUS_DETAILS_ANOTHER = 'This is another error detail'
+
+
+def _ok_unary_unary(request, servicer_context):
+ return _RESPONSE
+
+
+def _not_ok_unary_unary(request, servicer_context):
+ servicer_context.abort(grpc.StatusCode.INTERNAL, _STATUS_DETAILS)
+
+
+def _error_details_unary_unary(request, servicer_context):
+ details = any_pb2.Any()
+ details.Pack(
+ error_details_pb2.DebugInfo(
+ stack_entries=traceback.format_stack(),
+ detail='Intentionally invoked'))
+ rich_status = status_pb2.Status(
+ code=code_pb2.INTERNAL,
+ message=_STATUS_DETAILS,
+ details=[details],
+ )
+ servicer_context.abort_with_status(rpc_status.to_status(rich_status))
+
+
+def _inconsistent_unary_unary(request, servicer_context):
+ rich_status = status_pb2.Status(
+ code=code_pb2.INTERNAL,
+ message=_STATUS_DETAILS,
+ )
+ servicer_context.set_code(grpc.StatusCode.NOT_FOUND)
+ servicer_context.set_details(_STATUS_DETAILS_ANOTHER)
+ # User put inconsistent status information in trailing metadata
+ servicer_context.set_trailing_metadata(((_GRPC_DETAILS_METADATA_KEY,
+ rich_status.SerializeToString()),))
+
+
+def _invalid_code_unary_unary(request, servicer_context):
+ rich_status = status_pb2.Status(
+ code=42,
+ message='Invalid code',
+ )
+ servicer_context.abort_with_status(rpc_status.to_status(rich_status))
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+ def service(self, handler_call_details):
+ if handler_call_details.method == _STATUS_OK:
+ return grpc.unary_unary_rpc_method_handler(_ok_unary_unary)
+ elif handler_call_details.method == _STATUS_NOT_OK:
+ return grpc.unary_unary_rpc_method_handler(_not_ok_unary_unary)
+ elif handler_call_details.method == _ERROR_DETAILS:
+ return grpc.unary_unary_rpc_method_handler(
+ _error_details_unary_unary)
+ elif handler_call_details.method == _INCONSISTENT:
+ return grpc.unary_unary_rpc_method_handler(
+ _inconsistent_unary_unary)
+ elif handler_call_details.method == _INVALID_CODE:
+ return grpc.unary_unary_rpc_method_handler(
+ _invalid_code_unary_unary)
+ else:
+ return None
+
+
+class StatusTest(unittest.TestCase):
+
+ def setUp(self):
+ self._server = test_common.test_server()
+ self._server.add_generic_rpc_handlers((_GenericHandler(),))
+ port = self._server.add_insecure_port('[::]:0')
+ self._server.start()
+
+ self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+ def tearDown(self):
+ self._server.stop(None)
+ self._channel.close()
+
+ def test_status_ok(self):
+ _, call = self._channel.unary_unary(_STATUS_OK).with_call(_REQUEST)
+
+ # Succeed RPC doesn't have status
+ status = rpc_status.from_call(call)
+ self.assertIs(status, None)
+
+ def test_status_not_ok(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_STATUS_NOT_OK).with_call(_REQUEST)
+ rpc_error = exception_context.exception
+
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL)
+ # Failed RPC doesn't automatically generate status
+ status = rpc_status.from_call(rpc_error)
+ self.assertIs(status, None)
+
+ def test_error_details(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_ERROR_DETAILS).with_call(_REQUEST)
+ rpc_error = exception_context.exception
+
+ status = rpc_status.from_call(rpc_error)
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL)
+ self.assertEqual(status.code, code_pb2.Code.Value('INTERNAL'))
+
+ # Check if the underlying proto message is intact
+ self.assertEqual(status.details[0].Is(
+ error_details_pb2.DebugInfo.DESCRIPTOR), True)
+ info = error_details_pb2.DebugInfo()
+ status.details[0].Unpack(info)
+ self.assertIn('_error_details_unary_unary', info.stack_entries[-1])
+
+ def test_code_message_validation(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_INCONSISTENT).with_call(_REQUEST)
+ rpc_error = exception_context.exception
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.NOT_FOUND)
+
+ # Code/Message validation failed
+ self.assertRaises(ValueError, rpc_status.from_call, rpc_error)
+
+ def test_invalid_code(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_INVALID_CODE).with_call(_REQUEST)
+ rpc_error = exception_context.exception
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN)
+ # Invalid status code exception raised during coversion
+ self.assertIn('Invalid status code', rpc_error.details())
+
+
+if __name__ == '__main__':
+ logging.basicConfig()
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index a3006d9afc..b27e6f2693 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -1,5 +1,6 @@
[
"_sanity._sanity_test.SanityTest",
+ "channelz._channelz_servicer_test.ChannelzServicerTest",
"health_check._health_servicer_test.HealthServicerTest",
"interop._insecure_intraop_test.InsecureIntraopTest",
"interop._secure_intraop_test.SecureIntraopTest",
@@ -14,10 +15,12 @@
"protoc_plugin._split_definitions_test.SplitProtoSingleProtocExecutionProtocStyleTest",
"protoc_plugin.beta_python_plugin_test.PythonPluginTest",
"reflection._reflection_servicer_test.ReflectionServicerTest",
+ "status._grpc_status_test.StatusTest",
"testing._client_test.ClientTest",
"testing._server_test.FirstServiceServicerTest",
"testing._time_test.StrictFakeTimeTest",
"testing._time_test.StrictRealTimeTest",
+ "unit._abort_test.AbortTest",
"unit._api_test.AllTest",
"unit._api_test.ChannelConnectivityTest",
"unit._api_test.ChannelTest",
diff --git a/src/python/grpcio_tests/tests/unit/BUILD.bazel b/src/python/grpcio_tests/tests/unit/BUILD.bazel
index de33b81e32..4f850220f8 100644
--- a/src/python/grpcio_tests/tests/unit/BUILD.bazel
+++ b/src/python/grpcio_tests/tests/unit/BUILD.bazel
@@ -3,6 +3,7 @@ load("@grpc_python_dependencies//:requirements.bzl", "requirement")
package(default_visibility = ["//visibility:public"])
GRPCIO_TESTS_UNIT = [
+ "_abort_test.py",
"_api_test.py",
"_auth_context_test.py",
"_auth_test.py",
diff --git a/src/python/grpcio_tests/tests/unit/_abort_test.py b/src/python/grpcio_tests/tests/unit/_abort_test.py
new file mode 100644
index 0000000000..6438f6897a
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/_abort_test.py
@@ -0,0 +1,124 @@
+# 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.
+"""Tests server context abort mechanism"""
+
+import unittest
+import collections
+import logging
+
+import grpc
+
+from tests.unit import test_common
+from tests.unit.framework.common import test_constants
+
+_ABORT = '/test/abort'
+_ABORT_WITH_STATUS = '/test/AbortWithStatus'
+_INVALID_CODE = '/test/InvalidCode'
+
+_REQUEST = b'\x00\x00\x00'
+_RESPONSE = b'\x00\x00\x00'
+
+_ABORT_DETAILS = 'Abandon ship!'
+_ABORT_METADATA = (('a-trailing-metadata', '42'),)
+
+
+class _Status(
+ collections.namedtuple(
+ '_Status', ('code', 'details', 'trailing_metadata')), grpc.Status):
+ pass
+
+
+def abort_unary_unary(request, servicer_context):
+ servicer_context.abort(
+ grpc.StatusCode.INTERNAL,
+ _ABORT_DETAILS,
+ )
+ raise Exception('This line should not be executed!')
+
+
+def abort_with_status_unary_unary(request, servicer_context):
+ servicer_context.abort_with_status(
+ _Status(
+ code=grpc.StatusCode.INTERNAL,
+ details=_ABORT_DETAILS,
+ trailing_metadata=_ABORT_METADATA,
+ ))
+ raise Exception('This line should not be executed!')
+
+
+def invalid_code_unary_unary(request, servicer_context):
+ servicer_context.abort(
+ 42,
+ _ABORT_DETAILS,
+ )
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+ def service(self, handler_call_details):
+ if handler_call_details.method == _ABORT:
+ return grpc.unary_unary_rpc_method_handler(abort_unary_unary)
+ elif handler_call_details.method == _ABORT_WITH_STATUS:
+ return grpc.unary_unary_rpc_method_handler(
+ abort_with_status_unary_unary)
+ elif handler_call_details.method == _INVALID_CODE:
+ return grpc.stream_stream_rpc_method_handler(
+ invalid_code_unary_unary)
+ else:
+ return None
+
+
+class AbortTest(unittest.TestCase):
+
+ def setUp(self):
+ self._server = test_common.test_server()
+ port = self._server.add_insecure_port('[::]:0')
+ self._server.add_generic_rpc_handlers((_GenericHandler(),))
+ self._server.start()
+
+ self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+ def tearDown(self):
+ self._channel.close()
+ self._server.stop(0)
+
+ def test_abort(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_ABORT)(_REQUEST)
+ rpc_error = exception_context.exception
+
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL)
+ self.assertEqual(rpc_error.details(), _ABORT_DETAILS)
+
+ def test_abort_with_status(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_ABORT_WITH_STATUS)(_REQUEST)
+ rpc_error = exception_context.exception
+
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.INTERNAL)
+ self.assertEqual(rpc_error.details(), _ABORT_DETAILS)
+ self.assertEqual(rpc_error.trailing_metadata(), _ABORT_METADATA)
+
+ def test_invalid_code(self):
+ with self.assertRaises(grpc.RpcError) as exception_context:
+ self._channel.unary_unary(_INVALID_CODE)(_REQUEST)
+ rpc_error = exception_context.exception
+
+ self.assertEqual(rpc_error.code(), grpc.StatusCode.UNKNOWN)
+ self.assertEqual(rpc_error.details(), _ABORT_DETAILS)
+
+
+if __name__ == '__main__':
+ logging.basicConfig()
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py
index 38072861a4..427894bfe9 100644
--- a/src/python/grpcio_tests/tests/unit/_api_test.py
+++ b/src/python/grpcio_tests/tests/unit/_api_test.py
@@ -32,6 +32,7 @@ class AllTest(unittest.TestCase):
'Future',
'ChannelConnectivity',
'StatusCode',
+ 'Status',
'RpcError',
'RpcContext',
'Call',
diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py
index be7378ecbc..187a6f0388 100644
--- a/src/python/grpcio_tests/tests/unit/_credentials_test.py
+++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py
@@ -15,6 +15,7 @@
import unittest
import logging
+import six
import grpc
@@ -53,6 +54,16 @@ class CredentialsTest(unittest.TestCase):
self.assertIsInstance(channel_first_second_and_third,
grpc.ChannelCredentials)
+ @unittest.skipIf(six.PY2, 'only invalid in Python3')
+ def test_invalid_string_certificate(self):
+ self.assertRaises(
+ TypeError,
+ grpc.ssl_channel_credentials,
+ root_certificates='A Certificate',
+ private_key=None,
+ certificate_chain=None,
+ )
+
if __name__ == '__main__':
logging.basicConfig()
diff --git a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
index f489db12cb..d1263c2c56 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_scenarios.py
@@ -87,7 +87,7 @@ def hang_stream_stream(request_iterator, servicer_context):
def hang_partial_stream_stream(request_iterator, servicer_context):
for _ in range(test_constants.STREAM_LENGTH // 2):
- yield next(request_iterator)
+ yield next(request_iterator) #pylint: disable=stop-iteration-return
time.sleep(WAIT_TIME)
diff --git a/src/python/grpcio_tests/tests/unit/_exit_test.py b/src/python/grpcio_tests/tests/unit/_exit_test.py
index 5226537579..b429ee089f 100644
--- a/src/python/grpcio_tests/tests/unit/_exit_test.py
+++ b/src/python/grpcio_tests/tests/unit/_exit_test.py
@@ -71,7 +71,6 @@ def wait(process):
process.wait()
-@unittest.skip('https://github.com/grpc/grpc/issues/7311')
class ExitTest(unittest.TestCase):
def test_unstarted_server(self):
@@ -130,6 +129,8 @@ class ExitTest(unittest.TestCase):
stderr=sys.stderr)
interrupt_and_wait(process)
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_unary_unary_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_UNARY_CALL],
@@ -138,6 +139,8 @@ class ExitTest(unittest.TestCase):
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_unary_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_UNARY_STREAM_CALL],
@@ -145,6 +148,8 @@ class ExitTest(unittest.TestCase):
stderr=sys.stderr)
interrupt_and_wait(process)
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_stream_unary_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_UNARY_CALL],
@@ -153,6 +158,8 @@ class ExitTest(unittest.TestCase):
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_stream_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND + [_exit_scenarios.IN_FLIGHT_STREAM_STREAM_CALL],
@@ -161,6 +168,8 @@ class ExitTest(unittest.TestCase):
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_partial_unary_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND +
@@ -169,6 +178,8 @@ class ExitTest(unittest.TestCase):
stderr=sys.stderr)
interrupt_and_wait(process)
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_partial_stream_unary_call(self):
process = subprocess.Popen(
BASE_COMMAND +
@@ -178,6 +189,8 @@ class ExitTest(unittest.TestCase):
interrupt_and_wait(process)
@unittest.skipIf(six.PY2, 'https://github.com/grpc/grpc/issues/6999')
+ @unittest.skipIf(os.name == 'nt',
+ 'os.kill does not have required permission on Windows')
def test_in_flight_partial_stream_stream_call(self):
process = subprocess.Popen(
BASE_COMMAND +
diff --git a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
index 9771764635..0ff49490d5 100644
--- a/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
+++ b/src/python/grpcio_tests/tests/unit/_invalid_metadata_test.py
@@ -130,6 +130,9 @@ class InvalidMetadataTest(unittest.TestCase):
self._stream_stream(request_iterator, metadata=metadata)
self.assertIn(expected_error_details, str(exception_context.exception))
+ def testInvalidMetadata(self):
+ self.assertRaises(TypeError, self._unary_unary, b'', metadata=42)
+
if __name__ == '__main__':
logging.basicConfig()
diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
index e733a59a5b..9e4bd61816 100644
--- a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
+++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
@@ -70,18 +70,11 @@ SERVER_CERT_CHAIN_2_PEM = (resources.cert_hier_2_server_1_cert() +
Call = collections.namedtuple('Call', ['did_raise', 'returned_cert_config'])
-def _create_client_stub(
- port,
- expect_success,
- root_certificates=None,
- private_key=None,
- certificate_chain=None,
-):
- channel = grpc.secure_channel('localhost:{}'.format(port),
- grpc.ssl_channel_credentials(
- root_certificates=root_certificates,
- private_key=private_key,
- certificate_chain=certificate_chain))
+def _create_channel(port, credentials):
+ return grpc.secure_channel('localhost:{}'.format(port), credentials)
+
+
+def _create_client_stub(channel, expect_success):
if expect_success:
# per Nathaniel: there's some robustness issue if we start
# using a channel without waiting for it to be actually ready
@@ -176,14 +169,13 @@ class _ServerSSLCertReloadTest(
root_certificates=None,
private_key=None,
certificate_chain=None):
- client_stub = _create_client_stub(
- self.port,
- expect_success,
+ credentials = grpc.ssl_channel_credentials(
root_certificates=root_certificates,
private_key=private_key,
certificate_chain=certificate_chain)
- self._perform_rpc(client_stub, expect_success)
- del client_stub
+ with _create_channel(self.port, credentials) as client_channel:
+ client_stub = _create_client_stub(client_channel, expect_success)
+ self._perform_rpc(client_stub, expect_success)
def _test(self):
# things should work...
@@ -259,12 +251,13 @@ class _ServerSSLCertReloadTest(
# now create the "persistent" clients
self.cert_config_fetcher.reset()
self.cert_config_fetcher.configure(False, None)
- persistent_client_stub_A = _create_client_stub(
+ channel_A = _create_channel(
self.port,
- True,
- root_certificates=CA_1_PEM,
- private_key=CLIENT_KEY_2_PEM,
- certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ grpc.ssl_channel_credentials(
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM))
+ persistent_client_stub_A = _create_client_stub(channel_A, True)
self._perform_rpc(persistent_client_stub_A, True)
actual_calls = self.cert_config_fetcher.getCalls()
self.assertEqual(len(actual_calls), 1)
@@ -273,12 +266,13 @@ class _ServerSSLCertReloadTest(
self.cert_config_fetcher.reset()
self.cert_config_fetcher.configure(False, None)
- persistent_client_stub_B = _create_client_stub(
+ channel_B = _create_channel(
self.port,
- True,
- root_certificates=CA_1_PEM,
- private_key=CLIENT_KEY_2_PEM,
- certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ grpc.ssl_channel_credentials(
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM))
+ persistent_client_stub_B = _create_client_stub(channel_B, True)
self._perform_rpc(persistent_client_stub_B, True)
actual_calls = self.cert_config_fetcher.getCalls()
self.assertEqual(len(actual_calls), 1)
@@ -359,6 +353,9 @@ class _ServerSSLCertReloadTest(
actual_calls = self.cert_config_fetcher.getCalls()
self.assertEqual(len(actual_calls), 0)
+ channel_A.close()
+ channel_B.close()
+
class ServerSSLCertConfigFetcherParamsChecks(unittest.TestCase):
diff --git a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel b/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel
deleted file mode 100644
index d3e0fe20eb..0000000000
--- a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel
+++ /dev/null
@@ -1,75 +0,0 @@
-load("@grpc_python_dependencies//:requirements.bzl", "requirement")
-
-package(default_visibility = ["//visibility:public"])
-
-py_library(
- name = "test_utilities",
- srcs = ["test_utilities.py"],
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- ],
-)
-
-py_test(
- name = "_beta_features_test",
- srcs = ["_beta_features_test.py"],
- main = "_beta_features_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- "//src/python/grpcio_tests/tests/unit:resources",
- "//src/python/grpcio_tests/tests/unit/framework/common",
- ":test_utilities",
- ],
- imports=["../../../",],
-)
-
-py_test(
- name = "_connectivity_channel_test",
- srcs = ["_connectivity_channel_test.py"],
- main = "_connectivity_channel_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- ],
-)
-
-# TODO(ghostwriternr): To be added later.
-#py_test(
-# name = "_implementations_test",
-# srcs = ["_implementations_test.py"],
-# main = "_implementations_test.py",
-# size = "small",
-# deps = [
-# "//src/python/grpcio/grpc:grpcio",
-# "//src/python/grpcio_tests/tests/unit:resources",
-# requirement('oauth2client'),
-# ],
-# imports=["../../../",],
-#)
-
-py_test(
- name = "_not_found_test",
- srcs = ["_not_found_test.py"],
- main = "_not_found_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- "//src/python/grpcio_tests/tests/unit/framework/common",
- ],
- imports=["../../../",],
-)
-
-py_test(
- name = "_utilities_test",
- srcs = ["_utilities_test.py"],
- main = "_utilities_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- "//src/python/grpcio_tests/tests/unit/framework/common",
- ],
- imports=["../../../",],
-)
-
-
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 56d222c7ec..e61a35d09f 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -272,7 +272,7 @@ extern grpc_channelz_get_servers_type grpc_channelz_get_servers_import;
typedef char*(*grpc_channelz_get_server_type)(intptr_t server_id);
extern grpc_channelz_get_server_type grpc_channelz_get_server_import;
#define grpc_channelz_get_server grpc_channelz_get_server_import
-typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id);
+typedef char*(*grpc_channelz_get_server_sockets_type)(intptr_t server_id, intptr_t start_socket_id, intptr_t max_results);
extern grpc_channelz_get_server_sockets_type grpc_channelz_get_server_sockets_import;
#define grpc_channelz_get_server_sockets grpc_channelz_get_server_sockets_import
typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id);
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 4764217406..169a62f11d 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -95,7 +95,7 @@ module GRPC
rpc_descs[name] = RpcDesc.new(name, input, output,
marshal_class_method,
unmarshal_class_method)
- define_method(GenericService.underscore(name.to_s).to_sym) do |_, _|
+ define_method(GenericService.underscore(name.to_s).to_sym) do |*|
fail GRPC::BadStatus.new_status_exception(
GRPC::Core::StatusCodes::UNIMPLEMENTED)
end
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 243d566645..a4ed052d85 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.17.0.dev'
+ VERSION = '1.18.0.dev'
end
diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb
index c492455d8f..7ad68409dd 100644
--- a/src/ruby/pb/grpc/health/checker.rb
+++ b/src/ruby/pb/grpc/health/checker.rb
@@ -14,7 +14,6 @@
require 'grpc'
require 'grpc/health/v1/health_services_pb'
-require 'thread'
module Grpc
# Health contains classes and modules that support providing a health check
@@ -37,9 +36,9 @@ module Grpc
@status_mutex.synchronize do
status = @statuses["#{req.service}"]
end
- if status.nil?
+ if status.nil?
fail GRPC::BadStatus.new_status_exception(StatusCodes::NOT_FOUND)
- end
+ end
HealthCheckResponse.new(status: status)
end
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 44a6134086..924d747a79 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -342,6 +342,28 @@ describe GRPC::RpcServer do
t.join
end
+ it 'should return UNIMPLEMENTED on unimplemented ' \
+ 'methods for client_streamer', server: true do
+ @srv.handle(EchoService)
+ t = Thread.new { @srv.run }
+ @srv.wait_till_running
+ blk = proc do
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
+ requests = [EchoMsg.new, EchoMsg.new]
+ stub.a_client_streaming_rpc_unimplemented(requests)
+ end
+
+ begin
+ expect(&blk).to raise_error do |error|
+ expect(error).to be_a(GRPC::BadStatus)
+ expect(error.code).to eq(GRPC::Core::StatusCodes::UNIMPLEMENTED)
+ end
+ ensure
+ @srv.stop # should be call not to crash
+ t.join
+ end
+ end
+
it 'should handle multiple sequential requests', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
diff --git a/src/ruby/spec/support/services.rb b/src/ruby/spec/support/services.rb
index 6e693f1cde..438459dfd7 100644
--- a/src/ruby/spec/support/services.rb
+++ b/src/ruby/spec/support/services.rb
@@ -33,6 +33,7 @@ class EchoService
rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg
rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg)
rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg)
+ rpc :a_client_streaming_rpc_unimplemented, stream(EchoMsg), EchoMsg
attr_reader :received_md
def initialize(**kw)
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 92e85eb882..389fb70684 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.17.0.dev'
+ VERSION = '1.18.0.dev'
end
end
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 0b67416d3e..8bb06176bf 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1370,7 +1370,7 @@
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]})-dll.a $(prefix)/lib/lib${lib.name}.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.core_version.major}
+ $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so
endif
% endif
diff --git a/templates/config.m4.template b/templates/config.m4.template
index 19f9904911..18378cfc34 100644
--- a/templates/config.m4.template
+++ b/templates/config.m4.template
@@ -45,7 +45,8 @@
% endfor
, $ext_shared, , -fvisibility=hidden ${"\\"}
-DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN ${"\\"}
- -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0)
+ -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 ${"\\"}
+ -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1)
PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
<%
diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template
index ed69a1ed4c..94d5a4fb09 100644
--- a/templates/gRPC-C++.podspec.template
+++ b/templates/gRPC-C++.podspec.template
@@ -127,12 +127,20 @@
def ruby_multiline_list(files, indent):
return (',\n' + indent*' ').join('\'%s\'' % f for f in files)
+
+ def modify_podspec_version_string(pod_version, grpc_version):
+ # Append -preX when it is a pre-release
+ if len(str(grpc_version).split('-')) > 1:
+ return pod_version + '-' + str(grpc_version).split('-')[-1]
+ else:
+ return pod_version
+
%>
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '${settings.version}'
- version = '0.0.3'
+ version = '${modify_podspec_version_string('0.0.6', settings.version)}'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
diff --git a/templates/src/python/grpcio_channelz/grpc_version.py.template b/templates/src/python/grpcio_channelz/grpc_version.py.template
new file mode 100644
index 0000000000..75d510cd17
--- /dev/null
+++ b/templates/src/python/grpcio_channelz/grpc_version.py.template
@@ -0,0 +1,19 @@
+%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.
+
+ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
+
+ VERSION = '${settings.python_version.pep440()}'
diff --git a/templates/src/python/grpcio_status/grpc_version.py.template b/templates/src/python/grpcio_status/grpc_version.py.template
new file mode 100644
index 0000000000..727e01edb9
--- /dev/null
+++ b/templates/src/python/grpcio_status/grpc_version.py.template
@@ -0,0 +1,19 @@
+%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.
+
+ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_status/grpc_version.py.template`!!!
+
+ VERSION = '${settings.python_version.pep440()}'
diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include
index 7ed0074867..fdede9e840 100644
--- a/templates/tools/dockerfile/csharp_deps.include
+++ b/templates/tools/dockerfile/csharp_deps.include
@@ -1,24 +1,15 @@
#================
# C# dependencies
-# Update to a newer version of mono
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'}
+# cmake >=3.6 needed to build grpc_csharp_ext
+RUN apt-get update && apt-get install -y cmake && apt-get clean
+
+# Install mono
+RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean
+RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list
+RUN apt-get update && apt-get install -y ${'\\'}
mono-devel ${'\\'}
ca-certificates-mono ${'\\'}
nuget ${'\\'}
&& apt-get clean
-
-RUN nuget update -self
-
-#=================
-# Use cmake 3.6 from jessie-backports
-# needed to build grpc_csharp_ext with cmake
-
-RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
-RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean
diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
index bc88d2bfa3..f333592640 100644
--- a/templates/tools/dockerfile/csharp_dotnetcli_deps.include
+++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
@@ -1,12 +1,20 @@
-# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-RUN apt-get update && apt-get install -y curl libunwind8 gettext
-# dotnet-dev-1.0.0-preview2-003131
-RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
-RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
-# dotnet-dev-1.0.1
-RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
-RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
-RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+# Install dotnet SDK
+ENV DOTNET_SDK_VERSION 2.1.500
+RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz ${'\\'}
+ && mkdir -p /usr/share/dotnet ${'\\'}
+ && tar -zxf dotnet.tar.gz -C /usr/share/dotnet ${'\\'}
+ && rm dotnet.tar.gz ${'\\'}
+ && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
+
+
+# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1)
+RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz ${'\\'}
+ && mkdir -p dotnet_old ${'\\'}
+ && tar zxf dotnet_old.tar.gz -C dotnet_old ${'\\'}
+ && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ ${'\\'}
+ && rm -rf dotnet_old/ dotnet_old.tar.gz
+RUN apt-get update && apt-get install -y libunwind8 && apt-get clean
+
# Trigger the population of the local package cache
ENV NUGET_XMLDOC_MODE skip
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template
index a1f1283de0..abf1a3853d 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile.template
@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
- FROM debian:jessie
+ FROM debian:stretch
<%include file="../../apt_get_basic.include"/>
<%include file="../../python_deps.include"/>
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
index a1f1283de0..abf1a3853d 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
- FROM debian:jessie
+ FROM debian:stretch
<%include file="../../apt_get_basic.include"/>
<%include file="../../python_deps.include"/>
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
index bf28796de3..f584a2378e 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
@@ -14,15 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
- FROM debian:jessie
-
- <%include file="../../apt_get_basic.include"/>
- <%include file="../../python_deps.include"/>
- # Install pip and virtualenv for Python 3.4
- RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
- RUN python3.4 -m pip install virtualenv
+ <%include file="../../python_stretch.include"/>
- <%include file="../../run_tests_addons.include"/>
- # 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/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template
index 432f05442c..1526d07fc6 100644
--- a/templates/tools/dockerfile/test/csharp_jessie_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/csharp_stretch_x64/Dockerfile.template
@@ -1,6 +1,6 @@
%YAML 1.2
--- |
- # Copyright 2015 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.
@@ -14,7 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
- FROM debian:jessie
+ FROM debian:stretch
<%include file="../../apt_get_basic.include"/>
<%include file="../../gcp_api_libraries.include"/>
diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
deleted file mode 100644
index ac687b710f..0000000000
--- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
+++ /dev/null
@@ -1,41 +0,0 @@
-%YAML 1.2
---- |
- # Copyright 2016 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:jessie
-
- <%include file="../../apt_get_basic.include"/>
- <%include file="../../gcp_api_libraries.include"/>
- <%include file="../../csharp_deps.include"/>
- <%include file="../../csharp_dotnetcli_deps.include"/>
- <%include file="../../cxx_deps.include"/>
- <%include file="../../node_deps.include"/>
- <%include file="../../php_deps.include"/>
- <%include file="../../ruby_deps.include"/>
- <%include file="../../python_deps.include"/>
- # Install pip and virtualenv for Python 3.4
- RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
- RUN python3.4 -m pip install virtualenv
-
- # Install coverage for Python test coverage reporting
- RUN pip install coverage
- ENV PATH ~/.local/bin:$PATH
-
- # Install Mako to generate files in grpc/grpc-node
- RUN pip install Mako
-
- <%include file="../../run_tests_addons.include"/>
- # Define the default command.
- CMD ["bash"]
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
index ff342db493..c3602f6c51 100644
--- a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template
@@ -18,3 +18,6 @@
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
+
+ # for Python test coverage reporting
+ RUN pip install coverage
diff --git a/test/core/avl/avl_test.cc b/test/core/avl/avl_test.cc
index 01002fec72..769e67563d 100644
--- a/test/core/avl/avl_test.cc
+++ b/test/core/avl/avl_test.cc
@@ -283,7 +283,7 @@ static void test_stress(int amount_of_stress) {
}
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_get();
test_ll();
diff --git a/test/core/backoff/backoff_test.cc b/test/core/backoff/backoff_test.cc
index 1998a83977..8fd120e042 100644
--- a/test/core/backoff/backoff_test.cc
+++ b/test/core/backoff/backoff_test.cc
@@ -171,7 +171,7 @@ TEST(BackOffTest, JitterBackOff) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/bad_client/bad_client.cc b/test/core/bad_client/bad_client.cc
index 4f5d2a2862..ae1e42a4e0 100644
--- a/test/core/bad_client/bad_client.cc
+++ b/test/core/bad_client/bad_client.cc
@@ -66,7 +66,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
thd_args* a = static_cast<thd_args*>(ts);
grpc_core::ExecCtx exec_ctx;
grpc_server_setup_transport(a->server, transport, nullptr,
- grpc_server_get_channel_args(a->server), 0);
+ grpc_server_get_channel_args(a->server), nullptr);
}
/* Sets the read_done event */
diff --git a/test/core/bad_client/tests/badreq.cc b/test/core/bad_client/tests/badreq.cc
index eeaf4c9974..c560dc5561 100644
--- a/test/core/bad_client/tests/badreq.cc
+++ b/test/core/bad_client/tests/badreq.cc
@@ -39,7 +39,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* invalid content type */
diff --git a/test/core/bad_client/tests/connection_prefix.cc b/test/core/bad_client/tests/connection_prefix.cc
index 4aab234d3e..286a3ccafb 100644
--- a/test/core/bad_client/tests/connection_prefix.cc
+++ b/test/core/bad_client/tests/connection_prefix.cc
@@ -29,7 +29,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr, "X", 0);
diff --git a/test/core/bad_client/tests/duplicate_header.cc b/test/core/bad_client/tests/duplicate_header.cc
index e3cae8b595..dfa6e51811 100644
--- a/test/core/bad_client/tests/duplicate_header.cc
+++ b/test/core/bad_client/tests/duplicate_header.cc
@@ -122,7 +122,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* Verify that sending multiple headers doesn't segfault */
diff --git a/test/core/bad_client/tests/head_of_line_blocking.cc b/test/core/bad_client/tests/head_of_line_blocking.cc
index 427db46446..c856b9b122 100644
--- a/test/core/bad_client/tests/head_of_line_blocking.cc
+++ b/test/core/bad_client/tests/head_of_line_blocking.cc
@@ -109,7 +109,7 @@ static void addbuf(const void* data, size_t len) {
int main(int argc, char** argv) {
int i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
#define NUM_FRAMES 10
diff --git a/test/core/bad_client/tests/headers.cc b/test/core/bad_client/tests/headers.cc
index 2aa1b280ce..02ea759750 100644
--- a/test/core/bad_client/tests/headers.cc
+++ b/test/core/bad_client/tests/headers.cc
@@ -33,7 +33,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* partial http2 header prefixes */
diff --git a/test/core/bad_client/tests/initial_settings_frame.cc b/test/core/bad_client/tests/initial_settings_frame.cc
index 0220000ece..fcbb841331 100644
--- a/test/core/bad_client/tests/initial_settings_frame.cc
+++ b/test/core/bad_client/tests/initial_settings_frame.cc
@@ -32,7 +32,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* various partial prefixes */
diff --git a/test/core/bad_client/tests/large_metadata.cc b/test/core/bad_client/tests/large_metadata.cc
index d534753f53..520a1af0c2 100644
--- a/test/core/bad_client/tests/large_metadata.cc
+++ b/test/core/bad_client/tests/large_metadata.cc
@@ -141,7 +141,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server* server,
int main(int argc, char** argv) {
int i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
// Test sending more metadata than the server will accept.
gpr_strvec headers;
diff --git a/test/core/bad_client/tests/server_registered_method.cc b/test/core/bad_client/tests/server_registered_method.cc
index c2dc9c66af..834142ac1b 100644
--- a/test/core/bad_client/tests/server_registered_method.cc
+++ b/test/core/bad_client/tests/server_registered_method.cc
@@ -76,7 +76,7 @@ static void verifier_fails(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* body generated with
diff --git a/test/core/bad_client/tests/simple_request.cc b/test/core/bad_client/tests/simple_request.cc
index c80fc5cb4a..34049aaaff 100644
--- a/test/core/bad_client/tests/simple_request.cc
+++ b/test/core/bad_client/tests/simple_request.cc
@@ -123,7 +123,7 @@ static void failure_verifier(grpc_server* server, grpc_completion_queue* cq,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* basic request: check that things are working */
diff --git a/test/core/bad_client/tests/unknown_frame.cc b/test/core/bad_client/tests/unknown_frame.cc
index b1b618a43f..9e0cf3f6a9 100644
--- a/test/core/bad_client/tests/unknown_frame.cc
+++ b/test/core/bad_client/tests/unknown_frame.cc
@@ -34,7 +34,7 @@ static void verifier(grpc_server* server, grpc_completion_queue* cq,
int main(int argc, char** argv) {
grpc_init();
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
/* test adding prioritization data */
GRPC_RUN_BAD_CLIENT_TEST(verifier, nullptr,
diff --git a/test/core/bad_client/tests/window_overflow.cc b/test/core/bad_client/tests/window_overflow.cc
index b552704e9c..87042a46f2 100644
--- a/test/core/bad_client/tests/window_overflow.cc
+++ b/test/core/bad_client/tests/window_overflow.cc
@@ -71,7 +71,7 @@ int main(int argc, char** argv) {
#define FRAME_SIZE (MESSAGES_PER_FRAME * 5)
#define SEND_SIZE (4 * 1024 * 1024)
#define NUM_FRAMES (SEND_SIZE / FRAME_SIZE + 1)
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
addbuf(PFX_STR, sizeof(PFX_STR) - 1);
diff --git a/test/core/channel/channel_args_test.cc b/test/core/channel/channel_args_test.cc
index 41c62a8f16..087a7679bf 100644
--- a/test/core/channel/channel_args_test.cc
+++ b/test/core/channel/channel_args_test.cc
@@ -231,7 +231,7 @@ static void test_server_create_with_args(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_create();
test_set_compression_algorithm();
diff --git a/test/core/channel/channel_stack_builder_test.cc b/test/core/channel/channel_stack_builder_test.cc
index aad6d6eee9..b5598e63f9 100644
--- a/test/core/channel/channel_stack_builder_test.cc
+++ b/test/core/channel/channel_stack_builder_test.cc
@@ -132,7 +132,7 @@ static void init_plugin(void) {
static void destroy_plugin(void) {}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_register_plugin(init_plugin, destroy_plugin);
grpc_init();
test_channel_stack_builder_filter_replace();
diff --git a/test/core/channel/channel_stack_test.cc b/test/core/channel/channel_stack_test.cc
index 6f0bfa06d2..14726336f9 100644
--- a/test/core/channel/channel_stack_test.cc
+++ b/test/core/channel/channel_stack_test.cc
@@ -147,7 +147,7 @@ static void test_create_channel_stack(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_create_channel_stack();
grpc_shutdown();
diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc
index 3d8de79e37..b3c0b36898 100644
--- a/test/core/channel/channel_trace_test.cc
+++ b/test/core/channel/channel_trace_test.cc
@@ -342,7 +342,7 @@ TEST(ChannelTracerTest, TestTotalEviction) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc
index fdfc8eec94..ed3d629dc9 100644
--- a/test/core/channel/channelz_registry_test.cc
+++ b/test/core/channel/channelz_registry_test.cc
@@ -195,7 +195,7 @@ TEST_F(ChannelzRegistryTest, TestAddAfterCompaction) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc
index 4d4b077002..abd1601ad1 100644
--- a/test/core/channel/channelz_test.cc
+++ b/test/core/channel/channelz_test.cc
@@ -541,7 +541,7 @@ INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest,
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
diff --git a/test/core/channel/minimal_stack_is_minimal_test.cc b/test/core/channel/minimal_stack_is_minimal_test.cc
index e5953acedc..bee0bfb41f 100644
--- a/test/core/channel/minimal_stack_is_minimal_test.cc
+++ b/test/core/channel/minimal_stack_is_minimal_test.cc
@@ -56,7 +56,7 @@ static int check_stack(const char* file, int line, const char* transport_name,
#define CHECK_STACK(...) check_stack(__FILE__, __LINE__, __VA_ARGS__)
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
int errors = 0;
diff --git a/test/core/client_channel/parse_address_test.cc b/test/core/client_channel/parse_address_test.cc
index 004549fa62..b77a51a9e4 100644
--- a/test/core/client_channel/parse_address_test.cc
+++ b/test/core/client_channel/parse_address_test.cc
@@ -101,7 +101,7 @@ static void test_grpc_parse_ipv6_invalid(const char* uri_text) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_grpc_parse_unix("unix:/path/name", "/path/name");
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 eb5a911748..0cf549d01d 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.cc
@@ -21,10 +21,10 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
@@ -63,7 +63,8 @@ static grpc_address_resolver_vtable test_resolver = {my_resolve_address,
static grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) {
gpr_mu_lock(&g_mu);
GPR_ASSERT(0 == strcmp("test", addr));
@@ -74,9 +75,11 @@ static grpc_ares_request* my_dns_lookup_ares_locked(
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
gpr_mu_unlock(&g_mu);
- *lb_addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_lb_addresses_set_address(*lb_addrs, 0, nullptr, 0, false, nullptr,
- nullptr);
+ *addresses = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
+ grpc_resolved_address dummy_resolved_address;
+ memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address));
+ dummy_resolved_address.len = 123;
+ (*addresses)->emplace_back(dummy_resolved_address, nullptr);
}
GRPC_CLOSURE_SCHED(on_done, error);
return nullptr;
@@ -145,7 +148,7 @@ static void call_resolver_next_after_locking(grpc_core::Resolver* resolver,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
gpr_mu_init(&g_mu);
diff --git a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
index 1a7db40f59..16210b8164 100644
--- a/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_cooldown_test.cc
@@ -22,6 +22,7 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -40,7 +41,8 @@ static grpc_combiner* g_combiner;
static grpc_ares_request* (*g_default_dns_lookup_ares_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_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner);
// Counter incremented by test_resolve_address_impl indicating the number of
@@ -90,11 +92,12 @@ static grpc_address_resolver_vtable test_resolver = {
static grpc_ares_request* test_dns_lookup_ares_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_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) {
grpc_ares_request* result = g_default_dns_lookup_ares_locked(
- dns_server, name, default_port, g_iomgr_args.pollset_set, on_done, addrs,
- check_grpclb, service_config_json, combiner);
+ dns_server, name, default_port, g_iomgr_args.pollset_set, on_done,
+ addresses, check_grpclb, service_config_json, query_timeout_ms, combiner);
++g_resolution_count;
static grpc_millis last_resolution_time = 0;
if (last_resolution_time == 0) {
@@ -262,7 +265,7 @@ static void test_cooldown() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
g_combiner = grpc_combiner_create();
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.cc b/test/core/client_channel/resolvers/dns_resolver_test.cc
index 103b2916c4..571746abe8 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.cc
+++ b/test/core/client_channel/resolvers/dns_resolver_test.cc
@@ -60,7 +60,7 @@ static void test_fails(grpc_core::ResolverFactory* factory,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
g_combiner = grpc_combiner_create();
diff --git a/test/core/client_channel/resolvers/fake_resolver_test.cc b/test/core/client_channel/resolvers/fake_resolver_test.cc
index f6696bf127..3b06fe063a 100644
--- a/test/core/client_channel/resolvers/fake_resolver_test.cc
+++ b/test/core/client_channel/resolvers/fake_resolver_test.cc
@@ -22,10 +22,10 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/combiner.h"
@@ -63,12 +63,14 @@ void on_resolution_cb(void* arg, grpc_error* error) {
// We only check the addresses channel arg because that's the only one
// explicitly set by the test via
// FakeResolverResponseGenerator::SetResponse().
- const grpc_lb_addresses* actual_lb_addresses =
- grpc_lb_addresses_find_channel_arg(res->resolver_result);
- const grpc_lb_addresses* expected_lb_addresses =
- grpc_lb_addresses_find_channel_arg(res->expected_resolver_result);
- GPR_ASSERT(
- grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0);
+ const grpc_core::ServerAddressList* actual_addresses =
+ grpc_core::FindServerAddressListChannelArg(res->resolver_result);
+ const grpc_core::ServerAddressList* expected_addresses =
+ grpc_core::FindServerAddressListChannelArg(res->expected_resolver_result);
+ GPR_ASSERT(actual_addresses->size() == expected_addresses->size());
+ for (size_t i = 0; i < expected_addresses->size(); ++i) {
+ GPR_ASSERT((*actual_addresses)[i] == (*expected_addresses)[i]);
+ }
grpc_channel_args_destroy(res->resolver_result);
grpc_channel_args_destroy(res->expected_resolver_result);
gpr_event_set(&res->ev, (void*)1);
@@ -80,27 +82,35 @@ static grpc_channel_args* create_new_resolver_result() {
const size_t num_addresses = 2;
char* uri_string;
char* balancer_name;
- // Create grpc_lb_addresses.
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(num_addresses, nullptr);
+ // Create address list.
+ grpc_core::ServerAddressList addresses;
for (size_t i = 0; i < num_addresses; ++i) {
gpr_asprintf(&uri_string, "ipv4:127.0.0.1:100%" PRIuPTR,
test_counter * num_addresses + i);
grpc_uri* uri = grpc_uri_parse(uri_string, true);
gpr_asprintf(&balancer_name, "balancer%" PRIuPTR,
test_counter * num_addresses + i);
- grpc_lb_addresses_set_address_from_uri(
- addresses, i, uri, bool(num_addresses % 2), balancer_name, nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(uri, &address));
+ grpc_core::InlinedVector<grpc_arg, 2> args_to_add;
+ const bool is_balancer = num_addresses % 2;
+ if (is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME), balancer_name));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
+ addresses.emplace_back(address.addr, address.len, args);
gpr_free(balancer_name);
grpc_uri_destroy(uri);
gpr_free(uri_string);
}
- // Convert grpc_lb_addresses to grpc_channel_args.
- const grpc_arg addresses_arg =
- grpc_lb_addresses_create_channel_arg(addresses);
+ // Embed the address list in channel args.
+ const grpc_arg addresses_arg = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args* results =
grpc_channel_args_copy_and_add(nullptr, &addresses_arg, 1);
- grpc_lb_addresses_destroy(addresses);
++test_counter;
return results;
}
@@ -213,7 +223,7 @@ static void test_fake_resolver() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_fake_resolver();
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc
index b9287c2468..ff7db6046d 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.cc
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.cc
@@ -84,7 +84,7 @@ static void test_fails(grpc_core::ResolverFactory* factory,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
g_combiner = grpc_combiner_create();
diff --git a/test/core/client_channel/retry_throttle_test.cc b/test/core/client_channel/retry_throttle_test.cc
index c6d5d3ebbb..793e86dc06 100644
--- a/test/core/client_channel/retry_throttle_test.cc
+++ b/test/core/client_channel/retry_throttle_test.cc
@@ -136,7 +136,7 @@ TEST(ServerRetryThrottleMap, Replacement) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/client_channel/uri_parser_test.cc b/test/core/client_channel/uri_parser_test.cc
index ec4f755dda..713ec32e5e 100644
--- a/test/core/client_channel/uri_parser_test.cc
+++ b/test/core/client_channel/uri_parser_test.cc
@@ -119,7 +119,7 @@ static void test_query_parts() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_succeeds("http://www.google.com", "http", "www.google.com", "", "", "");
test_succeeds("dns:///foo", "dns", "", "/foo", "", "");
diff --git a/test/core/compression/algorithm_test.cc b/test/core/compression/algorithm_test.cc
index 8989a41989..24fe83774b 100644
--- a/test/core/compression/algorithm_test.cc
+++ b/test/core/compression/algorithm_test.cc
@@ -105,7 +105,7 @@ static void test_algorithm_failure(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_algorithm_mesh();
diff --git a/test/core/compression/message_compress_test.cc b/test/core/compression/message_compress_test.cc
index e3fe825fdf..e2abf2d321 100644
--- a/test/core/compression/message_compress_test.cc
+++ b/test/core/compression/message_compress_test.cc
@@ -292,7 +292,7 @@ int main(int argc, char** argv) {
GRPC_SLICE_SPLIT_IDENTITY,
GRPC_SLICE_SPLIT_ONE_BYTE};
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
for (i = 0; i < GRPC_MESSAGE_COMPRESS_ALGORITHMS_COUNT; i++) {
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index 398e8a2d9a..9d7f96683e 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -70,6 +70,19 @@ grpc_cc_library(
],
)
+grpc_cc_library(
+ name = "local_util",
+ srcs = ["fixtures/local_util.cc"],
+ hdrs = ["fixtures/local_util.h",
+ "end2end_tests.h"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
grpc_cc_test(
name = "bad_server_response_test",
srcs = ["bad_server_response_test.cc"],
diff --git a/test/core/end2end/bad_server_response_test.cc b/test/core/end2end/bad_server_response_test.cc
index f7396a1684..f8ffb55180 100644
--- a/test/core/end2end/bad_server_response_test.cc
+++ b/test/core/end2end/bad_server_response_test.cc
@@ -302,7 +302,7 @@ static void run_test(const char* response_payload,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
/* status defined in hpack static table */
diff --git a/test/core/end2end/connection_refused_test.cc b/test/core/end2end/connection_refused_test.cc
index 33812ec8e5..4318811b81 100644
--- a/test/core/end2end/connection_refused_test.cc
+++ b/test/core/end2end/connection_refused_test.cc
@@ -142,7 +142,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
run_test(false /* wait_for_ready */, false /* use_service_config */);
run_test(true /* wait_for_ready */, false /* use_service_config */);
run_test(true /* wait_for_ready */, true /* use_service_config */);
diff --git a/test/core/end2end/dualstack_socket_test.cc b/test/core/end2end/dualstack_socket_test.cc
index eb1d043fb2..330af8fce0 100644
--- a/test/core/end2end/dualstack_socket_test.cc
+++ b/test/core/end2end/dualstack_socket_test.cc
@@ -303,7 +303,7 @@ int external_dns_works(const char* host) {
int main(int argc, char** argv) {
int do_ipv6 = 1;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
if (!grpc_ipv6_loopback_available()) {
diff --git a/test/core/end2end/fixtures/h2_census.cc b/test/core/end2end/fixtures/h2_census.cc
index 29b1d6d883..60442ddcc7 100644
--- a/test/core/end2end/fixtures/h2_census.cc
+++ b/test/core/end2end/fixtures/h2_census.cc
@@ -118,7 +118,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_compress.cc b/test/core/end2end/fixtures/h2_compress.cc
index 4aaadf715c..04142daf63 100644
--- a/test/core/end2end/fixtures/h2_compress.cc
+++ b/test/core/end2end/fixtures/h2_compress.cc
@@ -118,7 +118,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_fakesec.cc b/test/core/end2end/fixtures/h2_fakesec.cc
index a653d7c477..ad83aab39f 100644
--- a/test/core/end2end/fixtures/h2_fakesec.cc
+++ b/test/core/end2end/fixtures/h2_fakesec.cc
@@ -142,7 +142,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_fd.cc b/test/core/end2end/fixtures/h2_fd.cc
index 52be0f7fd5..5d06bd5f3b 100644
--- a/test/core/end2end/fixtures/h2_fd.cc
+++ b/test/core/end2end/fixtures/h2_fd.cc
@@ -104,7 +104,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_full+pipe.cc b/test/core/end2end/fixtures/h2_full+pipe.cc
index c5329640dc..6d559c4e51 100644
--- a/test/core/end2end/fixtures/h2_full+pipe.cc
+++ b/test/core/end2end/fixtures/h2_full+pipe.cc
@@ -105,7 +105,7 @@ int main(int argc, char** argv) {
grpc_allow_specialized_wakeup_fd = 0;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_full+trace.cc b/test/core/end2end/fixtures/h2_full+trace.cc
index ba7a780304..2bbad48701 100644
--- a/test/core/end2end/fixtures/h2_full+trace.cc
+++ b/test/core/end2end/fixtures/h2_full+trace.cc
@@ -113,7 +113,7 @@ int main(int argc, char** argv) {
g_fixture_slowdown_factor = 10;
#endif
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_full+workarounds.cc b/test/core/end2end/fixtures/h2_full+workarounds.cc
index 78da8418f6..cb0f7d275b 100644
--- a/test/core/end2end/fixtures/h2_full+workarounds.cc
+++ b/test/core/end2end/fixtures/h2_full+workarounds.cc
@@ -114,7 +114,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_full.cc b/test/core/end2end/fixtures/h2_full.cc
index 0c826b6836..c0d21288c7 100644
--- a/test/core/end2end/fixtures/h2_full.cc
+++ b/test/core/end2end/fixtures/h2_full.cc
@@ -97,7 +97,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_http_proxy.cc b/test/core/end2end/fixtures/h2_http_proxy.cc
index 0af8a29a15..9b6a81494e 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.cc
+++ b/test/core/end2end/fixtures/h2_http_proxy.cc
@@ -120,7 +120,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_local_ipv4.cc b/test/core/end2end/fixtures/h2_local_ipv4.cc
new file mode 100644
index 0000000000..f6996bf6be
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_local_ipv4.cc
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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 <unistd.h>
+
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/gpr/host_port.h"
+#include "test/core/end2end/end2end_tests.h"
+#include "test/core/end2end/fixtures/local_util.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv4(
+ grpc_channel_args* client_args, grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f =
+ grpc_end2end_local_chttp2_create_fixture_fullstack();
+ int port = grpc_pick_unused_port_or_die();
+ gpr_join_host_port(
+ &static_cast<grpc_end2end_local_fullstack_fixture_data*>(f.fixture_data)
+ ->localaddr,
+ "127.0.0.1", port);
+ return f;
+}
+
+static void chttp2_init_client_fullstack_ipv4(grpc_end2end_test_fixture* f,
+ grpc_channel_args* client_args) {
+ grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP);
+}
+
+static void chttp2_init_server_fullstack_ipv4(grpc_end2end_test_fixture* f,
+ grpc_channel_args* client_args) {
+ grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack_local_ipv4",
+ FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+ FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+ FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
+ nullptr, chttp2_create_fixture_fullstack_ipv4,
+ chttp2_init_client_fullstack_ipv4, chttp2_init_server_fullstack_ipv4,
+ grpc_end2end_local_chttp2_tear_down_fullstack}};
+
+int main(int argc, char** argv) {
+ size_t i;
+ grpc::testing::TestEnvironment env(argc, argv);
+ grpc_end2end_tests_pre_init();
+ grpc_init();
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(argc, argv, configs[i]);
+ }
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_local_ipv6.cc b/test/core/end2end/fixtures/h2_local_ipv6.cc
new file mode 100644
index 0000000000..e360727ca8
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_local_ipv6.cc
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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 <unistd.h>
+
+#include <grpc/support/string_util.h>
+
+#include "src/core/lib/gpr/host_port.h"
+#include "test/core/end2end/end2end_tests.h"
+#include "test/core/end2end/fixtures/local_util.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_ipv6(
+ grpc_channel_args* client_args, grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f =
+ grpc_end2end_local_chttp2_create_fixture_fullstack();
+ int port = grpc_pick_unused_port_or_die();
+ gpr_join_host_port(
+ &static_cast<grpc_end2end_local_fullstack_fixture_data*>(f.fixture_data)
+ ->localaddr,
+ "[::1]", port);
+ return f;
+}
+
+static void chttp2_init_client_fullstack_ipv6(grpc_end2end_test_fixture* f,
+ grpc_channel_args* client_args) {
+ grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, LOCAL_TCP);
+}
+
+static void chttp2_init_server_fullstack_ipv6(grpc_end2end_test_fixture* f,
+ grpc_channel_args* client_args) {
+ grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, LOCAL_TCP);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack_local_ipv6",
+ FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+ FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+ FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
+ nullptr, chttp2_create_fixture_fullstack_ipv6,
+ chttp2_init_client_fullstack_ipv6, chttp2_init_server_fullstack_ipv6,
+ grpc_end2end_local_chttp2_tear_down_fullstack}};
+
+int main(int argc, char** argv) {
+ size_t i;
+ grpc::testing::TestEnvironment env(argc, argv);
+ grpc_end2end_tests_pre_init();
+ grpc_init();
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(argc, argv, configs[i]);
+ }
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_local_uds.cc b/test/core/end2end/fixtures/h2_local_uds.cc
new file mode 100644
index 0000000000..f1bce213dc
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_local_uds.cc
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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 <unistd.h>
+
+#include <grpc/support/string_util.h>
+
+#include "test/core/end2end/end2end_tests.h"
+#include "test/core/end2end/fixtures/local_util.h"
+#include "test/core/util/test_config.h"
+
+static int unique = 1;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack_uds(
+ grpc_channel_args* client_args, grpc_channel_args* server_args) {
+ grpc_end2end_test_fixture f =
+ grpc_end2end_local_chttp2_create_fixture_fullstack();
+ gpr_asprintf(
+ &static_cast<grpc_end2end_local_fullstack_fixture_data*>(f.fixture_data)
+ ->localaddr,
+ "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(), unique++);
+ return f;
+}
+
+static void chttp2_init_client_fullstack_uds(grpc_end2end_test_fixture* f,
+ grpc_channel_args* client_args) {
+ grpc_end2end_local_chttp2_init_client_fullstack(f, client_args, UDS);
+}
+
+static void chttp2_init_server_fullstack_uds(grpc_end2end_test_fixture* f,
+ grpc_channel_args* client_args) {
+ grpc_end2end_local_chttp2_init_server_fullstack(f, client_args, UDS);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+ {"chttp2/fullstack_local_uds",
+ FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+ FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
+ FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
+ FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
+ nullptr, chttp2_create_fixture_fullstack_uds,
+ chttp2_init_client_fullstack_uds, chttp2_init_server_fullstack_uds,
+ grpc_end2end_local_chttp2_tear_down_fullstack}};
+
+int main(int argc, char** argv) {
+ size_t i;
+ grpc::testing::TestEnvironment env(argc, argv);
+ grpc_end2end_tests_pre_init();
+ grpc_init();
+ for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+ grpc_end2end_tests(argc, argv, configs[i]);
+ }
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_oauth2.cc b/test/core/end2end/fixtures/h2_oauth2.cc
index 37397d6450..113a6b1173 100644
--- a/test/core/end2end/fixtures/h2_oauth2.cc
+++ b/test/core/end2end/fixtures/h2_oauth2.cc
@@ -224,7 +224,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_proxy.cc b/test/core/end2end/fixtures/h2_proxy.cc
index a32000061a..e334396ea7 100644
--- a/test/core/end2end/fixtures/h2_proxy.cc
+++ b/test/core/end2end/fixtures/h2_proxy.cc
@@ -124,7 +124,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.cc b/test/core/end2end/fixtures/h2_sockpair+trace.cc
index eb71e24c77..45f78b5964 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.cc
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.cc
@@ -53,7 +53,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
grpc_server_setup_transport(f->server, transport, nullptr,
- grpc_server_get_channel_args(f->server), 0);
+ grpc_server_get_channel_args(f->server), nullptr);
}
typedef struct {
@@ -140,7 +140,7 @@ int main(int argc, char** argv) {
g_fixture_slowdown_factor = 10;
#endif
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_sockpair.cc b/test/core/end2end/fixtures/h2_sockpair.cc
index 904bda5458..77bce7ebb3 100644
--- a/test/core/end2end/fixtures/h2_sockpair.cc
+++ b/test/core/end2end/fixtures/h2_sockpair.cc
@@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
grpc_server_setup_transport(f->server, transport, nullptr,
- grpc_server_get_channel_args(f->server), 0);
+ grpc_server_get_channel_args(f->server), nullptr);
}
typedef struct {
@@ -126,7 +126,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.cc b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
index 45f7f254ac..ac37841dc4 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.cc
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.cc
@@ -47,7 +47,7 @@ static void server_setup_transport(void* ts, grpc_transport* transport) {
grpc_endpoint_pair* sfd = static_cast<grpc_endpoint_pair*>(f->fixture_data);
grpc_endpoint_add_to_pollset(sfd->server, grpc_cq_pollset(f->cq));
grpc_server_setup_transport(f->server, transport, nullptr,
- grpc_server_get_channel_args(f->server), 0);
+ grpc_server_get_channel_args(f->server), nullptr);
}
typedef struct {
@@ -140,7 +140,7 @@ int main(int argc, char** argv) {
g_fixture_slowdown_factor = 2;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_ssl.cc b/test/core/end2end/fixtures/h2_ssl.cc
index 4d6c815716..1fcd785e25 100644
--- a/test/core/end2end/fixtures/h2_ssl.cc
+++ b/test/core/end2end/fixtures/h2_ssl.cc
@@ -158,7 +158,7 @@ int main(int argc, char** argv) {
size_t roots_size = strlen(test_root_cert);
char* roots_filename;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
/* Set the SSL roots env var. */
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.cc b/test/core/end2end/fixtures/h2_ssl_proxy.cc
index 09cbf974b6..f185807942 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.cc
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.cc
@@ -199,7 +199,7 @@ int main(int argc, char** argv) {
size_t roots_size = strlen(test_root_cert);
char* roots_filename;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
/* Set the SSL roots env var. */
diff --git a/test/core/end2end/fixtures/h2_uds.cc b/test/core/end2end/fixtures/h2_uds.cc
index 2c81c3d362..f251bbd28c 100644
--- a/test/core/end2end/fixtures/h2_uds.cc
+++ b/test/core/end2end/fixtures/h2_uds.cc
@@ -102,7 +102,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/inproc.cc b/test/core/end2end/fixtures/inproc.cc
index be6eda8483..dadf3ef455 100644
--- a/test/core/end2end/fixtures/inproc.cc
+++ b/test/core/end2end/fixtures/inproc.cc
@@ -83,7 +83,7 @@ static grpc_end2end_test_config configs[] = {
int main(int argc, char** argv) {
size_t i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_end2end_tests_pre_init();
grpc_init();
diff --git a/test/core/end2end/fixtures/h2_local.cc b/test/core/end2end/fixtures/local_util.cc
index cce8f1745a..5f0b0300ac 100644
--- a/test/core/end2end/fixtures/h2_local.cc
+++ b/test/core/end2end/fixtures/local_util.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * 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.
@@ -16,11 +16,7 @@
*
*/
-#include "test/core/end2end/end2end_tests.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
+#include "test/core/end2end/fixtures/local_util.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@@ -34,39 +30,28 @@
#include "src/core/lib/gpr/host_port.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/surface/channel.h"
#include "src/core/lib/surface/server.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-typedef struct fullstack_fixture_data {
- char* localaddr;
-} fullstack_fixture_data;
-
-static int unique = 1;
-
-static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
- grpc_channel_args* client_args, grpc_channel_args* server_args) {
+grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack() {
grpc_end2end_test_fixture f;
- fullstack_fixture_data* ffd = static_cast<fullstack_fixture_data*>(
- gpr_malloc(sizeof(fullstack_fixture_data)));
+ grpc_end2end_local_fullstack_fixture_data* ffd =
+ static_cast<grpc_end2end_local_fullstack_fixture_data*>(
+ gpr_malloc(sizeof(grpc_end2end_local_fullstack_fixture_data)));
memset(&f, 0, sizeof(f));
-
- gpr_asprintf(&ffd->localaddr, "unix:/tmp/grpc_fullstack_test.%d.%d", getpid(),
- unique++);
-
f.fixture_data = ffd;
f.cq = grpc_completion_queue_create_for_next(nullptr);
f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr);
-
return f;
}
-void chttp2_init_client_fullstack(grpc_end2end_test_fixture* f,
- grpc_channel_args* client_args) {
- grpc_channel_credentials* creds = grpc_local_credentials_create(UDS);
- fullstack_fixture_data* ffd =
- static_cast<fullstack_fixture_data*>(f->fixture_data);
+void grpc_end2end_local_chttp2_init_client_fullstack(
+ grpc_end2end_test_fixture* f, grpc_channel_args* client_args,
+ grpc_local_connect_type type) {
+ grpc_channel_credentials* creds = grpc_local_credentials_create(type);
+ grpc_end2end_local_fullstack_fixture_data* ffd =
+ static_cast<grpc_end2end_local_fullstack_fixture_data*>(f->fixture_data);
f->client =
grpc_secure_channel_create(creds, ffd->localaddr, client_args, nullptr);
GPR_ASSERT(f->client != nullptr);
@@ -98,11 +83,12 @@ static void process_auth_failure(void* state, grpc_auth_context* ctx,
cb(user_data, nullptr, 0, nullptr, 0, GRPC_STATUS_UNAUTHENTICATED, nullptr);
}
-void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f,
- grpc_channel_args* server_args) {
- grpc_server_credentials* creds = grpc_local_server_credentials_create(UDS);
- fullstack_fixture_data* ffd =
- static_cast<fullstack_fixture_data*>(f->fixture_data);
+void grpc_end2end_local_chttp2_init_server_fullstack(
+ grpc_end2end_test_fixture* f, grpc_channel_args* server_args,
+ grpc_local_connect_type type) {
+ grpc_server_credentials* creds = grpc_local_server_credentials_create(type);
+ grpc_end2end_local_fullstack_fixture_data* ffd =
+ static_cast<grpc_end2end_local_fullstack_fixture_data*>(f->fixture_data);
if (f->server) {
grpc_server_destroy(f->server);
}
@@ -119,36 +105,10 @@ void chttp2_init_server_fullstack(grpc_end2end_test_fixture* f,
grpc_server_start(f->server);
}
-void chttp2_tear_down_fullstack(grpc_end2end_test_fixture* f) {
- fullstack_fixture_data* ffd =
- static_cast<fullstack_fixture_data*>(f->fixture_data);
+void grpc_end2end_local_chttp2_tear_down_fullstack(
+ grpc_end2end_test_fixture* f) {
+ grpc_end2end_local_fullstack_fixture_data* ffd =
+ static_cast<grpc_end2end_local_fullstack_fixture_data*>(f->fixture_data);
gpr_free(ffd->localaddr);
gpr_free(ffd);
}
-
-/* All test configurations */
-static grpc_end2end_test_config configs[] = {
- {"chttp2/fullstack_local",
- FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
- FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL |
- FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER |
- FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
- nullptr, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
- chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
-};
-
-int main(int argc, char** argv) {
- size_t i;
-
- grpc_test_init(argc, argv);
- grpc_end2end_tests_pre_init();
- grpc_init();
-
- for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
- grpc_end2end_tests(argc, argv, configs[i]);
- }
-
- grpc_shutdown();
-
- return 0;
-}
diff --git a/test/core/end2end/fixtures/local_util.h b/test/core/end2end/fixtures/local_util.h
new file mode 100644
index 0000000000..f133b4d977
--- /dev/null
+++ b/test/core/end2end/fixtures/local_util.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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 "test/core/end2end/end2end_tests.h"
+
+#include <grpc/grpc_security.h>
+
+#include "src/core/lib/surface/channel.h"
+
+typedef struct grpc_end2end_local_fullstack_fixture_data {
+ char* localaddr;
+} grpc_end2end_local_fullstack_fixture_data;
+
+/* Utility functions shared by h2_local tests. */
+grpc_end2end_test_fixture grpc_end2end_local_chttp2_create_fixture_fullstack();
+
+void grpc_end2end_local_chttp2_init_client_fullstack(
+ grpc_end2end_test_fixture* f, grpc_channel_args* client_args,
+ grpc_local_connect_type type);
+
+void grpc_end2end_local_chttp2_init_server_fullstack(
+ grpc_end2end_test_fixture* f, grpc_channel_args* server_args,
+ grpc_local_connect_type type);
+
+void grpc_end2end_local_chttp2_tear_down_fullstack(
+ grpc_end2end_test_fixture* f);
diff --git a/test/core/end2end/fuzzers/api_fuzzer.cc b/test/core/end2end/fuzzers/api_fuzzer.cc
index e97a544e12..a0b8290475 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.cc
+++ b/test/core/end2end/fuzzers/api_fuzzer.cc
@@ -24,8 +24,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
@@ -325,7 +325,7 @@ typedef struct addr_req {
char* addr;
grpc_closure* on_done;
grpc_resolved_addresses** addrs;
- grpc_lb_addresses** lb_addrs;
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses;
} addr_req;
static void finish_resolve(void* arg, grpc_error* error) {
@@ -340,11 +340,12 @@ static void finish_resolve(void* arg, grpc_error* error) {
gpr_malloc(sizeof(*addrs->addrs)));
addrs->addrs[0].len = 0;
*r->addrs = addrs;
- } else if (r->lb_addrs != nullptr) {
- grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_lb_addresses_set_address(lb_addrs, 0, nullptr, 0, false, nullptr,
- nullptr);
- *r->lb_addrs = lb_addrs;
+ } else if (r->addresses != nullptr) {
+ *r->addresses = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
+ grpc_resolved_address dummy_resolved_address;
+ memset(&dummy_resolved_address, 0, sizeof(dummy_resolved_address));
+ dummy_resolved_address.len = 0;
+ (*r->addresses)->emplace_back(dummy_resolved_address, nullptr);
}
GRPC_CLOSURE_SCHED(r->on_done, GRPC_ERROR_NONE);
} else {
@@ -354,18 +355,17 @@ static void finish_resolve(void* arg, grpc_error* error) {
}
gpr_free(r->addr);
- gpr_free(r);
+ grpc_core::Delete(r);
}
void my_resolve_address(const char* addr, const char* default_port,
grpc_pollset_set* interested_parties,
grpc_closure* on_done,
- grpc_resolved_addresses** addresses) {
- addr_req* r = static_cast<addr_req*>(gpr_malloc(sizeof(*r)));
+ grpc_resolved_addresses** addrs) {
+ addr_req* r = grpc_core::New<addr_req>();
r->addr = gpr_strdup(addr);
r->on_done = on_done;
- r->addrs = addresses;
- r->lb_addrs = nullptr;
+ r->addrs = addrs;
grpc_timer_init(
&r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx));
@@ -377,13 +377,14 @@ static grpc_address_resolver_vtable fuzzer_resolver = {my_resolve_address,
grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout,
grpc_combiner* combiner) {
addr_req* r = static_cast<addr_req*>(gpr_malloc(sizeof(*r)));
r->addr = gpr_strdup(addr);
r->on_done = on_done;
r->addrs = nullptr;
- r->lb_addrs = lb_addrs;
+ r->addresses = addresses;
grpc_timer_init(
&r->timer, GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now(),
GRPC_CLOSURE_CREATE(finish_resolve, r, grpc_schedule_on_exec_ctx));
@@ -420,7 +421,7 @@ static void do_connect(void* arg, grpc_error* error) {
grpc_transport* transport =
grpc_create_chttp2_transport(nullptr, server, false);
- grpc_server_setup_transport(g_server, transport, nullptr, nullptr, 0);
+ grpc_server_setup_transport(g_server, transport, nullptr, nullptr, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
GRPC_CLOSURE_SCHED(fc->closure, GRPC_ERROR_NONE);
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index a79fe5ad95..0469421c97 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -35,6 +35,7 @@
"\x1Fgrpc.max_response_message_bytes"
"$/grpc.lb.v1.LoadBalancer/BalanceLoad"
"\x1C/grpc.health.v1.Health/Watch"
+"P/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources"
"\x07deflate"
"\x04gzip"
"\x0Bstream/gzip"
diff --git a/test/core/end2end/fuzzers/server_fuzzer.cc b/test/core/end2end/fuzzers/server_fuzzer.cc
index bd686215dd..d370dc7de8 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.cc
+++ b/test/core/end2end/fuzzers/server_fuzzer.cc
@@ -62,7 +62,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
grpc_server_start(server);
grpc_transport* transport =
grpc_create_chttp2_transport(nullptr, mock_endpoint, false);
- grpc_server_setup_transport(server, transport, nullptr, nullptr, 0);
+ grpc_server_setup_transport(server, transport, nullptr, nullptr, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
grpc_call* call1 = nullptr;
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 601d3bac38..c9518d9b81 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -74,7 +74,9 @@ END2END_FIXTURES = {
'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(
ci_mac=False, tracing=True, large_writes=False, exclude_iomgrs=['uv']),
'h2_ssl': default_secure_fixture_options,
- 'h2_local': local_fixture_options,
+ 'h2_local_uds': local_fixture_options,
+ 'h2_local_ipv4': local_fixture_options,
+ 'h2_local_ipv6': local_fixture_options,
'h2_ssl_proxy': default_secure_fixture_options._replace(
includes_proxy=True, ci_mac=False, exclude_iomgrs=['uv']),
'h2_uds': uds_fixture_options,
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 81956db841..8f194b2825 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -85,7 +85,9 @@ END2END_FIXTURES = {
client_channel = False,
),
"h2_ssl": _fixture_options(secure = True),
- "h2_local": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]),
+ "h2_local_uds": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]),
+ "h2_local_ipv4": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]),
+ "h2_local_ipv6": _fixture_options(secure = True, dns_resolver = False, _platforms = ["linux", "mac", "posix"]),
"h2_ssl_proxy": _fixture_options(includes_proxy = True, secure = True),
"h2_uds": _fixture_options(
dns_resolver = False,
@@ -376,6 +378,7 @@ def grpc_end2end_tests():
":ssl_test_data",
":http_proxy",
":proxy",
+ ":local_util",
],
)
@@ -426,6 +429,7 @@ def grpc_end2end_nosec_tests():
":ssl_test_data",
":http_proxy",
":proxy",
+ ":local_util",
],
)
diff --git a/test/core/end2end/goaway_server_test.cc b/test/core/end2end/goaway_server_test.cc
index 3f1c5596ad..7e3b418cd9 100644
--- a/test/core/end2end/goaway_server_test.cc
+++ b/test/core/end2end/goaway_server_test.cc
@@ -28,8 +28,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <string.h>
-#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "test/core/end2end/cq_verifier.h"
@@ -47,8 +47,9 @@ static int g_resolve_port = -1;
static grpc_ares_request* (*iomgr_dns_lookup_ares_locked)(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** addresses, bool check_grpclb,
- char** service_config_json, grpc_combiner* combiner);
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
+ grpc_combiner* combiner);
static void (*iomgr_cancel_ares_request_locked)(grpc_ares_request* request);
@@ -103,12 +104,13 @@ static grpc_address_resolver_vtable test_resolver = {
static grpc_ares_request* my_dns_lookup_ares_locked(
const char* dns_server, const char* addr, const char* default_port,
grpc_pollset_set* interested_parties, grpc_closure* on_done,
- grpc_lb_addresses** lb_addrs, bool check_grpclb, char** service_config_json,
+ grpc_core::UniquePtr<grpc_core::ServerAddressList>* addresses,
+ bool check_grpclb, char** service_config_json, int query_timeout_ms,
grpc_combiner* combiner) {
if (0 != strcmp(addr, "test")) {
return iomgr_dns_lookup_ares_locked(
- dns_server, addr, default_port, interested_parties, on_done, lb_addrs,
- check_grpclb, service_config_json, combiner);
+ dns_server, addr, default_port, interested_parties, on_done, addresses,
+ check_grpclb, service_config_json, query_timeout_ms, combiner);
}
grpc_error* error = GRPC_ERROR_NONE;
@@ -117,15 +119,12 @@ static grpc_ares_request* my_dns_lookup_ares_locked(
gpr_mu_unlock(&g_mu);
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
- *lb_addrs = grpc_lb_addresses_create(1, nullptr);
- grpc_sockaddr_in* sa =
- static_cast<grpc_sockaddr_in*>(gpr_zalloc(sizeof(grpc_sockaddr_in)));
- sa->sin_family = GRPC_AF_INET;
- sa->sin_addr.s_addr = 0x100007f;
- sa->sin_port = grpc_htons(static_cast<uint16_t>(g_resolve_port));
- grpc_lb_addresses_set_address(*lb_addrs, 0, sa, sizeof(*sa), false, nullptr,
- nullptr);
- gpr_free(sa);
+ *addresses = grpc_core::MakeUnique<grpc_core::ServerAddressList>();
+ grpc_sockaddr_in sa;
+ sa.sin_family = GRPC_AF_INET;
+ sa.sin_addr.s_addr = 0x100007f;
+ sa.sin_port = grpc_htons(static_cast<uint16_t>(g_resolve_port));
+ (*addresses)->emplace_back(&sa, sizeof(sa), nullptr);
gpr_mu_unlock(&g_mu);
}
GRPC_CLOSURE_SCHED(on_done, error);
@@ -144,7 +143,7 @@ int main(int argc, char** argv) {
grpc_op ops[6];
grpc_op* op;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
gpr_mu_init(&g_mu);
grpc_init();
diff --git a/test/core/end2end/h2_ssl_cert_test.cc b/test/core/end2end/h2_ssl_cert_test.cc
index 2c5ee3b156..cb0800bf89 100644
--- a/test/core/end2end/h2_ssl_cert_test.cc
+++ b/test/core/end2end/h2_ssl_cert_test.cc
@@ -358,7 +358,7 @@ int main(int argc, char** argv) {
size_t roots_size = strlen(test_root_cert);
char* roots_filename;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
/* Set the SSL roots env var. */
roots_file =
gpr_tmpfile("chttp2_simple_ssl_cert_fullstack_test", &roots_filename);
diff --git a/test/core/end2end/h2_ssl_session_reuse_test.cc b/test/core/end2end/h2_ssl_session_reuse_test.cc
index b2f398625a..fbcdcc4b3f 100644
--- a/test/core/end2end/h2_ssl_session_reuse_test.cc
+++ b/test/core/end2end/h2_ssl_session_reuse_test.cc
@@ -258,7 +258,7 @@ int main(int argc, char** argv) {
size_t roots_size = strlen(test_root_cert);
char* roots_filename;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
/* Set the SSL roots env var. */
roots_file = gpr_tmpfile("chttp2_ssl_session_reuse_test", &roots_filename);
GPR_ASSERT(roots_filename != nullptr);
diff --git a/test/core/end2end/inproc_callback_test.cc b/test/core/end2end/inproc_callback_test.cc
index 310030046a..72ad992d54 100644
--- a/test/core/end2end/inproc_callback_test.cc
+++ b/test/core/end2end/inproc_callback_test.cc
@@ -495,7 +495,7 @@ static grpc_end2end_test_config configs[] = {
};
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
simple_request_pre_init();
diff --git a/test/core/end2end/invalid_call_argument_test.cc b/test/core/end2end/invalid_call_argument_test.cc
index 6cb2e3ee80..bd28d19298 100644
--- a/test/core/end2end/invalid_call_argument_test.cc
+++ b/test/core/end2end/invalid_call_argument_test.cc
@@ -609,7 +609,7 @@ static void test_invalid_initial_metadata_reserved_key() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_invalid_initial_metadata_reserved_key();
test_non_null_reserved_on_start_batch();
diff --git a/test/core/end2end/multiple_server_queues_test.cc b/test/core/end2end/multiple_server_queues_test.cc
index dfa3b48b52..5ae828c1e3 100644
--- a/test/core/end2end/multiple_server_queues_test.cc
+++ b/test/core/end2end/multiple_server_queues_test.cc
@@ -27,7 +27,7 @@ int main(int argc, char** argv) {
grpc_server* server;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
attr.version = 1;
diff --git a/test/core/end2end/no_server_test.cc b/test/core/end2end/no_server_test.cc
index e8ce4032e0..c289e719ee 100644
--- a/test/core/end2end/no_server_test.cc
+++ b/test/core/end2end/no_server_test.cc
@@ -23,6 +23,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/core/end2end/cq_verifier.h"
#include "test/core/util/test_config.h"
@@ -107,7 +108,7 @@ void run_test(bool wait_for_ready) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
run_test(true /* wait_for_ready */);
run_test(false /* wait_for_ready */);
return 0;
diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc
index 922783aa0d..169190eec0 100644
--- a/test/core/end2end/tests/channelz.cc
+++ b/test/core/end2end/tests/channelz.cc
@@ -259,8 +259,8 @@ static void test_channelz(grpc_end2end_test_config config) {
GPR_ASSERT(nullptr == strstr(json, "\"severity\":\"CT_INFO\""));
gpr_free(json);
- json = channelz_server->RenderServerSockets(0);
- GPR_ASSERT(nullptr != strstr(json, "\"socketRef\":"));
+ json = channelz_server->RenderServerSockets(0, 100);
+ GPR_ASSERT(nullptr != strstr(json, "\"end\":true"));
gpr_free(json);
end_test(&f);
diff --git a/test/core/fling/client.cc b/test/core/fling/client.cc
index 05dc3052d1..2a7a5ca623 100644
--- a/test/core/fling/client.cc
+++ b/test/core/fling/client.cc
@@ -158,11 +158,11 @@ int main(int argc, char** argv) {
gpr_timers_set_log_filename("latency_trace.fling_client.txt");
- grpc_init();
-
GPR_ASSERT(argc >= 1);
fake_argv[0] = argv[0];
- grpc_test_init(1, fake_argv);
+ grpc::testing::TestEnvironment env(1, fake_argv);
+
+ grpc_init();
int warmup_seconds = 1;
int benchmark_seconds = 5;
diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD
index d58d4f2a14..67657ee1ce 100644
--- a/test/core/gpr/BUILD
+++ b/test/core/gpr/BUILD
@@ -81,12 +81,12 @@ grpc_cc_test(
grpc_cc_test(
name = "mpscq_test",
srcs = ["mpscq_test.cc"],
+ exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
language = "C++",
deps = [
"//:gpr",
"//test/core/util:gpr_test_util",
],
- data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
)
grpc_cc_test(
diff --git a/test/core/gpr/alloc_test.cc b/test/core/gpr/alloc_test.cc
index 36cdc02ff2..0b110e2b77 100644
--- a/test/core/gpr/alloc_test.cc
+++ b/test/core/gpr/alloc_test.cc
@@ -64,7 +64,7 @@ static void test_malloc_aligned() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_custom_allocs();
test_malloc_aligned();
return 0;
diff --git a/test/core/gpr/arena_test.cc b/test/core/gpr/arena_test.cc
index 3e7c906591..de4bd9804e 100644
--- a/test/core/gpr/arena_test.cc
+++ b/test/core/gpr/arena_test.cc
@@ -116,7 +116,7 @@ static void concurrent_test(void) {
}
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_noop();
TEST(0_1, 0, 1);
diff --git a/test/core/gpr/cpu_test.cc b/test/core/gpr/cpu_test.cc
index 1052d40b42..dbaeb08c18 100644
--- a/test/core/gpr/cpu_test.cc
+++ b/test/core/gpr/cpu_test.cc
@@ -144,7 +144,7 @@ static void cpu_test(void) {
}
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
cpu_test();
return 0;
}
diff --git a/test/core/gpr/env_test.cc b/test/core/gpr/env_test.cc
index 3f4b493239..a8206bd3cf 100644
--- a/test/core/gpr/env_test.cc
+++ b/test/core/gpr/env_test.cc
@@ -43,7 +43,7 @@ static void test_setenv_getenv(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_setenv_getenv();
return 0;
}
diff --git a/test/core/gpr/host_port_test.cc b/test/core/gpr/host_port_test.cc
index b5d88b2b01..b01bbf4b69 100644
--- a/test/core/gpr/host_port_test.cc
+++ b/test/core/gpr/host_port_test.cc
@@ -50,7 +50,7 @@ static void test_join_host_port_garbage(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_join_host_port();
test_join_host_port_garbage();
diff --git a/test/core/gpr/log_test.cc b/test/core/gpr/log_test.cc
index 839ff0aef9..f96257738b 100644
--- a/test/core/gpr/log_test.cc
+++ b/test/core/gpr/log_test.cc
@@ -53,7 +53,7 @@ static void test_should_not_log(gpr_log_func_args* args) { GPR_ASSERT(false); }
gpr_log(SEVERITY, "hello %d %d %d", 1, 2, 3);
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
/* test logging at various verbosity levels */
gpr_log(GPR_DEBUG, "%s", "hello world");
gpr_log(GPR_INFO, "%s", "hello world");
diff --git a/test/core/gpr/mpscq_test.cc b/test/core/gpr/mpscq_test.cc
index f51bdf8c50..c826ccb498 100644
--- a/test/core/gpr/mpscq_test.cc
+++ b/test/core/gpr/mpscq_test.cc
@@ -182,7 +182,7 @@ static void test_mt_multipop(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_serial();
test_mt();
test_mt_multipop();
diff --git a/test/core/gpr/murmur_hash_test.cc b/test/core/gpr/murmur_hash_test.cc
index 2d2fa72cfb..fdc2cfa76b 100644
--- a/test/core/gpr/murmur_hash_test.cc
+++ b/test/core/gpr/murmur_hash_test.cc
@@ -64,7 +64,7 @@ static void verification_test(hash_func hash, uint32_t expected) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
/* basic tests to verify that things don't crash */
gpr_murmur_hash3("", 0, 0);
gpr_murmur_hash3("xyz", 3, 0);
diff --git a/test/core/gpr/spinlock_test.cc b/test/core/gpr/spinlock_test.cc
index 0ee72edb15..8bd9396da6 100644
--- a/test/core/gpr/spinlock_test.cc
+++ b/test/core/gpr/spinlock_test.cc
@@ -149,7 +149,7 @@ static void inctry(void* v /*=m*/) {
/* ------------------------------------------------- */
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test("spinlock", &inc, 1, 1);
test("spinlock try", &inctry, 1, 1);
return 0;
diff --git a/test/core/gpr/string_test.cc b/test/core/gpr/string_test.cc
index 9f3b312465..7da7b18778 100644
--- a/test/core/gpr/string_test.cc
+++ b/test/core/gpr/string_test.cc
@@ -295,7 +295,7 @@ static void test_is_true(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_strdup();
test_dump();
test_parse_uint32();
diff --git a/test/core/gpr/sync_test.cc b/test/core/gpr/sync_test.cc
index 24b4562819..fc7216e360 100644
--- a/test/core/gpr/sync_test.cc
+++ b/test/core/gpr/sync_test.cc
@@ -458,7 +458,7 @@ static void refcheck(void* v /*=m*/) {
/* ------------------------------------------------- */
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test("mutex", &inc, nullptr, 1, 1);
test("mutex try", &inctry, nullptr, 1, 1);
test("cv", &inc_by_turns, nullptr, 1, 1);
diff --git a/test/core/gpr/time_test.cc b/test/core/gpr/time_test.cc
index 6f070f58df..a32cbfb09a 100644
--- a/test/core/gpr/time_test.cc
+++ b/test/core/gpr/time_test.cc
@@ -254,7 +254,7 @@ static void test_cmp_extreme(void) {
}
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_values();
test_add_sub();
diff --git a/test/core/gpr/tls_test.cc b/test/core/gpr/tls_test.cc
index 0502fc7ef4..d1bed0aafe 100644
--- a/test/core/gpr/tls_test.cc
+++ b/test/core/gpr/tls_test.cc
@@ -50,7 +50,7 @@ static void thd_body(void* arg) {
int main(int argc, char* argv[]) {
grpc_core::Thread threads[NUM_THREADS];
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
gpr_tls_init(&test_var);
diff --git a/test/core/gpr/useful_test.cc b/test/core/gpr/useful_test.cc
index 619c800c4d..4f8582ab41 100644
--- a/test/core/gpr/useful_test.cc
+++ b/test/core/gpr/useful_test.cc
@@ -26,7 +26,7 @@ int main(int argc, char** argv) {
int four[4];
int five[5];
uint32_t bitset = 0;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
GPR_ASSERT(GPR_MIN(1, 2) == 1);
GPR_ASSERT(GPR_MAX(1, 2) == 2);
diff --git a/test/core/gprpp/fork_test.cc b/test/core/gprpp/fork_test.cc
index 642f910489..0f56eead49 100644
--- a/test/core/gprpp/fork_test.cc
+++ b/test/core/gprpp/fork_test.cc
@@ -130,7 +130,7 @@ static void test_exec_count() {
}
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_init();
test_thd_count();
test_exec_count();
diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc
index 73e0773b31..f943128f53 100644
--- a/test/core/gprpp/inlined_vector_test.cc
+++ b/test/core/gprpp/inlined_vector_test.cc
@@ -116,7 +116,7 @@ typedef InlinedVector<int, kInlinedLength> IntVec8;
const size_t kInlinedFillSize = kInlinedLength - 1;
const size_t kAllocatedFillSize = kInlinedLength + 1;
-TEST(InlinedVectorTest, CopyConstructerInlined) {
+TEST(InlinedVectorTest, CopyConstructorInlined) {
IntVec8 original;
FillVector(&original, kInlinedFillSize);
IntVec8 copy_constructed(original);
@@ -125,7 +125,7 @@ TEST(InlinedVectorTest, CopyConstructerInlined) {
}
}
-TEST(InlinedVectorTest, CopyConstructerAllocated) {
+TEST(InlinedVectorTest, CopyConstructorAllocated) {
IntVec8 original;
FillVector(&original, kAllocatedFillSize);
IntVec8 copy_constructed(original);
@@ -264,6 +264,166 @@ TEST(InlinedVectorTest, MoveAssignmentAllocatedAllocated) {
EXPECT_EQ(move_assigned.data(), old_data);
}
+// A copyable and movable value class, used to test that elements' copy
+// and move methods are called correctly.
+class Value {
+ public:
+ explicit Value(int v) : value_(MakeUnique<int>(v)) {}
+
+ // copyable
+ Value(const Value& v) {
+ value_ = MakeUnique<int>(*v.value_);
+ copied_ = true;
+ }
+ Value& operator=(const Value& v) {
+ value_ = MakeUnique<int>(*v.value_);
+ copied_ = true;
+ return *this;
+ }
+
+ // movable
+ Value(Value&& v) {
+ value_ = std::move(v.value_);
+ moved_ = true;
+ }
+ Value& operator=(Value&& v) {
+ value_ = std::move(v.value_);
+ moved_ = true;
+ return *this;
+ }
+
+ const UniquePtr<int>& value() const { return value_; }
+ bool copied() const { return copied_; }
+ bool moved() const { return moved_; }
+
+ private:
+ UniquePtr<int> value_;
+ bool copied_ = false;
+ bool moved_ = false;
+};
+
+TEST(InlinedVectorTest, CopyConstructorCopiesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ InlinedVector<Value, 1> v2(v1);
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_TRUE(v2[0].copied());
+}
+
+TEST(InlinedVectorTest, CopyConstructorCopiesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ InlinedVector<Value, 1> v2(v1);
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_NE(v1[1].value().get(), v2[1].value().get());
+ EXPECT_TRUE(v2[0].copied());
+ EXPECT_TRUE(v2[1].copied());
+}
+
+TEST(InlinedVectorTest, CopyAssignmentCopiesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = v1;
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_TRUE(v2[0].copied());
+}
+
+TEST(InlinedVectorTest, CopyAssignmentCopiesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = v1;
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_NE(v1[1].value().get(), v2[1].value().get());
+ EXPECT_TRUE(v2[0].copied());
+ EXPECT_TRUE(v2[1].copied());
+}
+
+TEST(InlinedVectorTest, MoveConstructorMovesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ int* addr = v1[0].value().get();
+ InlinedVector<Value, 1> v2(std::move(v1));
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(addr, v2[0].value().get());
+ EXPECT_TRUE(v2[0].moved());
+}
+
+TEST(InlinedVectorTest, MoveConstructorMovesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ int* addr1 = v1[0].value().get();
+ int* addr2 = v1[1].value().get();
+ Value* data1 = v1.data();
+ InlinedVector<Value, 1> v2(std::move(v1));
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ EXPECT_EQ(addr1, v2[0].value().get());
+ EXPECT_EQ(addr2, v2[1].value().get());
+ // In this case, elements won't be moved, because we have just stolen
+ // the underlying storage.
+ EXPECT_EQ(data1, v2.data());
+}
+
+TEST(InlinedVectorTest, MoveAssignmentMovesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ int* addr = v1[0].value().get();
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = std::move(v1);
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(addr, v2[0].value().get());
+ EXPECT_TRUE(v2[0].moved());
+}
+
+TEST(InlinedVectorTest, MoveAssignmentMovesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ int* addr1 = v1[0].value().get();
+ int* addr2 = v1[1].value().get();
+ Value* data1 = v1.data();
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = std::move(v1);
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ EXPECT_EQ(addr1, v2[0].value().get());
+ EXPECT_EQ(addr2, v2[1].value().get());
+ // In this case, elements won't be moved, because we have just stolen
+ // the underlying storage.
+ EXPECT_EQ(data1, v2.data());
+}
+
TEST(InlinedVectorTest, PopBackInlined) {
InlinedVector<UniquePtr<int>, 2> v;
// Add two elements, pop one out
@@ -294,7 +454,7 @@ TEST(InlinedVectorTest, PopBackAllocated) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/gprpp/manual_constructor_test.cc b/test/core/gprpp/manual_constructor_test.cc
index af162ae8e8..a5a45133d8 100644
--- a/test/core/gprpp/manual_constructor_test.cc
+++ b/test/core/gprpp/manual_constructor_test.cc
@@ -92,7 +92,7 @@ static void complex_test() {
/* ------------------------------------------------- */
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
basic_test();
complex_test();
return 0;
diff --git a/test/core/gprpp/memory_test.cc b/test/core/gprpp/memory_test.cc
index 180c36fad7..bb6a219a84 100644
--- a/test/core/gprpp/memory_test.cc
+++ b/test/core/gprpp/memory_test.cc
@@ -68,7 +68,7 @@ TEST(MemoryTest, UniquePtrWithCustomDeleter) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/gprpp/orphanable_test.cc b/test/core/gprpp/orphanable_test.cc
index ad6b9ac867..fe13df0d0d 100644
--- a/test/core/gprpp/orphanable_test.cc
+++ b/test/core/gprpp/orphanable_test.cc
@@ -83,11 +83,11 @@ TEST(OrphanablePtr, InternallyRefCounted) {
// things build properly in both debug and non-debug cases.
DebugOnlyTraceFlag baz_tracer(true, "baz");
-class Baz : public InternallyRefCountedWithTracing<Baz> {
+class Baz : public InternallyRefCounted<Baz> {
public:
Baz() : Baz(0) {}
explicit Baz(int value)
- : InternallyRefCountedWithTracing<Baz>(&baz_tracer), value_(value) {}
+ : InternallyRefCounted<Baz>(&baz_tracer), value_(value) {}
void Orphan() override { Unref(); }
int value() const { return value_; }
@@ -114,7 +114,7 @@ TEST(OrphanablePtr, InternallyRefCountedWithTracing) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc
index 463b5e8966..96dbdf884b 100644
--- a/test/core/gprpp/ref_counted_ptr_test.cc
+++ b/test/core/gprpp/ref_counted_ptr_test.cc
@@ -163,9 +163,9 @@ TEST(MakeRefCounted, Args) {
TraceFlag foo_tracer(true, "foo");
-class FooWithTracing : public RefCountedWithTracing<FooWithTracing> {
+class FooWithTracing : public RefCounted<FooWithTracing> {
public:
- FooWithTracing() : RefCountedWithTracing(&foo_tracer) {}
+ FooWithTracing() : RefCounted(&foo_tracer) {}
};
TEST(RefCountedPtr, RefCountedWithTracing) {
@@ -241,7 +241,7 @@ TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc
index 62a3ea4d53..1955be3311 100644
--- a/test/core/gprpp/ref_counted_test.cc
+++ b/test/core/gprpp/ref_counted_test.cc
@@ -74,9 +74,9 @@ TEST(RefCountedNonPolymorphic, ExtraRef) {
// things build properly in both debug and non-debug cases.
DebugOnlyTraceFlag foo_tracer(true, "foo");
-class FooWithTracing : public RefCountedWithTracing<FooWithTracing> {
+class FooWithTracing : public RefCounted<FooWithTracing> {
public:
- FooWithTracing() : RefCountedWithTracing(&foo_tracer) {}
+ FooWithTracing() : RefCounted(&foo_tracer) {}
};
TEST(RefCountedWithTracing, Basic) {
@@ -92,10 +92,9 @@ TEST(RefCountedWithTracing, Basic) {
}
class FooNonPolymorphicWithTracing
- : public RefCountedWithTracing<FooNonPolymorphicWithTracing,
- NonPolymorphicRefCount> {
+ : public RefCounted<FooNonPolymorphicWithTracing, NonPolymorphicRefCount> {
public:
- FooNonPolymorphicWithTracing() : RefCountedWithTracing(&foo_tracer) {}
+ FooNonPolymorphicWithTracing() : RefCounted(&foo_tracer) {}
};
TEST(RefCountedNonPolymorphicWithTracing, Basic) {
@@ -116,7 +115,7 @@ TEST(RefCountedNonPolymorphicWithTracing, Basic) {
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/gprpp/thd_test.cc b/test/core/gprpp/thd_test.cc
index 82dd681049..06aa58984b 100644
--- a/test/core/gprpp/thd_test.cc
+++ b/test/core/gprpp/thd_test.cc
@@ -92,7 +92,7 @@ static void test2(void) {
/* ------------------------------------------------- */
int main(int argc, char* argv[]) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test1();
test2();
return 0;
diff --git a/test/core/http/format_request_test.cc b/test/core/http/format_request_test.cc
index 353e138b2a..b0a90c4613 100644
--- a/test/core/http/format_request_test.cc
+++ b/test/core/http/format_request_test.cc
@@ -138,7 +138,7 @@ static void test_format_post_request_content_type_override(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_format_get_request();
diff --git a/test/core/http/httpcli_test.cc b/test/core/http/httpcli_test.cc
index a51a0a5f6d..bfd75f8649 100644
--- a/test/core/http/httpcli_test.cc
+++ b/test/core/http/httpcli_test.cc
@@ -145,7 +145,7 @@ static void destroy_pops(void* p, grpc_error* error) {
int main(int argc, char** argv) {
gpr_subprocess* server;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_closure destroyed;
diff --git a/test/core/http/httpscli_test.cc b/test/core/http/httpscli_test.cc
index 3fecf2b08b..326b0e95e2 100644
--- a/test/core/http/httpscli_test.cc
+++ b/test/core/http/httpscli_test.cc
@@ -201,7 +201,7 @@ int main(int argc, char** argv) {
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_seconds(5, GPR_TIMESPAN)));
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
grpc_httpcli_context_init(&g_context);
grpc_pollset* pollset =
diff --git a/test/core/http/parser_test.cc b/test/core/http/parser_test.cc
index fe824f57fc..d105b40bcd 100644
--- a/test/core/http/parser_test.cc
+++ b/test/core/http/parser_test.cc
@@ -218,7 +218,7 @@ int main(int argc, char** argv) {
GRPC_SLICE_SPLIT_ONE_BYTE};
char *tmp1, *tmp2;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
for (i = 0; i < GPR_ARRAY_SIZE(split_modes); i++) {
diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD
index 70ee83acd2..e278632e50 100644
--- a/test/core/iomgr/BUILD
+++ b/test/core/iomgr/BUILD
@@ -40,7 +40,7 @@ grpc_cc_library(
grpc_cc_test(
name = "combiner_test",
srcs = ["combiner_test.cc"],
- data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
+ exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
language = "C++",
deps = [
"//:gpr",
diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc
index c7f30fa092..eca8f76e67 100644
--- a/test/core/iomgr/buffer_list_test.cc
+++ b/test/core/iomgr/buffer_list_test.cc
@@ -50,7 +50,7 @@ static void TestShutdownFlushesList() {
grpc_core::TracedBuffer::AddNewEntry(
&list, i, static_cast<void*>(&verifier_called[i]));
}
- grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE);
+ grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE);
GPR_ASSERT(list == nullptr);
for (auto i = 0; i < NUM_ELEM; i++) {
GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) ==
@@ -88,7 +88,7 @@ static void TestVerifierCalledOnAck() {
grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss);
GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast<gpr_atm>(1));
GPR_ASSERT(list == nullptr);
- grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE);
+ grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE);
}
static void TestTcpBufferList() {
@@ -97,7 +97,7 @@ static void TestTcpBufferList() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
TestTcpBufferList();
grpc_shutdown();
diff --git a/test/core/iomgr/combiner_test.cc b/test/core/iomgr/combiner_test.cc
index cf2c7db846..c39c3fc8fc 100644
--- a/test/core/iomgr/combiner_test.cc
+++ b/test/core/iomgr/combiner_test.cc
@@ -144,7 +144,7 @@ static void test_execute_finally(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_no_op();
test_execute_one();
diff --git a/test/core/iomgr/endpoint_pair_test.cc b/test/core/iomgr/endpoint_pair_test.cc
index ad38076b51..3ddbe7f2fc 100644
--- a/test/core/iomgr/endpoint_pair_test.cc
+++ b/test/core/iomgr/endpoint_pair_test.cc
@@ -60,7 +60,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/error_test.cc b/test/core/iomgr/error_test.cc
index d78a8c2af3..3ba90147aa 100644
--- a/test/core/iomgr/error_test.cc
+++ b/test/core/iomgr/error_test.cc
@@ -215,7 +215,7 @@ static void test_overflow() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_set_get_int();
test_set_get_str();
diff --git a/test/core/iomgr/ev_epollex_linux_test.cc b/test/core/iomgr/ev_epollex_linux_test.cc
index 08d1e68b39..faa3ef344a 100644
--- a/test/core/iomgr/ev_epollex_linux_test.cc
+++ b/test/core/iomgr/ev_epollex_linux_test.cc
@@ -92,7 +92,7 @@ static void test_pollable_owner_fd() {
int main(int argc, char** argv) {
const char* poll_strategy = nullptr;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/fd_conservation_posix_test.cc b/test/core/iomgr/fd_conservation_posix_test.cc
index 4866e350d5..0d27b94dc2 100644
--- a/test/core/iomgr/fd_conservation_posix_test.cc
+++ b/test/core/iomgr/fd_conservation_posix_test.cc
@@ -29,7 +29,7 @@ int main(int argc, char** argv) {
struct rlimit rlim;
grpc_endpoint_pair p;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/fd_posix_test.cc b/test/core/iomgr/fd_posix_test.cc
index 4ea2389bbd..cf5ffc6354 100644
--- a/test/core/iomgr/fd_posix_test.cc
+++ b/test/core/iomgr/fd_posix_test.cc
@@ -515,7 +515,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc
index 329aa9a851..2ef1f1978d 100644
--- a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc
+++ b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc
@@ -32,7 +32,7 @@
#endif
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
// This test assumes that the ipv6 loopback is available
// in all environments in which grpc tests run in.
diff --git a/test/core/iomgr/load_file_test.cc b/test/core/iomgr/load_file_test.cc
index 38c8710535..a0e0e4d7a7 100644
--- a/test/core/iomgr/load_file_test.cc
+++ b/test/core/iomgr/load_file_test.cc
@@ -152,7 +152,7 @@ static void test_load_big_file(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_load_empty_file();
test_load_failure();
diff --git a/test/core/iomgr/resolve_address_posix_test.cc b/test/core/iomgr/resolve_address_posix_test.cc
index e495e4c877..5785c73e22 100644
--- a/test/core/iomgr/resolve_address_posix_test.cc
+++ b/test/core/iomgr/resolve_address_posix_test.cc
@@ -27,6 +27,8 @@
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
+#include "src/core/lib/gpr/env.h"
+#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/executor.h"
@@ -158,13 +160,20 @@ static void test_unix_socket_path_name_too_long(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
- test_unix_socket();
- test_unix_socket_path_name_too_long();
+ char* resolver_env = gpr_getenv("GRPC_DNS_RESOLVER");
+ // c-ares resolver doesn't support UDS (ability for native DNS resolver
+ // to handle this is only expected to be used by servers, which
+ // unconditionally use the native DNS resolver).
+ if (resolver_env == nullptr || gpr_stricmp(resolver_env, "native") == 0) {
+ test_unix_socket();
+ test_unix_socket_path_name_too_long();
+ }
+ gpr_free(resolver_env);
}
grpc_shutdown();
diff --git a/test/core/iomgr/resolve_address_test.cc b/test/core/iomgr/resolve_address_test.cc
index 8d69bab5b1..1d9e1ee27e 100644
--- a/test/core/iomgr/resolve_address_test.cc
+++ b/test/core/iomgr/resolve_address_test.cc
@@ -271,7 +271,7 @@ int main(int argc, char** argv) {
abort();
}
// Run the test.
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/resource_quota_test.cc b/test/core/iomgr/resource_quota_test.cc
index f3b35fed32..4cbc016d58 100644
--- a/test/core/iomgr/resource_quota_test.cc
+++ b/test/core/iomgr/resource_quota_test.cc
@@ -891,7 +891,7 @@ static void test_thread_maxquota_change() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
gpr_mu_init(&g_mu);
gpr_cv_init(&g_cv);
diff --git a/test/core/iomgr/sockaddr_utils_test.cc b/test/core/iomgr/sockaddr_utils_test.cc
index 3783f968b7..250d36a74a 100644
--- a/test/core/iomgr/sockaddr_utils_test.cc
+++ b/test/core/iomgr/sockaddr_utils_test.cc
@@ -270,7 +270,7 @@ static void test_sockaddr_set_get_port(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_sockaddr_is_v4mapped();
test_sockaddr_to_v4mapped();
diff --git a/test/core/iomgr/socket_utils_test.cc b/test/core/iomgr/socket_utils_test.cc
index a21f3fac62..420873734d 100644
--- a/test/core/iomgr/socket_utils_test.cc
+++ b/test/core/iomgr/socket_utils_test.cc
@@ -80,7 +80,7 @@ static const grpc_socket_mutator_vtable mutator_vtable = {
int main(int argc, char** argv) {
int sock;
grpc_error* err;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
sock = socket(PF_INET, SOCK_STREAM, 0);
GPR_ASSERT(sock > 0);
diff --git a/test/core/iomgr/tcp_client_posix_test.cc b/test/core/iomgr/tcp_client_posix_test.cc
index 90fc5aecfc..5cf3530c77 100644
--- a/test/core/iomgr/tcp_client_posix_test.cc
+++ b/test/core/iomgr/tcp_client_posix_test.cc
@@ -191,7 +191,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
diff --git a/test/core/iomgr/tcp_client_uv_test.cc b/test/core/iomgr/tcp_client_uv_test.cc
index 27f894e3f3..bde8c2f353 100644
--- a/test/core/iomgr/tcp_client_uv_test.cc
+++ b/test/core/iomgr/tcp_client_uv_test.cc
@@ -188,7 +188,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/tcp_posix_test.cc b/test/core/iomgr/tcp_posix_test.cc
index 6447cc234d..80f17a914f 100644
--- a/test/core/iomgr/tcp_posix_test.cc
+++ b/test/core/iomgr/tcp_posix_test.cc
@@ -623,7 +623,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
grpc_core::grpc_tcp_set_write_timestamps_callback(timestamps_verifier);
{
diff --git a/test/core/iomgr/tcp_server_posix_test.cc b/test/core/iomgr/tcp_server_posix_test.cc
index d646df1dae..2c66cdec77 100644
--- a/test/core/iomgr/tcp_server_posix_test.cc
+++ b/test/core/iomgr/tcp_server_posix_test.cc
@@ -437,7 +437,7 @@ int main(int argc, char** argv) {
// Zalloc dst_addrs to avoid oversized frames.
test_addrs* dst_addrs =
static_cast<test_addrs*>(gpr_zalloc(sizeof(*dst_addrs)));
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/tcp_server_uv_test.cc b/test/core/iomgr/tcp_server_uv_test.cc
index e99fa79bfd..625a18c0cc 100644
--- a/test/core/iomgr/tcp_server_uv_test.cc
+++ b/test/core/iomgr/tcp_server_uv_test.cc
@@ -288,7 +288,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
grpc_core::ExecCtx exec_ctx;
diff --git a/test/core/iomgr/time_averaged_stats_test.cc b/test/core/iomgr/time_averaged_stats_test.cc
index b932e62d1f..2923a35d1b 100644
--- a/test/core/iomgr/time_averaged_stats_test.cc
+++ b/test/core/iomgr/time_averaged_stats_test.cc
@@ -180,7 +180,7 @@ static void some_regress_some_persist_test(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
no_regress_no_persist_test_1();
no_regress_no_persist_test_2();
no_regress_no_persist_test_3();
diff --git a/test/core/iomgr/timer_heap_test.cc b/test/core/iomgr/timer_heap_test.cc
index ebe5e6610d..872cf17486 100644
--- a/test/core/iomgr/timer_heap_test.cc
+++ b/test/core/iomgr/timer_heap_test.cc
@@ -286,7 +286,7 @@ static void shrink_test(void) {
int main(int argc, char** argv) {
int i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
for (i = 0; i < 5; i++) {
test1();
diff --git a/test/core/iomgr/timer_list_test.cc b/test/core/iomgr/timer_list_test.cc
index fd65d1abf1..fa2444948b 100644
--- a/test/core/iomgr/timer_list_test.cc
+++ b/test/core/iomgr/timer_list_test.cc
@@ -221,7 +221,7 @@ void long_running_service_cleanup_test(void) {
int main(int argc, char** argv) {
/* Tests with default g_start_time */
{
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_core::ExecCtx::GlobalInit();
grpc_core::ExecCtx exec_ctx;
grpc_determine_iomgr_platform();
@@ -235,7 +235,7 @@ int main(int argc, char** argv) {
/* Begin long running service tests */
{
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
/* Set g_start_time back 25 days. */
/* We set g_start_time here in case there are any initialization
dependencies that use g_start_time. */
diff --git a/test/core/iomgr/udp_server_test.cc b/test/core/iomgr/udp_server_test.cc
index d167c0131f..f65783a017 100644
--- a/test/core/iomgr/udp_server_test.cc
+++ b/test/core/iomgr/udp_server_test.cc
@@ -360,7 +360,7 @@ static void test_receive(int number_of_clients) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
if (grpc_is_socket_reuse_port_supported()) {
g_num_listeners = 10;
diff --git a/test/core/json/json_rewrite_test.cc b/test/core/json/json_rewrite_test.cc
index 2fade12e13..b7e89cdb1a 100644
--- a/test/core/json/json_rewrite_test.cc
+++ b/test/core/json/json_rewrite_test.cc
@@ -287,7 +287,7 @@ void test_rewrites() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_rewrites();
gpr_log(GPR_INFO, "json_rewrite_test success");
return 0;
diff --git a/test/core/json/json_stream_error_test.cc b/test/core/json/json_stream_error_test.cc
index 00288d6d5e..53e20be206 100644
--- a/test/core/json/json_stream_error_test.cc
+++ b/test/core/json/json_stream_error_test.cc
@@ -49,7 +49,7 @@ static void read_error() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
read_error();
gpr_log(GPR_INFO, "json_stream_error success");
return 0;
diff --git a/test/core/json/json_test.cc b/test/core/json/json_test.cc
index 7f1dbb774a..03dd96a8ae 100644
--- a/test/core/json/json_test.cc
+++ b/test/core/json/json_test.cc
@@ -184,7 +184,7 @@ static void test_atypical() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_pairs();
test_atypical();
gpr_log(GPR_INFO, "json_test success");
diff --git a/test/core/memory_usage/client.cc b/test/core/memory_usage/client.cc
index 3c3fa53b51..467586ea5f 100644
--- a/test/core/memory_usage/client.cc
+++ b/test/core/memory_usage/client.cc
@@ -193,11 +193,11 @@ int main(int argc, char** argv) {
gpr_cmdline* cl;
grpc_event event;
- grpc_init();
-
GPR_ASSERT(argc >= 1);
fake_argv[0] = argv[0];
- grpc_test_init(1, fake_argv);
+ grpc::testing::TestEnvironment env(1, fake_argv);
+
+ grpc_init();
int warmup_iterations = 100;
int benchmark_iterations = 1000;
diff --git a/test/core/memory_usage/server.cc b/test/core/memory_usage/server.cc
index 6f8a9bc0d4..7424797e6f 100644
--- a/test/core/memory_usage/server.cc
+++ b/test/core/memory_usage/server.cc
@@ -162,7 +162,7 @@ int main(int argc, char** argv) {
GPR_ASSERT(argc >= 1);
fake_argv[0] = argv[0];
- grpc_test_init(1, fake_argv);
+ grpc::testing::TestEnvironment env(1, fake_argv);
grpc_init();
srand(static_cast<unsigned>(clock()));
diff --git a/test/core/security/alts_security_connector_test.cc b/test/core/security/alts_security_connector_test.cc
index 9378236338..bcba340821 100644
--- a/test/core/security/alts_security_connector_test.cc
+++ b/test/core/security/alts_security_connector_test.cc
@@ -33,40 +33,34 @@ using grpc_core::internal::grpc_alts_auth_context_from_tsi_peer;
/* This file contains unit tests of grpc_alts_auth_context_from_tsi_peer(). */
static void test_invalid_input_failure() {
- tsi_peer peer;
- grpc_auth_context* ctx;
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(nullptr, &ctx) ==
- GRPC_SECURITY_ERROR);
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, nullptr) ==
- GRPC_SECURITY_ERROR);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_alts_auth_context_from_tsi_peer(nullptr);
+ GPR_ASSERT(ctx == nullptr);
}
static void test_empty_certificate_type_failure() {
tsi_peer peer;
- grpc_auth_context* ctx = nullptr;
GPR_ASSERT(tsi_construct_peer(0, &peer) == TSI_OK);
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) ==
- GRPC_SECURITY_ERROR);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_alts_auth_context_from_tsi_peer(&peer);
GPR_ASSERT(ctx == nullptr);
tsi_peer_destruct(&peer);
}
static void test_empty_peer_property_failure() {
tsi_peer peer;
- grpc_auth_context* ctx;
GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE,
&peer.properties[0]) == TSI_OK);
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) ==
- GRPC_SECURITY_ERROR);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_alts_auth_context_from_tsi_peer(&peer);
GPR_ASSERT(ctx == nullptr);
tsi_peer_destruct(&peer);
}
static void test_missing_rpc_protocol_versions_property_failure() {
tsi_peer peer;
- grpc_auth_context* ctx;
GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE,
@@ -74,23 +68,22 @@ static void test_missing_rpc_protocol_versions_property_failure() {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice",
&peer.properties[1]) == TSI_OK);
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) ==
- GRPC_SECURITY_ERROR);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_alts_auth_context_from_tsi_peer(&peer);
GPR_ASSERT(ctx == nullptr);
tsi_peer_destruct(&peer);
}
static void test_unknown_peer_property_failure() {
tsi_peer peer;
- grpc_auth_context* ctx;
GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE,
&peer.properties[0]) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
"unknown", "alice", &peer.properties[1]) == TSI_OK);
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) ==
- GRPC_SECURITY_ERROR);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_alts_auth_context_from_tsi_peer(&peer);
GPR_ASSERT(ctx == nullptr);
tsi_peer_destruct(&peer);
}
@@ -119,7 +112,6 @@ static bool test_identity(const grpc_auth_context* ctx,
static void test_alts_peer_to_auth_context_success() {
tsi_peer peer;
- grpc_auth_context* ctx;
GPR_ASSERT(tsi_construct_peer(kTsiAltsNumOfPeerProperties, &peer) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_ALTS_CERTIFICATE_TYPE,
@@ -144,11 +136,12 @@ static void test_alts_peer_to_auth_context_success() {
GRPC_SLICE_START_PTR(serialized_peer_versions)),
GRPC_SLICE_LENGTH(serialized_peer_versions),
&peer.properties[2]) == TSI_OK);
- GPR_ASSERT(grpc_alts_auth_context_from_tsi_peer(&peer, &ctx) ==
- GRPC_SECURITY_OK);
- GPR_ASSERT(
- test_identity(ctx, TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY, "alice"));
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_alts_auth_context_from_tsi_peer(&peer);
+ GPR_ASSERT(ctx != nullptr);
+ GPR_ASSERT(test_identity(ctx.get(), TSI_ALTS_SERVICE_ACCOUNT_PEER_PROPERTY,
+ "alice"));
+ ctx.reset(DEBUG_LOCATION, "test");
grpc_slice_unref(serialized_peer_versions);
tsi_peer_destruct(&peer);
}
diff --git a/test/core/security/auth_context_test.cc b/test/core/security/auth_context_test.cc
index 58f0d8e1c2..e7e0cb2ed9 100644
--- a/test/core/security/auth_context_test.cc
+++ b/test/core/security/auth_context_test.cc
@@ -19,118 +19,126 @@
#include <string.h>
#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/security/context/security_context.h"
#include "test/core/util/test_config.h"
#include <grpc/support/log.h>
static void test_empty_context(void) {
- grpc_auth_context* ctx = grpc_auth_context_create(nullptr);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_property_iterator it;
gpr_log(GPR_INFO, "test_empty_context");
GPR_ASSERT(ctx != nullptr);
- GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr);
- it = grpc_auth_context_peer_identity(ctx);
+ GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) ==
+ nullptr);
+ it = grpc_auth_context_peer_identity(ctx.get());
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- it = grpc_auth_context_property_iterator(ctx);
+ it = grpc_auth_context_property_iterator(ctx.get());
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- it = grpc_auth_context_find_properties_by_name(ctx, "foo");
+ it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo");
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "bar") ==
- 0);
- GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == nullptr);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ GPR_ASSERT(
+ grpc_auth_context_set_peer_identity_property_name(ctx.get(), "bar") == 0);
+ GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx.get()) ==
+ nullptr);
+ ctx.reset(DEBUG_LOCATION, "test");
}
static void test_simple_context(void) {
- grpc_auth_context* ctx = grpc_auth_context_create(nullptr);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
grpc_auth_property_iterator it;
size_t i;
gpr_log(GPR_INFO, "test_simple_context");
GPR_ASSERT(ctx != nullptr);
- grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
- grpc_auth_context_add_cstring_property(ctx, "name", "chapo");
- grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
- GPR_ASSERT(ctx->properties.count == 3);
- GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") ==
- 1);
-
- GPR_ASSERT(
- strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0);
- it = grpc_auth_context_property_iterator(ctx);
- for (i = 0; i < ctx->properties.count; i++) {
+ grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi");
+ grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapo");
+ grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar");
+ GPR_ASSERT(ctx->properties().count == 3);
+ GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(),
+ "name") == 1);
+
+ GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()),
+ "name") == 0);
+ it = grpc_auth_context_property_iterator(ctx.get());
+ for (i = 0; i < ctx->properties().count; i++) {
const grpc_auth_property* p = grpc_auth_property_iterator_next(&it);
- GPR_ASSERT(p == &ctx->properties.array[i]);
+ GPR_ASSERT(p == &ctx->properties().array[i]);
}
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- it = grpc_auth_context_find_properties_by_name(ctx, "foo");
+ it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo");
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &ctx->properties.array[2]);
+ &ctx->properties().array[2]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- it = grpc_auth_context_peer_identity(ctx);
+ it = grpc_auth_context_peer_identity(ctx.get());
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &ctx->properties.array[0]);
+ &ctx->properties().array[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &ctx->properties.array[1]);
+ &ctx->properties().array[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
static void test_chained_context(void) {
- grpc_auth_context* chained = grpc_auth_context_create(nullptr);
- grpc_auth_context* ctx = grpc_auth_context_create(chained);
+ grpc_core::RefCountedPtr<grpc_auth_context> chained =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
+ grpc_auth_context* chained_ptr = chained.get();
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(std::move(chained));
+
grpc_auth_property_iterator it;
size_t i;
gpr_log(GPR_INFO, "test_chained_context");
- GRPC_AUTH_CONTEXT_UNREF(chained, "chained");
- grpc_auth_context_add_cstring_property(chained, "name", "padapo");
- grpc_auth_context_add_cstring_property(chained, "foo", "baz");
- grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
- grpc_auth_context_add_cstring_property(ctx, "name", "chap0");
- grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
- GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx, "name") ==
- 1);
-
- GPR_ASSERT(
- strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0);
- it = grpc_auth_context_property_iterator(ctx);
- for (i = 0; i < ctx->properties.count; i++) {
+ grpc_auth_context_add_cstring_property(chained_ptr, "name", "padapo");
+ grpc_auth_context_add_cstring_property(chained_ptr, "foo", "baz");
+ grpc_auth_context_add_cstring_property(ctx.get(), "name", "chapi");
+ grpc_auth_context_add_cstring_property(ctx.get(), "name", "chap0");
+ grpc_auth_context_add_cstring_property(ctx.get(), "foo", "bar");
+ GPR_ASSERT(grpc_auth_context_set_peer_identity_property_name(ctx.get(),
+ "name") == 1);
+
+ GPR_ASSERT(strcmp(grpc_auth_context_peer_identity_property_name(ctx.get()),
+ "name") == 0);
+ it = grpc_auth_context_property_iterator(ctx.get());
+ for (i = 0; i < ctx->properties().count; i++) {
const grpc_auth_property* p = grpc_auth_property_iterator_next(&it);
- GPR_ASSERT(p == &ctx->properties.array[i]);
+ GPR_ASSERT(p == &ctx->properties().array[i]);
}
- for (i = 0; i < chained->properties.count; i++) {
+ for (i = 0; i < chained_ptr->properties().count; i++) {
const grpc_auth_property* p = grpc_auth_property_iterator_next(&it);
- GPR_ASSERT(p == &chained->properties.array[i]);
+ GPR_ASSERT(p == &chained_ptr->properties().array[i]);
}
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- it = grpc_auth_context_find_properties_by_name(ctx, "foo");
+ it = grpc_auth_context_find_properties_by_name(ctx.get(), "foo");
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &ctx->properties.array[2]);
+ &ctx->properties().array[2]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &chained->properties.array[1]);
+ &chained_ptr->properties().array[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- it = grpc_auth_context_peer_identity(ctx);
+ it = grpc_auth_context_peer_identity(ctx.get());
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &ctx->properties.array[0]);
+ &ctx->properties().array[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &ctx->properties.array[1]);
+ &ctx->properties().array[1]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) ==
- &chained->properties.array[0]);
+ &chained_ptr->properties().array[0]);
GPR_ASSERT(grpc_auth_property_iterator_next(&it) == nullptr);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_empty_context();
test_simple_context();
test_chained_context();
diff --git a/test/core/security/credentials_test.cc b/test/core/security/credentials_test.cc
index 56c4c9c0ae..b3a8161786 100644
--- a/test/core/security/credentials_test.cc
+++ b/test/core/security/credentials_test.cc
@@ -46,19 +46,6 @@
using grpc_core::internal::grpc_flush_cached_google_default_credentials;
using grpc_core::internal::set_gce_tenancy_checker_for_testing;
-/* -- Mock channel credentials. -- */
-
-static grpc_channel_credentials* grpc_mock_channel_credentials_create(
- const grpc_channel_credentials_vtable* vtable) {
- grpc_channel_credentials* c =
- static_cast<grpc_channel_credentials*>(gpr_malloc(sizeof(*c)));
- memset(c, 0, sizeof(*c));
- c->type = "mock";
- c->vtable = vtable;
- gpr_ref_init(&c->refcount, 1);
- return c;
-}
-
/* -- Constants. -- */
static const char test_google_iam_authorization_token[] = "blahblahblhahb";
@@ -377,9 +364,9 @@ static void run_request_metadata_test(grpc_call_credentials* creds,
grpc_auth_metadata_context auth_md_ctx,
request_metadata_state* state) {
grpc_error* error = GRPC_ERROR_NONE;
- if (grpc_call_credentials_get_request_metadata(
- creds, &state->pollent, auth_md_ctx, &state->md_array,
- &state->on_request_metadata, &error)) {
+ if (creds->get_request_metadata(&state->pollent, auth_md_ctx,
+ &state->md_array, &state->on_request_metadata,
+ &error)) {
// Synchronous result. Invoke the callback directly.
check_request_metadata(state, error);
GRPC_ERROR_UNREF(error);
@@ -400,7 +387,7 @@ static void test_google_iam_creds(void) {
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr};
run_request_metadata_test(creds, auth_md_ctx, state);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
}
static void test_access_token_creds(void) {
@@ -412,28 +399,36 @@ static void test_access_token_creds(void) {
grpc_access_token_credentials_create("blah", nullptr);
grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
nullptr, nullptr};
- GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
+ GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
run_request_metadata_test(creds, auth_md_ctx, state);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
}
-static grpc_security_status check_channel_oauth2_create_security_connector(
- grpc_channel_credentials* c, grpc_call_credentials* call_creds,
- const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
- GPR_ASSERT(strcmp(c->type, "mock") == 0);
- GPR_ASSERT(call_creds != nullptr);
- GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
- return GRPC_SECURITY_OK;
-}
+namespace {
+class check_channel_oauth2 final : public grpc_channel_credentials {
+ public:
+ check_channel_oauth2() : grpc_channel_credentials("mock") {}
+ ~check_channel_oauth2() override = default;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override {
+ GPR_ASSERT(strcmp(type(), "mock") == 0);
+ GPR_ASSERT(call_creds != nullptr);
+ GPR_ASSERT(strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) ==
+ 0);
+ return nullptr;
+ }
+};
+} // namespace
static void test_channel_oauth2_composite_creds(void) {
grpc_core::ExecCtx exec_ctx;
grpc_channel_args* new_args;
- grpc_channel_credentials_vtable vtable = {
- nullptr, check_channel_oauth2_create_security_connector, nullptr};
grpc_channel_credentials* channel_creds =
- grpc_mock_channel_credentials_create(&vtable);
+ grpc_core::New<check_channel_oauth2>();
grpc_call_credentials* oauth2_creds =
grpc_access_token_credentials_create("blah", nullptr);
grpc_channel_credentials* channel_oauth2_creds =
@@ -441,9 +436,8 @@ static void test_channel_oauth2_composite_creds(void) {
nullptr);
grpc_channel_credentials_release(channel_creds);
grpc_call_credentials_release(oauth2_creds);
- GPR_ASSERT(grpc_channel_credentials_create_security_connector(
- channel_oauth2_creds, nullptr, nullptr, nullptr, &new_args) ==
- GRPC_SECURITY_OK);
+ channel_oauth2_creds->create_security_connector(nullptr, nullptr, nullptr,
+ &new_args);
grpc_channel_credentials_release(channel_oauth2_creds);
}
@@ -467,47 +461,54 @@ static void test_oauth2_google_iam_composite_creds(void) {
grpc_call_credentials* composite_creds =
grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds,
nullptr);
- grpc_call_credentials_unref(oauth2_creds);
- grpc_call_credentials_unref(google_iam_creds);
- GPR_ASSERT(
- strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
- const grpc_call_credentials_array* creds_array =
- grpc_composite_call_credentials_get_credentials(composite_creds);
- GPR_ASSERT(creds_array->num_creds == 2);
- GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
+ oauth2_creds->Unref();
+ google_iam_creds->Unref();
+ GPR_ASSERT(strcmp(composite_creds->type(),
+ GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
+ const grpc_call_credentials_array& creds_array =
+ static_cast<const grpc_composite_call_credentials*>(composite_creds)
+ ->inner();
+ GPR_ASSERT(creds_array.size() == 2);
+ GPR_ASSERT(strcmp(creds_array.get(0)->type(),
GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
- GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
- GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
+ GPR_ASSERT(
+ strcmp(creds_array.get(1)->type(), GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
run_request_metadata_test(composite_creds, auth_md_ctx, state);
- grpc_call_credentials_unref(composite_creds);
+ composite_creds->Unref();
}
-static grpc_security_status
-check_channel_oauth2_google_iam_create_security_connector(
- grpc_channel_credentials* c, grpc_call_credentials* call_creds,
- const char* target, const grpc_channel_args* args,
- grpc_channel_security_connector** sc, grpc_channel_args** new_args) {
- const grpc_call_credentials_array* creds_array;
- GPR_ASSERT(strcmp(c->type, "mock") == 0);
- GPR_ASSERT(call_creds != nullptr);
- GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) ==
- 0);
- creds_array = grpc_composite_call_credentials_get_credentials(call_creds);
- GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
- GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
- GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
- GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
- return GRPC_SECURITY_OK;
-}
+namespace {
+class check_channel_oauth2_google_iam final : public grpc_channel_credentials {
+ public:
+ check_channel_oauth2_google_iam() : grpc_channel_credentials("mock") {}
+ ~check_channel_oauth2_google_iam() override = default;
+
+ grpc_core::RefCountedPtr<grpc_channel_security_connector>
+ create_security_connector(
+ grpc_core::RefCountedPtr<grpc_call_credentials> call_creds,
+ const char* target, const grpc_channel_args* args,
+ grpc_channel_args** new_args) override {
+ GPR_ASSERT(strcmp(type(), "mock") == 0);
+ GPR_ASSERT(call_creds != nullptr);
+ GPR_ASSERT(
+ strcmp(call_creds->type(), GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
+ const grpc_call_credentials_array& creds_array =
+ static_cast<const grpc_composite_call_credentials*>(call_creds.get())
+ ->inner();
+ GPR_ASSERT(strcmp(creds_array.get(0)->type(),
+ GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
+ GPR_ASSERT(strcmp(creds_array.get(1)->type(),
+ GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
+ return nullptr;
+ }
+};
+} // namespace
static void test_channel_oauth2_google_iam_composite_creds(void) {
grpc_core::ExecCtx exec_ctx;
grpc_channel_args* new_args;
- grpc_channel_credentials_vtable vtable = {
- nullptr, check_channel_oauth2_google_iam_create_security_connector,
- nullptr};
grpc_channel_credentials* channel_creds =
- grpc_mock_channel_credentials_create(&vtable);
+ grpc_core::New<check_channel_oauth2_google_iam>();
grpc_call_credentials* oauth2_creds =
grpc_access_token_credentials_create("blah", nullptr);
grpc_channel_credentials* channel_oauth2_creds =
@@ -524,9 +525,8 @@ static void test_channel_oauth2_google_iam_composite_creds(void) {
grpc_channel_credentials_release(channel_oauth2_creds);
grpc_call_credentials_release(google_iam_creds);
- GPR_ASSERT(grpc_channel_credentials_create_security_connector(
- channel_oauth2_iam_creds, nullptr, nullptr, nullptr,
- &new_args) == GRPC_SECURITY_OK);
+ channel_oauth2_iam_creds->create_security_connector(nullptr, nullptr, nullptr,
+ &new_args);
grpc_channel_credentials_release(channel_oauth2_iam_creds);
}
@@ -578,7 +578,7 @@ static int httpcli_get_should_not_be_called(const grpc_httpcli_request* request,
return 1;
}
-static void test_compute_engine_creds_success(void) {
+static void test_compute_engine_creds_success() {
grpc_core::ExecCtx exec_ctx;
expected_md emd[] = {
{"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
@@ -603,7 +603,7 @@ static void test_compute_engine_creds_success(void) {
run_request_metadata_test(creds, auth_md_ctx, state);
grpc_core::ExecCtx::Get()->Flush();
- grpc_call_credentials_unref(creds);
+ creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
}
@@ -620,7 +620,7 @@ static void test_compute_engine_creds_failure(void) {
grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
httpcli_post_should_not_be_called);
run_request_metadata_test(creds, auth_md_ctx, state);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
}
@@ -692,7 +692,7 @@ static void test_refresh_token_creds_success(void) {
run_request_metadata_test(creds, auth_md_ctx, state);
grpc_core::ExecCtx::Get()->Flush();
- grpc_call_credentials_unref(creds);
+ creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
}
@@ -709,7 +709,7 @@ static void test_refresh_token_creds_failure(void) {
grpc_httpcli_set_override(httpcli_get_should_not_be_called,
refresh_token_httpcli_post_failure);
run_request_metadata_test(creds, auth_md_ctx, state);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
}
@@ -762,7 +762,7 @@ static char* encode_and_sign_jwt_should_not_be_called(
static grpc_service_account_jwt_access_credentials* creds_as_jwt(
grpc_call_credentials* creds) {
GPR_ASSERT(creds != nullptr);
- GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0);
+ GPR_ASSERT(strcmp(creds->type(), GRPC_CALL_CREDENTIALS_TYPE_JWT) == 0);
return reinterpret_cast<grpc_service_account_jwt_access_credentials*>(creds);
}
@@ -773,7 +773,7 @@ static void test_jwt_creds_lifetime(void) {
grpc_call_credentials* jwt_creds =
grpc_service_account_jwt_access_credentials_create(
json_key_string, grpc_max_auth_token_lifetime(), nullptr);
- GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime,
+ GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(),
grpc_max_auth_token_lifetime()) == 0);
grpc_call_credentials_release(jwt_creds);
@@ -782,8 +782,8 @@ static void test_jwt_creds_lifetime(void) {
GPR_ASSERT(gpr_time_cmp(grpc_max_auth_token_lifetime(), token_lifetime) > 0);
jwt_creds = grpc_service_account_jwt_access_credentials_create(
json_key_string, token_lifetime, nullptr);
- GPR_ASSERT(
- gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime, token_lifetime) == 0);
+ GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(),
+ token_lifetime) == 0);
grpc_call_credentials_release(jwt_creds);
// Cropped lifetime.
@@ -791,7 +791,7 @@ static void test_jwt_creds_lifetime(void) {
token_lifetime = gpr_time_add(grpc_max_auth_token_lifetime(), add_to_max);
jwt_creds = grpc_service_account_jwt_access_credentials_create(
json_key_string, token_lifetime, nullptr);
- GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime,
+ GPR_ASSERT(gpr_time_cmp(creds_as_jwt(jwt_creds)->jwt_lifetime(),
grpc_max_auth_token_lifetime()) == 0);
grpc_call_credentials_release(jwt_creds);
@@ -834,7 +834,7 @@ static void test_jwt_creds_success(void) {
run_request_metadata_test(creds, auth_md_ctx, state);
grpc_core::ExecCtx::Get()->Flush();
- grpc_call_credentials_unref(creds);
+ creds->Unref();
gpr_free(json_key_string);
gpr_free(expected_md_value);
grpc_jwt_encode_and_sign_set_override(nullptr);
@@ -856,7 +856,7 @@ static void test_jwt_creds_signing_failure(void) {
run_request_metadata_test(creds, auth_md_ctx, state);
gpr_free(json_key_string);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
grpc_jwt_encode_and_sign_set_override(nullptr);
}
@@ -875,8 +875,6 @@ static void set_google_default_creds_env_var_with_file_contents(
static void test_google_default_creds_auth_key(void) {
grpc_core::ExecCtx exec_ctx;
- grpc_service_account_jwt_access_credentials* jwt;
- grpc_google_default_channel_credentials* default_creds;
grpc_composite_channel_credentials* creds;
char* json_key = test_json_key_str();
grpc_flush_cached_google_default_credentials();
@@ -885,40 +883,58 @@ static void test_google_default_creds_auth_key(void) {
gpr_free(json_key);
creds = reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
- default_creds = reinterpret_cast<grpc_google_default_channel_credentials*>(
- creds->inner_creds);
- GPR_ASSERT(default_creds->ssl_creds != nullptr);
- jwt = reinterpret_cast<grpc_service_account_jwt_access_credentials*>(
- creds->call_creds);
+ auto* default_creds =
+ reinterpret_cast<const grpc_google_default_channel_credentials*>(
+ creds->inner_creds());
+ GPR_ASSERT(default_creds->ssl_creds() != nullptr);
+ auto* jwt =
+ reinterpret_cast<const grpc_service_account_jwt_access_credentials*>(
+ creds->call_creds());
GPR_ASSERT(
- strcmp(jwt->key.client_id,
+ strcmp(jwt->key().client_id,
"777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
0);
- grpc_channel_credentials_unref(&creds->base);
+ creds->Unref();
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
}
static void test_google_default_creds_refresh_token(void) {
grpc_core::ExecCtx exec_ctx;
- grpc_google_refresh_token_credentials* refresh;
- grpc_google_default_channel_credentials* default_creds;
grpc_composite_channel_credentials* creds;
grpc_flush_cached_google_default_credentials();
set_google_default_creds_env_var_with_file_contents(
"refresh_token_google_default_creds", test_refresh_token_str);
creds = reinterpret_cast<grpc_composite_channel_credentials*>(
grpc_google_default_credentials_create());
- default_creds = reinterpret_cast<grpc_google_default_channel_credentials*>(
- creds->inner_creds);
- GPR_ASSERT(default_creds->ssl_creds != nullptr);
- refresh = reinterpret_cast<grpc_google_refresh_token_credentials*>(
- creds->call_creds);
- GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
+ auto* default_creds =
+ reinterpret_cast<const grpc_google_default_channel_credentials*>(
+ creds->inner_creds());
+ GPR_ASSERT(default_creds->ssl_creds() != nullptr);
+ auto* refresh =
+ reinterpret_cast<const grpc_google_refresh_token_credentials*>(
+ creds->call_creds());
+ GPR_ASSERT(strcmp(refresh->refresh_token().client_id,
"32555999999.apps.googleusercontent.com") == 0);
- grpc_channel_credentials_unref(&creds->base);
+ creds->Unref();
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
}
+static int default_creds_metadata_server_detection_httpcli_get_success_override(
+ const grpc_httpcli_request* request, grpc_millis deadline,
+ grpc_closure* on_done, grpc_httpcli_response* response) {
+ *response = http_response(200, "");
+ grpc_http_header* headers =
+ static_cast<grpc_http_header*>(gpr_malloc(sizeof(*headers) * 1));
+ headers[0].key = gpr_strdup("Metadata-Flavor");
+ headers[0].value = gpr_strdup("Google");
+ response->hdr_count = 1;
+ response->hdrs = headers;
+ GPR_ASSERT(strcmp(request->http.path, "/") == 0);
+ GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
+ GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
+ return 1;
+}
+
static char* null_well_known_creds_path_getter(void) { return nullptr; }
static bool test_gce_tenancy_checker(void) {
@@ -949,40 +965,87 @@ static void test_google_default_creds_gce(void) {
/* Verify that the default creds actually embeds a GCE creds. */
GPR_ASSERT(creds != nullptr);
- GPR_ASSERT(creds->call_creds != nullptr);
+ GPR_ASSERT(creds->call_creds() != nullptr);
grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
httpcli_post_should_not_be_called);
- run_request_metadata_test(creds->call_creds, auth_md_ctx, state);
+ run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state);
grpc_core::ExecCtx::Get()->Flush();
GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
/* Cleanup. */
- grpc_channel_credentials_unref(&creds->base);
+ creds->Unref();
grpc_httpcli_set_override(nullptr, nullptr);
grpc_override_well_known_credentials_path_getter(nullptr);
}
-static void test_no_google_default_creds(void) {
+static void test_google_default_creds_non_gce(void) {
+ grpc_core::ExecCtx exec_ctx;
+ expected_md emd[] = {
+ {"authorization", "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_"}};
+ request_metadata_state* state =
+ make_request_metadata_state(GRPC_ERROR_NONE, emd, GPR_ARRAY_SIZE(emd));
+ grpc_auth_metadata_context auth_md_ctx = {test_service_url, test_method,
+ nullptr, nullptr};
grpc_flush_cached_google_default_credentials();
gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
grpc_override_well_known_credentials_path_getter(
null_well_known_creds_path_getter);
-
set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
g_test_gce_tenancy_checker_called = false;
g_test_is_on_gce = false;
+ /* Simulate a successful detection of metadata server. */
+ grpc_httpcli_set_override(
+ default_creds_metadata_server_detection_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ grpc_composite_channel_credentials* creds =
+ reinterpret_cast<grpc_composite_channel_credentials*>(
+ grpc_google_default_credentials_create());
+ /* Verify that the default creds actually embeds a GCE creds. */
+ GPR_ASSERT(creds != nullptr);
+ GPR_ASSERT(creds->call_creds() != nullptr);
+ grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
+ httpcli_post_should_not_be_called);
+ run_request_metadata_test(creds->mutable_call_creds(), auth_md_ctx, state);
+ grpc_core::ExecCtx::Get()->Flush();
+ GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
+ /* Cleanup. */
+ creds->Unref();
+ grpc_httpcli_set_override(nullptr, nullptr);
+ grpc_override_well_known_credentials_path_getter(nullptr);
+}
+
+static int default_creds_gce_detection_httpcli_get_failure_override(
+ const grpc_httpcli_request* request, grpc_millis deadline,
+ grpc_closure* on_done, grpc_httpcli_response* response) {
+ /* No magic header. */
+ GPR_ASSERT(strcmp(request->http.path, "/") == 0);
+ GPR_ASSERT(strcmp(request->host, "metadata.google.internal") == 0);
+ *response = http_response(200, "");
+ GRPC_CLOSURE_SCHED(on_done, GRPC_ERROR_NONE);
+ return 1;
+}
+static void test_no_google_default_creds(void) {
+ grpc_flush_cached_google_default_credentials();
+ gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
+ grpc_override_well_known_credentials_path_getter(
+ null_well_known_creds_path_getter);
+ set_gce_tenancy_checker_for_testing(test_gce_tenancy_checker);
+ g_test_gce_tenancy_checker_called = false;
+ g_test_is_on_gce = false;
+ grpc_httpcli_set_override(
+ default_creds_gce_detection_httpcli_get_failure_override,
+ httpcli_post_should_not_be_called);
/* Simulate a successful detection of GCE. */
GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
-
- /* Try a second one. GCE detection should not occur anymore. */
+ /* Try a second one. GCE detection should occur again. */
g_test_gce_tenancy_checker_called = false;
GPR_ASSERT(grpc_google_default_credentials_create() == nullptr);
- GPR_ASSERT(g_test_gce_tenancy_checker_called == false);
-
+ GPR_ASSERT(g_test_gce_tenancy_checker_called == true);
/* Cleanup. */
grpc_override_well_known_credentials_path_getter(nullptr);
+ grpc_httpcli_set_override(nullptr, nullptr);
}
typedef enum {
@@ -1058,7 +1121,7 @@ static void test_metadata_plugin_success(void) {
GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
run_request_metadata_test(creds, auth_md_ctx, md_state);
GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
}
@@ -1086,7 +1149,7 @@ static void test_metadata_plugin_failure(void) {
GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
run_request_metadata_test(creds, auth_md_ctx, md_state);
GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
- grpc_call_credentials_unref(creds);
+ creds->Unref();
GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
}
@@ -1113,25 +1176,23 @@ static void test_channel_creds_duplicate_without_call_creds(void) {
grpc_channel_credentials* channel_creds =
grpc_fake_transport_security_credentials_create();
- grpc_channel_credentials* dup =
- grpc_channel_credentials_duplicate_without_call_credentials(
- channel_creds);
+ grpc_core::RefCountedPtr<grpc_channel_credentials> dup =
+ channel_creds->duplicate_without_call_credentials();
GPR_ASSERT(dup == channel_creds);
- grpc_channel_credentials_unref(dup);
+ dup.reset();
grpc_call_credentials* call_creds =
grpc_access_token_credentials_create("blah", nullptr);
grpc_channel_credentials* composite_creds =
grpc_composite_channel_credentials_create(channel_creds, call_creds,
nullptr);
- grpc_call_credentials_unref(call_creds);
- dup = grpc_channel_credentials_duplicate_without_call_credentials(
- composite_creds);
+ call_creds->Unref();
+ dup = composite_creds->duplicate_without_call_credentials();
GPR_ASSERT(dup == channel_creds);
- grpc_channel_credentials_unref(dup);
+ dup.reset();
- grpc_channel_credentials_unref(channel_creds);
- grpc_channel_credentials_unref(composite_creds);
+ channel_creds->Unref();
+ composite_creds->Unref();
}
typedef struct {
@@ -1206,7 +1267,7 @@ static void test_auth_metadata_context(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_empty_md_array();
test_add_to_empty_md_array();
@@ -1233,6 +1294,7 @@ int main(int argc, char** argv) {
test_google_default_creds_auth_key();
test_google_default_creds_refresh_token();
test_google_default_creds_gce();
+ test_google_default_creds_non_gce();
test_no_google_default_creds();
test_metadata_plugin_success();
test_metadata_plugin_failure();
diff --git a/test/core/security/json_token_test.cc b/test/core/security/json_token_test.cc
index 7a5b3355fe..a3ae18e6ab 100644
--- a/test/core/security/json_token_test.cc
+++ b/test/core/security/json_token_test.cc
@@ -482,7 +482,7 @@ static void test_parse_refresh_token_failure_no_refresh_token(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_parse_json_key_success();
test_parse_json_key_failure_bad_json();
diff --git a/test/core/security/jwt_verifier_test.cc b/test/core/security/jwt_verifier_test.cc
index 9718580a08..70155cdd06 100644
--- a/test/core/security/jwt_verifier_test.cc
+++ b/test/core/security/jwt_verifier_test.cc
@@ -600,7 +600,7 @@ static void test_jwt_verifier_bad_format(void) {
/* bad key */
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_jwt_issuer_email_domain();
test_claims_success();
diff --git a/test/core/security/linux_system_roots_test.cc b/test/core/security/linux_system_roots_test.cc
index 24d446de35..cd8bd3beb7 100644
--- a/test/core/security/linux_system_roots_test.cc
+++ b/test/core/security/linux_system_roots_test.cc
@@ -86,7 +86,7 @@ TEST(CreateRootCertsBundleTest, BundlesCorrectly) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/security/oauth2_utils.cc b/test/core/security/oauth2_utils.cc
index 469129a6d0..c9e205ab74 100644
--- a/test/core/security/oauth2_utils.cc
+++ b/test/core/security/oauth2_utils.cc
@@ -86,9 +86,8 @@ char* grpc_test_fetch_oauth2_token_with_credentials(
grpc_schedule_on_exec_ctx);
grpc_error* error = GRPC_ERROR_NONE;
- if (grpc_call_credentials_get_request_metadata(creds, &request.pops, null_ctx,
- &request.md_array,
- &request.closure, &error)) {
+ if (creds->get_request_metadata(&request.pops, null_ctx, &request.md_array,
+ &request.closure, &error)) {
// Synchronous result; invoke callback directly.
on_oauth2_response(&request, error);
GRPC_ERROR_UNREF(error);
diff --git a/test/core/security/print_google_default_creds_token.cc b/test/core/security/print_google_default_creds_token.cc
index 4d251391ff..398c58c6e1 100644
--- a/test/core/security/print_google_default_creds_token.cc
+++ b/test/core/security/print_google_default_creds_token.cc
@@ -96,11 +96,10 @@ int main(int argc, char** argv) {
grpc_schedule_on_exec_ctx);
error = GRPC_ERROR_NONE;
- if (grpc_call_credentials_get_request_metadata(
- (reinterpret_cast<grpc_composite_channel_credentials*>(creds))
- ->call_creds,
- &sync.pops, context, &sync.md_array, &sync.on_request_metadata,
- &error)) {
+ if (reinterpret_cast<grpc_composite_channel_credentials*>(creds)
+ ->mutable_call_creds()
+ ->get_request_metadata(&sync.pops, context, &sync.md_array,
+ &sync.on_request_metadata, &error)) {
// Synchronous response. Invoke callback directly.
on_metadata_response(&sync, error);
GRPC_ERROR_UNREF(error);
diff --git a/test/core/security/secure_endpoint_test.cc b/test/core/security/secure_endpoint_test.cc
index 23cef99dfa..f6d02895b5 100644
--- a/test/core/security/secure_endpoint_test.cc
+++ b/test/core/security/secure_endpoint_test.cc
@@ -208,7 +208,7 @@ static void destroy_pollset(void* p, grpc_error* error) {
int main(int argc, char** argv) {
grpc_closure destroyed;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
{
diff --git a/test/core/security/security_connector_test.cc b/test/core/security/security_connector_test.cc
index fef0ea71f7..2a31763c73 100644
--- a/test/core/security/security_connector_test.cc
+++ b/test/core/security/security_connector_test.cc
@@ -27,6 +27,7 @@
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/tmpfile.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.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"
@@ -83,22 +84,22 @@ static int check_ssl_peer_equivalence(const tsi_peer* original,
static void test_unauthenticated_ssl_peer(void) {
tsi_peer peer;
tsi_peer rpeer;
- grpc_auth_context* ctx;
GPR_ASSERT(tsi_construct_peer(1, &peer) == TSI_OK);
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
&peer.properties[0]) == TSI_OK);
- ctx = grpc_ssl_peer_to_auth_context(&peer);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
- GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx));
- GPR_ASSERT(check_transport_security_type(ctx));
+ GPR_ASSERT(!grpc_auth_context_peer_is_authenticated(ctx.get()));
+ GPR_ASSERT(check_transport_security_type(ctx.get()));
- rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get());
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
static int check_identity(const grpc_auth_context* ctx,
@@ -175,7 +176,6 @@ static int check_x509_pem_cert(const grpc_auth_context* ctx,
static void test_cn_only_ssl_peer_to_auth_context(void) {
tsi_peer peer;
tsi_peer rpeer;
- grpc_auth_context* ctx;
const char* expected_cn = "cn1";
const char* expected_pem_cert = "pem_cert1";
GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK);
@@ -188,26 +188,27 @@ static void test_cn_only_ssl_peer_to_auth_context(void) {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
&peer.properties[2]) == TSI_OK);
- ctx = grpc_ssl_peer_to_auth_context(&peer);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
- GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
- GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1));
- GPR_ASSERT(check_transport_security_type(ctx));
- GPR_ASSERT(check_x509_cn(ctx, expected_cn));
- GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
+ GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get()));
+ GPR_ASSERT(
+ check_identity(ctx.get(), GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1));
+ GPR_ASSERT(check_transport_security_type(ctx.get()));
+ GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn));
+ GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert));
- rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get());
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
static void test_cn_and_one_san_ssl_peer_to_auth_context(void) {
tsi_peer peer;
tsi_peer rpeer;
- grpc_auth_context* ctx;
const char* expected_cn = "cn1";
const char* expected_san = "san1";
const char* expected_pem_cert = "pem_cert1";
@@ -224,27 +225,28 @@ static void test_cn_and_one_san_ssl_peer_to_auth_context(void) {
GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
&peer.properties[3]) == TSI_OK);
- ctx = grpc_ssl_peer_to_auth_context(&peer);
+
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
- GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
+ GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get()));
GPR_ASSERT(
- check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1));
- GPR_ASSERT(check_transport_security_type(ctx));
- GPR_ASSERT(check_x509_cn(ctx, expected_cn));
- GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
+ check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1));
+ GPR_ASSERT(check_transport_security_type(ctx.get()));
+ GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn));
+ GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert));
- rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get());
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) {
tsi_peer peer;
tsi_peer rpeer;
- grpc_auth_context* ctx;
const char* expected_cn = "cn1";
const char* expected_sans[] = {"san1", "san2", "san3"};
const char* expected_pem_cert = "pem_cert1";
@@ -265,28 +267,28 @@ static void test_cn_and_multiple_sans_ssl_peer_to_auth_context(void) {
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
expected_sans[i], &peer.properties[3 + i]) == TSI_OK);
}
- ctx = grpc_ssl_peer_to_auth_context(&peer);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
- GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
- GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
- GPR_ARRAY_SIZE(expected_sans)));
- GPR_ASSERT(check_transport_security_type(ctx));
- GPR_ASSERT(check_x509_cn(ctx, expected_cn));
- GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
-
- rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get()));
+ GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME,
+ expected_sans, GPR_ARRAY_SIZE(expected_sans)));
+ GPR_ASSERT(check_transport_security_type(ctx.get()));
+ GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn));
+ GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert));
+
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get());
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
void) {
tsi_peer peer;
tsi_peer rpeer;
- grpc_auth_context* ctx;
const char* expected_cn = "cn1";
const char* expected_pem_cert = "pem_cert1";
const char* expected_sans[] = {"san1", "san2", "san3"};
@@ -311,21 +313,22 @@ static void test_cn_and_multiple_sans_and_others_ssl_peer_to_auth_context(
TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
expected_sans[i], &peer.properties[5 + i]) == TSI_OK);
}
- ctx = grpc_ssl_peer_to_auth_context(&peer);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_ssl_peer_to_auth_context(&peer);
GPR_ASSERT(ctx != nullptr);
- GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
- GPR_ASSERT(check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, expected_sans,
- GPR_ARRAY_SIZE(expected_sans)));
- GPR_ASSERT(check_transport_security_type(ctx));
- GPR_ASSERT(check_x509_cn(ctx, expected_cn));
- GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
-
- rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx);
+ GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx.get()));
+ GPR_ASSERT(check_identity(ctx.get(), GRPC_X509_SAN_PROPERTY_NAME,
+ expected_sans, GPR_ARRAY_SIZE(expected_sans)));
+ GPR_ASSERT(check_transport_security_type(ctx.get()));
+ GPR_ASSERT(check_x509_cn(ctx.get(), expected_cn));
+ GPR_ASSERT(check_x509_pem_cert(ctx.get(), expected_pem_cert));
+
+ rpeer = grpc_shallow_peer_from_ssl_auth_context(ctx.get());
GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
grpc_shallow_peer_destruct(&rpeer);
tsi_peer_destruct(&peer);
- GRPC_AUTH_CONTEXT_UNREF(ctx, "test");
+ ctx.reset(DEBUG_LOCATION, "test");
}
static const char* roots_for_override_api = "roots for override api";
@@ -430,7 +433,7 @@ static void test_default_ssl_roots(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_unauthenticated_ssl_peer();
diff --git a/test/core/security/ssl_credentials_test.cc b/test/core/security/ssl_credentials_test.cc
index 9edcf42d3a..7c9f561665 100644
--- a/test/core/security/ssl_credentials_test.cc
+++ b/test/core/security/ssl_credentials_test.cc
@@ -56,7 +56,7 @@ static void test_convert_grpc_to_tsi_cert_pairs() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_convert_grpc_to_tsi_cert_pairs();
diff --git a/test/core/security/ssl_server_fuzzer.cc b/test/core/security/ssl_server_fuzzer.cc
index d2bbb7c1c2..c9380126dd 100644
--- a/test/core/security/ssl_server_fuzzer.cc
+++ b/test/core/security/ssl_server_fuzzer.cc
@@ -82,16 +82,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
ca_cert, &pem_key_cert_pair, 1, 0, nullptr);
// Create security connector
- grpc_server_security_connector* sc = nullptr;
- grpc_security_status status =
- grpc_server_credentials_create_security_connector(creds, &sc);
- GPR_ASSERT(status == GRPC_SECURITY_OK);
+ grpc_core::RefCountedPtr<grpc_server_security_connector> sc =
+ creds->create_security_connector();
+ GPR_ASSERT(sc != nullptr);
grpc_millis deadline = GPR_MS_PER_SEC + grpc_core::ExecCtx::Get()->Now();
struct handshake_state state;
state.done_callback_called = false;
grpc_handshake_manager* handshake_mgr = grpc_handshake_manager_create();
- grpc_server_security_connector_add_handshakers(sc, nullptr, handshake_mgr);
+ sc->add_handshakers(nullptr, handshake_mgr);
grpc_handshake_manager_do_handshake(
handshake_mgr, mock_endpoint, nullptr /* channel_args */, deadline,
nullptr /* acceptor */, on_handshake_done, &state);
@@ -110,7 +109,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
GPR_ASSERT(state.done_callback_called);
grpc_handshake_manager_destroy(handshake_mgr);
- GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "test");
+ sc.reset(DEBUG_LOCATION, "test");
grpc_server_credentials_release(creds);
grpc_slice_unref(cert_slice);
grpc_slice_unref(key_slice);
diff --git a/test/core/slice/b64_test.cc b/test/core/slice/b64_test.cc
index 6b29443ba1..6677150c23 100644
--- a/test/core/slice/b64_test.cc
+++ b/test/core/slice/b64_test.cc
@@ -201,7 +201,7 @@ static void test_unpadded_decode(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_simple_encode_decode_b64_no_multiline();
test_simple_encode_decode_b64_multiline();
diff --git a/test/core/slice/percent_encoding_test.cc b/test/core/slice/percent_encoding_test.cc
index e8d04fcc83..ae6c39eb26 100644
--- a/test/core/slice/percent_encoding_test.cc
+++ b/test/core/slice/percent_encoding_test.cc
@@ -118,7 +118,7 @@ static void test_nonconformant_vector(const char* encoded,
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
TEST_VECTOR(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~",
diff --git a/test/core/slice/slice_buffer_test.cc b/test/core/slice/slice_buffer_test.cc
index e59986730b..b53e3312df 100644
--- a/test/core/slice/slice_buffer_test.cc
+++ b/test/core/slice/slice_buffer_test.cc
@@ -106,7 +106,7 @@ void test_slice_buffer_move_first() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_slice_buffer_add();
diff --git a/test/core/slice/slice_hash_table_test.cc b/test/core/slice/slice_hash_table_test.cc
index 43ddfe9bf2..08cfe91e5a 100644
--- a/test/core/slice/slice_hash_table_test.cc
+++ b/test/core/slice/slice_hash_table_test.cc
@@ -217,7 +217,7 @@ TEST(SliceHashTable, CmpEmptyKeysDifferentValue) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_core::ExecCtx::GlobalInit();
int result = RUN_ALL_TESTS();
grpc_core::ExecCtx::GlobalShutdown();
diff --git a/test/core/slice/slice_string_helpers_test.cc b/test/core/slice/slice_string_helpers_test.cc
index 860a1bfe03..1bbc0947bc 100644
--- a/test/core/slice/slice_string_helpers_test.cc
+++ b/test/core/slice/slice_string_helpers_test.cc
@@ -195,7 +195,7 @@ static void test_strsplit_nospace(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_dump_slice();
test_strsplit();
test_strsplit_nospace();
diff --git a/test/core/slice/slice_test.cc b/test/core/slice/slice_test.cc
index e683c41f31..1e53a1951c 100644
--- a/test/core/slice/slice_test.cc
+++ b/test/core/slice/slice_test.cc
@@ -294,7 +294,7 @@ static void test_static_slice_copy_interning(void) {
int main(int argc, char** argv) {
unsigned length;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_slice_malloc_returns_something_sensible();
test_slice_new_returns_something_sensible();
diff --git a/test/core/slice/slice_weak_hash_table_test.cc b/test/core/slice/slice_weak_hash_table_test.cc
index b0a243d572..ab0a648727 100644
--- a/test/core/slice/slice_weak_hash_table_test.cc
+++ b/test/core/slice/slice_weak_hash_table_test.cc
@@ -98,7 +98,7 @@ TEST(SliceWeakHashTable, ForceOverload) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_core::ExecCtx::GlobalInit();
int result = RUN_ALL_TESTS();
grpc_core::ExecCtx::GlobalShutdown();
diff --git a/test/core/surface/byte_buffer_reader_test.cc b/test/core/surface/byte_buffer_reader_test.cc
index cff05caec1..301a1e283b 100644
--- a/test/core/surface/byte_buffer_reader_test.cc
+++ b/test/core/surface/byte_buffer_reader_test.cc
@@ -267,7 +267,7 @@ static void test_byte_buffer_copy(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_read_one_slice();
test_read_one_slice_malloc();
test_read_none_compressed_slice();
diff --git a/test/core/surface/channel_create_test.cc b/test/core/surface/channel_create_test.cc
index 56f4f602e8..5f109c0f84 100644
--- a/test/core/surface/channel_create_test.cc
+++ b/test/core/surface/channel_create_test.cc
@@ -44,7 +44,7 @@ void test_unknown_scheme_target(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_unknown_scheme_target();
grpc_shutdown();
diff --git a/test/core/surface/completion_queue_test.cc b/test/core/surface/completion_queue_test.cc
index f7ce8a7042..a157d75eda 100644
--- a/test/core/surface/completion_queue_test.cc
+++ b/test/core/surface/completion_queue_test.cc
@@ -440,7 +440,7 @@ struct thread_state {
};
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_no_op();
test_pollset_conversion();
diff --git a/test/core/surface/completion_queue_threading_test.cc b/test/core/surface/completion_queue_threading_test.cc
index 0b82803af6..4215aad14a 100644
--- a/test/core/surface/completion_queue_threading_test.cc
+++ b/test/core/surface/completion_queue_threading_test.cc
@@ -288,7 +288,7 @@ static void test_threading(size_t producers, size_t consumers) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_too_many_plucks();
test_threading(1, 1);
diff --git a/test/core/surface/concurrent_connectivity_test.cc b/test/core/surface/concurrent_connectivity_test.cc
index fbc5ec4c54..f606e89ac8 100644
--- a/test/core/surface/concurrent_connectivity_test.cc
+++ b/test/core/surface/concurrent_connectivity_test.cc
@@ -300,7 +300,7 @@ int run_concurrent_watches_with_short_timeouts_test() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
run_concurrent_connectivity_test();
run_concurrent_watches_with_short_timeouts_test();
diff --git a/test/core/surface/init_test.cc b/test/core/surface/init_test.cc
index 5749bc8b36..1bcd13a0b8 100644
--- a/test/core/surface/init_test.cc
+++ b/test/core/surface/init_test.cc
@@ -60,7 +60,7 @@ static void test_repeatedly() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test(1);
test(2);
test(3);
diff --git a/test/core/surface/lame_client_test.cc b/test/core/surface/lame_client_test.cc
index fac5ca8f7f..09c3d43197 100644
--- a/test/core/surface/lame_client_test.cc
+++ b/test/core/surface/lame_client_test.cc
@@ -75,7 +75,7 @@ int main(int argc, char** argv) {
grpc_slice details;
char* peer;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/surface/num_external_connectivity_watchers_test.cc b/test/core/surface/num_external_connectivity_watchers_test.cc
index 7b7a0b6dfc..454cbd5747 100644
--- a/test/core/surface/num_external_connectivity_watchers_test.cc
+++ b/test/core/surface/num_external_connectivity_watchers_test.cc
@@ -191,7 +191,7 @@ static const test_fixture secure_test = {
};
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
run_timeouts_test(&insecure_test);
run_timeouts_test(&secure_test);
diff --git a/test/core/surface/secure_channel_create_test.cc b/test/core/surface/secure_channel_create_test.cc
index 06962179a2..e9bb815f6e 100644
--- a/test/core/surface/secure_channel_create_test.cc
+++ b/test/core/surface/secure_channel_create_test.cc
@@ -39,7 +39,7 @@ void test_unknown_scheme_target(void) {
GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client"));
grpc_core::ExecCtx exec_ctx;
GRPC_CHANNEL_INTERNAL_UNREF(chan, "test");
- grpc_channel_credentials_unref(creds);
+ creds->Unref();
}
void test_security_connector_already_in_arg(void) {
@@ -70,7 +70,7 @@ void test_null_creds(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_security_connector_already_in_arg();
test_null_creds();
diff --git a/test/core/surface/sequential_connectivity_test.cc b/test/core/surface/sequential_connectivity_test.cc
index 10562b3be9..3f9a7baf98 100644
--- a/test/core/surface/sequential_connectivity_test.cc
+++ b/test/core/surface/sequential_connectivity_test.cc
@@ -168,7 +168,7 @@ static const test_fixture secure_test = {
};
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
run_test(&insecure_test);
run_test(&secure_test);
diff --git a/test/core/surface/server_chttp2_test.cc b/test/core/surface/server_chttp2_test.cc
index fd8ab9cd3d..ffb7f14f98 100644
--- a/test/core/surface/server_chttp2_test.cc
+++ b/test/core/surface/server_chttp2_test.cc
@@ -67,7 +67,7 @@ void test_add_same_port_twice() {
#endif
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_unparsable_target();
#ifndef GRPC_UV
diff --git a/test/core/surface/server_test.cc b/test/core/surface/server_test.cc
index b4eabd8d4d..2fc166546b 100644
--- a/test/core/surface/server_test.cc
+++ b/test/core/surface/server_test.cc
@@ -148,7 +148,7 @@ static void test_bind_server_to_addrs(const char** addrs, size_t n) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_register_method_fail();
test_request_call_on_no_server_cq();
diff --git a/test/core/transport/bdp_estimator_test.cc b/test/core/transport/bdp_estimator_test.cc
index c7e6b2bd84..a795daaead 100644
--- a/test/core/transport/bdp_estimator_test.cc
+++ b/test/core/transport/bdp_estimator_test.cc
@@ -139,7 +139,7 @@ INSTANTIATE_TEST_CASE_P(TooManyNames, BdpEstimatorRandomTest,
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
gpr_now_impl = grpc_core::testing::fake_gpr_now;
grpc_init();
grpc_timer_manager_set_threading(false);
diff --git a/test/core/transport/byte_stream_test.cc b/test/core/transport/byte_stream_test.cc
index df09637249..6c543892d0 100644
--- a/test/core/transport/byte_stream_test.cc
+++ b/test/core/transport/byte_stream_test.cc
@@ -245,7 +245,7 @@ TEST(CachingByteStream, SharedCache) {
int main(int argc, char** argv) {
grpc_init();
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int retval = RUN_ALL_TESTS();
grpc_shutdown();
diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD
index 6eff716b01..33437373e4 100644
--- a/test/core/transport/chttp2/BUILD
+++ b/test/core/transport/chttp2/BUILD
@@ -67,6 +67,22 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "context_list_test",
+ srcs = ["context_list_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+
+grpc_cc_test(
name = "hpack_encoder_test",
srcs = ["hpack_encoder_test.cc"],
language = "C++",
diff --git a/test/core/transport/chttp2/alpn_test.cc b/test/core/transport/chttp2/alpn_test.cc
index a43377393e..6da5299363 100644
--- a/test/core/transport/chttp2/alpn_test.cc
+++ b/test/core/transport/chttp2/alpn_test.cc
@@ -49,7 +49,7 @@ static void test_alpn_grpc_before_h2(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_alpn_success();
test_alpn_failure();
test_alpn_grpc_before_h2();
diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc
new file mode 100644
index 0000000000..edbe658a89
--- /dev/null
+++ b/test/core/transport/chttp2/context_list_test.cc
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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 "src/core/lib/iomgr/port.h"
+
+#include <gtest/gtest.h>
+#include <new>
+#include <vector>
+
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
+#include "src/core/lib/transport/transport.h"
+#include "test/core/util/mock_endpoint.h"
+#include "test/core/util/test_config.h"
+
+#include <grpc/grpc.h>
+
+namespace grpc_core {
+namespace testing {
+namespace {
+
+const uint32_t kByteOffset = 123;
+
+void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) {
+ ASSERT_NE(arg, nullptr);
+ EXPECT_EQ(ts->byte_offset, kByteOffset);
+ gpr_atm* done = reinterpret_cast<gpr_atm*>(arg);
+ gpr_atm_rel_store(done, static_cast<gpr_atm>(1));
+}
+
+void discard_write(grpc_slice slice) {}
+
+/** Tests that all ContextList elements in the list are flushed out on
+ * execute.
+ * Also tests that arg and byte_counter are passed correctly.
+ */
+TEST(ContextList, ExecuteFlushesList) {
+ grpc_core::ContextList* list = nullptr;
+ grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier);
+ const int kNumElems = 5;
+ grpc_core::ExecCtx exec_ctx;
+ grpc_stream_refcount ref;
+ GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "dummy ref");
+ grpc_resource_quota* resource_quota =
+ grpc_resource_quota_create("context_list_test");
+ grpc_endpoint* mock_endpoint =
+ grpc_mock_endpoint_create(discard_write, resource_quota);
+ grpc_transport* t =
+ grpc_create_chttp2_transport(nullptr, mock_endpoint, true);
+ std::vector<grpc_chttp2_stream*> s;
+ s.reserve(kNumElems);
+ gpr_atm verifier_called[kNumElems];
+ for (auto i = 0; i < kNumElems; i++) {
+ s.push_back(static_cast<grpc_chttp2_stream*>(
+ gpr_malloc(grpc_transport_stream_size(t))));
+ grpc_transport_init_stream(reinterpret_cast<grpc_transport*>(t),
+ reinterpret_cast<grpc_stream*>(s[i]), &ref,
+ nullptr, nullptr);
+ s[i]->context = &verifier_called[i];
+ s[i]->byte_counter = kByteOffset;
+ gpr_atm_rel_store(&verifier_called[i], static_cast<gpr_atm>(0));
+ grpc_core::ContextList::Append(&list, s[i]);
+ }
+ grpc_core::Timestamps ts;
+ grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE);
+ for (auto i = 0; i < kNumElems; i++) {
+ EXPECT_EQ(gpr_atm_acq_load(&verifier_called[i]), static_cast<gpr_atm>(1));
+ grpc_transport_destroy_stream(reinterpret_cast<grpc_transport*>(t),
+ reinterpret_cast<grpc_stream*>(s[i]),
+ nullptr);
+ exec_ctx.Flush();
+ gpr_free(s[i]);
+ }
+ grpc_transport_destroy(t);
+ grpc_resource_quota_unref(resource_quota);
+ exec_ctx.Flush();
+}
+} // namespace
+} // namespace testing
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ grpc::testing::TestEnvironment env(argc, argv);
+ grpc_init();
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/core/transport/chttp2/hpack_encoder_test.cc b/test/core/transport/chttp2/hpack_encoder_test.cc
index ab819f9092..6cbc914c7f 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.cc
+++ b/test/core/transport/chttp2/hpack_encoder_test.cc
@@ -261,7 +261,7 @@ static void run_test(void (*test)(), const char* name) {
int main(int argc, char** argv) {
size_t i;
grpc_test_only_set_slice_hash_seed(0);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
TEST(test_basic_headers);
TEST(test_decode_table_overflow);
diff --git a/test/core/transport/chttp2/hpack_parser_test.cc b/test/core/transport/chttp2/hpack_parser_test.cc
index 43b6c79e8a..882ad726b5 100644
--- a/test/core/transport/chttp2/hpack_parser_test.cc
+++ b/test/core/transport/chttp2/hpack_parser_test.cc
@@ -208,7 +208,7 @@ static void test_vectors(grpc_slice_split_mode mode) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_vectors(GRPC_SLICE_SPLIT_MERGE_ALL);
test_vectors(GRPC_SLICE_SPLIT_ONE_BYTE);
diff --git a/test/core/transport/chttp2/hpack_table_test.cc b/test/core/transport/chttp2/hpack_table_test.cc
index 3ab463b631..c31975786f 100644
--- a/test/core/transport/chttp2/hpack_table_test.cc
+++ b/test/core/transport/chttp2/hpack_table_test.cc
@@ -268,7 +268,7 @@ static void test_find(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_static_lookup();
test_many_additions();
diff --git a/test/core/transport/chttp2/settings_timeout_test.cc b/test/core/transport/chttp2/settings_timeout_test.cc
index 2d6f0a9a62..a9789edbf2 100644
--- a/test/core/transport/chttp2/settings_timeout_test.cc
+++ b/test/core/transport/chttp2/settings_timeout_test.cc
@@ -248,7 +248,7 @@ TEST(SettingsTimeout, Basic) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
int result = RUN_ALL_TESTS();
grpc_shutdown();
diff --git a/test/core/transport/chttp2/stream_map_test.cc b/test/core/transport/chttp2/stream_map_test.cc
index 773eb3a35f..a36c496eb1 100644
--- a/test/core/transport/chttp2/stream_map_test.cc
+++ b/test/core/transport/chttp2/stream_map_test.cc
@@ -193,7 +193,7 @@ int main(int argc, char** argv) {
uint32_t prev = 1;
uint32_t tmp;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_no_op();
test_empty_find();
diff --git a/test/core/transport/chttp2/varint_test.cc b/test/core/transport/chttp2/varint_test.cc
index 36760d0c72..5e00cc376a 100644
--- a/test/core/transport/chttp2/varint_test.cc
+++ b/test/core/transport/chttp2/varint_test.cc
@@ -44,7 +44,7 @@ static void test_varint(uint32_t value, uint32_t prefix_bits, uint8_t prefix_or,
test_varint(value, prefix_bits, prefix_or, expect, sizeof(expect) - 1)
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
TEST_VARINT(0, 1, 0, "\x00");
TEST_VARINT(128, 1, 0, "\x7f\x01");
diff --git a/test/core/transport/connectivity_state_test.cc b/test/core/transport/connectivity_state_test.cc
index cbd6318f52..7c7e3084bf 100644
--- a/test/core/transport/connectivity_state_test.cc
+++ b/test/core/transport/connectivity_state_test.cc
@@ -134,7 +134,7 @@ static void test_subscribe_with_failure_then_destroy(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
grpc_core::testing::grpc_tracer_enable_flag(&grpc_connectivity_state_trace);
test_connectivity_state_name();
diff --git a/test/core/transport/metadata_test.cc b/test/core/transport/metadata_test.cc
index 8ab9639dfa..9a49d28ccc 100644
--- a/test/core/transport/metadata_test.cc
+++ b/test/core/transport/metadata_test.cc
@@ -370,7 +370,7 @@ static void test_copied_static_metadata(bool dup_key, bool dup_value) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_no_op();
for (int k = 0; k <= 1; k++) {
diff --git a/test/core/transport/pid_controller_test.cc b/test/core/transport/pid_controller_test.cc
index 8d2cec4042..f6235244f6 100644
--- a/test/core/transport/pid_controller_test.cc
+++ b/test/core/transport/pid_controller_test.cc
@@ -85,7 +85,7 @@ INSTANTIATE_TEST_CASE_P(
} // namespace grpc_core
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/core/transport/status_conversion_test.cc b/test/core/transport/status_conversion_test.cc
index f7b3c62a40..949be42aeb 100644
--- a/test/core/transport/status_conversion_test.cc
+++ b/test/core/transport/status_conversion_test.cc
@@ -163,7 +163,7 @@ static void test_http2_status_to_grpc_status() {
int main(int argc, char** argv) {
int i;
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
test_grpc_status_to_http2_error();
diff --git a/test/core/transport/stream_owned_slice_test.cc b/test/core/transport/stream_owned_slice_test.cc
index 7831f67a04..48a77db9a5 100644
--- a/test/core/transport/stream_owned_slice_test.cc
+++ b/test/core/transport/stream_owned_slice_test.cc
@@ -26,7 +26,7 @@
static void do_nothing(void* arg, grpc_error* error) {}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
uint8_t buffer[] = "abc123";
diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc
index b7044b5b41..22e68fe554 100644
--- a/test/core/transport/timeout_encoding_test.cc
+++ b/test/core/transport/timeout_encoding_test.cc
@@ -156,7 +156,7 @@ void test_decoding_fails(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_encoding();
test_decoding();
test_decoding_fails();
diff --git a/test/core/tsi/fake_transport_security_test.cc b/test/core/tsi/fake_transport_security_test.cc
index 587d8f5dda..32361f19d3 100644
--- a/test/core/tsi/fake_transport_security_test.cc
+++ b/test/core/tsi/fake_transport_security_test.cc
@@ -139,7 +139,7 @@ void fake_tsi_test_do_round_trip_odd_buffer_size() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
fake_tsi_test_do_handshake_tiny_handshake_buffer();
fake_tsi_test_do_handshake_small_handshake_buffer();
diff --git a/test/core/tsi/ssl_session_cache_test.cc b/test/core/tsi/ssl_session_cache_test.cc
index c86cefb3ff..b9c98c0b57 100644
--- a/test/core/tsi/ssl_session_cache_test.cc
+++ b/test/core/tsi/ssl_session_cache_test.cc
@@ -145,7 +145,7 @@ TEST(SslSessionCacheTest, LruCache) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
int ret = RUN_ALL_TESTS();
grpc_shutdown();
diff --git a/test/core/tsi/ssl_transport_security_test.cc b/test/core/tsi/ssl_transport_security_test.cc
index baffad6ea3..fc6c6ba320 100644
--- a/test/core/tsi/ssl_transport_security_test.cc
+++ b/test/core/tsi/ssl_transport_security_test.cc
@@ -777,7 +777,7 @@ void ssl_tsi_test_handshaker_factory_internals() {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc_init();
ssl_tsi_test_do_handshake_tiny_handshake_buffer();
diff --git a/test/core/tsi/transport_security_test.cc b/test/core/tsi/transport_security_test.cc
index 5c92912f6f..150e5745a8 100644
--- a/test/core/tsi/transport_security_test.cc
+++ b/test/core/tsi/transport_security_test.cc
@@ -381,7 +381,7 @@ static void test_handshaker_invalid_state(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_peer_matches_name();
test_result_strings();
test_protector_invalid_args();
diff --git a/test/core/util/cmdline_test.cc b/test/core/util/cmdline_test.cc
index 9f5ad88d57..59e1bbff34 100644
--- a/test/core/util/cmdline_test.cc
+++ b/test/core/util/cmdline_test.cc
@@ -463,7 +463,7 @@ static void test_badargs4(void) {
}
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
test_simple_int();
test_eq_int();
test_2dash_int();
diff --git a/test/core/util/fuzzer_corpus_test.cc b/test/core/util/fuzzer_corpus_test.cc
index ebf1913137..6e3785c4f7 100644
--- a/test/core/util/fuzzer_corpus_test.cc
+++ b/test/core/util/fuzzer_corpus_test.cc
@@ -144,7 +144,7 @@ INSTANTIATE_TEST_CASE_P(
::testing::internal::ParamGenerator<std::string>(new ExampleGenerator));
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
ParseCommandLineFlags(&argc, &argv, true);
::testing::InitGoogleTest(&argc, argv);
diff --git a/test/core/util/memory_counters.cc b/test/core/util/memory_counters.cc
index 4960fe0757..d0da05d9b4 100644
--- a/test/core/util/memory_counters.cc
+++ b/test/core/util/memory_counters.cc
@@ -22,6 +22,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/gpr/alloc.h"
#include "test/core/util/memory_counters.h"
static struct grpc_memory_counters g_memory_counters;
@@ -42,19 +43,18 @@ static void guard_free(void* vptr);
#endif
static void* guard_malloc(size_t size) {
- size_t* ptr;
if (!size) return nullptr;
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size);
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size);
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1);
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1);
- ptr = static_cast<size_t*>(g_old_allocs.malloc_fn(size + sizeof(size)));
- *ptr++ = size;
- return ptr;
+ void* ptr = g_old_allocs.malloc_fn(
+ GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size);
+ *static_cast<size_t*>(ptr) = size;
+ return static_cast<char*>(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size));
}
static void* guard_realloc(void* vptr, size_t size) {
- size_t* ptr = static_cast<size_t*>(vptr);
if (vptr == nullptr) {
return guard_malloc(size);
}
@@ -62,21 +62,25 @@ static void* guard_realloc(void* vptr, size_t size) {
guard_free(vptr);
return nullptr;
}
- --ptr;
+ void* ptr =
+ static_cast<char*>(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size));
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size);
- NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr);
+ NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative,
+ -*static_cast<gpr_atm*>(ptr));
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size);
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1);
- ptr = static_cast<size_t*>(g_old_allocs.realloc_fn(ptr, size + sizeof(size)));
- *ptr++ = size;
- return ptr;
+ ptr = g_old_allocs.realloc_fn(
+ ptr, GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size)) + size);
+ *static_cast<size_t*>(ptr) = size;
+ return static_cast<char*>(ptr) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size));
}
static void guard_free(void* vptr) {
- size_t* ptr = static_cast<size_t*>(vptr);
- if (!vptr) return;
- --ptr;
- NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr);
+ if (vptr == nullptr) return;
+ void* ptr =
+ static_cast<char*>(vptr) - GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(size_t));
+ NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative,
+ -*static_cast<gpr_atm*>(ptr));
NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1);
g_old_allocs.free_fn(ptr);
}
diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc
index ef6fd62b51..e5867cd526 100644
--- a/test/core/util/mock_endpoint.cc
+++ b/test/core/util/mock_endpoint.cc
@@ -103,18 +103,19 @@ static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
static int me_get_fd(grpc_endpoint* ep) { return -1; }
-static const grpc_endpoint_vtable vtable = {
- me_read,
- me_write,
- me_add_to_pollset,
- me_add_to_pollset_set,
- me_delete_from_pollset_set,
- me_shutdown,
- me_destroy,
- me_get_resource_user,
- me_get_peer,
- me_get_fd,
-};
+static bool me_can_track_err(grpc_endpoint* ep) { return false; }
+
+static const grpc_endpoint_vtable vtable = {me_read,
+ me_write,
+ me_add_to_pollset,
+ me_add_to_pollset_set,
+ me_delete_from_pollset_set,
+ me_shutdown,
+ me_destroy,
+ me_get_resource_user,
+ me_get_peer,
+ me_get_fd,
+ me_can_track_err};
grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
grpc_resource_quota* resource_quota) {
diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc
index 3cc8ad6fe1..51b6de4695 100644
--- a/test/core/util/passthru_endpoint.cc
+++ b/test/core/util/passthru_endpoint.cc
@@ -155,6 +155,8 @@ static char* me_get_peer(grpc_endpoint* ep) {
static int me_get_fd(grpc_endpoint* ep) { return -1; }
+static bool me_can_track_err(grpc_endpoint* ep) { return false; }
+
static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
half* m = reinterpret_cast<half*>(ep);
return m->resource_user;
@@ -171,6 +173,7 @@ static const grpc_endpoint_vtable vtable = {
me_get_resource_user,
me_get_peer,
me_get_fd,
+ me_can_track_err,
};
static void half_init(half* m, passthru_endpoint* parent,
diff --git a/test/core/util/test_config.cc b/test/core/util/test_config.cc
index 6a0d444a73..fe80bb2d4d 100644
--- a/test/core/util/test_config.cc
+++ b/test/core/util/test_config.cc
@@ -397,3 +397,15 @@ void grpc_test_init(int argc, char** argv) {
concurrently running test binary */
srand(seed());
}
+
+namespace grpc {
+namespace testing {
+
+TestEnvironment::TestEnvironment(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+}
+
+TestEnvironment::~TestEnvironment() {}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h
index 5b3d34799e..112af3176f 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -37,6 +37,21 @@ gpr_timespec grpc_timeout_milliseconds_to_deadline(int64_t time_ms);
#define GRPC_TEST_PICK_PORT
#endif
+// Prefer TestEnvironment below.
void grpc_test_init(int argc, char** argv);
+namespace grpc {
+namespace testing {
+
+// A TestEnvironment object should be alive in the main function of a test. It
+// provides test init and shutdown inside.
+class TestEnvironment {
+ public:
+ TestEnvironment(int argc, char** argv);
+ ~TestEnvironment();
+};
+
+} // namespace testing
+} // namespace grpc
+
#endif /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */
diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc
index 62ed72a629..b0da735e57 100644
--- a/test/core/util/trickle_endpoint.cc
+++ b/test/core/util/trickle_endpoint.cc
@@ -131,6 +131,8 @@ static int te_get_fd(grpc_endpoint* ep) {
return grpc_endpoint_get_fd(te->wrapped);
}
+static bool te_can_track_err(grpc_endpoint* ep) { return false; }
+
static void te_finish_write(void* arg, grpc_error* error) {
trickle_endpoint* te = static_cast<trickle_endpoint*>(arg);
gpr_mu_lock(&te->mu);
@@ -148,7 +150,8 @@ static const grpc_endpoint_vtable vtable = {te_read,
te_destroy,
te_get_resource_user,
te_get_peer,
- te_get_fd};
+ te_get_fd,
+ te_can_track_err};
grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap,
double bytes_per_second) {
diff --git a/test/core/util/ubsan_suppressions.txt b/test/core/util/ubsan_suppressions.txt
index 63898ea3b1..8ed7d4d7fb 100644
--- a/test/core/util/ubsan_suppressions.txt
+++ b/test/core/util/ubsan_suppressions.txt
@@ -25,7 +25,6 @@ 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
+enum:grpc_chttp2_cancel_stream
diff --git a/test/cpp/client/client_channel_stress_test.cc b/test/cpp/client/client_channel_stress_test.cc
index 976eeb6aea..124557eb56 100644
--- a/test/cpp/client/client_channel_stress_test.cc
+++ b/test/cpp/client/client_channel_stress_test.cc
@@ -34,7 +34,9 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/thd.h"
#include "src/core/lib/iomgr/sockaddr.h"
@@ -216,23 +218,31 @@ class ClientChannelStressTest {
void SetNextResolution(const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(address_data.size(), nullptr);
- for (size_t i = 0; i < address_data.size(); ++i) {
+ grpc_core::ServerAddressList addresses;
+ for (const auto& addr : address_data) {
char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port);
+ gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port);
grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(
- addresses, i, lb_uri, address_data[i].is_balancer,
- address_data[i].balancer_name.c_str(), nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ std::vector<grpc_arg> args_to_add;
+ if (addr.is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME),
+ const_cast<char*>(addr.balancer_name.c_str())));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
+ addresses.emplace_back(address.addr, address.len, args);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
- grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetResponse(&fake_result);
- grpc_lb_addresses_destroy(addresses);
}
void KeepSendingRequests() {
@@ -321,7 +331,7 @@ class ClientChannelStressTest {
int main(int argc, char** argv) {
grpc_init();
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
grpc::testing::ClientChannelStressTest test;
test.Run();
grpc_shutdown();
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index fdc67969d9..1871e1375e 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -30,6 +30,7 @@
#include <grpcpp/impl/codegen/async_generic_service.h>
#include <grpcpp/impl/codegen/async_stream.h>
#include <grpcpp/impl/codegen/async_unary_call.h>
+#include <grpcpp/impl/codegen/client_callback.h>
#include <grpcpp/impl/codegen/method_handler_impl.h>
#include <grpcpp/impl/codegen/proto_utils.h>
#include <grpcpp/impl/codegen/rpc_method.h>
@@ -117,10 +118,13 @@ class ServiceA final {
//
// Method A2 leading comment 1
// Method A2 leading comment 2
+ virtual void MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor< ::grpc::testing::Request>* reactor) = 0;
// MethodA2 trailing comment 1
// Method A3 leading comment 1
+ virtual void MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor< ::grpc::testing::Response>* reactor) = 0;
// Method A3 trailing comment 1
// Method A4 leading comment 1
+ virtual void MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::grpc::testing::Request,::grpc::testing::Response>* reactor) = 0;
// Method A4 trailing comment 1
};
virtual class experimental_async_interface* experimental_async() { return nullptr; }
@@ -178,6 +182,9 @@ class ServiceA final {
public StubInterface::experimental_async_interface {
public:
void MethodA1(::grpc::ClientContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response, std::function<void(::grpc::Status)>) override;
+ void MethodA2(::grpc::ClientContext* context, ::grpc::testing::Response* response, ::grpc::experimental::ClientWriteReactor< ::grpc::testing::Request>* reactor) override;
+ void MethodA3(::grpc::ClientContext* context, ::grpc::testing::Request* request, ::grpc::experimental::ClientReadReactor< ::grpc::testing::Response>* reactor) override;
+ void MethodA4(::grpc::ClientContext* context, ::grpc::experimental::ClientBidiReactor< ::grpc::testing::Request,::grpc::testing::Response>* reactor) override;
private:
friend class Stub;
explicit experimental_async(Stub* stub): stub_(stub) { }
@@ -315,13 +322,13 @@ class ServiceA final {
public:
ExperimentalWithCallbackMethod_MethodA1() {
::grpc::Service::experimental().MarkMethodCallback(0,
- new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodA1<BaseClass>, ::grpc::testing::Request, ::grpc::testing::Response>(
+ new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(
[this](::grpc::ServerContext* context,
const ::grpc::testing::Request* request,
::grpc::testing::Response* response,
::grpc::experimental::ServerCallbackRpcController* controller) {
- this->MethodA1(context, request, response, controller);
- }, this));
+ return this->MethodA1(context, request, response, controller);
+ }));
}
~ExperimentalWithCallbackMethod_MethodA1() override {
BaseClassMustBeDerivedFromService(this);
@@ -339,6 +346,9 @@ class ServiceA final {
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
ExperimentalWithCallbackMethod_MethodA2() {
+ ::grpc::Service::experimental().MarkMethodCallback(1,
+ new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(
+ [this] { return this->MethodA2(); }));
}
~ExperimentalWithCallbackMethod_MethodA2() override {
BaseClassMustBeDerivedFromService(this);
@@ -348,6 +358,9 @@ class ServiceA final {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
+ virtual ::grpc::experimental::ServerReadReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA2() {
+ return new ::grpc::internal::UnimplementedReadReactor<
+ ::grpc::testing::Request, ::grpc::testing::Response>;}
};
template <class BaseClass>
class ExperimentalWithCallbackMethod_MethodA3 : public BaseClass {
@@ -355,6 +368,9 @@ class ServiceA final {
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
ExperimentalWithCallbackMethod_MethodA3() {
+ ::grpc::Service::experimental().MarkMethodCallback(2,
+ new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::testing::Request, ::grpc::testing::Response>(
+ [this] { return this->MethodA3(); }));
}
~ExperimentalWithCallbackMethod_MethodA3() override {
BaseClassMustBeDerivedFromService(this);
@@ -364,6 +380,9 @@ class ServiceA final {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
+ virtual ::grpc::experimental::ServerWriteReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA3() {
+ return new ::grpc::internal::UnimplementedWriteReactor<
+ ::grpc::testing::Request, ::grpc::testing::Response>;}
};
template <class BaseClass>
class ExperimentalWithCallbackMethod_MethodA4 : public BaseClass {
@@ -371,6 +390,9 @@ class ServiceA final {
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
ExperimentalWithCallbackMethod_MethodA4() {
+ ::grpc::Service::experimental().MarkMethodCallback(3,
+ new ::grpc::internal::CallbackBidiHandler< ::grpc::testing::Request, ::grpc::testing::Response>(
+ [this] { return this->MethodA4(); }));
}
~ExperimentalWithCallbackMethod_MethodA4() override {
BaseClassMustBeDerivedFromService(this);
@@ -380,6 +402,9 @@ class ServiceA final {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
+ virtual ::grpc::experimental::ServerBidiReactor< ::grpc::testing::Request, ::grpc::testing::Response>* MethodA4() {
+ return new ::grpc::internal::UnimplementedBidiReactor<
+ ::grpc::testing::Request, ::grpc::testing::Response>;}
};
typedef ExperimentalWithCallbackMethod_MethodA1<ExperimentalWithCallbackMethod_MethodA2<ExperimentalWithCallbackMethod_MethodA3<ExperimentalWithCallbackMethod_MethodA4<Service > > > > ExperimentalCallbackService;
template <class BaseClass>
@@ -537,13 +562,13 @@ class ServiceA final {
public:
ExperimentalWithRawCallbackMethod_MethodA1() {
::grpc::Service::experimental().MarkMethodRawCallback(0,
- new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodA1<BaseClass>, ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
[this](::grpc::ServerContext* context,
const ::grpc::ByteBuffer* request,
::grpc::ByteBuffer* response,
::grpc::experimental::ServerCallbackRpcController* controller) {
this->MethodA1(context, request, response, controller);
- }, this));
+ }));
}
~ExperimentalWithRawCallbackMethod_MethodA1() override {
BaseClassMustBeDerivedFromService(this);
@@ -561,6 +586,9 @@ class ServiceA final {
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
ExperimentalWithRawCallbackMethod_MethodA2() {
+ ::grpc::Service::experimental().MarkMethodRawCallback(1,
+ new ::grpc::internal::CallbackClientStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ [this] { return this->MethodA2(); }));
}
~ExperimentalWithRawCallbackMethod_MethodA2() override {
BaseClassMustBeDerivedFromService(this);
@@ -570,6 +598,9 @@ class ServiceA final {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
+ virtual ::grpc::experimental::ServerReadReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA2() {
+ return new ::grpc::internal::UnimplementedReadReactor<
+ ::grpc::ByteBuffer, ::grpc::ByteBuffer>;}
};
template <class BaseClass>
class ExperimentalWithRawCallbackMethod_MethodA3 : public BaseClass {
@@ -577,6 +608,9 @@ class ServiceA final {
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
ExperimentalWithRawCallbackMethod_MethodA3() {
+ ::grpc::Service::experimental().MarkMethodRawCallback(2,
+ new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ [this] { return this->MethodA3(); }));
}
~ExperimentalWithRawCallbackMethod_MethodA3() override {
BaseClassMustBeDerivedFromService(this);
@@ -586,6 +620,9 @@ class ServiceA final {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
+ virtual ::grpc::experimental::ServerWriteReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA3() {
+ return new ::grpc::internal::UnimplementedWriteReactor<
+ ::grpc::ByteBuffer, ::grpc::ByteBuffer>;}
};
template <class BaseClass>
class ExperimentalWithRawCallbackMethod_MethodA4 : public BaseClass {
@@ -593,6 +630,9 @@ class ServiceA final {
void BaseClassMustBeDerivedFromService(const Service *service) {}
public:
ExperimentalWithRawCallbackMethod_MethodA4() {
+ ::grpc::Service::experimental().MarkMethodRawCallback(3,
+ new ::grpc::internal::CallbackBidiHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ [this] { return this->MethodA4(); }));
}
~ExperimentalWithRawCallbackMethod_MethodA4() override {
BaseClassMustBeDerivedFromService(this);
@@ -602,6 +642,9 @@ class ServiceA final {
abort();
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
}
+ virtual ::grpc::experimental::ServerBidiReactor< ::grpc::ByteBuffer, ::grpc::ByteBuffer>* MethodA4() {
+ return new ::grpc::internal::UnimplementedBidiReactor<
+ ::grpc::ByteBuffer, ::grpc::ByteBuffer>;}
};
template <class BaseClass>
class WithStreamedUnaryMethod_MethodA1 : public BaseClass {
@@ -745,13 +788,13 @@ class ServiceB final {
public:
ExperimentalWithCallbackMethod_MethodB1() {
::grpc::Service::experimental().MarkMethodCallback(0,
- new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithCallbackMethod_MethodB1<BaseClass>, ::grpc::testing::Request, ::grpc::testing::Response>(
+ new ::grpc::internal::CallbackUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(
[this](::grpc::ServerContext* context,
const ::grpc::testing::Request* request,
::grpc::testing::Response* response,
::grpc::experimental::ServerCallbackRpcController* controller) {
- this->MethodB1(context, request, response, controller);
- }, this));
+ return this->MethodB1(context, request, response, controller);
+ }));
}
~ExperimentalWithCallbackMethod_MethodB1() override {
BaseClassMustBeDerivedFromService(this);
@@ -808,13 +851,13 @@ class ServiceB final {
public:
ExperimentalWithRawCallbackMethod_MethodB1() {
::grpc::Service::experimental().MarkMethodRawCallback(0,
- new ::grpc::internal::CallbackUnaryHandler< ExperimentalWithRawCallbackMethod_MethodB1<BaseClass>, ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+ new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
[this](::grpc::ServerContext* context,
const ::grpc::ByteBuffer* request,
::grpc::ByteBuffer* response,
::grpc::experimental::ServerCallbackRpcController* controller) {
this->MethodB1(context, request, response, controller);
- }, this));
+ }));
}
~ExperimentalWithRawCallbackMethod_MethodB1() override {
BaseClassMustBeDerivedFromService(this);
diff --git a/test/cpp/common/alarm_test.cc b/test/cpp/common/alarm_test.cc
index e909d03658..802cdc209a 100644
--- a/test/cpp/common/alarm_test.cc
+++ b/test/cpp/common/alarm_test.cc
@@ -313,7 +313,7 @@ TEST(AlarmTest, UnsetDestruction) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc
index 9634555e4b..5a2844d518 100644
--- a/test/cpp/common/auth_property_iterator_test.cc
+++ b/test/cpp/common/auth_property_iterator_test.cc
@@ -40,15 +40,14 @@ class TestAuthPropertyIterator : public AuthPropertyIterator {
class AuthPropertyIteratorTest : public ::testing::Test {
protected:
void SetUp() override {
- ctx_ = grpc_auth_context_create(nullptr);
- grpc_auth_context_add_cstring_property(ctx_, "name", "chapi");
- grpc_auth_context_add_cstring_property(ctx_, "name", "chapo");
- grpc_auth_context_add_cstring_property(ctx_, "foo", "bar");
- EXPECT_EQ(1,
- grpc_auth_context_set_peer_identity_property_name(ctx_, "name"));
+ ctx_ = grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
+ grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapi");
+ grpc_auth_context_add_cstring_property(ctx_.get(), "name", "chapo");
+ grpc_auth_context_add_cstring_property(ctx_.get(), "foo", "bar");
+ EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx_.get(),
+ "name"));
}
- void TearDown() override { grpc_auth_context_release(ctx_); }
- grpc_auth_context* ctx_;
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx_;
};
TEST_F(AuthPropertyIteratorTest, DefaultCtor) {
@@ -59,7 +58,7 @@ TEST_F(AuthPropertyIteratorTest, DefaultCtor) {
TEST_F(AuthPropertyIteratorTest, GeneralTest) {
grpc_auth_property_iterator c_iter =
- grpc_auth_context_property_iterator(ctx_);
+ grpc_auth_context_property_iterator(ctx_.get());
const grpc_auth_property* property =
grpc_auth_property_iterator_next(&c_iter);
TestAuthPropertyIterator iter(property, &c_iter);
diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc
index 6461f49743..03b3a9fdd8 100644
--- a/test/cpp/common/secure_auth_context_test.cc
+++ b/test/cpp/common/secure_auth_context_test.cc
@@ -33,7 +33,7 @@ class SecureAuthContextTest : public ::testing::Test {};
// Created with nullptr
TEST_F(SecureAuthContextTest, EmptyContext) {
- SecureAuthContext context(nullptr, true);
+ SecureAuthContext context(nullptr);
EXPECT_TRUE(context.GetPeerIdentity().empty());
EXPECT_TRUE(context.GetPeerIdentityPropertyName().empty());
EXPECT_TRUE(context.FindPropertyValues("").empty());
@@ -42,8 +42,10 @@ TEST_F(SecureAuthContextTest, EmptyContext) {
}
TEST_F(SecureAuthContextTest, Properties) {
- grpc_auth_context* ctx = grpc_auth_context_create(nullptr);
- SecureAuthContext context(ctx, true);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
+ SecureAuthContext context(ctx.get());
+ ctx.reset();
context.AddProperty("name", "chapi");
context.AddProperty("name", "chapo");
context.AddProperty("foo", "bar");
@@ -60,8 +62,10 @@ TEST_F(SecureAuthContextTest, Properties) {
}
TEST_F(SecureAuthContextTest, Iterators) {
- grpc_auth_context* ctx = grpc_auth_context_create(nullptr);
- SecureAuthContext context(ctx, true);
+ grpc_core::RefCountedPtr<grpc_auth_context> ctx =
+ grpc_core::MakeRefCounted<grpc_auth_context>(nullptr);
+ SecureAuthContext context(ctx.get());
+ ctx.reset();
context.AddProperty("name", "chapi");
context.AddProperty("name", "chapo");
context.AddProperty("foo", "bar");
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index 4e3d841db0..eb600ffb17 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -36,6 +36,18 @@ grpc_cc_library(
)
grpc_cc_library(
+ name = "test_health_check_service_impl",
+ testonly = True,
+ srcs = ["test_health_check_service_impl.cc"],
+ hdrs = ["test_health_check_service_impl.h"],
+ deps = [
+ "//:grpc",
+ "//:grpc++",
+ "//src/proto/grpc/health/v1:health_proto",
+ ],
+)
+
+grpc_cc_library(
name = "interceptors_util",
testonly = True,
srcs = ["interceptors_util.cc"],
@@ -124,6 +136,7 @@ grpc_cc_test(
"//:grpc",
"//:grpc++",
"//src/proto/grpc/testing:echo_messages_proto",
+ "//src/proto/grpc/testing:simple_messages_proto",
"//src/proto/grpc/testing:echo_proto",
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
@@ -282,6 +295,7 @@ grpc_cc_test(
"gtest",
],
deps = [
+ ":test_health_check_service_impl",
":test_service_impl",
"//:gpr",
"//:grpc",
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 6ecb957801..e09f54dcc3 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -1884,7 +1884,7 @@ int main(int argc, char** argv) {
// Change the backup poll interval from 5s to 100ms to speed up the
// ReconnectChannel test
gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "100");
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc
index f04ffe4f2d..425334d972 100644
--- a/test/cpp/end2end/channelz_service_test.cc
+++ b/test/cpp/end2end/channelz_service_test.cc
@@ -54,6 +54,14 @@ using grpc::channelz::v1::GetSubchannelResponse;
using grpc::channelz::v1::GetTopChannelsRequest;
using grpc::channelz::v1::GetTopChannelsResponse;
+// This code snippet can be used to print out any responses for
+// visual debugging.
+//
+//
+// string out_str;
+// google::protobuf::TextFormat::PrintToString(resp, &out_str);
+// std::cout << "resp: " << out_str << "\n";
+
namespace grpc {
namespace testing {
namespace {
@@ -164,6 +172,19 @@ class ChannelzServerTest : public ::testing::Test {
echo_stub_ = grpc::testing::EchoTestService::NewStub(channel);
}
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> NewEchoStub() {
+ static int salt = 0;
+ string target = "dns:localhost:" + to_string(proxy_port_);
+ ChannelArguments args;
+ // disable channelz. We only want to focus on proxy to backend outbound.
+ args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0);
+ // This ensures that gRPC will not do connection sharing.
+ args.SetInt("salt", salt++);
+ std::shared_ptr<Channel> channel =
+ CreateCustomChannel(target, InsecureChannelCredentials(), args);
+ return grpc::testing::EchoTestService::NewStub(channel);
+ }
+
void SendSuccessfulEcho(int channel_idx) {
EchoRequest request;
EchoResponse response;
@@ -651,6 +672,67 @@ TEST_F(ChannelzServerTest, GetServerSocketsTest) {
EXPECT_EQ(get_server_sockets_response.socket_ref_size(), 1);
}
+TEST_F(ChannelzServerTest, GetServerSocketsPaginationTest) {
+ ResetStubs();
+ ConfigureProxy(1);
+ std::vector<std::unique_ptr<grpc::testing::EchoTestService::Stub>> stubs;
+ const int kNumServerSocketsCreated = 20;
+ for (int i = 0; i < kNumServerSocketsCreated; ++i) {
+ stubs.push_back(NewEchoStub());
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello channelz");
+ request.mutable_param()->set_backend_channel_idx(0);
+ ClientContext context;
+ Status s = stubs.back()->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ }
+ GetServersRequest get_server_request;
+ GetServersResponse get_server_response;
+ get_server_request.set_start_server_id(0);
+ ClientContext get_server_context;
+ Status s = channelz_stub_->GetServers(&get_server_context, get_server_request,
+ &get_server_response);
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ EXPECT_EQ(get_server_response.server_size(), 1);
+ // Make a request that gets all of the serversockets
+ {
+ GetServerSocketsRequest get_server_sockets_request;
+ GetServerSocketsResponse get_server_sockets_response;
+ get_server_sockets_request.set_server_id(
+ get_server_response.server(0).ref().server_id());
+ get_server_sockets_request.set_start_socket_id(0);
+ ClientContext get_server_sockets_context;
+ s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
+ get_server_sockets_request,
+ &get_server_sockets_response);
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ // We add one to account the the channelz stub that will end up creating
+ // a serversocket.
+ EXPECT_EQ(get_server_sockets_response.socket_ref_size(),
+ kNumServerSocketsCreated + 1);
+ EXPECT_TRUE(get_server_sockets_response.end());
+ }
+ // Now we make a request that exercises pagination.
+ {
+ GetServerSocketsRequest get_server_sockets_request;
+ GetServerSocketsResponse get_server_sockets_response;
+ get_server_sockets_request.set_server_id(
+ get_server_response.server(0).ref().server_id());
+ get_server_sockets_request.set_start_socket_id(0);
+ const int kMaxResults = 10;
+ get_server_sockets_request.set_max_results(kMaxResults);
+ ClientContext get_server_sockets_context;
+ s = channelz_stub_->GetServerSockets(&get_server_sockets_context,
+ get_server_sockets_request,
+ &get_server_sockets_response);
+ EXPECT_TRUE(s.ok()) << "s.error_message() = " << s.error_message();
+ EXPECT_EQ(get_server_sockets_response.socket_ref_size(), kMaxResults);
+ EXPECT_FALSE(get_server_sockets_response.end());
+ }
+}
+
TEST_F(ChannelzServerTest, GetServerListenSocketsTest) {
ResetStubs();
ConfigureProxy(1);
@@ -677,7 +759,7 @@ TEST_F(ChannelzServerTest, GetServerListenSocketsTest) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc
index a35991396a..a999321992 100644
--- a/test/cpp/end2end/client_callback_end2end_test.cc
+++ b/test/cpp/end2end/client_callback_end2end_test.cc
@@ -182,6 +182,67 @@ class ClientCallbackEnd2endTest
}
}
+ void SendGenericEchoAsBidi(int num_rpcs, int reuses) {
+ const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo");
+ grpc::string test_string("");
+ for (int i = 0; i < num_rpcs; i++) {
+ test_string += "Hello world. ";
+ class Client : public grpc::experimental::ClientBidiReactor<ByteBuffer,
+ ByteBuffer> {
+ public:
+ Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name,
+ const grpc::string& test_str, int reuses)
+ : reuses_remaining_(reuses) {
+ activate_ = [this, test, method_name, test_str] {
+ if (reuses_remaining_ > 0) {
+ cli_ctx_.reset(new ClientContext);
+ reuses_remaining_--;
+ test->generic_stub_->experimental().PrepareBidiStreamingCall(
+ cli_ctx_.get(), method_name, this);
+ request_.set_message(test_str);
+ send_buf_ = SerializeToByteBuffer(&request_);
+ StartWrite(send_buf_.get());
+ StartRead(&recv_buf_);
+ StartCall();
+ } else {
+ std::unique_lock<std::mutex> l(mu_);
+ done_ = true;
+ cv_.notify_one();
+ }
+ };
+ activate_();
+ }
+ void OnWriteDone(bool ok) override { StartWritesDone(); }
+ void OnReadDone(bool ok) override {
+ EchoResponse response;
+ EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response));
+ EXPECT_EQ(request_.message(), response.message());
+ };
+ void OnDone(const Status& s) override {
+ EXPECT_TRUE(s.ok());
+ activate_();
+ }
+ void Await() {
+ std::unique_lock<std::mutex> l(mu_);
+ while (!done_) {
+ cv_.wait(l);
+ }
+ }
+
+ EchoRequest request_;
+ std::unique_ptr<ByteBuffer> send_buf_;
+ ByteBuffer recv_buf_;
+ std::unique_ptr<ClientContext> cli_ctx_;
+ int reuses_remaining_;
+ std::function<void()> activate_;
+ std::mutex mu_;
+ std::condition_variable cv_;
+ bool done_ = false;
+ } rpc{this, kMethodName, test_string, reuses};
+
+ rpc.Await();
+ }
+ }
bool is_server_started_;
std::shared_ptr<Channel> channel_;
std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
@@ -201,6 +262,37 @@ TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) {
SendRpcs(10, false);
}
+TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) {
+ ResetStub();
+ SimpleRequest request;
+ SimpleResponse response;
+ ClientContext cli_ctx;
+
+ cli_ctx.AddMetadata(kCheckClientInitialMetadataKey,
+ kCheckClientInitialMetadataVal);
+
+ std::mutex mu;
+ std::condition_variable cv;
+ bool done = false;
+ stub_->experimental_async()->CheckClientInitialMetadata(
+ &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) {
+ GPR_ASSERT(s.ok());
+
+ std::lock_guard<std::mutex> l(mu);
+ done = true;
+ cv.notify_one();
+ });
+ std::unique_lock<std::mutex> l(mu);
+ while (!done) {
+ cv.wait(l);
+ }
+}
+
+TEST_P(ClientCallbackEnd2endTest, SimpleRpcWithBinaryMetadata) {
+ ResetStub();
+ SendRpcs(1, true);
+}
+
TEST_P(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) {
ResetStub();
SendRpcs(10, true);
@@ -211,6 +303,16 @@ TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) {
SendRpcsGeneric(10, false);
}
+TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) {
+ ResetStub();
+ SendGenericEchoAsBidi(10, 1);
+}
+
+TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) {
+ ResetStub();
+ SendGenericEchoAsBidi(10, 10);
+}
+
#if GRPC_ALLOW_EXCEPTIONS
TEST_P(ClientCallbackEnd2endTest, ExceptingRpc) {
ResetStub();
@@ -267,6 +369,156 @@ TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) {
}
}
+TEST_P(ClientCallbackEnd2endTest, RequestStream) {
+ ResetStub();
+ class Client : public grpc::experimental::ClientWriteReactor<EchoRequest> {
+ public:
+ explicit Client(grpc::testing::EchoTestService::Stub* stub) {
+ context_.set_initial_metadata_corked(true);
+ stub->experimental_async()->RequestStream(&context_, &response_, this);
+ StartCall();
+ request_.set_message("Hello server.");
+ StartWrite(&request_);
+ }
+ void OnWriteDone(bool ok) override {
+ writes_left_--;
+ if (writes_left_ > 1) {
+ StartWrite(&request_);
+ } else if (writes_left_ == 1) {
+ StartWriteLast(&request_, WriteOptions());
+ }
+ }
+ void OnDone(const Status& s) override {
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response_.message(), "Hello server.Hello server.Hello server.");
+ std::unique_lock<std::mutex> l(mu_);
+ done_ = true;
+ cv_.notify_one();
+ }
+ void Await() {
+ std::unique_lock<std::mutex> l(mu_);
+ while (!done_) {
+ cv_.wait(l);
+ }
+ }
+
+ private:
+ EchoRequest request_;
+ EchoResponse response_;
+ ClientContext context_;
+ int writes_left_{3};
+ std::mutex mu_;
+ std::condition_variable cv_;
+ bool done_ = false;
+ } test{stub_.get()};
+
+ test.Await();
+}
+
+TEST_P(ClientCallbackEnd2endTest, ResponseStream) {
+ ResetStub();
+ class Client : public grpc::experimental::ClientReadReactor<EchoResponse> {
+ public:
+ explicit Client(grpc::testing::EchoTestService::Stub* stub) {
+ request_.set_message("Hello client ");
+ stub->experimental_async()->ResponseStream(&context_, &request_, this);
+ StartCall();
+ StartRead(&response_);
+ }
+ void OnReadDone(bool ok) override {
+ if (!ok) {
+ EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend);
+ } else {
+ EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend);
+ EXPECT_EQ(response_.message(),
+ request_.message() + grpc::to_string(reads_complete_));
+ reads_complete_++;
+ StartRead(&response_);
+ }
+ }
+ void OnDone(const Status& s) override {
+ EXPECT_TRUE(s.ok());
+ std::unique_lock<std::mutex> l(mu_);
+ done_ = true;
+ cv_.notify_one();
+ }
+ void Await() {
+ std::unique_lock<std::mutex> l(mu_);
+ while (!done_) {
+ cv_.wait(l);
+ }
+ }
+
+ private:
+ EchoRequest request_;
+ EchoResponse response_;
+ ClientContext context_;
+ int reads_complete_{0};
+ std::mutex mu_;
+ std::condition_variable cv_;
+ bool done_ = false;
+ } test{stub_.get()};
+
+ test.Await();
+}
+
+TEST_P(ClientCallbackEnd2endTest, BidiStream) {
+ ResetStub();
+ class Client : public grpc::experimental::ClientBidiReactor<EchoRequest,
+ EchoResponse> {
+ public:
+ explicit Client(grpc::testing::EchoTestService::Stub* stub) {
+ request_.set_message("Hello fren ");
+ stub->experimental_async()->BidiStream(&context_, this);
+ StartCall();
+ StartRead(&response_);
+ StartWrite(&request_);
+ }
+ void OnReadDone(bool ok) override {
+ if (!ok) {
+ EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend);
+ } else {
+ EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend);
+ EXPECT_EQ(response_.message(), request_.message());
+ reads_complete_++;
+ StartRead(&response_);
+ }
+ }
+ void OnWriteDone(bool ok) override {
+ EXPECT_TRUE(ok);
+ if (++writes_complete_ == kServerDefaultResponseStreamsToSend) {
+ StartWritesDone();
+ } else {
+ StartWrite(&request_);
+ }
+ }
+ void OnDone(const Status& s) override {
+ EXPECT_TRUE(s.ok());
+ std::unique_lock<std::mutex> l(mu_);
+ done_ = true;
+ cv_.notify_one();
+ }
+ void Await() {
+ std::unique_lock<std::mutex> l(mu_);
+ while (!done_) {
+ cv_.wait(l);
+ }
+ }
+
+ private:
+ EchoRequest request_;
+ EchoResponse response_;
+ ClientContext context_;
+ int reads_complete_{0};
+ int writes_complete_{0};
+ std::mutex mu_;
+ std::condition_variable cv_;
+ bool done_ = false;
+ } test{stub_.get()};
+
+ test.Await();
+}
+
TestScenario scenarios[] = {TestScenario{false}, TestScenario{true}};
INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest,
@@ -277,7 +529,7 @@ INSTANTIATE_TEST_CASE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest,
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc
index 2a06f44c60..992f3c488f 100644
--- a/test/cpp/end2end/client_crash_test.cc
+++ b/test/cpp/end2end/client_crash_test.cc
@@ -135,7 +135,7 @@ int main(int argc, char** argv) {
g_root = ".";
}
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
// Order seems to matter on these tests: run three times to eliminate that
for (int i = 0; i < 3; i++) {
diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc
index 3708c11235..33773e3b3b 100644
--- a/test/cpp/end2end/client_interceptors_end2end_test.cc
+++ b/test/cpp/end2end/client_interceptors_end2end_test.cc
@@ -50,6 +50,7 @@ class HijackingInterceptor : public experimental::Interceptor {
info_ = info;
// Make sure it is the right method
EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0);
+ EXPECT_EQ(info->type(), experimental::ClientRpcInfo::Type::UNARY);
}
virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
@@ -415,15 +416,13 @@ class ClientInterceptorsEnd2endTest : public ::testing::Test {
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -436,20 +435,19 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) {
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors before hijacking interceptor
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
- creators->push_back(std::unique_ptr<HijackingInterceptorFactory>(
+ creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
new HijackingInterceptorFactory()));
// Add 20 dummy interceptors after hijacking interceptor
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -462,13 +460,11 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) {
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLogThenHijackTest) {
ChannelArguments args;
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
- creators->push_back(std::unique_ptr<HijackingInterceptorFactory>(
+ creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
new HijackingInterceptorFactory()));
auto channel = experimental::CreateCustomChannelWithInterceptors(
server_address_, InsecureChannelCredentials(), args, std::move(creators));
@@ -480,21 +476,20 @@ TEST_F(ClientInterceptorsEnd2endTest,
ClientInterceptorHijackingMakesAnotherCallTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 5 dummy interceptors before hijacking interceptor
+ creators.reserve(5);
for (auto i = 0; i < 5; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
- creators->push_back(
+ creators.push_back(
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>(
new HijackingInterceptorMakesAnotherCallFactory()));
// Add 7 dummy interceptors after hijacking interceptor
for (auto i = 0; i < 7; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = server_->experimental().InProcessChannelWithInterceptors(
@@ -510,15 +505,13 @@ TEST_F(ClientInterceptorsEnd2endTest,
ClientInterceptorLoggingTestWithCallback) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = server_->experimental().InProcessChannelWithInterceptors(
@@ -550,15 +543,13 @@ class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test {
TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -571,15 +562,13 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) {
TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -623,15 +612,13 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) {
TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -668,13 +655,12 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) {
experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -695,13 +681,12 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) {
experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -722,13 +707,12 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) {
experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -746,7 +730,7 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index d13fb23796..929c2bb589 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -35,7 +35,9 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/ext/filters/client_channel/subchannel_index.h"
#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/env.h"
@@ -116,7 +118,10 @@ class MyTestServiceImpl : public TestServiceImpl {
class ClientLbEnd2endTest : public ::testing::Test {
protected:
ClientLbEnd2endTest()
- : server_host_("localhost"), kRequestMessage_("Live long and prosper.") {
+ : server_host_("localhost"),
+ kRequestMessage_("Live long and prosper."),
+ creds_(new SecureChannelCredentials(
+ grpc_fake_transport_security_credentials_create())) {
// Make the backup poller poll very frequently in order to pick up
// updates from all the subchannels's FDs.
gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "1");
@@ -156,24 +161,22 @@ class ClientLbEnd2endTest : public ::testing::Test {
}
grpc_channel_args* BuildFakeResults(const std::vector<int>& ports) {
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(ports.size(), nullptr);
- for (size_t i = 0; i < ports.size(); ++i) {
+ grpc_core::ServerAddressList addresses;
+ for (const int& port : ports) {
char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", ports[i]);
+ gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", port);
grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(addresses, i, lb_uri,
- false /* is balancer */,
- "" /* balancer name */, nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ addresses.emplace_back(address.addr, address.len, nullptr /* args */);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
const grpc_arg fake_addresses =
- grpc_lb_addresses_create_channel_arg(addresses);
+ CreateServerAddressListChannelArg(&addresses);
grpc_channel_args* fake_results =
grpc_channel_args_copy_and_add(nullptr, &fake_addresses, 1);
- grpc_lb_addresses_destroy(addresses);
return fake_results;
}
@@ -191,6 +194,11 @@ class ClientLbEnd2endTest : public ::testing::Test {
grpc_channel_args_destroy(fake_results);
}
+ void SetFailureOnReresolution() {
+ grpc_core::ExecCtx exec_ctx;
+ response_generator_->SetFailureOnReresolution();
+ }
+
std::vector<int> GetServersPorts() {
std::vector<int> ports;
for (const auto& server : servers_) ports.push_back(server->port_);
@@ -210,9 +218,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
} // else, default to pick first
args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
response_generator_.get());
- std::shared_ptr<ChannelCredentials> creds(new SecureChannelCredentials(
- grpc_fake_transport_security_credentials_create()));
- return CreateCustomChannel("fake:///", std::move(creds), args);
+ return CreateCustomChannel("fake:///", creds_, args);
}
bool SendRpc(
@@ -260,6 +266,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
MyTestServiceImpl service_;
std::unique_ptr<std::thread> thread_;
bool server_ready_ = false;
+ bool started_ = false;
explicit ServerData(int port = 0) {
port_ = port > 0 ? port : grpc_pick_unused_port_or_die();
@@ -267,6 +274,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
void Start(const grpc::string& server_host) {
gpr_log(GPR_INFO, "starting server on port %d", port_);
+ started_ = true;
std::mutex mu;
std::unique_lock<std::mutex> lock(mu);
std::condition_variable cond;
@@ -292,9 +300,11 @@ class ClientLbEnd2endTest : public ::testing::Test {
cond->notify_one();
}
- void Shutdown(bool join = true) {
+ void Shutdown() {
+ if (!started_) return;
server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
- if (join) thread_->join();
+ thread_->join();
+ started_ = false;
}
void SetServingStatus(const grpc::string& service, bool serving) {
@@ -373,6 +383,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator>
response_generator_;
const grpc::string kRequestMessage_;
+ std::shared_ptr<ChannelCredentials> creds_;
};
TEST_F(ClientLbEnd2endTest, PickFirst) {
@@ -417,6 +428,30 @@ TEST_F(ClientLbEnd2endTest, PickFirstProcessPending) {
CheckRpcSendOk(second_stub, DEBUG_LOCATION);
}
+TEST_F(ClientLbEnd2endTest, PickFirstSelectsReadyAtStartup) {
+ ChannelArguments args;
+ constexpr int kInitialBackOffMs = 5000;
+ args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs);
+ // Create 2 servers, but start only the second one.
+ std::vector<int> ports = {grpc_pick_unused_port_or_die(),
+ grpc_pick_unused_port_or_die()};
+ CreateServers(2, ports);
+ StartServer(1);
+ auto channel1 = BuildChannel("pick_first", args);
+ auto stub1 = BuildStub(channel1);
+ SetNextResolution(ports);
+ // Wait for second server to be ready.
+ WaitForServer(stub1, 1, DEBUG_LOCATION);
+ // Create a second channel with the same addresses. Its PF instance
+ // should immediately pick the second subchannel, since it's already
+ // in READY state.
+ auto channel2 = BuildChannel("pick_first", args);
+ SetNextResolution(ports);
+ // Check that the channel reports READY without waiting for the
+ // initial backoff.
+ EXPECT_TRUE(WaitForChannelReady(channel2.get(), 1 /* timeout_seconds */));
+}
+
TEST_F(ClientLbEnd2endTest, PickFirstBackOffInitialReconnect) {
ChannelArguments args;
constexpr int kInitialBackOffMs = 100;
@@ -502,6 +537,51 @@ TEST_F(ClientLbEnd2endTest, PickFirstResetConnectionBackoff) {
EXPECT_LT(waited_ms, kInitialBackOffMs);
}
+TEST_F(ClientLbEnd2endTest,
+ PickFirstResetConnectionBackoffNextAttemptStartsImmediately) {
+ ChannelArguments args;
+ constexpr int kInitialBackOffMs = 1000;
+ args.SetInt(GRPC_ARG_INITIAL_RECONNECT_BACKOFF_MS, kInitialBackOffMs);
+ const std::vector<int> ports = {grpc_pick_unused_port_or_die()};
+ auto channel = BuildChannel("pick_first", args);
+ auto stub = BuildStub(channel);
+ SetNextResolution(ports);
+ // Wait for connect, which should fail ~immediately, because the server
+ // is not up.
+ gpr_log(GPR_INFO, "=== INITIAL CONNECTION ATTEMPT");
+ EXPECT_FALSE(
+ channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10)));
+ // Reset connection backoff.
+ // Note that the time at which the third attempt will be started is
+ // actually computed at this point, so we record the start time here.
+ gpr_log(GPR_INFO, "=== RESETTING BACKOFF");
+ const gpr_timespec t0 = gpr_now(GPR_CLOCK_MONOTONIC);
+ experimental::ChannelResetConnectionBackoff(channel.get());
+ // Trigger a second connection attempt. This should also fail
+ // ~immediately, but the retry should be scheduled for
+ // kInitialBackOffMs instead of applying the multiplier.
+ gpr_log(GPR_INFO, "=== POLLING FOR SECOND CONNECTION ATTEMPT");
+ EXPECT_FALSE(
+ channel->WaitForConnected(grpc_timeout_milliseconds_to_deadline(10)));
+ // Bring up a server on the chosen port.
+ gpr_log(GPR_INFO, "=== STARTING BACKEND");
+ StartServers(1, ports);
+ // Wait for connect. Should happen within kInitialBackOffMs.
+ // Give an extra 100ms to account for the time spent in the second and
+ // third connection attempts themselves (since what we really want to
+ // measure is the time between the two). As long as this is less than
+ // the 1.6x increase we would see if the backoff state was not reset
+ // properly, the test is still proving that the backoff was reset.
+ constexpr int kWaitMs = kInitialBackOffMs + 100;
+ gpr_log(GPR_INFO, "=== POLLING FOR THIRD CONNECTION ATTEMPT");
+ EXPECT_TRUE(channel->WaitForConnected(
+ grpc_timeout_milliseconds_to_deadline(kWaitMs)));
+ const gpr_timespec t1 = gpr_now(GPR_CLOCK_MONOTONIC);
+ const grpc_millis waited_ms = gpr_time_to_millis(gpr_time_sub(t1, t0));
+ gpr_log(GPR_DEBUG, "Waited %" PRId64 " milliseconds", waited_ms);
+ EXPECT_LT(waited_ms, kWaitMs);
+}
+
TEST_F(ClientLbEnd2endTest, PickFirstUpdates) {
// Start servers and send one RPC per server.
const int kNumServers = 3;
@@ -728,6 +808,23 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) {
EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName());
}
+TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) {
+ // Start server, send RPC, and make sure channel is READY.
+ const int kNumServers = 1;
+ StartServers(kNumServers);
+ auto channel = BuildChannel(""); // pick_first is the default.
+ auto stub = BuildStub(channel);
+ SetNextResolution(GetServersPorts());
+ CheckRpcSendOk(stub, DEBUG_LOCATION);
+ EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
+ // Stop server. Channel should go into state IDLE.
+ SetFailureOnReresolution();
+ servers_[0]->Shutdown();
+ EXPECT_TRUE(WaitForChannelNotReady(channel.get()));
+ EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE);
+ servers_.clear();
+}
+
TEST_F(ClientLbEnd2endTest, RoundRobin) {
// Start servers and send one RPC per server.
const int kNumServers = 3;
@@ -877,7 +974,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinUpdateInError) {
servers_[0]->service_.ResetCounters();
// Shutdown one of the servers to be sent in the update.
- servers_[1]->Shutdown(false);
+ servers_[1]->Shutdown();
ports.emplace_back(servers_[1]->port_);
ports.emplace_back(servers_[2]->port_);
SetNextResolution(ports);
@@ -936,7 +1033,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinReresolve) {
// Kill all servers
gpr_log(GPR_INFO, "****** ABOUT TO KILL SERVERS *******");
for (size_t i = 0; i < servers_.size(); ++i) {
- servers_[i]->Shutdown(true);
+ servers_[i]->Shutdown();
}
gpr_log(GPR_INFO, "****** SERVERS KILLED *******");
gpr_log(GPR_INFO, "****** SENDING DOOMED REQUESTS *******");
@@ -984,7 +1081,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinSingleReconnect) {
}
const auto pre_death = servers_[0]->service_.request_count();
// Kill the first server.
- servers_[0]->Shutdown(true);
+ servers_[0]->Shutdown();
// Client request still succeed. May need retrying if RR had returned a pick
// before noticing the change in the server's connectivity.
while (!SendRpc(stub)) {
@@ -1131,7 +1228,7 @@ TEST_F(ClientLbEnd2endTest, RoundRobinWithHealthCheckingInhibitPerChannel) {
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
const auto result = RUN_ALL_TESTS();
return result;
}
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 03291e1785..05cd4330c6 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -196,16 +196,18 @@ class TestServiceImplDupPkg
class TestScenario {
public:
TestScenario(bool interceptors, bool proxy, bool inproc_stub,
- const grpc::string& creds_type)
+ const grpc::string& creds_type, bool use_callback_server)
: use_interceptors(interceptors),
use_proxy(proxy),
inproc(inproc_stub),
- credentials_type(creds_type) {}
+ credentials_type(creds_type),
+ callback_server(use_callback_server) {}
void Log() const;
bool use_interceptors;
bool use_proxy;
bool inproc;
const grpc::string credentials_type;
+ bool callback_server;
};
static std::ostream& operator<<(std::ostream& out,
@@ -214,6 +216,8 @@ static std::ostream& operator<<(std::ostream& out,
<< (scenario.use_interceptors ? "true" : "false")
<< ", use_proxy=" << (scenario.use_proxy ? "true" : "false")
<< ", inproc=" << (scenario.inproc ? "true" : "false")
+ << ", server_type="
+ << (scenario.callback_server ? "callback" : "sync")
<< ", credentials='" << scenario.credentials_type << "'}";
}
@@ -280,7 +284,11 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> {
builder.experimental().SetInterceptorCreators(std::move(creators));
}
builder.AddListeningPort(server_address_.str(), server_creds);
- builder.RegisterService(&service_);
+ if (!GetParam().callback_server) {
+ builder.RegisterService(&service_);
+ } else {
+ builder.RegisterService(&callback_service_);
+ }
builder.RegisterService("foo.test.youtube.com", &special_service_);
builder.RegisterService(&dup_pkg_service_);
@@ -362,6 +370,7 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> {
std::ostringstream server_address_;
const int kMaxMessageSize_;
TestServiceImpl service_;
+ CallbackTestServiceImpl callback_service_;
TestServiceImpl special_service_;
TestServiceImplDupPkg dup_pkg_service_;
grpc::string user_agent_prefix_;
@@ -1016,7 +1025,8 @@ TEST_P(End2endTest, DiffPackageServices) {
EXPECT_TRUE(s.ok());
}
-void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
+template <class ServiceType>
+void CancelRpc(ClientContext* context, int delay_us, ServiceType* service) {
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(delay_us, GPR_TIMESPAN)));
while (!service->signal_client()) {
@@ -1446,7 +1456,24 @@ TEST_P(ProxyEnd2endTest, ClientCancelsRpc) {
request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
ClientContext context;
- std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
+ std::thread cancel_thread;
+ if (!GetParam().callback_server) {
+ cancel_thread = std::thread(
+ [&context, this](int delay) { CancelRpc(&context, delay, &service_); },
+ kCancelDelayUs);
+ // Note: the unusual pattern above (and below) is caused by a conflict
+ // between two sets of compiler expectations. clang allows const to be
+ // captured without mention, so there is no need to capture kCancelDelayUs
+ // (and indeed clang-tidy complains if you do so). OTOH, a Windows compiler
+ // in our tests requires an explicit capture even for const. We square this
+ // circle by passing the const value in as an argument to the lambda.
+ } else {
+ cancel_thread = std::thread(
+ [&context, this](int delay) {
+ CancelRpc(&context, delay, &callback_service_);
+ },
+ kCancelDelayUs);
+ }
Status s = stub_->Echo(&context, request, &response);
cancel_thread.join();
EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
@@ -1838,10 +1865,12 @@ TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) {
EXPECT_TRUE(s.ok());
}
+// TODO(vjpai): refactor arguments into a struct if it makes sense
std::vector<TestScenario> CreateTestScenarios(bool use_proxy,
bool test_insecure,
bool test_secure,
- bool test_inproc) {
+ bool test_inproc,
+ bool test_callback_server) {
std::vector<TestScenario> scenarios;
std::vector<grpc::string> credentials_types;
if (test_secure) {
@@ -1857,41 +1886,48 @@ std::vector<TestScenario> CreateTestScenarios(bool use_proxy,
if (test_insecure && insec_ok()) {
credentials_types.push_back(kInsecureCredentialsType);
}
+
+ // For now test callback server only with inproc
GPR_ASSERT(!credentials_types.empty());
for (const auto& cred : credentials_types) {
- scenarios.emplace_back(false, false, false, cred);
- scenarios.emplace_back(true, false, false, cred);
+ scenarios.emplace_back(false, false, false, cred, false);
+ scenarios.emplace_back(true, false, false, cred, false);
if (use_proxy) {
- scenarios.emplace_back(false, true, false, cred);
- scenarios.emplace_back(true, true, false, cred);
+ scenarios.emplace_back(false, true, false, cred, false);
+ scenarios.emplace_back(true, true, false, cred, false);
}
}
if (test_inproc && insec_ok()) {
- scenarios.emplace_back(false, false, true, kInsecureCredentialsType);
- scenarios.emplace_back(true, false, true, kInsecureCredentialsType);
+ scenarios.emplace_back(false, false, true, kInsecureCredentialsType, false);
+ scenarios.emplace_back(true, false, true, kInsecureCredentialsType, false);
+ if (test_callback_server) {
+ scenarios.emplace_back(false, false, true, kInsecureCredentialsType,
+ true);
+ scenarios.emplace_back(true, false, true, kInsecureCredentialsType, true);
+ }
}
return scenarios;
}
-INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
- ::testing::ValuesIn(CreateTestScenarios(false, true,
- true, true)));
+INSTANTIATE_TEST_CASE_P(
+ End2end, End2endTest,
+ ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true)));
-INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest,
- ::testing::ValuesIn(CreateTestScenarios(false, true,
- true, true)));
+INSTANTIATE_TEST_CASE_P(
+ End2endServerTryCancel, End2endServerTryCancelTest,
+ ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, true)));
-INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
- ::testing::ValuesIn(CreateTestScenarios(true, true,
- true, true)));
+INSTANTIATE_TEST_CASE_P(
+ ProxyEnd2end, ProxyEnd2endTest,
+ ::testing::ValuesIn(CreateTestScenarios(true, true, true, true, false)));
-INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest,
- ::testing::ValuesIn(CreateTestScenarios(false, false,
- true, false)));
+INSTANTIATE_TEST_CASE_P(
+ SecureEnd2end, SecureEnd2endTest,
+ ::testing::ValuesIn(CreateTestScenarios(false, false, true, false, true)));
-INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest,
- ::testing::ValuesIn(CreateTestScenarios(false, true,
- true, true)));
+INSTANTIATE_TEST_CASE_P(
+ ResourceQuotaEnd2end, ResourceQuotaEnd2endTest,
+ ::testing::ValuesIn(CreateTestScenarios(false, true, true, true, false)));
} // namespace
} // namespace testing
@@ -1899,7 +1935,7 @@ INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest,
int main(int argc, char** argv) {
gpr_setenv("GRPC_CLIENT_CHANNEL_BACKUP_POLL_INTERVAL_MS", "200");
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/exception_test.cc b/test/cpp/end2end/exception_test.cc
index 5343997663..0d2c00263b 100644
--- a/test/cpp/end2end/exception_test.cc
+++ b/test/cpp/end2end/exception_test.cc
@@ -117,7 +117,7 @@ TEST_F(ExceptionTest, RequestStream) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index 88f8f380c3..ad67402e3d 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -331,7 +331,7 @@ void RegisterFilter() {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
grpc::testing::RegisterFilter();
return RUN_ALL_TESTS();
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 88a1227ca2..015862bfe8 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -333,7 +333,7 @@ TEST_F(GenericEnd2endTest, Deadline) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 6ce0696114..2eaacd429d 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -32,7 +32,9 @@
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/sockaddr.h"
@@ -412,8 +414,8 @@ class GrpclbEnd2endTest : public ::testing::Test {
std::shared_ptr<ChannelCredentials> creds(
new SecureChannelCredentials(grpc_composite_channel_credentials_create(
channel_creds, call_creds, nullptr)));
- grpc_call_credentials_unref(call_creds);
- grpc_channel_credentials_unref(channel_creds);
+ call_creds->Unref();
+ channel_creds->Unref();
channel_ = CreateCustomChannel(uri.str(), creds, args);
stub_ = grpc::testing::EchoTestService::NewStub(channel_);
}
@@ -486,18 +488,27 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc::string balancer_name;
};
- grpc_lb_addresses* CreateLbAddressesFromAddressDataList(
+ grpc_core::ServerAddressList CreateLbAddressesFromAddressDataList(
const std::vector<AddressData>& address_data) {
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(address_data.size(), nullptr);
- for (size_t i = 0; i < address_data.size(); ++i) {
+ grpc_core::ServerAddressList addresses;
+ for (const auto& addr : address_data) {
char* lb_uri_str;
- gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", address_data[i].port);
+ gpr_asprintf(&lb_uri_str, "ipv4:127.0.0.1:%d", addr.port);
grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str, true);
GPR_ASSERT(lb_uri != nullptr);
- grpc_lb_addresses_set_address_from_uri(
- addresses, i, lb_uri, address_data[i].is_balancer,
- address_data[i].balancer_name.c_str(), nullptr);
+ grpc_resolved_address address;
+ GPR_ASSERT(grpc_parse_uri(lb_uri, &address));
+ std::vector<grpc_arg> args_to_add;
+ if (addr.is_balancer) {
+ args_to_add.emplace_back(grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_IS_BALANCER), 1));
+ args_to_add.emplace_back(grpc_channel_arg_string_create(
+ const_cast<char*>(GRPC_ARG_ADDRESS_BALANCER_NAME),
+ const_cast<char*>(addr.balancer_name.c_str())));
+ }
+ grpc_channel_args* args = grpc_channel_args_copy_and_add(
+ nullptr, args_to_add.data(), args_to_add.size());
+ addresses.emplace_back(address.addr, address.len, args);
grpc_uri_destroy(lb_uri);
gpr_free(lb_uri_str);
}
@@ -506,23 +517,21 @@ class GrpclbEnd2endTest : public ::testing::Test {
void SetNextResolution(const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses* addresses =
+ grpc_core::ServerAddressList addresses =
CreateLbAddressesFromAddressDataList(address_data);
- grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetResponse(&fake_result);
- grpc_lb_addresses_destroy(addresses);
}
void SetNextReresolutionResponse(
const std::vector<AddressData>& address_data) {
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses* addresses =
+ grpc_core::ServerAddressList addresses =
CreateLbAddressesFromAddressDataList(address_data);
- grpc_arg fake_addresses = grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_arg fake_addresses = CreateServerAddressListChannelArg(&addresses);
grpc_channel_args fake_result = {1, &fake_addresses};
response_generator_->SetReresolutionResponse(&fake_result);
- grpc_lb_addresses_destroy(addresses);
}
const std::vector<int> GetBackendPorts(const size_t start_index = 0) const {
@@ -553,10 +562,11 @@ class GrpclbEnd2endTest : public ::testing::Test {
return status;
}
- void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) {
+ void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000,
+ bool wait_for_ready = false) {
for (size_t i = 0; i < times; ++i) {
EchoResponse response;
- const Status status = SendRpc(&response, timeout_ms);
+ const Status status = SendRpc(&response, timeout_ms, wait_for_ready);
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
EXPECT_EQ(response.message(), kRequestMessage_);
@@ -717,10 +727,9 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}),
kServerlistDelayMs);
-
const auto t0 = system_clock::now();
// Client will block: LB will initially send empty serverlist.
- CheckRpcSendOk(1, kCallDeadlineMs);
+ CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */);
const auto ellapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
system_clock::now() - t0);
@@ -1518,7 +1527,7 @@ TEST_F(SingleBalancerWithClientLoadReportingTest, Drop) {
int main(int argc, char** argv) {
grpc_init();
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
const auto result = RUN_ALL_TESTS();
grpc_shutdown();
diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc
index fca65dfc13..b96ff53a3e 100644
--- a/test/cpp/end2end/health_service_end2end_test.cc
+++ b/test/cpp/end2end/health_service_end2end_test.cc
@@ -37,6 +37,7 @@
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_health_check_service_impl.h"
#include "test/cpp/end2end/test_service_impl.h"
#include <gtest/gtest.h>
@@ -49,62 +50,6 @@ namespace grpc {
namespace testing {
namespace {
-// A sample sync implementation of the health checking service. This does the
-// same thing as the default one.
-class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service {
- public:
- Status Check(ServerContext* context, const HealthCheckRequest* request,
- HealthCheckResponse* response) override {
- std::lock_guard<std::mutex> lock(mu_);
- auto iter = status_map_.find(request->service());
- if (iter == status_map_.end()) {
- return Status(StatusCode::NOT_FOUND, "");
- }
- response->set_status(iter->second);
- 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_);
- status_map_[service_name] = status;
- }
-
- void SetAll(HealthCheckResponse::ServingStatus status) {
- std::lock_guard<std::mutex> lock(mu_);
- for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
- iter->second = status;
- }
- }
-
- private:
- std::mutex mu_;
- std::map<const grpc::string, HealthCheckResponse::ServingStatus> status_map_;
-};
-
// A custom implementation of the health checking service interface. This is
// used to test that it prevents the server from creating a default service and
// also serves as an example of how to override the default service.
@@ -125,6 +70,8 @@ class CustomHealthCheckService : public HealthCheckServiceInterface {
: HealthCheckResponse::NOT_SERVING);
}
+ void Shutdown() override { impl_->Shutdown(); }
+
private:
HealthCheckServiceImpl* impl_; // not owned
};
@@ -260,6 +207,74 @@ class HealthServiceEnd2endTest : public ::testing::Test {
context.TryCancel();
}
+ // Verify that after HealthCheckServiceInterface::Shutdown is called
+ // 1. unary client will see NOT_SERVING.
+ // 2. unary client still sees NOT_SERVING after a SetServing(true) is called.
+ // 3. streaming (Watch) client will see an update.
+ // 4. setting a new service to serving after shutdown will add the service
+ // name but return NOT_SERVING to client.
+ // This has to be called last.
+ void VerifyHealthCheckServiceShutdown() {
+ HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+ EXPECT_TRUE(service != nullptr);
+ const grpc::string kHealthyService("healthy_service");
+ const grpc::string kUnhealthyService("unhealthy_service");
+ const grpc::string kNotRegisteredService("not_registered");
+ const grpc::string kNewService("add_after_shutdown");
+ service->SetServingStatus(kHealthyService, true);
+ service->SetServingStatus(kUnhealthyService, false);
+
+ ResetStubs();
+
+ // Start Watch for service.
+ ClientContext context;
+ HealthCheckRequest request;
+ request.set_service(kHealthyService);
+ std::unique_ptr<::grpc::ClientReaderInterface<HealthCheckResponse>> reader =
+ hc_stub_->Watch(&context, request);
+
+ HealthCheckResponse response;
+ EXPECT_TRUE(reader->Read(&response));
+ EXPECT_EQ(response.SERVING, response.status());
+
+ SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING);
+ SendHealthCheckRpc(kHealthyService, Status::OK,
+ HealthCheckResponse::SERVING);
+ SendHealthCheckRpc(kUnhealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kNotRegisteredService,
+ Status(StatusCode::NOT_FOUND, ""));
+ SendHealthCheckRpc(kNewService, Status(StatusCode::NOT_FOUND, ""));
+
+ // Shutdown health check service.
+ service->Shutdown();
+
+ // Watch client gets another update.
+ EXPECT_TRUE(reader->Read(&response));
+ EXPECT_EQ(response.NOT_SERVING, response.status());
+ // Finish Watch call.
+ context.TryCancel();
+
+ SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kHealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kUnhealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ SendHealthCheckRpc(kNotRegisteredService,
+ Status(StatusCode::NOT_FOUND, ""));
+
+ // Setting status after Shutdown has no effect.
+ service->SetServingStatus(kHealthyService, true);
+ SendHealthCheckRpc(kHealthyService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+
+ // Adding serving status for a new service after shutdown will return
+ // NOT_SERVING.
+ service->SetServingStatus(kNewService, true);
+ SendHealthCheckRpc(kNewService, Status::OK,
+ HealthCheckResponse::NOT_SERVING);
+ }
+
TestServiceImpl echo_test_service_;
HealthCheckServiceImpl health_check_service_impl_;
std::unique_ptr<Health::Stub> hc_stub_;
@@ -295,6 +310,13 @@ TEST_F(HealthServiceEnd2endTest, DefaultHealthService) {
Status(StatusCode::INVALID_ARGUMENT, ""));
}
+TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) {
+ EnableDefaultHealthCheckService(true);
+ EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+ SetUpServer(true, false, false, nullptr);
+ VerifyHealthCheckServiceShutdown();
+}
+
// Provide an empty service to disable the default service.
TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) {
EnableDefaultHealthCheckService(true);
@@ -326,12 +348,27 @@ TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) {
VerifyHealthCheckServiceStreaming();
}
+TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) {
+ EnableDefaultHealthCheckService(true);
+ EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+ std::unique_ptr<HealthCheckServiceInterface> override_service(
+ new CustomHealthCheckService(&health_check_service_impl_));
+ HealthCheckServiceInterface* underlying_service = override_service.get();
+ SetUpServer(false, false, true, std::move(override_service));
+ HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+ EXPECT_TRUE(service == underlying_service);
+
+ ResetStubs();
+
+ VerifyHealthCheckServiceShutdown();
+}
+
} // namespace
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc
index 339eadde92..18bb1ff4b9 100644
--- a/test/cpp/end2end/hybrid_end2end_test.cc
+++ b/test/cpp/end2end/hybrid_end2end_test.cc
@@ -894,7 +894,7 @@ TEST_F(HybridEnd2endTest, GenericMethodWithoutGenericService) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc
index 602d1695a3..e0ad7d1526 100644
--- a/test/cpp/end2end/interceptors_util.cc
+++ b/test/cpp/end2end/interceptors_util.cc
@@ -132,16 +132,14 @@ bool CheckMetadata(const std::multimap<grpc::string_ref, grpc::string_ref>& map,
return false;
}
-std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
CreateDummyClientInterceptors() {
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors before hijacking interceptor
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
return creators;
diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h
index b4c4791fca..d886e32494 100644
--- a/test/cpp/end2end/interceptors_util.h
+++ b/test/cpp/end2end/interceptors_util.h
@@ -149,8 +149,7 @@ void MakeCallbackCall(const std::shared_ptr<Channel>& channel);
bool CheckMetadata(const std::multimap<grpc::string_ref, grpc::string_ref>& map,
const string& key, const string& value);
-std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
CreateDummyClientInterceptors();
inline void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index ba3122c895..917ca28020 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -345,7 +345,7 @@ TEST_F(MockTest, BidiStream) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/nonblocking_test.cc b/test/cpp/end2end/nonblocking_test.cc
index d8337baca2..36dea1fcb3 100644
--- a/test/cpp/end2end/nonblocking_test.cc
+++ b/test/cpp/end2end/nonblocking_test.cc
@@ -187,7 +187,7 @@ int main(int argc, char** argv) {
grpc_poll_function = maybe_assert_non_blocking_poll;
#endif // GRPC_POSIX_SOCKET
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc
index 21a275ef62..ff097aa9a7 100644
--- a/test/cpp/end2end/proto_server_reflection_test.cc
+++ b/test/cpp/end2end/proto_server_reflection_test.cc
@@ -144,7 +144,7 @@ TEST_F(ProtoServerReflectionTest, CheckResponseWithLocalDescriptorPool) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/raw_end2end_test.cc b/test/cpp/end2end/raw_end2end_test.cc
index a413905ef7..c8556bae95 100644
--- a/test/cpp/end2end/raw_end2end_test.cc
+++ b/test/cpp/end2end/raw_end2end_test.cc
@@ -363,7 +363,7 @@ TEST_F(RawEnd2EndTest, CompileTest) {
int main(int argc, char** argv) {
// Change the backup poll interval from 5s to 100ms to speed up the
// ReconnectChannel test
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc
index d54523fcbb..d744a93912 100644
--- a/test/cpp/end2end/server_builder_plugin_test.cc
+++ b/test/cpp/end2end/server_builder_plugin_test.cc
@@ -264,7 +264,7 @@ INSTANTIATE_TEST_CASE_P(ServerBuilderPluginTest, ServerBuilderPluginTest,
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc
index 93257b2705..353ebf713a 100644
--- a/test/cpp/end2end/server_crash_test.cc
+++ b/test/cpp/end2end/server_crash_test.cc
@@ -153,7 +153,7 @@ int main(int argc, char** argv) {
g_root = ".";
}
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/server_early_return_test.cc b/test/cpp/end2end/server_early_return_test.cc
index 8948e5b854..c47e25052e 100644
--- a/test/cpp/end2end/server_early_return_test.cc
+++ b/test/cpp/end2end/server_early_return_test.cc
@@ -226,7 +226,7 @@ TEST_F(ServerEarlyReturnTest, RequestStreamEarlyCancel) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc
index 295d63516b..9460a7d6c6 100644
--- a/test/cpp/end2end/server_interceptors_end2end_test.cc
+++ b/test/cpp/end2end/server_interceptors_end2end_test.cc
@@ -44,7 +44,34 @@ namespace {
class LoggingInterceptor : public experimental::Interceptor {
public:
- LoggingInterceptor(experimental::ServerRpcInfo* info) { info_ = info; }
+ LoggingInterceptor(experimental::ServerRpcInfo* info) {
+ info_ = info;
+
+ // Check the method name and compare to the type
+ const char* method = info->method();
+ experimental::ServerRpcInfo::Type type = info->type();
+
+ // Check that we use one of our standard methods with expected type.
+ // Also allow the health checking service.
+ // We accept BIDI_STREAMING for Echo in case it's an AsyncGenericService
+ // being tested (the GenericRpc test).
+ // The empty method is for the Unimplemented requests that arise
+ // when draining the CQ.
+ EXPECT_TRUE(
+ strstr(method, "/grpc.health") == method ||
+ (strcmp(method, "/grpc.testing.EchoTestService/Echo") == 0 &&
+ (type == experimental::ServerRpcInfo::Type::UNARY ||
+ type == experimental::ServerRpcInfo::Type::BIDI_STREAMING)) ||
+ (strcmp(method, "/grpc.testing.EchoTestService/RequestStream") == 0 &&
+ type == experimental::ServerRpcInfo::Type::CLIENT_STREAMING) ||
+ (strcmp(method, "/grpc.testing.EchoTestService/ResponseStream") == 0 &&
+ type == experimental::ServerRpcInfo::Type::SERVER_STREAMING) ||
+ (strcmp(method, "/grpc.testing.EchoTestService/BidiStream") == 0 &&
+ type == experimental::ServerRpcInfo::Type::BIDI_STREAMING) ||
+ strcmp(method, "/grpc.testing.EchoTestService/Unimplemented") == 0 ||
+ (strcmp(method, "") == 0 &&
+ type == experimental::ServerRpcInfo::Type::BIDI_STREAMING));
+ }
virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
if (methods->QueryInterceptionHookPoint(
@@ -577,7 +604,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc
index a53de691bc..da42178d67 100644
--- a/test/cpp/end2end/shutdown_test.cc
+++ b/test/cpp/end2end/shutdown_test.cc
@@ -164,7 +164,7 @@ TEST_P(ShutdownTest, ShutdownTest) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc
index 898d1ec118..440656588b 100644
--- a/test/cpp/end2end/streaming_throughput_test.cc
+++ b/test/cpp/end2end/streaming_throughput_test.cc
@@ -187,7 +187,7 @@ TEST_F(End2endTest, StreamingThroughput) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/end2end/test_health_check_service_impl.cc b/test/cpp/end2end/test_health_check_service_impl.cc
new file mode 100644
index 0000000000..0801e30199
--- /dev/null
+++ b/test/cpp/end2end/test_health_check_service_impl.cc
@@ -0,0 +1,97 @@
+/*
+ *
+ * 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 "test/cpp/end2end/test_health_check_service_impl.h"
+
+#include <grpc/grpc.h>
+
+using grpc::health::v1::HealthCheckRequest;
+using grpc::health::v1::HealthCheckResponse;
+
+namespace grpc {
+namespace testing {
+
+Status HealthCheckServiceImpl::Check(ServerContext* context,
+ const HealthCheckRequest* request,
+ HealthCheckResponse* response) {
+ std::lock_guard<std::mutex> lock(mu_);
+ auto iter = status_map_.find(request->service());
+ if (iter == status_map_.end()) {
+ return Status(StatusCode::NOT_FOUND, "");
+ }
+ response->set_status(iter->second);
+ return Status::OK;
+}
+
+Status HealthCheckServiceImpl::Watch(
+ ServerContext* context, const HealthCheckRequest* request,
+ ::grpc::ServerWriter<HealthCheckResponse>* writer) {
+ 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 HealthCheckServiceImpl::SetStatus(
+ const grpc::string& service_name,
+ HealthCheckResponse::ServingStatus status) {
+ std::lock_guard<std::mutex> lock(mu_);
+ if (shutdown_) {
+ status = HealthCheckResponse::NOT_SERVING;
+ }
+ status_map_[service_name] = status;
+}
+
+void HealthCheckServiceImpl::SetAll(HealthCheckResponse::ServingStatus status) {
+ std::lock_guard<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
+ for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
+ iter->second = status;
+ }
+}
+
+void HealthCheckServiceImpl::Shutdown() {
+ std::lock_guard<std::mutex> lock(mu_);
+ if (shutdown_) {
+ return;
+ }
+ shutdown_ = true;
+ for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
+ iter->second = HealthCheckResponse::NOT_SERVING;
+ }
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/end2end/test_health_check_service_impl.h b/test/cpp/end2end/test_health_check_service_impl.h
new file mode 100644
index 0000000000..5d36ce5320
--- /dev/null
+++ b/test/cpp/end2end/test_health_check_service_impl.h
@@ -0,0 +1,58 @@
+/*
+ *
+ * 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_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H
+#define GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H
+
+#include <map>
+#include <mutex>
+
+#include <grpcpp/server_context.h>
+#include <grpcpp/support/status.h>
+
+#include "src/proto/grpc/health/v1/health.grpc.pb.h"
+
+namespace grpc {
+namespace testing {
+
+// A sample sync implementation of the health checking service. This does the
+// same thing as the default one.
+class HealthCheckServiceImpl : public health::v1::Health::Service {
+ public:
+ Status Check(ServerContext* context,
+ const health::v1::HealthCheckRequest* request,
+ health::v1::HealthCheckResponse* response) override;
+ Status Watch(ServerContext* context,
+ const health::v1::HealthCheckRequest* request,
+ ServerWriter<health::v1::HealthCheckResponse>* writer) override;
+ void SetStatus(const grpc::string& service_name,
+ health::v1::HealthCheckResponse::ServingStatus status);
+ void SetAll(health::v1::HealthCheckResponse::ServingStatus status);
+
+ void Shutdown();
+
+ private:
+ std::mutex mu_;
+ bool shutdown_ = false;
+ std::map<const grpc::string, health::v1::HealthCheckResponse::ServingStatus>
+ status_map_;
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_END2END_TEST_HEALTH_CHECK_SERVICE_IMPL_H
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index 605356724f..6729ad14f4 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -69,6 +69,62 @@ void CheckServerAuthContext(
EXPECT_EQ(expected_client_identity, identity[0]);
}
}
+
+// Returns the number of pairs in metadata that exactly match the given
+// key-value pair. Returns -1 if the pair wasn't found.
+int MetadataMatchCount(
+ const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
+ const grpc::string& key, const grpc::string& value) {
+ int count = 0;
+ for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
+ metadata.begin();
+ iter != metadata.end(); ++iter) {
+ if (ToString(iter->first) == key && ToString(iter->second) == value) {
+ count++;
+ }
+ }
+ return count;
+}
+} // namespace
+
+namespace {
+int GetIntValueFromMetadataHelper(
+ const char* key,
+ const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
+ int default_value) {
+ if (metadata.find(key) != metadata.end()) {
+ std::istringstream iss(ToString(metadata.find(key)->second));
+ iss >> default_value;
+ gpr_log(GPR_INFO, "%s : %d", key, default_value);
+ }
+
+ return default_value;
+}
+
+int GetIntValueFromMetadata(
+ const char* key,
+ const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
+ int default_value) {
+ return GetIntValueFromMetadataHelper(key, metadata, default_value);
+}
+
+void ServerTryCancel(ServerContext* context) {
+ EXPECT_FALSE(context->IsCancelled());
+ context->TryCancel();
+ gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request");
+ // Now wait until it's really canceled
+ while (!context->IsCancelled()) {
+ gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_micros(1000, GPR_TIMESPAN)));
+ }
+}
+
+void ServerTryCancelNonblocking(ServerContext* context) {
+ EXPECT_FALSE(context->IsCancelled());
+ context->TryCancel();
+ gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request");
+}
+
} // namespace
Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request,
@@ -165,6 +221,18 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request,
return Status::OK;
}
+Status TestServiceImpl::CheckClientInitialMetadata(ServerContext* context,
+ const SimpleRequest* request,
+ SimpleResponse* response) {
+ EXPECT_EQ(MetadataMatchCount(context->client_metadata(),
+ kCheckClientInitialMetadataKey,
+ kCheckClientInitialMetadataVal),
+ 1);
+ EXPECT_EQ(1u,
+ context->client_metadata().count(kCheckClientInitialMetadataKey));
+ return Status::OK;
+}
+
void CallbackTestServiceImpl::Echo(
ServerContext* context, const EchoRequest* request, EchoResponse* response,
experimental::ServerCallbackRpcController* controller) {
@@ -183,6 +251,19 @@ void CallbackTestServiceImpl::Echo(
}
}
+void CallbackTestServiceImpl::CheckClientInitialMetadata(
+ ServerContext* context, const SimpleRequest* request,
+ SimpleResponse* response,
+ experimental::ServerCallbackRpcController* controller) {
+ EXPECT_EQ(MetadataMatchCount(context->client_metadata(),
+ kCheckClientInitialMetadataKey,
+ kCheckClientInitialMetadataVal),
+ 1);
+ EXPECT_EQ(1u,
+ context->client_metadata().count(kCheckClientInitialMetadataKey));
+ controller->Finish(Status::OK);
+}
+
void CallbackTestServiceImpl::EchoNonDelayed(
ServerContext* context, const EchoRequest* request, EchoResponse* response,
experimental::ServerCallbackRpcController* controller) {
@@ -195,6 +276,7 @@ void CallbackTestServiceImpl::EchoNonDelayed(
controller->Finish(Status(static_cast<StatusCode>(error.code()),
error.error_message(),
error.binary_error_details()));
+ return;
}
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
@@ -223,6 +305,7 @@ void CallbackTestServiceImpl::EchoNonDelayed(
return;
}
+ gpr_log(GPR_DEBUG, "Request message was %s", request->message().c_str());
response->set_message(request->message());
MaybeEchoDeadline(context, request, response);
if (host_) {
@@ -253,7 +336,7 @@ void CallbackTestServiceImpl::EchoNonDelayed(
alarm_.experimental().Set(
gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(request->param().client_cancel_after_us(),
+ gpr_time_from_micros(request->param().server_cancel_after_us(),
GPR_TIMESPAN)),
[controller](bool) { controller->Finish(Status::CANCELLED); });
return;
@@ -278,6 +361,7 @@ void CallbackTestServiceImpl::EchoNonDelayed(
request->param().debug_info().SerializeAsString();
context->AddTrailingMetadata(kDebugInfoTrailerKey, serialized_debug_info);
controller->Finish(Status::CANCELLED);
+ return;
}
}
if (request->has_param() &&
@@ -324,7 +408,7 @@ Status TestServiceImpl::RequestStream(ServerContext* context,
std::thread* server_try_cancel_thd = nullptr;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
- new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
+ new std::thread([context] { ServerTryCancel(context); });
}
int num_msgs_read = 0;
@@ -379,7 +463,7 @@ Status TestServiceImpl::ResponseStream(ServerContext* context,
std::thread* server_try_cancel_thd = nullptr;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
- new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
+ new std::thread([context] { ServerTryCancel(context); });
}
for (int i = 0; i < server_responses_to_send; i++) {
@@ -430,7 +514,7 @@ Status TestServiceImpl::BidiStream(
std::thread* server_try_cancel_thd = nullptr;
if (server_try_cancel == CANCEL_DURING_PROCESSING) {
server_try_cancel_thd =
- new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
+ new std::thread([context] { ServerTryCancel(context); });
}
// kServerFinishAfterNReads suggests after how many reads, the server should
@@ -464,44 +548,244 @@ Status TestServiceImpl::BidiStream(
return Status::OK;
}
-namespace {
-int GetIntValueFromMetadataHelper(
- const char* key,
- const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
- int default_value) {
- if (metadata.find(key) != metadata.end()) {
- std::istringstream iss(ToString(metadata.find(key)->second));
- iss >> default_value;
- gpr_log(GPR_INFO, "%s : %d", key, default_value);
- }
+experimental::ServerReadReactor<EchoRequest, EchoResponse>*
+CallbackTestServiceImpl::RequestStream() {
+ class Reactor : public ::grpc::experimental::ServerReadReactor<EchoRequest,
+ EchoResponse> {
+ public:
+ Reactor() {}
+ void OnStarted(ServerContext* context, EchoResponse* response) override {
+ ctx_ = context;
+ response_ = response;
+ // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by
+ // the server by calling ServerContext::TryCancel() depending on the
+ // value:
+ // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server
+ // reads any message from the client CANCEL_DURING_PROCESSING: The RPC
+ // is cancelled while the server is reading messages from the client
+ // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads
+ // all the messages from the client
+ server_try_cancel_ = GetIntValueFromMetadata(
+ kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
+
+ response_->set_message("");
+
+ if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) {
+ ServerTryCancelNonblocking(ctx_);
+ return;
+ }
- return default_value;
-}
-}; // namespace
+ if (server_try_cancel_ == CANCEL_DURING_PROCESSING) {
+ ctx_->TryCancel();
+ // Don't wait for it here
+ }
-int TestServiceImpl::GetIntValueFromMetadata(
- const char* key,
- const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
- int default_value) {
- return GetIntValueFromMetadataHelper(key, metadata, default_value);
+ StartRead(&request_);
+ }
+ void OnDone() override { delete this; }
+ void OnCancel() override { FinishOnce(Status::CANCELLED); }
+ void OnReadDone(bool ok) override {
+ if (ok) {
+ response_->mutable_message()->append(request_.message());
+ num_msgs_read_++;
+ StartRead(&request_);
+ } else {
+ gpr_log(GPR_INFO, "Read: %d messages", num_msgs_read_);
+
+ if (server_try_cancel_ == CANCEL_DURING_PROCESSING) {
+ // Let OnCancel recover this
+ return;
+ }
+ if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) {
+ ServerTryCancelNonblocking(ctx_);
+ return;
+ }
+ FinishOnce(Status::OK);
+ }
+ }
+
+ private:
+ void FinishOnce(const Status& s) {
+ std::lock_guard<std::mutex> l(finish_mu_);
+ if (!finished_) {
+ Finish(s);
+ finished_ = true;
+ }
+ }
+
+ ServerContext* ctx_;
+ EchoResponse* response_;
+ EchoRequest request_;
+ int num_msgs_read_{0};
+ int server_try_cancel_;
+ std::mutex finish_mu_;
+ bool finished_{false};
+ };
+
+ return new Reactor;
}
-int CallbackTestServiceImpl::GetIntValueFromMetadata(
- const char* key,
- const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
- int default_value) {
- return GetIntValueFromMetadataHelper(key, metadata, default_value);
+// Return 'kNumResponseStreamMsgs' messages.
+// TODO(yangg) make it generic by adding a parameter into EchoRequest
+experimental::ServerWriteReactor<EchoRequest, EchoResponse>*
+CallbackTestServiceImpl::ResponseStream() {
+ class Reactor
+ : public ::grpc::experimental::ServerWriteReactor<EchoRequest,
+ EchoResponse> {
+ public:
+ Reactor() {}
+ void OnStarted(ServerContext* context,
+ const EchoRequest* request) override {
+ ctx_ = context;
+ request_ = request;
+ // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by
+ // the server by calling ServerContext::TryCancel() depending on the
+ // value:
+ // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server
+ // reads any message from the client CANCEL_DURING_PROCESSING: The RPC
+ // is cancelled while the server is reading messages from the client
+ // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads
+ // all the messages from the client
+ server_try_cancel_ = GetIntValueFromMetadata(
+ kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
+ server_coalescing_api_ = GetIntValueFromMetadata(
+ kServerUseCoalescingApi, context->client_metadata(), 0);
+ server_responses_to_send_ = GetIntValueFromMetadata(
+ kServerResponseStreamsToSend, context->client_metadata(),
+ kServerDefaultResponseStreamsToSend);
+ if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) {
+ ServerTryCancelNonblocking(ctx_);
+ return;
+ }
+
+ if (server_try_cancel_ == CANCEL_DURING_PROCESSING) {
+ ctx_->TryCancel();
+ }
+ if (num_msgs_sent_ < server_responses_to_send_) {
+ NextWrite();
+ }
+ }
+ void OnDone() override { delete this; }
+ void OnCancel() override { FinishOnce(Status::CANCELLED); }
+ void OnWriteDone(bool ok) override {
+ if (num_msgs_sent_ < server_responses_to_send_) {
+ NextWrite();
+ } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) {
+ // Let OnCancel recover this
+ } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) {
+ ServerTryCancelNonblocking(ctx_);
+ } else {
+ FinishOnce(Status::OK);
+ }
+ }
+
+ private:
+ void FinishOnce(const Status& s) {
+ std::lock_guard<std::mutex> l(finish_mu_);
+ if (!finished_) {
+ Finish(s);
+ finished_ = true;
+ }
+ }
+
+ void NextWrite() {
+ response_.set_message(request_->message() +
+ grpc::to_string(num_msgs_sent_));
+ if (num_msgs_sent_ == server_responses_to_send_ - 1 &&
+ server_coalescing_api_ != 0) {
+ num_msgs_sent_++;
+ StartWriteLast(&response_, WriteOptions());
+ } else {
+ num_msgs_sent_++;
+ StartWrite(&response_);
+ }
+ }
+ ServerContext* ctx_;
+ const EchoRequest* request_;
+ EchoResponse response_;
+ int num_msgs_sent_{0};
+ int server_try_cancel_;
+ int server_coalescing_api_;
+ int server_responses_to_send_;
+ std::mutex finish_mu_;
+ bool finished_{false};
+ };
+ return new Reactor;
}
-void TestServiceImpl::ServerTryCancel(ServerContext* context) {
- EXPECT_FALSE(context->IsCancelled());
- context->TryCancel();
- gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request");
- // Now wait until it's really canceled
- while (!context->IsCancelled()) {
- gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_micros(1000, GPR_TIMESPAN)));
- }
+experimental::ServerBidiReactor<EchoRequest, EchoResponse>*
+CallbackTestServiceImpl::BidiStream() {
+ class Reactor : public ::grpc::experimental::ServerBidiReactor<EchoRequest,
+ EchoResponse> {
+ public:
+ Reactor() {}
+ void OnStarted(ServerContext* context) override {
+ ctx_ = context;
+ // If 'server_try_cancel' is set in the metadata, the RPC is cancelled by
+ // the server by calling ServerContext::TryCancel() depending on the
+ // value:
+ // CANCEL_BEFORE_PROCESSING: The RPC is cancelled before the server
+ // reads any message from the client CANCEL_DURING_PROCESSING: The RPC
+ // is cancelled while the server is reading messages from the client
+ // CANCEL_AFTER_PROCESSING: The RPC is cancelled after the server reads
+ // all the messages from the client
+ server_try_cancel_ = GetIntValueFromMetadata(
+ kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
+ server_write_last_ = GetIntValueFromMetadata(
+ kServerFinishAfterNReads, context->client_metadata(), 0);
+ if (server_try_cancel_ == CANCEL_BEFORE_PROCESSING) {
+ ServerTryCancelNonblocking(ctx_);
+ return;
+ }
+
+ if (server_try_cancel_ == CANCEL_DURING_PROCESSING) {
+ ctx_->TryCancel();
+ }
+
+ StartRead(&request_);
+ }
+ void OnDone() override { delete this; }
+ void OnCancel() override { FinishOnce(Status::CANCELLED); }
+ void OnReadDone(bool ok) override {
+ if (ok) {
+ num_msgs_read_++;
+ gpr_log(GPR_INFO, "recv msg %s", request_.message().c_str());
+ response_.set_message(request_.message());
+ if (num_msgs_read_ == server_write_last_) {
+ StartWriteLast(&response_, WriteOptions());
+ } else {
+ StartWrite(&response_);
+ }
+ } else if (server_try_cancel_ == CANCEL_DURING_PROCESSING) {
+ // Let OnCancel handle this
+ } else if (server_try_cancel_ == CANCEL_AFTER_PROCESSING) {
+ ServerTryCancelNonblocking(ctx_);
+ } else {
+ FinishOnce(Status::OK);
+ }
+ }
+ void OnWriteDone(bool ok) override { StartRead(&request_); }
+
+ private:
+ void FinishOnce(const Status& s) {
+ std::lock_guard<std::mutex> l(finish_mu_);
+ if (!finished_) {
+ Finish(s);
+ finished_ = true;
+ }
+ }
+
+ ServerContext* ctx_;
+ EchoRequest request_;
+ EchoResponse response_;
+ int num_msgs_read_{0};
+ int server_try_cancel_;
+ int server_write_last_;
+ std::mutex finish_mu_;
+ bool finished_{false};
+ };
+
+ return new Reactor;
}
} // namespace testing
diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h
index ddfe94487e..e36423d44e 100644
--- a/test/cpp/end2end/test_service_impl.h
+++ b/test/cpp/end2end/test_service_impl.h
@@ -36,6 +36,8 @@ const char* const kServerTryCancelRequest = "server_try_cancel";
const char* const kDebugInfoTrailerKey = "debug-info-bin";
const char* const kServerFinishAfterNReads = "server_finish_after_n_reads";
const char* const kServerUseCoalescingApi = "server_use_coalescing_api";
+const char* const kCheckClientInitialMetadataKey = "custom_client_metadata";
+const char* const kCheckClientInitialMetadataVal = "Value for client metadata";
typedef enum {
DO_NOT_CANCEL = 0,
@@ -53,6 +55,10 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
Status Echo(ServerContext* context, const EchoRequest* request,
EchoResponse* response) override;
+ Status CheckClientInitialMetadata(ServerContext* context,
+ const SimpleRequest* request,
+ SimpleResponse* response) override;
+
// Unimplemented is left unimplemented to test the returned error.
Status RequestStream(ServerContext* context,
@@ -72,13 +78,6 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
}
private:
- int GetIntValueFromMetadata(
- const char* key,
- const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
- int default_value);
-
- void ServerTryCancel(ServerContext* context);
-
bool signal_client_;
std::mutex mu_;
std::unique_ptr<grpc::string> host_;
@@ -95,6 +94,20 @@ class CallbackTestServiceImpl
EchoResponse* response,
experimental::ServerCallbackRpcController* controller) override;
+ void CheckClientInitialMetadata(
+ ServerContext* context, const SimpleRequest* request,
+ SimpleResponse* response,
+ experimental::ServerCallbackRpcController* controller) override;
+
+ experimental::ServerReadReactor<EchoRequest, EchoResponse>* RequestStream()
+ override;
+
+ experimental::ServerWriteReactor<EchoRequest, EchoResponse>* ResponseStream()
+ override;
+
+ experimental::ServerBidiReactor<EchoRequest, EchoResponse>* BidiStream()
+ override;
+
// Unimplemented is left unimplemented to test the returned error.
bool signal_client() {
std::unique_lock<std::mutex> lock(mu_);
@@ -106,11 +119,6 @@ class CallbackTestServiceImpl
EchoResponse* response,
experimental::ServerCallbackRpcController* controller);
- int GetIntValueFromMetadata(
- const char* key,
- const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
- int default_value);
-
Alarm alarm_;
bool signal_client_;
std::mutex mu_;
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index 1a5ed28a2c..e30ce0dbcb 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -429,7 +429,7 @@ TYPED_TEST(AsyncClientEnd2endTest, ThreadStress) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc
index 664504a090..7339402830 100644
--- a/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc
+++ b/test/cpp/ext/filters/census/stats_plugin_end2end_test.cc
@@ -370,7 +370,7 @@ TEST_F(StatsPluginEnd2EndTest, RequestReceivedMessagesPerRpc) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD
index 097e92f583..93ed962a00 100644
--- a/test/cpp/microbenchmarks/BUILD
+++ b/test/cpp/microbenchmarks/BUILD
@@ -62,6 +62,13 @@ grpc_cc_binary(
)
grpc_cc_binary(
+ name = "bm_byte_buffer",
+ testonly = 1,
+ srcs = ["bm_byte_buffer.cc"],
+ deps = [":helpers"],
+)
+
+grpc_cc_binary(
name = "bm_channel",
testonly = 1,
srcs = ["bm_channel.cc"],
diff --git a/test/cpp/microbenchmarks/bm_byte_buffer.cc b/test/cpp/microbenchmarks/bm_byte_buffer.cc
new file mode 100644
index 0000000000..a359e6f621
--- /dev/null
+++ b/test/cpp/microbenchmarks/bm_byte_buffer.cc
@@ -0,0 +1,65 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* This benchmark exists to show that byte-buffer copy is size-independent */
+
+#include <memory>
+
+#include <benchmark/benchmark.h>
+#include <grpcpp/impl/grpc_library.h>
+#include <grpcpp/support/byte_buffer.h>
+#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
+
+namespace grpc {
+namespace testing {
+
+auto& force_library_initialization = Library::get();
+
+static void BM_ByteBuffer_Copy(benchmark::State& state) {
+ int num_slices = state.range(0);
+ size_t slice_size = state.range(1);
+ std::vector<grpc::Slice> slices;
+ while (num_slices > 0) {
+ num_slices--;
+ std::unique_ptr<char[]> buf(new char[slice_size]);
+ memset(buf.get(), 0, slice_size);
+ slices.emplace_back(buf.get(), slice_size);
+ }
+ grpc::ByteBuffer bb(slices.data(), num_slices);
+ while (state.KeepRunning()) {
+ grpc::ByteBuffer cc(bb);
+ }
+}
+BENCHMARK(BM_ByteBuffer_Copy)->Ranges({{1, 64}, {1, 1024 * 1024}});
+
+} // namespace testing
+} // namespace grpc
+
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index 446dc93edb..8d12606434 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -135,7 +135,8 @@ static void BM_LameChannelCallCreateCpp(benchmark::State& state) {
"",
grpc_lame_client_channel_create("localhost:1234",
GRPC_STATUS_UNAUTHENTICATED, "blah"),
- nullptr));
+ std::vector<std::unique_ptr<
+ grpc::experimental::ClientInterceptorFactoryInterface>>()));
grpc::CompletionQueue cq;
grpc::testing::EchoRequest send_request;
grpc::testing::EchoResponse recv_response;
diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
index f7ae16e61d..650152ecc0 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
@@ -54,7 +54,8 @@ class DummyEndpoint : public grpc_endpoint {
destroy,
get_resource_user,
get_peer,
- get_fd};
+ get_fd,
+ can_track_err};
grpc_endpoint::vtable = &my_vtable;
ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint");
}
@@ -125,6 +126,7 @@ class DummyEndpoint : public grpc_endpoint {
}
static char* get_peer(grpc_endpoint* ep) { return gpr_strdup("test"); }
static int get_fd(grpc_endpoint* ep) { return 0; }
+ static bool can_track_err(grpc_endpoint* ep) { return false; }
};
class Fixture {
diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
index 85767c8758..dca97c85b1 100644
--- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
+++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
@@ -94,6 +94,7 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) {
g_vtable.pollset_destroy = pollset_destroy;
g_vtable.pollset_work = pollset_work;
g_vtable.pollset_kick = pollset_kick;
+ g_vtable.shutdown_background_closure = [] {};
g_vtable.shutdown_engine = [] {};
return &g_vtable;
diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h
index e57eb6ddd1..6bbf553bbd 100644
--- a/test/cpp/microbenchmarks/fullstack_fixtures.h
+++ b/test/cpp/microbenchmarks/fullstack_fixtures.h
@@ -200,7 +200,7 @@ class EndpointPairFixture : public BaseFixture {
}
grpc_server_setup_transport(server_->c_server(), server_transport_,
- nullptr, server_args, 0);
+ nullptr, server_args, nullptr);
grpc_chttp2_transport_start_reading(server_transport_, nullptr, nullptr);
}
@@ -218,7 +218,10 @@ class EndpointPairFixture : public BaseFixture {
"target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_);
grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr);
- channel_ = CreateChannelInternal("", channel, nullptr);
+ channel_ = CreateChannelInternal(
+ "", channel,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
}
diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc
index fc6721d0ba..09e705df78 100644
--- a/test/cpp/naming/address_sorting_test.cc
+++ b/test/cpp/naming/address_sorting_test.cc
@@ -37,6 +37,7 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
@@ -167,30 +168,26 @@ void OverrideAddressSortingSourceAddrFactory(
address_sorting_override_source_addr_factory_for_testing(factory);
}
-grpc_lb_addresses* BuildLbAddrInputs(std::vector<TestAddress> test_addrs) {
- grpc_lb_addresses* lb_addrs = grpc_lb_addresses_create(0, nullptr);
- lb_addrs->addresses =
- (grpc_lb_address*)gpr_zalloc(sizeof(grpc_lb_address) * test_addrs.size());
- lb_addrs->num_addresses = test_addrs.size();
- for (size_t i = 0; i < test_addrs.size(); i++) {
- lb_addrs->addresses[i].address =
- TestAddressToGrpcResolvedAddress(test_addrs[i]);
+grpc_core::ServerAddressList BuildLbAddrInputs(
+ const std::vector<TestAddress>& test_addrs) {
+ grpc_core::ServerAddressList addresses;
+ for (const auto& addr : test_addrs) {
+ addresses.emplace_back(TestAddressToGrpcResolvedAddress(addr), nullptr);
}
- return lb_addrs;
+ return addresses;
}
-void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs,
+void VerifyLbAddrOutputs(const grpc_core::ServerAddressList addresses,
std::vector<std::string> expected_addrs) {
- EXPECT_EQ(lb_addrs->num_addresses, expected_addrs.size());
- for (size_t i = 0; i < lb_addrs->num_addresses; i++) {
+ EXPECT_EQ(addresses.size(), expected_addrs.size());
+ for (size_t i = 0; i < addresses.size(); ++i) {
char* ip_addr_str;
- grpc_sockaddr_to_string(&ip_addr_str, &lb_addrs->addresses[i].address,
+ grpc_sockaddr_to_string(&ip_addr_str, &addresses[i].address(),
false /* normalize */);
EXPECT_EQ(expected_addrs[i], ip_addr_str);
gpr_free(ip_addr_str);
}
grpc_core::ExecCtx exec_ctx;
- grpc_lb_addresses_destroy(lb_addrs);
}
/* We need to run each test case inside of its own
@@ -212,11 +209,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
{
{"1.2.3.4:443", {"4.3.2.1:443", AF_INET}},
});
- auto* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"1.2.3.4:443", AF_INET},
{"5.6.7.8:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"1.2.3.4:443",
"5.6.7.8:443",
@@ -235,7 +232,7 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
{"[2607:f8b0:400a:801::1002]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"1.2.3.4:443",
"[2607:f8b0:400a:801::1002]:443",
@@ -251,11 +248,11 @@ TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
{"1.2.3.4:443", {"4.3.2.1:0", AF_INET}},
{"[2607:f8b0:400a:801::1002]:443", {"[fec0::1234]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2607:f8b0:400a:801::1002]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2607:f8b0:400a:801::1002]:443",
"1.2.3.4:443",
@@ -275,11 +272,11 @@ TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
{"[fec0::5000]:443",
{"[fec0::5001]:0", AF_INET6}}, // site-local and site-local scope
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2000:f8b0:400a:801::1002]:443", AF_INET6},
{"[fec0::5000]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[fec0::5000]:443",
"[2000:f8b0:400a:801::1002]:443",
@@ -298,11 +295,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
{"[2001::5001]:443",
{"[2001::5002]:0", AF_INET6}}, // matching labels
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2002::5001]:443", AF_INET6},
{"[2001::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2001::5001]:443",
"[2002::5001]:443",
@@ -321,11 +318,11 @@ TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
{"[2001::5001]:443",
{"[2001::5002]:0", AF_INET6}}, // matching labels
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2001::5001]:443", AF_INET6},
{"[2002::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2001::5001]:443",
"[2002::5001]:443",
@@ -344,11 +341,11 @@ TEST_F(AddressSortingTest,
{"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
{"1.2.3.4:443", {"5.6.7.8:0", AF_INET}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::5001]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(
lb_addrs, {
// The AF_INET address should be IPv4-mapped by the sort,
@@ -377,11 +374,11 @@ TEST_F(AddressSortingTest,
{"[::1]:443", {"[::1]:0", AF_INET6}},
{v4_compat_dest, {v4_compat_src, AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{v4_compat_dest, AF_INET6},
{"[::1]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
v4_compat_dest,
@@ -400,11 +397,11 @@ TEST_F(AddressSortingTest,
{"[1234::2]:443", {"[1234::2]:0", AF_INET6}},
{"[::1]:443", {"[::1]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[1234::2]:443", AF_INET6},
{"[::1]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(
lb_addrs,
{
@@ -424,11 +421,11 @@ TEST_F(AddressSortingTest,
{"[2001::1234]:443", {"[2001::5678]:0", AF_INET6}},
{"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2001::1234]:443", AF_INET6},
{"[2000::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(
lb_addrs, {
// The 2000::/16 address should match the ::/0 prefix rule
@@ -448,11 +445,11 @@ TEST_F(
{"[2001::1231]:443", {"[2001::1232]:0", AF_INET6}},
{"[2000::5001]:443", {"[2000::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[2001::1231]:443", AF_INET6},
{"[2000::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[2000::5001]:443",
"[2001::1231]:443",
@@ -469,11 +466,11 @@ TEST_F(AddressSortingTest,
{"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
{"[fc00::5001]:443", {"[fc00::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[fec0::1234]:443", AF_INET6},
{"[fc00::5001]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[fc00::5001]:443",
"[fec0::1234]:443",
@@ -494,11 +491,11 @@ TEST_F(
{"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
{"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[::ffff:1.1.1.2]:443", AF_INET6},
{"[1234::2]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
// ::ffff:0:2 should match the v4-mapped
// precedence entry and be deprioritized.
@@ -521,11 +518,11 @@ TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
{"[fec0::1234]:443", {"[fec0::5678]:0", AF_INET6}},
{"[3ffe::5001]:443", {"[3ffe::5002]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::5001]:443", AF_INET6},
{"[fec0::1234]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[fec0::1234]:443",
"[3ffe::5001]:443",
@@ -546,11 +543,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
{"[3ffe:1234::]:443", {"[3ffe:1235::]:0", AF_INET6}},
{"[3ffe:5001::]:443", {"[3ffe:4321::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:5001::]:443", AF_INET6},
{"[3ffe:1234::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:1234::]:443",
"[3ffe:5001::]:443",
@@ -567,11 +564,11 @@ TEST_F(AddressSortingTest,
{"[3ffe::1234]:443", {"[3ffe::1235]:0", AF_INET6}},
{"[3ffe::5001]:443", {"[3ffe::4321]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::5001]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1234]:443",
"[3ffe::5001]:443",
@@ -587,11 +584,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
{"[3ffe:8000::]:443", {"[3ffe:C000::]:0", AF_INET6}},
{"[3ffe:2000::]:443", {"[3ffe:3000::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:8000::]:443", AF_INET6},
{"[3ffe:2000::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:2000::]:443",
"[3ffe:8000::]:443",
@@ -607,11 +604,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
{"[3ffe:6::]:443", {"[3ffe:8::]:0", AF_INET6}},
{"[3ffe:c::]:443", {"[3ffe:8::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:6::]:443", AF_INET6},
{"[3ffe:c::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:c::]:443",
"[3ffe:6::]:443",
@@ -629,11 +626,11 @@ TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
{"[3ffe:1111:1111:1110::]:443",
{"[3ffe:1111:1111:1111::]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe:1111:1111:1110::]:443", AF_INET6},
{"[3ffe:1111:1111:1111::]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe:1111:1111:1111::]:443",
"[3ffe:1111:1111:1110::]:443",
@@ -651,11 +648,11 @@ TEST_F(AddressSortingTest, TestStableSort) {
{"[3ffe::1234]:443", {"[3ffe::1236]:0", AF_INET6}},
{"[3ffe::1235]:443", {"[3ffe::1237]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1234]:443",
"[3ffe::1235]:443",
@@ -674,14 +671,14 @@ TEST_F(AddressSortingTest, TestStableSortFiveElements) {
{"[3ffe::1234]:443", {"[3ffe::1204]:0", AF_INET6}},
{"[3ffe::1235]:443", {"[3ffe::1205]:0", AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::1231]:443", AF_INET6},
{"[3ffe::1232]:443", AF_INET6},
{"[3ffe::1233]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1231]:443",
"[3ffe::1232]:443",
@@ -695,14 +692,14 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[3ffe::1231]:443", AF_INET6},
{"[3ffe::1232]:443", AF_INET6},
{"[3ffe::1233]:443", AF_INET6},
{"[3ffe::1234]:443", AF_INET6},
{"[3ffe::1235]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[3ffe::1231]:443",
"[3ffe::1232]:443",
@@ -716,11 +713,11 @@ TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[::ffff:5.6.7.8]:443", AF_INET6},
{"1.2.3.4:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::ffff:5.6.7.8]:443",
"1.2.3.4:443",
@@ -744,11 +741,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
{"[fec0::2000]:443", {"[fec0::2001]:0", AF_INET6}},
{v4_compat_dest, {v4_compat_src, AF_INET6}},
});
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[fec0::2000]:443", AF_INET6},
{v4_compat_dest, AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs,
{
// The sort should be stable since
@@ -765,11 +762,11 @@ TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
* (whether ipv4 loopback is available or not, an available ipv6
* loopback should be preferred). */
TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"[::1]:443", AF_INET6},
{"127.0.0.1:443", AF_INET},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
"127.0.0.1:443",
@@ -779,11 +776,11 @@ TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
/* Flip the order of the inputs above and expect the same output order
* (try to rule out influence of arbitrary qsort ordering) */
TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
- grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ auto lb_addrs = BuildLbAddrInputs({
{"127.0.0.1:443", AF_INET},
{"[::1]:443", AF_INET6},
});
- grpc_cares_wrapper_address_sorting_sort(lb_addrs);
+ grpc_cares_wrapper_address_sorting_sort(&lb_addrs);
VerifyLbAddrOutputs(lb_addrs, {
"[::1]:443",
"127.0.0.1:443",
@@ -838,7 +835,7 @@ int main(int argc, char** argv) {
gpr_log(GPR_INFO, "GRPC_DNS_RESOLVER != ares: %s.", resolver);
}
gpr_free(resolver);
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
auto result = RUN_ALL_TESTS();
// Test sequential and nested inits and shutdowns.
diff --git a/test/cpp/naming/cancel_ares_query_test.cc b/test/cpp/naming/cancel_ares_query_test.cc
index dec7c171dc..3e789f0b14 100644
--- a/test/cpp/naming/cancel_ares_query_test.cc
+++ b/test/cpp/naming/cancel_ares_query_test.cc
@@ -260,8 +260,15 @@ TEST(CancelDuringAresQuery, TestFdsAreDeletedFromPollsetSet) {
grpc_pollset_set_destroy(fake_other_pollset_set);
}
-TEST(CancelDuringAresQuery,
- TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) {
+// Settings for TestCancelDuringActiveQuery test
+typedef enum {
+ NONE,
+ SHORT,
+ ZERO,
+} cancellation_test_query_timeout_setting;
+
+void TestCancelDuringActiveQuery(
+ cancellation_test_query_timeout_setting query_timeout_setting) {
// Start up fake non responsive DNS server
int fake_dns_port = grpc_pick_unused_port_or_die();
FakeNonResponsiveDNSServer fake_dns_server(fake_dns_port);
@@ -271,9 +278,33 @@ TEST(CancelDuringAresQuery,
&client_target,
"dns://[::1]:%d/dont-care-since-wont-be-resolved.test.com:1234",
fake_dns_port));
+ gpr_log(GPR_DEBUG, "TestCancelActiveDNSQuery. query timeout setting: %d",
+ query_timeout_setting);
+ grpc_channel_args* client_args = nullptr;
+ grpc_status_code expected_status_code = GRPC_STATUS_OK;
+ if (query_timeout_setting == NONE) {
+ expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED;
+ client_args = nullptr;
+ } else if (query_timeout_setting == SHORT) {
+ expected_status_code = GRPC_STATUS_UNAVAILABLE;
+ grpc_arg arg;
+ arg.type = GRPC_ARG_INTEGER;
+ arg.key = const_cast<char*>(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS);
+ arg.value.integer =
+ 1; // Set this shorter than the call deadline so that it goes off.
+ client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
+ } else if (query_timeout_setting == ZERO) {
+ expected_status_code = GRPC_STATUS_DEADLINE_EXCEEDED;
+ grpc_arg arg;
+ arg.type = GRPC_ARG_INTEGER;
+ arg.key = const_cast<char*>(GRPC_ARG_DNS_ARES_QUERY_TIMEOUT_MS);
+ arg.value.integer = 0; // Set this to zero to disable query timeouts.
+ client_args = grpc_channel_args_copy_and_add(nullptr, &arg, 1);
+ } else {
+ abort();
+ }
grpc_channel* client =
- grpc_insecure_channel_create(client_target,
- /* client_args */ nullptr, nullptr);
+ grpc_insecure_channel_create(client_target, client_args, nullptr);
gpr_free(client_target);
grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr);
cq_verifier* cqv = cq_verifier_create(cq);
@@ -325,8 +356,9 @@ TEST(CancelDuringAresQuery,
EXPECT_EQ(GRPC_CALL_OK, error);
CQ_EXPECT_COMPLETION(cqv, Tag(1), 1);
cq_verify(cqv);
- EXPECT_EQ(status, GRPC_STATUS_DEADLINE_EXCEEDED);
+ EXPECT_EQ(status, expected_status_code);
// Teardown
+ grpc_channel_args_destroy(client_args);
grpc_slice_unref(details);
gpr_free((void*)error_string);
grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -338,10 +370,27 @@ TEST(CancelDuringAresQuery,
EndTest(client, cq);
}
+TEST(CancelDuringAresQuery,
+ TestHitDeadlineAndDestroyChannelDuringAresResolutionIsGraceful) {
+ TestCancelDuringActiveQuery(NONE /* don't set query timeouts */);
+}
+
+TEST(
+ CancelDuringAresQuery,
+ TestHitDeadlineAndDestroyChannelDuringAresResolutionWithQueryTimeoutIsGraceful) {
+ TestCancelDuringActiveQuery(SHORT /* set short query timeout */);
+}
+
+TEST(
+ CancelDuringAresQuery,
+ TestHitDeadlineAndDestroyChannelDuringAresResolutionWithZeroQueryTimeoutIsGraceful) {
+ TestCancelDuringActiveQuery(ZERO /* disable query timeouts */);
+}
+
} // namespace
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
gpr_setenv("GRPC_DNS_RESOLVER", "ares");
// Sanity check the time that it takes to run the test
diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc
index 3dc6e7178c..2ac2c237ce 100644
--- a/test/cpp/naming/resolver_component_test.cc
+++ b/test/cpp/naming/resolver_component_test.cc
@@ -41,6 +41,7 @@
#include "src/core/ext/filters/client_channel/resolver.h"
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/server_address.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/host_port.h"
@@ -382,23 +383,19 @@ void CheckResolverResultLocked(void* argsp, grpc_error* err) {
EXPECT_EQ(err, GRPC_ERROR_NONE);
ArgsStruct* args = (ArgsStruct*)argsp;
grpc_channel_args* channel_args = args->channel_args;
- const grpc_arg* channel_arg =
- grpc_channel_args_find(channel_args, GRPC_ARG_LB_ADDRESSES);
- GPR_ASSERT(channel_arg != nullptr);
- GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
- grpc_lb_addresses* addresses =
- (grpc_lb_addresses*)channel_arg->value.pointer.p;
+ grpc_core::ServerAddressList* addresses =
+ grpc_core::FindServerAddressListChannelArg(channel_args);
gpr_log(GPR_INFO, "num addrs found: %" PRIdPTR ". expected %" PRIdPTR,
- addresses->num_addresses, args->expected_addrs.size());
- GPR_ASSERT(addresses->num_addresses == args->expected_addrs.size());
+ addresses->size(), args->expected_addrs.size());
+ GPR_ASSERT(addresses->size() == args->expected_addrs.size());
std::vector<GrpcLBAddress> found_lb_addrs;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- grpc_lb_address addr = addresses->addresses[i];
+ for (size_t i = 0; i < addresses->size(); i++) {
+ grpc_core::ServerAddress& addr = (*addresses)[i];
char* str;
- grpc_sockaddr_to_string(&str, &addr.address, 1 /* normalize */);
+ grpc_sockaddr_to_string(&str, &addr.address(), 1 /* normalize */);
gpr_log(GPR_INFO, "%s", str);
found_lb_addrs.emplace_back(
- GrpcLBAddress(std::string(str), addr.is_balancer));
+ GrpcLBAddress(std::string(str), addr.IsBalancer()));
gpr_free(str);
}
if (args->expected_addrs.size() != found_lb_addrs.size()) {
@@ -477,7 +474,7 @@ TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) {
int main(int argc, char** argv) {
grpc_init();
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
ParseCommandLineFlags(&argc, &argv, true);
if (FLAGS_target_name == "") {
diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc
index 32eab1fc44..7b22f23cf0 100644
--- a/test/cpp/performance/writes_per_rpc_test.cc
+++ b/test/cpp/performance/writes_per_rpc_test.cc
@@ -100,7 +100,7 @@ class EndpointPairFixture {
}
grpc_server_setup_transport(server_->c_server(), transport, nullptr,
- server_args, 0);
+ server_args, nullptr);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
}
@@ -118,7 +118,10 @@ class EndpointPairFixture {
"target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
- channel_ = CreateChannelInternal("", channel, nullptr);
+ channel_ = CreateChannelInternal(
+ "", channel,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
}
@@ -252,7 +255,7 @@ TEST(WritesPerRpcTest, UnaryPingPong) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
index 26f43284a6..626ac5f3f2 100644
--- a/test/cpp/qps/BUILD
+++ b/test/cpp/qps/BUILD
@@ -170,7 +170,7 @@ grpc_cc_test(
grpc_cc_test(
name = "qps_openloop_test",
srcs = ["qps_openloop_test.cc"],
- data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
+ exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
deps = [
":benchmark_config",
":driver_impl",
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 11cfb4aa05..181e11f12b 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -95,6 +95,17 @@ static deque<string> get_workers(const string& env_name) {
return out;
}
+std::string GetCredType(
+ const std::string& worker_addr,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ const std::string& credential_type) {
+ auto it = per_worker_credential_types.find(worker_addr);
+ if (it != per_worker_credential_types.end()) {
+ return it->second;
+ }
+ return credential_type;
+}
+
// helpers for postprocess_scenario_result
static double WallTime(const ClientStats& s) { return s.time_elapsed(); }
static double SystemTime(const ClientStats& s) { return s.time_system(); }
@@ -198,8 +209,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
const ServerConfig& initial_server_config, size_t num_servers,
int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
const grpc::string& qps_server_target_override,
- const grpc::string& credential_type, bool run_inproc,
- int32_t median_latency_collection_interval_millis) {
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool run_inproc, int32_t median_latency_collection_interval_millis) {
if (run_inproc) {
g_inproc_servers = new std::vector<grpc::testing::Server*>;
}
@@ -278,7 +290,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
if (!run_inproc) {
servers[i].stub = WorkerService::NewStub(CreateChannel(
workers[i], GetCredentialsProvider()->GetChannelCredentials(
- credential_type, &channel_args)));
+ GetCredType(workers[i], per_worker_credential_types,
+ credential_type),
+ &channel_args)));
} else {
servers[i].stub = WorkerService::NewStub(
local_workers[i]->InProcessChannel(channel_args));
@@ -335,9 +349,11 @@ std::unique_ptr<ScenarioResult> RunScenario(
gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
worker.c_str(), i + num_servers);
if (!run_inproc) {
- clients[i].stub = WorkerService::NewStub(
- CreateChannel(worker, GetCredentialsProvider()->GetChannelCredentials(
- credential_type, &channel_args)));
+ clients[i].stub = WorkerService::NewStub(CreateChannel(
+ worker,
+ GetCredentialsProvider()->GetChannelCredentials(
+ GetCredType(worker, per_worker_credential_types, credential_type),
+ &channel_args)));
} else {
clients[i].stub = WorkerService::NewStub(
local_workers[i + num_servers]->InProcessChannel(channel_args));
@@ -529,7 +545,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
return result;
}
-bool RunQuit(const grpc::string& credential_type) {
+bool RunQuit(
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types) {
// Get client, server lists
bool result = true;
auto workers = get_workers("QPS_WORKERS");
@@ -541,7 +559,9 @@ bool RunQuit(const grpc::string& credential_type) {
for (size_t i = 0; i < workers.size(); i++) {
auto stub = WorkerService::NewStub(CreateChannel(
workers[i], GetCredentialsProvider()->GetChannelCredentials(
- credential_type, &channel_args)));
+ GetCredType(workers[i], per_worker_credential_types,
+ credential_type),
+ &channel_args)));
Void dummy;
grpc::ClientContext ctx;
ctx.set_wait_for_ready(true);
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index cda89f7ddf..568871d2da 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -32,10 +32,13 @@ std::unique_ptr<ScenarioResult> RunScenario(
const grpc::testing::ServerConfig& server_config, size_t num_servers,
int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
const grpc::string& qps_server_target_override,
- const grpc::string& credential_type, bool run_inproc,
- int32_t median_latency_collection_interval_millis);
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool run_inproc, int32_t median_latency_collection_interval_millis);
-bool RunQuit(const grpc::string& credential_type);
+bool RunQuit(
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types);
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc
index 56d1730252..6257e42ebf 100644
--- a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc
@@ -48,7 +48,7 @@ static void RunSynchronousUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "",
- kInsecureCredentialsType, true, 0);
+ kInsecureCredentialsType, {}, true, 0);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index eaa0dd992c..1d67e79b86 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -65,6 +65,16 @@ DEFINE_string(json_file_out, "", "File to write the JSON output to.");
DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType,
"Credential type for communication with workers");
+DEFINE_string(
+ per_worker_credential_types, "",
+ "A map of QPS worker addresses to credential types. When creating a "
+ "channel to a QPS worker's driver port, the qps_json_driver first checks "
+ "if the 'name:port' string is in the map, and it uses the corresponding "
+ "credential type if so. If the QPS worker's 'name:port' string is not "
+ "in the map, then the driver -> worker channel will be created with "
+ "the credentials specified in --credential_type. The value of this flag "
+ "is a semicolon-separated list of map entries, where each map entry is "
+ "a comma-separated pair.");
DEFINE_bool(run_inproc, false, "Perform an in-process transport test");
DEFINE_int32(
median_latency_collection_interval_millis, 0,
@@ -75,16 +85,53 @@ DEFINE_int32(
namespace grpc {
namespace testing {
-static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
- bool* success) {
+static std::map<std::string, std::string>
+ConstructPerWorkerCredentialTypesMap() {
+ // Parse a list of the form: "addr1,cred_type1;addr2,cred_type2;..." into
+ // a map.
+ std::string remaining = FLAGS_per_worker_credential_types;
+ std::map<std::string, std::string> out;
+ while (!remaining.empty()) {
+ size_t next_semicolon = remaining.find(';');
+ std::string next_entry = remaining.substr(0, next_semicolon);
+ if (next_semicolon == std::string::npos) {
+ remaining = "";
+ } else {
+ remaining = remaining.substr(next_semicolon + 1, std::string::npos);
+ }
+ size_t comma = next_entry.find(',');
+ if (comma == std::string::npos) {
+ gpr_log(GPR_ERROR,
+ "Expectd --per_worker_credential_types to be a list "
+ "of the form: 'addr1,cred_type1;addr2,cred_type2;...' "
+ "into.");
+ abort();
+ }
+ std::string addr = next_entry.substr(0, comma);
+ std::string cred_type = next_entry.substr(comma + 1, std::string::npos);
+ if (out.find(addr) != out.end()) {
+ gpr_log(GPR_ERROR,
+ "Found duplicate addr in per_worker_credential_types.");
+ abort();
+ }
+ out[addr] = cred_type;
+ }
+ return out;
+}
+
+static std::unique_ptr<ScenarioResult> RunAndReport(
+ const Scenario& scenario,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n";
- auto result = RunScenario(
- scenario.client_config(), scenario.num_clients(),
- scenario.server_config(), scenario.num_servers(),
- scenario.warmup_seconds(), scenario.benchmark_seconds(),
- !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2,
- FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc,
- FLAGS_median_latency_collection_interval_millis);
+ auto result =
+ RunScenario(scenario.client_config(), scenario.num_clients(),
+ scenario.server_config(), scenario.num_servers(),
+ scenario.warmup_seconds(), scenario.benchmark_seconds(),
+ !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2,
+ FLAGS_qps_server_target_override, FLAGS_credential_type,
+ per_worker_credential_types, FLAGS_run_inproc,
+ FLAGS_median_latency_collection_interval_millis);
// Amend the result with scenario config. Eventually we should adjust
// RunScenario contract so we don't need to touch the result here.
@@ -115,21 +162,26 @@ static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
return result;
}
-static double GetCpuLoad(Scenario* scenario, double offered_load,
- bool* success) {
+static double GetCpuLoad(
+ Scenario* scenario, double offered_load,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
scenario->mutable_client_config()
->mutable_load_params()
->mutable_poisson()
->set_offered_load(offered_load);
- auto result = RunAndReport(*scenario, success);
+ auto result = RunAndReport(*scenario, per_worker_credential_types, success);
return result->summary().server_cpu_usage();
}
-static double BinarySearch(Scenario* scenario, double targeted_cpu_load,
- double low, double high, bool* success) {
+static double BinarySearch(
+ Scenario* scenario, double targeted_cpu_load, double low, double high,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
while (low <= high * (1 - FLAGS_error_tolerance)) {
double mid = low + (high - low) / 2;
- double current_cpu_load = GetCpuLoad(scenario, mid, success);
+ double current_cpu_load =
+ GetCpuLoad(scenario, mid, per_worker_credential_types, success);
gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f", mid);
if (!*success) {
gpr_log(GPR_ERROR, "Client/Server Failure");
@@ -145,12 +197,14 @@ static double BinarySearch(Scenario* scenario, double targeted_cpu_load,
return low;
}
-static double SearchOfferedLoad(double initial_offered_load,
- double targeted_cpu_load, Scenario* scenario,
- bool* success) {
+static double SearchOfferedLoad(
+ double initial_offered_load, double targeted_cpu_load, Scenario* scenario,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
std::cerr << "RUNNING SCENARIO: " << scenario->name() << "\n";
double current_offered_load = initial_offered_load;
- double current_cpu_load = GetCpuLoad(scenario, current_offered_load, success);
+ double current_cpu_load = GetCpuLoad(scenario, current_offered_load,
+ per_worker_credential_types, success);
if (current_cpu_load > targeted_cpu_load) {
gpr_log(GPR_ERROR, "Initial offered load too high");
return -1;
@@ -158,14 +212,15 @@ static double SearchOfferedLoad(double initial_offered_load,
while (*success && (current_cpu_load < targeted_cpu_load)) {
current_offered_load *= 2;
- current_cpu_load = GetCpuLoad(scenario, current_offered_load, success);
+ current_cpu_load = GetCpuLoad(scenario, current_offered_load,
+ per_worker_credential_types, success);
gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f",
current_offered_load);
}
double targeted_offered_load =
BinarySearch(scenario, targeted_cpu_load, current_offered_load / 2,
- current_offered_load, success);
+ current_offered_load, per_worker_credential_types, success);
return targeted_offered_load;
}
@@ -183,6 +238,7 @@ static bool QpsDriver() {
abort();
}
+ auto per_worker_credential_types = ConstructPerWorkerCredentialTypesMap();
if (scfile) {
// Read the json data from disk
FILE* json_file = fopen(FLAGS_scenarios_file.c_str(), "r");
@@ -198,7 +254,7 @@ static bool QpsDriver() {
} else if (scjson) {
json = FLAGS_scenarios_json.c_str();
} else if (FLAGS_quit) {
- return RunQuit(FLAGS_credential_type);
+ return RunQuit(FLAGS_credential_type, per_worker_credential_types);
}
// Parse into an array of scenarios
@@ -212,15 +268,16 @@ static bool QpsDriver() {
for (int i = 0; i < scenarios.scenarios_size(); i++) {
if (FLAGS_search_param == "") {
const Scenario& scenario = scenarios.scenarios(i);
- RunAndReport(scenario, &success);
+ RunAndReport(scenario, per_worker_credential_types, &success);
} else {
if (FLAGS_search_param == "offered_load") {
Scenario* scenario = scenarios.mutable_scenarios(i);
- double targeted_offered_load =
- SearchOfferedLoad(FLAGS_initial_search_value,
- FLAGS_targeted_cpu_load, scenario, &success);
+ double targeted_offered_load = SearchOfferedLoad(
+ FLAGS_initial_search_value, FLAGS_targeted_cpu_load, scenario,
+ per_worker_credential_types, &success);
gpr_log(GPR_INFO, "targeted_offered_load %f", targeted_offered_load);
- GetCpuLoad(scenario, targeted_offered_load, &success);
+ GetCpuLoad(scenario, targeted_offered_load, per_worker_credential_types,
+ &success);
} else {
gpr_log(GPR_ERROR, "Unimplemented search param");
}
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 6044f4265a..68062e66f2 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -52,7 +52,7 @@ static void RunQPS() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "",
- kInsecureCredentialsType, false, 0);
+ kInsecureCredentialsType, {}, false, 0);
GetReporter()->ReportQPSPerCore(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index a559c82cc8..422bd617eb 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -55,7 +55,7 @@ static void RunSynchronousUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "",
- kInsecureCredentialsType, false, 0);
+ kInsecureCredentialsType, {}, false, 0);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/server_callback.cc b/test/cpp/qps/server_callback.cc
index 8bedd44739..4a346dd017 100644
--- a/test/cpp/qps/server_callback.cc
+++ b/test/cpp/qps/server_callback.cc
@@ -34,13 +34,53 @@ class BenchmarkCallbackServiceImpl final
: public BenchmarkService::ExperimentalCallbackService {
public:
void UnaryCall(
- ServerContext* context, const SimpleRequest* request,
- SimpleResponse* response,
- experimental::ServerCallbackRpcController* controller) override {
+ ServerContext* context, const ::grpc::testing::SimpleRequest* request,
+ ::grpc::testing::SimpleResponse* response,
+ ::grpc::experimental::ServerCallbackRpcController* controller) override {
auto s = SetResponse(request, response);
controller->Finish(s);
}
+ ::grpc::experimental::ServerBidiReactor<::grpc::testing::SimpleRequest,
+ ::grpc::testing::SimpleResponse>*
+ StreamingCall() override {
+ class Reactor
+ : public ::grpc::experimental::ServerBidiReactor<
+ ::grpc::testing::SimpleRequest, ::grpc::testing::SimpleResponse> {
+ public:
+ Reactor() {}
+ void OnStarted(ServerContext* context) override { StartRead(&request_); }
+
+ void OnReadDone(bool ok) override {
+ if (!ok) {
+ Finish(::grpc::Status::OK);
+ return;
+ }
+ auto s = SetResponse(&request_, &response_);
+ if (!s.ok()) {
+ Finish(s);
+ return;
+ }
+ StartWrite(&response_);
+ }
+
+ void OnWriteDone(bool ok) override {
+ if (!ok) {
+ Finish(::grpc::Status::OK);
+ return;
+ }
+ StartRead(&request_);
+ }
+
+ void OnDone() override { delete (this); }
+
+ private:
+ SimpleRequest request_;
+ SimpleResponse response_;
+ };
+ return new Reactor;
+ }
+
private:
static Status SetResponse(const SimpleRequest* request,
SimpleResponse* response) {
diff --git a/test/cpp/server/load_reporter/get_cpu_stats_test.cc b/test/cpp/server/load_reporter/get_cpu_stats_test.cc
index 5b1d5fa3a4..98c15b2c69 100644
--- a/test/cpp/server/load_reporter/get_cpu_stats_test.cc
+++ b/test/cpp/server/load_reporter/get_cpu_stats_test.cc
@@ -55,7 +55,7 @@ TEST(GetCpuStatsTest, Ascending) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc
index c92c407e4f..a3a67a2851 100644
--- a/test/cpp/server/load_reporter/load_data_store_test.cc
+++ b/test/cpp/server/load_reporter/load_data_store_test.cc
@@ -475,7 +475,7 @@ TEST_F(PerBalancerStoreTest, DataAggregation) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/server/load_reporter/load_reporter_test.cc b/test/cpp/server/load_reporter/load_reporter_test.cc
index 0d56cdf431..9d2ebfb0b4 100644
--- a/test/cpp/server/load_reporter/load_reporter_test.cc
+++ b/test/cpp/server/load_reporter/load_reporter_test.cc
@@ -501,7 +501,7 @@ TEST_F(LoadReportTest, BasicReport) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD
index 57eaf3baf2..61e65029ff 100644
--- a/test/cpp/util/BUILD
+++ b/test/cpp/util/BUILD
@@ -181,6 +181,7 @@ grpc_cc_test(
data = [
"//src/proto/grpc/testing:echo.proto",
"//src/proto/grpc/testing:echo_messages.proto",
+ "//src/proto/grpc/testing:simple_messages.proto",
],
external_deps = [
"gtest",
@@ -192,6 +193,7 @@ grpc_cc_test(
"//:grpc++_reflection",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
+ "//src/proto/grpc/testing:simple_messages_proto",
"//test/core/end2end:ssl_test_data",
"//test/core/util:grpc_test_util",
],
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 516f3fa53d..1d641535e2 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -122,7 +122,7 @@ TEST_F(CliCallTest, SimpleRpc) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc
index be9a624a2c..b96b00f2db 100644
--- a/test/cpp/util/grpc_tool_test.cc
+++ b/test/cpp/util/grpc_tool_test.cc
@@ -48,6 +48,7 @@ using grpc::testing::EchoResponse;
#define ECHO_TEST_SERVICE_SUMMARY \
"Echo\n" \
+ "CheckClientInitialMetadata\n" \
"RequestStream\n" \
"ResponseStream\n" \
"BidiStream\n" \
@@ -59,6 +60,8 @@ using grpc::testing::EchoResponse;
"service EchoTestService {\n" \
" rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
"{}\n" \
+ " rpc CheckClientInitialMetadata(grpc.testing.SimpleRequest) returns " \
+ "(grpc.testing.SimpleResponse) {}\n" \
" rpc RequestStream(stream grpc.testing.EchoRequest) returns " \
"(grpc.testing.EchoResponse) {}\n" \
" rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \
@@ -1173,7 +1176,7 @@ TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) {
} // namespace grpc
int main(int argc, char** argv) {
- grpc_test_init(argc, argv);
+ grpc::testing::TestEnvironment env(argc, argv);
::testing::InitGoogleTest(&argc, argv);
::testing::FLAGS_gtest_death_test_style = "threadsafe";
return RUN_ALL_TESTS();
diff --git a/third_party/data-plane-api b/third_party/data-plane-api
new file mode 160000
+Subproject 911001cdca003337bdb93fab32740cde61bafee
diff --git a/third_party/googleapis b/third_party/googleapis
new file mode 160000
+Subproject 80ed4d0bbf65d57cc267dfc63bd2584557f11f9
diff --git a/third_party/protoc-gen-validate b/third_party/protoc-gen-validate
new file mode 160000
+Subproject e143189bf6f37b3957fb31743df6a1bcf4a8c68
diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD
index 02cd87a7b9..e213461acc 100644
--- a/third_party/toolchains/BUILD
+++ b/third_party/toolchains/BUILD
@@ -16,37 +16,72 @@ licenses(["notice"]) # Apache v2
package(default_visibility = ["//visibility:public"])
-exports_files(["RBE_USE_MACHINE_TYPE_LARGE",])
-
# Latest RBE Ubuntu16_04 container
# Update every time when a new container is released.
alias(
name = "rbe_ubuntu1604",
- actual = ":rbe_ubuntu1604_r328903",
+ actual = ":rbe_ubuntu1604_r342117",
+)
+
+alias(
+ name = "rbe_ubuntu1604_large",
+ actual = ":rbe_ubuntu1604_r342117_large",
)
-# RBE Ubuntu16_04 r328903
+# RBE Ubuntu16_04 r342117
platform(
- name = "rbe_ubuntu1604_r328903",
+ name = "rbe_ubuntu1604_r342117",
constraint_values = [
"@bazel_tools//platforms:x86_64",
"@bazel_tools//platforms:linux",
"@bazel_tools//tools/cpp:clang",
"@com_github_bazelbuild_bazeltoolchains//constraints:xenial",
"@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan",
+ "//third_party/toolchains/machine_size:standard",
],
remote_execution_properties = """
properties: {
name: "container-image"
- value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:59bf0e191a6b5cc1ab62c2224c810681d1326bad5a27b1d36c9f40113e79da7f"
+ value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375"
}
properties: {
name: "gceMachineType" # Small machines for majority of tests.
value: "n1-highmem-2"
}
+ """,
+)
+
+# RBE Ubuntu16_04 r342117 large
+platform(
+ name = "rbe_ubuntu1604_r342117_large",
+ constraint_values = [
+ "@bazel_tools//platforms:x86_64",
+ "@bazel_tools//platforms:linux",
+ "@bazel_tools//tools/cpp:clang",
+ "@com_github_bazelbuild_bazeltoolchains//constraints:xenial",
+ "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan",
+ "//third_party/toolchains/machine_size:large",
+ ],
+ remote_execution_properties = """
+ properties: {
+ name: "container-image"
+ value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375"
+ }
properties: {
- name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN.
+ name: "gceMachineType" # Large machines for some resource demanding tests (TSAN).
value: "n1-standard-8"
}
- """,
+ """,
+)
+
+# This target is auto-generated from release/cpp.tpl and should not be
+# modified directly.
+toolchain(
+ name = "cc-toolchain-clang-x86_64-default",
+ exec_compatible_with = [
+ ],
+ target_compatible_with = [
+ ],
+ toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8",
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
diff --git a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE b/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE
deleted file mode 100644
index b1120238d7..0000000000
--- a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE
+++ /dev/null
@@ -1 +0,0 @@
-# This file is a sentinel and is meant to be empty.
diff --git a/tools/run_tests/helper_scripts/run_lcov.sh b/third_party/toolchains/machine_size/BUILD
index 9d8b6793fc..cc962946c3 100755..100644
--- a/tools/run_tests/helper_scripts/run_lcov.sh
+++ b/third_party/toolchains/machine_size/BUILD
@@ -1,5 +1,4 @@
-#!/bin/bash
-# Copyright 2015 gRPC authors.
+# 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.
@@ -13,19 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-set -ex
+licenses(["notice"]) # Apache v2
-out=$(readlink -f "${1:-coverage}")
+package(default_visibility = ["//visibility:public"])
-root=$(readlink -f "$(dirname "$0")/../../..")
-shift || true
-tmp=$(mktemp)
-cd "$root"
-tools/run_tests/run_tests.py -c gcov -l c c++ "$@" || true
-lcov --capture --directory . --output-file "$tmp"
-genhtml "$tmp" --output-directory "$out"
-rm "$tmp"
-if which xdg-open > /dev/null
-then
- xdg-open "file://$out/index.html"
-fi
+constraint_setting(name = "machine_size")
+
+constraint_value(
+ name = "large",
+ constraint_setting = ":machine_size",
+)
+
+constraint_value(
+ name = "standard",
+ constraint_setting = ":machine_size",
+)
+
+# Add other constraint values as needed (tiny, huge, etc.) in the future.
diff --git a/third_party/upb b/third_party/upb
new file mode 160000
+Subproject 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index adfd4a24f9..ab288a0090 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -64,6 +64,7 @@ CONFIG = [
# well known method names
'/grpc.lb.v1.LoadBalancer/BalanceLoad',
'/grpc.health.v1.Health/Watch',
+ '/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources',
# compression algorithm names
'deflate',
'gzip',
diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh
index 82a818cce5..8a5f7af6c6 100755
--- a/tools/distrib/pylint_code.sh
+++ b/tools/distrib/pylint_code.sh
@@ -20,9 +20,11 @@ cd "$(dirname "$0")/../.."
DIRS=(
'src/python/grpcio/grpc'
+ 'src/python/grpcio_channelz/grpc_channelz'
'src/python/grpcio_health_checking/grpc_health'
'src/python/grpcio_reflection/grpc_reflection'
'src/python/grpcio_testing/grpc_testing'
+ 'src/python/grpcio_status/grpc_status'
)
TEST_DIRS=(
diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py
index 732d948bbc..de47c00618 100755
--- a/tools/distrib/python/docgen.py
+++ b/tools/distrib/python/docgen.py
@@ -32,12 +32,10 @@ parser.add_argument(
help='GRPC/GPR libraries build configuration',
default='opt')
parser.add_argument('--submit', action='store_true')
-parser.add_argument('--gh-user', type=str, help='GitHub user to push as.')
parser.add_argument(
- '--gh-repo-owner',
+ '--repo-owner',
type=str,
- help=('Owner of the GitHub repository to be pushed; '
- 'defaults to --gh-user.'))
+ help=('Owner of the GitHub repository to be pushed'))
parser.add_argument('--doc-branch', type=str)
args = parser.parse_args()
@@ -70,7 +68,7 @@ subprocess_arguments_list = [
'env': environment
},
{
- 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==10.0.1'],
+ 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==18.1'],
'env': environment
},
{
@@ -78,7 +76,7 @@ subprocess_arguments_list = [
'env': environment
},
{
- 'args': [VIRTUALENV_PYTHON_PATH, SETUP_PATH, 'build'],
+ 'args': [VIRTUALENV_PIP_PATH, 'install', 'Sphinx~=1.8.1'],
'env': environment
},
{
@@ -91,12 +89,12 @@ for subprocess_arguments in subprocess_arguments_list:
print('Running command: {}'.format(subprocess_arguments['args']))
subprocess.check_call(**subprocess_arguments)
-if args.submit:
- assert args.gh_user
+if not args.submit:
+ print('Please check generated Python doc inside doc/build')
+elif args.submit:
+ assert args.repo_owner
assert args.doc_branch
- github_user = args.gh_user
- github_repository_owner = (args.gh_repo_owner
- if args.gh_repo_owner else args.gh_user)
+ github_repository_owner = args.repo_owner
# Create a temporary directory out of tree, checkout gh-pages from the
# specified repository, edit it, and push it. It's up to the user to then go
# onto GitHub and make a PR against grpc/grpc:gh-pages.
@@ -109,16 +107,19 @@ if args.submit:
print('Cloning your repository...')
subprocess.check_call(
[
- 'git', 'clone', 'https://{}@github.com/{}/grpc'.format(
- github_user, github_repository_owner)
+ 'git',
+ 'clone',
+ '--branch',
+ 'gh-pages',
+ 'https://github.com/grpc/grpc',
],
cwd=repo_parent_dir)
+ subprocess.check_call(['git', 'checkout', '-b', doc_branch], cwd=repo_dir)
subprocess.check_call(
- ['git', 'remote', 'add', 'upstream', 'https://github.com/grpc/grpc'],
- cwd=repo_dir)
- subprocess.check_call(['git', 'fetch', 'upstream'], cwd=repo_dir)
- subprocess.check_call(
- ['git', 'checkout', 'upstream/gh-pages', '-b', doc_branch],
+ [
+ 'git', 'remote', 'add', 'ssh-origin',
+ 'git@github.com:%s/grpc.git' % (github_repository_owner)
+ ],
cwd=repo_dir)
print('Updating documentation...')
shutil.rmtree(python_doc_dir, ignore_errors=True)
@@ -130,7 +131,7 @@ if args.submit:
['git', 'commit', '-m', 'Auto-update Python documentation'],
cwd=repo_dir)
subprocess.check_call(
- ['git', 'push', '--set-upstream', 'origin', doc_branch],
+ ['git', 'push', '--set-upstream', 'ssh-origin', doc_branch],
cwd=repo_dir)
except subprocess.CalledProcessError:
print('Failed to push documentation. Examine this directory and push '
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 4b775e667e..29b2127960 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
index b2216c79d4..b49fa10410 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharp/Dockerfile
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM debian:jessie
+FROM debian:stretch
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
@@ -67,37 +67,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t
#================
# C# dependencies
-# Update to a newer version of mono
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+# cmake >=3.6 needed to build grpc_csharp_ext
+RUN apt-get update && apt-get install -y cmake && apt-get clean
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
+# Install mono
+RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean
+RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list
+RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget \
&& apt-get clean
-RUN nuget update -self
+# Install dotnet SDK
+ENV DOTNET_SDK_VERSION 2.1.500
+RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz \
+ && mkdir -p /usr/share/dotnet \
+ && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \
+ && rm dotnet.tar.gz \
+ && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
-#=================
-# Use cmake 3.6 from jessie-backports
-# needed to build grpc_csharp_ext with cmake
-RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
-RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean
+# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1)
+RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \
+ && mkdir -p dotnet_old \
+ && tar zxf dotnet_old.tar.gz -C dotnet_old \
+ && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \
+ && rm -rf dotnet_old/ dotnet_old.tar.gz
+RUN apt-get update && apt-get install -y libunwind8 && apt-get clean
-# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-RUN apt-get update && apt-get install -y curl libunwind8 gettext
-# dotnet-dev-1.0.0-preview2-003131
-RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
-RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
-# dotnet-dev-1.0.1
-RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
-RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
-RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
ENV NUGET_XMLDOC_MODE skip
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
index b2216c79d4..b49fa10410 100644
--- a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM debian:jessie
+FROM debian:stretch
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
@@ -67,37 +67,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t
#================
# C# dependencies
-# Update to a newer version of mono
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+# cmake >=3.6 needed to build grpc_csharp_ext
+RUN apt-get update && apt-get install -y cmake && apt-get clean
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
+# Install mono
+RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean
+RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list
+RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget \
&& apt-get clean
-RUN nuget update -self
+# Install dotnet SDK
+ENV DOTNET_SDK_VERSION 2.1.500
+RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz \
+ && mkdir -p /usr/share/dotnet \
+ && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \
+ && rm dotnet.tar.gz \
+ && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
-#=================
-# Use cmake 3.6 from jessie-backports
-# needed to build grpc_csharp_ext with cmake
-RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
-RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean
+# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1)
+RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \
+ && mkdir -p dotnet_old \
+ && tar zxf dotnet_old.tar.gz -C dotnet_old \
+ && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \
+ && rm -rf dotnet_old/ dotnet_old.tar.gz
+RUN apt-get update && apt-get install -y libunwind8 && apt-get clean
-# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-RUN apt-get update && apt-get install -y curl libunwind8 gettext
-# dotnet-dev-1.0.0-preview2-003131
-RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
-RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
-# dotnet-dev-1.0.1
-RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
-RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
-RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
ENV NUGET_XMLDOC_MODE skip
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
index dadd856740..acad500f90 100644
--- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM debian:jessie
-
+FROM debian:stretch
+
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
autoconf \
@@ -49,27 +49,24 @@ RUN apt-get update && apt-get install -y \
# Build profiling
RUN apt-get update && apt-get install -y time && apt-get clean
-#====================
-# Python dependencies
-
-# Install dependencies
-
-RUN apt-get update && apt-get install -y \
- python-all-dev \
- python3-all-dev \
- python-pip
+# 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 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 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.4
-RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
-RUN python3.4 -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 -t testing install -y python3.7 python3-all-dev
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
index 7917e1cd60..468aa20e3f 100755
--- a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
@@ -28,5 +28,5 @@ cp -r /var/local/jenkins/service_account $HOME || true
cd /var/local/git/grpc
-# interop tests only run using python2.7 currently (and python build is slow)
-tools/run_tests/run_tests.py -l python --compiler python2.7 -c opt --build_only
+# interop tests only run using python3.7 currently (and python build is slow)
+tools/run_tests/run_tests.py -l python --compiler python3.7 -c opt --build_only
diff --git a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile b/tools/dockerfile/test/csharp_stretch_x64/Dockerfile
index 030d301a40..04d2584209 100644
--- a/tools/dockerfile/test/csharp_jessie_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_stretch_x64/Dockerfile
@@ -1,4 +1,4 @@
-# Copyright 2015 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.
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM debian:jessie
+FROM debian:stretch
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
@@ -71,37 +71,36 @@ RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 t
#================
# C# dependencies
-# Update to a newer version of mono
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+# cmake >=3.6 needed to build grpc_csharp_ext
+RUN apt-get update && apt-get install -y cmake && apt-get clean
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
+# Install mono
+RUN apt-get update && apt-get install -y apt-transport-https dirmngr && apt-get clean
+RUN apt-key adv --no-tty --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb https://download.mono-project.com/repo/debian stable-stretch main" | tee /etc/apt/sources.list.d/mono-official-stable.list
+RUN apt-get update && apt-get install -y \
mono-devel \
ca-certificates-mono \
nuget \
&& apt-get clean
-RUN nuget update -self
+# Install dotnet SDK
+ENV DOTNET_SDK_VERSION 2.1.500
+RUN curl -sSL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$DOTNET_SDK_VERSION/dotnet-sdk-$DOTNET_SDK_VERSION-linux-x64.tar.gz \
+ && mkdir -p /usr/share/dotnet \
+ && tar -zxf dotnet.tar.gz -C /usr/share/dotnet \
+ && rm dotnet.tar.gz \
+ && ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet
-#=================
-# Use cmake 3.6 from jessie-backports
-# needed to build grpc_csharp_ext with cmake
-RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
-RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean
+# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1)
+RUN curl -sSL -o dotnet_old.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Runtime/1.1.10/dotnet-debian.9-x64.1.1.10.tar.gz \
+ && mkdir -p dotnet_old \
+ && tar zxf dotnet_old.tar.gz -C dotnet_old \
+ && cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/ \
+ && rm -rf dotnet_old/ dotnet_old.tar.gz
+RUN apt-get update && apt-get install -y libunwind8 && apt-get clean
-# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-RUN apt-get update && apt-get install -y curl libunwind8 gettext
-# dotnet-dev-1.0.0-preview2-003131
-RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
-RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
-# dotnet-dev-1.0.1
-RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
-RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
-RUN ln -s /opt/dotnet/dotnet /usr/local/bin
# Trigger the population of the local package cache
ENV NUGET_XMLDOC_MODE skip
diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
deleted file mode 100644
index 3c95554b02..0000000000
--- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2016 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:jessie
-
-# 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
-
-#================
-# C# dependencies
-
-# Update to a newer version of mono
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
- mono-devel \
- ca-certificates-mono \
- nuget \
- && apt-get clean
-
-RUN nuget update -self
-
-#=================
-# Use cmake 3.6 from jessie-backports
-# needed to build grpc_csharp_ext with cmake
-
-RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
-RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean
-
-# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-RUN apt-get update && apt-get install -y curl libunwind8 gettext
-# dotnet-dev-1.0.0-preview2-003131
-RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
-RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
-# dotnet-dev-1.0.1
-RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
-RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
-RUN ln -s /opt/dotnet/dotnet /usr/local/bin
-
-# Trigger the population of the local package cache
-ENV NUGET_XMLDOC_MODE skip
-RUN mkdir warmup \
- && cd warmup \
- && dotnet new \
- && cd .. \
- && rm -rf warmup
-
-#=================
-# C++ dependencies
-RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
-
-#==================
-# Node dependencies
-
-# Install nvm
-RUN touch .profile
-RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
-# Install all versions of node that we want to test
-RUN /bin/bash -l -c "nvm install 4 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 5 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 6 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 8 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 9 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 10 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm alias default 10"
-#=================
-# PHP dependencies
-
-# Install dependencies
-
-RUN apt-get update && apt-get install -y \
- git php5 php5-dev phpunit unzip
-
-#==================
-# Ruby dependencies
-
-# Install rvm
-RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-RUN \curl -sSL https://get.rvm.io | bash -s stable
-
-# Install Ruby 2.1
-RUN /bin/bash -l -c "rvm install ruby-2.1"
-RUN /bin/bash -l -c "rvm use --default ruby-2.1"
-RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
-RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
-RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
-RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
-
-#====================
-# 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 pip and virtualenv for Python 3.4
-RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
-RUN python3.4 -m pip install virtualenv
-
-# Install coverage for Python test coverage reporting
-RUN pip install coverage
-ENV PATH ~/.local/bin:$PATH
-
-# Install Mako to generate files in grpc/grpc-node
-RUN pip install Mako
-
-
-RUN mkdir /var/local/jenkins
-
-# Define the default command.
-CMD ["bash"]
diff --git a/tools/dockerfile/test/python_alpine_x64/Dockerfile b/tools/dockerfile/test/python_alpine_x64/Dockerfile
index 6e06e2d52c..3001bf43ff 100644
--- a/tools/dockerfile/test/python_alpine_x64/Dockerfile
+++ b/tools/dockerfile/test/python_alpine_x64/Dockerfile
@@ -42,13 +42,7 @@ RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0
# Google Cloud platform API libraries
-RUN pip install --upgrade google-api-python-client
-
-# Prepare ccache
-RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
-RUN ln -s /usr/bin/ccache /usr/local/bin/g++
-RUN ln -s /usr/bin/ccache /usr/local/bin/cc
-RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN pip install --upgrade google-api-python-client oauth2client
RUN mkdir -p /var/local/jenkins
diff --git a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile
index add1cc509d..45291ffdcf 100644
--- a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile
+++ b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile
@@ -70,3 +70,6 @@ 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
+
+# for Python test coverage reporting
+RUN pip install coverage
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 392113c284..a5f817997d 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.17.0-dev
+PROJECT_NUMBER = 1.18.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -777,6 +777,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
@@ -924,6 +925,7 @@ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/support/workaround_list.h \
include/grpcpp/alarm.h \
+include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index a96683883c..1535aa06d3 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.17.0-dev
+PROJECT_NUMBER = 1.18.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -777,6 +777,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
@@ -925,6 +926,7 @@ include/grpc/support/thd_id.h \
include/grpc/support/time.h \
include/grpc/support/workaround_list.h \
include/grpcpp/alarm.h \
+include/grpcpp/alarm_impl.h \
include/grpcpp/channel.h \
include/grpcpp/client_context.h \
include/grpcpp/completion_queue.h \
@@ -1083,6 +1085,7 @@ src/core/lib/iomgr/buffer_list.h \
src/core/lib/iomgr/call_combiner.h \
src/core/lib/iomgr/closure.h \
src/core/lib/iomgr/combiner.h \
+src/core/lib/iomgr/dynamic_annotations.h \
src/core/lib/iomgr/endpoint.h \
src/core/lib/iomgr/endpoint_pair.h \
src/core/lib/iomgr/error.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index b78fb607ad..8c557383b2 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -784,6 +784,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 67b6cefa09..5011e19b03 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -784,6 +784,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
@@ -922,12 +923,9 @@ 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 \
src/core/ext/filters/client_channel/lb_policy_registry.h \
-src/core/ext/filters/client_channel/method_params.cc \
-src/core/ext/filters/client_channel/method_params.h \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/parse_address.h \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -956,8 +954,12 @@ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/client_channel/resolver_factory.h \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_registry.h \
+src/core/ext/filters/client_channel/resolver_result_parsing.cc \
+src/core/ext/filters/client_channel/resolver_result_parsing.h \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/retry_throttle.h \
+src/core/ext/filters/client_channel/server_address.cc \
+src/core/ext/filters/client_channel/server_address.h \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel.h \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -1009,6 +1011,8 @@ src/core/ext/transport/chttp2/transport/bin_encoder.h \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.h \
+src/core/ext/transport/chttp2/transport/context_list.cc \
+src/core/ext/transport/chttp2/transport/context_list.h \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/flow_control.h \
src/core/ext/transport/chttp2/transport/frame.h \
@@ -1179,6 +1183,7 @@ src/core/lib/iomgr/call_combiner.h \
src/core/lib/iomgr/closure.h \
src/core/lib/iomgr/combiner.cc \
src/core/lib/iomgr/combiner.h \
+src/core/lib/iomgr/dynamic_annotations.h \
src/core/lib/iomgr/endpoint.cc \
src/core/lib/iomgr/endpoint.h \
src/core/lib/iomgr/endpoint_pair.h \
diff --git a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh
index 0f7939be4c..28c49a66f2 100755
--- a/tools/gce/create_linux_kokoro_performance_worker_from_image.sh
+++ b/tools/gce/create_linux_kokoro_performance_worker_from_image.sh
@@ -22,7 +22,7 @@ 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
+LATEST_PERF_WORKER_IMAGE=grpc-performance-kokoro-v3 # update if newer image exists
INSTANCE_NAME="${1:-grpc-kokoro-performance-server}"
MACHINE_TYPE="${2:-n1-standard-32}"
diff --git a/tools/gce/linux_kokoro_performance_worker_init.sh b/tools/gce/linux_kokoro_performance_worker_init.sh
index b78695d802..d67ff58506 100755
--- a/tools/gce/linux_kokoro_performance_worker_init.sh
+++ b/tools/gce/linux_kokoro_performance_worker_init.sh
@@ -133,6 +133,12 @@ sudo cp -r dotnet105_download/shared/Microsoft.NETCore.App/1.0.5/ /usr/share/dot
wget -q http://security.ubuntu.com/ubuntu/pool/main/i/icu/libicu55_55.1-7ubuntu0.4_amd64.deb
sudo dpkg -i libicu55_55.1-7ubuntu0.4_amd64.deb
+# Install .NET Core 1.1.10 runtime (required to run netcoreapp1.1)
+wget -q -O dotnet_old.tar.gz https://download.visualstudio.microsoft.com/download/pr/b25b5650-0cb8-4699-a347-48d73650da0b/920966211e9bb1907232bbda1faa895a/dotnet-ubuntu.18.04-x64.1.1.10.tar.gz
+mkdir -p dotnet_old
+tar zxf dotnet_old.tar.gz -C dotnet_old
+sudo cp -r dotnet_old/shared/Microsoft.NETCore.App/1.1.10/ /usr/share/dotnet/shared/Microsoft.NETCore.App/
+
# Ruby dependencies
gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
curl -sSL https://get.rvm.io | bash -s stable --ruby
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
index 24a3545ded..bafe0d98c1 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
@@ -28,15 +28,14 @@ sudo systemsetup -setusingnetworktime on
date
# Add GCP credentials for BQ access
-# pin google-api-python-client to avoid https://github.com/grpc/grpc/issues/15600
-pip install google-api-python-client==1.6.7 --user python
+pip install google-api-python-client oauth2client --user python
export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json
# If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests
if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then
set +x
brew update
- brew install jq
+ brew install jq || brew upgrade jq
ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref)
export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch"
@@ -91,3 +90,6 @@ mkdir -p /tmpfs/DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData
mkdir -p ~/Library/Developer/Xcode
ln -s /tmpfs/DerivedData ~/Library/Developer/Xcode/DerivedData
+
+# PHP tests currently require using an older version of PHPUnit
+ln -sf /usr/local/bin/phpunit-5.7 /usr/local/bin/phpunit
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 74778d9d29..d35bbbd275 100755
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh
@@ -15,8 +15,8 @@
set -ex
-# A temporary solution to give Kokoro credentials.
-# The file name 4321_grpc-testing-service needs to match auth_credential in
+# A temporary solution to give Kokoro credentials.
+# The file name 4321_grpc-testing-service needs to match auth_credential in
# the build config.
mkdir -p ${KOKORO_KEYSTORE_DIR}
cp ${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json ${KOKORO_KEYSTORE_DIR}/4321_grpc-testing-service
@@ -35,14 +35,15 @@ cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
# to get "bazel" link for kokoro build, we need to generate
-# invocation UUID, set an env var for bazel to pick it up
-# and upload "bazel_invocation_ids" file as artifact.
-export BAZEL_INTERNAL_INVOCATION_ID="$(uuidgen)"
-echo "${BAZEL_INTERNAL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids"
+# invocation UUID, set a flag for bazel to use it
+# and upload "bazel_invocation_ids" file as artifact.
+BAZEL_INVOCATION_ID="$(uuidgen)"
+echo "${BAZEL_INVOCATION_ID}" >"${KOKORO_ARTIFACTS_DIR}/bazel_invocation_ids"
bazel \
--bazelrc=tools/remote_build/kokoro.bazelrc \
test \
+ --invocation_id="${BAZEL_INVOCATION_ID}" \
$@ \
-- //test/... || FAILED="true"
diff --git a/tools/internal_ci/linux/grpc_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh
index 97166372ab..a91cffdf98 100755
--- a/tools/internal_ci/linux/grpc_coverage.sh
+++ b/tools/internal_ci/linux/grpc_coverage.sh
@@ -21,12 +21,20 @@ cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
python tools/run_tests/run_tests.py \
- --use_docker \
- -t \
- -l all \
- -c gcov \
- -x sponge_log.xml \
- -j 16 || FAILED="true"
+ -l c c++ -x coverage_cpp/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
+
+python tools/run_tests/run_tests.py \
+ -l python -x coverage_python/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
+
+python tools/run_tests/run_tests.py \
+ -l ruby -x coverage_ruby/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
+
+python tools/run_tests/run_tests.py \
+ -l php -x coverage_php/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
# HTML reports can't be easily displayed in GCS, so create a zip archive
# and put it under reports directory to get it uploaded as an artifact.
diff --git a/tools/internal_ci/linux/grpc_run_tests_matrix.sh b/tools/internal_ci/linux/grpc_run_tests_matrix.sh
index 4e7515227b..f9acd814ae 100755
--- a/tools/internal_ci/linux/grpc_run_tests_matrix.sh
+++ b/tools/internal_ci/linux/grpc_run_tests_matrix.sh
@@ -22,6 +22,7 @@ source tools/internal_ci/helper_scripts/prepare_build_linux_rc
# If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests
if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then
+ sudo apt-get update
sudo apt-get install -y jq
ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref)
export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch"
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index ff3344cd95..931beddb9c 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -207,6 +207,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.16.1': None
},
+ {
+ 'v1.17.1': None
+ },
],
'python': [
{
diff --git a/tools/remote_build/kokoro.bazelrc b/tools/remote_build/kokoro.bazelrc
index 11462bd301..2fbdd3ce02 100644
--- a/tools/remote_build/kokoro.bazelrc
+++ b/tools/remote_build/kokoro.bazelrc
@@ -26,7 +26,6 @@ build --auth_credentials=/tmpfs/src/keystore/4321_grpc-testing-service
build --auth_scope=https://www.googleapis.com/auth/cloud-source-tools
build --bes_backend=buildeventservice.googleapis.com
-build --bes_best_effort=false
build --bes_timeout=600s
build --project_id=grpc-testing
diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc
index 75a42a317e..aa3ddb050c 100644
--- a/tools/remote_build/rbe_common.bazelrc
+++ b/tools/remote_build/rbe_common.bazelrc
@@ -18,10 +18,10 @@
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
+build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain
+build --extra_toolchains=//third_party/toolchains: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 --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large
build --host_platform=//third_party/toolchains:rbe_ubuntu1604
build --platforms=//third_party/toolchains:rbe_ubuntu1604
@@ -61,9 +61,9 @@ build:msan --cxxopt=--stdlib=libc++
# setting LD_LIBRARY_PATH is necessary
# to avoid "libc++.so.1: cannot open shared object file"
build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib
-build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain
+build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain
# override the config-agnostic crosstool_top
-build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/msan:toolchain
+build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain
# thread sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
@@ -71,6 +71,7 @@ build:tsan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:tsan --test_timeout=3600
build:tsan --test_tag_filters=-qps_json_driver
+build:tsan --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large
# undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
@@ -78,7 +79,7 @@ build:ubsan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:ubsan --test_timeout=3600
# override the config-agnostic crosstool_top
---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.16.1/ubsan:toolchain
+--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/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.
diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh
index 65f2d1c765..e451ced338 100755
--- a/tools/run_tests/artifacts/build_artifact_python.sh
+++ b/tools/run_tests/artifacts/build_artifact_python.sh
@@ -105,9 +105,15 @@ then
"${PIP}" install grpcio-tools --no-index --find-links "file://$ARTIFACT_DIR/"
# Build grpcio_testing source distribution
- ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py sdist
+ ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py preprocess \
+ sdist
cp -r src/python/grpcio_testing/dist/* "$ARTIFACT_DIR"
+ # Build grpcio_channelz source distribution
+ ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_channelz/setup.py \
+ preprocess build_package_protos sdist
+ cp -r src/python/grpcio_channelz/dist/* "$ARTIFACT_DIR"
+
# Build grpcio_health_checking source distribution
${SETARCH_CMD} "${PYTHON}" src/python/grpcio_health_checking/setup.py \
preprocess build_package_protos sdist
@@ -117,6 +123,11 @@ then
${SETARCH_CMD} "${PYTHON}" src/python/grpcio_reflection/setup.py \
preprocess build_package_protos sdist
cp -r src/python/grpcio_reflection/dist/* "$ARTIFACT_DIR"
+
+ # Build grpcio_status source distribution
+ ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_status/setup.py \
+ preprocess sdist
+ cp -r src/python/grpcio_status/dist/* "$ARTIFACT_DIR"
fi
cp -r dist/* "$ARTIFACT_DIR"
diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh
index d93e8979fc..29801a5b86 100755
--- a/tools/run_tests/artifacts/build_package_python.sh
+++ b/tools/run_tests/artifacts/build_package_python.sh
@@ -19,20 +19,10 @@ cd "$(dirname "$0")/../../.."
mkdir -p artifacts/
+# All the python packages have been built in the artifact phase already
+# and we only collect them here to deliver them to the distribtest phase.
cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true
-strip_binary_wheel() {
- TEMP_WHEEL_DIR=$(mktemp -d)
- unzip "$1" -d "$TEMP_WHEEL_DIR"
- find "$TEMP_WHEEL_DIR" -name "_protoc_compiler*.so" -exec strip --strip-debug {} ";"
- find "$TEMP_WHEEL_DIR" -name "cygrpc*.so" -exec strip --strip-debug {} ";"
- (cd "$TEMP_WHEEL_DIR" && zip -r - .) > "$1"
-}
-
-for wheel in artifacts/*.whl; do
- strip_binary_wheel "$wheel"
-done
-
# TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz
# source distribution package, and only one of them will end up
# in the artifacts/ directory. They should be all equivalent though.
diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
index 614049cae5..1741b3268b 100755
--- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh
+++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
@@ -22,9 +22,6 @@ cd "$(dirname "$0")/../../.."
git_root=$(pwd)
cd -
-# Ensure existence of ccache directory
-mkdir -p /tmp/ccache
-
# Inputs
# DOCKERFILE_DIR - Directory in which Dockerfile file is located.
# DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root)
@@ -57,7 +54,6 @@ docker run \
-e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \
-e "config=$config" \
-e "arch=$arch" \
- -e CCACHE_DIR=/tmp/ccache \
-e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
-e HOST_GIT_ROOT="$git_root" \
-e LOCAL_GIT_ROOT=$docker_instance_git_root \
@@ -73,7 +69,6 @@ docker run \
--sysctl net.ipv6.conf.all.disable_ipv6=0 \
-v ~/.config/gcloud:/root/.config/gcloud \
-v "$git_root:$docker_instance_git_root" \
- -v /tmp/ccache:/tmp/ccache \
-v /tmp/npm-cache:/tmp/npm-cache \
-w /var/local/git/grpc \
--name="$CONTAINER_NAME" \
diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh
index fcfcdeb4e4..126dd4065e 100755
--- a/tools/run_tests/dockerize/build_interop_image.sh
+++ b/tools/run_tests/dockerize/build_interop_image.sh
@@ -64,8 +64,6 @@ else
echo "WARNING: grpc-node not found, it won't be mounted to the docker container."
fi
-mkdir -p /tmp/ccache
-
# Mount service account dir if available.
# If service_directory does not contain the service account JSON file,
# some of the tests will fail.
@@ -105,14 +103,12 @@ CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)"
# shellcheck disable=SC2086
(docker run \
--cap-add SYS_PTRACE \
- -e CCACHE_DIR=/tmp/ccache \
-e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
-e THIS_IS_REALLY_NEEDED_ONCE_AGAIN='For issue 4835. See https://github.com/docker/docker/issues/14203 for why docker is awful' \
-i \
$TTY_FLAG \
$MOUNT_ARGS \
$BUILD_INTEROP_DOCKER_EXTRA_ARGS \
- -v /tmp/ccache:/tmp/ccache \
--name="$CONTAINER_NAME" \
"$BASE_IMAGE" \
bash -l "/var/local/jenkins/grpc/tools/dockerfile/interoptest/$BASE_NAME/build_interop.sh" \
diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh
index c41734c92d..b7686e48ba 100755
--- a/tools/run_tests/dockerize/docker_run_tests.sh
+++ b/tools/run_tests/dockerize/docker_run_tests.sh
@@ -38,16 +38,8 @@ exit_code=0
$RUN_TESTS_COMMAND || exit_code=$?
-cd reports
-echo '<html><head></head><body>' > index.html
-find . -maxdepth 1 -mindepth 1 -type d | sort | while read d ; do
- d=${d#*/}
- n=${d//_/ }
- echo "<a href='$d/index.html'>$n</a><br />" >> index.html
-done
-echo '</body></html>' >> index.html
-cd ..
-
+# The easiest way to copy all the reports files from inside of
+# the docker container is to zip them and then copy the zip.
zip -r reports.zip reports
find . -name report.xml -print0 | xargs -0 -r zip reports.zip
find . -name sponge_log.xml -print0 | xargs -0 -r zip reports.zip
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 27f15abbef..40c49895fd 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -2804,6 +2804,28 @@
"headers": [],
"is_filegroup": false,
"language": "c++",
+ "name": "bm_byte_buffer",
+ "src": [
+ "test/cpp/microbenchmarks/bm_byte_buffer.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "benchmark",
+ "gpr",
+ "gpr_test_util",
+ "grpc++_test_config",
+ "grpc++_test_util_unsecure",
+ "grpc++_unsecure",
+ "grpc_benchmark",
+ "grpc_test_util_unsecure",
+ "grpc_unsecure"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
"name": "bm_call_create",
"src": [
"test/cpp/microbenchmarks/bm_call_create.cc"
@@ -3510,6 +3532,23 @@
{
"deps": [
"gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "context_list_test",
+ "src": [
+ "test/core/transport/chttp2/context_list_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
"grpc",
"grpc++"
],
@@ -6202,9 +6241,45 @@
"headers": [],
"is_filegroup": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_ipv4_test",
+ "src": [
+ "test/core/end2end/fixtures/h2_local_ipv4.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "end2end_tests",
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "src": [
+ "test/core/end2end/fixtures/h2_local_ipv6.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "end2end_tests",
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
+ "name": "h2_local_uds_test",
"src": [
- "test/core/end2end/fixtures/h2_local.cc"
+ "test/core/end2end/fixtures/h2_local_uds.cc"
],
"third_party": false,
"type": "target"
@@ -7427,6 +7502,10 @@
"src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
"src/proto/grpc/testing/echo_mock.grpc.pb.h",
+ "src/proto/grpc/testing/simple_messages.grpc.pb.h",
+ "src/proto/grpc/testing/simple_messages.pb.h",
+ "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/channel_trace_proto_helper.h",
@@ -7439,6 +7518,8 @@
"language": "c++",
"name": "grpc++_test_util",
"src": [
+ "test/cpp/end2end/test_health_check_service_impl.cc",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.cc",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.cc",
@@ -7480,6 +7561,10 @@
"src/proto/grpc/testing/echo_messages.pb.h",
"src/proto/grpc/testing/echo_messages_mock.grpc.pb.h",
"src/proto/grpc/testing/echo_mock.grpc.pb.h",
+ "src/proto/grpc/testing/simple_messages.grpc.pb.h",
+ "src/proto/grpc/testing/simple_messages.pb.h",
+ "src/proto/grpc/testing/simple_messages_mock.grpc.pb.h",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.h",
"test/cpp/util/string_ref_helper.h",
@@ -7489,6 +7574,8 @@
"language": "c++",
"name": "grpc++_test_util_unsecure",
"src": [
+ "test/cpp/end2end/test_health_check_service_impl.cc",
+ "test/cpp/end2end/test_health_check_service_impl.h",
"test/cpp/end2end/test_service_impl.cc",
"test/cpp/end2end/test_service_impl.h",
"test/cpp/util/byte_buffer_proto_helper.cc",
@@ -9715,6 +9802,7 @@
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/closure.h",
"src/core/lib/iomgr/combiner.h",
+ "src/core/lib/iomgr/dynamic_annotations.h",
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
@@ -9867,6 +9955,7 @@
"src/core/lib/iomgr/call_combiner.h",
"src/core/lib/iomgr/closure.h",
"src/core/lib/iomgr/combiner.h",
+ "src/core/lib/iomgr/dynamic_annotations.h",
"src/core/lib/iomgr/endpoint.h",
"src/core/lib/iomgr/endpoint_pair.h",
"src/core/lib/iomgr/error.h",
@@ -10035,14 +10124,15 @@
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
- "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
"src/core/ext/filters/client_channel/resolver.h",
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.h",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h"
],
@@ -10070,12 +10160,9 @@
"src/core/ext/filters/client_channel/http_proxy.h",
"src/core/ext/filters/client_channel/lb_policy.cc",
"src/core/ext/filters/client_channel/lb_policy.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",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
- "src/core/ext/filters/client_channel/method_params.cc",
- "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
@@ -10087,8 +10174,12 @@
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.cc",
"src/core/ext/filters/client_channel/resolver_registry.h",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.cc",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/retry_throttle.h",
+ "src/core/ext/filters/client_channel/server_address.cc",
+ "src/core/ext/filters/client_channel/server_address.h",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.cc",
@@ -10628,6 +10719,7 @@
"src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h",
"test/core/end2end/cq_verifier.h",
"test/core/end2end/fixtures/http_proxy_fixture.h",
+ "test/core/end2end/fixtures/local_util.h",
"test/core/end2end/fixtures/proxy.h",
"test/core/iomgr/endpoint_tests.h",
"test/core/util/debugger_macros.h",
@@ -10655,6 +10747,8 @@
"test/core/end2end/cq_verifier.h",
"test/core/end2end/fixtures/http_proxy_fixture.cc",
"test/core/end2end/fixtures/http_proxy_fixture.h",
+ "test/core/end2end/fixtures/local_util.cc",
+ "test/core/end2end/fixtures/local_util.h",
"test/core/end2end/fixtures/proxy.cc",
"test/core/end2end/fixtures/proxy.h",
"test/core/iomgr/endpoint_tests.cc",
@@ -10736,6 +10830,7 @@
"src/core/ext/transport/chttp2/transport/bin_decoder.h",
"src/core/ext/transport/chttp2/transport/bin_encoder.h",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/context_list.h",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/frame_data.h",
@@ -10765,6 +10860,8 @@
"src/core/ext/transport/chttp2/transport/chttp2_plugin.cc",
"src/core/ext/transport/chttp2/transport/chttp2_transport.cc",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/context_list.cc",
+ "src/core/ext/transport/chttp2/transport/context_list.h",
"src/core/ext/transport/chttp2/transport/flow_control.cc",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
@@ -11411,6 +11508,7 @@
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
"include/grpcpp/alarm.h",
+ "include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
@@ -11516,6 +11614,7 @@
"include/grpc++/support/sync_stream.h",
"include/grpc++/support/time.h",
"include/grpcpp/alarm.h",
+ "include/grpcpp/alarm_impl.h",
"include/grpcpp/channel.h",
"include/grpcpp/client_context.h",
"include/grpcpp/completion_queue.h",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 340343caf0..3a348e4a92 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3377,6 +3377,28 @@
"flaky": false,
"gtest": false,
"language": "c++",
+ "name": "bm_byte_buffer",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": true,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": false,
+ "language": "c++",
"name": "bm_call_create",
"platforms": [
"linux",
@@ -4138,6 +4160,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "context_list_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "credentials_test",
"platforms": [
"linux",
@@ -22330,7 +22376,3457 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "bad_hostname"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "bad_ping"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "binary_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "call_creds"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_accept"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_client_done"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_invoke"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_round_trip"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_before_invoke"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_in_a_vacuum"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_with_status"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "channelz"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "compressed_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "connectivity"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "disappearing_server"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": true,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "empty_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_call_init_fails"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_causes_close"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_latency"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_status_code"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "graceful_server_shutdown"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "high_initial_seqno"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "hpack_size"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "idempotent_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "invoke_large_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "keepalive_timeout"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "large_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_concurrent_streams"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_connection_age"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_connection_idle"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_message_length"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "negative_deadline"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "network_status_change"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "no_error_on_hotpath"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "no_logging"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "no_op"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "ping"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "ping_pong_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "registered_call"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "request_with_flags"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "request_with_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "resource_quota_server"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "server_finishes_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "shutdown_finishes_calls"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "shutdown_finishes_tags"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_cacheable_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_delayed_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "stream_compression_compressed_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "stream_compression_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "stream_compression_ping_pong_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "streaming_error_response"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "trailing_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "workaround_cronet_compression"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "write_buffering"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "write_buffering_at_end"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv4_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "authority_not_supported"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "bad_hostname"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "bad_ping"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "binary_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "call_creds"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_accept"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_client_done"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_invoke"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_after_round_trip"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_before_invoke"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_in_a_vacuum"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "cancel_with_status"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "channelz"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "compressed_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "connectivity"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "disappearing_server"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": true,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "empty_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_call_init_fails"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_causes_close"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_latency"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "filter_status_code"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "graceful_server_shutdown"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "high_initial_seqno"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "hpack_size"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "idempotent_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "invoke_large_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "keepalive_timeout"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "large_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_concurrent_streams"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_connection_age"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_connection_idle"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "max_message_length"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "negative_deadline"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "network_status_change"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "no_error_on_hotpath"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "no_logging"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "no_op"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "ping"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "ping_pong_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "registered_call"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "request_with_flags"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "request_with_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "resource_quota_server"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_cancellation"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_initial_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_exceeds_buffer_size_in_subsequent_batch"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_non_retriable_status_before_recv_trailing_metadata_started"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_initial_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_recv_message"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_delay"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_server_pushback_disabled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_after_commit"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_streaming_succeeds_before_replay_finished"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_throttled"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "retry_too_many_attempts"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "server_finishes_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "shutdown_finishes_calls"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "shutdown_finishes_tags"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_cacheable_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_delayed_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "simple_request"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "stream_compression_compressed_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "stream_compression_payload"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "stream_compression_ping_pong_streaming"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "streaming_error_response"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "trailing_metadata"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "workaround_cronet_compression"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "write_buffering"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "write_buffering_at_end"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 0.1,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_ipv6_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ]
+ },
+ {
+ "args": [
+ "authority_not_supported"
+ ],
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "language": "c",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22353,7 +25849,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22376,7 +25872,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22399,7 +25895,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22422,7 +25918,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22445,7 +25941,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22468,7 +25964,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22491,7 +25987,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22514,7 +26010,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22537,7 +26033,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22560,7 +26056,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22583,7 +26079,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22606,7 +26102,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22629,7 +26125,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22652,7 +26148,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22675,7 +26171,7 @@
],
"flaky": true,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22698,7 +26194,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22721,7 +26217,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22744,7 +26240,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22767,7 +26263,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22790,7 +26286,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22813,7 +26309,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22836,7 +26332,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22859,7 +26355,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22882,7 +26378,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22905,7 +26401,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22928,7 +26424,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22951,7 +26447,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22974,7 +26470,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -22997,7 +26493,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23020,7 +26516,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23043,7 +26539,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23066,7 +26562,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23089,7 +26585,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23112,7 +26608,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23135,7 +26631,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23158,7 +26654,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23181,7 +26677,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23204,7 +26700,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23227,7 +26723,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23250,7 +26746,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23273,7 +26769,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23296,7 +26792,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23319,7 +26815,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23342,7 +26838,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23365,7 +26861,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23388,7 +26884,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23411,7 +26907,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23434,7 +26930,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23457,7 +26953,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23480,7 +26976,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23503,7 +26999,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23526,7 +27022,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23549,7 +27045,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23572,7 +27068,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23595,7 +27091,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23618,7 +27114,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23641,7 +27137,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23664,7 +27160,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23687,7 +27183,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23710,7 +27206,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23733,7 +27229,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23756,7 +27252,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23779,7 +27275,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23802,7 +27298,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23825,7 +27321,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23848,7 +27344,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23871,7 +27367,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23894,7 +27390,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23917,7 +27413,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23940,7 +27436,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23963,7 +27459,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -23986,7 +27482,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -24009,7 +27505,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
@@ -24032,7 +27528,7 @@
],
"flaky": false,
"language": "c",
- "name": "h2_local_test",
+ "name": "h2_local_uds_test",
"platforms": [
"linux",
"mac",
diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
index 8394f07e51..7cd1ef9d51 100755
--- a/tools/run_tests/helper_scripts/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -189,6 +189,11 @@ pip_install_dir "$ROOT"
$VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py"
pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools"
+# Build/install Channelz
+$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess
+$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos
+pip_install_dir "$ROOT/src/python/grpcio_channelz"
+
# Build/install health checking
$VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" preprocess
$VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" build_package_protos
@@ -199,12 +204,18 @@ $VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" preprocess
$VENV_PYTHON "$ROOT/src/python/grpcio_reflection/setup.py" build_package_protos
pip_install_dir "$ROOT/src/python/grpcio_reflection"
+# Build/install status proto mapping
+$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" preprocess
+$VENV_PYTHON "$ROOT/src/python/grpcio_status/setup.py" build_package_protos
+pip_install_dir "$ROOT/src/python/grpcio_status"
+
# Install testing
pip_install_dir "$ROOT/src/python/grpcio_testing"
# Build/install tests
$VENV_PYTHON -m pip install coverage==4.4 oauth2client==4.1.0 \
- google-auth==1.0.0 requests==2.14.2
+ google-auth==1.0.0 requests==2.14.2 \
+ googleapis-common-protos==1.5.5
$VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" preprocess
$VENV_PYTHON "$ROOT/src/python/grpcio_tests/setup.py" build_package_protos
pip_install_dir "$ROOT/src/python/grpcio_tests"
diff --git a/tools/run_tests/performance/run_worker_csharp.sh b/tools/run_tests/performance/run_worker_csharp.sh
index 6546d6010b..bfa59b5d9e 100755
--- a/tools/run_tests/performance/run_worker_csharp.sh
+++ b/tools/run_tests/performance/run_worker_csharp.sh
@@ -18,6 +18,6 @@ set -ex
cd "$(dirname "$0")/../../.."
# needed to correctly locate testca
-cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp1.0
+cd src/csharp/Grpc.IntegrationTesting.QpsWorker/bin/Release/netcoreapp1.1
dotnet exec Grpc.IntegrationTesting.QpsWorker.dll "$@"
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index ff6682c3cf..d026145d66 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -141,8 +141,8 @@ class CSharpLanguage:
class CSharpCoreCLRLanguage:
def __init__(self):
- self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0'
- self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0'
+ self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.1'
+ self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.1'
self.safename = str(self)
def client_cmd(self, args):
@@ -545,13 +545,13 @@ class PythonLanguage:
def client_cmd(self, args):
return [
- 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py',
+ 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py',
'run_interop', '--client', '--args="{}"'.format(' '.join(args))
]
def client_cmd_http2interop(self, args):
return [
- 'py27_native/bin/python',
+ 'py37_native/bin/python',
'src/python/grpcio_tests/tests/http2/negative_http2_client.py',
] + args
@@ -560,7 +560,7 @@ class PythonLanguage:
def server_cmd(self, args):
return [
- 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py',
+ 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py',
'run_interop', '--server', '--args="{}"'.format(' '.join(args))
]
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index a1f2aaab2f..2556e77773 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -756,9 +756,10 @@ class PythonLanguage(object):
def dockerfile_dir(self):
return 'tools/dockerfile/test/python_%s_%s' % (
- self.python_manager_name(), _docker_arch_suffix(self.args.arch))
+ self._python_manager_name(), _docker_arch_suffix(self.args.arch))
- def python_manager_name(self):
+ def _python_manager_name(self):
+ """Choose the docker image to use based on python version."""
if self.args.compiler in [
'python2.7', 'python3.5', 'python3.6', 'python3.7'
]:
@@ -771,6 +772,7 @@ class PythonLanguage(object):
return 'stretch_3.7'
def _get_pythons(self, args):
+ """Get python runtimes to test with, based on current platform, architecture, compiler etc."""
if args.arch == 'x86':
bits = '32'
else:
@@ -940,7 +942,7 @@ class CSharpLanguage(object):
self._cmake_arch_option = 'x64'
else:
_check_compiler(self.args.compiler, ['default', 'coreclr'])
- self._docker_distro = 'jessie'
+ self._docker_distro = 'stretch'
def test_specs(self):
with open('src/csharp/tests.json') as f:
@@ -952,7 +954,7 @@ class CSharpLanguage(object):
assembly_extension = '.exe'
if self.args.compiler == 'coreclr':
- assembly_subdir += '/netcoreapp1.0'
+ assembly_subdir += '/netcoreapp1.1'
runtime_cmd = ['dotnet', 'exec']
assembly_extension = '.dll'
else:
@@ -1340,9 +1342,9 @@ argp.add_argument(
argp.add_argument(
'-l',
'--language',
- choices=['all'] + sorted(_LANGUAGES.keys()),
+ choices=sorted(_LANGUAGES.keys()),
nargs='+',
- default=['all'])
+ required=True)
argp.add_argument(
'-S', '--stop_on_failure', default=False, action='store_const', const=True)
argp.add_argument(
@@ -1513,17 +1515,7 @@ build_config = run_config.build_config
if args.travis:
_FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'}
-if 'all' in args.language:
- lang_list = list(_LANGUAGES.keys())
-else:
- lang_list = args.language
-# We don't support code coverage on some languages
-if 'gcov' in args.config:
- for bad in ['csharp', 'grpc-node', 'objc', 'sanity']:
- if bad in lang_list:
- lang_list.remove(bad)
-
-languages = set(_LANGUAGES[l] for l in lang_list)
+languages = set(_LANGUAGES[l] for l in args.language)
for l in languages:
l.configure(run_config, args)
@@ -1535,7 +1527,7 @@ if any(language.make_options() for language in languages):
)
sys.exit(1)
else:
- # Combining make options is not clean and just happens to work. It allows C/C++ and C# to build
+ # Combining make options is not clean and just happens to work. It allows C & C++ to build
# together, and is only used under gcov. All other configs should build languages individually.
language_make_options = list(
set([
@@ -1558,16 +1550,9 @@ if args.use_docker:
dockerfile_dirs = set([l.dockerfile_dir() for l in languages])
if len(dockerfile_dirs) > 1:
- if 'gcov' in args.config:
- dockerfile_dir = 'tools/dockerfile/test/multilang_jessie_x64'
- print(
- 'Using multilang_jessie_x64 docker image for code coverage for '
- 'all languages.')
- else:
- print(
- 'Languages to be tested require running under different docker '
- 'images.')
- sys.exit(1)
+ print('Languages to be tested require running under different docker '
+ 'images.')
+ sys.exit(1)
else:
dockerfile_dir = next(iter(dockerfile_dirs))
diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py
index d562fffc8a..1486d0bd27 100755
--- a/tools/run_tests/sanity/check_bazel_workspace.py
+++ b/tools/run_tests/sanity/check_bazel_workspace.py
@@ -42,6 +42,7 @@ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME = 'com_github_zopefoundation_zope_interf
_TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly'
_GRPC_DEP_NAMES = [
+ 'upb',
'boringssl',
'com_github_madler_zlib',
'com_google_protobuf',
@@ -110,6 +111,8 @@ bazel_file += '\ngrpc_deps()\n'
bazel_file += '\ngrpc_test_only_deps()\n'
build_rules = {
'native': eval_state,
+ 'http_archive': lambda **args: eval_state.http_archive(**args),
+ 'load': lambda a, b: None,
}
exec bazel_file in build_rules
for name in _GRPC_DEP_NAMES:
@@ -149,6 +152,8 @@ for name in _GRPC_DEP_NAMES:
names_and_urls_with_overridden_name, overridden_name=name)
rules = {
'native': state,
+ 'http_archive': lambda **args: state.http_archive(**args),
+ 'load': lambda a, b: None,
}
exec bazel_file in rules
assert name not in names_and_urls_with_overridden_name.keys()
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 8ea53dfec5..f1103596d5 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -32,11 +32,15 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules"
b29b21a81b32ec273f118f589f46d56ad3332420 third_party/boringssl (remotes/origin/chromium-stable)
afc30d43eef92979b05776ec0963c9cede5fb80f third_party/boringssl-with-bazel (fips-20180716-116-gafc30d43e)
3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
+ 911001cdca003337bdb93fab32740cde61bafee3 third_party/data-plane-api (heads/master)
30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0-5-g30dbc81)
+ 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb)
ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60)
9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60)
48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 third_party/protobuf (v3.6.0.1-37-g48cb18e5)
+ e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10)
+ 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 third_party/upb (heads/upbc-cpp)
cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
EOF