diff --git a/.gitignore b/.gitignore index f37989176ea..ed015b3c92e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ # C/C++ build outputs +.build/ bins gens libs @@ -96,3 +97,9 @@ Pods/ # Artifacts directory artifacts/ + +# Git generated files for conflicting +*.orig + +# IDE specific folder for JetBrains IDEs +.idea/ diff --git a/.gitmodules b/.gitmodules index ce647f3c455..92d5ac3e4f1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "third_party/protobuf"] path = third_party/protobuf url = https://github.com/google/protobuf.git - branch = 3.0.0-beta-3 + branch = 3.0.0-GA [submodule "third_party/gflags"] path = third_party/gflags url = https://github.com/gflags/gflags.git @@ -17,3 +17,6 @@ [submodule "third_party/nanopb"] path = third_party/nanopb url = https://github.com/nanopb/nanopb.git +[submodule "third_party/thrift"] + path = third_party/thrift + url = https://github.com/apache/thrift.git diff --git a/.travis.yml b/.travis.yml index 4cdad37c6c5..94bf382b25e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,33 +8,37 @@ env: - TEST=objc - JOBS=1 matrix: - - SCHEME="RxLibraryUnitTests" WORKSPACE="Tests.xcworkspace" - TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + - SCHEME="RxLibraryUnitTests" + WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="false" - - SCHEME="InteropTestsLocalSSL" WORKSPACE="Tests.xcworkspace" - TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="true" - - SCHEME="InteropTestsLocalCleartext" WORKSPACE="Tests.xcworkspace" - TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + - SCHEME="InteropTestsLocalSSL" + WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + INTEROP_SERVER="true" + - SCHEME="InteropTestsLocalCleartext" + WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" INTEROP_SERVER="true" # TODO(jcanizales): Make tests an app project (instead of library), so the following will work. - # - SCHEME="InteropTestsRemote" WORKSPACE="Tests.xcworkspace" - # TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" + # - SCHEME="InteropTestsRemote" + # WORKSPACE="Tests.xcworkspace" TEST_PATH="src/objective-c/tests" BUILD_ONLY="false" # INTEROP_SERVER="true" - - SCHEME="HelloWorld" WORKSPACE="HelloWorld.xcworkspace" - TEST_PATH="examples/objective-c/helloworld" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="RouteGuideClient" WORKSPACE="RouteGuideClient.xcworkspace" - TEST_PATH="examples/objective-c/route_guide" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="AuthSample" WORKSPACE="AuthSample.xcworkspace" - TEST_PATH="examples/objective-c/auth_sample" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="Sample" WORKSPACE="Sample.xcworkspace" - TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" - INTEROP_SERVER="false" - - SCHEME="SwiftSample" WORKSPACE="SwiftSample.xcworkspace" - TEST_PATH="src/objective-c/examples/SwiftSample" BUILD_ONLY="true" + - SCHEME="HelloWorld" + WORKSPACE="HelloWorld.xcworkspace" TEST_PATH="examples/objective-c/helloworld" + BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="RouteGuideClient" + WORKSPACE="RouteGuideClient.xcworkspace" TEST_PATH="examples/objective-c/route_guide" + BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="AuthSample" + WORKSPACE="AuthSample.xcworkspace" TEST_PATH="examples/objective-c/auth_sample" + BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="Sample" + WORKSPACE="Sample.xcworkspace" TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" INTEROP_SERVER="false" + - SCHEME="Sample" + WORKSPACE="Sample.xcworkspace" TEST_PATH="src/objective-c/examples/Sample" BUILD_ONLY="true" + INTEROP_SERVER="false" FRAMEWORKS="YES" + - SCHEME="SwiftSample" + WORKSPACE="SwiftSample.xcworkspace" TEST_PATH="src/objective-c/examples/SwiftSample" + BUILD_ONLY="true" INTEROP_SERVER="false" before_install: # Until Travis upgrades from Cocoapods 0.39, we need to do it here. - pod --version diff --git a/BUILD b/BUILD index 33323be229d..b934a5f337c 100644 --- a/BUILD +++ b/BUILD @@ -36,6 +36,8 @@ licenses(["notice"]) # 3-clause BSD +exports_files(["LICENSE"]) + package(default_visibility = ["//visibility:public"]) @@ -50,6 +52,7 @@ cc_library( "src/core/lib/support/block_annotate.h", "src/core/lib/support/env.h", "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/percent_encoding.h", "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", @@ -77,6 +80,7 @@ cc_library( "src/core/lib/support/log_posix.c", "src/core/lib/support/log_windows.c", "src/core/lib/support/murmur_hash.c", + "src/core/lib/support/percent_encoding.c", "src/core/lib/support/slice.c", "src/core/lib/support/slice_buffer.c", "src/core/lib/support/stack_lockfree.c", @@ -165,6 +169,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -235,6 +240,7 @@ cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "src/core/ext/transport/chttp2/transport/bin_decoder.h", @@ -256,7 +262,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/lib/security/context/security_context.h", @@ -285,7 +290,6 @@ cc_library( "src/core/lib/tsi/transport_security_interface.h", "src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel_factory.h", - "src/core/ext/client_config/client_config.h", "src/core/ext/client_config/connector.h", "src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/lb_policy.h", @@ -295,20 +299,24 @@ cc_library( "src/core/ext/client_config/resolver.h", "src/core/ext/client_config/resolver_factory.h", "src/core/ext/client_config/resolver_registry.h", + "src/core/ext/client_config/resolver_result.h", "src/core/ext/client_config/subchannel.h", - "src/core/ext/client_config/subchannel_call_holder.h", "src/core/ext/client_config/subchannel_index.h", "src/core/ext/client_config/uri_parser.h", + "src/core/ext/lb_policy/grpclb/grpclb.h", "src/core/ext/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/load_reporting/load_reporting.h", "src/core/ext/load_reporting/load_reporting_filter.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", + "src/core/ext/census/gen/trace_context.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", "src/core/lib/surface/init.c", "src/core/lib/channel/channel_args.c", @@ -316,6 +324,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -396,6 +405,7 @@ cc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c", @@ -418,7 +428,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -454,7 +463,6 @@ cc_library( "src/core/ext/client_config/channel_connectivity.c", "src/core/ext/client_config/client_channel.c", "src/core/ext/client_config/client_channel_factory.c", - "src/core/ext/client_config/client_config.c", "src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/connector.c", "src/core/ext/client_config/default_initial_connect_string.c", @@ -466,14 +474,15 @@ cc_library( "src/core/ext/client_config/resolver.c", "src/core/ext/client_config/resolver_factory.c", "src/core/ext/client_config/resolver_registry.c", + "src/core/ext/client_config/resolver_result.c", "src/core/ext/client_config/subchannel.c", - "src/core/ext/client_config/subchannel_call_holder.c", "src/core/ext/client_config/subchannel_index.c", "src/core/ext/client_config/uri_parser.c", "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c", "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c", "src/core/ext/transport/chttp2/client/insecure/channel_create.c", "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c", + "src/core/ext/lb_policy/grpclb/grpclb.c", "src/core/ext/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/lb_policy/pick_first/pick_first.c", @@ -482,8 +491,10 @@ cc_library( "src/core/ext/resolver/sockaddr/sockaddr_resolver.c", "src/core/ext/load_reporting/load_reporting.c", "src/core/ext/load_reporting/load_reporting_filter.c", + "src/core/ext/census/base_resources.c", "src/core/ext/census/context.c", "src/core/ext/census/gen/census.pb.c", + "src/core/ext/census/gen/trace_context.pb.c", "src/core/ext/census/grpc_context.c", "src/core/ext/census/grpc_filter.c", "src/core/ext/census/grpc_plugin.c", @@ -491,6 +502,7 @@ cc_library( "src/core/ext/census/mlog.c", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", "src/core/ext/census/tracing.c", "src/core/plugin_registry/grpc_plugin_registry.c", ], @@ -500,6 +512,7 @@ cc_library( "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", "include/grpc/status.h", "include/grpc/impl/codegen/byte_buffer.h", "include/grpc/impl/codegen/byte_buffer_reader.h", @@ -523,7 +536,6 @@ cc_library( "include/grpc/impl/codegen/sync_windows.h", "include/grpc/impl/codegen/time.h", "include/grpc/grpc_security.h", - "include/grpc/grpc_security_constants.h", "include/grpc/census.h", ], includes = [ @@ -552,6 +564,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -622,6 +635,7 @@ cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "third_party/objective_c/Cronet/cronet_c_for_grpc.h", @@ -644,12 +658,10 @@ cc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel_factory.h", - "src/core/ext/client_config/client_config.h", "src/core/ext/client_config/connector.h", "src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/lb_policy.h", @@ -659,8 +671,8 @@ cc_library( "src/core/ext/client_config/resolver.h", "src/core/ext/client_config/resolver_factory.h", "src/core/ext/client_config/resolver_registry.h", + "src/core/ext/client_config/resolver_result.h", "src/core/ext/client_config/subchannel.h", - "src/core/ext/client_config/subchannel_call_holder.h", "src/core/ext/client_config/subchannel_index.h", "src/core/ext/client_config/uri_parser.h", "src/core/lib/security/context/security_context.h", @@ -693,6 +705,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -773,6 +786,7 @@ cc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c", @@ -798,14 +812,12 @@ cc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", "src/core/ext/client_config/channel_connectivity.c", "src/core/ext/client_config/client_channel.c", "src/core/ext/client_config/client_channel_factory.c", - "src/core/ext/client_config/client_config.c", "src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/connector.c", "src/core/ext/client_config/default_initial_connect_string.c", @@ -817,8 +829,8 @@ cc_library( "src/core/ext/client_config/resolver.c", "src/core/ext/client_config/resolver_factory.c", "src/core/ext/client_config/resolver_registry.c", + "src/core/ext/client_config/resolver_result.c", "src/core/ext/client_config/subchannel.c", - "src/core/ext/client_config/subchannel_call_holder.c", "src/core/ext/client_config/subchannel_index.c", "src/core/ext/client_config/uri_parser.c", "src/core/lib/http/httpcli_security_connector.c", @@ -857,6 +869,7 @@ cc_library( "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", "include/grpc/status.h", "include/grpc/impl/codegen/byte_buffer.h", "include/grpc/impl/codegen/byte_buffer_reader.h", @@ -881,7 +894,6 @@ cc_library( "include/grpc/impl/codegen/time.h", "include/grpc/grpc_cronet.h", "include/grpc/grpc_security.h", - "include/grpc/grpc_security_constants.h", ], includes = [ "include", @@ -904,6 +916,7 @@ cc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -974,6 +987,7 @@ cc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "src/core/ext/transport/chttp2/transport/bin_decoder.h", @@ -995,12 +1009,10 @@ cc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel_factory.h", - "src/core/ext/client_config/client_config.h", "src/core/ext/client_config/connector.h", "src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/lb_policy.h", @@ -1010,20 +1022,24 @@ cc_library( "src/core/ext/client_config/resolver.h", "src/core/ext/client_config/resolver_factory.h", "src/core/ext/client_config/resolver_registry.h", + "src/core/ext/client_config/resolver_result.h", "src/core/ext/client_config/subchannel.h", - "src/core/ext/client_config/subchannel_call_holder.h", "src/core/ext/client_config/subchannel_index.h", "src/core/ext/client_config/uri_parser.h", "src/core/ext/load_reporting/load_reporting.h", "src/core/ext/load_reporting/load_reporting_filter.h", + "src/core/ext/lb_policy/grpclb/grpclb.h", "src/core/ext/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", + "src/core/ext/census/gen/trace_context.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", "src/core/lib/surface/init.c", "src/core/lib/surface/init_unsecure.c", @@ -1032,6 +1048,7 @@ cc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -1112,6 +1129,7 @@ cc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c", @@ -1135,7 +1153,6 @@ cc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -1144,7 +1161,6 @@ cc_library( "src/core/ext/client_config/channel_connectivity.c", "src/core/ext/client_config/client_channel.c", "src/core/ext/client_config/client_channel_factory.c", - "src/core/ext/client_config/client_config.c", "src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/connector.c", "src/core/ext/client_config/default_initial_connect_string.c", @@ -1156,20 +1172,23 @@ cc_library( "src/core/ext/client_config/resolver.c", "src/core/ext/client_config/resolver_factory.c", "src/core/ext/client_config/resolver_registry.c", + "src/core/ext/client_config/resolver_result.c", "src/core/ext/client_config/subchannel.c", - "src/core/ext/client_config/subchannel_call_holder.c", "src/core/ext/client_config/subchannel_index.c", "src/core/ext/client_config/uri_parser.c", "src/core/ext/resolver/dns/native/dns_resolver.c", "src/core/ext/resolver/sockaddr/sockaddr_resolver.c", "src/core/ext/load_reporting/load_reporting.c", "src/core/ext/load_reporting/load_reporting_filter.c", + "src/core/ext/lb_policy/grpclb/grpclb.c", "src/core/ext/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/lb_policy/pick_first/pick_first.c", "src/core/ext/lb_policy/round_robin/round_robin.c", + "src/core/ext/census/base_resources.c", "src/core/ext/census/context.c", "src/core/ext/census/gen/census.pb.c", + "src/core/ext/census/gen/trace_context.pb.c", "src/core/ext/census/grpc_context.c", "src/core/ext/census/grpc_filter.c", "src/core/ext/census/grpc_plugin.c", @@ -1177,6 +1196,7 @@ cc_library( "src/core/ext/census/mlog.c", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", "src/core/ext/census/tracing.c", "src/core/plugin_registry/grpc_unsecure_plugin_registry.c", ], @@ -1186,6 +1206,7 @@ cc_library( "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", "include/grpc/status.h", "include/grpc/impl/codegen/byte_buffer.h", "include/grpc/impl/codegen/byte_buffer_reader.h", @@ -1233,8 +1254,89 @@ cc_library( "src/cpp/common/secure_auth_context.h", "src/cpp/server/secure_server_credentials.h", "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/ev_epoll_linux.h", + "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_posix.h", + "src/core/lib/iomgr/ev_posix.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/load_file.h", + "src/core/lib/iomgr/network_status_tracker.h", + "src/core/lib/iomgr/polling_entity.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_windows.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", "src/cpp/client/secure_credentials.cc", "src/cpp/common/auth_property_iterator.cc", "src/cpp/common/secure_auth_context.cc", @@ -1250,6 +1352,7 @@ cc_library( "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", @@ -1267,6 +1370,95 @@ cc_library( "src/cpp/util/status.cc", "src/cpp/util/string_ref.cc", "src/cpp/util/time.cc", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/compression/compression.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/debug/trace.c", + "src/core/lib/http/format_request.c", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/parser.c", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/error.c", + "src/core/lib/iomgr/ev_epoll_linux.c", + "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_posix.c", + "src/core/lib/iomgr/ev_posix.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/load_file.c", + "src/core/lib/iomgr/network_status_tracker.c", + "src/core/lib/iomgr/polling_entity.c", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/json/json.c", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport_op_string.c", "src/cpp/codegen/codegen_init.cc", ], hdrs = [ @@ -1317,6 +1509,34 @@ cc_library( "include/grpc++/support/stub_options.h", "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/compression.h", + "include/grpc/grpc.h", + "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", + "include/grpc/status.h", + "include/grpc/impl/codegen/byte_buffer.h", + "include/grpc/impl/codegen/byte_buffer_reader.h", + "include/grpc/impl/codegen/compression_types.h", + "include/grpc/impl/codegen/connectivity_state.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/status.h", + "include/grpc/impl/codegen/alloc.h", + "include/grpc/impl/codegen/atm.h", + "include/grpc/impl/codegen/atm_gcc_atomic.h", + "include/grpc/impl/codegen/atm_gcc_sync.h", + "include/grpc/impl/codegen/atm_windows.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/slice_buffer.h", + "include/grpc/impl/codegen/sync.h", + "include/grpc/impl/codegen/sync_generic.h", + "include/grpc/impl/codegen/sync_posix.h", + "include/grpc/impl/codegen/sync_windows.h", + "include/grpc/impl/codegen/time.h", "include/grpc++/impl/codegen/async_stream.h", "include/grpc++/impl/codegen/async_unary_call.h", "include/grpc++/impl/codegen/call.h", @@ -1347,27 +1567,6 @@ cc_library( "include/grpc++/impl/codegen/sync_no_cxx11.h", "include/grpc++/impl/codegen/sync_stream.h", "include/grpc++/impl/codegen/time.h", - "include/grpc/impl/codegen/byte_buffer.h", - "include/grpc/impl/codegen/byte_buffer_reader.h", - "include/grpc/impl/codegen/compression_types.h", - "include/grpc/impl/codegen/connectivity_state.h", - "include/grpc/impl/codegen/grpc_types.h", - "include/grpc/impl/codegen/propagation_bits.h", - "include/grpc/impl/codegen/status.h", - "include/grpc/impl/codegen/alloc.h", - "include/grpc/impl/codegen/atm.h", - "include/grpc/impl/codegen/atm_gcc_atomic.h", - "include/grpc/impl/codegen/atm_gcc_sync.h", - "include/grpc/impl/codegen/atm_windows.h", - "include/grpc/impl/codegen/log.h", - "include/grpc/impl/codegen/port_platform.h", - "include/grpc/impl/codegen/slice.h", - "include/grpc/impl/codegen/slice_buffer.h", - "include/grpc/impl/codegen/sync.h", - "include/grpc/impl/codegen/sync_generic.h", - "include/grpc/impl/codegen/sync_posix.h", - "include/grpc/impl/codegen/sync_windows.h", - "include/grpc/impl/codegen/time.h", ], includes = [ "include", @@ -1377,6 +1576,7 @@ cc_library( "//external:libssl", "//external:protobuf_clib", ":grpc", + ":gpr", ], ) @@ -1464,8 +1664,89 @@ cc_library( name = "grpc++_unsecure", srcs = [ "src/cpp/client/create_channel_internal.h", + "src/cpp/common/channel_filter.h", "src/cpp/server/dynamic_thread_pool.h", "src/cpp/server/thread_pool_interface.h", + "src/core/lib/channel/channel_args.h", + "src/core/lib/channel/channel_stack.h", + "src/core/lib/channel/channel_stack_builder.h", + "src/core/lib/channel/compress_filter.h", + "src/core/lib/channel/connected_channel.h", + "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", + "src/core/lib/channel/http_client_filter.h", + "src/core/lib/channel/http_server_filter.h", + "src/core/lib/compression/algorithm_metadata.h", + "src/core/lib/compression/message_compress.h", + "src/core/lib/debug/trace.h", + "src/core/lib/http/format_request.h", + "src/core/lib/http/httpcli.h", + "src/core/lib/http/parser.h", + "src/core/lib/iomgr/closure.h", + "src/core/lib/iomgr/endpoint.h", + "src/core/lib/iomgr/endpoint_pair.h", + "src/core/lib/iomgr/error.h", + "src/core/lib/iomgr/ev_epoll_linux.h", + "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", + "src/core/lib/iomgr/ev_poll_posix.h", + "src/core/lib/iomgr/ev_posix.h", + "src/core/lib/iomgr/exec_ctx.h", + "src/core/lib/iomgr/executor.h", + "src/core/lib/iomgr/iocp_windows.h", + "src/core/lib/iomgr/iomgr.h", + "src/core/lib/iomgr/iomgr_internal.h", + "src/core/lib/iomgr/iomgr_posix.h", + "src/core/lib/iomgr/load_file.h", + "src/core/lib/iomgr/network_status_tracker.h", + "src/core/lib/iomgr/polling_entity.h", + "src/core/lib/iomgr/pollset.h", + "src/core/lib/iomgr/pollset_set.h", + "src/core/lib/iomgr/pollset_set_windows.h", + "src/core/lib/iomgr/pollset_windows.h", + "src/core/lib/iomgr/resolve_address.h", + "src/core/lib/iomgr/sockaddr.h", + "src/core/lib/iomgr/sockaddr_posix.h", + "src/core/lib/iomgr/sockaddr_utils.h", + "src/core/lib/iomgr/sockaddr_windows.h", + "src/core/lib/iomgr/socket_utils_posix.h", + "src/core/lib/iomgr/socket_windows.h", + "src/core/lib/iomgr/tcp_client.h", + "src/core/lib/iomgr/tcp_posix.h", + "src/core/lib/iomgr/tcp_server.h", + "src/core/lib/iomgr/tcp_windows.h", + "src/core/lib/iomgr/time_averaged_stats.h", + "src/core/lib/iomgr/timer.h", + "src/core/lib/iomgr/timer_heap.h", + "src/core/lib/iomgr/udp_server.h", + "src/core/lib/iomgr/unix_sockets_posix.h", + "src/core/lib/iomgr/wakeup_fd_pipe.h", + "src/core/lib/iomgr/wakeup_fd_posix.h", + "src/core/lib/iomgr/workqueue.h", + "src/core/lib/iomgr/workqueue_posix.h", + "src/core/lib/iomgr/workqueue_windows.h", + "src/core/lib/json/json.h", + "src/core/lib/json/json_common.h", + "src/core/lib/json/json_reader.h", + "src/core/lib/json/json_writer.h", + "src/core/lib/surface/api_trace.h", + "src/core/lib/surface/call.h", + "src/core/lib/surface/call_test_only.h", + "src/core/lib/surface/channel.h", + "src/core/lib/surface/channel_init.h", + "src/core/lib/surface/channel_stack_type.h", + "src/core/lib/surface/completion_queue.h", + "src/core/lib/surface/event_string.h", + "src/core/lib/surface/init.h", + "src/core/lib/surface/lame_client.h", + "src/core/lib/surface/server.h", + "src/core/lib/transport/byte_stream.h", + "src/core/lib/transport/connectivity_state.h", + "src/core/lib/transport/metadata.h", + "src/core/lib/transport/metadata_batch.h", + "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", + "src/core/lib/transport/transport.h", + "src/core/lib/transport/transport_impl.h", "src/cpp/common/insecure_create_auth_context.cc", "src/cpp/client/channel.cc", "src/cpp/client/client_context.cc", @@ -1476,6 +1757,7 @@ cc_library( "src/cpp/client/generic_stub.cc", "src/cpp/client/insecure_credentials.cc", "src/cpp/common/channel_arguments.cc", + "src/cpp/common/channel_filter.cc", "src/cpp/common/completion_queue.cc", "src/cpp/common/core_codegen.cc", "src/cpp/common/rpc_method.cc", @@ -1493,6 +1775,95 @@ cc_library( "src/cpp/util/status.cc", "src/cpp/util/string_ref.cc", "src/cpp/util/time.cc", + "src/core/lib/channel/channel_args.c", + "src/core/lib/channel/channel_stack.c", + "src/core/lib/channel/channel_stack_builder.c", + "src/core/lib/channel/compress_filter.c", + "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", + "src/core/lib/channel/http_client_filter.c", + "src/core/lib/channel/http_server_filter.c", + "src/core/lib/compression/compression.c", + "src/core/lib/compression/message_compress.c", + "src/core/lib/debug/trace.c", + "src/core/lib/http/format_request.c", + "src/core/lib/http/httpcli.c", + "src/core/lib/http/parser.c", + "src/core/lib/iomgr/closure.c", + "src/core/lib/iomgr/endpoint.c", + "src/core/lib/iomgr/endpoint_pair_posix.c", + "src/core/lib/iomgr/endpoint_pair_windows.c", + "src/core/lib/iomgr/error.c", + "src/core/lib/iomgr/ev_epoll_linux.c", + "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", + "src/core/lib/iomgr/ev_poll_posix.c", + "src/core/lib/iomgr/ev_posix.c", + "src/core/lib/iomgr/exec_ctx.c", + "src/core/lib/iomgr/executor.c", + "src/core/lib/iomgr/iocp_windows.c", + "src/core/lib/iomgr/iomgr.c", + "src/core/lib/iomgr/iomgr_posix.c", + "src/core/lib/iomgr/iomgr_windows.c", + "src/core/lib/iomgr/load_file.c", + "src/core/lib/iomgr/network_status_tracker.c", + "src/core/lib/iomgr/polling_entity.c", + "src/core/lib/iomgr/pollset_set_windows.c", + "src/core/lib/iomgr/pollset_windows.c", + "src/core/lib/iomgr/resolve_address_posix.c", + "src/core/lib/iomgr/resolve_address_windows.c", + "src/core/lib/iomgr/sockaddr_utils.c", + "src/core/lib/iomgr/socket_utils_common_posix.c", + "src/core/lib/iomgr/socket_utils_linux.c", + "src/core/lib/iomgr/socket_utils_posix.c", + "src/core/lib/iomgr/socket_windows.c", + "src/core/lib/iomgr/tcp_client_posix.c", + "src/core/lib/iomgr/tcp_client_windows.c", + "src/core/lib/iomgr/tcp_posix.c", + "src/core/lib/iomgr/tcp_server_posix.c", + "src/core/lib/iomgr/tcp_server_windows.c", + "src/core/lib/iomgr/tcp_windows.c", + "src/core/lib/iomgr/time_averaged_stats.c", + "src/core/lib/iomgr/timer.c", + "src/core/lib/iomgr/timer_heap.c", + "src/core/lib/iomgr/udp_server.c", + "src/core/lib/iomgr/unix_sockets_posix.c", + "src/core/lib/iomgr/unix_sockets_posix_noop.c", + "src/core/lib/iomgr/wakeup_fd_eventfd.c", + "src/core/lib/iomgr/wakeup_fd_nospecial.c", + "src/core/lib/iomgr/wakeup_fd_pipe.c", + "src/core/lib/iomgr/wakeup_fd_posix.c", + "src/core/lib/iomgr/workqueue_posix.c", + "src/core/lib/iomgr/workqueue_windows.c", + "src/core/lib/json/json.c", + "src/core/lib/json/json_reader.c", + "src/core/lib/json/json_string.c", + "src/core/lib/json/json_writer.c", + "src/core/lib/surface/alarm.c", + "src/core/lib/surface/api_trace.c", + "src/core/lib/surface/byte_buffer.c", + "src/core/lib/surface/byte_buffer_reader.c", + "src/core/lib/surface/call.c", + "src/core/lib/surface/call_details.c", + "src/core/lib/surface/call_log_batch.c", + "src/core/lib/surface/channel.c", + "src/core/lib/surface/channel_init.c", + "src/core/lib/surface/channel_ping.c", + "src/core/lib/surface/channel_stack_type.c", + "src/core/lib/surface/completion_queue.c", + "src/core/lib/surface/event_string.c", + "src/core/lib/surface/lame_client.c", + "src/core/lib/surface/metadata_array.c", + "src/core/lib/surface/server.c", + "src/core/lib/surface/validate_metadata.c", + "src/core/lib/surface/version.c", + "src/core/lib/transport/byte_stream.c", + "src/core/lib/transport/connectivity_state.c", + "src/core/lib/transport/metadata.c", + "src/core/lib/transport/metadata_batch.c", + "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", + "src/core/lib/transport/transport.c", + "src/core/lib/transport/transport_op_string.c", "src/cpp/codegen/codegen_init.cc", ], hdrs = [ @@ -1543,6 +1914,34 @@ cc_library( "include/grpc++/support/stub_options.h", "include/grpc++/support/sync_stream.h", "include/grpc++/support/time.h", + "include/grpc/byte_buffer.h", + "include/grpc/byte_buffer_reader.h", + "include/grpc/compression.h", + "include/grpc/grpc.h", + "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", + "include/grpc/status.h", + "include/grpc/impl/codegen/byte_buffer.h", + "include/grpc/impl/codegen/byte_buffer_reader.h", + "include/grpc/impl/codegen/compression_types.h", + "include/grpc/impl/codegen/connectivity_state.h", + "include/grpc/impl/codegen/grpc_types.h", + "include/grpc/impl/codegen/propagation_bits.h", + "include/grpc/impl/codegen/status.h", + "include/grpc/impl/codegen/alloc.h", + "include/grpc/impl/codegen/atm.h", + "include/grpc/impl/codegen/atm_gcc_atomic.h", + "include/grpc/impl/codegen/atm_gcc_sync.h", + "include/grpc/impl/codegen/atm_windows.h", + "include/grpc/impl/codegen/log.h", + "include/grpc/impl/codegen/port_platform.h", + "include/grpc/impl/codegen/slice.h", + "include/grpc/impl/codegen/slice_buffer.h", + "include/grpc/impl/codegen/sync.h", + "include/grpc/impl/codegen/sync_generic.h", + "include/grpc/impl/codegen/sync_posix.h", + "include/grpc/impl/codegen/sync_windows.h", + "include/grpc/impl/codegen/time.h", "include/grpc++/impl/codegen/async_stream.h", "include/grpc++/impl/codegen/async_unary_call.h", "include/grpc++/impl/codegen/call.h", @@ -1573,27 +1972,6 @@ cc_library( "include/grpc++/impl/codegen/sync_no_cxx11.h", "include/grpc++/impl/codegen/sync_stream.h", "include/grpc++/impl/codegen/time.h", - "include/grpc/impl/codegen/byte_buffer.h", - "include/grpc/impl/codegen/byte_buffer_reader.h", - "include/grpc/impl/codegen/compression_types.h", - "include/grpc/impl/codegen/connectivity_state.h", - "include/grpc/impl/codegen/grpc_types.h", - "include/grpc/impl/codegen/propagation_bits.h", - "include/grpc/impl/codegen/status.h", - "include/grpc/impl/codegen/alloc.h", - "include/grpc/impl/codegen/atm.h", - "include/grpc/impl/codegen/atm_gcc_atomic.h", - "include/grpc/impl/codegen/atm_gcc_sync.h", - "include/grpc/impl/codegen/atm_windows.h", - "include/grpc/impl/codegen/log.h", - "include/grpc/impl/codegen/port_platform.h", - "include/grpc/impl/codegen/slice.h", - "include/grpc/impl/codegen/slice_buffer.h", - "include/grpc/impl/codegen/sync.h", - "include/grpc/impl/codegen/sync_generic.h", - "include/grpc/impl/codegen/sync_posix.h", - "include/grpc/impl/codegen/sync_windows.h", - "include/grpc/impl/codegen/time.h", ], includes = [ "include", @@ -1603,7 +1981,6 @@ cc_library( "//external:protobuf_clib", ":gpr", ":grpc_unsecure", - ":grpc", ], ) @@ -1692,6 +2069,7 @@ objc_library( "src/core/lib/support/log_posix.c", "src/core/lib/support/log_windows.c", "src/core/lib/support/murmur_hash.c", + "src/core/lib/support/percent_encoding.c", "src/core/lib/support/slice.c", "src/core/lib/support/slice_buffer.c", "src/core/lib/support/stack_lockfree.c", @@ -1765,6 +2143,7 @@ objc_library( "src/core/lib/support/block_annotate.h", "src/core/lib/support/env.h", "src/core/lib/support/murmur_hash.h", + "src/core/lib/support/percent_encoding.h", "src/core/lib/support/stack_lockfree.h", "src/core/lib/support/string.h", "src/core/lib/support/string_windows.h", @@ -1791,6 +2170,7 @@ objc_library( "src/core/lib/channel/channel_stack_builder.c", "src/core/lib/channel/compress_filter.c", "src/core/lib/channel/connected_channel.c", + "src/core/lib/channel/handshaker.c", "src/core/lib/channel/http_client_filter.c", "src/core/lib/channel/http_server_filter.c", "src/core/lib/compression/compression.c", @@ -1871,6 +2251,7 @@ objc_library( "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/static_metadata.c", + "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", "src/core/lib/transport/transport_op_string.c", "src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c", @@ -1893,7 +2274,6 @@ objc_library( "src/core/ext/transport/chttp2/transport/status_conversion.c", "src/core/ext/transport/chttp2/transport/stream_lists.c", "src/core/ext/transport/chttp2/transport/stream_map.c", - "src/core/ext/transport/chttp2/transport/timeout_encoding.c", "src/core/ext/transport/chttp2/transport/varint.c", "src/core/ext/transport/chttp2/transport/writing.c", "src/core/ext/transport/chttp2/alpn/alpn.c", @@ -1929,7 +2309,6 @@ objc_library( "src/core/ext/client_config/channel_connectivity.c", "src/core/ext/client_config/client_channel.c", "src/core/ext/client_config/client_channel_factory.c", - "src/core/ext/client_config/client_config.c", "src/core/ext/client_config/client_config_plugin.c", "src/core/ext/client_config/connector.c", "src/core/ext/client_config/default_initial_connect_string.c", @@ -1941,14 +2320,15 @@ objc_library( "src/core/ext/client_config/resolver.c", "src/core/ext/client_config/resolver_factory.c", "src/core/ext/client_config/resolver_registry.c", + "src/core/ext/client_config/resolver_result.c", "src/core/ext/client_config/subchannel.c", - "src/core/ext/client_config/subchannel_call_holder.c", "src/core/ext/client_config/subchannel_index.c", "src/core/ext/client_config/uri_parser.c", "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c", "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c", "src/core/ext/transport/chttp2/client/insecure/channel_create.c", "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c", + "src/core/ext/lb_policy/grpclb/grpclb.c", "src/core/ext/lb_policy/grpclb/load_balancer_api.c", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c", "src/core/ext/lb_policy/pick_first/pick_first.c", @@ -1957,8 +2337,10 @@ objc_library( "src/core/ext/resolver/sockaddr/sockaddr_resolver.c", "src/core/ext/load_reporting/load_reporting.c", "src/core/ext/load_reporting/load_reporting_filter.c", + "src/core/ext/census/base_resources.c", "src/core/ext/census/context.c", "src/core/ext/census/gen/census.pb.c", + "src/core/ext/census/gen/trace_context.pb.c", "src/core/ext/census/grpc_context.c", "src/core/ext/census/grpc_filter.c", "src/core/ext/census/grpc_plugin.c", @@ -1966,6 +2348,7 @@ objc_library( "src/core/ext/census/mlog.c", "src/core/ext/census/operation.c", "src/core/ext/census/placeholders.c", + "src/core/ext/census/resource.c", "src/core/ext/census/tracing.c", "src/core/plugin_registry/grpc_plugin_registry.c", ], @@ -1975,6 +2358,7 @@ objc_library( "include/grpc/compression.h", "include/grpc/grpc.h", "include/grpc/grpc_posix.h", + "include/grpc/grpc_security_constants.h", "include/grpc/status.h", "include/grpc/impl/codegen/byte_buffer.h", "include/grpc/impl/codegen/byte_buffer_reader.h", @@ -1998,7 +2382,6 @@ objc_library( "include/grpc/impl/codegen/sync_windows.h", "include/grpc/impl/codegen/time.h", "include/grpc/grpc_security.h", - "include/grpc/grpc_security_constants.h", "include/grpc/census.h", "src/core/lib/channel/channel_args.h", "src/core/lib/channel/channel_stack.h", @@ -2006,6 +2389,7 @@ objc_library( "src/core/lib/channel/compress_filter.h", "src/core/lib/channel/connected_channel.h", "src/core/lib/channel/context.h", + "src/core/lib/channel/handshaker.h", "src/core/lib/channel/http_client_filter.h", "src/core/lib/channel/http_server_filter.h", "src/core/lib/compression/algorithm_metadata.h", @@ -2076,6 +2460,7 @@ objc_library( "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", "src/core/lib/transport/static_metadata.h", + "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", "src/core/lib/transport/transport_impl.h", "src/core/ext/transport/chttp2/transport/bin_decoder.h", @@ -2097,7 +2482,6 @@ objc_library( "src/core/ext/transport/chttp2/transport/internal.h", "src/core/ext/transport/chttp2/transport/status_conversion.h", "src/core/ext/transport/chttp2/transport/stream_map.h", - "src/core/ext/transport/chttp2/transport/timeout_encoding.h", "src/core/ext/transport/chttp2/transport/varint.h", "src/core/ext/transport/chttp2/alpn/alpn.h", "src/core/lib/security/context/security_context.h", @@ -2126,7 +2510,6 @@ objc_library( "src/core/lib/tsi/transport_security_interface.h", "src/core/ext/client_config/client_channel.h", "src/core/ext/client_config/client_channel_factory.h", - "src/core/ext/client_config/client_config.h", "src/core/ext/client_config/connector.h", "src/core/ext/client_config/initial_connect_string.h", "src/core/ext/client_config/lb_policy.h", @@ -2136,20 +2519,24 @@ objc_library( "src/core/ext/client_config/resolver.h", "src/core/ext/client_config/resolver_factory.h", "src/core/ext/client_config/resolver_registry.h", + "src/core/ext/client_config/resolver_result.h", "src/core/ext/client_config/subchannel.h", - "src/core/ext/client_config/subchannel_call_holder.h", "src/core/ext/client_config/subchannel_index.h", "src/core/ext/client_config/uri_parser.h", + "src/core/ext/lb_policy/grpclb/grpclb.h", "src/core/ext/lb_policy/grpclb/load_balancer_api.h", "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h", "src/core/ext/load_reporting/load_reporting.h", "src/core/ext/load_reporting/load_reporting_filter.h", "src/core/ext/census/aggregation.h", + "src/core/ext/census/base_resources.h", "src/core/ext/census/census_interface.h", "src/core/ext/census/census_rpc_stats.h", "src/core/ext/census/gen/census.pb.h", + "src/core/ext/census/gen/trace_context.pb.h", "src/core/ext/census/grpc_filter.h", "src/core/ext/census/mlog.h", + "src/core/ext/census/resource.h", "src/core/ext/census/rpc_metric_id.h", ], includes = [ diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c0059cd2db..7c6ae34e8d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,29 +48,126 @@ set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") project(${PACKAGE_NAME} C CXX) -if(NOT BORINGSSL_ROOT_DIR) - set(BORINGSSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/boringssl) +if (NOT MSVC) + set(gRPC_INSTALL ON CACHE BOOL "Generate installation target") +else() + set(gRPC_INSTALL OFF CACHE BOOL "Generate installation target") endif() -if(NOT PROTOBUF_ROOT_DIR) - set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf) + +set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library") +set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library") +set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library") +set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package") + +set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library") + +if (MSVC) + add_definitions( -D_WIN32_WINNT=0x600 ) endif() -if(NOT ZLIB_ROOT_DIR) - set(ZLIB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zlib) + +if (gRPC_USE_PROTO_LITE) + set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite") + add_definitions("-DGRPC_USE_PROTO_LITE") +else() + set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") endif() -# Building the protobuf tests require gmock what is not part of a standard protobuf checkout. -# Disable them unless they are explicitly requested from the cmake command line (when we assume -# gmock is downloaded to the right location inside protobuf). -if(NOT protobuf_BUILD_TESTS) - set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build protobuf tests") +if("${gRPC_ZLIB_PROVIDER}" STREQUAL "module") + if(NOT ZLIB_ROOT_DIR) + set(ZLIB_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zlib) + endif() + set(ZLIB_INCLUDE_DIR "${ZLIB_ROOT_DIR}") + if(EXISTS "${ZLIB_ROOT_DIR}/CMakeLists.txt") + add_subdirectory(${ZLIB_ROOT_DIR} third_party/zlib) + if(TARGET zlibstatic) + set(_gRPC_ZLIB_LIBRARIES zlibstatic) + endif() + else() + message(WARNING "gRPC_ZLIB_PROVIDER is \"module\" but ZLIB_ROOT_DIR is wrong") + endif() +elseif("${gRPC_ZLIB_PROVIDER}" STREQUAL "package") + find_package(ZLIB) + if(TARGET ZLIB::ZLIB) + set(_gRPC_ZLIB_LIBRARIES ZLIB::ZLIB) + endif() + set(_gRPC_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()") endif() -add_subdirectory(${BORINGSSL_ROOT_DIR} third_party/boringssl) -add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf) -add_subdirectory(${ZLIB_ROOT_DIR} third_party/zlib) +if("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "module") + # Building the protobuf tests require gmock what is not part of a standard protobuf checkout. + # Disable them unless they are explicitly requested from the cmake command line (when we assume + # gmock is downloaded to the right location inside protobuf). + if(NOT protobuf_BUILD_TESTS) + set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build protobuf tests") + endif() + if(NOT PROTOBUF_ROOT_DIR) + set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf) + endif() + if(EXISTS "${PROTOBUF_ROOT_DIR}/cmake/CMakeLists.txt") + set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries") + add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf) + if(TARGET ${_gRPC_PROTOBUF_LIBRARY_NAME}) + set(_gRPC_PROTOBUF_LIBRARIES ${_gRPC_PROTOBUF_LIBRARY_NAME}) + endif() + if(TARGET libprotoc) + set(_gRPC_PROTOBUF_PROTOC_LIBRARIES libprotoc) + endif() + else() + message(WARNING "gRPC_PROTOBUF_PROVIDER is \"module\" but PROTOBUF_ROOT_DIR is wrong") + endif() +elseif("${gRPC_PROTOBUF_PROVIDER}" STREQUAL "package") + find_package(protobuf CONFIG) + if(protobuf_FOUND) + if(TARGET protobuf::${_gRPC_PROTOBUF_LIBRARY_NAME}) + set(_gRPC_PROTOBUF_LIBRARIES protobuf::${_gRPC_PROTOBUF_LIBRARY_NAME}) + endif() + if(TARGET protobuf::libprotoc) + set(_gRPC_PROTOBUF_PROTOC_LIBRARIES protobuf::libprotoc) + endif() + set(_gRPC_FIND_PROTOBUF "if(NOT protobuf_FOUND)\n find_package(protobuf CONFIG)\nendif()") + else() + find_package(Protobuf MODULE) + set(_gRPC_FIND_PROTOBUF "if(NOT Protobuf_FOUND)\n find_package(Protobuf)\nendif()") + endif() +endif() -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +if("${gRPC_SSL_PROVIDER}" STREQUAL "module") + if(NOT BORINGSSL_ROOT_DIR) + set(BORINGSSL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/boringssl) + endif() + if(EXISTS "${BORINGSSL_ROOT_DIR}/CMakeLists.txt") + add_subdirectory(${BORINGSSL_ROOT_DIR} third_party/boringssl) + if(TARGET ssl) + set(_gRPC_SSL_LIBRARIES ssl) + endif() + else() + message(WARNING "gRPC_SSL_PROVIDER is \"module\" but BORINGSSL_ROOT_DIR is wrong") + endif() +elseif("${gRPC_SSL_PROVIDER}" STREQUAL "package") + find_package(OpenSSL) + if(TARGET OpenSSL::SSL) + set(_gRPC_SSL_LIBRARIES OpenSSL::SSL) + endif() + set(_gRPC_FIND_SSL "if(NOT OpenSSL_FOUND)\n find_package(OpenSSL)\nendif()") +endif() + +if(NOT MSVC) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") +endif() + +if(WIN32 AND MSVC) + set(_gRPC_BASELIB_LIBRARIES wsock32 ws2_32) +endif() + +include(GNUInstallDirs) +if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR) + set(CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/gRPC") +endif() add_library(gpr @@ -95,6 +192,7 @@ add_library(gpr src/core/lib/support/log_posix.c src/core/lib/support/log_windows.c src/core/lib/support/murmur_hash.c + src/core/lib/support/percent_encoding.c src/core/lib/support/slice.c src/core/lib/support/slice_buffer.c src/core/lib/support/stack_lockfree.c @@ -126,11 +224,71 @@ target_include_directories(gpr PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) +foreach(_hdr + include/grpc/support/alloc.h + include/grpc/support/atm.h + include/grpc/support/atm_gcc_atomic.h + include/grpc/support/atm_gcc_sync.h + include/grpc/support/atm_windows.h + include/grpc/support/avl.h + include/grpc/support/cmdline.h + include/grpc/support/cpu.h + include/grpc/support/histogram.h + include/grpc/support/host_port.h + include/grpc/support/log.h + include/grpc/support/log_windows.h + include/grpc/support/port_platform.h + include/grpc/support/slice.h + include/grpc/support/slice_buffer.h + include/grpc/support/string_util.h + include/grpc/support/subprocess.h + include/grpc/support/sync.h + include/grpc/support/sync_generic.h + include/grpc/support/sync_posix.h + include/grpc/support/sync_windows.h + include/grpc/support/thd.h + include/grpc/support/time.h + include/grpc/support/tls.h + include/grpc/support/tls_gcc.h + include/grpc/support/tls_msvc.h + include/grpc/support/tls_pthread.h + include/grpc/support/useful.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS gpr EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + add_library(grpc src/core/lib/surface/init.c @@ -139,6 +297,7 @@ add_library(grpc src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -219,6 +378,7 @@ add_library(grpc src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -241,7 +401,6 @@ add_library(grpc src/core/ext/transport/chttp2/transport/status_conversion.c src/core/ext/transport/chttp2/transport/stream_lists.c src/core/ext/transport/chttp2/transport/stream_map.c - src/core/ext/transport/chttp2/transport/timeout_encoding.c src/core/ext/transport/chttp2/transport/varint.c src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c @@ -277,7 +436,6 @@ add_library(grpc src/core/ext/client_config/channel_connectivity.c src/core/ext/client_config/client_channel.c src/core/ext/client_config/client_channel_factory.c - src/core/ext/client_config/client_config.c src/core/ext/client_config/client_config_plugin.c src/core/ext/client_config/connector.c src/core/ext/client_config/default_initial_connect_string.c @@ -289,14 +447,15 @@ add_library(grpc src/core/ext/client_config/resolver.c src/core/ext/client_config/resolver_factory.c src/core/ext/client_config/resolver_registry.c + src/core/ext/client_config/resolver_result.c src/core/ext/client_config/subchannel.c - src/core/ext/client_config/subchannel_call_holder.c src/core/ext/client_config/subchannel_index.c src/core/ext/client_config/uri_parser.c src/core/ext/transport/chttp2/server/insecure/server_chttp2.c src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c src/core/ext/transport/chttp2/client/insecure/channel_create.c src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c + src/core/ext/lb_policy/grpclb/grpclb.c src/core/ext/lb_policy/grpclb/load_balancer_api.c src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c third_party/nanopb/pb_common.c @@ -308,8 +467,10 @@ add_library(grpc src/core/ext/resolver/sockaddr/sockaddr_resolver.c src/core/ext/load_reporting/load_reporting.c src/core/ext/load_reporting/load_reporting_filter.c + src/core/ext/census/base_resources.c src/core/ext/census/context.c src/core/ext/census/gen/census.pb.c + src/core/ext/census/gen/trace_context.pb.c src/core/ext/census/grpc_context.c src/core/ext/census/grpc_filter.c src/core/ext/census/grpc_plugin.c @@ -317,6 +478,7 @@ add_library(grpc src/core/ext/census/mlog.c src/core/ext/census/operation.c src/core/ext/census/placeholders.c + src/core/ext/census/resource.c src/core/ext/census/tracing.c src/core/plugin_registry/grpc_plugin_registry.c ) @@ -326,16 +488,65 @@ target_include_directories(grpc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) target_link_libraries(grpc - ssl - zlibstatic + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_ZLIB_LIBRARIES} gpr ) +foreach(_hdr + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/compression.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security_constants.h + include/grpc/status.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h + include/grpc/grpc_security.h + include/grpc/census.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + add_library(grpc_cronet src/core/lib/surface/init.c @@ -344,6 +555,7 @@ add_library(grpc_cronet src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -424,6 +636,7 @@ add_library(grpc_cronet src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/ext/transport/cronet/client/secure/cronet_channel_create.c @@ -449,14 +662,12 @@ add_library(grpc_cronet src/core/ext/transport/chttp2/transport/status_conversion.c src/core/ext/transport/chttp2/transport/stream_lists.c src/core/ext/transport/chttp2/transport/stream_map.c - src/core/ext/transport/chttp2/transport/timeout_encoding.c src/core/ext/transport/chttp2/transport/varint.c src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c src/core/ext/client_config/channel_connectivity.c src/core/ext/client_config/client_channel.c src/core/ext/client_config/client_channel_factory.c - src/core/ext/client_config/client_config.c src/core/ext/client_config/client_config_plugin.c src/core/ext/client_config/connector.c src/core/ext/client_config/default_initial_connect_string.c @@ -468,8 +679,8 @@ add_library(grpc_cronet src/core/ext/client_config/resolver.c src/core/ext/client_config/resolver_factory.c src/core/ext/client_config/resolver_registry.c + src/core/ext/client_config/resolver_result.c src/core/ext/client_config/subchannel.c - src/core/ext/client_config/subchannel_call_holder.c src/core/ext/client_config/subchannel_index.c src/core/ext/client_config/uri_parser.c src/core/lib/http/httpcli_security_connector.c @@ -508,15 +719,64 @@ target_include_directories(grpc_cronet PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) target_link_libraries(grpc_cronet - ssl + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_SSL_LIBRARIES} gpr ) +foreach(_hdr + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/compression.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security_constants.h + include/grpc/status.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h + include/grpc/grpc_cronet.h + include/grpc/grpc_security.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc_cronet EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + add_library(grpc_unsecure src/core/lib/surface/init.c @@ -526,6 +786,7 @@ add_library(grpc_unsecure src/core/lib/channel/channel_stack_builder.c src/core/lib/channel/compress_filter.c src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c src/core/lib/channel/http_client_filter.c src/core/lib/channel/http_server_filter.c src/core/lib/compression/compression.c @@ -606,6 +867,7 @@ add_library(grpc_unsecure src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c src/core/lib/transport/transport_op_string.c src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -629,7 +891,6 @@ add_library(grpc_unsecure src/core/ext/transport/chttp2/transport/status_conversion.c src/core/ext/transport/chttp2/transport/stream_lists.c src/core/ext/transport/chttp2/transport/stream_map.c - src/core/ext/transport/chttp2/transport/timeout_encoding.c src/core/ext/transport/chttp2/transport/varint.c src/core/ext/transport/chttp2/transport/writing.c src/core/ext/transport/chttp2/alpn/alpn.c @@ -638,7 +899,6 @@ add_library(grpc_unsecure src/core/ext/client_config/channel_connectivity.c src/core/ext/client_config/client_channel.c src/core/ext/client_config/client_channel_factory.c - src/core/ext/client_config/client_config.c src/core/ext/client_config/client_config_plugin.c src/core/ext/client_config/connector.c src/core/ext/client_config/default_initial_connect_string.c @@ -650,14 +910,15 @@ add_library(grpc_unsecure src/core/ext/client_config/resolver.c src/core/ext/client_config/resolver_factory.c src/core/ext/client_config/resolver_registry.c + src/core/ext/client_config/resolver_result.c src/core/ext/client_config/subchannel.c - src/core/ext/client_config/subchannel_call_holder.c src/core/ext/client_config/subchannel_index.c src/core/ext/client_config/uri_parser.c src/core/ext/resolver/dns/native/dns_resolver.c src/core/ext/resolver/sockaddr/sockaddr_resolver.c src/core/ext/load_reporting/load_reporting.c src/core/ext/load_reporting/load_reporting_filter.c + src/core/ext/lb_policy/grpclb/grpclb.c src/core/ext/lb_policy/grpclb/load_balancer_api.c src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c third_party/nanopb/pb_common.c @@ -665,8 +926,10 @@ add_library(grpc_unsecure third_party/nanopb/pb_encode.c src/core/ext/lb_policy/pick_first/pick_first.c src/core/ext/lb_policy/round_robin/round_robin.c + src/core/ext/census/base_resources.c src/core/ext/census/context.c src/core/ext/census/gen/census.pb.c + src/core/ext/census/gen/trace_context.pb.c src/core/ext/census/grpc_context.c src/core/ext/census/grpc_filter.c src/core/ext/census/grpc_plugin.c @@ -674,6 +937,7 @@ add_library(grpc_unsecure src/core/ext/census/mlog.c src/core/ext/census/operation.c src/core/ext/census/placeholders.c + src/core/ext/census/resource.c src/core/ext/census/tracing.c src/core/plugin_registry/grpc_unsecure_plugin_registry.c ) @@ -683,14 +947,62 @@ target_include_directories(grpc_unsecure PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) target_link_libraries(grpc_unsecure + ${_gRPC_BASELIB_LIBRARIES} gpr ) +foreach(_hdr + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/compression.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security_constants.h + include/grpc/status.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h + include/grpc/census.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc_unsecure EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + add_library(grpc++ src/cpp/client/secure_credentials.cc @@ -708,6 +1020,7 @@ add_library(grpc++ src/cpp/client/generic_stub.cc src/cpp/client/insecure_credentials.cc src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc src/cpp/common/completion_queue.cc src/cpp/common/core_codegen.cc src/cpp/common/rpc_method.cc @@ -725,6 +1038,95 @@ add_library(grpc++ src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time.cc + src/core/lib/channel/channel_args.c + src/core/lib/channel/channel_stack.c + src/core/lib/channel/channel_stack_builder.c + src/core/lib/channel/compress_filter.c + src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c + src/core/lib/channel/http_client_filter.c + src/core/lib/channel/http_server_filter.c + src/core/lib/compression/compression.c + src/core/lib/compression/message_compress.c + src/core/lib/debug/trace.c + src/core/lib/http/format_request.c + src/core/lib/http/httpcli.c + src/core/lib/http/parser.c + src/core/lib/iomgr/closure.c + src/core/lib/iomgr/endpoint.c + src/core/lib/iomgr/endpoint_pair_posix.c + src/core/lib/iomgr/endpoint_pair_windows.c + src/core/lib/iomgr/error.c + src/core/lib/iomgr/ev_epoll_linux.c + src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_posix.c + src/core/lib/iomgr/ev_posix.c + src/core/lib/iomgr/exec_ctx.c + src/core/lib/iomgr/executor.c + src/core/lib/iomgr/iocp_windows.c + src/core/lib/iomgr/iomgr.c + src/core/lib/iomgr/iomgr_posix.c + src/core/lib/iomgr/iomgr_windows.c + src/core/lib/iomgr/load_file.c + src/core/lib/iomgr/network_status_tracker.c + src/core/lib/iomgr/polling_entity.c + src/core/lib/iomgr/pollset_set_windows.c + src/core/lib/iomgr/pollset_windows.c + src/core/lib/iomgr/resolve_address_posix.c + src/core/lib/iomgr/resolve_address_windows.c + src/core/lib/iomgr/sockaddr_utils.c + src/core/lib/iomgr/socket_utils_common_posix.c + src/core/lib/iomgr/socket_utils_linux.c + src/core/lib/iomgr/socket_utils_posix.c + src/core/lib/iomgr/socket_windows.c + src/core/lib/iomgr/tcp_client_posix.c + src/core/lib/iomgr/tcp_client_windows.c + src/core/lib/iomgr/tcp_posix.c + src/core/lib/iomgr/tcp_server_posix.c + src/core/lib/iomgr/tcp_server_windows.c + src/core/lib/iomgr/tcp_windows.c + src/core/lib/iomgr/time_averaged_stats.c + src/core/lib/iomgr/timer.c + src/core/lib/iomgr/timer_heap.c + src/core/lib/iomgr/udp_server.c + src/core/lib/iomgr/unix_sockets_posix.c + src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_eventfd.c + src/core/lib/iomgr/wakeup_fd_nospecial.c + src/core/lib/iomgr/wakeup_fd_pipe.c + src/core/lib/iomgr/wakeup_fd_posix.c + src/core/lib/iomgr/workqueue_posix.c + src/core/lib/iomgr/workqueue_windows.c + src/core/lib/json/json.c + src/core/lib/json/json_reader.c + src/core/lib/json/json_string.c + src/core/lib/json/json_writer.c + src/core/lib/surface/alarm.c + src/core/lib/surface/api_trace.c + src/core/lib/surface/byte_buffer.c + src/core/lib/surface/byte_buffer_reader.c + src/core/lib/surface/call.c + src/core/lib/surface/call_details.c + src/core/lib/surface/call_log_batch.c + src/core/lib/surface/channel.c + src/core/lib/surface/channel_init.c + src/core/lib/surface/channel_ping.c + src/core/lib/surface/channel_stack_type.c + src/core/lib/surface/completion_queue.c + src/core/lib/surface/event_string.c + src/core/lib/surface/lame_client.c + src/core/lib/surface/metadata_array.c + src/core/lib/surface/server.c + src/core/lib/surface/validate_metadata.c + src/core/lib/surface/version.c + src/core/lib/transport/byte_stream.c + src/core/lib/transport/connectivity_state.c + src/core/lib/transport/metadata.c + src/core/lib/transport/metadata_batch.c + src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c + src/core/lib/transport/transport.c + src/core/lib/transport/transport_op_string.c src/cpp/codegen/codegen_init.cc ) @@ -733,15 +1135,140 @@ target_include_directories(grpc++ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) target_link_libraries(grpc++ - ssl - libprotobuf + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_SSL_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} grpc + gpr +) + +foreach(_hdr + include/grpc++/alarm.h + include/grpc++/channel.h + include/grpc++/client_context.h + include/grpc++/completion_queue.h + include/grpc++/create_channel.h + include/grpc++/create_channel_posix.h + include/grpc++/generic/async_generic_service.h + include/grpc++/generic/generic_stub.h + include/grpc++/grpc++.h + include/grpc++/impl/call.h + include/grpc++/impl/client_unary_call.h + include/grpc++/impl/codegen/core_codegen.h + include/grpc++/impl/grpc_library.h + include/grpc++/impl/method_handler_impl.h + include/grpc++/impl/rpc_method.h + include/grpc++/impl/rpc_service_method.h + include/grpc++/impl/serialization_traits.h + include/grpc++/impl/server_builder_option.h + include/grpc++/impl/server_builder_plugin.h + include/grpc++/impl/server_initializer.h + include/grpc++/impl/service_type.h + include/grpc++/impl/sync.h + include/grpc++/impl/sync_cxx11.h + include/grpc++/impl/sync_no_cxx11.h + include/grpc++/impl/thd.h + include/grpc++/impl/thd_cxx11.h + include/grpc++/impl/thd_no_cxx11.h + include/grpc++/security/auth_context.h + include/grpc++/security/auth_metadata_processor.h + include/grpc++/security/credentials.h + include/grpc++/security/server_credentials.h + include/grpc++/server.h + include/grpc++/server_builder.h + include/grpc++/server_context.h + include/grpc++/server_posix.h + include/grpc++/support/async_stream.h + include/grpc++/support/async_unary_call.h + include/grpc++/support/byte_buffer.h + include/grpc++/support/channel_arguments.h + include/grpc++/support/config.h + include/grpc++/support/slice.h + include/grpc++/support/status.h + include/grpc++/support/status_code_enum.h + include/grpc++/support/string_ref.h + include/grpc++/support/stub_options.h + include/grpc++/support/sync_stream.h + include/grpc++/support/time.h + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/compression.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security_constants.h + include/grpc/status.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h + include/grpc++/impl/codegen/async_stream.h + include/grpc++/impl/codegen/async_unary_call.h + include/grpc++/impl/codegen/call.h + include/grpc++/impl/codegen/call_hook.h + include/grpc++/impl/codegen/channel_interface.h + include/grpc++/impl/codegen/client_context.h + include/grpc++/impl/codegen/client_unary_call.h + include/grpc++/impl/codegen/completion_queue.h + include/grpc++/impl/codegen/completion_queue_tag.h + include/grpc++/impl/codegen/config.h + include/grpc++/impl/codegen/core_codegen_interface.h + include/grpc++/impl/codegen/create_auth_context.h + include/grpc++/impl/codegen/grpc_library.h + include/grpc++/impl/codegen/method_handler_impl.h + include/grpc++/impl/codegen/rpc_method.h + include/grpc++/impl/codegen/rpc_service_method.h + include/grpc++/impl/codegen/security/auth_context.h + include/grpc++/impl/codegen/serialization_traits.h + include/grpc++/impl/codegen/server_context.h + include/grpc++/impl/codegen/server_interface.h + include/grpc++/impl/codegen/service_type.h + include/grpc++/impl/codegen/status.h + include/grpc++/impl/codegen/status_code_enum.h + include/grpc++/impl/codegen/string_ref.h + include/grpc++/impl/codegen/stub_options.h + include/grpc++/impl/codegen/sync.h + include/grpc++/impl/codegen/sync_cxx11.h + include/grpc++/impl/codegen/sync_no_cxx11.h + include/grpc++/impl/codegen/sync_stream.h + include/grpc++/impl/codegen/time.h ) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc++ EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() add_library(grpc++_reflection @@ -756,7 +1283,7 @@ target_include_directories(grpc++_reflection PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) @@ -764,6 +1291,80 @@ target_link_libraries(grpc++_reflection grpc++ ) +foreach(_hdr + include/grpc++/ext/proto_server_reflection_plugin.h + include/grpc++/ext/reflection.grpc.pb.h + include/grpc++/ext/reflection.pb.h + include/grpc++/impl/codegen/proto_utils.h + include/grpc++/impl/codegen/async_stream.h + include/grpc++/impl/codegen/async_unary_call.h + include/grpc++/impl/codegen/call.h + include/grpc++/impl/codegen/call_hook.h + include/grpc++/impl/codegen/channel_interface.h + include/grpc++/impl/codegen/client_context.h + include/grpc++/impl/codegen/client_unary_call.h + include/grpc++/impl/codegen/completion_queue.h + include/grpc++/impl/codegen/completion_queue_tag.h + include/grpc++/impl/codegen/config.h + include/grpc++/impl/codegen/core_codegen_interface.h + include/grpc++/impl/codegen/create_auth_context.h + include/grpc++/impl/codegen/grpc_library.h + include/grpc++/impl/codegen/method_handler_impl.h + include/grpc++/impl/codegen/rpc_method.h + include/grpc++/impl/codegen/rpc_service_method.h + include/grpc++/impl/codegen/security/auth_context.h + include/grpc++/impl/codegen/serialization_traits.h + include/grpc++/impl/codegen/server_context.h + include/grpc++/impl/codegen/server_interface.h + include/grpc++/impl/codegen/service_type.h + include/grpc++/impl/codegen/status.h + include/grpc++/impl/codegen/status_code_enum.h + include/grpc++/impl/codegen/string_ref.h + include/grpc++/impl/codegen/stub_options.h + include/grpc++/impl/codegen/sync.h + include/grpc++/impl/codegen/sync_cxx11.h + include/grpc++/impl/codegen/sync_no_cxx11.h + include/grpc++/impl/codegen/sync_stream.h + include/grpc++/impl/codegen/time.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h + include/grpc++/impl/codegen/config_protobuf.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc++_reflection EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + add_library(grpc++_unsecure src/cpp/common/insecure_create_auth_context.cc @@ -776,6 +1377,7 @@ add_library(grpc++_unsecure src/cpp/client/generic_stub.cc src/cpp/client/insecure_credentials.cc src/cpp/common/channel_arguments.cc + src/cpp/common/channel_filter.cc src/cpp/common/completion_queue.cc src/cpp/common/core_codegen.cc src/cpp/common/rpc_method.cc @@ -793,6 +1395,95 @@ add_library(grpc++_unsecure src/cpp/util/status.cc src/cpp/util/string_ref.cc src/cpp/util/time.cc + src/core/lib/channel/channel_args.c + src/core/lib/channel/channel_stack.c + src/core/lib/channel/channel_stack_builder.c + src/core/lib/channel/compress_filter.c + src/core/lib/channel/connected_channel.c + src/core/lib/channel/handshaker.c + src/core/lib/channel/http_client_filter.c + src/core/lib/channel/http_server_filter.c + src/core/lib/compression/compression.c + src/core/lib/compression/message_compress.c + src/core/lib/debug/trace.c + src/core/lib/http/format_request.c + src/core/lib/http/httpcli.c + src/core/lib/http/parser.c + src/core/lib/iomgr/closure.c + src/core/lib/iomgr/endpoint.c + src/core/lib/iomgr/endpoint_pair_posix.c + src/core/lib/iomgr/endpoint_pair_windows.c + src/core/lib/iomgr/error.c + src/core/lib/iomgr/ev_epoll_linux.c + src/core/lib/iomgr/ev_poll_and_epoll_posix.c + src/core/lib/iomgr/ev_poll_posix.c + src/core/lib/iomgr/ev_posix.c + src/core/lib/iomgr/exec_ctx.c + src/core/lib/iomgr/executor.c + src/core/lib/iomgr/iocp_windows.c + src/core/lib/iomgr/iomgr.c + src/core/lib/iomgr/iomgr_posix.c + src/core/lib/iomgr/iomgr_windows.c + src/core/lib/iomgr/load_file.c + src/core/lib/iomgr/network_status_tracker.c + src/core/lib/iomgr/polling_entity.c + src/core/lib/iomgr/pollset_set_windows.c + src/core/lib/iomgr/pollset_windows.c + src/core/lib/iomgr/resolve_address_posix.c + src/core/lib/iomgr/resolve_address_windows.c + src/core/lib/iomgr/sockaddr_utils.c + src/core/lib/iomgr/socket_utils_common_posix.c + src/core/lib/iomgr/socket_utils_linux.c + src/core/lib/iomgr/socket_utils_posix.c + src/core/lib/iomgr/socket_windows.c + src/core/lib/iomgr/tcp_client_posix.c + src/core/lib/iomgr/tcp_client_windows.c + src/core/lib/iomgr/tcp_posix.c + src/core/lib/iomgr/tcp_server_posix.c + src/core/lib/iomgr/tcp_server_windows.c + src/core/lib/iomgr/tcp_windows.c + src/core/lib/iomgr/time_averaged_stats.c + src/core/lib/iomgr/timer.c + src/core/lib/iomgr/timer_heap.c + src/core/lib/iomgr/udp_server.c + src/core/lib/iomgr/unix_sockets_posix.c + src/core/lib/iomgr/unix_sockets_posix_noop.c + src/core/lib/iomgr/wakeup_fd_eventfd.c + src/core/lib/iomgr/wakeup_fd_nospecial.c + src/core/lib/iomgr/wakeup_fd_pipe.c + src/core/lib/iomgr/wakeup_fd_posix.c + src/core/lib/iomgr/workqueue_posix.c + src/core/lib/iomgr/workqueue_windows.c + src/core/lib/json/json.c + src/core/lib/json/json_reader.c + src/core/lib/json/json_string.c + src/core/lib/json/json_writer.c + src/core/lib/surface/alarm.c + src/core/lib/surface/api_trace.c + src/core/lib/surface/byte_buffer.c + src/core/lib/surface/byte_buffer_reader.c + src/core/lib/surface/call.c + src/core/lib/surface/call_details.c + src/core/lib/surface/call_log_batch.c + src/core/lib/surface/channel.c + src/core/lib/surface/channel_init.c + src/core/lib/surface/channel_ping.c + src/core/lib/surface/channel_stack_type.c + src/core/lib/surface/completion_queue.c + src/core/lib/surface/event_string.c + src/core/lib/surface/lame_client.c + src/core/lib/surface/metadata_array.c + src/core/lib/surface/server.c + src/core/lib/surface/validate_metadata.c + src/core/lib/surface/version.c + src/core/lib/transport/byte_stream.c + src/core/lib/transport/connectivity_state.c + src/core/lib/transport/metadata.c + src/core/lib/transport/metadata_batch.c + src/core/lib/transport/static_metadata.c + src/core/lib/transport/timeout_encoding.c + src/core/lib/transport/transport.c + src/core/lib/transport/transport_op_string.c src/cpp/codegen/codegen_init.cc ) @@ -801,17 +1492,140 @@ target_include_directories(grpc++_unsecure PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) target_link_libraries(grpc++_unsecure - libprotobuf + ${_gRPC_BASELIB_LIBRARIES} + ${_gRPC_PROTOBUF_LIBRARIES} gpr grpc_unsecure - grpc ) +foreach(_hdr + include/grpc++/alarm.h + include/grpc++/channel.h + include/grpc++/client_context.h + include/grpc++/completion_queue.h + include/grpc++/create_channel.h + include/grpc++/create_channel_posix.h + include/grpc++/generic/async_generic_service.h + include/grpc++/generic/generic_stub.h + include/grpc++/grpc++.h + include/grpc++/impl/call.h + include/grpc++/impl/client_unary_call.h + include/grpc++/impl/codegen/core_codegen.h + include/grpc++/impl/grpc_library.h + include/grpc++/impl/method_handler_impl.h + include/grpc++/impl/rpc_method.h + include/grpc++/impl/rpc_service_method.h + include/grpc++/impl/serialization_traits.h + include/grpc++/impl/server_builder_option.h + include/grpc++/impl/server_builder_plugin.h + include/grpc++/impl/server_initializer.h + include/grpc++/impl/service_type.h + include/grpc++/impl/sync.h + include/grpc++/impl/sync_cxx11.h + include/grpc++/impl/sync_no_cxx11.h + include/grpc++/impl/thd.h + include/grpc++/impl/thd_cxx11.h + include/grpc++/impl/thd_no_cxx11.h + include/grpc++/security/auth_context.h + include/grpc++/security/auth_metadata_processor.h + include/grpc++/security/credentials.h + include/grpc++/security/server_credentials.h + include/grpc++/server.h + include/grpc++/server_builder.h + include/grpc++/server_context.h + include/grpc++/server_posix.h + include/grpc++/support/async_stream.h + include/grpc++/support/async_unary_call.h + include/grpc++/support/byte_buffer.h + include/grpc++/support/channel_arguments.h + include/grpc++/support/config.h + include/grpc++/support/slice.h + include/grpc++/support/status.h + include/grpc++/support/status_code_enum.h + include/grpc++/support/string_ref.h + include/grpc++/support/stub_options.h + include/grpc++/support/sync_stream.h + include/grpc++/support/time.h + include/grpc/byte_buffer.h + include/grpc/byte_buffer_reader.h + include/grpc/compression.h + include/grpc/grpc.h + include/grpc/grpc_posix.h + include/grpc/grpc_security_constants.h + include/grpc/status.h + include/grpc/impl/codegen/byte_buffer.h + include/grpc/impl/codegen/byte_buffer_reader.h + include/grpc/impl/codegen/compression_types.h + include/grpc/impl/codegen/connectivity_state.h + include/grpc/impl/codegen/grpc_types.h + include/grpc/impl/codegen/propagation_bits.h + include/grpc/impl/codegen/status.h + include/grpc/impl/codegen/alloc.h + include/grpc/impl/codegen/atm.h + include/grpc/impl/codegen/atm_gcc_atomic.h + include/grpc/impl/codegen/atm_gcc_sync.h + include/grpc/impl/codegen/atm_windows.h + include/grpc/impl/codegen/log.h + include/grpc/impl/codegen/port_platform.h + include/grpc/impl/codegen/slice.h + include/grpc/impl/codegen/slice_buffer.h + include/grpc/impl/codegen/sync.h + include/grpc/impl/codegen/sync_generic.h + include/grpc/impl/codegen/sync_posix.h + include/grpc/impl/codegen/sync_windows.h + include/grpc/impl/codegen/time.h + include/grpc++/impl/codegen/async_stream.h + include/grpc++/impl/codegen/async_unary_call.h + include/grpc++/impl/codegen/call.h + include/grpc++/impl/codegen/call_hook.h + include/grpc++/impl/codegen/channel_interface.h + include/grpc++/impl/codegen/client_context.h + include/grpc++/impl/codegen/client_unary_call.h + include/grpc++/impl/codegen/completion_queue.h + include/grpc++/impl/codegen/completion_queue_tag.h + include/grpc++/impl/codegen/config.h + include/grpc++/impl/codegen/core_codegen_interface.h + include/grpc++/impl/codegen/create_auth_context.h + include/grpc++/impl/codegen/grpc_library.h + include/grpc++/impl/codegen/method_handler_impl.h + include/grpc++/impl/codegen/rpc_method.h + include/grpc++/impl/codegen/rpc_service_method.h + include/grpc++/impl/codegen/security/auth_context.h + include/grpc++/impl/codegen/serialization_traits.h + include/grpc++/impl/codegen/server_context.h + include/grpc++/impl/codegen/server_interface.h + include/grpc++/impl/codegen/service_type.h + include/grpc++/impl/codegen/status.h + include/grpc++/impl/codegen/status_code_enum.h + include/grpc++/impl/codegen/string_ref.h + include/grpc++/impl/codegen/stub_options.h + include/grpc++/impl/codegen/sync.h + include/grpc++/impl/codegen/sync_cxx11.h + include/grpc++/impl/codegen/sync_no_cxx11.h + include/grpc++/impl/codegen/sync_stream.h + include/grpc++/impl/codegen/time.h +) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc++_unsecure EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + add_library(grpc_plugin_support src/compiler/cpp_generator.cc @@ -827,13 +1641,32 @@ target_include_directories(grpc_plugin_support PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) target_link_libraries(grpc_plugin_support - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} +) + +foreach(_hdr + include/grpc++/impl/codegen/config_protobuf.h ) + string(REPLACE "include/" "" _path ${_hdr}) + get_filename_component(_path ${_path} PATH) + install(FILES ${_hdr} + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) +endforeach() + + +if (gRPC_INSTALL) + install(TARGETS grpc_plugin_support EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() add_library(grpc_csharp_ext @@ -845,7 +1678,7 @@ target_include_directories(grpc_csharp_ext PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE ${BORINGSSL_ROOT_DIR}/include PRIVATE ${PROTOBUF_ROOT_DIR}/src - PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${ZLIB_INCLUDE_DIR} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) @@ -855,6 +1688,16 @@ target_link_libraries(grpc_csharp_ext ) + +if (gRPC_INSTALL) + install(TARGETS grpc_csharp_ext EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(gen_hpack_tables tools/codegen/core/gen_hpack_tables.c @@ -875,6 +1718,15 @@ target_link_libraries(gen_hpack_tables ) +if (gRPC_INSTALL) + install(TARGETS gen_hpack_tables EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(gen_legal_metadata_characters tools/codegen/core/gen_legal_metadata_characters.c ) @@ -890,6 +1742,37 @@ target_include_directories(gen_legal_metadata_characters +if (gRPC_INSTALL) + install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + +add_executable(gen_percent_encoding_tables + tools/codegen/core/gen_percent_encoding_tables.c +) + +target_include_directories(gen_percent_encoding_tables + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib +) + + + +install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + + add_executable(grpc_create_jwt test/core/security/create_jwt.c ) @@ -904,12 +1787,21 @@ target_include_directories(grpc_create_jwt ) target_link_libraries(grpc_create_jwt - ssl + ${_gRPC_SSL_LIBRARIES} grpc gpr ) +if (gRPC_INSTALL) + install(TARGETS grpc_create_jwt EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_print_google_default_creds_token test/core/security/print_google_default_creds_token.c ) @@ -929,6 +1821,15 @@ target_link_libraries(grpc_print_google_default_creds_token ) +if (gRPC_INSTALL) + install(TARGETS grpc_print_google_default_creds_token EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_verify_jwt test/core/security/verify_jwt.c ) @@ -948,6 +1849,15 @@ target_link_libraries(grpc_verify_jwt ) +if (gRPC_INSTALL) + install(TARGETS grpc_verify_jwt EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_cpp_plugin src/compiler/cpp_plugin.cc ) @@ -962,11 +1872,20 @@ target_include_directories(grpc_cpp_plugin ) target_link_libraries(grpc_cpp_plugin - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} grpc_plugin_support ) +if (gRPC_INSTALL) + install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_csharp_plugin src/compiler/csharp_plugin.cc ) @@ -981,11 +1900,20 @@ target_include_directories(grpc_csharp_plugin ) target_link_libraries(grpc_csharp_plugin - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} grpc_plugin_support ) +if (gRPC_INSTALL) + install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_node_plugin src/compiler/node_plugin.cc ) @@ -1000,11 +1928,20 @@ target_include_directories(grpc_node_plugin ) target_link_libraries(grpc_node_plugin - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} grpc_plugin_support ) +if (gRPC_INSTALL) + install(TARGETS grpc_node_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_objective_c_plugin src/compiler/objective_c_plugin.cc ) @@ -1019,11 +1956,20 @@ target_include_directories(grpc_objective_c_plugin ) target_link_libraries(grpc_objective_c_plugin - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} grpc_plugin_support ) +if (gRPC_INSTALL) + install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_python_plugin src/compiler/python_plugin.cc ) @@ -1038,11 +1984,20 @@ target_include_directories(grpc_python_plugin ) target_link_libraries(grpc_python_plugin - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} grpc_plugin_support ) +if (gRPC_INSTALL) + install(TARGETS grpc_python_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + add_executable(grpc_ruby_plugin src/compiler/ruby_plugin.cc ) @@ -1057,11 +2012,37 @@ target_include_directories(grpc_ruby_plugin ) target_link_libraries(grpc_ruby_plugin - libprotoc + ${_gRPC_PROTOBUF_PROTOC_LIBRARIES} grpc_plugin_support ) +if (gRPC_INSTALL) + install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + ) +endif() + + + + + +if (gRPC_INSTALL) + install(EXPORT gRPCTargets + DESTINATION ${CMAKE_INSTALL_CMAKEDIR} + NAMESPACE gRPC:: + ) +endif() + +foreach(_config gRPCConfig gRPCConfigVersion) + configure_file(tools/cmake/${_config}.cmake.in + ${_config}.cmake @ONLY) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${_config}.cmake + DESTINATION ${CMAKE_INSTALL_CMAKEDIR} + ) +endforeach() diff --git a/INSTALL.md b/INSTALL.md index 6718aad120d..686145566fa 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -9,7 +9,7 @@ refer to these documents * [Java](https://github.com/grpc/grpc-java) * [Node](src/node): `npm install grpc` * [Objective-C](src/objective-c) - * [PHP](src/php): `pecl install grpc-beta` + * [PHP](src/php): `pecl install grpc` * [Python](src/python/grpcio): `pip install grpcio` * [Ruby](src/ruby): `gem install grpc` @@ -55,3 +55,55 @@ gRPC C Core library. $ make $ [sudo] make install ``` + +##Windows + +There are several ways to build under Windows, of varying complexity depending +on experience with the tools involved. + + + +###msys2 + +This approach requires having [msys2](https://msys2.github.io/) installed. + +- The Makefile (and source code) should support msys2's mingw32 and mingw64 + compilers. Building with msys2's native compiler is also possible, but + difficult. +- The Makefile is expecting the Windows versions of OpenSSL (see + https://slproweb.com/products/Win32OpenSSL.html). It's also possible to build + the Windows version of OpenSSL from scratch. The output should be `libeay32` + and `ssleay32`. +- If you are not installing the above files under msys2's path, you may specify + it, for instance, in the following way: + ```CPPFLAGS=â€-I/c/OpenSSL-Win32/include†LDFLAGS=â€-L/c/OpenSSL-Win32/lib†make static_c``` +- [protobuf3](https://github.com/google/protobuf/blob/master/src/README.md#c-installation---windows) + must be installed on the msys2 path. + +###Cmake (experimental) + +- Install [CMake](https://cmake.org/download/). +- Run it over [grpc's + CMakeLists.txt](https://github.com/grpc/grpc/blob/master/CMakeLists.txt) to + generate "projects" for your compiler. +- Build with your compiler of choice. The generated build files should have the + protobuf3 dependency baked in. diff --git a/Makefile b/Makefile index 4ce22678d7e..bb0c5bde8e8 100644 --- a/Makefile +++ b/Makefile @@ -405,6 +405,29 @@ LIBS = m pthread ws2_32 LDFLAGS += -pthread endif +# +# The steps for cross-compiling are as follows: +# First, clone and make install of grpc using the native compilers for the host. +# Also, install protoc (e.g., from a package like apt-get) +# Then clone a fresh grpc for the actual cross-compiled build +# Set the environment variable GRPC_CROSS_COMPILE to true +# Set CC, CXX, LD, LDXX, AR, and STRIP to the cross-compiling binaries +# Also set PROTOBUF_CONFIG_OPTS to indicate cross-compilation to protobuf (e.g., +# PROTOBUF_CONFIG_OPTS="--host=arm-linux --with-protoc=/usr/local/bin/protoc" ) +# Set HAS_PKG_CONFIG=false +# To build tests, go to third_party/gflags and follow its ccmake instructions +# Make sure that you enable building shared libraries and set your prefix to +# something useful like /usr/local/cross +# You will also need to set GRPC_CROSS_LDOPTS and GRPC_CROSS_AROPTS to hold +# additional required arguments for LD and AR (examples below) +# Then you can do a make from the cross-compiling fresh clone! +# +ifeq ($(GRPC_CROSS_COMPILE),true) +LDFLAGS += $(GRPC_CROSS_LDOPTS) # e.g. -L/usr/local/lib -L/usr/local/cross/lib +AROPTS = $(GRPC_CROSS_AROPTS) # e.g., rc --target=elf32-little +USE_BUILT_PROTOC = false +endif + GTEST_LIB = -Ithird_party/googletest/include -Ithird_party/googletest third_party/googletest/src/gtest-all.cc GTEST_LIB += -lgflags ifeq ($(V),1) @@ -469,7 +492,7 @@ ifeq ($(HAS_PKG_CONFIG),true) OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib -PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0-alpha-3 protobuf +PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf else # HAS_PKG_CONFIG ifeq ($(SYSTEM),MINGW32) @@ -709,6 +732,9 @@ PC_LIBS_GRPCXX = CPPFLAGS := -Ithird_party/googletest/include $(CPPFLAGS) +PROTOC_PLUGINS_ALL = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG) + ifeq ($(HAS_SYSTEM_PROTOBUF),true) ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true @@ -723,12 +749,19 @@ endif else PC_LIBS_GRPCXX = -lprotobuf endif +PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) else ifeq ($(HAS_EMBEDDED_PROTOBUF),true) PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a CPPFLAGS := -Ithird_party/protobuf/src $(CPPFLAGS) LDFLAGS := -L$(LIBDIR)/$(CONFIG)/protobuf $(LDFLAGS) +ifneq ($(USE_BUILT_PROTOC),false) PROTOC = $(BINDIR)/$(CONFIG)/protobuf/protoc +PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) +else +PROTOC_PLUGINS = +PROTOC_PLUGINS_DIR = $(prefix)/bin +endif else NO_PROTOBUF = true endif @@ -767,16 +800,8 @@ ifeq ($(MAKECMDGOALS),clean) NO_DEPS = true endif -INSTALL_OK = false -ifeq ($(HAS_VALID_PROTOC),true) -ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true) -INSTALL_OK = true -endif -endif - .SECONDARY = %.pb.h %.pb.cc -PROTOC_PLUGINS = $(BINDIR)/$(CONFIG)/grpc_cpp_plugin $(BINDIR)/$(CONFIG)/grpc_csharp_plugin $(BINDIR)/$(CONFIG)/grpc_node_plugin $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin $(BINDIR)/$(CONFIG)/grpc_python_plugin $(BINDIR)/$(CONFIG)/grpc_ruby_plugin ifeq ($(DEP_MISSING),) all: static shared plugins dep_error: @@ -883,6 +908,7 @@ bad_server_response_test: $(BINDIR)/$(CONFIG)/bad_server_response_test bin_decoder_test: $(BINDIR)/$(CONFIG)/bin_decoder_test bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test census_context_test: $(BINDIR)/$(CONFIG)/census_context_test +census_resource_test: $(BINDIR)/$(CONFIG)/census_resource_test channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test chttp2_status_conversion_test: $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test @@ -904,6 +930,7 @@ fling_stream_test: $(BINDIR)/$(CONFIG)/fling_stream_test fling_test: $(BINDIR)/$(CONFIG)/fling_test gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters +gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables goaway_server_test: $(BINDIR)/$(CONFIG)/goaway_server_test gpr_avl_test: $(BINDIR)/$(CONFIG)/gpr_avl_test gpr_backoff_test: $(BINDIR)/$(CONFIG)/gpr_backoff_test @@ -913,6 +940,7 @@ gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test +gpr_percent_encoding_test: $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test gpr_slice_buffer_test: $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test gpr_slice_test: $(BINDIR)/$(CONFIG)/gpr_slice_test gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test @@ -967,6 +995,8 @@ murmur_hash_test: $(BINDIR)/$(CONFIG)/murmur_hash_test nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test no_server_test: $(BINDIR)/$(CONFIG)/no_server_test +percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer +percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test @@ -1006,6 +1036,7 @@ cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test cxx_string_ref_test: $(BINDIR)/$(CONFIG)/cxx_string_ref_test cxx_time_test: $(BINDIR)/$(CONFIG)/cxx_time_test end2end_test: $(BINDIR)/$(CONFIG)/end2end_test +filter_end2end_test: $(BINDIR)/$(CONFIG)/filter_end2end_test generic_end2end_test: $(BINDIR)/$(CONFIG)/generic_end2end_test golden_file_test: $(BINDIR)/$(CONFIG)/golden_file_test grpc_cli: $(BINDIR)/$(CONFIG)/grpc_cli @@ -1015,7 +1046,9 @@ grpc_node_plugin: $(BINDIR)/$(CONFIG)/grpc_node_plugin grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin +grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test +grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test interop_client: $(BINDIR)/$(CONFIG)/interop_client interop_server: $(BINDIR)/$(CONFIG)/interop_server @@ -1100,7 +1133,7 @@ h2_fd_test: $(BINDIR)/$(CONFIG)/h2_fd_test h2_full_test: $(BINDIR)/$(CONFIG)/h2_full_test h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test -h2_loadreporting_test: $(BINDIR)/$(CONFIG)/h2_loadreporting_test +h2_load_reporting_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_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 @@ -1116,7 +1149,7 @@ h2_fd_nosec_test: $(BINDIR)/$(CONFIG)/h2_fd_nosec_test h2_full_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_nosec_test h2_full+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test -h2_loadreporting_nosec_test: $(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test +h2_load_reporting_nosec_test: $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test @@ -1130,6 +1163,8 @@ http_response_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/http_response_fuzzer_te json_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry nanopb_fuzzer_response_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry nanopb_fuzzer_serverlist_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry +percent_decode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry +percent_encode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry uri_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry @@ -1147,7 +1182,7 @@ third_party/protobuf/configure: $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure $(E) "[MAKE] Building protobuf" - $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static) + $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static $(PROTOBUF_CONFIG_OPTS)) $(Q)$(MAKE) -C third_party/protobuf clean $(Q)$(MAKE) -C third_party/protobuf $(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf @@ -1184,9 +1219,9 @@ pc_cxx: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc ifeq ($(EMBED_OPENSSL),true) -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a else -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a endif @@ -1201,6 +1236,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/bin_decoder_test \ $(BINDIR)/$(CONFIG)/bin_encoder_test \ $(BINDIR)/$(CONFIG)/census_context_test \ + $(BINDIR)/$(CONFIG)/census_resource_test \ $(BINDIR)/$(CONFIG)/channel_create_test \ $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \ $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test \ @@ -1228,6 +1264,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/gpr_histogram_test \ $(BINDIR)/$(CONFIG)/gpr_host_port_test \ $(BINDIR)/$(CONFIG)/gpr_log_test \ + $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test \ $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test \ $(BINDIR)/$(CONFIG)/gpr_slice_test \ $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \ @@ -1316,7 +1353,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_full_test \ $(BINDIR)/$(CONFIG)/h2_full+pipe_test \ $(BINDIR)/$(CONFIG)/h2_full+trace_test \ - $(BINDIR)/$(CONFIG)/h2_loadreporting_test \ + $(BINDIR)/$(CONFIG)/h2_load_reporting_test \ $(BINDIR)/$(CONFIG)/h2_oauth2_test \ $(BINDIR)/$(CONFIG)/h2_proxy_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_test \ @@ -1332,7 +1369,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/h2_full_nosec_test \ $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test \ $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \ - $(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test \ + $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test \ $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \ $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \ @@ -1346,6 +1383,8 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry \ $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry \ $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry \ + $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry \ + $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry \ $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry \ $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry \ @@ -1367,10 +1406,13 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ + $(BINDIR)/$(CONFIG)/grpclb_test \ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ $(BINDIR)/$(CONFIG)/interop_client \ $(BINDIR)/$(CONFIG)/interop_server \ @@ -1451,10 +1493,13 @@ buildtests_cxx: privatelibs_cxx \ $(BINDIR)/$(CONFIG)/cxx_string_ref_test \ $(BINDIR)/$(CONFIG)/cxx_time_test \ $(BINDIR)/$(CONFIG)/end2end_test \ + $(BINDIR)/$(CONFIG)/filter_end2end_test \ $(BINDIR)/$(CONFIG)/generic_end2end_test \ $(BINDIR)/$(CONFIG)/golden_file_test \ $(BINDIR)/$(CONFIG)/grpc_cli \ + $(BINDIR)/$(CONFIG)/grpc_tool_test \ $(BINDIR)/$(CONFIG)/grpclb_api_test \ + $(BINDIR)/$(CONFIG)/grpclb_test \ $(BINDIR)/$(CONFIG)/hybrid_end2end_test \ $(BINDIR)/$(CONFIG)/interop_client \ $(BINDIR)/$(CONFIG)/interop_server \ @@ -1504,6 +1549,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 ) $(E) "[RUN] Testing census_context_test" $(Q) $(BINDIR)/$(CONFIG)/census_context_test || ( echo test census_context_test failed ; exit 1 ) + $(E) "[RUN] Testing census_resource_test" + $(Q) $(BINDIR)/$(CONFIG)/census_resource_test || ( echo test census_resource_test failed ; exit 1 ) $(E) "[RUN] Testing channel_create_test" $(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_hpack_encoder_test" @@ -1554,6 +1601,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/gpr_host_port_test || ( echo test gpr_host_port_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_log_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 ) + $(E) "[RUN] Testing gpr_percent_encoding_test" + $(Q) $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test || ( echo test gpr_percent_encoding_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_slice_buffer_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test || ( echo test gpr_slice_buffer_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_slice_test" @@ -1736,12 +1785,18 @@ test_cxx: buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/cxx_time_test || ( echo test cxx_time_test failed ; exit 1 ) $(E) "[RUN] Testing end2end_test" $(Q) $(BINDIR)/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 ) + $(E) "[RUN] Testing filter_end2end_test" + $(Q) $(BINDIR)/$(CONFIG)/filter_end2end_test || ( echo test filter_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing generic_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing golden_file_test" $(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 ) + $(E) "[RUN] Testing grpc_tool_test" + $(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_test failed ; exit 1 ) $(E) "[RUN] Testing grpclb_api_test" $(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 ) + $(E) "[RUN] Testing grpclb_test" + $(Q) $(BINDIR)/$(CONFIG)/grpclb_test || ( echo test grpclb_test failed ; exit 1 ) $(E) "[RUN] Testing hybrid_end2end_test" $(Q) $(BINDIR)/$(CONFIG)/hybrid_end2end_test || ( echo test hybrid_end2end_test failed ; exit 1 ) $(E) "[RUN] Testing interop_test" @@ -1781,7 +1836,7 @@ test_python: static_c tools: tools_c tools_cxx -tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt +tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt tools_cxx: privatelibs_cxx @@ -1886,7 +1941,22 @@ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc: src/proto/grpc/lb/v1/load_ba $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: src/proto/grpc/lb/v1/load_balancer.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< +endif + +ifeq ($(NO_PROTOC),true) +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: protoc_dep_error +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc: protoc_dep_error +else +$(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.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/reflection/v1alpha/reflection.grpc.pb.cc: src/proto/grpc/reflection/v1alpha/reflection.proto $(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 $< endif ifeq ($(NO_PROTOC),true) @@ -1901,7 +1971,7 @@ $(GENDIR)/src/proto/grpc/testing/compiler_test.pb.cc: src/proto/grpc/testing/com $(GENDIR)/src/proto/grpc/testing/compiler_test.grpc.pb.cc: src/proto/grpc/testing/compiler_test.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1916,7 +1986,7 @@ $(GENDIR)/src/proto/grpc/testing/control.pb.cc: src/proto/grpc/testing/control.p $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc: src/proto/grpc/testing/control.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.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=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1931,7 +2001,7 @@ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc: src/proto/grpc/ $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc: src/proto/grpc/testing/duplicate/echo_duplicate.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_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=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1946,7 +2016,7 @@ $(GENDIR)/src/proto/grpc/testing/echo.pb.cc: src/proto/grpc/testing/echo.proto $ $(GENDIR)/src/proto/grpc/testing/echo.grpc.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_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=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1961,7 +2031,7 @@ $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc: src/proto/grpc/testing/ech $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc: src/proto/grpc/testing/echo_messages.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1976,7 +2046,7 @@ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc: src/proto/grpc/testing/empty.proto $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc: src/proto/grpc/testing/empty.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -1991,7 +2061,7 @@ $(GENDIR)/src/proto/grpc/testing/messages.pb.cc: src/proto/grpc/testing/messages $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc: src/proto/grpc/testing/messages.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2006,7 +2076,7 @@ $(GENDIR)/src/proto/grpc/testing/metrics.pb.cc: src/proto/grpc/testing/metrics.p $(GENDIR)/src/proto/grpc/testing/metrics.grpc.pb.cc: src/proto/grpc/testing/metrics.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2021,7 +2091,7 @@ $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc: src/proto/grpc/testing/payloads $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc: src/proto/grpc/testing/payloads.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2036,7 +2106,7 @@ $(GENDIR)/src/proto/grpc/testing/services.pb.cc: src/proto/grpc/testing/services $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: src/proto/grpc/testing/services.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2051,7 +2121,7 @@ $(GENDIR)/src/proto/grpc/testing/stats.pb.cc: src/proto/grpc/testing/stats.proto $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc: src/proto/grpc/testing/stats.proto $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif ifeq ($(NO_PROTOC),true) @@ -2066,7 +2136,7 @@ $(GENDIR)/src/proto/grpc/testing/test.pb.cc: src/proto/grpc/testing/test.proto $ $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc: src/proto/grpc/testing/test.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/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=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif @@ -2102,7 +2172,7 @@ $(OBJDIR)/$(CONFIG)/%.o : %.cc $(Q) mkdir -p `dirname $@` $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< -install: install_c install_cxx install-plugins install-certs verify-install +install: install_c install_cxx install-plugins install-certs install_c: install-headers_c install-static_c install-shared_c @@ -2285,28 +2355,6 @@ install-certs: etc/roots.pem $(Q) $(INSTALL) -d $(prefix)/share/grpc $(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem -verify-install: -ifeq ($(INSTALL_OK),true) - @echo "Your system looks ready to go." - @echo -else - @echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system," - @echo "which means that you won't be able to compile .proto files for use" - @echo "with gRPC." - @echo - @echo "If you are just using pre-compiled protocol buffers, or you otherwise" - @echo "have no need to compile .proto files, you can ignore this." - @echo - @echo "If you do need protobuf for some reason, you can download and install" - @echo "it from:" - @echo - @echo " https://github.com/google/protobuf/releases" - @echo - @echo "Once you've done so, you can re-run this check by doing:" - @echo - @echo " make verify-install" -endif - clean: $(E) "[CLEAN] Cleaning build directories." $(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk @@ -2337,6 +2385,7 @@ LIBGPR_SRC = \ src/core/lib/support/log_posix.c \ src/core/lib/support/log_windows.c \ src/core/lib/support/murmur_hash.c \ + src/core/lib/support/percent_encoding.c \ src/core/lib/support/slice.c \ src/core/lib/support/slice_buffer.c \ src/core/lib/support/stack_lockfree.c \ @@ -2413,7 +2462,7 @@ $(LIBDIR)/$(CONFIG)/libgpr.a: $(ZLIB_DEP) $(LIBGPR_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBGPR_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr.a endif @@ -2455,7 +2504,7 @@ $(LIBDIR)/$(CONFIG)/libgpr_test_util.a: $(ZLIB_DEP) $(LIBGPR_TEST_UTIL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgpr_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBGPR_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgpr_test_util.a endif @@ -2475,6 +2524,7 @@ LIBGRPC_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -2555,6 +2605,7 @@ LIBGRPC_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ @@ -2577,7 +2628,6 @@ LIBGRPC_SRC = \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ @@ -2613,7 +2663,6 @@ LIBGRPC_SRC = \ src/core/ext/client_config/channel_connectivity.c \ src/core/ext/client_config/client_channel.c \ src/core/ext/client_config/client_channel_factory.c \ - src/core/ext/client_config/client_config.c \ src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/connector.c \ src/core/ext/client_config/default_initial_connect_string.c \ @@ -2625,14 +2674,15 @@ LIBGRPC_SRC = \ src/core/ext/client_config/resolver.c \ src/core/ext/client_config/resolver_factory.c \ src/core/ext/client_config/resolver_registry.c \ + src/core/ext/client_config/resolver_result.c \ src/core/ext/client_config/subchannel.c \ - src/core/ext/client_config/subchannel_call_holder.c \ src/core/ext/client_config/subchannel_index.c \ src/core/ext/client_config/uri_parser.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \ src/core/ext/transport/chttp2/client/insecure/channel_create.c \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \ + src/core/ext/lb_policy/grpclb/grpclb.c \ src/core/ext/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ third_party/nanopb/pb_common.c \ @@ -2644,8 +2694,10 @@ LIBGRPC_SRC = \ src/core/ext/resolver/sockaddr/sockaddr_resolver.c \ src/core/ext/load_reporting/load_reporting.c \ src/core/ext/load_reporting/load_reporting_filter.c \ + src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ + src/core/ext/census/gen/trace_context.pb.c \ src/core/ext/census/grpc_context.c \ src/core/ext/census/grpc_filter.c \ src/core/ext/census/grpc_plugin.c \ @@ -2653,6 +2705,7 @@ LIBGRPC_SRC = \ src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ + src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_plugin_registry.c \ @@ -2662,6 +2715,7 @@ PUBLIC_HEADERS_C += \ include/grpc/compression.h \ include/grpc/grpc.h \ include/grpc/grpc_posix.h \ + include/grpc/grpc_security_constants.h \ include/grpc/status.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -2685,7 +2739,6 @@ PUBLIC_HEADERS_C += \ include/grpc/impl/codegen/sync_windows.h \ include/grpc/impl/codegen/time.h \ include/grpc/grpc_security.h \ - include/grpc/grpc_security_constants.h \ include/grpc/census.h \ LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC)))) @@ -2706,7 +2759,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_OBJS) $(LIB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc.a endif @@ -2747,6 +2800,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -2827,6 +2881,7 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \ @@ -2852,14 +2907,12 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ src/core/ext/client_config/channel_connectivity.c \ src/core/ext/client_config/client_channel.c \ src/core/ext/client_config/client_channel_factory.c \ - src/core/ext/client_config/client_config.c \ src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/connector.c \ src/core/ext/client_config/default_initial_connect_string.c \ @@ -2871,8 +2924,8 @@ LIBGRPC_CRONET_SRC = \ src/core/ext/client_config/resolver.c \ src/core/ext/client_config/resolver_factory.c \ src/core/ext/client_config/resolver_registry.c \ + src/core/ext/client_config/resolver_result.c \ src/core/ext/client_config/subchannel.c \ - src/core/ext/client_config/subchannel_call_holder.c \ src/core/ext/client_config/subchannel_index.c \ src/core/ext/client_config/uri_parser.c \ src/core/lib/http/httpcli_security_connector.c \ @@ -2911,6 +2964,7 @@ PUBLIC_HEADERS_C += \ include/grpc/compression.h \ include/grpc/grpc.h \ include/grpc/grpc_posix.h \ + include/grpc/grpc_security_constants.h \ include/grpc/status.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -2935,7 +2989,6 @@ PUBLIC_HEADERS_C += \ include/grpc/impl/codegen/time.h \ include/grpc/grpc_cronet.h \ include/grpc/grpc_security.h \ - include/grpc/grpc_security_constants.h \ LIBGRPC_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CRONET_SRC)))) @@ -2955,7 +3008,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CRONE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) $(OPENSSL_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a endif @@ -3007,8 +3060,125 @@ LIBGRPC_TEST_UTIL_SRC = \ test/core/util/port_server_client.c \ test/core/util/port_windows.c \ test/core/util/slice_splitter.c \ + src/core/lib/channel/channel_args.c \ + src/core/lib/channel/channel_stack.c \ + src/core/lib/channel/channel_stack_builder.c \ + src/core/lib/channel/compress_filter.c \ + src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ + src/core/lib/channel/http_client_filter.c \ + src/core/lib/channel/http_server_filter.c \ + src/core/lib/compression/compression.c \ + src/core/lib/compression/message_compress.c \ + src/core/lib/debug/trace.c \ + src/core/lib/http/format_request.c \ + src/core/lib/http/httpcli.c \ + src/core/lib/http/parser.c \ + src/core/lib/iomgr/closure.c \ + src/core/lib/iomgr/endpoint.c \ + src/core/lib/iomgr/endpoint_pair_posix.c \ + src/core/lib/iomgr/endpoint_pair_windows.c \ + src/core/lib/iomgr/error.c \ + src/core/lib/iomgr/ev_epoll_linux.c \ + src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_posix.c \ + src/core/lib/iomgr/ev_posix.c \ + src/core/lib/iomgr/exec_ctx.c \ + src/core/lib/iomgr/executor.c \ + src/core/lib/iomgr/iocp_windows.c \ + src/core/lib/iomgr/iomgr.c \ + src/core/lib/iomgr/iomgr_posix.c \ + src/core/lib/iomgr/iomgr_windows.c \ + src/core/lib/iomgr/load_file.c \ + src/core/lib/iomgr/network_status_tracker.c \ + src/core/lib/iomgr/polling_entity.c \ + src/core/lib/iomgr/pollset_set_windows.c \ + src/core/lib/iomgr/pollset_windows.c \ + src/core/lib/iomgr/resolve_address_posix.c \ + src/core/lib/iomgr/resolve_address_windows.c \ + src/core/lib/iomgr/sockaddr_utils.c \ + src/core/lib/iomgr/socket_utils_common_posix.c \ + src/core/lib/iomgr/socket_utils_linux.c \ + src/core/lib/iomgr/socket_utils_posix.c \ + src/core/lib/iomgr/socket_windows.c \ + src/core/lib/iomgr/tcp_client_posix.c \ + src/core/lib/iomgr/tcp_client_windows.c \ + src/core/lib/iomgr/tcp_posix.c \ + src/core/lib/iomgr/tcp_server_posix.c \ + src/core/lib/iomgr/tcp_server_windows.c \ + src/core/lib/iomgr/tcp_windows.c \ + src/core/lib/iomgr/time_averaged_stats.c \ + src/core/lib/iomgr/timer.c \ + src/core/lib/iomgr/timer_heap.c \ + src/core/lib/iomgr/udp_server.c \ + src/core/lib/iomgr/unix_sockets_posix.c \ + src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_eventfd.c \ + src/core/lib/iomgr/wakeup_fd_nospecial.c \ + src/core/lib/iomgr/wakeup_fd_pipe.c \ + src/core/lib/iomgr/wakeup_fd_posix.c \ + src/core/lib/iomgr/workqueue_posix.c \ + src/core/lib/iomgr/workqueue_windows.c \ + src/core/lib/json/json.c \ + src/core/lib/json/json_reader.c \ + src/core/lib/json/json_string.c \ + src/core/lib/json/json_writer.c \ + src/core/lib/surface/alarm.c \ + src/core/lib/surface/api_trace.c \ + src/core/lib/surface/byte_buffer.c \ + src/core/lib/surface/byte_buffer_reader.c \ + src/core/lib/surface/call.c \ + src/core/lib/surface/call_details.c \ + src/core/lib/surface/call_log_batch.c \ + src/core/lib/surface/channel.c \ + src/core/lib/surface/channel_init.c \ + src/core/lib/surface/channel_ping.c \ + src/core/lib/surface/channel_stack_type.c \ + src/core/lib/surface/completion_queue.c \ + src/core/lib/surface/event_string.c \ + src/core/lib/surface/lame_client.c \ + src/core/lib/surface/metadata_array.c \ + src/core/lib/surface/server.c \ + src/core/lib/surface/validate_metadata.c \ + src/core/lib/surface/version.c \ + src/core/lib/transport/byte_stream.c \ + src/core/lib/transport/connectivity_state.c \ + src/core/lib/transport/metadata.c \ + src/core/lib/transport/metadata_batch.c \ + src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ + src/core/lib/transport/transport.c \ + src/core/lib/transport/transport_op_string.c \ PUBLIC_HEADERS_C += \ + include/grpc/byte_buffer.h \ + include/grpc/byte_buffer_reader.h \ + include/grpc/compression.h \ + include/grpc/grpc.h \ + include/grpc/grpc_posix.h \ + include/grpc/grpc_security_constants.h \ + include/grpc/status.h \ + include/grpc/impl/codegen/byte_buffer.h \ + include/grpc/impl/codegen/byte_buffer_reader.h \ + include/grpc/impl/codegen/compression_types.h \ + include/grpc/impl/codegen/connectivity_state.h \ + include/grpc/impl/codegen/grpc_types.h \ + include/grpc/impl/codegen/propagation_bits.h \ + include/grpc/impl/codegen/status.h \ + include/grpc/impl/codegen/alloc.h \ + include/grpc/impl/codegen/atm.h \ + include/grpc/impl/codegen/atm_gcc_atomic.h \ + include/grpc/impl/codegen/atm_gcc_sync.h \ + include/grpc/impl/codegen/atm_windows.h \ + include/grpc/impl/codegen/log.h \ + include/grpc/impl/codegen/port_platform.h \ + include/grpc/impl/codegen/slice.h \ + include/grpc/impl/codegen/slice_buffer.h \ + include/grpc/impl/codegen/sync.h \ + include/grpc/impl/codegen/sync_generic.h \ + include/grpc/impl/codegen/sync_posix.h \ + include/grpc/impl/codegen/sync_windows.h \ + include/grpc/impl/codegen/time.h \ LIBGRPC_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_TEST_UTIL_SRC)))) @@ -3027,7 +3197,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_TE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBGRPC_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBGRPC_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a endif @@ -3067,7 +3237,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a: $(ZLIB_DEP) $(LIBGRPC_TEST_UT $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBGRPC_TEST_UTIL_UNSECURE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a endif @@ -3088,6 +3258,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -3168,6 +3339,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \ @@ -3191,7 +3363,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ @@ -3200,7 +3371,6 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/client_config/channel_connectivity.c \ src/core/ext/client_config/client_channel.c \ src/core/ext/client_config/client_channel_factory.c \ - src/core/ext/client_config/client_config.c \ src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/connector.c \ src/core/ext/client_config/default_initial_connect_string.c \ @@ -3212,14 +3382,15 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/client_config/resolver.c \ src/core/ext/client_config/resolver_factory.c \ src/core/ext/client_config/resolver_registry.c \ + src/core/ext/client_config/resolver_result.c \ src/core/ext/client_config/subchannel.c \ - src/core/ext/client_config/subchannel_call_holder.c \ src/core/ext/client_config/subchannel_index.c \ src/core/ext/client_config/uri_parser.c \ src/core/ext/resolver/dns/native/dns_resolver.c \ src/core/ext/resolver/sockaddr/sockaddr_resolver.c \ src/core/ext/load_reporting/load_reporting.c \ src/core/ext/load_reporting/load_reporting_filter.c \ + src/core/ext/lb_policy/grpclb/grpclb.c \ src/core/ext/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ third_party/nanopb/pb_common.c \ @@ -3227,8 +3398,10 @@ LIBGRPC_UNSECURE_SRC = \ third_party/nanopb/pb_encode.c \ src/core/ext/lb_policy/pick_first/pick_first.c \ src/core/ext/lb_policy/round_robin/round_robin.c \ + src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ + src/core/ext/census/gen/trace_context.pb.c \ src/core/ext/census/grpc_context.c \ src/core/ext/census/grpc_filter.c \ src/core/ext/census/grpc_plugin.c \ @@ -3236,6 +3409,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ + src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_unsecure_plugin_registry.c \ @@ -3245,6 +3419,7 @@ PUBLIC_HEADERS_C += \ include/grpc/compression.h \ include/grpc/grpc.h \ include/grpc/grpc_posix.h \ + include/grpc/grpc_security_constants.h \ include/grpc/status.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ @@ -3276,7 +3451,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a: $(ZLIB_DEP) $(LIBGRPC_UNSECURE_OBJS) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBGRPC_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a endif @@ -3328,7 +3503,7 @@ $(LIBDIR)/$(CONFIG)/libreconnect_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBRECON $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libreconnect_server.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBRECONNECT_SERVER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBRECONNECT_SERVER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libreconnect_server.a endif @@ -3367,7 +3542,7 @@ $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBTEST_T $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBTEST_TCP_SERVER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBTEST_TCP_SERVER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a endif @@ -3400,6 +3575,7 @@ LIBGRPC++_SRC = \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ + src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ @@ -3417,6 +3593,95 @@ LIBGRPC++_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time.cc \ + src/core/lib/channel/channel_args.c \ + src/core/lib/channel/channel_stack.c \ + src/core/lib/channel/channel_stack_builder.c \ + src/core/lib/channel/compress_filter.c \ + src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ + src/core/lib/channel/http_client_filter.c \ + src/core/lib/channel/http_server_filter.c \ + src/core/lib/compression/compression.c \ + src/core/lib/compression/message_compress.c \ + src/core/lib/debug/trace.c \ + src/core/lib/http/format_request.c \ + src/core/lib/http/httpcli.c \ + src/core/lib/http/parser.c \ + src/core/lib/iomgr/closure.c \ + src/core/lib/iomgr/endpoint.c \ + src/core/lib/iomgr/endpoint_pair_posix.c \ + src/core/lib/iomgr/endpoint_pair_windows.c \ + src/core/lib/iomgr/error.c \ + src/core/lib/iomgr/ev_epoll_linux.c \ + src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_posix.c \ + src/core/lib/iomgr/ev_posix.c \ + src/core/lib/iomgr/exec_ctx.c \ + src/core/lib/iomgr/executor.c \ + src/core/lib/iomgr/iocp_windows.c \ + src/core/lib/iomgr/iomgr.c \ + src/core/lib/iomgr/iomgr_posix.c \ + src/core/lib/iomgr/iomgr_windows.c \ + src/core/lib/iomgr/load_file.c \ + src/core/lib/iomgr/network_status_tracker.c \ + src/core/lib/iomgr/polling_entity.c \ + src/core/lib/iomgr/pollset_set_windows.c \ + src/core/lib/iomgr/pollset_windows.c \ + src/core/lib/iomgr/resolve_address_posix.c \ + src/core/lib/iomgr/resolve_address_windows.c \ + src/core/lib/iomgr/sockaddr_utils.c \ + src/core/lib/iomgr/socket_utils_common_posix.c \ + src/core/lib/iomgr/socket_utils_linux.c \ + src/core/lib/iomgr/socket_utils_posix.c \ + src/core/lib/iomgr/socket_windows.c \ + src/core/lib/iomgr/tcp_client_posix.c \ + src/core/lib/iomgr/tcp_client_windows.c \ + src/core/lib/iomgr/tcp_posix.c \ + src/core/lib/iomgr/tcp_server_posix.c \ + src/core/lib/iomgr/tcp_server_windows.c \ + src/core/lib/iomgr/tcp_windows.c \ + src/core/lib/iomgr/time_averaged_stats.c \ + src/core/lib/iomgr/timer.c \ + src/core/lib/iomgr/timer_heap.c \ + src/core/lib/iomgr/udp_server.c \ + src/core/lib/iomgr/unix_sockets_posix.c \ + src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_eventfd.c \ + src/core/lib/iomgr/wakeup_fd_nospecial.c \ + src/core/lib/iomgr/wakeup_fd_pipe.c \ + src/core/lib/iomgr/wakeup_fd_posix.c \ + src/core/lib/iomgr/workqueue_posix.c \ + src/core/lib/iomgr/workqueue_windows.c \ + src/core/lib/json/json.c \ + src/core/lib/json/json_reader.c \ + src/core/lib/json/json_string.c \ + src/core/lib/json/json_writer.c \ + src/core/lib/surface/alarm.c \ + src/core/lib/surface/api_trace.c \ + src/core/lib/surface/byte_buffer.c \ + src/core/lib/surface/byte_buffer_reader.c \ + src/core/lib/surface/call.c \ + src/core/lib/surface/call_details.c \ + src/core/lib/surface/call_log_batch.c \ + src/core/lib/surface/channel.c \ + src/core/lib/surface/channel_init.c \ + src/core/lib/surface/channel_ping.c \ + src/core/lib/surface/channel_stack_type.c \ + src/core/lib/surface/completion_queue.c \ + src/core/lib/surface/event_string.c \ + src/core/lib/surface/lame_client.c \ + src/core/lib/surface/metadata_array.c \ + src/core/lib/surface/server.c \ + src/core/lib/surface/validate_metadata.c \ + src/core/lib/surface/version.c \ + src/core/lib/transport/byte_stream.c \ + src/core/lib/transport/connectivity_state.c \ + src/core/lib/transport/metadata.c \ + src/core/lib/transport/metadata_batch.c \ + src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ + src/core/lib/transport/transport.c \ + src/core/lib/transport/transport_op_string.c \ src/cpp/codegen/codegen_init.cc \ PUBLIC_HEADERS_CXX += \ @@ -3467,36 +3732,13 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/stub_options.h \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ - include/grpc++/impl/codegen/async_stream.h \ - include/grpc++/impl/codegen/async_unary_call.h \ - include/grpc++/impl/codegen/call.h \ - include/grpc++/impl/codegen/call_hook.h \ - include/grpc++/impl/codegen/channel_interface.h \ - include/grpc++/impl/codegen/client_context.h \ - include/grpc++/impl/codegen/client_unary_call.h \ - include/grpc++/impl/codegen/completion_queue.h \ - include/grpc++/impl/codegen/completion_queue_tag.h \ - include/grpc++/impl/codegen/config.h \ - include/grpc++/impl/codegen/core_codegen_interface.h \ - include/grpc++/impl/codegen/create_auth_context.h \ - include/grpc++/impl/codegen/grpc_library.h \ - include/grpc++/impl/codegen/method_handler_impl.h \ - include/grpc++/impl/codegen/rpc_method.h \ - include/grpc++/impl/codegen/rpc_service_method.h \ - include/grpc++/impl/codegen/security/auth_context.h \ - include/grpc++/impl/codegen/serialization_traits.h \ - include/grpc++/impl/codegen/server_context.h \ - include/grpc++/impl/codegen/server_interface.h \ - include/grpc++/impl/codegen/service_type.h \ - include/grpc++/impl/codegen/status.h \ - include/grpc++/impl/codegen/status_code_enum.h \ - include/grpc++/impl/codegen/string_ref.h \ - include/grpc++/impl/codegen/stub_options.h \ - include/grpc++/impl/codegen/sync.h \ - include/grpc++/impl/codegen/sync_cxx11.h \ - include/grpc++/impl/codegen/sync_no_cxx11.h \ - include/grpc++/impl/codegen/sync_stream.h \ - include/grpc++/impl/codegen/time.h \ + include/grpc/byte_buffer.h \ + include/grpc/byte_buffer_reader.h \ + include/grpc/compression.h \ + include/grpc/grpc.h \ + include/grpc/grpc_posix.h \ + include/grpc/grpc_security_constants.h \ + include/grpc/status.h \ include/grpc/impl/codegen/byte_buffer.h \ include/grpc/impl/codegen/byte_buffer_reader.h \ include/grpc/impl/codegen/compression_types.h \ @@ -3518,6 +3760,36 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/sync_posix.h \ include/grpc/impl/codegen/sync_windows.h \ include/grpc/impl/codegen/time.h \ + include/grpc++/impl/codegen/async_stream.h \ + include/grpc++/impl/codegen/async_unary_call.h \ + include/grpc++/impl/codegen/call.h \ + include/grpc++/impl/codegen/call_hook.h \ + include/grpc++/impl/codegen/channel_interface.h \ + include/grpc++/impl/codegen/client_context.h \ + include/grpc++/impl/codegen/client_unary_call.h \ + include/grpc++/impl/codegen/completion_queue.h \ + include/grpc++/impl/codegen/completion_queue_tag.h \ + include/grpc++/impl/codegen/config.h \ + include/grpc++/impl/codegen/core_codegen_interface.h \ + include/grpc++/impl/codegen/create_auth_context.h \ + include/grpc++/impl/codegen/grpc_library.h \ + include/grpc++/impl/codegen/method_handler_impl.h \ + include/grpc++/impl/codegen/rpc_method.h \ + include/grpc++/impl/codegen/rpc_service_method.h \ + include/grpc++/impl/codegen/security/auth_context.h \ + include/grpc++/impl/codegen/serialization_traits.h \ + include/grpc++/impl/codegen/server_context.h \ + include/grpc++/impl/codegen/server_interface.h \ + include/grpc++/impl/codegen/service_type.h \ + include/grpc++/impl/codegen/status.h \ + include/grpc++/impl/codegen/status_code_enum.h \ + include/grpc++/impl/codegen/string_ref.h \ + include/grpc++/impl/codegen/stub_options.h \ + include/grpc++/impl/codegen/sync.h \ + include/grpc++/impl/codegen/sync_cxx11.h \ + include/grpc++/impl/codegen/sync_no_cxx11.h \ + include/grpc++/impl/codegen/sync_stream.h \ + include/grpc++/impl/codegen/time.h \ LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC)))) @@ -3546,7 +3818,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LI $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++.a endif @@ -3554,18 +3826,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp -lgpr-imp else -$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP) +$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(OPENSSL_DEP) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc -lgpr else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc -lgpr $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so endif @@ -3673,7 +3945,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBU $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a endif @@ -3709,6 +3981,55 @@ endif endif +LIBGRPC++_REFLECTION_CODEGEN_SRC = \ + $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc \ + +PUBLIC_HEADERS_CXX += \ + +LIBGRPC++_REFLECTION_CODEGEN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_CODEGEN_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_CODEGEN_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a $(LIBGRPC++_REFLECTION_CODEGEN_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection_codegen.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC++_REFLECTION_CODEGEN_OBJS:.o=.dep) +endif +endif + + LIBGRPC++_TEST_CONFIG_SRC = \ test/cpp/util/test_config.cc \ @@ -3739,7 +4060,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBGRPC++_TEST_CONFIG_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBGRPC++_TEST_CONFIG_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a endif @@ -3824,6 +4145,8 @@ PUBLIC_HEADERS_CXX += \ include/grpc/impl/codegen/time.h \ include/grpc++/impl/codegen/proto_utils.h \ include/grpc++/impl/codegen/config_protobuf.h \ + include/grpc++/impl/codegen/thrift_serializer.h \ + include/grpc++/impl/codegen/thrift_utils.h \ LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) @@ -3850,7 +4173,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBGRPC++_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBGRPC++_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a endif @@ -3887,6 +4210,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/client/generic_stub.cc \ src/cpp/client/insecure_credentials.cc \ src/cpp/common/channel_arguments.cc \ + src/cpp/common/channel_filter.cc \ src/cpp/common/completion_queue.cc \ src/cpp/common/core_codegen.cc \ src/cpp/common/rpc_method.cc \ @@ -3904,6 +4228,95 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/util/status.cc \ src/cpp/util/string_ref.cc \ src/cpp/util/time.cc \ + src/core/lib/channel/channel_args.c \ + src/core/lib/channel/channel_stack.c \ + src/core/lib/channel/channel_stack_builder.c \ + src/core/lib/channel/compress_filter.c \ + src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ + src/core/lib/channel/http_client_filter.c \ + src/core/lib/channel/http_server_filter.c \ + src/core/lib/compression/compression.c \ + src/core/lib/compression/message_compress.c \ + src/core/lib/debug/trace.c \ + src/core/lib/http/format_request.c \ + src/core/lib/http/httpcli.c \ + src/core/lib/http/parser.c \ + src/core/lib/iomgr/closure.c \ + src/core/lib/iomgr/endpoint.c \ + src/core/lib/iomgr/endpoint_pair_posix.c \ + src/core/lib/iomgr/endpoint_pair_windows.c \ + src/core/lib/iomgr/error.c \ + src/core/lib/iomgr/ev_epoll_linux.c \ + src/core/lib/iomgr/ev_poll_and_epoll_posix.c \ + src/core/lib/iomgr/ev_poll_posix.c \ + src/core/lib/iomgr/ev_posix.c \ + src/core/lib/iomgr/exec_ctx.c \ + src/core/lib/iomgr/executor.c \ + src/core/lib/iomgr/iocp_windows.c \ + src/core/lib/iomgr/iomgr.c \ + src/core/lib/iomgr/iomgr_posix.c \ + src/core/lib/iomgr/iomgr_windows.c \ + src/core/lib/iomgr/load_file.c \ + src/core/lib/iomgr/network_status_tracker.c \ + src/core/lib/iomgr/polling_entity.c \ + src/core/lib/iomgr/pollset_set_windows.c \ + src/core/lib/iomgr/pollset_windows.c \ + src/core/lib/iomgr/resolve_address_posix.c \ + src/core/lib/iomgr/resolve_address_windows.c \ + src/core/lib/iomgr/sockaddr_utils.c \ + src/core/lib/iomgr/socket_utils_common_posix.c \ + src/core/lib/iomgr/socket_utils_linux.c \ + src/core/lib/iomgr/socket_utils_posix.c \ + src/core/lib/iomgr/socket_windows.c \ + src/core/lib/iomgr/tcp_client_posix.c \ + src/core/lib/iomgr/tcp_client_windows.c \ + src/core/lib/iomgr/tcp_posix.c \ + src/core/lib/iomgr/tcp_server_posix.c \ + src/core/lib/iomgr/tcp_server_windows.c \ + src/core/lib/iomgr/tcp_windows.c \ + src/core/lib/iomgr/time_averaged_stats.c \ + src/core/lib/iomgr/timer.c \ + src/core/lib/iomgr/timer_heap.c \ + src/core/lib/iomgr/udp_server.c \ + src/core/lib/iomgr/unix_sockets_posix.c \ + src/core/lib/iomgr/unix_sockets_posix_noop.c \ + src/core/lib/iomgr/wakeup_fd_eventfd.c \ + src/core/lib/iomgr/wakeup_fd_nospecial.c \ + src/core/lib/iomgr/wakeup_fd_pipe.c \ + src/core/lib/iomgr/wakeup_fd_posix.c \ + src/core/lib/iomgr/workqueue_posix.c \ + src/core/lib/iomgr/workqueue_windows.c \ + src/core/lib/json/json.c \ + src/core/lib/json/json_reader.c \ + src/core/lib/json/json_string.c \ + src/core/lib/json/json_writer.c \ + src/core/lib/surface/alarm.c \ + src/core/lib/surface/api_trace.c \ + src/core/lib/surface/byte_buffer.c \ + src/core/lib/surface/byte_buffer_reader.c \ + src/core/lib/surface/call.c \ + src/core/lib/surface/call_details.c \ + src/core/lib/surface/call_log_batch.c \ + src/core/lib/surface/channel.c \ + src/core/lib/surface/channel_init.c \ + src/core/lib/surface/channel_ping.c \ + src/core/lib/surface/channel_stack_type.c \ + src/core/lib/surface/completion_queue.c \ + src/core/lib/surface/event_string.c \ + src/core/lib/surface/lame_client.c \ + src/core/lib/surface/metadata_array.c \ + src/core/lib/surface/server.c \ + src/core/lib/surface/validate_metadata.c \ + src/core/lib/surface/version.c \ + src/core/lib/transport/byte_stream.c \ + src/core/lib/transport/connectivity_state.c \ + src/core/lib/transport/metadata.c \ + src/core/lib/transport/metadata_batch.c \ + src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ + src/core/lib/transport/transport.c \ + src/core/lib/transport/transport_op_string.c \ src/cpp/codegen/codegen_init.cc \ PUBLIC_HEADERS_CXX += \ @@ -3954,6 +4367,34 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/support/stub_options.h \ include/grpc++/support/sync_stream.h \ include/grpc++/support/time.h \ + include/grpc/byte_buffer.h \ + include/grpc/byte_buffer_reader.h \ + include/grpc/compression.h \ + include/grpc/grpc.h \ + include/grpc/grpc_posix.h \ + include/grpc/grpc_security_constants.h \ + include/grpc/status.h \ + include/grpc/impl/codegen/byte_buffer.h \ + include/grpc/impl/codegen/byte_buffer_reader.h \ + include/grpc/impl/codegen/compression_types.h \ + include/grpc/impl/codegen/connectivity_state.h \ + include/grpc/impl/codegen/grpc_types.h \ + include/grpc/impl/codegen/propagation_bits.h \ + include/grpc/impl/codegen/status.h \ + include/grpc/impl/codegen/alloc.h \ + include/grpc/impl/codegen/atm.h \ + include/grpc/impl/codegen/atm_gcc_atomic.h \ + include/grpc/impl/codegen/atm_gcc_sync.h \ + include/grpc/impl/codegen/atm_windows.h \ + include/grpc/impl/codegen/log.h \ + include/grpc/impl/codegen/port_platform.h \ + include/grpc/impl/codegen/slice.h \ + include/grpc/impl/codegen/slice_buffer.h \ + include/grpc/impl/codegen/sync.h \ + include/grpc/impl/codegen/sync_generic.h \ + include/grpc/impl/codegen/sync_posix.h \ + include/grpc/impl/codegen/sync_windows.h \ + include/grpc/impl/codegen/time.h \ include/grpc++/impl/codegen/async_stream.h \ include/grpc++/impl/codegen/async_unary_call.h \ include/grpc++/impl/codegen/call.h \ @@ -3984,27 +4425,6 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/codegen/sync_no_cxx11.h \ include/grpc++/impl/codegen/sync_stream.h \ include/grpc++/impl/codegen/time.h \ - include/grpc/impl/codegen/byte_buffer.h \ - include/grpc/impl/codegen/byte_buffer_reader.h \ - include/grpc/impl/codegen/compression_types.h \ - include/grpc/impl/codegen/connectivity_state.h \ - include/grpc/impl/codegen/grpc_types.h \ - include/grpc/impl/codegen/propagation_bits.h \ - include/grpc/impl/codegen/status.h \ - include/grpc/impl/codegen/alloc.h \ - include/grpc/impl/codegen/atm.h \ - include/grpc/impl/codegen/atm_gcc_atomic.h \ - include/grpc/impl/codegen/atm_gcc_sync.h \ - include/grpc/impl/codegen/atm_windows.h \ - include/grpc/impl/codegen/log.h \ - include/grpc/impl/codegen/port_platform.h \ - include/grpc/impl/codegen/slice.h \ - include/grpc/impl/codegen/slice_buffer.h \ - include/grpc/impl/codegen/sync.h \ - include/grpc/impl/codegen/sync_generic.h \ - include/grpc/impl/codegen/sync_posix.h \ - include/grpc/impl/codegen/sync_windows.h \ - include/grpc/impl/codegen/time.h \ LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC)))) @@ -4023,7 +4443,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) $(LIBGPR_OBJS) $(ZLIB_MERGE_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a endif @@ -4031,18 +4451,18 @@ endif ifeq ($(SYSTEM),MINGW32) -$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) +$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp -lgrpc-imp + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp else -$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` ifeq ($(SYSTEM),Darwin) - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure else - $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure -lgrpc + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so.1 $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so endif @@ -4057,7 +4477,10 @@ endif LIBGRPC_CLI_LIBS_SRC = \ test/cpp/util/cli_call.cc \ + test/cpp/util/cli_credentials.cc \ + test/cpp/util/grpc_tool.cc \ test/cpp/util/proto_file_parser.cc \ + test/cpp/util/proto_reflection_descriptor_database.cc \ PUBLIC_HEADERS_CXX += \ @@ -4086,7 +4509,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBGRPC_CLI_LIBS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBGRPC_CLI_LIBS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a endif @@ -4132,7 +4555,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a $(LIBGRPC_PLUGIN_SUPPORT_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_plugin_support.a endif @@ -4178,7 +4601,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PRO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBINTEROP_CLIENT_HELPER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBINTEROP_CLIENT_HELPER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a endif @@ -4232,7 +4655,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_client_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_main.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBINTEROP_CLIENT_MAIN_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBINTEROP_CLIENT_MAIN_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_client_main.a endif @@ -4283,7 +4706,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PRO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBINTEROP_SERVER_HELPER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBINTEROP_SERVER_HELPER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a endif @@ -4302,7 +4725,7 @@ endif endif -LIBINTEROP_SERVER_MAIN_SRC = \ +LIBINTEROP_SERVER_LIB_SRC = \ $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.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/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc \ @@ -4310,6 +4733,56 @@ LIBINTEROP_SERVER_MAIN_SRC = \ PUBLIC_HEADERS_CXX += \ +LIBINTEROP_SERVER_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_LIB_SRC)))) + + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL. + +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: protobuf_dep_error + + +else + +$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBINTEROP_SERVER_LIB_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBINTEROP_SERVER_LIB_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.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/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc + + +LIBINTEROP_SERVER_MAIN_SRC = \ + test/cpp/interop/interop_server_bootstrap.cc \ + +PUBLIC_HEADERS_CXX += \ + LIBINTEROP_SERVER_MAIN_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_MAIN_SRC)))) @@ -4335,7 +4808,7 @@ $(LIBDIR)/$(CONFIG)/libinterop_server_main.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTO $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_main.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBINTEROP_SERVER_MAIN_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBINTEROP_SERVER_MAIN_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libinterop_server_main.a endif @@ -4352,7 +4825,6 @@ ifneq ($(NO_DEPS),true) -include $(LIBINTEROP_SERVER_MAIN_OBJS:.o=.dep) endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_server.o: $(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.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/test.pb.cc $(GENDIR)/src/proto/grpc/testing/test.grpc.pb.cc LIBQPS_SRC = \ @@ -4400,7 +4872,7 @@ $(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBQP $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libqps.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBQPS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBQPS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libqps.a endif @@ -4453,7 +4925,7 @@ $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_C $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a $(LIBGRPC_CSHARP_EXT_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a endif @@ -4797,7 +5269,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl.a: $(ZLIB_DEP) $(LIBBORINGSSL_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl.a $(LIBBORINGSSL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl.a $(LIBBORINGSSL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl.a endif @@ -4835,7 +5307,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBBORINGSSL_TEST_UTIL_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBBORINGSSL_TEST_UTIL_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a endif @@ -4873,7 +5345,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBBORINGSSL_AES_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a endif @@ -4911,7 +5383,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBBORINGSSL_ASN1_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a endif @@ -4949,7 +5421,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBBORINGSSL_BASE64_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a endif @@ -4987,7 +5459,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBBORINGSSL_BIO_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a endif @@ -5025,7 +5497,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBBORINGSSL_BN_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a endif @@ -5063,7 +5535,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBBORINGSSL_BYTESTRING_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a endif @@ -5101,7 +5573,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBBORINGSSL_AEAD_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a endif @@ -5139,7 +5611,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBBORINGSSL_CIPHER_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a endif @@ -5177,7 +5649,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBBORINGSSL_CMAC_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a endif @@ -5206,7 +5678,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a: $(ZLIB_DEP) $(LIBBOR $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a $(LIBBORINGSSL_CONSTANT_TIME_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_constant_time_test_lib.a endif @@ -5242,7 +5714,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBBORINGSSL_ED25519_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a endif @@ -5280,7 +5752,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBBORINGSSL_X25519_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a endif @@ -5318,7 +5790,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBBORINGSSL_DH_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a endif @@ -5356,7 +5828,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBBORINGSSL_DIGEST_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a endif @@ -5385,7 +5857,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_DSA $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a $(LIBBORINGSSL_DSA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_dsa_test_lib.a endif @@ -5421,7 +5893,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBBORINGSSL_EC_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a endif @@ -5450,7 +5922,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a $(LIBBORINGSSL_EXAMPLE_MUL_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_example_mul_lib.a endif @@ -5486,7 +5958,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBBORINGSSL_ECDSA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a endif @@ -5524,7 +5996,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBBORINGSSL_ERR_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a endif @@ -5562,7 +6034,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_D $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBBORINGSSL_EVP_EXTRA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a endif @@ -5600,7 +6072,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBBORINGSSL_EVP_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a endif @@ -5638,7 +6110,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBBORINGSSL_PBKDF_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a endif @@ -5667,7 +6139,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_HK $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a $(LIBBORINGSSL_HKDF_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hkdf_test_lib.a endif @@ -5703,7 +6175,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBBORINGSSL_HMAC_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a endif @@ -5732,7 +6204,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_L $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a $(LIBBORINGSSL_LHASH_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_lhash_test_lib.a endif @@ -5759,7 +6231,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_GCM $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBBORINGSSL_GCM_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a endif @@ -5795,7 +6267,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBBORINGSSL_PKCS12_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a endif @@ -5833,7 +6305,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBBORINGSSL_PKCS8_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a endif @@ -5871,7 +6343,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBBORINGSSL_POLY1305_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a endif @@ -5900,7 +6372,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSS $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a $(LIBBORINGSSL_REFCOUNT_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_refcount_test_lib.a endif @@ -5936,7 +6408,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBBORINGSSL_RSA_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a endif @@ -5965,7 +6437,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a $(LIBBORINGSSL_THREAD_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_thread_test_lib.a endif @@ -5992,7 +6464,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_P $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a $(LIBBORINGSSL_PKCS7_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pkcs7_test_lib.a endif @@ -6028,7 +6500,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBBORINGSSL_X509_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a endif @@ -6057,7 +6529,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_TAB $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a $(LIBBORINGSSL_TAB_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_tab_test_lib.a endif @@ -6084,7 +6556,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a $(LIBBORINGSSL_V3NAME_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_v3name_test_lib.a endif @@ -6111,7 +6583,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a: $(ZLIB_DEP) $(LIBBORINGSSL_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a $(LIBBORINGSSL_PQUEUE_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_pqueue_test_lib.a endif @@ -6147,7 +6619,7 @@ $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $( $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBBORINGSSL_SSL_TEST_LIB_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a endif @@ -6189,7 +6661,7 @@ $(LIBDIR)/$(CONFIG)/libz.a: $(LIBZ_OBJS) $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libz.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libz.a $(LIBZ_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libz.a $(LIBZ_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libz.a endif @@ -6224,7 +6696,7 @@ $(LIBDIR)/$(CONFIG)/libbad_client_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBBAD_CL $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_client_test.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBBAD_CLIENT_TEST_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBBAD_CLIENT_TEST_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbad_client_test.a endif @@ -6263,7 +6735,7 @@ $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBBA $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBBAD_SSL_TEST_SERVER_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBBAD_SSL_TEST_SERVER_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a endif @@ -6296,6 +6768,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/default_host.c \ test/core/end2end/tests/disappearing_server.c \ test/core/end2end/tests/empty_batch.c \ + test/core/end2end/tests/filter_call_init_fails.c \ test/core/end2end/tests/filter_causes_close.c \ test/core/end2end/tests/graceful_server_shutdown.c \ test/core/end2end/tests/high_initial_seqno.c \ @@ -6303,10 +6776,12 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/idempotent_request.c \ test/core/end2end/tests/invoke_large_request.c \ test/core/end2end/tests/large_metadata.c \ + test/core/end2end/tests/load_reporting_hook.c \ test/core/end2end/tests/max_concurrent_streams.c \ test/core/end2end/tests/max_message_length.c \ test/core/end2end/tests/negative_deadline.c \ test/core/end2end/tests/network_status_change.c \ + test/core/end2end/tests/no_logging.c \ test/core/end2end/tests/no_op.c \ test/core/end2end/tests/payload.c \ test/core/end2end/tests/ping.c \ @@ -6317,6 +6792,7 @@ LIBEND2END_TESTS_SRC = \ test/core/end2end/tests/server_finishes_request.c \ test/core/end2end/tests/shutdown_finishes_calls.c \ test/core/end2end/tests/shutdown_finishes_tags.c \ + test/core/end2end/tests/simple_cacheable_request.c \ test/core/end2end/tests/simple_delayed_request.c \ test/core/end2end/tests/simple_metadata.c \ test/core/end2end/tests/simple_request.c \ @@ -6342,7 +6818,7 @@ $(LIBDIR)/$(CONFIG)/libend2end_tests.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBEND2END_ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_tests.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBEND2END_TESTS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBEND2END_TESTS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_tests.a endif @@ -6374,6 +6850,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/default_host.c \ test/core/end2end/tests/disappearing_server.c \ test/core/end2end/tests/empty_batch.c \ + test/core/end2end/tests/filter_call_init_fails.c \ test/core/end2end/tests/filter_causes_close.c \ test/core/end2end/tests/graceful_server_shutdown.c \ test/core/end2end/tests/high_initial_seqno.c \ @@ -6381,10 +6858,12 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/idempotent_request.c \ test/core/end2end/tests/invoke_large_request.c \ test/core/end2end/tests/large_metadata.c \ + test/core/end2end/tests/load_reporting_hook.c \ test/core/end2end/tests/max_concurrent_streams.c \ test/core/end2end/tests/max_message_length.c \ test/core/end2end/tests/negative_deadline.c \ test/core/end2end/tests/network_status_change.c \ + test/core/end2end/tests/no_logging.c \ test/core/end2end/tests/no_op.c \ test/core/end2end/tests/payload.c \ test/core/end2end/tests/ping.c \ @@ -6395,6 +6874,7 @@ LIBEND2END_NOSEC_TESTS_SRC = \ test/core/end2end/tests/server_finishes_request.c \ test/core/end2end/tests/shutdown_finishes_calls.c \ test/core/end2end/tests/shutdown_finishes_tags.c \ + test/core/end2end/tests/simple_cacheable_request.c \ test/core/end2end/tests/simple_delayed_request.c \ test/core/end2end/tests/simple_metadata.c \ test/core/end2end/tests/simple_request.c \ @@ -6410,7 +6890,7 @@ $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a: $(ZLIB_DEP) $(LIBEND2END_NOSEC_TE $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBEND2END_NOSEC_TESTS_OBJS) + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBEND2END_NOSEC_TESTS_OBJS) ifeq ($(SYSTEM),Darwin) $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a endif @@ -6697,20 +7177,52 @@ else -$(BINDIR)/$(CONFIG)/census_context_test: $(CENSUS_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/census_context_test: $(CENSUS_CONTEXT_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) $(LD) $(LDFLAGS) $(CENSUS_CONTEXT_TEST_OBJS) $(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)/census_context_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/census/context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_census_context_test: $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep) +endif +endif + + +CENSUS_RESOURCE_TEST_SRC = \ + test/core/census/resource_test.c \ + +CENSUS_RESOURCE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_RESOURCE_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/census_resource_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/census_resource_test: $(CENSUS_RESOURCE_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) $(LD) $(LDFLAGS) $(CENSUS_CONTEXT_TEST_OBJS) $(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)/census_context_test + $(Q) $(LD) $(LDFLAGS) $(CENSUS_RESOURCE_TEST_OBJS) $(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)/census_resource_test endif -$(OBJDIR)/$(CONFIG)/test/core/census/context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/census/resource_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_census_context_test: $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep) +deps_census_resource_test: $(CENSUS_RESOURCE_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep) +-include $(CENSUS_RESOURCE_TEST_OBJS:.o=.dep) endif endif @@ -7387,6 +7899,38 @@ endif endif +GEN_PERCENT_ENCODING_TABLES_SRC = \ + tools/codegen/core/gen_percent_encoding_tables.c \ + +GEN_PERCENT_ENCODING_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_PERCENT_ENCODING_TABLES_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(GEN_PERCENT_ENCODING_TABLES_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables + +endif + +$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_percent_encoding_tables.o: + +deps_gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep) +endif +endif + + GOAWAY_SERVER_TEST_SRC = \ test/core/end2end/goaway_server_test.c \ @@ -7675,6 +8219,38 @@ endif endif +GPR_PERCENT_ENCODING_TEST_SRC = \ + test/core/support/percent_encoding_test.c \ + +GPR_PERCENT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_PERCENT_ENCODING_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test: $(GPR_PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(GPR_PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/percent_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_gpr_percent_encoding_test: $(GPR_PERCENT_ENCODING_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GPR_PERCENT_ENCODING_TEST_OBJS:.o=.dep) +endif +endif + + GPR_SLICE_BUFFER_TEST_SRC = \ test/core/support/slice_buffer_test.c \ @@ -9403,6 +9979,70 @@ endif endif +PERCENT_DECODE_FUZZER_SRC = \ + test/core/support/percent_decode_fuzzer.c \ + +PERCENT_DECODE_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_DECODE_FUZZER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_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) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep) +endif +endif + + +PERCENT_ENCODE_FUZZER_SRC = \ + test/core/support/percent_encode_fuzzer.c \ + +PERCENT_ENCODE_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_ENCODE_FUZZER_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_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) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep) +endif +endif + + RESOLVE_ADDRESS_TEST_SRC = \ test/core/iomgr/resolve_address_test.c \ @@ -9884,7 +10524,7 @@ endif TIMEOUT_ENCODING_TEST_SRC = \ - test/core/transport/chttp2/timeout_encoding_test.c \ + test/core/transport/timeout_encoding_test.c \ TIMEOUT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TIMEOUT_ENCODING_TEST_SRC)))) ifeq ($(NO_SECURE),true) @@ -9904,7 +10544,7 @@ $(BINDIR)/$(CONFIG)/timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS) $(LIBDI endif -$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/transport/timeout_encoding_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a deps_timeout_encoding_test: $(TIMEOUT_ENCODING_TEST_OBJS:.o=.dep) @@ -10852,6 +11492,49 @@ endif endif +FILTER_END2END_TEST_SRC = \ + test/cpp/end2end/filter_end2end_test.cc \ + +FILTER_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(FILTER_END2END_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/filter_end2end_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.0.0+. + +$(BINDIR)/$(CONFIG)/filter_end2end_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/filter_end2end_test: $(PROTOBUF_DEP) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(FILTER_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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)/filter_end2end_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/filter_end2end_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_filter_end2end_test: $(FILTER_END2END_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(FILTER_END2END_TEST_OBJS:.o=.dep) +endif +endif + + GENERIC_END2END_TEST_SRC = \ test/cpp/end2end/generic_end2end_test.cc \ @@ -10965,16 +11648,16 @@ $(BINDIR)/$(CONFIG)/grpc_cli: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.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)/grpc_cli + $(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli endif endif -$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep) @@ -11171,6 +11854,60 @@ ifneq ($(NO_DEPS),true) endif +GRPC_TOOL_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \ + $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \ + test/cpp/util/grpc_tool_test.cc \ + test/cpp/util/string_ref_helper.cc \ + +GRPC_TOOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_TOOL_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/grpc_tool_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.0.0+. + +$(BINDIR)/$(CONFIG)/grpc_tool_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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)/grpc_tool_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo_messages.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPC_TOOL_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc + + GRPCLB_API_TEST_SRC = \ $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ test/cpp/grpclb/grpclb_api_test.cc \ @@ -11218,6 +11955,53 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_api_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc +GRPCLB_TEST_SRC = \ + $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \ + test/cpp/grpclb/grpclb_test.cc \ + +GRPCLB_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPCLB_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/grpclb_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.0.0+. + +$(BINDIR)/$(CONFIG)/grpclb_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/grpclb_test: $(PROTOBUF_DEP) $(GRPCLB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(GRPCLB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpclb_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/src/proto/grpc/lb/v1/load_balancer.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a + +$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a + +deps_grpclb_test: $(GRPCLB_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GRPCLB_TEST_OBJS:.o=.dep) +endif +endif +$(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc + + HYBRID_END2END_TEST_SRC = \ test/cpp/end2end/hybrid_end2end_test.cc \ @@ -11311,10 +12095,10 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a +$(BINDIR)/$(CONFIG)/interop_server: $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.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) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.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)/interop_server + $(Q) $(LDXX) $(LDFLAGS) $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.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)/interop_server endif @@ -13892,34 +14676,34 @@ endif endif -H2_LOADREPORTING_TEST_SRC = \ - test/core/end2end/fixtures/h2_loadreporting.c \ +H2_LOAD_REPORTING_TEST_SRC = \ + test/core/end2end/fixtures/h2_load_reporting.c \ -H2_LOADREPORTING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOADREPORTING_TEST_SRC)))) +H2_LOAD_REPORTING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOAD_REPORTING_TEST_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL. -$(BINDIR)/$(CONFIG)/h2_loadreporting_test: openssl_dep_error +$(BINDIR)/$(CONFIG)/h2_load_reporting_test: openssl_dep_error else -$(BINDIR)/$(CONFIG)/h2_loadreporting_test: $(H2_LOADREPORTING_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_load_reporting_test: $(H2_LOAD_REPORTING_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_LOADREPORTING_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_loadreporting_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOAD_REPORTING_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_load_reporting_test endif -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_loadreporting.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_load_reporting.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_loadreporting_test: $(H2_LOADREPORTING_TEST_OBJS:.o=.dep) +deps_h2_load_reporting_test: $(H2_LOAD_REPORTING_TEST_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(H2_LOADREPORTING_TEST_OBJS:.o=.dep) +-include $(H2_LOAD_REPORTING_TEST_OBJS:.o=.dep) endif endif @@ -14332,23 +15116,23 @@ ifneq ($(NO_DEPS),true) endif -H2_LOADREPORTING_NOSEC_TEST_SRC = \ - test/core/end2end/fixtures/h2_loadreporting.c \ +H2_LOAD_REPORTING_NOSEC_TEST_SRC = \ + test/core/end2end/fixtures/h2_load_reporting.c \ -H2_LOADREPORTING_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOADREPORTING_NOSEC_TEST_SRC)))) +H2_LOAD_REPORTING_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOAD_REPORTING_NOSEC_TEST_SRC)))) -$(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test: $(H2_LOADREPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test: $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(E) "[LD] Linking $@" $(Q) mkdir -p `dirname $@` - $(Q) $(LD) $(LDFLAGS) $(H2_LOADREPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test + $(Q) $(LD) $(LDFLAGS) $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_load_reporting_nosec_test -$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_loadreporting.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a +$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_load_reporting.o: $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a -deps_h2_loadreporting_nosec_test: $(H2_LOADREPORTING_NOSEC_TEST_OBJS:.o=.dep) +deps_h2_load_reporting_nosec_test: $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS:.o=.dep) ifneq ($(NO_DEPS),true) --include $(H2_LOADREPORTING_NOSEC_TEST_OBJS:.o=.dep) +-include $(H2_LOAD_REPORTING_NOSEC_TEST_OBJS:.o=.dep) endif @@ -14732,6 +15516,76 @@ endif endif +PERCENT_DECODE_FUZZER_ONE_ENTRY_SRC = \ + test/core/support/percent_decode_fuzzer.c \ + test/core/util/one_corpus_entry_fuzzer.c \ + +PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_DECODE_FUZZER_ONE_ENTRY_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_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) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(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)/percent_decode_fuzzer_one_entry + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/percent_decode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) +endif +endif + + +PERCENT_ENCODE_FUZZER_ONE_ENTRY_SRC = \ + test/core/support/percent_encode_fuzzer.c \ + test/core/util/one_corpus_entry_fuzzer.c \ + +PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_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) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(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)/percent_encode_fuzzer_one_entry + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/percent_encode_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep) +endif +endif + + SERVER_FUZZER_ONE_ENTRY_SRC = \ test/core/end2end/fuzzers/server_fuzzer.c \ test/core/util/one_corpus_entry_fuzzer.c \ @@ -14872,6 +15726,7 @@ test/cpp/interop/client.cc: $(OPENSSL_DEP) test/cpp/interop/client_helper.cc: $(OPENSSL_DEP) test/cpp/interop/interop_client.cc: $(OPENSSL_DEP) test/cpp/interop/interop_server.cc: $(OPENSSL_DEP) +test/cpp/interop/interop_server_bootstrap.cc: $(OPENSSL_DEP) test/cpp/interop/server_helper.cc: $(OPENSSL_DEP) test/cpp/qps/client_async.cc: $(OPENSSL_DEP) test/cpp/qps/client_sync.cc: $(OPENSSL_DEP) @@ -14886,8 +15741,11 @@ test/cpp/qps/usage_timer.cc: $(OPENSSL_DEP) test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP) test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP) test/cpp/util/cli_call.cc: $(OPENSSL_DEP) +test/cpp/util/cli_credentials.cc: $(OPENSSL_DEP) test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP) +test/cpp/util/grpc_tool.cc: $(OPENSSL_DEP) test/cpp/util/proto_file_parser.cc: $(OPENSSL_DEP) +test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP) test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP) test/cpp/util/subprocess.cc: $(OPENSSL_DEP) test/cpp/util/test_config.cc: $(OPENSSL_DEP) diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in index 175a47f1576..adeb3906495 100644 --- a/PYTHON-MANIFEST.in +++ b/PYTHON-MANIFEST.in @@ -7,7 +7,7 @@ graft include/grpc graft third_party/boringssl graft third_party/nanopb graft third_party/zlib -include src/python/grpcio/build.py +include src/python/grpcio/_spawn_patch.py include src/python/grpcio/commands.py include src/python/grpcio/grpc_version.py include src/python/grpcio/grpc_core_dependencies.py diff --git a/README.md b/README.md index 3283517df17..e9b0454871c 100644 --- a/README.md +++ b/README.md @@ -23,16 +23,16 @@ This repository contains source code for gRPC libraries for multiple languages w Libraries in different languages are in different states of development. We are seeking contributions for all of these libraries. -| Language | Source | Status | -|-------------------------|-------------------------------------|----------------------------------| -| Shared C [core library] | [src/core] (src/core) | Beta - the surface API is stable | -| C++ | [src/cpp] (src/cpp) | Beta - the surface API is stable | -| Ruby | [src/ruby] (src/ruby) | Beta - the surface API is stable | -| NodeJS | [src/node] (src/node) | Beta - the surface API is stable | -| Python | [src/python] (src/python) | Beta - the surface API is stable | -| PHP | [src/php] (src/php) | Beta - the surface API is stable | -| C# | [src/csharp] (src/csharp) | Beta - the surface API is stable | -| Objective-C | [src/objective-c] (src/objective-c) | Beta - the surface API is stable | +| Language | Source | Status | +|-------------------------|-------------------------------------|---------| +| Shared C [core library] | [src/core] (src/core) | 1.0 | +| C++ | [src/cpp] (src/cpp) | 1.0 | +| Ruby | [src/ruby] (src/ruby) | 1.0 | +| NodeJS | [src/node] (src/node) | 1.0 | +| Python | [src/python] (src/python) | 1.0 | +| PHP | [src/php] (src/php) | 1.0 | +| C# | [src/csharp] (src/csharp) | 1.0 | +| Objective-C | [src/objective-c] (src/objective-c) | 1.0 | Java source code is in the [grpc-java] (http://github.com/grpc/grpc-java) repository. diff --git a/Rakefile b/Rakefile index f44946fe937..5b6f101d8ff 100755 --- a/Rakefile +++ b/Rakefile @@ -83,7 +83,7 @@ task 'dlls' do env += 'EMBED_ZLIB=true ' env += 'BUILDDIR=/tmp ' env += "V=#{verbose} " - out = '/tmp/libs/opt/grpc-0.dll' + out = '/tmp/libs/opt/grpc-1.dll' w64 = { cross: 'x86_64-w64-mingw32', out: 'grpc_c.64.ruby' } w32 = { cross: 'i686-w64-mingw32', out: 'grpc_c.32.ruby' } diff --git a/binding.gyp b/binding.gyp index e1130ad01ab..7cc8a58c01c 100644 --- a/binding.gyp +++ b/binding.gyp @@ -516,6 +516,7 @@ 'src/core/lib/support/log_posix.c', 'src/core/lib/support/log_windows.c', 'src/core/lib/support/murmur_hash.c', + 'src/core/lib/support/percent_encoding.c', 'src/core/lib/support/slice.c', 'src/core/lib/support/slice_buffer.c', 'src/core/lib/support/stack_lockfree.c', @@ -568,6 +569,7 @@ 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -648,6 +650,7 @@ 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -670,7 +673,6 @@ 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', @@ -706,7 +708,6 @@ 'src/core/ext/client_config/channel_connectivity.c', 'src/core/ext/client_config/client_channel.c', 'src/core/ext/client_config/client_channel_factory.c', - 'src/core/ext/client_config/client_config.c', 'src/core/ext/client_config/client_config_plugin.c', 'src/core/ext/client_config/connector.c', 'src/core/ext/client_config/default_initial_connect_string.c', @@ -718,14 +719,15 @@ 'src/core/ext/client_config/resolver.c', 'src/core/ext/client_config/resolver_factory.c', 'src/core/ext/client_config/resolver_registry.c', + 'src/core/ext/client_config/resolver_result.c', 'src/core/ext/client_config/subchannel.c', - 'src/core/ext/client_config/subchannel_call_holder.c', 'src/core/ext/client_config/subchannel_index.c', 'src/core/ext/client_config/uri_parser.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c', + 'src/core/ext/lb_policy/grpclb/grpclb.c', 'src/core/ext/lb_policy/grpclb/load_balancer_api.c', 'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'third_party/nanopb/pb_common.c', @@ -737,8 +739,10 @@ 'src/core/ext/resolver/sockaddr/sockaddr_resolver.c', 'src/core/ext/load_reporting/load_reporting.c', 'src/core/ext/load_reporting/load_reporting_filter.c', + 'src/core/ext/census/base_resources.c', 'src/core/ext/census/context.c', 'src/core/ext/census/gen/census.pb.c', + 'src/core/ext/census/gen/trace_context.pb.c', 'src/core/ext/census/grpc_context.c', 'src/core/ext/census/grpc_filter.c', 'src/core/ext/census/grpc_plugin.c', @@ -746,6 +750,7 @@ 'src/core/ext/census/mlog.c', 'src/core/ext/census/operation.c', 'src/core/ext/census/placeholders.c', + 'src/core/ext/census/resource.c', 'src/core/ext/census/tracing.c', 'src/core/plugin_registry/grpc_plugin_registry.c', ], diff --git a/build.yaml b/build.yaml index 57545839d43..1f44e794d5e 100644 --- a/build.yaml +++ b/build.yaml @@ -2,11 +2,17 @@ '#2': It is used among other things to generate all of our project files. '#3': Please refer to the templates directory for more information. settings: - '#1': The public version number of the library. - '#2': Master always has a "-dev" suffix - '#3': Use "-preN" suffixes to identify pre-release versions - '#4': Per-language overrides are possible with (eg) ruby_version tag here - '#5': See the expand_version.py for all the quirks here + '#01': The public version number of the library. + '#02': === + '#03': Please update the 'g_stands_for' field periodically with a new g word + '#04': not listed in doc/g_stands_for.md - and update that document to list the + '#05': new word. + '#06': === + '#07': Master always has a "-dev" suffix + '#08': Use "-preN" suffixes to identify pre-release versions + '#09': Per-language overrides are possible with (eg) ruby_version tag here + '#10': See the expand_version.py for all the quirks here + g_stands_for: good version: 1.1.0-dev filegroups: - name: census @@ -14,15 +20,20 @@ filegroups: - include/grpc/census.h headers: - src/core/ext/census/aggregation.h + - src/core/ext/census/base_resources.h - src/core/ext/census/census_interface.h - src/core/ext/census/census_rpc_stats.h - src/core/ext/census/gen/census.pb.h + - src/core/ext/census/gen/trace_context.pb.h - src/core/ext/census/grpc_filter.h - src/core/ext/census/mlog.h + - src/core/ext/census/resource.h - src/core/ext/census/rpc_metric_id.h src: + - src/core/ext/census/base_resources.c - src/core/ext/census/context.c - src/core/ext/census/gen/census.pb.c + - src/core/ext/census/gen/trace_context.pb.c - src/core/ext/census/grpc_context.c - src/core/ext/census/grpc_filter.c - src/core/ext/census/grpc_plugin.c @@ -30,6 +41,7 @@ filegroups: - src/core/ext/census/mlog.c - src/core/ext/census/operation.c - src/core/ext/census/placeholders.c + - src/core/ext/census/resource.c - src/core/ext/census/tracing.c plugin: census_grpc_plugin uses: @@ -71,6 +83,7 @@ filegroups: - src/core/lib/support/block_annotate.h - src/core/lib/support/env.h - src/core/lib/support/murmur_hash.h + - src/core/lib/support/percent_encoding.h - src/core/lib/support/stack_lockfree.h - src/core/lib/support/string.h - src/core/lib/support/string_windows.h @@ -99,6 +112,7 @@ filegroups: - src/core/lib/support/log_posix.c - src/core/lib/support/log_windows.c - src/core/lib/support/murmur_hash.c + - src/core/lib/support/percent_encoding.c - src/core/lib/support/slice.c - src/core/lib/support/slice_buffer.c - src/core/lib/support/stack_lockfree.c @@ -148,6 +162,7 @@ filegroups: - include/grpc/compression.h - include/grpc/grpc.h - include/grpc/grpc_posix.h + - include/grpc/grpc_security_constants.h - include/grpc/status.h headers: - src/core/lib/channel/channel_args.h @@ -156,6 +171,7 @@ filegroups: - src/core/lib/channel/compress_filter.h - src/core/lib/channel/connected_channel.h - src/core/lib/channel/context.h + - src/core/lib/channel/handshaker.h - src/core/lib/channel/http_client_filter.h - src/core/lib/channel/http_server_filter.h - src/core/lib/compression/algorithm_metadata.h @@ -226,6 +242,7 @@ filegroups: - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h - src/core/lib/transport/static_metadata.h + - src/core/lib/transport/timeout_encoding.h - src/core/lib/transport/transport.h - src/core/lib/transport/transport_impl.h src: @@ -234,6 +251,7 @@ filegroups: - src/core/lib/channel/channel_stack_builder.c - src/core/lib/channel/compress_filter.c - src/core/lib/channel/connected_channel.c + - src/core/lib/channel/handshaker.c - src/core/lib/channel/http_client_filter.c - src/core/lib/channel/http_server_filter.c - src/core/lib/compression/compression.c @@ -314,6 +332,7 @@ filegroups: - src/core/lib/transport/metadata.c - src/core/lib/transport/metadata_batch.c - src/core/lib/transport/static_metadata.c + - src/core/lib/transport/timeout_encoding.c - src/core/lib/transport/transport.c - src/core/lib/transport/transport_op_string.c deps: @@ -324,7 +343,6 @@ filegroups: headers: - src/core/ext/client_config/client_channel.h - src/core/ext/client_config/client_channel_factory.h - - src/core/ext/client_config/client_config.h - src/core/ext/client_config/connector.h - src/core/ext/client_config/initial_connect_string.h - src/core/ext/client_config/lb_policy.h @@ -334,15 +352,14 @@ filegroups: - src/core/ext/client_config/resolver.h - src/core/ext/client_config/resolver_factory.h - src/core/ext/client_config/resolver_registry.h + - src/core/ext/client_config/resolver_result.h - src/core/ext/client_config/subchannel.h - - src/core/ext/client_config/subchannel_call_holder.h - src/core/ext/client_config/subchannel_index.h - src/core/ext/client_config/uri_parser.h src: - src/core/ext/client_config/channel_connectivity.c - src/core/ext/client_config/client_channel.c - src/core/ext/client_config/client_channel_factory.c - - src/core/ext/client_config/client_config.c - src/core/ext/client_config/client_config_plugin.c - src/core/ext/client_config/connector.c - src/core/ext/client_config/default_initial_connect_string.c @@ -354,8 +371,8 @@ filegroups: - src/core/ext/client_config/resolver.c - src/core/ext/client_config/resolver_factory.c - src/core/ext/client_config/resolver_registry.c + - src/core/ext/client_config/resolver_result.c - src/core/ext/client_config/subchannel.c - - src/core/ext/client_config/subchannel_call_holder.c - src/core/ext/client_config/subchannel_index.c - src/core/ext/client_config/uri_parser.c plugin: grpc_client_config @@ -374,11 +391,14 @@ filegroups: - gpr_codegen - name: grpc_lb_policy_grpclb headers: + - src/core/ext/lb_policy/grpclb/grpclb.h - src/core/ext/lb_policy/grpclb/load_balancer_api.h - src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h src: + - src/core/ext/lb_policy/grpclb/grpclb.c - src/core/ext/lb_policy/grpclb/load_balancer_api.c - src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c + plugin: grpc_lb_policy_grpclb uses: - grpc_base - grpc_client_config @@ -424,7 +444,6 @@ filegroups: - name: grpc_secure public_headers: - include/grpc/grpc_security.h - - include/grpc/grpc_security_constants.h headers: - src/core/lib/security/context/security_context.h - src/core/lib/security/credentials/composite/composite_credentials.h @@ -527,7 +546,6 @@ filegroups: - src/core/ext/transport/chttp2/transport/internal.h - src/core/ext/transport/chttp2/transport/status_conversion.h - src/core/ext/transport/chttp2/transport/stream_map.h - - src/core/ext/transport/chttp2/transport/timeout_encoding.h - src/core/ext/transport/chttp2/transport/varint.h src: - src/core/ext/transport/chttp2/transport/bin_decoder.c @@ -549,7 +567,6 @@ filegroups: - src/core/ext/transport/chttp2/transport/status_conversion.c - src/core/ext/transport/chttp2/transport/stream_lists.c - src/core/ext/transport/chttp2/transport/stream_map.c - - src/core/ext/transport/chttp2/transport/timeout_encoding.c - src/core/ext/transport/chttp2/transport/varint.c - src/core/ext/transport/chttp2/transport/writing.c plugin: grpc_chttp2_plugin @@ -683,6 +700,7 @@ filegroups: - include/grpc++/support/time.h headers: - src/cpp/client/create_channel_internal.h + - src/cpp/common/channel_filter.h - src/cpp/server/dynamic_thread_pool.h - src/cpp/server/thread_pool_interface.h src: @@ -695,6 +713,7 @@ filegroups: - src/cpp/client/generic_stub.cc - src/cpp/client/insecure_credentials.cc - src/cpp/common/channel_arguments.cc + - src/cpp/common/channel_filter.cc - src/cpp/common/completion_queue.cc - src/cpp/common/core_codegen.cc - src/cpp/common/rpc_method.cc @@ -712,9 +731,8 @@ filegroups: - src/cpp/util/status.cc - src/cpp/util/string_ref.cc - src/cpp/util/time.cc - deps: - - grpc uses: + - grpc_base - grpc++_codegen_base - name: grpc++_codegen_base language: c++ @@ -768,6 +786,23 @@ filegroups: language: c++ public_headers: - include/grpc++/impl/codegen/config_protobuf.h +- name: grpc++_reflection_proto + language: c++ + public_headers: + - include/grpc++/ext/reflection.grpc.pb.h + - include/grpc++/ext/reflection.pb.h + src: + - src/cpp/ext/reflection.grpc.pb.cc + - src/cpp/ext/reflection.pb.cc + uses: + - grpc++_codegen_proto +- name: thrift_util + language: c++ + public_headers: + - include/grpc++/impl/codegen/thrift_serializer.h + - include/grpc++/impl/codegen/thrift_utils.h + uses: + - grpc++_codegen_base libs: - name: gpr build: all @@ -870,6 +905,7 @@ libs: - grpc filegroups: - grpc_test_util_base + - grpc_base vs_project_guid: '{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}' - name: grpc_test_util_unsecure build: private @@ -960,19 +996,20 @@ libs: language: c++ public_headers: - include/grpc++/ext/proto_server_reflection_plugin.h - - include/grpc++/ext/reflection.grpc.pb.h - - include/grpc++/ext/reflection.pb.h headers: - src/cpp/ext/proto_server_reflection.h src: - src/cpp/ext/proto_server_reflection.cc - src/cpp/ext/proto_server_reflection_plugin.cc - - src/cpp/ext/reflection.grpc.pb.cc - - src/cpp/ext/reflection.pb.cc deps: - grpc++ filegroups: - - grpc++_codegen_proto + - grpc++_reflection_proto +- name: grpc++_reflection_codegen + build: private + language: c++ + src: + - src/proto/grpc/reflection/v1alpha/reflection.proto - name: grpc++_test_config build: private language: c++ @@ -1008,6 +1045,7 @@ libs: - grpc++_codegen_base_src - grpc++_codegen_proto - grpc++_config_proto + - thrift_util - name: grpc++_unsecure build: all language: c++ @@ -1029,13 +1067,21 @@ libs: language: c++ headers: - test/cpp/util/cli_call.h + - test/cpp/util/cli_credentials.h + - test/cpp/util/config_grpc_cli.h + - test/cpp/util/grpc_tool.h - test/cpp/util/proto_file_parser.h + - test/cpp/util/proto_reflection_descriptor_database.h src: - test/cpp/util/cli_call.cc + - test/cpp/util/cli_credentials.cc + - test/cpp/util/grpc_tool.cc - test/cpp/util/proto_file_parser.cc + - test/cpp/util/proto_reflection_descriptor_database.cc deps: + - grpc++_reflection - grpc++ - - grpc_plugin_support + - grpc++_test_config - name: grpc_plugin_support build: protoc language: c++ @@ -1114,7 +1160,7 @@ libs: - grpc++ - grpc - gpr -- name: interop_server_main +- name: interop_server_lib build: private language: c++ src: @@ -1131,6 +1177,13 @@ libs: - gpr_test_util - gpr - grpc++_test_config +- name: interop_server_main + build: private + language: c++ + src: + - test/cpp/interop/interop_server_bootstrap.cc + deps: + - interop_server_lib - name: qps build: private language: c++ @@ -1279,6 +1332,16 @@ targets: - grpc - gpr_test_util - gpr +- name: census_resource_test + build: test + language: c + src: + - test/core/census/resource_test.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr - name: channel_create_test build: test language: c @@ -1515,6 +1578,12 @@ targets: src: - tools/codegen/core/gen_legal_metadata_characters.c deps: [] +- name: gen_percent_encoding_tables + build: tool + language: c + src: + - tools/codegen/core/gen_percent_encoding_tables.c + deps: [] - name: goaway_server_test cpu_cost: 0.1 build: test @@ -1594,6 +1663,14 @@ targets: deps: - gpr_test_util - gpr +- name: gpr_percent_encoding_test + build: test + language: c + src: + - test/core/support/percent_encoding_test.c + deps: + - gpr_test_util + - gpr - name: gpr_slice_buffer_test build: test language: c @@ -2155,6 +2232,32 @@ targets: - grpc - gpr_test_util - gpr +- name: percent_decode_fuzzer + build: fuzzer + language: c + src: + - test/core/support/percent_decode_fuzzer.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + corpus_dirs: + - test/core/support/percent_decode_corpus + maxlen: 32 +- name: percent_encode_fuzzer + build: fuzzer + language: c + src: + - test/core/support/percent_encode_fuzzer.c + deps: + - grpc_test_util + - grpc + - gpr_test_util + - gpr + corpus_dirs: + - test/core/support/percent_encode_corpus + maxlen: 32 - name: resolve_address_test build: test language: c @@ -2333,7 +2436,7 @@ targets: build: test language: c src: - - test/core/transport/chttp2/timeout_encoding_test.c + - test/core/transport/timeout_encoding_test.c deps: - grpc_test_util - grpc @@ -2623,6 +2726,19 @@ targets: - grpc - gpr_test_util - gpr +- name: filter_end2end_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/filter_end2end_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr - name: generic_end2end_test gtest: true build: test @@ -2655,11 +2771,9 @@ targets: - test/cpp/util/grpc_cli.cc deps: - grpc_cli_libs - - grpc++_test_util - - grpc_test_util + - grpc++_reflection - grpc++ - grpc - - gpr_test_util - gpr - grpc++_test_config - name: grpc_cpp_plugin @@ -2721,6 +2835,28 @@ targets: secure: false vs_config_type: Application vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}' +- name: grpc_tool_test + gtest: true + build: test + language: c++ + headers: + - test/cpp/util/string_ref_helper.h + src: + - src/proto/grpc/testing/echo.proto + - src/proto/grpc/testing/echo_messages.proto + - test/cpp/util/grpc_tool_test.cc + - test/cpp/util/string_ref_helper.cc + deps: + - grpc_cli_libs + - grpc++_reflection + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr + filegroups: + - grpc++_codegen_proto + - grpc++_config_proto - name: grpclb_api_test gtest: true build: test @@ -2733,6 +2869,20 @@ targets: - grpc_test_util - grpc++ - grpc +- name: grpclb_test + gtest: false + build: test + language: c++ + src: + - src/proto/grpc/lb/v1/load_balancer.proto + - test/cpp/grpclb/grpclb_test.cc + deps: + - gpr + - gpr_test_util + - grpc + - grpc++ + - grpc++_test_util + - grpc_test_util - name: hybrid_end2end_test gtest: true build: test @@ -2773,6 +2923,7 @@ targets: deps: - interop_server_main - interop_server_helper + - interop_server_lib - grpc++_test_util - grpc_test_util - grpc++ @@ -3353,6 +3504,7 @@ php_config_m4: - src/php/ext/grpc/channel.h - src/php/ext/grpc/channel_credentials.h - src/php/ext/grpc/completion_queue.h + - src/php/ext/grpc/php7_wrapper.h - src/php/ext/grpc/php_grpc.h - src/php/ext/grpc/server.h - src/php/ext/grpc/server_credentials.h diff --git a/composer.json b/composer.json index 0ebe0a11084..78366208edb 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "v0.6" }, "require-dev": { "google/auth": "v0.9" diff --git a/config.m4 b/config.m4 index 0c3322d8efe..5384585dd6c 100644 --- a/config.m4 +++ b/config.m4 @@ -57,6 +57,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/support/log_posix.c \ src/core/lib/support/log_windows.c \ src/core/lib/support/murmur_hash.c \ + src/core/lib/support/percent_encoding.c \ src/core/lib/support/slice.c \ src/core/lib/support/slice_buffer.c \ src/core/lib/support/stack_lockfree.c \ @@ -87,6 +88,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/channel/channel_stack_builder.c \ src/core/lib/channel/compress_filter.c \ src/core/lib/channel/connected_channel.c \ + src/core/lib/channel/handshaker.c \ src/core/lib/channel/http_client_filter.c \ src/core/lib/channel/http_server_filter.c \ src/core/lib/compression/compression.c \ @@ -167,6 +169,7 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ src/core/lib/transport/static_metadata.c \ + src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ src/core/lib/transport/transport_op_string.c \ src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c \ @@ -189,7 +192,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/transport/chttp2/transport/status_conversion.c \ src/core/ext/transport/chttp2/transport/stream_lists.c \ src/core/ext/transport/chttp2/transport/stream_map.c \ - src/core/ext/transport/chttp2/transport/timeout_encoding.c \ src/core/ext/transport/chttp2/transport/varint.c \ src/core/ext/transport/chttp2/transport/writing.c \ src/core/ext/transport/chttp2/alpn/alpn.c \ @@ -225,7 +227,6 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/client_config/channel_connectivity.c \ src/core/ext/client_config/client_channel.c \ src/core/ext/client_config/client_channel_factory.c \ - src/core/ext/client_config/client_config.c \ src/core/ext/client_config/client_config_plugin.c \ src/core/ext/client_config/connector.c \ src/core/ext/client_config/default_initial_connect_string.c \ @@ -237,14 +238,15 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/client_config/resolver.c \ src/core/ext/client_config/resolver_factory.c \ src/core/ext/client_config/resolver_registry.c \ + src/core/ext/client_config/resolver_result.c \ src/core/ext/client_config/subchannel.c \ - src/core/ext/client_config/subchannel_call_holder.c \ src/core/ext/client_config/subchannel_index.c \ src/core/ext/client_config/uri_parser.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \ src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \ src/core/ext/transport/chttp2/client/insecure/channel_create.c \ src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \ + src/core/ext/lb_policy/grpclb/grpclb.c \ src/core/ext/lb_policy/grpclb/load_balancer_api.c \ src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \ third_party/nanopb/pb_common.c \ @@ -256,8 +258,10 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/resolver/sockaddr/sockaddr_resolver.c \ src/core/ext/load_reporting/load_reporting.c \ src/core/ext/load_reporting/load_reporting_filter.c \ + src/core/ext/census/base_resources.c \ src/core/ext/census/context.c \ src/core/ext/census/gen/census.pb.c \ + src/core/ext/census/gen/trace_context.pb.c \ src/core/ext/census/grpc_context.c \ src/core/ext/census/grpc_filter.c \ src/core/ext/census/grpc_plugin.c \ @@ -265,6 +269,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/census/mlog.c \ src/core/ext/census/operation.c \ src/core/ext/census/placeholders.c \ + src/core/ext/census/resource.c \ src/core/ext/census/tracing.c \ src/core/plugin_registry/grpc_plugin_registry.c \ src/boringssl/err_data.c \ diff --git a/doc/.gitignore b/doc/.gitignore new file mode 100644 index 00000000000..95464d3e664 --- /dev/null +++ b/doc/.gitignore @@ -0,0 +1,2 @@ +build/ +src/ diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md index 31d694b803d..df7585d6099 100644 --- a/doc/PROTOCOL-HTTP2.md +++ b/doc/PROTOCOL-HTTP2.md @@ -98,8 +98,11 @@ For requests, **EOS** (end-of-stream) is indicated by the presence of the END_ST * **Trailers-Only** → HTTP-Status Content-Type Trailers * **Trailers** → Status [Status-Message] \*Custom-Metadata * **HTTP-Status** → ":status 200" -* **Status** → "grpc-status" -* **Status-Message** → "grpc-message" +* **Status** → "grpc-status" 1\*DIGIT ; 0-9 +* **Status-Message** → "grpc-message" Percent-Encoded +* **Percent-Encoded** → 1\*(Percent-Byte-Unencoded / Percent-Byte-Encoded) +* **Percent-Byte-Unencoded** → 1\*( %x20-%x24 / %x26-%x7E ) ; space and VCHAR, except % +* **Percent-Byte-Encoded** → "%" 2HEXDIGIT ; 0-9 A-F **Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK. @@ -110,6 +113,21 @@ Implementations should expect broken deployments to send non-200 HTTP status cod Clients may limit the size of **Response-Headers**, **Trailers**, and **Trailers-Only**, with a default of 8 KiB each suggested. +The value portion of **Status** is a decimal-encoded integer as an ASCII string, +without any leading zeros. + +The value portion of **Status-Message** is conceptually a Unicode string +description of the error, physically encoded as UTF-8 followed by +percent-encoding. Percent-encoding is specified in [RFC 3986 +§2.1](https://tools.ietf.org/html/rfc3986#section-2.1), although the form used +here has different restricted characters. When decoding invalid values, +implementations MUST NOT error or throw away the message. At worst, the +implementation can abort decoding the status message altogether such that the +user would received the raw percent-encoded form. Alternatively, the +implementation can decode valid portions while leaving broken %-encodings as-is +or replacing them with a replacement character (e.g., '?' or the Unicode +replacement character). + ####Example Sample unary-call showing HTTP2 framing sequence diff --git a/doc/c-style-guide.md b/doc/c-style-guide.md index d6f9bbd7d4a..369bd56a463 100644 --- a/doc/c-style-guide.md +++ b/doc/c-style-guide.md @@ -9,16 +9,17 @@ Here we document style rules for C usage in the gRPC Core library. General ------- -- Layout rules are defined by clang-format, and all code should be passed through - clang-format. A (docker-based) script to do so is included in - [tools/distrib/clang\_format\_code.sh] (../tools/distrib/clang_format_code.sh). +- Layout rules are defined by clang-format, and all code should be passed + through clang-format. A (docker-based) script to do so is included in + [tools/distrib/clang\_format\_code.sh](../tools/distrib/clang_format_code.sh). Header Files ------------ -- Public header files (those in the include/grpc tree) should compile as pedantic C89 -- Public header files should be includable from C++ programs. That is, they should - include the following: +- Public header files (those in the include/grpc tree) should compile as + pedantic C89. +- Public header files should be includable from C++ programs. That is, they + should include the following: ```c #ifdef __cplusplus extern "C" { @@ -34,24 +35,34 @@ Header Files - All header files should have a #define guard to prevent multiple inclusion. To guarantee uniqueness they should be based on the file's path. - For public headers: include/grpc/grpc.h --> GRPC_GRPC_H + For public headers: `include/grpc/grpc.h` → `GRPC_GRPC_H` + + For private headers: + `src/core/channel/channel_stack.h` → + `GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H` + +Variable Initialization +----------------------- + +When declaring a (non-static) pointer variable, always initialize it to `NULL`. +Even in the case of static pointer variables, it's recommended to explicitly +initialize them to `NULL`. - For private headers: - src/core/channel/channel_stack.h --> GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H C99 Features ------------ -- Variable sized arrays are not allowed -- Do not use the 'inline' keyword -- Flexible array members are allowed (https://en.wikipedia.org/wiki/Flexible_array_member) +- Variable sized arrays are not allowed. +- Do not use the 'inline' keyword. +- Flexible array members are allowed + (https://en.wikipedia.org/wiki/Flexible_array_member). Comments -------- Within public header files, only `/* */` comments are allowed. -Within implementation files and private headers, either single line `//` +Within implementation files and private headers, either single line `//` or multi line `/* */` comments are allowed. Only one comment style per file is allowed however (i.e. if single line comments are used anywhere within a file, ALL comments within that file must be single line comments). @@ -59,7 +70,15 @@ ALL comments within that file must be single line comments). Symbol Names ------------ -- Non-static functions must be prefixed by grpc_ -- static functions must not be prefixed by grpc_ -- enumeration values and #define names are uppercased, all others are lowercased -- Multiple word identifiers use underscore as a delimiter (NEVER camel casing) +- Non-static functions must be prefixed by `grpc_` +- Static functions must *not* be prefixed by `grpc_` +- Enumeration values and `#define` names must be uppercase. All other values + must be lowercase. +- Multiple word identifiers use underscore as a delimiter, *never* camel + case. E.g. `variable_name`. + +Functions +---------- + +- The use of [`atexit()`](http://man7.org/linux/man-pages/man3/atexit.3.html) is + in forbidden in libgrpc. diff --git a/doc/command_line_tool.md b/doc/command_line_tool.md index 89a70548b8b..79a131c041a 100644 --- a/doc/command_line_tool.md +++ b/doc/command_line_tool.md @@ -15,6 +15,7 @@ The command line tool can do the following things: - Send unary rpc. - Attach metadata and display received metadata. - Handle common authentication to server. +- Infer request/response types from server reflection result. - Find the request/response types from a given proto file. - Read proto request in text form. - Read request in wire form (for protobuf messages, this means serialized binary form). @@ -24,7 +25,6 @@ The command line tool can do the following things: The command line tool should support the following things: - List server services and methods through server reflection. -- Infer request/response types from server reflection result. - Fine-grained auth control (such as, use this oauth token to talk to the server). - Send streaming rpc. @@ -46,24 +46,35 @@ https://github.com/grpc/grpc/blob/master/test/cpp/util/grpc_cli.cc Send a rpc to a helloworld server at `localhost:50051`: ``` -$ bins/opt/grpc_cli call localhost:50051 SayHello examples/protos/helloworld.proto \ - "name: 'world'" --enable_ssl=false +$ bins/opt/grpc_cli call localhost:50051 SayHello "name: 'world'" \ + --enable_ssl=false ``` On success, the tool will print out ``` Rpc succeeded with OK status -Response: +Response: message: "Hello world" ``` The `localhost:50051` part indicates the server you are connecting to. `SayHello` is (part of) the -gRPC method string. Then there is the path to the proto file containing the service definition, -if it is not under current directory, you can use `--proto_path` to specify a new search root. -`"name: 'world'"` is the text format of the request proto message. -We are not using ssl here by `--enable_ssl=false`. For information on more -flags, look at the comments of `grpc_cli.cc`. +gRPC method string. Then `"name: 'world'"` is the text format of the request proto message. We are +not using ssl here by `--enable_ssl=false`. For information on more flags, look at the comments of `grpc_cli.cc`. + +### Use local proto files + +If the server does not have the server reflection service, you will need to provide local proto +files containing the service definition. The tool will try to find request/response types from +them. + +``` +$ bins/opt/grpc_cli call localhost:50051 SayHello "name: 'world'" \ + --protofiles=examples/protos/helloworld.proto --enable_ssl=false +``` + +If the proto files is not under current directory, you can use `--proto_path` to specify a new +search root. ### Send non-proto rpc diff --git a/doc/fail_fast.md b/doc/fail_fast.md index 3ed4297194b..2dd5561fc67 100644 --- a/doc/fail_fast.md +++ b/doc/fail_fast.md @@ -1,15 +1 @@ -gRPC Fail Fast Semantics -======================== - -Fail fast requests allow terminating requests (with status UNAVAILABLE) prior -to the deadline of the request being met. - -gRPC implementations of fail fast can terminate requests whenever a channel is -in the TRANSIENT_FAILURE or SHUTDOWN states. If the channel is in any other -state (CONNECTING, READY, or IDLE) the request should not be terminated. - -Fail fast SHOULD be the default for gRPC implementations, with an option to -switch to non fail fast. - -The opposite of fail fast is 'ignore connectivity'. - +Moved to wait-for-ready.md diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md new file mode 100644 index 00000000000..52f8eae05aa --- /dev/null +++ b/doc/g_stands_for.md @@ -0,0 +1,8 @@ +Each version of gRPC gets a new description of what the 'g' stands for, since +we've never really been able to figure it out. + +Below is a list of already-used definitions (that should not be repeated in the +future), and the corresponding version numbers that used them: + +- 1.0 'g' stands for 'gRPC' +- 1.1 'g' stands for 'good' diff --git a/doc/health-checking.md b/doc/health-checking.md index 92512e942bd..7be8107b60f 100644 --- a/doc/health-checking.md +++ b/doc/health-checking.md @@ -58,7 +58,7 @@ a response must be sent back with an `OK` status and the status field should be set to `SERVING` or `NOT_SERVING` accordingly. If the service name is not registered, the server returns a `NOT_FOUND` GRPC status. -The server should use an empty string as the key for server’s +The server should use an empty string as the key for server's overall health status, so that a client not interested in a specific service can query the server's status with an empty request. The server can just do exact matching of the service name without support of any kind of wildcard matching. diff --git a/doc/images/load_balancing_design.png b/doc/images/load_balancing_design.png new file mode 100644 index 00000000000..86183966fb8 Binary files /dev/null and b/doc/images/load_balancing_design.png differ diff --git a/doc/load-balancing.md b/doc/load-balancing.md index 681be02a72f..dfaa7a7f33b 100644 --- a/doc/load-balancing.md +++ b/doc/load-balancing.md @@ -4,7 +4,7 @@ Load Balancing in gRPC # Objective To design a load balancing API between a gRPC client and a Load Balancer to -instruct the client how to send load to multiple backend servers. +instruct the client how to send load to multiple backend servers. # Background @@ -19,7 +19,7 @@ have temporary copies of the RPC request and response. This model also increases latency to the RPCs. The proxy model was deemed inefficient when considering request heavy services -like storage. +like storage. ### Balancing-aware Client @@ -28,7 +28,7 @@ example, the client could contain many load balancing policies (Round Robin, Random, etc) used to select servers from a list. In this model, a list of servers would be either statically configured in the client, provided by the name resolution system, an external load balancer, etc. In any case, the client -is responsible for choosing the preferred server from the list. +is responsible for choosing the preferred server from the list. One of the drawbacks of this approach is writing and maintaining the load balancing policies in multiple languages and/or versions of the clients. These @@ -53,14 +53,69 @@ unavailability or health issues. The load balancer will make any necessary complex decisions and inform the client. The load balancer may communicate with the backend servers to collect load and health information. + +## Requirements + +#### Simple API and client + +The gRPC client load balancing code must be simple and portable. The client +should only contain simple algorithms (ie Round Robin) for server selection. For +complex algorithms, the client should rely on a load balancer to provide load +balancing configuration and the list of servers to which the client should send +requests. The balancer will update the server list as needed to balance the load +as well as handle server unavailability or health issues. The load balancer will +make any necessary complex decisions and inform the client. The load balancer +may communicate with the backend servers to collect load and health information. + +#### Security + +The load balancer may be separate from the actual server backends and a +compromise of the load balancer should only lead to a compromise of the +loadbalancing functionality. In other words, a compromised load balancer should +not be able to cause a client to trust a (potentially malicious) backend server +any more than in a comparable situation without loadbalancing. + # Proposed Architecture -The gRPC load balancing approach follows the third approach, by having an -external load balancer which provides simple clients with a list of servers. +The gRPC load balancing implements the external load balancing server approach: +an external load balancer provides simple clients with an up-to-date list of +servers. + +![image](images/load_balancing_design.png) + +1. On startup, the gRPC client issues a name resolution request for the service. + The name will resolve to one or more IP addresses to gRPC servers, a hint on + whether the IP address(es) point to a load balancer or not, and also return a + client config. +2. The gRPC client connects to a gRPC Server. + 1. If the name resolution has hinted that the endpoint is a load balancer, + the client's gRPC LB policy will attempt to open a stream to the load + balancer service. The server may respond in only one of the following + ways. + 1. `status::UNIMPLEMENTED`. There is no loadbalancing in use. The client + call will fail. + 2. "I am a Load Balancer and here is the server list." (Goto Step 4.) + 3. "Please contact Load Balancer X" (See Step 3.) The client will close + this connection and cancel the stream. + 4. If the server fails to respond, the client will wait for some timeout + and then re-resolve the name (process to Step 1 above). + 2. If the name resolution has not hinted that the endpoint is a load + balancer, the client connects directly to the service it wants to talk to. +3. The gRPC client's gRPC LB policy opens a separate connection to the Load + Balancer. If this fails, it will go back to step 1 and try another address. + 1. During channel initialization to the Load Balancer, the client will + attempt to open a stream to the Load Balancer service. + 2. The Load Balancer will return a server list to the gRPC client. If the + server list is empty, the call will wait until a non-empty one is + received. Optional: The Load Balancer will also open channels to the gRPC + servers if load reporting is needed. +4. The gRPC client will send RPCs to the gRPC servers contained in the server + list from the Load Balancer. +5. Optional: The gRPC servers may periodically report load to the Load Balancer. ## Client -When establishing a gRPC stream to the balancer, the client will send an initial +When establishing a gRPC _stream_ to the balancer, the client will send an initial request to the load balancer (via a regular gRPC message). The load balancer will respond with client config (including, for example, settings for flow control, RPC deadlines, etc.) or a redirect to another load balancer. If the @@ -87,11 +142,3 @@ balancer in order to compute the next list of servers. The gRPC Server is responsible for answering RPC requests and providing responses to the client. The server will also report load to the load balancer if a reporting stream was opened for this purpose. - -### Security - -The load balancer may be separate from the actual server backends and a -compromise of the load balancer should only lead to a compromise of the -loadbalancing functionality. In other words, a compromised load balancer should -not be able to cause a client to trust a (potentially malicious) backend server -any more than in a comparable situation without loadbalancing. diff --git a/doc/statuscodes.md b/doc/statuscodes.md index c918f9ed9ab..1cd72df30ad 100644 --- a/doc/statuscodes.md +++ b/doc/statuscodes.md @@ -18,6 +18,7 @@ Only a subset of the pre-defined status codes are generated by the gRPC librarie | Could not decompress, but compression algorithm supported (Server -> Client) | INTERNAL | Client | | Compression mechanism used by client not supported at server | UNIMPLEMENTED | Server | | Server temporarily out of resources (e.g., Flow-control resource limits reached) | RESOURCE_EXHAUSTED | Server| +| Client does not have enough memory to hold the server response | RESOURCE_EXHAUSTED | Client | | Flow-control protocol violation | INTERNAL | Both | | Error parsing returned status | UNKNOWN | Client | | Incorrect Auth metadata ( Credentials failed to get metadata, Incompatible credentials set on channel and call, Invalid host set in `:authority` metadata, etc.) | UNAUTHENTICATED | Both | diff --git a/doc/wait-for-ready.md b/doc/wait-for-ready.md new file mode 100644 index 00000000000..fd426042693 --- /dev/null +++ b/doc/wait-for-ready.md @@ -0,0 +1,14 @@ +gRPC Wait for Ready Semantics +============================= + +If an RPC is issued but the channel is in `TRANSIENT_FAILURE` or `SHUTDOWN` +states, the RPC is unable to be transmited promptly. By default, gRPC +implementations SHOULD fail such RPCs immediately. This is known as "fail fast," +but usage of the term is historical. RPCs SHOULD NOT fail as a result of the +channel being in other states (`CONNECTING`, `READY`, or `IDLE`). + +gRPC implementations MAY provide a per-RPC option to not fail RPCs as a result +of the channel being in `TRANSIENT_FAILURE` state. Instead, the implementation +queues the RPCs until the channel is `READY`. This is known as "wait for ready." +The RPCs SHOULD still fail before `READY` if there are unrelated reasons, such +as the channel is `SHUTDOWN` or the RPC's deadline is reached. diff --git a/etc/roots.pem b/etc/roots.pem index 7b4d5f10fba..e6df88ea923 100644 --- a/etc/roots.pem +++ b/etc/roots.pem @@ -2,33 +2,6 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -# Issuer: O=Equifax OU=Equifax Secure Certificate Authority -# Subject: O=Equifax OU=Equifax Secure Certificate Authority -# Label: "Equifax Secure CA" -# Serial: 903804111 -# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4 -# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a -# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78 ------BEGIN CERTIFICATE----- -MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV -UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy -dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 -MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx -dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B -AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f -BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A -cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC -AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ -MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm -aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw -ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj -IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF -MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA -A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y -7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh -1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 ------END CERTIFICATE----- - # Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Label: "GlobalSign Root CA" @@ -120,38 +93,6 @@ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- -# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only -# Label: "Verisign Class 4 Public Primary Certification Authority - G3" -# Serial: 314531972711909413743075096039378935511 -# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df -# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d -# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06 ------BEGIN CERTIFICATE----- -MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw -CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl -cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu -LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT -aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp -dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD -VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT -aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ -bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu -IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg -LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 -GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ -+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd -U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm -NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY -ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ -ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 -CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq -g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm -fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c -2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ -bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== ------END CERTIFICATE----- - # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Premium 2048 Secure Server CA" @@ -214,30 +155,6 @@ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. -# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. -# Label: "Equifax Secure Global eBusiness CA" -# Serial: 1 -# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc -# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45 -# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07 ------BEGIN CERTIFICATE----- -MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc -MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT -ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw -MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj -dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l -c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC -UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc -58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ -o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH -MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr -aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA -A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA -Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv -8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV ------END CERTIFICATE----- - # Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network # Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network # Label: "AddTrust Low-Value Services Root" @@ -907,70 +824,6 @@ Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M -----END CERTIFICATE----- -# Issuer: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden -# Subject: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden -# Label: "Staat der Nederlanden Root CA" -# Serial: 10000010 -# MD5 Fingerprint: 60:84:7c:5a:ce:db:0c:d4:cb:a7:e9:fe:02:c6:a9:c0 -# SHA1 Fingerprint: 10:1d:fa:3f:d5:0b:cb:bb:9b:b5:60:0c:19:55:a4:1a:f4:73:3a:04 -# SHA256 Fingerprint: d4:1d:82:9e:8c:16:59:82:2a:f9:3f:ce:62:bf:fc:de:26:4f:c8:4e:8b:95:0c:5f:f2:75:d0:52:35:46:95:a3 ------BEGIN CERTIFICATE----- -MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO -TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh -dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy -MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk -ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn -ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 -9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO -hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U -tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o -BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh -SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww -OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv -cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA -7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k -/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm -eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 -u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy -7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR -iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== ------END CERTIFICATE----- - -# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com -# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com -# Label: "UTN DATACorp SGC Root CA" -# Serial: 91374294542884689855167577680241077609 -# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06 -# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4 -# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48 ------BEGIN CERTIFICATE----- -MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB -kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug -Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho -dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw -IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG -EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD -VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu -dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 -E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ -D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK -4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq -lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW -bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB -o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT -MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js -LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr -BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB -AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft -Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj -j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH -KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv -2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 -mfnGV/TJVTl4uix5yaaIK/QI ------END CERTIFICATE----- - # Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com # Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com # Label: "UTN USERFirst Hardware Root CA" @@ -1077,51 +930,6 @@ ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== -----END CERTIFICATE----- -# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok -# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok -# Label: "NetLock Notary (Class A) Root" -# Serial: 259 -# MD5 Fingerprint: 86:38:6d:5e:49:63:6c:85:5c:db:6d:dc:94:b7:d0:f7 -# SHA1 Fingerprint: ac:ed:5f:65:53:fd:25:ce:01:5f:1f:7a:48:3b:6a:74:9f:61:78:c6 -# SHA256 Fingerprint: 7f:12:cd:5f:7e:5e:29:0e:c7:d8:51:79:d5:b7:2c:20:a5:be:75:08:ff:db:5b:f8:1a:b9:68:4a:7f:c9:f6:67 ------BEGIN CERTIFICATE----- -MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV -MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe -TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 -dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB -KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 -N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC -dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu -MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL -b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD -zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi -3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 -WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY -Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi -NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC -ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 -QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 -YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz -aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu -IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm -ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg -ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs -amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv -IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 -Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 -ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 -YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg -dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs -b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G -CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO -xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP -0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ -QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk -f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK -8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI ------END CERTIFICATE----- - # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Label: "XRamp Global CA Root" @@ -1534,71 +1342,6 @@ rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= -----END CERTIFICATE----- -# Issuer: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=(c) 2005 TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. -# Subject: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=(c) 2005 TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. -# Label: "TURKTRUST Certificate Services Provider Root 1" -# Serial: 1 -# MD5 Fingerprint: f1:6a:22:18:c9:cd:df:ce:82:1d:1d:b7:78:5c:a9:a5 -# SHA1 Fingerprint: 79:98:a3:08:e1:4d:65:85:e6:c2:1e:15:3a:71:9f:ba:5a:d3:4a:d9 -# SHA256 Fingerprint: 44:04:e3:3b:5e:14:0d:cf:99:80:51:fd:fc:80:28:c7:c8:16:15:c5:ee:73:7b:11:1b:58:82:33:a9:b5:35:a0 ------BEGIN CERTIFICATE----- -MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc -UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg -MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 -dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz -MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy -dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD -VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg -xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu -xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7 -XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k -heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J -YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C -urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1 -JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51 -b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV -9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7 -kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh -fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy -B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA -aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS -RGQDJereW26fyfJOrN3H ------END CERTIFICATE----- - -# Issuer: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. (c) Kasım 2005 -# Subject: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. (c) Kasım 2005 -# Label: "TURKTRUST Certificate Services Provider Root 2" -# Serial: 1 -# MD5 Fingerprint: 37:a5:6e:d4:b1:25:84:97:b7:fd:56:15:7a:f9:a2:00 -# SHA1 Fingerprint: b4:35:d4:e1:11:9d:1c:66:90:a7:49:eb:b3:94:bd:63:7b:a7:82:b7 -# SHA256 Fingerprint: c4:70:cf:54:7e:23:02:b9:77:fb:29:dd:71:a8:9a:7b:6c:1f:60:77:7b:03:29:f5:60:17:f3:28:bf:4f:6b:e6 ------BEGIN CERTIFICATE----- -MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc -UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx -c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS -S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg -SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3 -WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv -bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU -UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw -bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe -LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef -J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh -R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ -Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX -JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p -zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S -Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ -KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq -ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 -Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz -gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH -uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS -y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI= ------END CERTIFICATE----- - # Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG # Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG # Label: "SwissSign Gold CA - G2" @@ -2137,107 +1880,6 @@ t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== -----END CERTIFICATE----- -# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA -# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA -# Label: "TC TrustCenter Class 2 CA II" -# Serial: 941389028203453866782103406992443 -# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23 -# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e -# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4 ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf -tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg -uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J -XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK -8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 -5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 -kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS -GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt -ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 -au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV -hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI -dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA -# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA -# Label: "TC TrustCenter Class 3 CA II" -# Serial: 1506523511417715638772220530020799 -# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e -# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5 -# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e ------BEGIN CERTIFICATE----- -MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV -BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 -Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 -OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i -SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc -VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW -Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q -Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 -1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq -ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 -Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud -EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX -XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy -dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 -Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz -JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 -Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u -TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN -irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 -TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 -g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB -95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj -S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== ------END CERTIFICATE----- - -# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA -# Label: "TC TrustCenter Universal CA I" -# Serial: 601024842042189035295619584734726 -# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c -# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3 -# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7 ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL -MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV -BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 -c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx -MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg -R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD -VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR -JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T -fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu -jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z -wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ -fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD -VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G -CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 -7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn -8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs -ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT -ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ -2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY ------END CERTIFICATE----- - # Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center # Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center # Label: "Deutsche Telekom Root CA 2" @@ -2268,36 +1910,6 @@ xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU Cm26OWMohpLzGITY+9HPBVZkVw== -----END CERTIFICATE----- -# Issuer: CN=ComSign Secured CA O=ComSign -# Subject: CN=ComSign Secured CA O=ComSign -# Label: "ComSign Secured CA" -# Serial: 264725503855295744117309814499492384489 -# MD5 Fingerprint: 40:01:25:06:8d:21:43:6a:0e:43:00:9c:e7:43:f3:d5 -# SHA1 Fingerprint: f9:cd:0e:2c:da:76:24:c1:8f:bd:f0:f0:ab:b6:45:b8:f7:fe:d5:7a -# SHA256 Fingerprint: 50:79:41:c7:44:60:a0:b4:70:86:22:0d:4e:99:32:57:2a:b5:d1:b5:bb:cb:89:80:ab:1c:b1:76:51:a8:44:d2 ------BEGIN CERTIFICATE----- -MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw -PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu -MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx -GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL -MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf -HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh -gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW -v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue -Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr -9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt -6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7 -MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl -Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58 -ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq -hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p -iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC -dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL -kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL -hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz -OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw== ------END CERTIFICATE----- - # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc # Label: "Cybertrust Global Root" @@ -2435,34 +2047,6 @@ h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho -----END CERTIFICATE----- -# Issuer: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327 -# Subject: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327 -# Label: "Buypass Class 3 CA 1" -# Serial: 2 -# MD5 Fingerprint: df:3c:73:59:81:e7:39:50:81:04:4c:34:a2:cb:b3:7b -# SHA1 Fingerprint: 61:57:3a:11:df:0e:d8:7e:d5:92:65:22:ea:d0:56:d7:44:b3:23:71 -# SHA256 Fingerprint: b7:b1:2b:17:1f:82:1d:aa:99:0c:d0:fe:50:87:b1:28:44:8b:a8:e5:18:4f:84:c5:1e:02:b5:c8:fb:96:2b:24 ------BEGIN CERTIFICATE----- -MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd -MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg -Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL -MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD -VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP -ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg -isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z -NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI -+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R -hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+ -mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD -AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP -Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s -EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2 -mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC -e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow -dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915 ------END CERTIFICATE----- - # Issuer: CN=EBG Elektronik Sertifika Hizmet SaÄŸlayıcısı O=EBG BiliÅŸim Teknolojileri ve Hizmetleri A.Åž. # Subject: CN=EBG Elektronik Sertifika Hizmet SaÄŸlayıcısı O=EBG BiliÅŸim Teknolojileri ve Hizmetleri A.Åž. # Label: "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1" @@ -2843,38 +2427,6 @@ Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== -----END CERTIFICATE----- -# Issuer: CN=CA Disig O=Disig a.s. -# Subject: CN=CA Disig O=Disig a.s. -# Label: "CA Disig" -# Serial: 1 -# MD5 Fingerprint: 3f:45:96:39:e2:50:87:f7:bb:fe:98:0c:3c:20:98:e6 -# SHA1 Fingerprint: 2a:c8:d5:8b:57:ce:bf:2f:49:af:f2:fc:76:8f:51:14:62:90:7a:41 -# SHA256 Fingerprint: 92:bf:51:19:ab:ec:ca:d0:b1:33:2d:c4:e1:d0:5f:ba:75:b5:67:90:44:ee:0c:a2:6e:93:1f:74:4f:2f:33:cf ------BEGIN CERTIFICATE----- -MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET -MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE -AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw -CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg -YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw -ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE -Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX -mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD -XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW -S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp -FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw -AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD -AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu -ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z -ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv -Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw -DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6 -yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq -EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/ -CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB -EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN -PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag= ------END CERTIFICATE----- - # Issuer: CN=Juur-SK O=AS Sertifitseerimiskeskus # Subject: CN=Juur-SK O=AS Sertifitseerimiskeskus # Label: "Juur-SK" @@ -3042,36 +2594,6 @@ tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW -----END CERTIFICATE----- -# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S. -# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S. -# Label: "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi" -# Serial: 91184789765598910059173000485363494069 -# MD5 Fingerprint: 3d:41:29:cb:1e:aa:11:74:cd:5d:b0:62:af:b0:43:5b -# SHA1 Fingerprint: dd:e1:d2:a9:01:80:2e:1d:87:5e:84:b3:80:7e:4b:b1:fd:99:41:34 -# SHA256 Fingerprint: e6:09:07:84:65:a4:19:78:0c:b6:ac:4c:1c:0b:fb:46:53:d9:d9:cc:6e:b3:94:6e:b7:f3:d6:99:97:ba:d5:98 ------BEGIN CERTIFICATE----- -MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1 -MQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp -Z2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp -a2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx -MzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg -R3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg -U2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD -ggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU -MZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT -L/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H -5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC -90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1 -c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/ -BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE -VtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP -qk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S -/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj -/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X -KWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq -fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX ------END CERTIFICATE----- - # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Label: "GlobalSign Root CA - R3" @@ -3610,37 +3132,6 @@ ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM= -----END CERTIFICATE----- -# Issuer: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03 -# Subject: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03 -# Label: "A-Trust-nQual-03" -# Serial: 93214 -# MD5 Fingerprint: 49:63:ae:27:f4:d5:95:3d:d8:db:24:86:b8:9c:07:53 -# SHA1 Fingerprint: d3:c0:63:f2:19:ed:07:3e:34:ad:5d:75:0b:32:76:29:ff:d5:9a:f2 -# SHA256 Fingerprint: 79:3c:bf:45:59:b9:fd:e3:8a:b2:2d:f1:68:69:f6:98:81:ae:14:c4:b0:13:9a:c7:88:a7:8a:1a:fc:ca:02:fb ------BEGIN CERTIFICATE----- -MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB -VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp -bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R -dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw -MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy -dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52 -ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM -EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj -lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ -znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH -2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1 -k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs -2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD -VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC -AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG -KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+ -8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R -FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS -mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE -DNuxUCAKGkq6ahq97BvIxYSazQ== ------END CERTIFICATE----- - # Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA # Label: "TWCA Root Certification Authority" @@ -3699,6 +3190,45 @@ t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 -----END CERTIFICATE----- +# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes +# Label: "EC-ACC" +# Serial: -23701579247955709139626555126524820479 +# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09 +# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8 +# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99 +-----BEGIN CERTIFICATE----- +MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB +8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy +dGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1 +YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3 +dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh +IEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD +LUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG +EwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g +KE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD +ZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu +bmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg +ZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R +85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm +4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV +HMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd +QlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t +lGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB +o4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4 +opvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo +dHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW +ZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN +AQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y +/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k +SBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy +Rp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS +Agu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl +nJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI= +-----END CERTIFICATE----- + # Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority # Label: "Hellenic Academic and Research Institutions RootCA 2011" @@ -5112,3 +4642,748 @@ KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg 515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO xwy8p2Fp8fc74SrL+SvzZpA3 -----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H5 O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. +# Subject: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H5 O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. +# Label: "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H5" +# Serial: 156233699172481 +# MD5 Fingerprint: da:70:8e:f0:22:df:93:26:f6:5f:9f:d3:15:06:52:4e +# SHA1 Fingerprint: c4:18:f6:4d:46:d1:df:00:3d:27:30:13:72:43:a9:12:11:c6:75:fb +# SHA256 Fingerprint: 49:35:1b:90:34:44:c1:85:cc:dc:5c:69:3d:24:d8:55:5c:b2:08:d6:a8:14:13:07:69:9f:4a:f0:63:19:9d:78 +-----BEGIN CERTIFICATE----- +MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE +BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn +aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg +QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg +SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0 +MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD +VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 +dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF +bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom +/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR +Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3 +4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z +5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0 +hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID +AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/ +BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX +SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l +VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq +URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf +peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF +Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW ++qtB4Uu2NQvAmxU= +-----END CERTIFICATE----- + +# Issuer: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6 O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. +# Subject: CN=TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6 O=TÃœRKTRUST Bilgi Ä°letiÅŸim ve BiliÅŸim GüvenliÄŸi Hizmetleri A.Åž. +# Label: "TÃœRKTRUST Elektronik Sertifika Hizmet SaÄŸlayıcısı H6" +# Serial: 138134509972618 +# MD5 Fingerprint: f8:c5:ee:2a:6b:be:95:8d:08:f7:25:4a:ea:71:3e:46 +# SHA1 Fingerprint: 8a:5c:8c:ee:a5:03:e6:05:56:ba:d8:1b:d4:f6:c9:b0:ed:e5:2f:e0 +# SHA256 Fingerprint: 8d:e7:86:55:e1:be:7f:78:47:80:0b:93:f6:94:d2:1d:36:8c:c0:6e:03:3e:7f:ab:04:bb:5e:b9:9d:a6:b7:00 +-----BEGIN CERTIFICATE----- +MIIEJjCCAw6gAwIBAgIGfaHyZeyKMA0GCSqGSIb3DQEBCwUAMIGxMQswCQYDVQQG +EwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYDVQQKDERUw5xSS1RSVVNUIEJpbGdp +IMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBB +LsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBI +aXptZXQgU2HEn2xhecSxY8Sxc8SxIEg2MB4XDTEzMTIxODA5MDQxMFoXDTIzMTIx +NjA5MDQxMFowgbExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExTTBLBgNV +BAoMRFTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2 +ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uMUIwQAYDVQQDDDlUw5xSS1RSVVNUIEVs +ZWt0cm9uaWsgU2VydGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLEgSDYwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdsGjW6L0UlqMACprx9MfMkU1x +eHe59yEmFXNRFpQJRwXiM/VomjX/3EsvMsew7eKC5W/a2uqsxgbPJQ1BgfbBOCK9 ++bGlprMBvD9QFyv26WZV1DOzXPhDIHiTVRZwGTLmiddk671IUP320EEDwnS3/faA +z1vFq6TWlRKb55cTMgPp1KtDWxbtMyJkKbbSk60vbNg9tvYdDjTu0n2pVQ8g9P0p +u5FbHH3GQjhtQiht1AH7zYiXSX6484P4tZgvsycLSF5W506jM7NE1qXyGJTtHB6p +lVxiSvgNZ1GpryHV+DKdeboaX+UEVU0TRv/yz3THGmNtwx8XEsMeED5gCLMxAgMB +AAGjQjBAMB0GA1UdDgQWBBTdVRcT9qzoSCHK77Wv0QAy7Z6MtTAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb1gNl0Oq +FlQ+v6nfkkU/hQu7VtMMUszIv3ZnXuaqs6fvuay0EBQNdH49ba3RfdCaqaXKGDsC +QC4qnFAUi/5XfldcEQlLNkVS9z2sFP1E34uXI9TDwe7UU5X+LEr+DXCqu4svLcsy +o4LyVN/Y8t3XSHLuSqMplsNEzm61kod2pLv0kmzOLBQJZo6NrRa1xxsJYTvjIKID +gI6tflEATseWhvtDmHd9KMeP2Cpu54Rvl0EpABZeTeIT6lnAY2c6RPuY/ATTMHKm +9ocJV612ph1jmv3XZch4gyt1O6VbuA1df74jrlZVlFjvH4GMKrLN5ptjnhi85WsG +tAuYSyher4hYyw== +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=Certification Authority of WoSign G2 O=WoSign CA Limited +# Subject: CN=Certification Authority of WoSign G2 O=WoSign CA Limited +# Label: "Certification Authority of WoSign G2" +# Serial: 142423943073812161787490648904721057092 +# MD5 Fingerprint: c8:1c:7d:19:aa:cb:71:93:f2:50:f8:52:a8:1e:ba:60 +# SHA1 Fingerprint: fb:ed:dc:90:65:b7:27:20:37:bc:55:0c:9c:56:de:bb:f2:78:94:e1 +# SHA256 Fingerprint: d4:87:a5:6f:83:b0:74:82:e8:5e:96:33:94:c1:ec:c2:c9:e5:1d:09:03:ee:94:6b:02:c3:01:58:1e:d9:9e:16 +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBY +MQswCQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNV +BAMTJENlcnRpZmljYXRpb24gQXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDEx +MDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgxCzAJBgNVBAYTAkNOMRowGAYDVQQK +ExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlmaWNhdGlvbiBBdXRo +b3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPX +JYY1kBaiXW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgO +gHzKtB0TiGsOqCR3A9DuW/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg +5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg95k4ot+vElbGs/V6r+kHLXZ1L3PR8du9n +fwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BKv0mUYQs4kI9dJGwlezt5 +2eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJ +KoZIhvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8 +fHulwqZm46qwtyeYP0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G +3CE4Q3RM+zD4F3LBMvzIkRfEzFg3TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yy +SrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu+sif/a+RZQp4OBXllxcU3fng +LDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+7Q9LGOHSJDy7 +XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg= +-----END CERTIFICATE----- + +# Issuer: CN=CA WoSign ECC Root O=WoSign CA Limited +# Subject: CN=CA WoSign ECC Root O=WoSign CA Limited +# Label: "CA WoSign ECC Root" +# Serial: 138625735294506723296996289575837012112 +# MD5 Fingerprint: 80:c6:53:ee:61:82:28:72:f0:ff:21:b9:17:ca:b2:20 +# SHA1 Fingerprint: d2:7a:d2:be:ed:94:c0:a1:3c:c7:25:21:ea:5d:71:be:81:19:f3:2b +# SHA256 Fingerprint: 8b:45:da:1c:06:f7:91:eb:0c:ab:f2:6b:e5:88:f5:fb:23:16:5c:2e:61:4b:f8:85:56:2d:0d:ce:50:b2:9b:02 +-----BEGIN CERTIFICATE----- +MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQsw +CQYDVQQGEwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMT +EkNBIFdvU2lnbiBFQ0MgUm9vdDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4 +NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEb +MBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACID +YgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiUt5v8 +KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES +1ns2o0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQUqv3VWqP2h4syhf3RMluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB +1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0Daupn75OcsqF1NnstTJFGG+rrQIwfcf3 +aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYua/GRspBl9JrmkO5K +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G1 O=Certplus +# Subject: CN=Certplus Root CA G1 O=Certplus +# Label: "Certplus Root CA G1" +# Serial: 1491911565779898356709731176965615564637713 +# MD5 Fingerprint: 7f:09:9c:f7:d9:b9:5c:69:69:56:d5:37:3e:14:0d:42 +# SHA1 Fingerprint: 22:fd:d0:b7:fd:a2:4e:0d:ac:49:2c:a0:ac:a6:7b:6a:1f:e3:f7:66 +# SHA256 Fingerprint: 15:2a:40:2b:fc:df:2c:d5:48:05:4d:22:75:b3:9c:7f:ca:3e:c0:97:80:78:b0:f0:ea:76:e5:61:a6:c7:43:3e +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa +MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy +dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a +iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt +6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP +0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f +6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE +EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN +1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc +h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT +mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV +4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO +WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud +DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd +Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq +hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh +66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7 +/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS +S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j +2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R +Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr +RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy +6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV +V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5 +g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl +++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo= +-----END CERTIFICATE----- + +# Issuer: CN=Certplus Root CA G2 O=Certplus +# Subject: CN=Certplus Root CA G2 O=Certplus +# Label: "Certplus Root CA G2" +# Serial: 1492087096131536844209563509228951875861589 +# MD5 Fingerprint: a7:ee:c4:78:2d:1b:ee:2d:b9:29:ce:d6:a7:96:32:31 +# SHA1 Fingerprint: 4f:65:8e:1f:e9:06:d8:28:02:e9:54:47:41:c9:54:25:5d:69:cc:1a +# SHA256 Fingerprint: 6c:c0:50:41:e6:44:5e:74:69:6c:4c:fb:c9:f8:0f:54:3b:7e:ab:bb:44:b4:ce:6f:78:7c:6a:99:71:c4:2f:17 +-----BEGIN CERTIFICATE----- +MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x +CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs +dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat +93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x +Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P +AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj +FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG +SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch +p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal +U5ORGpOucGpnutee5WEaXw== +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G1 O=OpenTrust +# Subject: CN=OpenTrust Root CA G1 O=OpenTrust +# Label: "OpenTrust Root CA G1" +# Serial: 1492036577811947013770400127034825178844775 +# MD5 Fingerprint: 76:00:cc:81:29:cd:55:5e:88:6a:7a:2e:f7:4d:39:da +# SHA1 Fingerprint: 79:91:e8:34:f7:e2:ee:dd:08:95:01:52:e9:55:2d:14:e9:58:d5:7e +# SHA256 Fingerprint: 56:c7:71:28:d9:8c:18:d9:1b:4c:fd:ff:bc:25:ee:91:03:d4:75:8e:a2:ab:ad:82:6a:90:f3:45:7d:46:0e:b4 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b +wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX +/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0 +77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP +uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx +p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx +Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2 +TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W +G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw +vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY +EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1 +2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw +DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E +PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf +gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS +FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0 +V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P +XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I +i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t +TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91 +09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky +Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ +AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj +1oxx +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G2 O=OpenTrust +# Subject: CN=OpenTrust Root CA G2 O=OpenTrust +# Label: "OpenTrust Root CA G2" +# Serial: 1492012448042702096986875987676935573415441 +# MD5 Fingerprint: 57:24:b6:59:24:6b:ae:c8:fe:1c:0c:20:f2:c0:4e:eb +# SHA1 Fingerprint: 79:5f:88:60:c5:ab:7c:3d:92:e6:cb:f4:8d:e1:45:cd:11:ef:60:0b +# SHA256 Fingerprint: 27:99:58:29:fe:6a:75:15:c1:bf:e8:48:f9:c4:76:1d:b1:6c:22:59:29:25:7b:f4:0d:08:94:f2:9e:a8:ba:f2 +-----BEGIN CERTIFICATE----- +MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA +MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w +ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw +MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU +T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh +/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e +CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6 +1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE +FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS +gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X +G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy +YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH +vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4 +t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/ +gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3 +5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w +DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz +Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0 +nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT +RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT +wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2 +t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa +TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2 +o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU +3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA +iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f +WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM +S1IK +-----END CERTIFICATE----- + +# Issuer: CN=OpenTrust Root CA G3 O=OpenTrust +# Subject: CN=OpenTrust Root CA G3 O=OpenTrust +# Label: "OpenTrust Root CA G3" +# Serial: 1492104908271485653071219941864171170455615 +# MD5 Fingerprint: 21:37:b4:17:16:92:7b:67:46:70:a9:96:d7:a8:13:24 +# SHA1 Fingerprint: 6e:26:64:f3:56:bf:34:55:bf:d1:93:3f:7c:01:de:d8:13:da:8a:a6 +# SHA256 Fingerprint: b7:c3:62:31:70:6e:81:07:8c:36:7c:b8:96:19:8f:1e:32:08:dd:92:69:49:dd:8f:57:09:a4:10:f7:5b:62:92 +-----BEGIN CERTIFICATE----- +MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx +CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U +cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow +QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl +blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm +3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d +oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G +A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5 +DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK +BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q +j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx +4nxp5V2a+EEfOzmTk51V6s2N8fvB +-----END CERTIFICATE----- diff --git a/examples/cpp/README.md b/examples/cpp/README.md index 3fa7ad4c784..783935cd53d 100644 --- a/examples/cpp/README.md +++ b/examples/cpp/README.md @@ -2,26 +2,14 @@ ## Installation -To install gRPC on your system, follow the instructions to build from source [here](../../INSTALL.md). This also installs the protocol buffer compiler `protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. +To install gRPC on your system, follow the instructions to build from source +[here](../../INSTALL.md). This also installs the protocol buffer compiler +`protoc` (if you don't have it already), and the C++ gRPC plugin for `protoc`. ## Hello C++ gRPC! -Here's how to build and run the C++ implementation of the [Hello World](../protos/helloworld.proto) example used in [Getting started](..). - -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 http://grpc.io/release) https://github.com/grpc/grpc -``` - -Change your current directory to examples/cpp/helloworld - -```sh -$ cd examples/cpp/helloworld/ -``` +Here's how to build and run the C++ implementation of the [Hello +World](../protos/helloworld.proto) example used in [Getting started](..). ### Client and server implementations @@ -31,18 +19,25 @@ The server implementation is at [greeter_server.cc](helloworld/greeter_server.cc ### 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 the "Greeter received: Hello world" in the client side output. + +If things go smoothly, you will see the "Greeter received: Hello world" in the +client side output. ## Tutorial diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md index 80fef07192e..ae84aba9163 100644 --- a/examples/cpp/cpptutorial.md +++ b/examples/cpp/cpptutorial.md @@ -1,58 +1,77 @@ #gRPC Basics: C++ -This tutorial provides a basic C++ programmer's introduction to working with gRPC. By walking through this example you'll learn how to: +This tutorial provides a basic C++ programmer's introduction to working with +gRPC. By walking through this example you'll learn how to: -- Define a service in a .proto file. +- Define a service in a `.proto` file. - Generate server and client code using the protocol buffer compiler. - Use the C++ gRPC API to write a simple client and server for your service. -It assumes that you have read the [Getting started](..) guide and are familiar with [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). Note that the example in this tutorial uses the proto3 version of the protocol buffers language, which is currently in alpha release: you can find out more in the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) and see the [release notes](https://github.com/google/protobuf/releases) for the new version in the protocol buffers Github repository. - -This isn't a comprehensive guide to using gRPC in C++: more reference documentation is coming soon. +It assumes that you are familiar with +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +Note that the example in this tutorial uses the proto3 version of the protocol +buffers language, which is currently in alpha release: you can find out more in +the [proto3 language guide](https://developers.google.com/protocol-buffers/docs/proto3) +and see the [release notes](https://github.com/google/protobuf/releases) for the +new version in the protocol buffers Github repository. ## Why use gRPC? -Our example is a simple route mapping application that lets clients get information about features on their route, create a summary of their route, and exchange route information such as traffic updates with the server and other clients. +Our example is a simple route mapping application that lets clients get +information about features on their route, create a summary of their route, and +exchange route information such as traffic updates with the server and other +clients. -With gRPC we can define our service once in a .proto file and implement clients and servers in any of gRPC's supported languages, which in turn can be run in environments ranging from servers inside Google to your own tablet - all the complexity of communication between different languages and environments is handled for you by gRPC. We also get all the advantages of working with protocol buffers, including efficient serialization, a simple IDL, and easy interface updating. +With gRPC we can define our service once in a `.proto` file and implement clients +and servers in any of gRPC's supported languages, which in turn can be run in +environments ranging from servers inside Google to your own tablet - all the +complexity of communication between different languages and environments is +handled for you by gRPC. We also get all the advantages of working with protocol +buffers, including efficient serialization, a simple IDL, and easy interface +updating. ## Example code and setup -The example code for our tutorial is in [examples/cpp/route_guide](route_guide). To download the example, clone this repository by running the following command: -```shell -$ git clone -b $(curl -L http://grpc.io/release) https://github.com/grpc/grpc -``` - -Then change your current directory to `examples/cpp/route_guide`: -```shell -$ cd examples/cpp/route_guide -``` - -You also should have the relevant tools installed to generate the server and client interface code - if you don't already, follow the setup instructions in [gRPC in 3 minutes](README.md). - +The example code for our tutorial is in [examples/cpp/route_guide](route_guide). +You also should have the relevant tools installed to generate the server and +client interface code - if you don't already, follow the setup instructions in +[INSTALL.md](../../INSTALL.md). ## Defining the service -Our first step (as you'll know from [Getting started](..) is to define the gRPC *service* and the method *request* and *response* types using [protocol buffers] (https://developers.google.com/protocol-buffers/docs/overview). You can see the complete .proto file in [`examples/protos/route_guide.proto`](../protos/route_guide.proto). +Our first step is to define the gRPC *service* and the method *request* and +*response* types using +[protocol buffers](https://developers.google.com/protocol-buffers/docs/overview). +You can see the complete `.proto` file in +[`examples/protos/route_guide.proto`](../protos/route_guide.proto). -To define a service, you specify a named `service` in your .proto file: +To define a service, you specify a named `service` in your `.proto` file: -``` +```protobuf service RouteGuide { ... } ``` -Then you define `rpc` methods inside your service definition, specifying their request and response types. gRPC lets you define four kinds of service method, all of which are used in the `RouteGuide` service: +Then you define `rpc` methods inside your service definition, specifying their +request and response types. gRPC lets you define four kinds of service method, +all of which are used in the `RouteGuide` service: -- A *simple RPC* where the client sends a request to the server using the stub and waits for a response to come back, just like a normal function call. -``` +- A *simple RPC* where the client sends a request to the server using the stub + and waits for a response to come back, just like a normal function call. + +```protobuf // Obtains the feature at a given position. rpc GetFeature(Point) returns (Feature) {} ``` -- A *server-side streaming RPC* where the client sends a request to the server and gets a stream to read a sequence of messages back. The client reads from the returned stream until there are no more messages. As you can see in our example, you specify a server-side streaming method by placing the `stream` keyword before the *response* type. -``` +- A *server-side streaming RPC* where the client sends a request to the server + and gets a stream to read a sequence of messages back. The client reads from + the returned stream until there are no more messages. As you can see in our + example, you specify a server-side streaming method by placing the `stream` + keyword before the *response* type. + +```protobuf // 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 @@ -60,22 +79,38 @@ Then you define `rpc` methods inside your service definition, specifying their r rpc ListFeatures(Rectangle) returns (stream Feature) {} ``` -- A *client-side streaming RPC* where the client writes a sequence of messages and sends them to the server, again using a provided stream. Once the client has finished writing the messages, it waits for the server to read them all and return its response. You specify a client-side streaming method by placing the `stream` keyword before the *request* type. -``` +- A *client-side streaming RPC* where the client writes a sequence of messages + and sends them to the server, again using a provided stream. Once the client + has finished writing the messages, it waits for the server to read them all + and return its response. You specify a client-side streaming method by placing + the `stream` keyword before the *request* type. + +```protobuf // Accepts a stream of Points on a route being traversed, returning a // RouteSummary when traversal is completed. rpc RecordRoute(stream Point) returns (RouteSummary) {} ``` -- A *bidirectional streaming RPC* where both sides send a sequence of messages using a read-write stream. The two streams operate independently, so clients and servers can read and write in whatever order they like: for example, the server could wait to receive all the client messages before writing its responses, or it could alternately read a message then write a message, or some other combination of reads and writes. The order of messages in each stream is preserved. You specify this type of method by placing the `stream` keyword before both the request and the response. -``` +- A *bidirectional streaming RPC* where both sides send a sequence of messages + using a read-write stream. The two streams operate independently, so clients + and servers can read and write in whatever order they like: for example, the + server could wait to receive all the client messages before writing its + responses, or it could alternately read a message then write a message, or + some other combination of reads and writes. The order of messages in each + stream is preserved. You specify this type of method by placing the `stream` + keyword before both the request and the response. + +```protobuf // Accepts a stream of RouteNotes sent while a route is being traversed, // while receiving other RouteNotes (e.g. from other users). rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} ``` -Our .proto file also contains protocol buffer message type definitions for all the request and response types used in our service methods - for example, here's the `Point` message type: -``` +Our `.proto` file also contains protocol buffer message type definitions for all +the request and response types used in our service methods - for example, here's +the `Point` message type: + +```protobuf // 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 @@ -86,12 +121,16 @@ message Point { } ``` - ## Generating client and server code -Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C++ plugin. +Next we need to generate the gRPC client and server interfaces from our `.proto` +service definition. We do this using the protocol buffer compiler `protoc` with +a special gRPC C++ plugin. -For simplicity, we've provided a [makefile](route_guide/Makefile) that runs `protoc` for you with the appropriate plugin, input, and output (if you want to run this yourself, make sure you've installed protoc and followed the gRPC code [installation instructions](../../INSTALL.md) first): +For simplicity, we've provided a [Makefile](route_guide/Makefile) that runs +`protoc` for you with the appropriate plugin, input, and output (if you want to +run this yourself, make sure you've installed protoc and followed the gRPC code +[installation instructions](../../INSTALL.md) first): ```shell $ make route_guide.grpc.pb.cc route_guide.pb.cc @@ -107,39 +146,58 @@ $ protoc -I ../../protos --cpp_out=. ../../protos/route_guide.proto Running this command generates the following files in your current directory: - `route_guide.pb.h`, the header which declares your generated message classes - `route_guide.pb.cc`, which contains the implementation of your message classes -- `route_guide.grpc.pb.h`, the header which declares your generated service classes -- `route_guide.grpc.pb.cc`, which contains the implementation of your service classes +- `route_guide.grpc.pb.h`, the header which declares your generated service + classes +- `route_guide.grpc.pb.cc`, which contains the implementation of your service + classes These contain: -- All the protocol buffer code to populate, serialize, and retrieve our request and response message types +- All the protocol buffer code to populate, serialize, and retrieve our request + and response message types - A class called `RouteGuide` that contains - - a remote interface type (or *stub*) for clients to call with the methods defined in the `RouteGuide` service. - - two abstract interfaces for servers to implement, also with the methods defined in the `RouteGuide` service. + - a remote interface type (or *stub*) for clients to call with the methods + defined in the `RouteGuide` service. + - two abstract interfaces for servers to implement, also with the methods + defined in the `RouteGuide` service. ## Creating the server -First let's look at how we create a `RouteGuide` server. If you're only interested in creating gRPC clients, you can skip this section and go straight to [Creating the client](#client) (though you might find it interesting anyway!). +First let's look at how we create a `RouteGuide` server. If you're only +interested in creating gRPC clients, you can skip this section and go straight +to [Creating the client](#client) (though you might find it interesting +anyway!). There are two parts to making our `RouteGuide` service do its job: -- Implementing the service interface generated from our service definition: doing the actual "work" of our service. -- Running a gRPC server to listen for requests from clients and return the service responses. +- Implementing the service interface generated from our service definition: + doing the actual "work" of our service. +- Running a gRPC server to listen for requests from clients and return the + service responses. -You can find our example `RouteGuide` server in [route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's take a closer look at how it works. +You can find our example `RouteGuide` server in +[route_guide/route_guide_server.cc](route_guide/route_guide_server.cc). Let's +take a closer look at how it works. ### Implementing RouteGuide -As you can see, our server has a `RouteGuideImpl` class that implements the generated `RouteGuide::Service` interface: +As you can see, our server has a `RouteGuideImpl` class that implements the +generated `RouteGuide::Service` interface: ```cpp class RouteGuideImpl final : public RouteGuide::Service { ... } ``` -In this case we're implementing the *synchronous* version of `RouteGuide`, which provides our default gRPC server behaviour. It's also possible to implement an asynchronous interface, `RouteGuide::AsyncService`, which allows you to further customize your server's threading behaviour, though we won't look at this in this tutorial. +In this case we're implementing the *synchronous* version of `RouteGuide`, which +provides our default gRPC server behaviour. It's also possible to implement an +asynchronous interface, `RouteGuide::AsyncService`, which allows you to further +customize your server's threading behaviour, though we won't look at this in +this tutorial. -`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`. +`RouteGuideImpl` implements all our service methods. Let's look at the simplest +type first, `GetFeature`, which just gets a `Point` from the client and returns +the corresponding feature information from its database in a `Feature`. ```cpp Status GetFeature(ServerContext* context, const Point* point, @@ -150,34 +208,52 @@ In this case we're implementing the *synchronous* version of `RouteGuide`, which } ``` -The method is passed a context object for the RPC, the client's `Point` protocol buffer request, and a `Feature` protocol buffer to fill in with the response information. In the method we populate the `Feature` with the appropriate information, and then `return` with an `OK` status to tell gRPC that we've finished dealing with the RPC and that the `Feature` can be returned to the client. +The method is passed a context object for the RPC, the client's `Point` protocol +buffer request, and a `Feature` protocol buffer to fill in with the response +information. In the method we populate the `Feature` with the appropriate +information, and then `return` with an `OK` status to tell gRPC that we've +finished dealing with the RPC and that the `Feature` can be returned to the +client. -Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature`s to our client. +Now let's look at something a bit more complicated - a streaming RPC. +`ListFeatures` is a server-side streaming RPC, so we need to send back multiple +`Feature`s to our client. ```cpp - Status ListFeatures(ServerContext* context, const Rectangle* rectangle, - ServerWriter* writer) override { - auto lo = rectangle->lo(); - auto hi = rectangle->hi(); - long left = std::min(lo.longitude(), hi.longitude()); - long right = std::max(lo.longitude(), hi.longitude()); - long top = std::max(lo.latitude(), hi.latitude()); - long bottom = std::min(lo.latitude(), hi.latitude()); - for (const Feature& f : feature_list_) { - if (f.location().longitude() >= left && - f.location().longitude() <= right && - f.location().latitude() >= bottom && - f.location().latitude() <= top) { - writer->Write(f); - } +Status ListFeatures(ServerContext* context, const Rectangle* rectangle, + ServerWriter* writer) override { + auto lo = rectangle->lo(); + auto hi = rectangle->hi(); + long left = std::min(lo.longitude(), hi.longitude()); + long right = std::max(lo.longitude(), hi.longitude()); + long top = std::max(lo.latitude(), hi.latitude()); + long bottom = std::min(lo.latitude(), hi.latitude()); + for (const Feature& f : feature_list_) { + if (f.location().longitude() >= left && + f.location().longitude() <= right && + f.location().latitude() >= bottom && + f.location().latitude() <= top) { + writer->Write(f); } - return Status::OK; } + return Status::OK; +} ``` -As you can see, instead of getting simple request and response objects in our method parameters, this time we get a request object (the `Rectangle` in which our client wants to find `Feature`s) and a special `ServerWriter` object. In the method, we populate as many `Feature` objects as we need to return, writing them to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, we `return Status::OK` to tell gRPC that we've finished writing responses. +As you can see, instead of getting simple request and response objects in our +method parameters, this time we get a request object (the `Rectangle` in which +our client wants to find `Feature`s) and a special `ServerWriter` object. In the +method, we populate as many `Feature` objects as we need to return, writing them +to the `ServerWriter` using its `Write()` method. Finally, as in our simple RPC, +we `return Status::OK` to tell gRPC that we've finished writing responses. -If you look at the client-side streaming method `RecordRoute` you'll see it's quite similar, except this time we get a `ServerReader` instead of a request object and a single response. We use the `ServerReader`s `Read()` method to repeatedly read in our client's requests to a request object (in this case a `Point`) until there are no more messages: the server needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. +If you look at the client-side streaming method `RecordRoute` you'll see it's +quite similar, except this time we get a `ServerReader` instead of a request +object and a single response. We use the `ServerReader`s `Read()` method to +repeatedly read in our client's requests to a request object (in this case a +`Point`) until there are no more messages: the server needs to check the return +value of `Read()` after each call. If `true`, the stream is still good and it +can continue reading; if `false` the message stream has ended. ```cpp while (stream->Read(&point)) { @@ -205,11 +281,18 @@ Finally, let's look at our bidirectional streaming RPC `RouteChat()`. } ``` -This time we get a `ServerReaderWriter` that can be used to read *and* write messages. The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +This time we get a `ServerReaderWriter` that can be used to read *and* write +messages. The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ### Starting the server -Once we've implemented all our methods, we also need to start up a gRPC server so that clients can actually use our service. The following snippet shows how we do this for our `RouteGuide` service: +Once we've implemented all our methods, we also need to start up a gRPC server +so that clients can actually use our service. The following snippet shows how we +do this for our `RouteGuide` service: ```cpp void RunServer(const std::string& db_path) { @@ -227,44 +310,55 @@ void RunServer(const std::string& db_path) { As you can see, we build and start our server using a `ServerBuilder`. To do this, we: 1. Create an instance of our service implementation class `RouteGuideImpl`. -2. Create an instance of the factory `ServerBuilder` class. -3. Specify the address and port we want to use to listen for client requests using the builder's `AddListeningPort()` method. -4. Register our service implementation with the builder. -5. Call `BuildAndStart()` on the builder to create and start an RPC server for our service. -5. Call `Wait()` on the server to do a blocking wait until process is killed or `Shutdown()` is called. +1. Create an instance of the factory `ServerBuilder` class. +1. Specify the address and port we want to use to listen for client requests + using the builder's `AddListeningPort()` method. +1. Register our service implementation with the builder. +1. Call `BuildAndStart()` on the builder to create and start an RPC server for + our service. +1. Call `Wait()` on the server to do a blocking wait until process is killed or + `Shutdown()` is called. ## Creating the client -In this section, we'll look at creating a C++ client for our `RouteGuide` service. You can see our complete example client code in [route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). +In this section, we'll look at creating a C++ client for our `RouteGuide` +service. You can see our complete example client code in +[route_guide/route_guide_client.cc](route_guide/route_guide_client.cc). ### Creating a stub To call service methods, we first need to create a *stub*. -First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to without SSL: +First we need to create a gRPC *channel* for our stub, specifying the server +address and port we want to connect to without SSL: ```cpp grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); ``` -Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto. +Now we can use the channel to create our stub using the `NewStub` method +provided in the `RouteGuide` class we generated from our `.proto`. ```cpp - public: - RouteGuideClient(std::shared_ptr channel, const std::string& db) - : stub_(RouteGuide::NewStub(channel)) { - ... - } +public: + RouteGuideClient(std::shared_ptr channel, const std::string& db) + : stub_(RouteGuide::NewStub(channel)) { + ... + } ``` ### Calling service methods -Now let's look at how we call our service methods. Note that in this tutorial we're calling the *blocking/synchronous* versions of each method: this means that the RPC call waits for the server to respond, and will either return a response or raise an exception. +Now let's look at how we call our service methods. Note that in this tutorial +we're calling the *blocking/synchronous* versions of each method: this means +that the RPC call waits for the server to respond, and will either return a +response or raise an exception. #### Simple RPC -Calling the simple RPC `GetFeature` is nearly as straightforward as calling a local method. +Calling the simple RPC `GetFeature` is nearly as straightforward as calling a +local method. ```cpp Point point; @@ -281,33 +375,53 @@ Calling the simple RPC `GetFeature` is nearly as straightforward as calling a lo } ``` -As you can see, we create and populate a request protocol buffer object (in our case `Point`), and create a response protocol buffer object for the server to fill in. We also create a `ClientContext` object for our call - you can optionally set RPC configuration values on this object, such as deadlines, though for now we'll use the default settings. Note that you cannot reuse this object between calls. Finally, we call the method on the stub, passing it the context, request, and response. If the method returns `OK`, then we can read the response information from the server from our response object. +As you can see, we create and populate a request protocol buffer object (in our +case `Point`), and create a response protocol buffer object for the server to +fill in. We also create a `ClientContext` object for our call - you can +optionally set RPC configuration values on this object, such as deadlines, +though for now we'll use the default settings. Note that you cannot reuse this +object between calls. Finally, we call the method on the stub, passing it the +context, request, and response. If the method returns `OK`, then we can read the +response information from the server from our response object. ```cpp - std::cout << "Found feature called " << feature->name() << " at " - << feature->location().latitude()/kCoordFactor_ << ", " - << feature->location().longitude()/kCoordFactor_ << std::endl; +std::cout << "Found feature called " << feature->name() << " at " + << feature->location().latitude()/kCoordFactor_ << ", " + << feature->location().longitude()/kCoordFactor_ << std::endl; ``` #### Streaming RPCs -Now let's look at our streaming methods. If you've already read [Creating the server](#server) some of this may look very familiar - streaming RPCs are implemented in a similar way on both sides. Here's where we call the server-side streaming method `ListFeatures`, which returns a stream of geographical `Feature`s: +Now let's look at our streaming methods. If you've already read [Creating the +server](#server) some of this may look very familiar - streaming RPCs are +implemented in a similar way on both sides. Here's where we call the server-side +streaming method `ListFeatures`, which returns a stream of geographical +`Feature`s: ```cpp - std::unique_ptr > reader( - stub_->ListFeatures(&context, rect)); - while (reader->Read(&feature)) { - std::cout << "Found feature called " - << feature.name() << " at " - << feature.location().latitude()/kCoordFactor_ << ", " - << feature.location().longitude()/kCoordFactor_ << std::endl; - } - Status status = reader->Finish(); +std::unique_ptr > reader( + stub_->ListFeatures(&context, rect)); +while (reader->Read(&feature)) { + std::cout << "Found feature called " + << feature.name() << " at " + << feature.location().latitude()/kCoordFactor_ << ", " + << feature.location().longitude()/kCoordFactor_ << std::endl; +} +Status status = reader->Finish(); ``` -Instead of passing the method a context, request, and response, we pass it a context and request and get a `ClientReader` object back. The client can use the `ClientReader` to read the server's responses. We use the `ClientReader`s `Read()` method to repeatedly read in the server's responses to a response protocol buffer object (in this case a `Feature`) until there are no more messages: the client needs to check the return value of `Read()` after each call. If `true`, the stream is still good and it can continue reading; if `false` the message stream has ended. Finally, we call `Finish()` on the stream to complete the call and get our RPC status. +Instead of passing the method a context, request, and response, we pass it a +context and request and get a `ClientReader` object back. The client can use the +`ClientReader` to read the server's responses. We use the `ClientReader`s +`Read()` method to repeatedly read in the server's responses to a response +protocol buffer object (in this case a `Feature`) until there are no more +messages: the client needs to check the return value of `Read()` after each +call. If `true`, the stream is still good and it can continue reading; if +`false` the message stream has ended. Finally, we call `Finish()` on the stream +to complete the call and get our RPC status. -The client-side streaming method `RecordRoute` is similar, except there we pass the method a context and response object and get back a `ClientWriter`. +The client-side streaming method `RecordRoute` is similar, except there we pass +the method a context and response object and get back a `ClientWriter`. ```cpp std::unique_ptr > writer( @@ -337,16 +451,26 @@ The client-side streaming method `RecordRoute` is similar, except there we pass } ``` -Once we've finished writing our client's requests to the stream using `Write()`, we need to call `WritesDone()` on the stream to let gRPC know that we've finished writing, then `Finish()` to complete the call and get our RPC status. If the status is `OK`, our response object that we initially passed to `RecordRoute()` will be populated with the server's response. +Once we've finished writing our client's requests to the stream using `Write()`, +we need to call `WritesDone()` on the stream to let gRPC know that we've +finished writing, then `Finish()` to complete the call and get our RPC status. +If the status is `OK`, our response object that we initially passed to +`RecordRoute()` will be populated with the server's response. -Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this case, we just pass a context to the method and get back a `ClientReaderWriter`, which we can use to both write and read messages. +Finally, let's look at our bidirectional streaming RPC `RouteChat()`. In this +case, we just pass a context to the method and get back a `ClientReaderWriter`, +which we can use to both write and read messages. ```cpp - std::shared_ptr > stream( - stub_->RouteChat(&context)); +std::shared_ptr > stream( + stub_->RouteChat(&context)); ``` -The syntax for reading and writing here is exactly the same as for our client-streaming and server-streaming methods. Although each side will always get the other's messages in the order they were written, both the client and server can read and write in any order — the streams operate completely independently. +The syntax for reading and writing here is exactly the same as for our +client-streaming and server-streaming methods. Although each side will always +get the other's messages in the order they were written, both the client and +server can read and write in any order — the streams operate completely +independently. ## Try it out! @@ -362,4 +486,3 @@ Run the client (in a different terminal): ```shell $ ./route_guide_client ``` - diff --git a/examples/cpp/helloworld/CMakeLists.txt b/examples/cpp/helloworld/CMakeLists.txt new file mode 100644 index 00000000000..8f098c91a6b --- /dev/null +++ b/examples/cpp/helloworld/CMakeLists.txt @@ -0,0 +1,49 @@ +# Minimum CMake required +cmake_minimum_required(VERSION 2.8) + +# Project +project(HelloWorld CXX) + +# Protobuf +set(protobuf_MODULE_COMPATIBLE TRUE) +find_package(protobuf CONFIG REQUIRED) +message(STATUS "Using protobuf ${protobuf_VERSION}") + +# gRPC +find_package(gRPC CONFIG REQUIRED) +message(STATUS "Using gRPC ${gRPC_VERSION}") + +# gRPC C++ plugin +get_target_property(gRPC_CPP_PLUGIN_EXECUTABLE gRPC::grpc_cpp_plugin + IMPORTED_LOCATION_RELEASE) + +# Proto file +get_filename_component(hw_proto "../../protos/helloworld.proto" ABSOLUTE) +get_filename_component(hw_proto_path "${hw_proto}" PATH) + +# Generated sources +protobuf_generate_cpp(hw_proto_srcs hw_proto_hdrs "${hw_proto}") +set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.cc") +set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/helloworld.grpc.pb.h") +add_custom_command( + OUTPUT "${hw_grpc_srcs}" "${hw_grpc_hdrs}" + COMMAND protobuf::protoc + ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" -I "${hw_proto_path}" + --plugin=protoc-gen-grpc="${gRPC_CPP_PLUGIN_EXECUTABLE}" + "${hw_proto}" + DEPENDS "${hw_proto}") + +# Generated include directory +include_directories("${CMAKE_CURRENT_BINARY_DIR}") + +# Targets greeter_[async_](client|server) +foreach(_target + greeter_client greeter_server + greeter_async_client greeter_async_server) + add_executable(${_target} "${_target}.cc" + ${hw_proto_srcs} + ${hw_grpc_srcs}) + target_link_libraries(${_target} + protobuf::libprotobuf + gRPC::grpc++_unsecure) +endforeach() diff --git a/examples/cpp/helloworld/Makefile b/examples/cpp/helloworld/Makefile index b45b3c7ee0c..2c50b8208b1 100644 --- a/examples/cpp/helloworld/Makefile +++ b/examples/cpp/helloworld/Makefile @@ -29,10 +29,20 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) CXX = g++ CPPFLAGS += -I/usr/local/include -pthread CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` -lprotobuf -lpthread -ldl +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \ + -lgrpc++_reflection \ + -lprotobuf -lpthread -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++ grpc` \ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \ + -lprotobuf -lpthread -ldl +endif PROTOC = protoc GRPC_CPP_PLUGIN = grpc_cpp_plugin GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` @@ -97,7 +107,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @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-beta-3.3" + @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 diff --git a/examples/cpp/route_guide/Makefile b/examples/cpp/route_guide/Makefile index 50ecf041f56..00cf9ad4e62 100644 --- a/examples/cpp/route_guide/Makefile +++ b/examples/cpp/route_guide/Makefile @@ -29,10 +29,20 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # +HOST_SYSTEM = $(shell uname | cut -f 1 -d_) +SYSTEM ?= $(HOST_SYSTEM) CXX = g++ CPPFLAGS += -I/usr/local/include -pthread CXXFLAGS += -std=c++11 -LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` -lprotobuf -lpthread -ldl +ifeq ($(SYSTEM),Darwin) +LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \ + -lgrpc++_reflection \ + -lprotobuf -lpthread -ldl +else +LDFLAGS += -L/usr/local/lib `pkg-config --libs grpc++` \ + -Wl,--no-as-needed -lgrpc++_reflection -Wl,--as-needed \ + -lprotobuf -lpthread -ldl +endif PROTOC = protoc GRPC_CPP_PLUGIN = grpc_cpp_plugin GRPC_CPP_PLUGIN_PATH ?= `which $(GRPC_CPP_PLUGIN)` @@ -86,7 +96,7 @@ ifneq ($(HAS_VALID_PROTOC),true) @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-beta-3.3" + @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 diff --git a/examples/csharp/.nuget/packages.config b/examples/csharp/.nuget/packages.config deleted file mode 100644 index b14373069f1..00000000000 --- a/examples/csharp/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs new file mode 100644 index 00000000000..6477b4f35be --- /dev/null +++ b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs @@ -0,0 +1,259 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +#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 { + + /// Holder for reflection information generated from helloworld.proto + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public static partial class HelloworldReflection { + + #region Descriptor + /// File descriptor for helloworld.proto + 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 + /// + /// The request message containing the user's name. + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloRequest : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloRequest()); + public static pb::MessageParser Parser { get { return _parser; } } + + public static pbr::MessageDescriptor Descriptor { + get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; } + } + + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + public HelloRequest() { + OnConstruction(); + } + + partial void OnConstruction(); + + public HelloRequest(HelloRequest other) : this() { + name_ = other.name_; + } + + public HelloRequest Clone() { + return new HelloRequest(this); + } + + /// Field number for the "name" field. + public const int NameFieldNumber = 1; + private string name_ = ""; + public string Name { + get { return name_; } + set { + name_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + public override bool Equals(object other) { + return Equals(other as HelloRequest); + } + + public bool Equals(HelloRequest other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Name != other.Name) return false; + return true; + } + + public override int GetHashCode() { + int hash = 1; + if (Name.Length != 0) hash ^= Name.GetHashCode(); + return hash; + } + + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + public void WriteTo(pb::CodedOutputStream output) { + if (Name.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Name); + } + } + + public int CalculateSize() { + int size = 0; + if (Name.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Name); + } + return size; + } + + public void MergeFrom(HelloRequest other) { + if (other == null) { + return; + } + if (other.Name.Length != 0) { + Name = other.Name; + } + } + + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Name = input.ReadString(); + break; + } + } + } + } + + } + + /// + /// The response message containing the greetings + /// + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + public sealed partial class HelloReply : pb::IMessage { + private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new HelloReply()); + public static pb::MessageParser Parser { get { return _parser; } } + + public static pbr::MessageDescriptor Descriptor { + get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; } + } + + pbr::MessageDescriptor pb::IMessage.Descriptor { + get { return Descriptor; } + } + + public HelloReply() { + OnConstruction(); + } + + partial void OnConstruction(); + + public HelloReply(HelloReply other) : this() { + message_ = other.message_; + } + + public HelloReply Clone() { + return new HelloReply(this); + } + + /// Field number for the "message" field. + public const int MessageFieldNumber = 1; + private string message_ = ""; + public string Message { + get { return message_; } + set { + message_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); + } + } + + public override bool Equals(object other) { + return Equals(other as HelloReply); + } + + public bool Equals(HelloReply other) { + if (ReferenceEquals(other, null)) { + return false; + } + if (ReferenceEquals(other, this)) { + return true; + } + if (Message != other.Message) return false; + return true; + } + + public override int GetHashCode() { + int hash = 1; + if (Message.Length != 0) hash ^= Message.GetHashCode(); + return hash; + } + + public override string ToString() { + return pb::JsonFormatter.ToDiagnosticString(this); + } + + public void WriteTo(pb::CodedOutputStream output) { + if (Message.Length != 0) { + output.WriteRawTag(10); + output.WriteString(Message); + } + } + + public int CalculateSize() { + int size = 0; + if (Message.Length != 0) { + size += 1 + pb::CodedOutputStream.ComputeStringSize(Message); + } + return size; + } + + public void MergeFrom(HelloReply other) { + if (other == null) { + return; + } + if (other.Message.Length != 0) { + Message = other.Message; + } + } + + public void MergeFrom(pb::CodedInputStream input) { + uint tag; + while ((tag = input.ReadTag()) != 0) { + switch(tag) { + default: + input.SkipLastField(); + break; + case 10: { + Message = input.ReadString(); + break; + } + } + } + } + + } + + #endregion + +} + +#endregion Designer generated code diff --git a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs new file mode 100644 index 00000000000..041f5a78d75 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs @@ -0,0 +1,143 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: helloworld.proto +// Original file comments: +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +#region Designer generated code + +using System; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; + +namespace Helloworld { + /// + /// The greeting service definition. + /// + public static class Greeter + { + static readonly string __ServiceName = "helloworld.Greeter"; + + static readonly Marshaller __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom); + static readonly Marshaller __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom); + + static readonly Method __Method_SayHello = new Method( + MethodType.Unary, + __ServiceName, + "SayHello", + __Marshaller_HelloRequest, + __Marshaller_HelloReply); + + /// Service descriptor + public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor + { + get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; } + } + + /// Base class for server-side implementations of Greeter + public abstract class GreeterBase + { + /// + /// Sends a greeting + /// + public virtual global::System.Threading.Tasks.Task SayHello(global::Helloworld.HelloRequest request, ServerCallContext context) + { + throw new RpcException(new Status(StatusCode.Unimplemented, "")); + } + + } + + /// Client for Greeter + public class GreeterClient : ClientBase + { + /// Creates a new client for Greeter + /// The channel to use to make remote calls. + public GreeterClient(Channel channel) : base(channel) + { + } + /// Creates a new client for Greeter that uses a custom CallInvoker. + /// The callInvoker to use to make remote calls. + public GreeterClient(CallInvoker callInvoker) : base(callInvoker) + { + } + /// Protected parameterless constructor to allow creation of test doubles. + protected GreeterClient() : base() + { + } + /// Protected constructor to allow creation of configured clients. + /// The client configuration. + protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration) + { + } + + /// + /// Sends a greeting + /// + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return SayHello(request, new CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sends a greeting + /// + public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options) + { + return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request); + } + /// + /// Sends a greeting + /// + public virtual AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken)) + { + return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken)); + } + /// + /// Sends a greeting + /// + public virtual AsyncUnaryCall SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options) + { + return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request); + } + protected override GreeterClient NewInstance(ClientBaseConfiguration configuration) + { + return new GreeterClient(configuration); + } + } + + /// Creates service definition that can be registered with a server + public static ServerServiceDefinition BindService(GreeterBase serviceImpl) + { + return ServerServiceDefinition.CreateBuilder() + .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build(); + } + + } +} +#endregion diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json new file mode 100644 index 00000000000..40fba7cf1f5 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/Greeter/project.json @@ -0,0 +1,22 @@ +{ + "title": "Greeter", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + }, + "dependencies": { + "Google.Protobuf": "3.0.0", + "Grpc": "1.0.0", + }, + "frameworks": { + "net45": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.IO": "" + }, + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1" + } + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs new file mode 100644 index 00000000000..444d4735095 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs @@ -0,0 +1,53 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using System; +using Grpc.Core; +using Helloworld; + +namespace GreeterClient +{ + class Program + { + public static void Main(string[] args) + { + Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure); + + var client = new Greeter.GreeterClient(channel); + String user = "you"; + + var reply = client.SayHello(new HelloRequest { Name = user }); + Console.WriteLine("Greeting: " + reply.Message); + + channel.ShutdownAsync().Wait(); + Console.WriteLine("Press any key to exit..."); + Console.ReadKey(); + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json new file mode 100644 index 00000000000..74962a90e90 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json @@ -0,0 +1,26 @@ +{ + "title": "GreeterClient", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + "emitEntryPoint": "true" + }, + "dependencies": { + "Google.Protobuf": "3.0.0", + "Grpc": "1.0.0", + "Greeter": { + "target": "project" + } + }, + "frameworks": { + "net45": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.IO": "" + }, + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1" + } + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs new file mode 100644 index 00000000000..fdab379e81d --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs @@ -0,0 +1,66 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +using System; +using System.Threading.Tasks; +using Grpc.Core; +using Helloworld; + +namespace GreeterServer +{ + class GreeterImpl : Greeter.GreeterBase + { + // Server side handler of the SayHello RPC + public override Task SayHello(HelloRequest request, ServerCallContext context) + { + return Task.FromResult(new HelloReply { Message = "Hello " + request.Name }); + } + } + + class Program + { + const int Port = 50051; + + public static void Main(string[] args) + { + Server server = new Server + { + Services = { Greeter.BindService(new GreeterImpl()) }, + Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) } + }; + server.Start(); + + Console.WriteLine("Greeter server listening on port " + Port); + Console.WriteLine("Press any key to stop the server..."); + Console.ReadKey(); + + server.ShutdownAsync().Wait(); + } + } +} diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json new file mode 100644 index 00000000000..33af2544819 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json @@ -0,0 +1,26 @@ +{ + "title": "GreeterServer", + "version": "1.0.0-*", + "buildOptions": { + "debugType": "portable", + "emitEntryPoint": "true" + }, + "dependencies": { + "Google.Protobuf": "3.0.0", + "Grpc": "1.0.0", + "Greeter": { + "target": "project" + } + }, + "frameworks": { + "net45": { + "frameworkAssemblies": { + "System.Runtime": "", + "System.IO": "" + }, + "dependencies": { + "Microsoft.NETCore.Platforms": "1.0.1" + } + } + } +} diff --git a/examples/csharp/helloworld-from-cli/README.md b/examples/csharp/helloworld-from-cli/README.md new file mode 100644 index 00000000000..4db077631d8 --- /dev/null +++ b/examples/csharp/helloworld-from-cli/README.md @@ -0,0 +1,59 @@ +gRPC in 3 minutes (C#) +======================== + +BACKGROUND +------------- +This is a different version of the helloworld example, using the dotnet sdk +tools to build and run. + +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. + +The examples in this directory target .NET 4.5 framework, as .NET Core support is +currently experimental. + +PREREQUISITES +------------- + +- The DotNetCore SDK cli. + +- The .NET 4.5 framework. + +Both are available to download at https://www.microsoft.com/net/download + +BUILD +------- + +From the `examples/csharp/helloworld-from-cli` directory: + +- `dotnet restore` + +- `dotnet build **/project.json` (this will automatically download NuGet dependencies) + +Try it! +------- + +- Run the server + + ``` + > cd GreeterServer + > dotnet run + ``` + +- Run the client + + ``` + > cd GreeterClient + > dotnet run + ``` + +Tutorial +-------- + +You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][] + +[helloworld.proto]:../../protos/helloworld.proto +[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html diff --git a/examples/csharp/helloworld/.nuget/packages.config b/examples/csharp/helloworld/.nuget/packages.config deleted file mode 100644 index aa060800c19..00000000000 --- a/examples/csharp/helloworld/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/helloworld/Greeter.sln b/examples/csharp/helloworld/Greeter.sln index 9430e94de99..49e364d91c0 100644 --- a/examples/csharp/helloworld/Greeter.sln +++ b/examples/csharp/helloworld/Greeter.sln @@ -9,11 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterSer EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/examples/csharp/helloworld/Greeter/Greeter.csproj b/examples/csharp/helloworld/Greeter/Greeter.csproj index 20b85db8b60..f4ff71e2d12 100644 --- a/examples/csharp/helloworld/Greeter/Greeter.csproj +++ b/examples/csharp/helloworld/Greeter/Greeter.csproj @@ -33,16 +33,16 @@ False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.0.0\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll False - ..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -61,11 +61,11 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config index ff9d6bbf73f..46f7ddacb76 100644 --- a/examples/csharp/helloworld/Greeter/packages.config +++ b/examples/csharp/helloworld/Greeter/packages.config @@ -1,7 +1,8 @@  - - - - - \ No newline at end of file + + + + + + diff --git a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj index 2b38ce290e9..c701f91ca50 100644 --- a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj +++ b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj @@ -33,16 +33,16 @@ False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.0.0\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll False - ..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -59,11 +59,11 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + diff --git a/examples/csharp/helloworld/GreeterClient/packages.config b/examples/csharp/helloworld/GreeterClient/packages.config index ff9d6bbf73f..9f5509769a1 100644 --- a/examples/csharp/helloworld/GreeterClient/packages.config +++ b/examples/csharp/helloworld/GreeterClient/packages.config @@ -1,7 +1,7 @@  - - - - - \ No newline at end of file + + + + + diff --git a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj index 43c633678b1..6869820ca7d 100644 --- a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj +++ b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj @@ -33,16 +33,16 @@ False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.0.0\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll False - ..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -59,11 +59,11 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + diff --git a/examples/csharp/helloworld/GreeterServer/packages.config b/examples/csharp/helloworld/GreeterServer/packages.config index ff9d6bbf73f..9f5509769a1 100644 --- a/examples/csharp/helloworld/GreeterServer/packages.config +++ b/examples/csharp/helloworld/GreeterServer/packages.config @@ -1,7 +1,7 @@  - - - - - \ No newline at end of file + + + + + diff --git a/examples/csharp/helloworld/README.md b/examples/csharp/helloworld/README.md index d13c9ac9db4..71840ad48bf 100644 --- a/examples/csharp/helloworld/README.md +++ b/examples/csharp/helloworld/README.md @@ -13,7 +13,7 @@ PREREQUISITES ------------- - Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015 -- Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed) +- Linux: Mono 4+, MonoDevelop 5.9+ - Mac OS X: Xamarin Studio 5.9+ BUILD @@ -21,7 +21,20 @@ BUILD - Open solution `Greeter.sln` with Visual Studio, Monodevelop (on Linux) or Xamarin Studio (on Mac OS X) -- Build the solution (this will automatically download NuGet dependencies) +# Using Visual Studio + +* Build the solution (this will automatically download NuGet dependencies) + +# 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. One alternative to is to use the dotnet command line tools instead (see [helloworld-from-cli]). + +Using these IDEs, a workaround is as follows: +* Obtain a nuget executable for your platform and update it with + `nuget update -self`. +* Navigate to this directory and run `nuget restore`. +* Now that packages have been restored into their proper package folder, build the solution from your IDE. Try it! ------- @@ -49,5 +62,6 @@ Tutorial You can find a more detailed tutorial in [gRPC Basics: C#][] +[helloworld-from-cli]:../helloworld-from-cli/README.md [helloworld.proto]:../../protos/helloworld.proto [gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html diff --git a/examples/csharp/helloworld/generate_protos.bat b/examples/csharp/helloworld/generate_protos.bat index a952bb46cdc..28b73956354 100644 --- a/examples/csharp/helloworld/generate_protos.bat +++ b/examples/csharp/helloworld/generate_protos.bat @@ -34,8 +34,8 @@ setlocal @rem enter this directory cd /d %~dp0 -set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86 +set TOOLS_PATH=packages\Grpc.Tools.1.0.0\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 \ No newline at end of file +endlocal diff --git a/examples/csharp/route_guide/.nuget/packages.config b/examples/csharp/route_guide/.nuget/packages.config deleted file mode 100644 index aa060800c19..00000000000 --- a/examples/csharp/route_guide/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/examples/csharp/route_guide/RouteGuide.sln b/examples/csharp/route_guide/RouteGuide.sln index 0b79fdc5ca7..00065b0ba9d 100644 --- a/examples/csharp/route_guide/RouteGuide.sln +++ b/examples/csharp/route_guide/RouteGuide.sln @@ -9,11 +9,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGu EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj index 601d16ba24d..8861f3f63d6 100644 --- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj +++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj @@ -33,11 +33,11 @@ False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.0.0\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll False - ..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll False @@ -45,15 +45,15 @@ - - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll - + + False + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll + @@ -74,12 +74,12 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config index b962a7232a9..4e8d3f236dc 100644 --- a/examples/csharp/route_guide/RouteGuide/packages.config +++ b/examples/csharp/route_guide/RouteGuide/packages.config @@ -1,8 +1,8 @@  - - - - + + + + - \ No newline at end of file + diff --git a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj index 6f5c0a50dd4..3fe8d0c104b 100644 --- a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj +++ b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj @@ -35,11 +35,11 @@ False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.0.0\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll False - ..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll False @@ -49,7 +49,7 @@ False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -71,12 +71,12 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config index b962a7232a9..4e8d3f236dc 100644 --- a/examples/csharp/route_guide/RouteGuideClient/packages.config +++ b/examples/csharp/route_guide/RouteGuideClient/packages.config @@ -1,8 +1,8 @@  - - - - + + + + - \ No newline at end of file + diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj index 5bf46b05b89..f77e2fefab3 100644 --- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj +++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj @@ -35,11 +35,11 @@ False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll + ..\packages\Google.Protobuf.3.0.0\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll False - ..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll + ..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll False @@ -47,15 +47,15 @@ - - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll - + + False + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll + @@ -72,12 +72,12 @@ - + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + - \ No newline at end of file + diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config index b962a7232a9..a742eb2ff10 100644 --- a/examples/csharp/route_guide/RouteGuideServer/packages.config +++ b/examples/csharp/route_guide/RouteGuideServer/packages.config @@ -1,8 +1,9 @@  - - - - + + + + - \ No newline at end of file + + diff --git a/examples/csharp/route_guide/generate_protos.bat b/examples/csharp/route_guide/generate_protos.bat index dbdbd1f172f..69f5e0f4a39 100644 --- a/examples/csharp/route_guide/generate_protos.bat +++ b/examples/csharp/route_guide/generate_protos.bat @@ -34,8 +34,8 @@ setlocal @rem enter this directory cd /d %~dp0 -set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86 +set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86 %TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe -endlocal \ No newline at end of file +endlocal diff --git a/examples/node/package.json b/examples/node/package.json index 2cae031175e..6317838295a 100644 --- a/examples/node/package.json +++ b/examples/node/package.json @@ -3,8 +3,8 @@ "version": "0.1.0", "dependencies": { "async": "^1.5.2", - "google-protobuf": "^3.0.0-alpha.5", - "grpc": "^0.14.0", + "google-protobuf": "^3.0.0", + "grpc": "^1.0.0", "lodash": "^4.6.1", "minimist": "^1.2.0" } diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec index af5ef289464..59fbb5f395f 100644 --- a/examples/objective-c/auth_sample/AuthTestService.podspec +++ b/examples/objective-c/auth_sample/AuthTestService.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' @@ -45,10 +45,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # Files generated by the gRPC plugin @@ -60,4 +56,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist b/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist index 86909d84a31..ff225074238 100644 --- a/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist +++ b/examples/objective-c/auth_sample/Misc/GoogleService-Info.plist @@ -2,9 +2,39 @@ + AD_UNIT_ID_FOR_BANNER_TEST + redacted + AD_UNIT_ID_FOR_INTERSTITIAL_TEST + redacted CLIENT_ID 15087385131-lh9bpkiai9nls53uadju0if6k7un3uih.apps.googleusercontent.com REVERSED_CLIENT_ID com.googleusercontent.apps.15087385131-lh9bpkiai9nls53uadju0if6k7un3uih + API_KEY + redacted + GCM_SENDER_ID + redacted + PLIST_VERSION + 1 + BUNDLE_ID + io.grpc.AuthSample + PROJECT_ID + grpc-authsample + STORAGE_BUCKET + grpc-authsample.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:15087385131:ios:d547168abe3c362f + DATABASE_URL + https://grpc-authsample.firebaseio.com - \ No newline at end of file + diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec index bce6cd51724..96a8e2ee5bc 100644 --- a/examples/objective-c/helloworld/HelloWorld.podspec +++ b/examples/objective-c/helloworld/HelloWorld.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' @@ -45,10 +45,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # Files generated by the gRPC plugin @@ -60,4 +56,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec index e2132507514..768b5bf635c 100644 --- a/examples/objective-c/route_guide/RouteGuide.podspec +++ b/examples/objective-c/route_guide/RouteGuide.podspec @@ -14,7 +14,7 @@ Pod::Spec.new do |s| src = "../../protos" # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0" # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = 'Pods' @@ -45,10 +45,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # Files generated by the gRPC plugin @@ -60,4 +56,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/examples/php/composer.json b/examples/php/composer.json index a8b790b1de1..e6409f87b43 100644 --- a/examples/php/composer.json +++ b/examples/php/composer.json @@ -1,8 +1,7 @@ { "name": "grpc/grpc-demo", "description": "gRPC example for PHP", - "minimum-stability": "dev", "require": { - "grpc/grpc": "v0.15.0" + "grpc/grpc": "v1.0.0" } } diff --git a/examples/php/route_guide/README.md b/examples/php/route_guide/README.md index 4e74a79f136..26f1704f122 100644 --- a/examples/php/route_guide/README.md +++ b/examples/php/route_guide/README.md @@ -1,6 +1,6 @@ #gRPC Basics: PHP sample code The files in this folder are the samples used in [gRPC Basics: PHP][], -a detailed tutorial for using gRPC in Ruby. +a detailed tutorial for using gRPC in PHP. [gRPC Basics: PHP]:http://www.grpc.io/docs/tutorials/basic/php.html diff --git a/examples/php/run_greeter_client.sh b/examples/php/run_greeter_client.sh index 1a6e9ee1010..4d0be4f24f5 100755 --- a/examples/php/run_greeter_client.sh +++ b/examples/php/run_greeter_client.sh @@ -30,5 +30,5 @@ set -e cd $(dirname $0) -php $extension_dir -d extension=grpc.so -d max_execution_time=300 \ +php -d extension=grpc.so -d max_execution_time=300 \ greeter_client.php $1 diff --git a/examples/python/README.md b/examples/python/README.md index 9992baa8421..d801d0dbca7 100644 --- a/examples/python/README.md +++ b/examples/python/README.md @@ -1,56 +1 @@ -gRPC in 3 minutes (Python) -======================== - -Background -------------- -For this sample, we've already generated the server and client stubs from -[helloworld.proto][] and we'll be using a specific reference platform. - - -Install gRPC: -```sh - $ pip install grpcio -``` -Or, to install it system wide: -```sh - $ sudo pip install grpcio -``` - -If you're on Windows, make sure you installed the `pip.exe` component when you -installed Python. Invoke as above but with `pip.exe` instead of `pip` (you may -also need to invoke from a `cmd.exe` ran as administrator): -```sh - $ pip.exe install grpcio -``` - -Download the example -```sh - $ # Clone the repository to get the example code: - $ git clone https://github.com/grpc/grpc - $ # Navigate to the "hello, world" Python example: - $ cd grpc/examples/python/helloworld - ``` - -Try it! -------- - -- Run the server - - ```sh - $ python2.7 greeter_server.py & - ``` - -- Run the client - - ```sh - $ python2.7 greeter_client.py - ``` - -Tutorial --------- - -You can find a more detailed tutorial in [gRPC Basics: Python][] - -[helloworld.proto]:../protos/helloworld.proto -[Install gRPC Python]:../../src/python#installation -[gRPC Basics: Python]:http://www.grpc.io/docs/tutorials/basic/python.html +[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html) diff --git a/examples/python/helloworld/README.md b/examples/python/helloworld/README.md index e889863a23d..d801d0dbca7 100644 --- a/examples/python/helloworld/README.md +++ b/examples/python/helloworld/README.md @@ -1 +1 @@ -[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs) +[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html) diff --git a/examples/python/helloworld/greeter_client.py b/examples/python/helloworld/greeter_client.py index 40d637fb7b4..44d42c102b5 100644 --- a/examples/python/helloworld/greeter_client.py +++ b/examples/python/helloworld/greeter_client.py @@ -31,17 +31,15 @@ from __future__ import print_function -from grpc.beta import implementations +import grpc import helloworld_pb2 -_TIMEOUT_SECONDS = 10 - def run(): - channel = implementations.insecure_channel('localhost', 50051) - stub = helloworld_pb2.beta_create_Greeter_stub(channel) - response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'), _TIMEOUT_SECONDS) + channel = grpc.insecure_channel('localhost:50051') + stub = helloworld_pb2.GreeterStub(channel) + response = stub.SayHello(helloworld_pb2.HelloRequest(name='you')) print("Greeter client received: " + response.message) diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py index 2cde5add435..37d8bd49ccd 100644 --- a/examples/python/helloworld/greeter_server.py +++ b/examples/python/helloworld/greeter_server.py @@ -29,21 +29,25 @@ """The Python implementation of the GRPC helloworld.Greeter server.""" +from concurrent import futures import time +import grpc + import helloworld_pb2 _ONE_DAY_IN_SECONDS = 60 * 60 * 24 -class Greeter(helloworld_pb2.BetaGreeterServicer): +class Greeter(helloworld_pb2.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) def serve(): - server = helloworld_pb2.beta_create_Greeter_server(Greeter()) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() try: diff --git a/examples/python/helloworld/helloworld_pb2.py b/examples/python/helloworld/helloworld_pb2.py index 1ee80e4034c..3ce33fbf2bf 100644 --- a/examples/python/helloworld/helloworld_pb2.py +++ b/examples/python/helloworld/helloworld_pb2.py @@ -107,13 +107,55 @@ _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')) -import abc -import six +import grpc from grpc.beta import implementations as beta_implementations from grpc.beta import interfaces as beta_interfaces from grpc.framework.common import cardinality from grpc.framework.interfaces.face import utilities as face_utilities + +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=HelloRequest.SerializeToString, + response_deserializer=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=HelloRequest.FromString, + response_serializer=HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + class BetaGreeterServicer(object): """The greeting service definition. """ @@ -122,23 +164,23 @@ class BetaGreeterServicer(object): """ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + class BetaGreeterStub(object): """The greeting service definition. """ - def SayHello(self, request, timeout): + def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None): """Sends a greeting """ raise NotImplementedError() SayHello.future = None + def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - import helloworld_pb2 - import helloworld_pb2 request_deserializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloRequest.FromString, + ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString, } response_serializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloReply.SerializeToString, + ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString, } method_implementations = { ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello), @@ -146,14 +188,13 @@ def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_time server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) return beta_implementations.server(method_implementations, options=server_options) + def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - import helloworld_pb2 - import helloworld_pb2 request_serializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloRequest.SerializeToString, + ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString, } response_deserializers = { - ('helloworld.Greeter', 'SayHello'): helloworld_pb2.HelloReply.FromString, + ('helloworld.Greeter', 'SayHello'): HelloReply.FromString, } cardinalities = { 'SayHello': cardinality.Cardinality.UNARY_UNARY, diff --git a/examples/python/route_guide/run_codegen.sh b/examples/python/helloworld/run_codegen.py old mode 100755 new mode 100644 similarity index 86% rename from examples/python/route_guide/run_codegen.sh rename to examples/python/helloworld/run_codegen.py index a377a1ab409..4835ec2b4d2 --- a/examples/python/route_guide/run_codegen.sh +++ b/examples/python/helloworld/run_codegen.py @@ -1,4 +1,3 @@ -#!/bin/bash # Copyright 2015, Google Inc. # All rights reserved. # @@ -28,5 +27,16 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -python -m grpc.tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/route_guide.proto +"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs.""" + +from grpc.tools import protoc + +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/helloworld.proto', + ) +) diff --git a/examples/python/multiplex/.gitignore b/examples/python/multiplex/.gitignore new file mode 100644 index 00000000000..0d20b6487c6 --- /dev/null +++ b/examples/python/multiplex/.gitignore @@ -0,0 +1 @@ +*.pyc diff --git a/examples/python/multiplex/README.md b/examples/python/multiplex/README.md new file mode 100644 index 00000000000..5931be392ac --- /dev/null +++ b/examples/python/multiplex/README.md @@ -0,0 +1,3 @@ +An example showing two stubs sharing a channel and two servicers sharing a server. + +More complete documentation lives at [grpc.io](http://www.grpc.io/docs/tutorials/basic/python.html). diff --git a/examples/python/multiplex/helloworld_pb2.py b/examples/python/multiplex/helloworld_pb2.py new file mode 100644 index 00000000000..3ce33fbf2bf --- /dev/null +++ b/examples/python/multiplex/helloworld_pb2.py @@ -0,0 +1,204 @@ +# 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') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_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 + +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')) +import grpc +from grpc.beta import implementations as beta_implementations +from grpc.beta import interfaces as beta_interfaces +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + + +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=HelloRequest.SerializeToString, + response_deserializer=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=HelloRequest.FromString, + response_serializer=HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class BetaGreeterServicer(object): + """The greeting service definition. + """ + def SayHello(self, request, context): + """Sends a greeting + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + + +class BetaGreeterStub(object): + """The greeting service definition. + """ + def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """Sends a greeting + """ + raise NotImplementedError() + SayHello.future = None + + +def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): + request_deserializers = { + ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString, + } + response_serializers = { + ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString, + } + method_implementations = { + ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello), + } + server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) + return beta_implementations.server(method_implementations, options=server_options) + + +def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): + request_serializers = { + ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString, + } + response_deserializers = { + ('helloworld.Greeter', 'SayHello'): HelloReply.FromString, + } + cardinalities = { + 'SayHello': cardinality.Cardinality.UNARY_UNARY, + } + stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) + return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options) +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/multiplex/multiplex_client.py b/examples/python/multiplex/multiplex_client.py new file mode 100644 index 00000000000..2e8162926b7 --- /dev/null +++ b/examples/python/multiplex/multiplex_client.py @@ -0,0 +1,139 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""A client that makes both Greeter and RouteGuide RPCs.""" + +from __future__ import print_function + +import random +import time + +import grpc + +import helloworld_pb2 +import route_guide_pb2 +import route_guide_resources + + +def make_route_note(message, latitude, longitude): + return route_guide_pb2.RouteNote( + message=message, + location=route_guide_pb2.Point(latitude=latitude, longitude=longitude)) + + +def guide_get_one_feature(route_guide_stub, point): + feature = route_guide_stub.GetFeature(point) + if not feature.location: + print("Server returned incomplete feature") + return + + if feature.name: + print("Feature called %s at %s" % (feature.name, feature.location)) + else: + print("Found no feature at %s" % feature.location) + + +def guide_get_feature(route_guide_stub): + guide_get_one_feature( + route_guide_stub, + route_guide_pb2.Point(latitude=409146138, longitude=-746188906)) + guide_get_one_feature( + route_guide_stub, route_guide_pb2.Point(latitude=0, longitude=0)) + + +def guide_list_features(route_guide_stub): + rectangle = route_guide_pb2.Rectangle( + lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000), + hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000)) + print("Looking for features between 40, -75 and 42, -73") + + features = route_guide_stub.ListFeatures(rectangle) + + for feature in features: + print("Feature called %s at %s" % (feature.name, feature.location)) + + +def generate_route(feature_list): + for _ in range(0, 10): + random_feature = feature_list[random.randint(0, len(feature_list) - 1)] + print("Visiting point %s" % random_feature.location) + yield random_feature.location + time.sleep(random.uniform(0.5, 1.5)) + + +def guide_record_route(route_guide_stub): + feature_list = route_guide_resources.read_route_guide_database() + + route_iterator = generate_route(feature_list) + route_summary = route_guide_stub.RecordRoute(route_iterator) + print("Finished trip with %s points " % route_summary.point_count) + print("Passed %s features " % route_summary.feature_count) + print("Travelled %s meters " % route_summary.distance) + print("It took %s seconds " % route_summary.elapsed_time) + + +def generate_messages(): + messages = [ + make_route_note("First message", 0, 0), + make_route_note("Second message", 0, 1), + make_route_note("Third message", 1, 0), + make_route_note("Fourth message", 0, 0), + make_route_note("Fifth message", 1, 0), + ] + for msg in messages: + print("Sending %s at %s" % (msg.message, msg.location)) + yield msg + time.sleep(random.uniform(0.5, 1.0)) + + +def guide_route_chat(route_guide_stub): + responses = route_guide_stub.RouteChat(generate_messages()) + for response in responses: + print("Received message %s at %s" % (response.message, response.location)) + + +def run(): + channel = grpc.insecure_channel('localhost:50051') + greeter_stub = helloworld_pb2.GreeterStub(channel) + route_guide_stub = route_guide_pb2.RouteGuideStub(channel) + greeter_response = greeter_stub.SayHello( + helloworld_pb2.HelloRequest(name='you')) + print("Greeter client received: " + greeter_response.message) + print("-------------- GetFeature --------------") + guide_get_feature(route_guide_stub) + print("-------------- ListFeatures --------------") + guide_list_features(route_guide_stub) + print("-------------- RecordRoute --------------") + guide_record_route(route_guide_stub) + print("-------------- RouteChat --------------") + guide_route_chat(route_guide_stub) + + +if __name__ == '__main__': + run() diff --git a/examples/python/multiplex/multiplex_server.py b/examples/python/multiplex/multiplex_server.py new file mode 100644 index 00000000000..32a4ee4a497 --- /dev/null +++ b/examples/python/multiplex/multiplex_server.py @@ -0,0 +1,149 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""A gRPC server servicing both Greeter and RouteGuide RPCs.""" + +from concurrent import futures +import time +import math + +import grpc + +import helloworld_pb2 +import route_guide_pb2 +import route_guide_resources + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def _get_feature(feature_db, point): + """Returns Feature at given location or None.""" + for feature in feature_db: + if feature.location == point: + return feature + return None + + +def _get_distance(start, end): + """Distance between two points.""" + coord_factor = 10000000.0 + lat_1 = start.latitude / coord_factor + lat_2 = end.latitude / coord_factor + lon_1 = start.longitude / coord_factor + lon_2 = end.longitude / coord_factor + lat_rad_1 = math.radians(lat_1) + lat_rad_2 = math.radians(lat_2) + delta_lat_rad = math.radians(lat_2 - lat_1) + delta_lon_rad = math.radians(lon_2 - lon_1) + + a = (pow(math.sin(delta_lat_rad / 2), 2) + + (math.cos(lat_rad_1) * math.cos(lat_rad_2) * + pow(math.sin(delta_lon_rad / 2), 2))) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + R = 6371000; # metres + return R * c; + + +class _GreeterServicer(helloworld_pb2.GreeterServicer): + + def SayHello(self, request, context): + return helloworld_pb2.HelloReply(message='Hello, {}!'.format(request.name)) + + +class _RouteGuideServicer(route_guide_pb2.RouteGuideServicer): + """Provides methods that implement functionality of route guide server.""" + + def __init__(self): + self.db = route_guide_resources.read_route_guide_database() + + def GetFeature(self, request, context): + feature = _get_feature(self.db, request) + if feature is None: + return route_guide_pb2.Feature(name="", location=request) + else: + return feature + + def ListFeatures(self, request, context): + left = min(request.lo.longitude, request.hi.longitude) + right = max(request.lo.longitude, request.hi.longitude) + top = max(request.lo.latitude, request.hi.latitude) + bottom = min(request.lo.latitude, request.hi.latitude) + for feature in self.db: + if (feature.location.longitude >= left and + feature.location.longitude <= right and + feature.location.latitude >= bottom and + feature.location.latitude <= top): + yield feature + + def RecordRoute(self, request_iterator, context): + point_count = 0 + feature_count = 0 + distance = 0.0 + prev_point = None + + start_time = time.time() + for point in request_iterator: + point_count += 1 + if _get_feature(self.db, point): + feature_count += 1 + if prev_point: + distance += _get_distance(prev_point, point) + prev_point = point + + elapsed_time = time.time() - start_time + return route_guide_pb2.RouteSummary(point_count=point_count, + feature_count=feature_count, + distance=int(distance), + elapsed_time=int(elapsed_time)) + + def RouteChat(self, request_iterator, context): + prev_notes = [] + for new_note in request_iterator: + for prev_note in prev_notes: + if prev_note.location == new_note.location: + yield prev_note + prev_notes.append(new_note) + + +def serve(): + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + helloworld_pb2.add_GreeterServicer_to_server(_GreeterServicer(), server) + route_guide_pb2.add_RouteGuideServicer_to_server( + _RouteGuideServicer(), 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__': + serve() diff --git a/examples/python/multiplex/route_guide_db.json b/examples/python/multiplex/route_guide_db.json new file mode 100644 index 00000000000..9d6a980ab7d --- /dev/null +++ b/examples/python/multiplex/route_guide_db.json @@ -0,0 +1,601 @@ +[{ + "location": { + "latitude": 407838351, + "longitude": -746143763 + }, + "name": "Patriots Path, Mendham, NJ 07945, USA" +}, { + "location": { + "latitude": 408122808, + "longitude": -743999179 + }, + "name": "101 New Jersey 10, Whippany, NJ 07981, USA" +}, { + "location": { + "latitude": 413628156, + "longitude": -749015468 + }, + "name": "U.S. 6, Shohola, PA 18458, USA" +}, { + "location": { + "latitude": 419999544, + "longitude": -740371136 + }, + "name": "5 Conners Road, Kingston, NY 12401, USA" +}, { + "location": { + "latitude": 414008389, + "longitude": -743951297 + }, + "name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA" +}, { + "location": { + "latitude": 419611318, + "longitude": -746524769 + }, + "name": "287 Flugertown Road, Livingston Manor, NY 12758, USA" +}, { + "location": { + "latitude": 406109563, + "longitude": -742186778 + }, + "name": "4001 Tremley Point Road, Linden, NJ 07036, USA" +}, { + "location": { + "latitude": 416802456, + "longitude": -742370183 + }, + "name": "352 South Mountain Road, Wallkill, NY 12589, USA" +}, { + "location": { + "latitude": 412950425, + "longitude": -741077389 + }, + "name": "Bailey Turn Road, Harriman, NY 10926, USA" +}, { + "location": { + "latitude": 412144655, + "longitude": -743949739 + }, + "name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA" +}, { + "location": { + "latitude": 415736605, + "longitude": -742847522 + }, + "name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA" +}, { + "location": { + "latitude": 413843930, + "longitude": -740501726 + }, + "name": "162 Merrill Road, Highland Mills, NY 10930, USA" +}, { + "location": { + "latitude": 410873075, + "longitude": -744459023 + }, + "name": "Clinton Road, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 412346009, + "longitude": -744026814 + }, + "name": "16 Old Brook Lane, Warwick, NY 10990, USA" +}, { + "location": { + "latitude": 402948455, + "longitude": -747903913 + }, + "name": "3 Drake Lane, Pennington, NJ 08534, USA" +}, { + "location": { + "latitude": 406337092, + "longitude": -740122226 + }, + "name": "6324 8th Avenue, Brooklyn, NY 11220, USA" +}, { + "location": { + "latitude": 406421967, + "longitude": -747727624 + }, + "name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA" +}, { + "location": { + "latitude": 416318082, + "longitude": -749677716 + }, + "name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA" +}, { + "location": { + "latitude": 415301720, + "longitude": -748416257 + }, + "name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA" +}, { + "location": { + "latitude": 402647019, + "longitude": -747071791 + }, + "name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA" +}, { + "location": { + "latitude": 412567807, + "longitude": -741058078 + }, + "name": "New York State Reference Route 987E, Southfields, NY 10975, USA" +}, { + "location": { + "latitude": 416855156, + "longitude": -744420597 + }, + "name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA" +}, { + "location": { + "latitude": 404663628, + "longitude": -744820157 + }, + "name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA" +}, { + "location": { + "latitude": 407113723, + "longitude": -749746483 + }, + "name": "" +}, { + "location": { + "latitude": 402133926, + "longitude": -743613249 + }, + "name": "" +}, { + "location": { + "latitude": 400273442, + "longitude": -741220915 + }, + "name": "" +}, { + "location": { + "latitude": 411236786, + "longitude": -744070769 + }, + "name": "" +}, { + "location": { + "latitude": 411633782, + "longitude": -746784970 + }, + "name": "211-225 Plains Road, Augusta, NJ 07822, USA" +}, { + "location": { + "latitude": 415830701, + "longitude": -742952812 + }, + "name": "" +}, { + "location": { + "latitude": 413447164, + "longitude": -748712898 + }, + "name": "165 Pedersen Ridge Road, Milford, PA 18337, USA" +}, { + "location": { + "latitude": 405047245, + "longitude": -749800722 + }, + "name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA" +}, { + "location": { + "latitude": 418858923, + "longitude": -746156790 + }, + "name": "" +}, { + "location": { + "latitude": 417951888, + "longitude": -748484944 + }, + "name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA" +}, { + "location": { + "latitude": 407033786, + "longitude": -743977337 + }, + "name": "26 East 3rd Street, New Providence, NJ 07974, USA" +}, { + "location": { + "latitude": 417548014, + "longitude": -740075041 + }, + "name": "" +}, { + "location": { + "latitude": 410395868, + "longitude": -744972325 + }, + "name": "" +}, { + "location": { + "latitude": 404615353, + "longitude": -745129803 + }, + "name": "" +}, { + "location": { + "latitude": 406589790, + "longitude": -743560121 + }, + "name": "611 Lawrence Avenue, Westfield, NJ 07090, USA" +}, { + "location": { + "latitude": 414653148, + "longitude": -740477477 + }, + "name": "18 Lannis Avenue, New Windsor, NY 12553, USA" +}, { + "location": { + "latitude": 405957808, + "longitude": -743255336 + }, + "name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA" +}, { + "location": { + "latitude": 411733589, + "longitude": -741648093 + }, + "name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA" +}, { + "location": { + "latitude": 412676291, + "longitude": -742606606 + }, + "name": "1270 Lakes Road, Monroe, NY 10950, USA" +}, { + "location": { + "latitude": 409224445, + "longitude": -748286738 + }, + "name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA" +}, { + "location": { + "latitude": 406523420, + "longitude": -742135517 + }, + "name": "652 Garden Street, Elizabeth, NJ 07202, USA" +}, { + "location": { + "latitude": 401827388, + "longitude": -740294537 + }, + "name": "349 Sea Spray Court, Neptune City, NJ 07753, USA" +}, { + "location": { + "latitude": 410564152, + "longitude": -743685054 + }, + "name": "13-17 Stanley Street, West Milford, NJ 07480, USA" +}, { + "location": { + "latitude": 408472324, + "longitude": -740726046 + }, + "name": "47 Industrial Avenue, Teterboro, NJ 07608, USA" +}, { + "location": { + "latitude": 412452168, + "longitude": -740214052 + }, + "name": "5 White Oak Lane, Stony Point, NY 10980, USA" +}, { + "location": { + "latitude": 409146138, + "longitude": -746188906 + }, + "name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA" +}, { + "location": { + "latitude": 404701380, + "longitude": -744781745 + }, + "name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 409642566, + "longitude": -746017679 + }, + "name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA" +}, { + "location": { + "latitude": 408031728, + "longitude": -748645385 + }, + "name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA" +}, { + "location": { + "latitude": 413700272, + "longitude": -742135189 + }, + "name": "367 Prospect Road, Chester, NY 10918, USA" +}, { + "location": { + "latitude": 404310607, + "longitude": -740282632 + }, + "name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA" +}, { + "location": { + "latitude": 409319800, + "longitude": -746201391 + }, + "name": "11 Ward Street, Mount Arlington, NJ 07856, USA" +}, { + "location": { + "latitude": 406685311, + "longitude": -742108603 + }, + "name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA" +}, { + "location": { + "latitude": 419018117, + "longitude": -749142781 + }, + "name": "43 Dreher Road, Roscoe, NY 12776, USA" +}, { + "location": { + "latitude": 412856162, + "longitude": -745148837 + }, + "name": "Swan Street, Pine Island, NY 10969, USA" +}, { + "location": { + "latitude": 416560744, + "longitude": -746721964 + }, + "name": "66 Pleasantview Avenue, Monticello, NY 12701, USA" +}, { + "location": { + "latitude": 405314270, + "longitude": -749836354 + }, + "name": "" +}, { + "location": { + "latitude": 414219548, + "longitude": -743327440 + }, + "name": "" +}, { + "location": { + "latitude": 415534177, + "longitude": -742900616 + }, + "name": "565 Winding Hills Road, Montgomery, NY 12549, USA" +}, { + "location": { + "latitude": 406898530, + "longitude": -749127080 + }, + "name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA" +}, { + "location": { + "latitude": 407586880, + "longitude": -741670168 + }, + "name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA" +}, { + "location": { + "latitude": 400106455, + "longitude": -742870190 + }, + "name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA" +}, { + "location": { + "latitude": 400066188, + "longitude": -746793294 + }, + "name": "" +}, { + "location": { + "latitude": 418803880, + "longitude": -744102673 + }, + "name": "40 Mountain Road, Napanoch, NY 12458, USA" +}, { + "location": { + "latitude": 414204288, + "longitude": -747895140 + }, + "name": "" +}, { + "location": { + "latitude": 414777405, + "longitude": -740615601 + }, + "name": "" +}, { + "location": { + "latitude": 415464475, + "longitude": -747175374 + }, + "name": "48 North Road, Forestburgh, NY 12777, USA" +}, { + "location": { + "latitude": 404062378, + "longitude": -746376177 + }, + "name": "" +}, { + "location": { + "latitude": 405688272, + "longitude": -749285130 + }, + "name": "" +}, { + "location": { + "latitude": 400342070, + "longitude": -748788996 + }, + "name": "" +}, { + "location": { + "latitude": 401809022, + "longitude": -744157964 + }, + "name": "" +}, { + "location": { + "latitude": 404226644, + "longitude": -740517141 + }, + "name": "9 Thompson Avenue, Leonardo, NJ 07737, USA" +}, { + "location": { + "latitude": 410322033, + "longitude": -747871659 + }, + "name": "" +}, { + "location": { + "latitude": 407100674, + "longitude": -747742727 + }, + "name": "" +}, { + "location": { + "latitude": 418811433, + "longitude": -741718005 + }, + "name": "213 Bush Road, Stone Ridge, NY 12484, USA" +}, { + "location": { + "latitude": 415034302, + "longitude": -743850945 + }, + "name": "" +}, { + "location": { + "latitude": 411349992, + "longitude": -743694161 + }, + "name": "" +}, { + "location": { + "latitude": 404839914, + "longitude": -744759616 + }, + "name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA" +}, { + "location": { + "latitude": 414638017, + "longitude": -745957854 + }, + "name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA" +}, { + "location": { + "latitude": 412127800, + "longitude": -740173578 + }, + "name": "" +}, { + "location": { + "latitude": 401263460, + "longitude": -747964303 + }, + "name": "" +}, { + "location": { + "latitude": 412843391, + "longitude": -749086026 + }, + "name": "" +}, { + "location": { + "latitude": 418512773, + "longitude": -743067823 + }, + "name": "" +}, { + "location": { + "latitude": 404318328, + "longitude": -740835638 + }, + "name": "42-102 Main Street, Belford, NJ 07718, USA" +}, { + "location": { + "latitude": 419020746, + "longitude": -741172328 + }, + "name": "" +}, { + "location": { + "latitude": 404080723, + "longitude": -746119569 + }, + "name": "" +}, { + "location": { + "latitude": 401012643, + "longitude": -744035134 + }, + "name": "" +}, { + "location": { + "latitude": 404306372, + "longitude": -741079661 + }, + "name": "" +}, { + "location": { + "latitude": 403966326, + "longitude": -748519297 + }, + "name": "" +}, { + "location": { + "latitude": 405002031, + "longitude": -748407866 + }, + "name": "" +}, { + "location": { + "latitude": 409532885, + "longitude": -742200683 + }, + "name": "" +}, { + "location": { + "latitude": 416851321, + "longitude": -742674555 + }, + "name": "" +}, { + "location": { + "latitude": 406411633, + "longitude": -741722051 + }, + "name": "3387 Richmond Terrace, Staten Island, NY 10303, USA" +}, { + "location": { + "latitude": 413069058, + "longitude": -744597778 + }, + "name": "261 Van Sickle Road, Goshen, NY 10924, USA" +}, { + "location": { + "latitude": 418465462, + "longitude": -746859398 + }, + "name": "" +}, { + "location": { + "latitude": 411733222, + "longitude": -744228360 + }, + "name": "" +}, { + "location": { + "latitude": 410248224, + "longitude": -747127767 + }, + "name": "3 Hasta Way, Newton, NJ 07860, USA" +}] diff --git a/examples/python/multiplex/route_guide_pb2.py b/examples/python/multiplex/route_guide_pb2.py new file mode 100644 index 00000000000..924e186e06e --- /dev/null +++ b/examples/python/multiplex/route_guide_pb2.py @@ -0,0 +1,516 @@ +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: route_guide.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='route_guide.proto', + package='routeguide', + syntax='proto3', + serialized_pb=_b('\n\x11route_guide.proto\x12\nrouteguide\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"I\n\tRectangle\x12\x1d\n\x02lo\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x1d\n\x02hi\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"<\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x08location\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"A\n\tRouteNote\x12#\n\x08location\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\x85\x02\n\nRouteGuide\x12\x36\n\nGetFeature\x12\x11.routeguide.Point\x1a\x13.routeguide.Feature\"\x00\x12>\n\x0cListFeatures\x12\x15.routeguide.Rectangle\x1a\x13.routeguide.Feature\"\x00\x30\x01\x12>\n\x0bRecordRoute\x12\x11.routeguide.Point\x1a\x18.routeguide.RouteSummary\"\x00(\x01\x12?\n\tRouteChat\x12\x15.routeguide.RouteNote\x1a\x15.routeguide.RouteNote\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.routeguideB\x0fRouteGuideProtoP\x01\xa2\x02\x03RTGb\x06proto3') +) +_sym_db.RegisterFileDescriptor(DESCRIPTOR) + + + + +_POINT = _descriptor.Descriptor( + name='Point', + full_name='routeguide.Point', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='latitude', full_name='routeguide.Point.latitude', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='longitude', full_name='routeguide.Point.longitude', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + 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=33, + serialized_end=77, +) + + +_RECTANGLE = _descriptor.Descriptor( + name='Rectangle', + full_name='routeguide.Rectangle', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='lo', full_name='routeguide.Rectangle.lo', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='hi', full_name='routeguide.Rectangle.hi', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + 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=79, + serialized_end=152, +) + + +_FEATURE = _descriptor.Descriptor( + name='Feature', + full_name='routeguide.Feature', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='name', full_name='routeguide.Feature.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), + _descriptor.FieldDescriptor( + name='location', full_name='routeguide.Feature.location', index=1, + number=2, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + 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=154, + serialized_end=214, +) + + +_ROUTENOTE = _descriptor.Descriptor( + name='RouteNote', + full_name='routeguide.RouteNote', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='location', full_name='routeguide.RouteNote.location', index=0, + number=1, type=11, cpp_type=10, label=1, + has_default_value=False, default_value=None, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='message', full_name='routeguide.RouteNote.message', index=1, + number=2, 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=216, + serialized_end=281, +) + + +_ROUTESUMMARY = _descriptor.Descriptor( + name='RouteSummary', + full_name='routeguide.RouteSummary', + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name='point_count', full_name='routeguide.RouteSummary.point_count', index=0, + number=1, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='feature_count', full_name='routeguide.RouteSummary.feature_count', index=1, + number=2, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='distance', full_name='routeguide.RouteSummary.distance', index=2, + number=3, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + message_type=None, enum_type=None, containing_type=None, + is_extension=False, extension_scope=None, + options=None), + _descriptor.FieldDescriptor( + name='elapsed_time', full_name='routeguide.RouteSummary.elapsed_time', index=3, + number=4, type=5, cpp_type=1, label=1, + has_default_value=False, default_value=0, + 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=283, + serialized_end=381, +) + +_RECTANGLE.fields_by_name['lo'].message_type = _POINT +_RECTANGLE.fields_by_name['hi'].message_type = _POINT +_FEATURE.fields_by_name['location'].message_type = _POINT +_ROUTENOTE.fields_by_name['location'].message_type = _POINT +DESCRIPTOR.message_types_by_name['Point'] = _POINT +DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE +DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE +DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE +DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY + +Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict( + DESCRIPTOR = _POINT, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.Point) + )) +_sym_db.RegisterMessage(Point) + +Rectangle = _reflection.GeneratedProtocolMessageType('Rectangle', (_message.Message,), dict( + DESCRIPTOR = _RECTANGLE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.Rectangle) + )) +_sym_db.RegisterMessage(Rectangle) + +Feature = _reflection.GeneratedProtocolMessageType('Feature', (_message.Message,), dict( + DESCRIPTOR = _FEATURE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.Feature) + )) +_sym_db.RegisterMessage(Feature) + +RouteNote = _reflection.GeneratedProtocolMessageType('RouteNote', (_message.Message,), dict( + DESCRIPTOR = _ROUTENOTE, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.RouteNote) + )) +_sym_db.RegisterMessage(RouteNote) + +RouteSummary = _reflection.GeneratedProtocolMessageType('RouteSummary', (_message.Message,), dict( + DESCRIPTOR = _ROUTESUMMARY, + __module__ = 'route_guide_pb2' + # @@protoc_insertion_point(class_scope:routeguide.RouteSummary) + )) +_sym_db.RegisterMessage(RouteSummary) + + +DESCRIPTOR.has_options = True +DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG')) +import grpc +from grpc.beta import implementations as beta_implementations +from grpc.beta import interfaces as beta_interfaces +from grpc.framework.common import cardinality +from grpc.framework.interfaces.face import utilities as face_utilities + + +class RouteGuideStub(object): + """Interface exported by the server. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetFeature = channel.unary_unary( + '/routeguide.RouteGuide/GetFeature', + request_serializer=Point.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.ListFeatures = channel.unary_stream( + '/routeguide.RouteGuide/ListFeatures', + request_serializer=Rectangle.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.RecordRoute = channel.stream_unary( + '/routeguide.RouteGuide/RecordRoute', + request_serializer=Point.SerializeToString, + response_deserializer=RouteSummary.FromString, + ) + self.RouteChat = channel.stream_stream( + '/routeguide.RouteGuide/RouteChat', + request_serializer=RouteNote.SerializeToString, + response_deserializer=RouteNote.FromString, + ) + + +class RouteGuideServicer(object): + """Interface exported by the server. + """ + + def GetFeature(self, request, context): + """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. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListFeatures(self, request, context): + """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. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RecordRoute(self, request_iterator, context): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RouteChat(self, request_iterator, context): + """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). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_RouteGuideServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetFeature': grpc.unary_unary_rpc_method_handler( + servicer.GetFeature, + request_deserializer=Point.FromString, + response_serializer=Feature.SerializeToString, + ), + 'ListFeatures': grpc.unary_stream_rpc_method_handler( + servicer.ListFeatures, + request_deserializer=Rectangle.FromString, + response_serializer=Feature.SerializeToString, + ), + 'RecordRoute': grpc.stream_unary_rpc_method_handler( + servicer.RecordRoute, + request_deserializer=Point.FromString, + response_serializer=RouteSummary.SerializeToString, + ), + 'RouteChat': grpc.stream_stream_rpc_method_handler( + servicer.RouteChat, + request_deserializer=RouteNote.FromString, + response_serializer=RouteNote.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'routeguide.RouteGuide', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + +class BetaRouteGuideServicer(object): + """Interface exported by the server. + """ + def GetFeature(self, request, context): + """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. + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def ListFeatures(self, request, context): + """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. + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def RecordRoute(self, request_iterator, context): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + def RouteChat(self, request_iterator, context): + """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). + """ + context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + + +class BetaRouteGuideStub(object): + """Interface exported by the server. + """ + def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """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. + """ + raise NotImplementedError() + GetFeature.future = None + def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None): + """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. + """ + raise NotImplementedError() + def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + raise NotImplementedError() + RecordRoute.future = None + def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): + """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). + """ + raise NotImplementedError() + + +def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): + request_deserializers = { + ('routeguide.RouteGuide', 'GetFeature'): Point.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, + } + response_serializers = { + ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, + } + method_implementations = { + ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature), + ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures), + ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute), + ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat), + } + server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) + return beta_implementations.server(method_implementations, options=server_options) + + +def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): + request_serializers = { + ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, + } + response_deserializers = { + ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, + } + cardinalities = { + 'GetFeature': cardinality.Cardinality.UNARY_UNARY, + 'ListFeatures': cardinality.Cardinality.UNARY_STREAM, + 'RecordRoute': cardinality.Cardinality.STREAM_UNARY, + 'RouteChat': cardinality.Cardinality.STREAM_STREAM, + } + stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size) + return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options) +# @@protoc_insertion_point(module_scope) diff --git a/examples/python/multiplex/route_guide_resources.py b/examples/python/multiplex/route_guide_resources.py new file mode 100644 index 00000000000..30c7711019f --- /dev/null +++ b/examples/python/multiplex/route_guide_resources.py @@ -0,0 +1,53 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Common resources used in the gRPC route guide example.""" + +import json + +import route_guide_pb2 + + +def read_route_guide_database(): + """Reads the route guide database. + + Returns: + The full contents of the route guide database as a sequence of + route_guide_pb2.Features. + """ + feature_list = [] + with open("route_guide_db.json") as route_guide_db_file: + for item in json.load(route_guide_db_file): + feature = route_guide_pb2.Feature( + name=item["name"], + location=route_guide_pb2.Point( + latitude=item["location"]["latitude"], + longitude=item["location"]["longitude"])) + feature_list.append(feature) + return feature_list diff --git a/examples/python/multiplex/run_codegen.py b/examples/python/multiplex/run_codegen.py new file mode 100755 index 00000000000..7922a0f5c7f --- /dev/null +++ b/examples/python/multiplex/run_codegen.py @@ -0,0 +1,51 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Generates protocol messages and gRPC stubs.""" + +from grpc.tools import protoc + +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/helloworld.proto', + ) +) +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/route_guide.proto', + ) +) diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py index ffcbd061d6e..8a80ed892de 100644 --- a/examples/python/route_guide/route_guide_client.py +++ b/examples/python/route_guide/route_guide_client.py @@ -34,13 +34,11 @@ from __future__ import print_function import random import time -from grpc.beta import implementations +import grpc import route_guide_pb2 import route_guide_resources -_TIMEOUT_SECONDS = 30 - def make_route_note(message, latitude, longitude): return route_guide_pb2.RouteNote( @@ -49,7 +47,7 @@ def make_route_note(message, latitude, longitude): def guide_get_one_feature(stub, point): - feature = stub.GetFeature(point, _TIMEOUT_SECONDS) + feature = stub.GetFeature(point) if not feature.location: print("Server returned incomplete feature") return @@ -66,14 +64,12 @@ def guide_get_feature(stub): def guide_list_features(stub): - rect = route_guide_pb2.Rectangle( - lo=route_guide_pb2.Point( - latitude=400000000, longitude = -750000000), - hi=route_guide_pb2.Point( - latitude = 420000000, longitude = -730000000)) + rectangle = route_guide_pb2.Rectangle( + lo=route_guide_pb2.Point(latitude=400000000, longitude=-750000000), + hi=route_guide_pb2.Point(latitude=420000000, longitude=-730000000)) print("Looking for features between 40, -75 and 42, -73") - features = stub.ListFeatures(rect, _TIMEOUT_SECONDS) + features = stub.ListFeatures(rectangle) for feature in features: print("Feature called %s at %s" % (feature.name, feature.location)) @@ -90,8 +86,8 @@ def generate_route(feature_list): def guide_record_route(stub): feature_list = route_guide_resources.read_route_guide_database() - route_iter = generate_route(feature_list) - route_summary = stub.RecordRoute(route_iter, _TIMEOUT_SECONDS) + route_iterator = generate_route(feature_list) + route_summary = stub.RecordRoute(route_iterator) print("Finished trip with %s points " % route_summary.point_count) print("Passed %s features " % route_summary.feature_count) print("Travelled %s meters " % route_summary.distance) @@ -113,14 +109,14 @@ def generate_messages(): def guide_route_chat(stub): - responses = stub.RouteChat(generate_messages(), _TIMEOUT_SECONDS) + responses = stub.RouteChat(generate_messages()) for response in responses: print("Received message %s at %s" % (response.message, response.location)) def run(): - channel = implementations.insecure_channel('localhost', 50051) - stub = route_guide_pb2.beta_create_RouteGuide_stub(channel) + channel = grpc.insecure_channel('localhost:50051') + stub = route_guide_pb2.RouteGuideStub(channel) print("-------------- GetFeature --------------") guide_get_feature(stub) print("-------------- ListFeatures --------------") diff --git a/examples/python/route_guide/route_guide_pb2.py b/examples/python/route_guide/route_guide_pb2.py index 81d5d075274..924e186e06e 100644 --- a/examples/python/route_guide/route_guide_pb2.py +++ b/examples/python/route_guide/route_guide_pb2.py @@ -277,13 +277,122 @@ _sym_db.RegisterMessage(RouteSummary) DESCRIPTOR.has_options = True DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG')) -import abc -import six +import grpc from grpc.beta import implementations as beta_implementations from grpc.beta import interfaces as beta_interfaces from grpc.framework.common import cardinality from grpc.framework.interfaces.face import utilities as face_utilities + +class RouteGuideStub(object): + """Interface exported by the server. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetFeature = channel.unary_unary( + '/routeguide.RouteGuide/GetFeature', + request_serializer=Point.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.ListFeatures = channel.unary_stream( + '/routeguide.RouteGuide/ListFeatures', + request_serializer=Rectangle.SerializeToString, + response_deserializer=Feature.FromString, + ) + self.RecordRoute = channel.stream_unary( + '/routeguide.RouteGuide/RecordRoute', + request_serializer=Point.SerializeToString, + response_deserializer=RouteSummary.FromString, + ) + self.RouteChat = channel.stream_stream( + '/routeguide.RouteGuide/RouteChat', + request_serializer=RouteNote.SerializeToString, + response_deserializer=RouteNote.FromString, + ) + + +class RouteGuideServicer(object): + """Interface exported by the server. + """ + + def GetFeature(self, request, context): + """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. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListFeatures(self, request, context): + """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. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RecordRoute(self, request_iterator, context): + """A client-to-server streaming RPC. + + Accepts a stream of Points on a route being traversed, returning a + RouteSummary when traversal is completed. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def RouteChat(self, request_iterator, context): + """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). + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_RouteGuideServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetFeature': grpc.unary_unary_rpc_method_handler( + servicer.GetFeature, + request_deserializer=Point.FromString, + response_serializer=Feature.SerializeToString, + ), + 'ListFeatures': grpc.unary_stream_rpc_method_handler( + servicer.ListFeatures, + request_deserializer=Rectangle.FromString, + response_serializer=Feature.SerializeToString, + ), + 'RecordRoute': grpc.stream_unary_rpc_method_handler( + servicer.RecordRoute, + request_deserializer=Point.FromString, + response_serializer=RouteSummary.SerializeToString, + ), + 'RouteChat': grpc.stream_stream_rpc_method_handler( + servicer.RouteChat, + request_deserializer=RouteNote.FromString, + response_serializer=RouteNote.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'routeguide.RouteGuide', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + class BetaRouteGuideServicer(object): """Interface exported by the server. """ @@ -320,10 +429,11 @@ class BetaRouteGuideServicer(object): """ context.code(beta_interfaces.StatusCode.UNIMPLEMENTED) + class BetaRouteGuideStub(object): """Interface exported by the server. """ - def GetFeature(self, request, timeout): + def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None): """A simple RPC. Obtains the feature at a given position. @@ -333,7 +443,7 @@ class BetaRouteGuideStub(object): """ raise NotImplementedError() GetFeature.future = None - def ListFeatures(self, request, timeout): + def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None): """A server-to-client streaming RPC. Obtains the Features available within the given Rectangle. Results are @@ -342,7 +452,7 @@ class BetaRouteGuideStub(object): huge number of features. """ raise NotImplementedError() - def RecordRoute(self, request_iterator, timeout): + def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): """A client-to-server streaming RPC. Accepts a stream of Points on a route being traversed, returning a @@ -350,7 +460,7 @@ class BetaRouteGuideStub(object): """ raise NotImplementedError() RecordRoute.future = None - def RouteChat(self, request_iterator, timeout): + def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None): """A Bidirectional streaming RPC. Accepts a stream of RouteNotes sent while a route is being traversed, @@ -358,26 +468,19 @@ class BetaRouteGuideStub(object): """ raise NotImplementedError() + def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None): - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 request_deserializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Point.FromString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Rectangle.FromString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.Point.FromString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.FromString, + ('routeguide.RouteGuide', 'GetFeature'): Point.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, } response_serializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Feature.SerializeToString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Feature.SerializeToString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.RouteSummary.SerializeToString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.SerializeToString, + ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, } method_implementations = { ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature), @@ -388,26 +491,19 @@ def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_t server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout) return beta_implementations.server(method_implementations, options=server_options) + def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None): - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 - import route_guide_pb2 request_serializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Point.SerializeToString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Rectangle.SerializeToString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.Point.SerializeToString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.SerializeToString, + ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString, + ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString, + ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString, } response_deserializers = { - ('routeguide.RouteGuide', 'GetFeature'): route_guide_pb2.Feature.FromString, - ('routeguide.RouteGuide', 'ListFeatures'): route_guide_pb2.Feature.FromString, - ('routeguide.RouteGuide', 'RecordRoute'): route_guide_pb2.RouteSummary.FromString, - ('routeguide.RouteGuide', 'RouteChat'): route_guide_pb2.RouteNote.FromString, + ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString, + ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString, + ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString, + ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString, } cardinalities = { 'GetFeature': cardinality.Cardinality.UNARY_UNARY, diff --git a/examples/python/route_guide/route_guide_resources.py b/examples/python/route_guide/route_guide_resources.py old mode 100755 new mode 100644 diff --git a/examples/python/route_guide/route_guide_server.py b/examples/python/route_guide/route_guide_server.py index 2d8b33ac178..3ffe6784768 100644 --- a/examples/python/route_guide/route_guide_server.py +++ b/examples/python/route_guide/route_guide_server.py @@ -29,9 +29,12 @@ """The Python implementation of the gRPC route guide server.""" +from concurrent import futures import time import math +import grpc + import route_guide_pb2 import route_guide_resources @@ -65,7 +68,7 @@ def get_distance(start, end): R = 6371000; # metres return R * c; -class RouteGuideServicer(route_guide_pb2.BetaRouteGuideServicer): +class RouteGuideServicer(route_guide_pb2.RouteGuideServicer): """Provides methods that implement functionality of route guide server.""" def __init__(self): @@ -121,7 +124,9 @@ class RouteGuideServicer(route_guide_pb2.BetaRouteGuideServicer): def serve(): - server = route_guide_pb2.beta_create_RouteGuide_server(RouteGuideServicer()) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + route_guide_pb2.add_RouteGuideServicer_to_server( + RouteGuideServicer(), server) server.add_insecure_port('[::]:50051') server.start() try: diff --git a/examples/python/route_guide/run_codegen.py b/examples/python/route_guide/run_codegen.py new file mode 100644 index 00000000000..c7c60085809 --- /dev/null +++ b/examples/python/route_guide/run_codegen.py @@ -0,0 +1,42 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Runs protoc with the gRPC plugin to generate messages and gRPC stubs.""" + +from grpc.tools import protoc + +protoc.main( + ( + '', + '-I../../protos', + '--python_out=.', + '--grpc_python_out=.', + '../../protos/route_guide.proto', + ) +) diff --git a/examples/ruby/greeter_client.rb b/examples/ruby/greeter_client.rb index cb4aa195e77..1cdf79ebf40 100755 --- a/examples/ruby/greeter_client.rb +++ b/examples/ruby/greeter_client.rb @@ -38,7 +38,7 @@ lib_dir = File.join(this_dir, 'lib') $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' -require 'helloworld_services' +require 'helloworld_services_pb' def main stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure) diff --git a/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb index 622513d3805..6d82043c526 100755 --- a/examples/ruby/greeter_server.rb +++ b/examples/ruby/greeter_server.rb @@ -38,7 +38,7 @@ lib_dir = File.join(this_dir, 'lib') $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' -require 'helloworld_services' +require 'helloworld_services_pb' # GreeterServer is simple server that implements the Helloworld Greeter server. class GreeterServer < Helloworld::Greeter::Service diff --git a/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec index b1dfdae6ab3..e1b77a56ac9 100644 --- a/examples/ruby/grpc-demo.gemspec +++ b/examples/ruby/grpc-demo.gemspec @@ -3,7 +3,7 @@ Gem::Specification.new do |s| s.name = 'grpc-demo' - s.version = '0.11.0' + s.version = '1.0.0' s.authors = ['gRPC Authors'] s.email = 'temiola@google.com' s.homepage = 'https://github.com/grpc/grpc' @@ -17,7 +17,7 @@ Gem::Specification.new do |s| s.require_paths = ['lib'] s.platform = Gem::Platform::RUBY - s.add_dependency 'grpc', '~> 0.11' + s.add_dependency 'grpc', '~> 1.0.0' s.add_development_dependency 'bundler', '~> 1.7' end diff --git a/examples/ruby/lib/helloworld.rb b/examples/ruby/lib/helloworld_pb.rb similarity index 100% rename from examples/ruby/lib/helloworld.rb rename to examples/ruby/lib/helloworld_pb.rb diff --git a/examples/ruby/lib/helloworld_services.rb b/examples/ruby/lib/helloworld_services_pb.rb similarity index 98% rename from examples/ruby/lib/helloworld_services.rb rename to examples/ruby/lib/helloworld_services_pb.rb index fbec6677942..4fee0aa2a91 100644 --- a/examples/ruby/lib/helloworld_services.rb +++ b/examples/ruby/lib/helloworld_services_pb.rb @@ -32,7 +32,7 @@ # require 'grpc' -require 'helloworld' +require 'helloworld_pb' module Helloworld module Greeter diff --git a/examples/ruby/lib/route_guide.rb b/examples/ruby/lib/route_guide_pb.rb similarity index 100% rename from examples/ruby/lib/route_guide.rb rename to examples/ruby/lib/route_guide_pb.rb diff --git a/examples/ruby/lib/route_guide_services.rb b/examples/ruby/lib/route_guide_services_pb.rb similarity index 99% rename from examples/ruby/lib/route_guide_services.rb rename to examples/ruby/lib/route_guide_services_pb.rb index d8f123dd95b..d43fcc64e9a 100644 --- a/examples/ruby/lib/route_guide_services.rb +++ b/examples/ruby/lib/route_guide_services_pb.rb @@ -32,7 +32,7 @@ # require 'grpc' -require 'route_guide' +require 'route_guide_pb' module Routeguide module RouteGuide diff --git a/examples/ruby/route_guide/route_guide_client.rb b/examples/ruby/route_guide/route_guide_client.rb index e7f802c21e6..330725ece0d 100755 --- a/examples/ruby/route_guide/route_guide_client.rb +++ b/examples/ruby/route_guide/route_guide_client.rb @@ -39,7 +39,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' require 'multi_json' -require 'route_guide_services' +require 'route_guide_services_pb' include Routeguide diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb index bebe49b3beb..a5a73a8bac1 100755 --- a/examples/ruby/route_guide/route_guide_server.rb +++ b/examples/ruby/route_guide/route_guide_server.rb @@ -40,7 +40,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) require 'grpc' require 'multi_json' -require 'route_guide_services' +require 'route_guide_services_pb' include Routeguide COORD_FACTOR = 1e7 diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index e10e05387b1..deffa1653ea 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -35,7 +35,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' @@ -44,7 +44,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules. :submodules => true, } @@ -101,6 +101,8 @@ Pod::Spec.new do |s| 'ALWAYS_SEARCH_USER_PATHS' => 'NO', } + s.default_subspecs = 'Interface', 'Implementation' + # Like many other C libraries, gRPC-Core has its public headers under `include//` and its # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in @@ -161,6 +163,7 @@ Pod::Spec.new do |s| 'include/grpc/compression.h', 'include/grpc/grpc.h', 'include/grpc/grpc_posix.h', + 'include/grpc/grpc_security_constants.h', 'include/grpc/status.h', 'include/grpc/impl/codegen/byte_buffer.h', 'include/grpc/impl/codegen/byte_buffer_reader.h', @@ -184,14 +187,13 @@ Pod::Spec.new do |s| 'include/grpc/impl/codegen/sync_windows.h', 'include/grpc/impl/codegen/time.h', 'include/grpc/grpc_security.h', - 'include/grpc/grpc_security_constants.h', 'include/grpc/census.h' end s.subspec 'Implementation' do |ss| ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL', '~> 4.0' + ss.dependency 'BoringSSL', '~> 6.0' # To save you from scrolling, this is the last part of the podspec. ss.source_files = 'src/core/lib/profiling/timers.h', @@ -199,6 +201,7 @@ Pod::Spec.new do |s| 'src/core/lib/support/block_annotate.h', 'src/core/lib/support/env.h', 'src/core/lib/support/murmur_hash.h', + 'src/core/lib/support/percent_encoding.h', 'src/core/lib/support/stack_lockfree.h', 'src/core/lib/support/string.h', 'src/core/lib/support/string_windows.h', @@ -226,6 +229,7 @@ Pod::Spec.new do |s| 'src/core/lib/support/log_posix.c', 'src/core/lib/support/log_windows.c', 'src/core/lib/support/murmur_hash.c', + 'src/core/lib/support/percent_encoding.c', 'src/core/lib/support/slice.c', 'src/core/lib/support/slice_buffer.c', 'src/core/lib/support/stack_lockfree.c', @@ -256,6 +260,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', @@ -326,6 +331,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -347,7 +353,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/internal.h', 'src/core/ext/transport/chttp2/transport/status_conversion.h', 'src/core/ext/transport/chttp2/transport/stream_map.h', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/lib/security/context/security_context.h', @@ -376,7 +381,6 @@ Pod::Spec.new do |s| 'src/core/lib/tsi/transport_security_interface.h', 'src/core/ext/client_config/client_channel.h', 'src/core/ext/client_config/client_channel_factory.h', - 'src/core/ext/client_config/client_config.h', 'src/core/ext/client_config/connector.h', 'src/core/ext/client_config/initial_connect_string.h', 'src/core/ext/client_config/lb_policy.h', @@ -386,10 +390,11 @@ Pod::Spec.new do |s| 'src/core/ext/client_config/resolver.h', 'src/core/ext/client_config/resolver_factory.h', 'src/core/ext/client_config/resolver_registry.h', + 'src/core/ext/client_config/resolver_result.h', 'src/core/ext/client_config/subchannel.h', - 'src/core/ext/client_config/subchannel_call_holder.h', 'src/core/ext/client_config/subchannel_index.h', 'src/core/ext/client_config/uri_parser.h', + 'src/core/ext/lb_policy/grpclb/grpclb.h', 'src/core/ext/lb_policy/grpclb/load_balancer_api.h', 'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'third_party/nanopb/pb.h', @@ -399,11 +404,14 @@ Pod::Spec.new do |s| 'src/core/ext/load_reporting/load_reporting.h', 'src/core/ext/load_reporting/load_reporting_filter.h', 'src/core/ext/census/aggregation.h', + 'src/core/ext/census/base_resources.h', 'src/core/ext/census/census_interface.h', 'src/core/ext/census/census_rpc_stats.h', 'src/core/ext/census/gen/census.pb.h', + 'src/core/ext/census/gen/trace_context.pb.h', 'src/core/ext/census/grpc_filter.h', 'src/core/ext/census/mlog.h', + 'src/core/ext/census/resource.h', 'src/core/ext/census/rpc_metric_id.h', 'src/core/lib/surface/init.c', 'src/core/lib/channel/channel_args.c', @@ -411,6 +419,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -491,6 +500,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -513,7 +523,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', @@ -549,7 +558,6 @@ Pod::Spec.new do |s| 'src/core/ext/client_config/channel_connectivity.c', 'src/core/ext/client_config/client_channel.c', 'src/core/ext/client_config/client_channel_factory.c', - 'src/core/ext/client_config/client_config.c', 'src/core/ext/client_config/client_config_plugin.c', 'src/core/ext/client_config/connector.c', 'src/core/ext/client_config/default_initial_connect_string.c', @@ -561,14 +569,15 @@ Pod::Spec.new do |s| 'src/core/ext/client_config/resolver.c', 'src/core/ext/client_config/resolver_factory.c', 'src/core/ext/client_config/resolver_registry.c', + 'src/core/ext/client_config/resolver_result.c', 'src/core/ext/client_config/subchannel.c', - 'src/core/ext/client_config/subchannel_call_holder.c', 'src/core/ext/client_config/subchannel_index.c', 'src/core/ext/client_config/uri_parser.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c', + 'src/core/ext/lb_policy/grpclb/grpclb.c', 'src/core/ext/lb_policy/grpclb/load_balancer_api.c', 'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'third_party/nanopb/pb_common.c', @@ -580,8 +589,10 @@ Pod::Spec.new do |s| 'src/core/ext/resolver/sockaddr/sockaddr_resolver.c', 'src/core/ext/load_reporting/load_reporting.c', 'src/core/ext/load_reporting/load_reporting_filter.c', + 'src/core/ext/census/base_resources.c', 'src/core/ext/census/context.c', 'src/core/ext/census/gen/census.pb.c', + 'src/core/ext/census/gen/trace_context.pb.c', 'src/core/ext/census/grpc_context.c', 'src/core/ext/census/grpc_filter.c', 'src/core/ext/census/grpc_plugin.c', @@ -589,6 +600,7 @@ Pod::Spec.new do |s| 'src/core/ext/census/mlog.c', 'src/core/ext/census/operation.c', 'src/core/ext/census/placeholders.c', + 'src/core/ext/census/resource.c', 'src/core/ext/census/tracing.c', 'src/core/plugin_registry/grpc_plugin_registry.c' @@ -597,6 +609,7 @@ Pod::Spec.new do |s| 'src/core/lib/support/block_annotate.h', 'src/core/lib/support/env.h', 'src/core/lib/support/murmur_hash.h', + 'src/core/lib/support/percent_encoding.h', 'src/core/lib/support/stack_lockfree.h', 'src/core/lib/support/string.h', 'src/core/lib/support/string_windows.h', @@ -609,6 +622,7 @@ Pod::Spec.new do |s| 'src/core/lib/channel/compress_filter.h', 'src/core/lib/channel/connected_channel.h', 'src/core/lib/channel/context.h', + 'src/core/lib/channel/handshaker.h', 'src/core/lib/channel/http_client_filter.h', 'src/core/lib/channel/http_server_filter.h', 'src/core/lib/compression/algorithm_metadata.h', @@ -679,6 +693,7 @@ Pod::Spec.new do |s| 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', 'src/core/lib/transport/static_metadata.h', + 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', 'src/core/lib/transport/transport_impl.h', 'src/core/ext/transport/chttp2/transport/bin_decoder.h', @@ -700,7 +715,6 @@ Pod::Spec.new do |s| 'src/core/ext/transport/chttp2/transport/internal.h', 'src/core/ext/transport/chttp2/transport/status_conversion.h', 'src/core/ext/transport/chttp2/transport/stream_map.h', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.h', 'src/core/ext/transport/chttp2/transport/varint.h', 'src/core/ext/transport/chttp2/alpn/alpn.h', 'src/core/lib/security/context/security_context.h', @@ -729,7 +743,6 @@ Pod::Spec.new do |s| 'src/core/lib/tsi/transport_security_interface.h', 'src/core/ext/client_config/client_channel.h', 'src/core/ext/client_config/client_channel_factory.h', - 'src/core/ext/client_config/client_config.h', 'src/core/ext/client_config/connector.h', 'src/core/ext/client_config/initial_connect_string.h', 'src/core/ext/client_config/lb_policy.h', @@ -739,10 +752,11 @@ Pod::Spec.new do |s| 'src/core/ext/client_config/resolver.h', 'src/core/ext/client_config/resolver_factory.h', 'src/core/ext/client_config/resolver_registry.h', + 'src/core/ext/client_config/resolver_result.h', 'src/core/ext/client_config/subchannel.h', - 'src/core/ext/client_config/subchannel_call_holder.h', 'src/core/ext/client_config/subchannel_index.h', 'src/core/ext/client_config/uri_parser.h', + 'src/core/ext/lb_policy/grpclb/grpclb.h', 'src/core/ext/lb_policy/grpclb/load_balancer_api.h', 'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h', 'third_party/nanopb/pb.h', @@ -752,11 +766,40 @@ Pod::Spec.new do |s| 'src/core/ext/load_reporting/load_reporting.h', 'src/core/ext/load_reporting/load_reporting_filter.h', 'src/core/ext/census/aggregation.h', + 'src/core/ext/census/base_resources.h', 'src/core/ext/census/census_interface.h', 'src/core/ext/census/census_rpc_stats.h', 'src/core/ext/census/gen/census.pb.h', + 'src/core/ext/census/gen/trace_context.pb.h', 'src/core/ext/census/grpc_filter.h', 'src/core/ext/census/mlog.h', + 'src/core/ext/census/resource.h', 'src/core/ext/census/rpc_metric_id.h' end + + s.subspec 'Cronet-Interface' do |ss| + ss.header_mappings_dir = 'include/grpc' + ss.source_files = 'include/grpc/grpc_cronet.h' + end + + s.subspec 'Cronet-Implementation' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c' + end + + s.subspec 'Tests' do |ss| + ss.header_mappings_dir = '.' + + ss.source_files = 'test/core/end2end/cq_verifier.{c,h}', + 'test/core/end2end/end2end_tests.{c,h}', + 'test/core/end2end/tests/*.{c,h}', + 'test/core/end2end/data/*.{c,h}', + 'test/core/util/test_config.{c,h}', + 'test/core/util/port.h', + 'test/core/util/port_posix.c', + 'test/core/util/port_server_client.{c,h}' + + ss.dependency 'CronetFramework' + end end diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec index 9cc33c7dbd0..f6426fb4deb 100644 --- a/gRPC-ProtoRPC.podspec +++ b/gRPC-ProtoRPC.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # @@ -36,7 +30,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-ProtoRPC' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'RPC library for Protocol Buffers, based on gRPC' s.homepage = 'http://www.grpc.io' @@ -45,7 +39,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", } s.ios.deployment_target = '7.1' @@ -61,9 +55,11 @@ Pod::Spec.new do |s| s.dependency 'gRPC', version s.dependency 'gRPC-RxLibrary', version - s.dependency 'Protobuf', '~> 3.0.0-beta-3.1' - # This is needed by all pods that depend on Protobuf: + s.dependency 'Protobuf', '~> 3.0' s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', } end diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec index 6263878213e..316843436ba 100644 --- a/gRPC-RxLibrary.podspec +++ b/gRPC-RxLibrary.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # @@ -36,7 +30,7 @@ Pod::Spec.new do |s| s.name = 'gRPC-RxLibrary' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'Reactive Extensions library for iOS/OSX.' s.homepage = 'http://www.grpc.io' @@ -45,7 +39,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", } s.ios.deployment_target = '7.1' diff --git a/gRPC.podspec b/gRPC.podspec index e5556cc5448..9a479349531 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -1,9 +1,3 @@ -# GRPC CocoaPods podspec -# This file has been automatically generated from a template file. -# Please look at the templates directory instead. -# This file can be regenerated from the template by running -# tools/buildgen/generate_projects.sh - # Copyright 2015, Google Inc. # All rights reserved. # @@ -36,7 +30,7 @@ Pod::Spec.new do |s| s.name = 'gRPC' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'gRPC client library for iOS/OSX' s.homepage = 'http://www.grpc.io' @@ -45,7 +39,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", } s.ios.deployment_target = '7.1' @@ -65,4 +59,9 @@ Pod::Spec.new do |s| # Certificates, to be able to establish TLS connections: s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] } + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/grpc.def b/grpc.def index 0849f84e0bc..d6ddd33a926 100644 --- a/grpc.def +++ b/grpc.def @@ -23,15 +23,10 @@ EXPORTS census_trace_scan_start census_get_trace_record census_trace_scan_end + census_define_resource + census_delete_resource + census_resource_id census_record_values - census_view_create - census_view_delete - census_view_metric - census_view_naggregations - census_view_tags - census_view_aggregrations - census_view_get_data - census_view_reset grpc_compression_algorithm_parse grpc_compression_algorithm_name grpc_compression_algorithm_for_level @@ -47,6 +42,7 @@ EXPORTS grpc_init grpc_shutdown grpc_version_string + grpc_g_stands_for grpc_completion_queue_create grpc_completion_queue_next grpc_completion_queue_pluck @@ -148,6 +144,7 @@ EXPORTS gpr_slice_ref gpr_slice_unref gpr_slice_new + gpr_slice_new_with_user_data gpr_slice_new_with_len gpr_slice_malloc gpr_slice_from_copied_string diff --git a/grpc.gemspec b/grpc.gemspec index 369851b0f24..f2490060656 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -27,8 +27,9 @@ Gem::Specification.new do |s| s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3' + s.add_dependency 'google-protobuf', '~> 3.0' s.add_dependency 'googleauth', '~> 0.5.1' + s.add_dependency 'concurrent-ruby' s.add_development_dependency 'bundler', '~> 1.9' s.add_development_dependency 'facter', '~> 2.4' @@ -90,6 +91,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/support/block_annotate.h ) s.files += %w( src/core/lib/support/env.h ) s.files += %w( src/core/lib/support/murmur_hash.h ) + s.files += %w( src/core/lib/support/percent_encoding.h ) s.files += %w( src/core/lib/support/stack_lockfree.h ) s.files += %w( src/core/lib/support/string.h ) s.files += %w( src/core/lib/support/string_windows.h ) @@ -117,6 +119,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/support/log_posix.c ) s.files += %w( src/core/lib/support/log_windows.c ) s.files += %w( src/core/lib/support/murmur_hash.c ) + s.files += %w( src/core/lib/support/percent_encoding.c ) s.files += %w( src/core/lib/support/slice.c ) s.files += %w( src/core/lib/support/slice_buffer.c ) s.files += %w( src/core/lib/support/stack_lockfree.c ) @@ -146,6 +149,7 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/compression.h ) s.files += %w( include/grpc/grpc.h ) s.files += %w( include/grpc/grpc_posix.h ) + s.files += %w( include/grpc/grpc_security_constants.h ) s.files += %w( include/grpc/status.h ) s.files += %w( include/grpc/impl/codegen/byte_buffer.h ) s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h ) @@ -169,7 +173,6 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/impl/codegen/sync_windows.h ) s.files += %w( include/grpc/impl/codegen/time.h ) s.files += %w( include/grpc/grpc_security.h ) - s.files += %w( include/grpc/grpc_security_constants.h ) s.files += %w( include/grpc/census.h ) s.files += %w( src/core/lib/channel/channel_args.h ) s.files += %w( src/core/lib/channel/channel_stack.h ) @@ -177,6 +180,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/compress_filter.h ) s.files += %w( src/core/lib/channel/connected_channel.h ) s.files += %w( src/core/lib/channel/context.h ) + s.files += %w( src/core/lib/channel/handshaker.h ) s.files += %w( src/core/lib/channel/http_client_filter.h ) s.files += %w( src/core/lib/channel/http_server_filter.h ) s.files += %w( src/core/lib/compression/algorithm_metadata.h ) @@ -247,6 +251,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.h ) s.files += %w( src/core/lib/transport/metadata_batch.h ) s.files += %w( src/core/lib/transport/static_metadata.h ) + s.files += %w( src/core/lib/transport/timeout_encoding.h ) s.files += %w( src/core/lib/transport/transport.h ) s.files += %w( src/core/lib/transport/transport_impl.h ) s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h ) @@ -268,7 +273,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/internal.h ) s.files += %w( src/core/ext/transport/chttp2/transport/status_conversion.h ) s.files += %w( src/core/ext/transport/chttp2/transport/stream_map.h ) - s.files += %w( src/core/ext/transport/chttp2/transport/timeout_encoding.h ) s.files += %w( src/core/ext/transport/chttp2/transport/varint.h ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.h ) s.files += %w( src/core/lib/security/context/security_context.h ) @@ -297,7 +301,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/tsi/transport_security_interface.h ) s.files += %w( src/core/ext/client_config/client_channel.h ) s.files += %w( src/core/ext/client_config/client_channel_factory.h ) - s.files += %w( src/core/ext/client_config/client_config.h ) s.files += %w( src/core/ext/client_config/connector.h ) s.files += %w( src/core/ext/client_config/initial_connect_string.h ) s.files += %w( src/core/ext/client_config/lb_policy.h ) @@ -307,10 +310,11 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/client_config/resolver.h ) s.files += %w( src/core/ext/client_config/resolver_factory.h ) s.files += %w( src/core/ext/client_config/resolver_registry.h ) + s.files += %w( src/core/ext/client_config/resolver_result.h ) s.files += %w( src/core/ext/client_config/subchannel.h ) - s.files += %w( src/core/ext/client_config/subchannel_call_holder.h ) s.files += %w( src/core/ext/client_config/subchannel_index.h ) s.files += %w( src/core/ext/client_config/uri_parser.h ) + s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.h ) s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h ) s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h ) s.files += %w( third_party/nanopb/pb.h ) @@ -320,11 +324,14 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/load_reporting/load_reporting.h ) s.files += %w( src/core/ext/load_reporting/load_reporting_filter.h ) s.files += %w( src/core/ext/census/aggregation.h ) + s.files += %w( src/core/ext/census/base_resources.h ) s.files += %w( src/core/ext/census/census_interface.h ) s.files += %w( src/core/ext/census/census_rpc_stats.h ) s.files += %w( src/core/ext/census/gen/census.pb.h ) + s.files += %w( src/core/ext/census/gen/trace_context.pb.h ) s.files += %w( src/core/ext/census/grpc_filter.h ) s.files += %w( src/core/ext/census/mlog.h ) + s.files += %w( src/core/ext/census/resource.h ) s.files += %w( src/core/ext/census/rpc_metric_id.h ) s.files += %w( src/core/lib/surface/init.c ) s.files += %w( src/core/lib/channel/channel_args.c ) @@ -332,6 +339,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/channel/channel_stack_builder.c ) s.files += %w( src/core/lib/channel/compress_filter.c ) s.files += %w( src/core/lib/channel/connected_channel.c ) + s.files += %w( src/core/lib/channel/handshaker.c ) s.files += %w( src/core/lib/channel/http_client_filter.c ) s.files += %w( src/core/lib/channel/http_server_filter.c ) s.files += %w( src/core/lib/compression/compression.c ) @@ -412,6 +420,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/metadata.c ) s.files += %w( src/core/lib/transport/metadata_batch.c ) s.files += %w( src/core/lib/transport/static_metadata.c ) + s.files += %w( src/core/lib/transport/timeout_encoding.c ) s.files += %w( src/core/lib/transport/transport.c ) s.files += %w( src/core/lib/transport/transport_op_string.c ) s.files += %w( src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c ) @@ -434,7 +443,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/transport/chttp2/transport/status_conversion.c ) s.files += %w( src/core/ext/transport/chttp2/transport/stream_lists.c ) s.files += %w( src/core/ext/transport/chttp2/transport/stream_map.c ) - s.files += %w( src/core/ext/transport/chttp2/transport/timeout_encoding.c ) s.files += %w( src/core/ext/transport/chttp2/transport/varint.c ) s.files += %w( src/core/ext/transport/chttp2/transport/writing.c ) s.files += %w( src/core/ext/transport/chttp2/alpn/alpn.c ) @@ -470,7 +478,6 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/client_config/channel_connectivity.c ) s.files += %w( src/core/ext/client_config/client_channel.c ) s.files += %w( src/core/ext/client_config/client_channel_factory.c ) - s.files += %w( src/core/ext/client_config/client_config.c ) s.files += %w( src/core/ext/client_config/client_config_plugin.c ) s.files += %w( src/core/ext/client_config/connector.c ) s.files += %w( src/core/ext/client_config/default_initial_connect_string.c ) @@ -482,14 +489,15 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/client_config/resolver.c ) s.files += %w( src/core/ext/client_config/resolver_factory.c ) s.files += %w( src/core/ext/client_config/resolver_registry.c ) + s.files += %w( src/core/ext/client_config/resolver_result.c ) s.files += %w( src/core/ext/client_config/subchannel.c ) - s.files += %w( src/core/ext/client_config/subchannel_call_holder.c ) s.files += %w( src/core/ext/client_config/subchannel_index.c ) s.files += %w( src/core/ext/client_config/uri_parser.c ) s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c ) s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c ) s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c ) s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c ) + s.files += %w( src/core/ext/lb_policy/grpclb/grpclb.c ) s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c ) s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c ) s.files += %w( third_party/nanopb/pb_common.c ) @@ -501,8 +509,10 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/resolver/sockaddr/sockaddr_resolver.c ) s.files += %w( src/core/ext/load_reporting/load_reporting.c ) s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c ) + s.files += %w( src/core/ext/census/base_resources.c ) s.files += %w( src/core/ext/census/context.c ) s.files += %w( src/core/ext/census/gen/census.pb.c ) + s.files += %w( src/core/ext/census/gen/trace_context.pb.c ) s.files += %w( src/core/ext/census/grpc_context.c ) s.files += %w( src/core/ext/census/grpc_filter.c ) s.files += %w( src/core/ext/census/grpc_plugin.c ) @@ -510,6 +520,7 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/census/mlog.c ) s.files += %w( src/core/ext/census/operation.c ) s.files += %w( src/core/ext/census/placeholders.c ) + s.files += %w( src/core/ext/census/resource.c ) s.files += %w( src/core/ext/census/tracing.c ) s.files += %w( src/core/plugin_registry/grpc_plugin_registry.c ) s.files += %w( third_party/boringssl/crypto/aes/internal.h ) diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h index e9ccb515039..0537695ed2b 100644 --- a/include/grpc++/create_channel.h +++ b/include/grpc++/create_channel.h @@ -48,7 +48,6 @@ namespace grpc { /// \param target The URI of the endpoint to connect to. /// \param creds Credentials to use for the created channel. If it does not hold /// an object or is invalid, a lame channel is returned. -/// \param args Options for channel creation. std::shared_ptr CreateChannel( const grpc::string& target, const std::shared_ptr& creds); diff --git a/include/grpc++/ext/reflection.grpc.pb.h b/include/grpc++/ext/reflection.grpc.pb.h index 0b4ef861472..064117e3030 100644 --- a/include/grpc++/ext/reflection.grpc.pb.h +++ b/include/grpc++/ext/reflection.grpc.pb.h @@ -74,6 +74,7 @@ #include #include +#include #include #include #include @@ -174,6 +175,7 @@ class ServerReflection GRPC_FINAL { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; + typedef Service StreamedUnaryService; }; } // namespace v1alpha diff --git a/include/grpc++/ext/reflection.pb.h b/include/grpc++/ext/reflection.pb.h index 00d07735ee8..bdb86197d03 100644 --- a/include/grpc++/ext/reflection.pb.h +++ b/include/grpc++/ext/reflection.pb.h @@ -83,7 +83,7 @@ class ServiceResponse; // =================================================================== -class ServerReflectionRequest : public ::google::protobuf::Message { +class ServerReflectionRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServerReflectionRequest) */ { public: ServerReflectionRequest(); virtual ~ServerReflectionRequest(); @@ -126,7 +126,11 @@ class ServerReflectionRequest : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -260,7 +264,7 @@ class ServerReflectionRequest : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ExtensionRequest : public ::google::protobuf::Message { +class ExtensionRequest : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ExtensionRequest) */ { public: ExtensionRequest(); virtual ~ExtensionRequest(); @@ -294,7 +298,11 @@ class ExtensionRequest : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -350,7 +358,7 @@ class ExtensionRequest : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ServerReflectionResponse : public ::google::protobuf::Message { +class ServerReflectionResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServerReflectionResponse) */ { public: ServerReflectionResponse(); virtual ~ServerReflectionResponse(); @@ -392,7 +400,11 @@ class ServerReflectionResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -505,7 +517,7 @@ class ServerReflectionResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class FileDescriptorResponse : public ::google::protobuf::Message { +class FileDescriptorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.FileDescriptorResponse) */ { public: FileDescriptorResponse(); virtual ~FileDescriptorResponse(); @@ -539,7 +551,11 @@ class FileDescriptorResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -593,7 +609,7 @@ class FileDescriptorResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ExtensionNumberResponse : public ::google::protobuf::Message { +class ExtensionNumberResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ExtensionNumberResponse) */ { public: ExtensionNumberResponse(); virtual ~ExtensionNumberResponse(); @@ -627,7 +643,11 @@ class ExtensionNumberResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -690,7 +710,7 @@ class ExtensionNumberResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ListServiceResponse : public ::google::protobuf::Message { +class ListServiceResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ListServiceResponse) */ { public: ListServiceResponse(); virtual ~ListServiceResponse(); @@ -724,7 +744,11 @@ class ListServiceResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -774,7 +798,7 @@ class ListServiceResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ServiceResponse : public ::google::protobuf::Message { +class ServiceResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ServiceResponse) */ { public: ServiceResponse(); virtual ~ServiceResponse(); @@ -808,7 +832,11 @@ class ServiceResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); @@ -857,7 +885,7 @@ class ServiceResponse : public ::google::protobuf::Message { }; // ------------------------------------------------------------------- -class ErrorResponse : public ::google::protobuf::Message { +class ErrorResponse : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:grpc.reflection.v1alpha.ErrorResponse) */ { public: ErrorResponse(); virtual ~ErrorResponse(); @@ -891,7 +919,11 @@ class ErrorResponse : public ::google::protobuf::Message { ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* output) const; + ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const { + return InternalSerializeWithCachedSizesToArray(false, output); + } int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h index ef07e199759..afb1c555bb6 100644 --- a/include/grpc++/grpc++.h +++ b/include/grpc++/grpc++.h @@ -51,6 +51,9 @@ #ifndef GRPCXX_GRPCXX_H #define GRPCXX_GRPCXX_H +// Pragma for http://include-what-you-use.org/ tool, tells that following +// headers are not private for grpc++.h and are part of its interface. +// IWYU pragma: begin_exports #include #include @@ -62,5 +65,6 @@ #include #include #include +// IWYU pragma: end_exports #endif // GRPCXX_GRPCXX_H diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h index e96d224ddbe..70533aa4d9f 100644 --- a/include/grpc++/impl/codegen/async_stream.h +++ b/include/grpc++/impl/codegen/async_stream.h @@ -330,6 +330,9 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface { meta_ops_.set_output_tag(tag); 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; call_.PerformOps(&meta_ops_); } @@ -345,6 +348,9 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface { 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. @@ -363,6 +369,9 @@ class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface { 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_, status); @@ -400,6 +409,9 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface { meta_ops_.set_output_tag(tag); 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; call_.PerformOps(&meta_ops_); } @@ -409,6 +421,9 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface { 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(ctiller): don't assert @@ -421,6 +436,9 @@ class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface { 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_, status); @@ -459,6 +477,9 @@ class ServerAsyncReaderWriter GRPC_FINAL meta_ops_.set_output_tag(tag); 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; call_.PerformOps(&meta_ops_); } @@ -474,6 +495,9 @@ class ServerAsyncReaderWriter GRPC_FINAL 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(ctiller): don't assert @@ -486,6 +510,9 @@ class ServerAsyncReaderWriter GRPC_FINAL 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_, status); diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h index 47ac5bee925..5ceab73cea6 100644 --- a/include/grpc++/impl/codegen/async_unary_call.h +++ b/include/grpc++/impl/codegen/async_unary_call.h @@ -65,7 +65,7 @@ class ClientAsyncResponseReader GRPC_FINAL const W& request) : context_(context), call_(channel->CreateCall(method, context, cq)), - collection_(new CallOpSetCollection) { + collection_(std::make_shared()) { collection_->init_buf_.SetCollection(collection_); collection_->init_buf_.SendInitialMetadata( context->send_initial_metadata_, context->initial_metadata_flags()); @@ -126,6 +126,9 @@ class ServerAsyncResponseWriter GRPC_FINAL meta_buf_.set_output_tag(tag); meta_buf_.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + meta_buf_.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; call_.PerformOps(&meta_buf_); } @@ -135,6 +138,9 @@ class ServerAsyncResponseWriter GRPC_FINAL if (!ctx_->sent_initial_metadata_) { finish_buf_.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_buf_.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; } // The response is dropped if the status is not OK. @@ -153,6 +159,9 @@ class ServerAsyncResponseWriter GRPC_FINAL if (!ctx_->sent_initial_metadata_) { finish_buf_.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + finish_buf_.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; } finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status); diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index fab85d15176..df225d362b4 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -180,17 +180,23 @@ class CallNoOp { class CallOpSendInitialMetadata { public: - CallOpSendInitialMetadata() : send_(false) {} + CallOpSendInitialMetadata() : send_(false) { + maybe_compression_level_.is_set = false; + } void SendInitialMetadata( const std::multimap& metadata, uint32_t flags) { + maybe_compression_level_.is_set = false; send_ = true; flags_ = flags; initial_metadata_count_ = metadata.size(); initial_metadata_ = FillMetadataArray(metadata); - // TODO(dgq): expose compression level in API so it can be properly set. - maybe_compression_level_.is_set = false; + } + + void set_compression_level(grpc_compression_level level) { + maybe_compression_level_.is_set = true; + maybe_compression_level_.level = level; } protected: @@ -656,10 +662,10 @@ class Call GRPC_FINAL { call_hook_->PerformOpsOnCall(ops, this); } - grpc_call* call() { return call_; } - CompletionQueue* cq() { return cq_; } + grpc_call* call() const { return call_; } + CompletionQueue* cq() const { return cq_; } - int max_message_size() { return max_message_size_; } + int max_message_size() const { return max_message_size_; } private: CallHook* call_hook_; diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h index a132c9a57aa..d77ca4c3961 100644 --- a/include/grpc++/impl/codegen/client_context.h +++ b/include/grpc++/impl/codegen/client_context.h @@ -41,7 +41,7 @@ /// /// Context settings are only relevant to the call they are invoked with, that /// is to say, they aren't sticky. Some of these settings, such as the -/// compression options, can be made persistant at channel construction time +/// compression options, can be made persistent at channel construction time /// (see \a grpc::CreateCustomChannel). /// /// \warning ClientContext instances should \em not be reused across rpcs. @@ -271,7 +271,7 @@ class ClientContext { /// Set \a algorithm to be the compression algorithm used for the client call. /// - /// \param algorith The compression algorithm used for the client call. + /// \param algorithm The compression algorithm used for the client call. void set_compression_algorithm(grpc_compression_algorithm algorithm); /// Return the peer uri in a string. @@ -307,6 +307,10 @@ class ClientContext { }; static void SetGlobalCallbacks(GlobalCallbacks* callbacks); + // Should be used for framework-level extensions only. + // Applications never need to call this method. + grpc_call* c_call() { return call_; } + private: // Disallow copy and assign. ClientContext(const ClientContext&); diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h index 03009e0561d..78bc5ca481c 100644 --- a/include/grpc++/impl/codegen/completion_queue.h +++ b/include/grpc++/impl/codegen/completion_queue.h @@ -68,8 +68,10 @@ template class ServerReader; template class ServerWriter; +namespace internal { template -class ServerReaderWriter; +class ServerReaderWriterBody; +} template class RpcMethodHandler; template @@ -178,15 +180,15 @@ class CompletionQueue : private GrpcLibraryCodegen { template friend class ::grpc::ServerWriter; template - friend class ::grpc::ServerReaderWriter; + friend class ::grpc::internal::ServerReaderWriterBody; template friend class RpcMethodHandler; template friend class ClientStreamingHandler; template friend class ServerStreamingHandler; - template - friend class BidiStreamingHandler; + template + friend class TemplatedBidiStreamingHandler; friend class UnknownMethodHandler; friend class ::grpc::Server; friend class ::grpc::ServerContext; diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h index 4bee1bc4227..8620d4b2183 100644 --- a/include/grpc++/impl/codegen/config_protobuf.h +++ b/include/grpc++/impl/codegen/config_protobuf.h @@ -40,16 +40,21 @@ #endif #ifndef GRPC_CUSTOM_MESSAGE +#ifdef GRPC_USE_PROTO_LITE +#include +#define GRPC_CUSTOM_MESSAGE ::google::protobuf::MessageLite +#else #include #define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message #endif +#endif #ifndef GRPC_CUSTOM_DESCRIPTOR #include #include #define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor #define GRPC_CUSTOM_DESCRIPTORPOOL ::google::protobuf::DescriptorPool -#define GPRC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor +#define GRPC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor #define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor #define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto #define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor @@ -57,6 +62,13 @@ #define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation #endif +#ifndef GRPC_CUSTOM_DESCRIPTORDATABASE +#include +#define GRPC_CUSTOM_DESCRIPTORDATABASE ::google::protobuf::DescriptorDatabase +#define GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE \ + ::google::protobuf::SimpleDescriptorDatabase +#endif + #ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM #include #include @@ -75,11 +87,13 @@ typedef GRPC_CUSTOM_PROTOBUF_INT64 int64; typedef GRPC_CUSTOM_DESCRIPTOR Descriptor; typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool; -typedef GPRC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; +typedef GRPC_CUSTOM_DESCRIPTORDATABASE DescriptorDatabase; +typedef GRPC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor; typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto; typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor; typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor; +typedef GRPC_CUSTOM_SIMPLEDESCRIPTORDATABASE SimpleDescriptorDatabase; typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation; namespace io { diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h index 9699abfb438..2586b945048 100644 --- a/include/grpc++/impl/codegen/core_codegen.h +++ b/include/grpc++/impl/codegen/core_codegen.h @@ -31,6 +31,9 @@ * */ +#ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H +#define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H + // This file should be compiled as part of grpc++. #include @@ -83,3 +86,5 @@ class CoreCodegen : public CoreCodegenInterface { }; } // namespace grpc + +#endif // GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_H diff --git a/include/grpc++/impl/codegen/impl/async_stream.h b/include/grpc++/impl/codegen/impl/async_stream.h deleted file mode 100644 index 7d7a9568077..00000000000 --- a/include/grpc++/impl/codegen/impl/async_stream.h +++ /dev/null @@ -1,486 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H -#define GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H - -#include -#include -#include -#include -#include -#include - -namespace grpc { - -class CompletionQueue; - -/// Common interface for all client side asynchronous streaming. -class ClientAsyncStreamingInterface { - public: - virtual ~ClientAsyncStreamingInterface() {} - - /// Request notification of the reading of the initial metadata. Completion - /// will be notified by \a tag on the associated completion queue. - /// - /// \param[in] tag Tag identifying this request. - virtual void ReadInitialMetadata(void* tag) = 0; - - /// Request notification completion. - /// - /// \param[out] status To be updated with the operation status. - /// \param[in] tag Tag identifying this request. - virtual void Finish(Status* status, void* tag) = 0; -}; - -/// An interface that yields a sequence of messages of type \a R. -template -class AsyncReaderInterface { - public: - virtual ~AsyncReaderInterface() {} - - /// Read a message of type \a R into \a msg. Completion will be notified by \a - /// tag on the associated completion queue. - /// - /// \param[out] msg Where to eventually store the read message. - /// \param[in] tag The tag identifying the operation. - virtual void Read(R* msg, void* tag) = 0; -}; - -/// An interface that can be fed a sequence of messages of type \a W. -template -class AsyncWriterInterface { - public: - virtual ~AsyncWriterInterface() {} - - /// Request the writing of \a msg with identifying tag \a tag. - /// - /// Only one write may be outstanding at any given time. This means that - /// after calling Write, one must wait to receive \a tag from the completion - /// queue BEFORE calling Write again. - /// - /// \param[in] msg The message to be written. - /// \param[in] tag The tag identifying the operation. - virtual void Write(const W& msg, void* tag) = 0; -}; - -template -class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface, - public AsyncReaderInterface {}; - -template -class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface { - public: - /// Create a stream and write the first request out. - template - ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq, - const RpcMethod& method, ClientContext* context, - const W& request, void* tag) - : context_(context), call_(channel->CreateCall(method, context, cq)) { - init_ops_.set_output_tag(tag); - init_ops_.SendInitialMetadata(context->send_initial_metadata_); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok()); - init_ops_.ClientSendClose(); - call_.PerformOps(&init_ops_); - } - - void ReadInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Finish(Status* status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - ClientContext* context_; - Call call_; - CallOpSet - init_ops_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet finish_ops_; -}; - -/// Common interface for client side asynchronous writing. -template -class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface, - public AsyncWriterInterface { - public: - /// Signal the client is done with the writes. - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; - -template -class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface { - public: - template - ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq, - const RpcMethod& method, ClientContext* context, - R* response, void* tag) - : context_(context), call_(channel->CreateCall(method, context, cq)) { - finish_ops_.RecvMessage(response); - - init_ops_.set_output_tag(tag); - init_ops_.SendInitialMetadata(context->send_initial_metadata_); - call_.PerformOps(&init_ops_); - } - - void ReadInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void WritesDone(void* tag) GRPC_OVERRIDE { - writes_done_ops_.set_output_tag(tag); - writes_done_ops_.ClientSendClose(); - call_.PerformOps(&writes_done_ops_); - } - - void Finish(Status* status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - ClientContext* context_; - Call call_; - CallOpSet init_ops_; - CallOpSet meta_ops_; - CallOpSet write_ops_; - CallOpSet writes_done_ops_; - CallOpSet - finish_ops_; -}; - -/// Client-side interface for asynchronous bi-directional streaming. -template -class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface, - public AsyncWriterInterface, - public AsyncReaderInterface { - public: - /// Signal the client is done with the writes. - /// - /// \param[in] tag The tag identifying the operation. - virtual void WritesDone(void* tag) = 0; -}; - -template -class ClientAsyncReaderWriter GRPC_FINAL - : public ClientAsyncReaderWriterInterface { - public: - ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq, - const RpcMethod& method, ClientContext* context, - void* tag) - : context_(context), call_(channel->CreateCall(method, context, cq)) { - init_ops_.set_output_tag(tag); - init_ops_.SendInitialMetadata(context->send_initial_metadata_); - call_.PerformOps(&init_ops_); - } - - void ReadInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_); - - meta_ops_.set_output_tag(tag); - meta_ops_.RecvInitialMetadata(context_); - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - read_ops_.RecvInitialMetadata(context_); - } - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void WritesDone(void* tag) GRPC_OVERRIDE { - writes_done_ops_.set_output_tag(tag); - writes_done_ops_.ClientSendClose(); - call_.PerformOps(&writes_done_ops_); - } - - void Finish(Status* status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!context_->initial_metadata_received_) { - finish_ops_.RecvInitialMetadata(context_); - } - finish_ops_.ClientRecvStatus(context_, status); - call_.PerformOps(&finish_ops_); - } - - private: - ClientContext* context_; - Call call_; - CallOpSet init_ops_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet write_ops_; - CallOpSet writes_done_ops_; - CallOpSet finish_ops_; -}; - -template -class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface, - public AsyncReaderInterface { - public: - virtual void Finish(const W& msg, const Status& status, void* tag) = 0; - - virtual void FinishWithError(const Status& status, void* tag) = 0; -}; - -template -class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface { - public: - explicit ServerAsyncReader(ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - void SendInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Finish(const W& msg, const Status& status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - // The response is dropped if the status is not OK. - if (status.ok()) { - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, - finish_ops_.SendMessage(msg)); - } else { - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - } - call_.PerformOps(&finish_ops_); - } - - void FinishWithError(const Status& status, void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!status.ok()); - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; } - - Call call_; - ServerContext* ctx_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet - finish_ops_; -}; - -template -class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface, - public AsyncWriterInterface { - public: - virtual void Finish(const Status& status, void* tag) = 0; -}; - -template -class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface { - public: - explicit ServerAsyncWriter(ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - void SendInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Finish(const Status& status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; } - - Call call_; - ServerContext* ctx_; - CallOpSet meta_ops_; - CallOpSet write_ops_; - CallOpSet finish_ops_; -}; - -/// Server-side interface for asynchronous bi-directional streaming. -template -class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface, - public AsyncWriterInterface, - public AsyncReaderInterface { - public: - virtual void Finish(const Status& status, void* tag) = 0; -}; - -template -class ServerAsyncReaderWriter GRPC_FINAL - : public ServerAsyncReaderWriterInterface { - public: - explicit ServerAsyncReaderWriter(ServerContext* ctx) - : call_(nullptr, nullptr, nullptr), ctx_(ctx) {} - - void SendInitialMetadata(void* tag) GRPC_OVERRIDE { - GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); - - meta_ops_.set_output_tag(tag); - meta_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - call_.PerformOps(&meta_ops_); - } - - void Read(R* msg, void* tag) GRPC_OVERRIDE { - read_ops_.set_output_tag(tag); - read_ops_.RecvMessage(msg); - call_.PerformOps(&read_ops_); - } - - void Write(const W& msg, void* tag) GRPC_OVERRIDE { - write_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - write_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - // TODO(ctiller): don't assert - GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok()); - call_.PerformOps(&write_ops_); - } - - void Finish(const Status& status, void* tag) GRPC_OVERRIDE { - finish_ops_.set_output_tag(tag); - if (!ctx_->sent_initial_metadata_) { - finish_ops_.SendInitialMetadata(ctx_->initial_metadata_); - ctx_->sent_initial_metadata_ = true; - } - finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status); - call_.PerformOps(&finish_ops_); - } - - private: - friend class ::grpc::Server; - - void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; } - - Call call_; - ServerContext* ctx_; - CallOpSet meta_ops_; - CallOpSet> read_ops_; - CallOpSet write_ops_; - CallOpSet finish_ops_; -}; - -} // namespace grpc - -#endif // GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h index 21ac6c4fb55..d989263252d 100644 --- a/include/grpc++/impl/codegen/method_handler_impl.h +++ b/include/grpc++/impl/codegen/method_handler_impl.h @@ -65,6 +65,9 @@ class RpcMethodHandler : public MethodHandler { ops; ops.SendInitialMetadata(param.server_context->initial_metadata_, param.server_context->initial_metadata_flags()); + if (param.server_context->compression_level_set()) { + ops.set_compression_level(param.server_context->compression_level()); + } if (status.ok()) { status = ops.SendMessage(rsp); } @@ -104,6 +107,9 @@ class ClientStreamingHandler : public MethodHandler { ops; ops.SendInitialMetadata(param.server_context->initial_metadata_, param.server_context->initial_metadata_flags()); + if (param.server_context->compression_level_set()) { + ops.set_compression_level(param.server_context->compression_level()); + } if (status.ok()) { status = ops.SendMessage(rsp); } @@ -144,6 +150,9 @@ class ServerStreamingHandler : public MethodHandler { if (!param.server_context->sent_initial_metadata_) { ops.SendInitialMetadata(param.server_context->initial_metadata_, param.server_context->initial_metadata_flags()); + if (param.server_context->compression_level_set()) { + ops.set_compression_level(param.server_context->compression_level()); + } } ops.ServerSendStatus(param.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); @@ -158,25 +167,36 @@ class ServerStreamingHandler : public MethodHandler { }; // A wrapper class of an application provided bidi-streaming handler. -template -class BidiStreamingHandler : public MethodHandler { +// This also applies to server-streamed implementation of a unary method +// with the additional requirement that such methods must have done a +// write for status to be ok +// Since this is used by more than 1 class, the service is not passed in. +// Instead, it is expected to be an implicitly-captured argument of func +// (through bind or something along those lines) +template +class TemplatedBidiStreamingHandler : public MethodHandler { public: - BidiStreamingHandler( - std::function*)> - func, - ServiceType* service) - : func_(func), service_(service) {} + TemplatedBidiStreamingHandler( + std::function func) + : func_(func), write_needed_(WriteNeeded) {} void RunHandler(const HandlerParameter& param) GRPC_FINAL { - ServerReaderWriter stream(param.call, - param.server_context); - Status status = func_(service_, param.server_context, &stream); + Streamer stream(param.call, param.server_context); + Status status = func_(param.server_context, &stream); CallOpSet ops; if (!param.server_context->sent_initial_metadata_) { ops.SendInitialMetadata(param.server_context->initial_metadata_, param.server_context->initial_metadata_flags()); + if (param.server_context->compression_level_set()) { + ops.set_compression_level(param.server_context->compression_level()); + } + if (write_needed_ && status.ok()) { + // If we needed a write but never did one, we need to mark the + // status as a fail + status = Status(StatusCode::INTERNAL, + "Service did not provide response message"); + } } ops.ServerSendStatus(param.server_context->trailing_metadata_, status); param.call->PerformOps(&ops); @@ -184,10 +204,36 @@ class BidiStreamingHandler : public MethodHandler { } private: - std::function*)> - func_; - ServiceType* service_; + std::function func_; + const bool write_needed_; +}; + +template +class BidiStreamingHandler + : public TemplatedBidiStreamingHandler< + ServerReaderWriter, false> { + public: + BidiStreamingHandler( + std::function*)> + func, + ServiceType* service) + : TemplatedBidiStreamingHandler< + ServerReaderWriter, false>(std::bind( + func, service, std::placeholders::_1, std::placeholders::_2)) {} +}; + +template +class StreamedUnaryHandler + : public TemplatedBidiStreamingHandler< + ServerUnaryStreamer, true> { + public: + explicit StreamedUnaryHandler( + std::function*)> + func) + : TemplatedBidiStreamingHandler< + ServerUnaryStreamer, true>(func) {} }; // Handle unknown method by returning UNIMPLEMENTED error. @@ -199,6 +245,9 @@ class UnknownMethodHandler : public MethodHandler { if (!context->sent_initial_metadata_) { ops->SendInitialMetadata(context->initial_metadata_, context->initial_metadata_flags()); + if (context->compression_level_set()) { + ops->set_compression_level(context->compression_level()); + } context->sent_initial_metadata_ = true; } ops->ServerSendStatus(context->trailing_metadata_, status); diff --git a/include/grpc++/impl/codegen/rpc_method.h b/include/grpc++/impl/codegen/rpc_method.h index 39cb4f75dfe..48974280747 100644 --- a/include/grpc++/impl/codegen/rpc_method.h +++ b/include/grpc++/impl/codegen/rpc_method.h @@ -60,11 +60,12 @@ class RpcMethod { const char* name() const { return name_; } RpcType method_type() const { return method_type_; } + void SetMethodType(RpcType type) { method_type_ = type; } void* channel_tag() const { return channel_tag_; } private: const char* const name_; - const RpcType method_type_; + RpcType method_type_; void* const channel_tag_; }; diff --git a/include/grpc++/impl/codegen/rpc_service_method.h b/include/grpc++/impl/codegen/rpc_service_method.h index 8b1f026c912..52124fba0b8 100644 --- a/include/grpc++/impl/codegen/rpc_service_method.h +++ b/include/grpc++/impl/codegen/rpc_service_method.h @@ -82,6 +82,7 @@ class RpcServiceMethod : public RpcMethod { // if MethodHandler is nullptr, then this is an async method MethodHandler* handler() const { return handler_.get(); } void ResetHandler() { handler_.reset(); } + void SetHandler(MethodHandler* handler) { handler_.reset(handler); } private: void* server_tag_; diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h index cea13a513f6..379c9f7cf8c 100644 --- a/include/grpc++/impl/codegen/server_context.h +++ b/include/grpc++/impl/codegen/server_context.h @@ -65,8 +65,10 @@ template class ServerReader; template class ServerWriter; +namespace internal { template -class ServerReaderWriter; +class ServerReaderWriterBody; +} template class RpcMethodHandler; template @@ -130,7 +132,13 @@ class ServerContext { grpc_compression_level compression_level() const { return compression_level_; } - void set_compression_level(grpc_compression_level level); + + void set_compression_level(grpc_compression_level level) { + compression_level_set_ = true; + compression_level_ = level; + } + + bool compression_level_set() const { return compression_level_set_; } grpc_compression_algorithm compression_algorithm() const { return compression_algorithm_; @@ -160,6 +168,10 @@ class ServerContext { async_notify_when_done_tag_ = tag; } + // Should be used for framework-level extensions only. + // Applications never need to call this method. + grpc_call* c_call() { return call_; } + private: friend class ::grpc::testing::InteropServerContextInspector; friend class ::grpc::ServerInterface; @@ -177,15 +189,15 @@ class ServerContext { template friend class ::grpc::ServerWriter; template - friend class ::grpc::ServerReaderWriter; + friend class ::grpc::internal::ServerReaderWriterBody; template friend class RpcMethodHandler; template friend class ClientStreamingHandler; template friend class ServerStreamingHandler; - template - friend class BidiStreamingHandler; + template + friend class TemplatedBidiStreamingHandler; friend class UnknownMethodHandler; friend class ::grpc::ClientContext; @@ -217,6 +229,7 @@ class ServerContext { std::multimap initial_metadata_; std::multimap trailing_metadata_; + bool compression_level_set_; grpc_compression_level compression_level_; grpc_compression_algorithm compression_algorithm_; }; diff --git a/include/grpc++/impl/codegen/service_type.h b/include/grpc++/impl/codegen/service_type.h index c19dfc7d45f..72b22253128 100644 --- a/include/grpc++/impl/codegen/service_type.h +++ b/include/grpc++/impl/codegen/service_type.h @@ -147,6 +147,17 @@ class Service { methods_[index].reset(); } + void MarkMethodStreamedUnary(int index, + MethodHandler* streamed_unary_method) { + GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() && + "Cannot mark an async or generic method Streamed Unary"); + methods_[index]->SetHandler(streamed_unary_method); + + // From the server's point of view, streamed unary is a special + // case of BIDI_STREAMING that has 1 read and 1 write, in that order. + methods_[index]->SetMethodType(::grpc::RpcMethod::BIDI_STREAMING); + } + private: friend class Server; friend class ServerInterface; diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h index cbfa4106995..e1d4660ae77 100644 --- a/include/grpc++/impl/codegen/sync_stream.h +++ b/include/grpc++/impl/codegen/sync_stream.h @@ -64,12 +64,24 @@ class ClientStreamingInterface { virtual Status Finish() = 0; }; +/// Common interface for all synchronous server side streaming. +class ServerStreamingInterface { + public: + virtual ~ServerStreamingInterface() {} + + /// Blocking send initial metadata to client. + virtual void SendInitialMetadata() = 0; +}; + /// An interface that yields a sequence of messages of type \a R. template class ReaderInterface { public: virtual ~ReaderInterface() {} + /// Upper bound on the next message size available for reading on this stream + virtual bool NextMessageSize(uint32_t* sz) = 0; + /// Blocking read a message and parse to \a msg. Returns \a true on success. /// This is thread-safe with respect to \a Write or \WritesDone methods on /// the same stream. It should not be called concurrently with another \a @@ -148,6 +160,11 @@ class ClientReader GRPC_FINAL : public ClientReaderInterface { cq_.Pluck(&ops); /// status ignored } + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = call_.max_message_size(); + return true; + } + bool Read(R* msg) GRPC_OVERRIDE { CallOpSet> ops; if (!context_->initial_metadata_received_) { @@ -293,6 +310,11 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface { cq_.Pluck(&ops); // status ignored } + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = call_.max_message_size(); + return true; + } + bool Read(R* msg) GRPC_OVERRIDE { CallOpSet> ops; if (!context_->initial_metadata_received_) { @@ -336,22 +358,35 @@ class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface { Call call_; }; +/// Server-side interface for streaming reads of message of type \a R. +template +class ServerReaderInterface : public ServerStreamingInterface, + public ReaderInterface {}; + template -class ServerReader GRPC_FINAL : public ReaderInterface { +class ServerReader GRPC_FINAL : public ServerReaderInterface { public: ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {} - void SendInitialMetadata() { + void SendInitialMetadata() GRPC_OVERRIDE { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); CallOpSet ops; ops.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; call_->PerformOps(&ops); call_->cq()->Pluck(&ops); } + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = call_->max_message_size(); + return true; + } + bool Read(R* msg) GRPC_OVERRIDE { CallOpSet> ops; ops.RecvMessage(msg); @@ -364,17 +399,25 @@ class ServerReader GRPC_FINAL : public ReaderInterface { ServerContext* const ctx_; }; +/// Server-side interface for streaming writes of message of type \a W. template -class ServerWriter GRPC_FINAL : public WriterInterface { +class ServerWriterInterface : public ServerStreamingInterface, + public WriterInterface {}; + +template +class ServerWriter GRPC_FINAL : public ServerWriterInterface { public: ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {} - void SendInitialMetadata() { + void SendInitialMetadata() GRPC_OVERRIDE { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); CallOpSet ops; ops.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; call_->PerformOps(&ops); call_->cq()->Pluck(&ops); @@ -389,6 +432,9 @@ class ServerWriter GRPC_FINAL : public WriterInterface { if (!ctx_->sent_initial_metadata_) { ops.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; } call_->PerformOps(&ops); @@ -402,10 +448,17 @@ class ServerWriter GRPC_FINAL : public WriterInterface { /// Server-side interface for bi-directional streaming. template -class ServerReaderWriter GRPC_FINAL : public WriterInterface, - public ReaderInterface { +class ServerReaderWriterInterface : public ServerStreamingInterface, + public WriterInterface, + public ReaderInterface {}; + +// Actual implementation of bi-directional streaming +namespace internal { +template +class ServerReaderWriterBody GRPC_FINAL { public: - ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {} + ServerReaderWriterBody(Call* call, ServerContext* ctx) + : call_(call), ctx_(ctx) {} void SendInitialMetadata() { GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_); @@ -413,20 +466,27 @@ class ServerReaderWriter GRPC_FINAL : public WriterInterface, CallOpSet ops; ops.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; call_->PerformOps(&ops); call_->cq()->Pluck(&ops); } - bool Read(R* msg) GRPC_OVERRIDE { + bool NextMessageSize(uint32_t* sz) { + *sz = call_->max_message_size(); + return true; + } + + bool Read(R* msg) { CallOpSet> ops; ops.RecvMessage(msg); call_->PerformOps(&ops); return call_->cq()->Pluck(&ops) && ops.got_message; } - using WriterInterface::Write; - bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE { + bool Write(const W& msg, const WriteOptions& options) { CallOpSet ops; if (!ops.SendMessage(msg, options).ok()) { return false; @@ -434,6 +494,9 @@ class ServerReaderWriter GRPC_FINAL : public WriterInterface, if (!ctx_->sent_initial_metadata_) { ops.SendInitialMetadata(ctx_->initial_metadata_, ctx_->initial_metadata_flags()); + if (ctx_->compression_level_set()) { + ops.set_compression_level(ctx_->compression_level()); + } ctx_->sent_initial_metadata_ = true; } call_->PerformOps(&ops); @@ -444,6 +507,76 @@ class ServerReaderWriter GRPC_FINAL : public WriterInterface, Call* const call_; ServerContext* const ctx_; }; +} + +// class to represent the user API for a bidirectional streaming call +template +class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface { + public: + ServerReaderWriter(Call* call, ServerContext* ctx) : body_(call, ctx) {} + + void SendInitialMetadata() GRPC_OVERRIDE { body_.SendInitialMetadata(); } + + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + return body_.NextMessageSize(sz); + } + + bool Read(R* msg) GRPC_OVERRIDE { return body_.Read(msg); } + + using WriterInterface::Write; + bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE { + return body_.Write(msg, options); + } + + private: + internal::ServerReaderWriterBody body_; +}; + +/// A class to represent a flow-controlled unary call. This is something +/// of a hybrid between conventional unary and streaming. This is invoked +/// through a unary call on the client side, but the server responds to it +/// as though it were a single-ping-pong streaming call. The server can use +/// the \a NextMessageSize method to determine an upper-bound on the size of +/// the message. +/// A key difference relative to streaming: ServerUnaryStreamer +/// must have exactly 1 Read and exactly 1 Write, in that order, to function +/// correctly. Otherwise, the RPC is in error. +template +class ServerUnaryStreamer GRPC_FINAL + : public ServerReaderWriterInterface { + public: + ServerUnaryStreamer(Call* call, ServerContext* ctx) + : body_(call, ctx), read_done_(false), write_done_(false) {} + + void SendInitialMetadata() GRPC_OVERRIDE { body_.SendInitialMetadata(); } + + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + return body_.NextMessageSize(sz); + } + + bool Read(RequestType* request) GRPC_OVERRIDE { + if (read_done_) { + return false; + } + read_done_ = true; + return body_.Read(request); + } + + using WriterInterface::Write; + bool Write(const ResponseType& response, + const WriteOptions& options) GRPC_OVERRIDE { + if (write_done_ || !read_done_) { + return false; + } + write_done_ = true; + return body_.Write(response, options); + } + + private: + internal::ServerReaderWriterBody body_; + bool read_done_; + bool write_done_; +}; } // namespace grpc diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h new file mode 100644 index 00000000000..7308a1577c8 --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_serializer.h @@ -0,0 +1,219 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H +#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace apache { +namespace thrift { +namespace util { + +using apache::thrift::protocol::TBinaryProtocolT; +using apache::thrift::protocol::TCompactProtocolT; +using apache::thrift::protocol::TMessageType; +using apache::thrift::protocol::TNetworkBigEndian; +using apache::thrift::transport::TMemoryBuffer; +using apache::thrift::transport::TBufferBase; +using apache::thrift::transport::TTransport; + +template +class ThriftSerializer { + public: + ThriftSerializer() + : prepared_(false), + last_deserialized_(false), + serialize_version_(false) {} + + virtual ~ThriftSerializer() {} + + // Serialize the passed type into the internal buffer + // and returns a pointer to internal buffer and its size + template + void Serialize(const T& fields, const uint8_t** serialized_buffer, + size_t* serialized_len) { + // prepare or reset buffer + if (!prepared_ || last_deserialized_) { + prepare(); + } else { + buffer_->resetBuffer(); + } + last_deserialized_ = false; + + // if required serialize protocol version + if (serialize_version_) { + protocol_->writeMessageBegin("", TMessageType(0), 0); + } + + // serialize fields into buffer + fields.write(protocol_.get()); + + // write the end of message + if (serialize_version_) { + protocol_->writeMessageEnd(); + } + + uint8_t* byte_buffer; + uint32_t byte_buffer_size; + buffer_->getBuffer(&byte_buffer, &byte_buffer_size); + *serialized_buffer = byte_buffer; + *serialized_len = byte_buffer_size; + } + + // Serialize the passed type into the byte buffer + template + void Serialize(const T& fields, grpc_byte_buffer** bp) { + const uint8_t* byte_buffer; + size_t byte_buffer_size; + + Serialize(fields, &byte_buffer, &byte_buffer_size); + + gpr_slice slice = gpr_slice_from_copied_buffer( + reinterpret_cast(byte_buffer), byte_buffer_size); + + *bp = grpc_raw_byte_buffer_create(&slice, 1); + + gpr_slice_unref(slice); + } + + // Deserialize the passed char array into the passed type, returns the number + // of bytes that have been consumed from the passed string. + template + uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) { + // prepare buffer if necessary + if (!prepared_) { + prepare(); + } + last_deserialized_ = true; + + // reset buffer transport + buffer_->resetBuffer(serialized_buffer, length); + + // read the protocol version if necessary + if (serialize_version_) { + std::string name = ""; + TMessageType mt = static_cast(0); + int32_t seq_id = 0; + protocol_->readMessageBegin(name, mt, seq_id); + } + + // deserialize buffer into fields + uint32_t len = fields->read(protocol_.get()); + + // read the end of message + if (serialize_version_) { + protocol_->readMessageEnd(); + } + + return len; + } + + // Deserialize the passed byte buffer to passed type, returns the number + // of bytes consumed from byte buffer + template + uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) { + grpc_byte_buffer_reader reader; + grpc_byte_buffer_reader_init(&reader, buffer); + + gpr_slice slice = grpc_byte_buffer_reader_readall(&reader); + + uint32_t len = + Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg); + + gpr_slice_unref(slice); + + grpc_byte_buffer_reader_destroy(&reader); + + return len; + } + + // set serialization version flag + void SetSerializeVersion(bool value) { serialize_version_ = value; } + + // Set the container size limit to deserialize + // This function should be called after buffer_ is initialized + void SetContainerSizeLimit(int32_t container_limit) { + if (!prepared_) { + prepare(); + } + protocol_->setContainerSizeLimit(container_limit); + } + + // Set the string size limit to deserialize + // This function should be called after buffer_ is initialized + void SetStringSizeLimit(int32_t string_limit) { + if (!prepared_) { + prepare(); + } + protocol_->setStringSizeLimit(string_limit); + } + + private: + bool prepared_; + bool last_deserialized_; + boost::shared_ptr buffer_; + std::shared_ptr protocol_; + bool serialize_version_; + + void prepare() { + buffer_ = boost::make_shared(); + // create a protocol for the memory buffer transport + protocol_ = std::make_shared(buffer_); + prepared_ = true; + } + +}; // ThriftSerializer + +typedef ThriftSerializer> + ThriftSerializerBinary; +typedef ThriftSerializer> + ThriftSerializerCompact; + +} // namespace util +} // namespace thrift +} // namespace apache + +#endif \ No newline at end of file diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h new file mode 100644 index 00000000000..7d19b247f4c --- /dev/null +++ b/include/grpc++/impl/codegen/thrift_utils.h @@ -0,0 +1,85 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H +#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace grpc { + +using apache::thrift::util::ThriftSerializerCompact; + +template +class SerializationTraits::value>::type> { + public: + static Status Serialize(const T& msg, grpc_byte_buffer** bp, + bool* own_buffer) { + *own_buffer = true; + + ThriftSerializerCompact serializer; + serializer.Serialize(msg, bp); + + return Status(StatusCode::OK, "ok"); + } + + static Status Deserialize(grpc_byte_buffer* buffer, T* msg, + int max_message_size) { + if (!buffer) { + return Status(StatusCode::INTERNAL, "No payload"); + } + + ThriftSerializerCompact deserializer; + deserializer.Deserialize(buffer, msg); + + grpc_byte_buffer_destroy(buffer); + + return Status(StatusCode::OK, "ok"); + } +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H diff --git a/include/grpc++/impl/server_builder_plugin.h b/include/grpc++/impl/server_builder_plugin.h index 1e157efa111..61632e32fa4 100644 --- a/include/grpc++/impl/server_builder_plugin.h +++ b/include/grpc++/impl/server_builder_plugin.h @@ -41,6 +41,7 @@ namespace grpc { class ServerInitializer; +class ChannelArguments; class ServerBuilderPlugin { public: @@ -58,6 +59,10 @@ class ServerBuilderPlugin { // ServerBuilderOption::UpdatePlugins virtual void ChangeArguments(const grpc::string& name, void* value) = 0; + // UpdateChannelArguments will be called in ServerBuilder::BuildAndStart(), + // before the Server instance is created. + virtual void UpdateChannelArguments(ChannelArguments* args) {} + virtual bool has_sync_methods() const { return false; } virtual bool has_async_methods() const { return false; } }; diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h index 20bd4071091..01249a0b88b 100644 --- a/include/grpc++/support/byte_buffer.h +++ b/include/grpc++/support/byte_buffer.h @@ -72,6 +72,9 @@ class ByteBuffer GRPC_FINAL { /// Buffer size in bytes. size_t Length() const; + /// Swap the state of *this and *other. + void Swap(ByteBuffer* other); + private: friend class SerializationTraits; diff --git a/include/grpc/census.h b/include/grpc/census.h index 39d87ba119c..62ff45d8941 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,9 +56,11 @@ enum census_features { /** Shutdown and startup census subsystem. The 'features' argument should be * the OR (|) of census_features values. If census fails to initialize, then - * census_initialize() will return a non-zero value. It is an error to call - * census_initialize() more than once (without an intervening - * census_shutdown()). */ + * census_initialize() will return -1, otherwise the set of enabled features + * (which may be smaller than that provided in the `features` argument, see + * census_supported()) is returned. It is an error to call census_initialize() + * more than once (without an intervening census_shutdown()). These functions + * are not thread-safe. */ CENSUSAPI int census_initialize(int features); CENSUSAPI void census_shutdown(void); @@ -430,30 +432,44 @@ CENSUSAPI int census_get_trace_record(census_trace_record *trace_record); CENSUSAPI void census_trace_scan_end(); /* Core stats collection API's. The following concepts are used: - * Aggregation: A collection of values. Census supports the following - aggregation types: - Sum - a single summation type. Typically used for keeping (e.g.) - counts of events. - Distribution - statistical distribution information, used for - recording average, standard deviation etc. - Histogram - a histogram of measurements falling in defined bucket - boundaries. - Window - a count of events that happen in reolling time window. - New aggregation types can be added by the user, if desired (see - census_register_aggregation()). - * Metric: Each measurement is for a single metric. Examples include RPC - latency, CPU seconds consumed, and bytes transmitted. - * View: A view is a combination of a metric, a tag set (in which the tag - values are regular expressions) and a set of aggregations. When a - measurement for a metric matches the view tags, it is recorded (for each - unique set of tags) against each aggregation. Each metric can have an - arbitrary number of views by which it will be broken down. + * Resource: Users record measurements for a single resource. Examples + include RPC latency, CPU seconds consumed, and bytes transmitted. + * Aggregation: An aggregation of a set of measurements. Census supports the + following aggregation types: + * Distribution - statistical distribution information, used for + recording average, standard deviation etc. Can include a histogram. + * Interval - a count of events that happen in a rolling time window. + * View: A view is a combination of a Resource, a set of tag keys and an + Aggregation. When a measurement for a Resource matches the View tags, it is + recorded (for each unique set of tag values) using the Aggregation type. + Each resource can have an arbitrary number of views by which it will be + broken down. + + Census uses protos to define each of the above, and output results. This + ensures unification across the different language and runtime + implementations. The proto definitions can be found in src/proto/census. */ +/* Define a new resource. `resource_pb` should contain an encoded Resource + protobuf, `resource_pb_size` being the size of the buffer. Returns a -ve + value on error, or a positive (>= 0) resource id (for use in + census_delete_resource() and census_record_values()). In order to be valid, a + resource must have a name, and at least one numerator in it's unit type. The + resource name must be unique, and an error will be returned if it is not. */ +CENSUSAPI int32_t census_define_resource(const uint8_t *resource_pb, + size_t resource_pb_size); + +/* Delete a resource created by census_define_resource(). */ +CENSUSAPI void census_delete_resource(int32_t resource_id); + +/* Determine the id of a resource, given it's name. returns -1 if the resource + does not exist. */ +CENSUSAPI int32_t census_resource_id(const char *name); + /* A single value to be recorded comprises two parts: an ID for the particular - * metric and the value to be recorded against it. */ + * resource and the value to be recorded against it. */ typedef struct { - uint32_t metric_id; + int32_t resource_id; double value; } census_value; @@ -461,78 +477,6 @@ typedef struct { CENSUSAPI void census_record_values(census_context *context, census_value *values, size_t nvalues); -/** Type representing a particular aggregation */ -typedef struct census_aggregation_ops census_aggregation_ops; - -/* Predefined aggregation types, for use with census_view_create(). */ -extern census_aggregation_ops census_agg_sum; -extern census_aggregation_ops census_agg_distribution; -extern census_aggregation_ops census_agg_histogram; -extern census_aggregation_ops census_agg_window; - -/** Information needed to instantiate a new aggregation. Used in view - construction via census_define_view(). */ -typedef struct { - const census_aggregation_ops *ops; - const void *create_arg; /* Aaggregation initialization argument. */ -} census_aggregation; - -/** A census view type. Opaque. */ -typedef struct census_view census_view; - -/** Create a new view. - @param metric_id Metric with which this view is associated. - @param tags tags that define the view. - @param aggregations aggregations to associate with the view - @param naggregations number of aggregations - - @return A new census view -*/ - -/* TODO(aveitch): consider if context is the right argument type to pass in - tags. */ -CENSUSAPI census_view *census_view_create( - uint32_t metric_id, const census_context *tags, - const census_aggregation *aggregations, size_t naggregations); - -/** Destroy a previously created view. */ -CENSUSAPI void census_view_delete(census_view *view); - -/** Metric ID associated with a view */ -CENSUSAPI size_t census_view_metric(const census_view *view); - -/** Number of aggregations associated with view. */ -CENSUSAPI size_t census_view_naggregations(const census_view *view); - -/** Get tags associated with view. */ -CENSUSAPI const census_context *census_view_tags(const census_view *view); - -/** Get aggregation descriptors associated with a view. */ -CENSUSAPI const census_aggregation *census_view_aggregrations( - const census_view *view); - -/** Holds all the aggregation data for a particular view instantiation. Forms - part of the data returned by census_view_data(). */ -typedef struct { - const census_context *tags; /* Tags for this set of aggregations. */ - const void **data; /* One data set for every aggregation in the view. */ -} census_view_aggregation_data; - -/** Census view data as returned by census_view_get_data(). */ -typedef struct { - size_t n_tag_sets; /* Number of unique tag sets that matched view. */ - const census_view_aggregation_data *data; /* n_tag_sets entries */ -} census_view_data; - -/** Get data from aggregations associated with a view. - @param view View from which to get data. - @return Full set of data for all aggregations for the view. -*/ -CENSUSAPI const census_view_data *census_view_get_data(const census_view *view); - -/** Reset all view data to zero for the specified view */ -CENSUSAPI void census_view_reset(census_view *view); - #ifdef __cplusplus } #endif diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 6f7a67b715e..587d86c98fd 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -90,6 +90,9 @@ GRPCAPI void grpc_shutdown(void); /** Return a string representing the current version of grpc */ GRPCAPI const char *grpc_version_string(void); +/** Return a string specifying what the 'g' in gRPC stands for */ +GRPCAPI const char *grpc_g_stands_for(void); + /** Create a completion queue */ GRPCAPI grpc_completion_queue *grpc_completion_queue_create(void *reserved); @@ -170,8 +173,9 @@ GRPCAPI void grpc_channel_watch_connectivity_state( completions are sent to 'completion_queue'. 'method' and 'host' need only live through the invocation of this function. If parent_call is non-NULL, it must be a server-side call. It will be used - to propagate properties from the server call to this new client call. - */ + to propagate properties from the server call to this new client call, + depending on the value of \a propagation_mask (see propagation_bits.h for + possible values). */ GRPCAPI grpc_call *grpc_channel_create_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, const char *method, @@ -187,7 +191,8 @@ GRPCAPI void *grpc_channel_register_call(grpc_channel *channel, const char *method, const char *host, void *reserved); -/** Create a call given a handle returned from grpc_channel_register_call */ +/** Create a call given a handle returned from grpc_channel_register_call. + \sa grpc_channel_create_call. */ GRPCAPI grpc_call *grpc_channel_create_registered_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_completion_queue *completion_queue, void *registered_call_handle, diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h index 9065d1edd02..3034182d4c5 100644 --- a/include/grpc/impl/codegen/compression_types.h +++ b/include/grpc/impl/codegen/compression_types.h @@ -46,12 +46,27 @@ extern "C" { #define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \ "grpc-internal-encoding-request" -/** To be used in channel arguments */ +/** To be used in channel arguments. + * + * \addtogroup grpc_arg_keys + * \{ */ +/** Default compression algorithm for the channel. + * Its value is an int from the \a grpc_compression_algorithm enum. */ #define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \ "grpc.default_compression_algorithm" +/** Default compression level for the channel. + * Its value is an int from the \a grpc_compression_level enum. */ #define GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL "grpc.default_compression_level" +/** Compression algorithms supported by the channel. + * Its value is a bitset (an int). Bits correspond to algorithms in \a + * grpc_compression_algorithm. For example, its LSB corresponds to + * GRPC_COMPRESS_NONE, the next bit to GRPC_COMPRESS_DEFLATE, etc. + * Unset bits disable support for the algorithm. By default all algorithms are + * supported. It's not possible to disable GRPC_COMPRESS_NONE (the attempt will + * be ignored). */ #define GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET \ "grpc.compression_enabled_algorithms_bitset" +/** \} */ /* The various compression algorithms supported by gRPC */ typedef enum { diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index c0ed1395066..e333b42ad66 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -106,58 +106,71 @@ typedef struct { by grpc_arg; keys are strings to allow easy backwards-compatible extension by arbitrary parties. All evaluation is performed at channel creation time (i.e. the values in - this structure need only live through the creation invocation). */ + this structure need only live through the creation invocation). + + See the description of the \ref grpc_arg_keys "available args" for more + details. */ typedef struct { size_t num_args; grpc_arg *args; } grpc_channel_args; -/* Channel argument keys: */ -/** Enable census for tracing and stats collection */ +/** \defgroup grpc_arg_keys + * Channel argument keys. + * \{ + */ +/** If non-zero, enable census for tracing and stats collection. */ #define GRPC_ARG_ENABLE_CENSUS "grpc.census" -/** Enable load reporting */ +/** If non-zero, enable load reporting. */ #define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting" /** Maximum number of concurrent incoming streams to allow on a http2 - connection */ + connection. Int valued. */ #define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams" -/** Maximum message length that the channel can receive */ +/** Maximum message length that the channel can receive. Int valued, bytes. */ #define GRPC_ARG_MAX_MESSAGE_LENGTH "grpc.max_message_length" -/** Initial sequence number for http2 transports */ +/** Initial sequence number for http2 transports. Int valued. */ #define GRPC_ARG_HTTP2_INITIAL_SEQUENCE_NUMBER \ "grpc.http2.initial_sequence_number" /** Amount to read ahead on individual streams. Defaults to 64kb, larger values can help throughput on high-latency connections. NOTE: at some point we'd like to auto-tune this, and this parameter - will become a no-op. */ + will become a no-op. Int valued, bytes. */ #define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes" -/** How much memory to use for hpack decoding */ +/** How much memory to use for hpack decoding. Int valued, bytes. */ #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \ "grpc.http2.hpack_table_size.decoder" -/** How much memory to use for hpack encoding */ +/** How much memory to use for hpack encoding. Int valued, bytes. */ #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \ "grpc.http2.hpack_table_size.encoder" -/** Default authority to pass if none specified on call construction */ +/** How big a frame are we willing to receive via HTTP2. + Min 16384, max 16777215. + Larger values give lower CPU usage for large messages, but more head of line + blocking for small messages. */ +#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size" +/** Default authority to pass if none specified on call construction. A string. + * */ #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority" /** Primary user agent: goes at the start of the user-agent metadata - sent on each request */ + sent on each request. A string. */ #define GRPC_ARG_PRIMARY_USER_AGENT_STRING "grpc.primary_user_agent" /** Secondary user agent: goes at the end of the user-agent metadata - sent on each request */ + sent on each request. A string. */ #define GRPC_ARG_SECONDARY_USER_AGENT_STRING "grpc.secondary_user_agent" /** The maximum time between subsequent connection attempts, in ms */ #define GRPC_ARG_MAX_RECONNECT_BACKOFF_MS "grpc.max_reconnect_backoff_ms" /* The caller of the secure_channel_create functions may override the target name used for SSL host name checking using this channel argument which is of - type GRPC_ARG_STRING. This *should* be used for testing only. + type \a GRPC_ARG_STRING. This *should* be used for testing only. If this argument is not specified, the name used for SSL host name checking will be the target parameter (assuming that the secure channel is an SSL channel). If this parameter is specified and the underlying is not an SSL channel, it will just be ignored. */ #define GRPC_SSL_TARGET_NAME_OVERRIDE_ARG "grpc.ssl_target_name_override" -/* Maximum metadata size */ +/* Maximum metadata size, in bytes. */ #define GRPC_ARG_MAX_METADATA_SIZE "grpc.max_metadata_size" /** If non-zero, allow the use of SO_REUSEPORT if it's available (default 1) */ #define GRPC_ARG_ALLOW_REUSEPORT "grpc.so_reuseport" +/** \} */ /** Result of a grpc call. If the caller satisfies the prerequisites of a particular operation, the grpc_call_error returned will be GRPC_CALL_OK. @@ -214,10 +227,14 @@ typedef enum grpc_call_error { #define GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST (0x00000010u) /** Signal that the call should not return UNAVAILABLE before it has started */ #define GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY (0x00000020u) +/** Signal that the call is cacheable. GRPC is free to use GET verb */ +#define GRPC_INITIAL_METADATA_CACHEABLE_REQUEST (0x00000040u) + /** Mask of all valid flags */ -#define GRPC_INITIAL_METADATA_USED_MASK \ - (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \ - GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY) +#define GRPC_INITIAL_METADATA_USED_MASK \ + (GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST | \ + GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY | \ + GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) /** A single metadata element */ typedef struct grpc_metadata { diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h index 3ad665a7a29..7c67bad5ae1 100644 --- a/include/grpc/impl/codegen/port_platform.h +++ b/include/grpc/impl/codegen/port_platform.h @@ -119,7 +119,7 @@ // libraries; it should be integrated with the `__linux__` definitions below. #define GPR_PLATFORM_STRING "manylinux" #define GPR_POSIX_CRASH_HANDLER 1 -#define GPR_CPU_LINUX 1 +#define GPR_CPU_POSIX 1 #define GPR_GCC_ATOMIC 1 #define GPR_GCC_TLS 1 #define GPR_LINUX 1 diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h index c684b7587d6..dfc0a774fcc 100644 --- a/include/grpc/impl/codegen/slice.h +++ b/include/grpc/impl/codegen/slice.h @@ -120,6 +120,14 @@ GPRAPI void gpr_slice_unref(gpr_slice s); passed in at destruction. */ GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)); +/* Equivalent to gpr_slice_new, but with a separate pointer that is + passed to the destroy function. This function can be useful when + the data is part of a larger structure that must be destroyed when + the data is no longer needed. */ +GPRAPI gpr_slice gpr_slice_new_with_user_data(void *p, size_t len, + void (*destroy)(void *), + void *user_data); + /* Equivalent to gpr_slice_new, but with a two argument destroy function that also takes the slice length. */ GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len, diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap index ae11a78b74a..02fb2f39b20 100644 --- a/include/grpc/module.modulemap +++ b/include/grpc/module.modulemap @@ -1,5 +1,15 @@ framework module grpc { umbrella header "grpc.h" + + header "byte_buffer_reader.h" + header "grpc_security.h" + header "grpc_security_constants.h" + header "impl/codegen/alloc.h" + header "impl/codegen/byte_buffer_reader.h" + header "support/alloc.h" + header "support/port_platform.h" + header "support/string_util.h" + export * module * { export * } } diff --git a/package.json b/package.json index 0e229c9842b..9afba318162 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "devDependencies": { "async": "^1.5.0", "google-auth-library": "^0.9.2", - "google-protobuf": "^3.0.0-alpha.5", + "google-protobuf": "^3.0.0", "istanbul": "^0.3.21", "jsdoc": "^3.3.2", "jshint": "^2.5.0", diff --git a/package.xml b/package.xml index b5d5f4602a9..93210ee47be 100644 --- a/package.xml +++ b/package.xml @@ -10,11 +10,11 @@ grpc-packages@google.com yes - 2016-07-13 + 2016-08-22 - 1.1.0 - 1.1.0 + 1.1.0dev + 1.1.0dev stable @@ -22,8 +22,7 @@ BSD -- GA release -- Fix shutdown hang problem #4017 +- Reject metadata keys which are not legal #7881 @@ -47,6 +46,7 @@ + @@ -98,6 +98,7 @@ + @@ -125,6 +126,7 @@ + @@ -154,6 +156,7 @@ + @@ -177,7 +180,6 @@ - @@ -185,6 +187,7 @@ + @@ -255,6 +258,7 @@ + @@ -276,7 +280,6 @@ - @@ -305,7 +308,6 @@ - @@ -315,10 +317,11 @@ + - + @@ -328,11 +331,14 @@ + + + @@ -340,6 +346,7 @@ + @@ -420,6 +427,7 @@ + @@ -442,7 +450,6 @@ - @@ -478,7 +485,6 @@ - @@ -490,14 +496,15 @@ + - + @@ -509,8 +516,10 @@ + + @@ -518,6 +527,7 @@ + @@ -1087,8 +1097,8 @@ Update to wrap gRPC C Core version 0.10.0 - 1.0.0 - 1.0.0 + 1.0.0RC1 + 1.0.0RC1 stable @@ -1101,5 +1111,80 @@ Update to wrap gRPC C Core version 0.10.0 - Fix shutdown hang problem #4017 + + + 1.0.0RC2 + 1.0.0RC2 + + + stable + stable + + 2016-07-21 + BSD + +- PHP7 Support #7464 + + + + + 1.0.0RC3 + 1.0.0RC3 + + + stable + stable + + 2016-07-28 + BSD + +- PHP7 Support continued, reduce code duplication #7543 + + + + + 1.0.0RC4 + 1.0.0RC4 + + + stable + stable + + 2016-08-09 + BSD + +- Fixed Ubuntu compile error #7571, #7642 + + + + + 1.0.0 + 1.0.0 + + + stable + stable + + 2016-08-18 + BSD + +- gRPC 1.0.0 release + + + + + 1.1.0dev + 1.1.0dev + + + stable + stable + + 2016-08-22 + BSD + +- Reject metadata keys which are not legal #7881 + + diff --git a/requirements.txt b/requirements.txt index 0ec0e75b762..bf87de07f89 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,6 +3,6 @@ coverage>=4.0 cython>=0.23 enum34>=1.0.4 futures>=2.2.0 -protobuf>=3.0.0a3 +protobuf>=3.0.0 six>=1.10 -wheel>=0.29 \ No newline at end of file +wheel>=0.29 diff --git a/setup.cfg b/setup.cfg index 7194716f61b..dd9161ca8b9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,5 +9,5 @@ build_base=python_build [build_ext] inplace=1 -[build_proto_modules] +[build_package_protos] exclude=.*protoc_plugin/protoc_plugin_test\.proto$ diff --git a/setup.py b/setup.py index 6dbc169053e..f7280952fd1 100644 --- a/setup.py +++ b/setup.py @@ -28,18 +28,19 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """A setup module for the GRPC Python package.""" - +from distutils import cygwinccompiler +from distutils import extension as _extension +from distutils import util import os import os.path +import pkg_resources import platform +import re import shlex import shutil import sys import sysconfig -from distutils import core as _core -from distutils import extension as _extension -import pkg_resources import setuptools from setuptools.command import egg_info @@ -47,24 +48,22 @@ from setuptools.command import egg_info egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in' PY3 = sys.version_info.major == 3 -PYTHON_STEM = './src/python/grpcio' -CORE_INCLUDE = ('./include', '.',) -BORINGSSL_INCLUDE = ('./third_party/boringssl/include',) -ZLIB_INCLUDE = ('./third_party/zlib',) +PYTHON_STEM = os.path.join('src', 'python', 'grpcio') +CORE_INCLUDE = ('include', '.',) +BORINGSSL_INCLUDE = (os.path.join('third_party', 'boringssl', 'include'),) +ZLIB_INCLUDE = (os.path.join('third_party', 'zlib'),) # 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__))) sys.path.insert(0, os.path.abspath(PYTHON_STEM)) # Break import-style to ensure we can actually find our in-repo dependencies. -import _unixccompiler_patch +import _spawn_patch import commands import grpc_core_dependencies import grpc_version -if 'win32' in sys.platform: - _unixccompiler_patch.monkeypatch_unix_compiler() - +_spawn_patch.monkeypatch_spawn() LICENSE = '3-clause BSD' @@ -90,8 +89,8 @@ ENABLE_CYTHON_TRACING = os.environ.get( EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None) EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None) if EXTRA_ENV_COMPILE_ARGS is None: - EXTRA_ENV_COMPILE_ARGS = '-fno-wrapv' - if 'win32' in sys.platform: + EXTRA_ENV_COMPILE_ARGS = '' + if 'win32' in sys.platform and sys.version_info < (3, 5): # We use define flags here and don't directly add to DEFINE_MACROS below to # ensure that the expert user/builder has a way of turning it off (via the # envvars) without adding yet more GRPC-specific envvars. @@ -101,21 +100,21 @@ if EXTRA_ENV_COMPILE_ARGS is None: else: EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64' elif "linux" in sys.platform or "darwin" in sys.platform: - EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden' + EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv' if EXTRA_ENV_LINK_ARGS is None: - EXTRA_ENV_LINK_ARGS = '-lpthread' - if 'win32' in sys.platform: - # TODO(atash) check if this is actually safe to just import and call on - # non-Windows (to avoid breaking import style) - from distutils.cygwinccompiler import get_msvcr - msvcr = get_msvcr()[0] + EXTRA_ENV_LINK_ARGS = '' + if "linux" in sys.platform or "darwin" in sys.platform: + EXTRA_ENV_LINK_ARGS += ' -lpthread' + elif "win32" in sys.platform and sys.version_info < (3, 5): + msvcr = cygwinccompiler.get_msvcr()[0] # TODO(atash) sift through the GCC specs to see if libstdc++ can have any # influence on the linkage outcome on MinGW for non-C++ programs. EXTRA_ENV_LINK_ARGS += ( ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} ' '-static'.format(msvcr=msvcr)) - elif "linux" in sys.platform: + if "linux" in sys.platform: EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy' + EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS) EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS) @@ -123,10 +122,7 @@ CYTHON_EXTENSION_PACKAGE_NAMES = () CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',) -CYTHON_HELPER_C_FILES = ( - os.path.join(PYTHON_STEM, 'grpc/_cython/loader.c'), - os.path.join(PYTHON_STEM, 'grpc/_cython/imports.generated.c'), -) +CYTHON_HELPER_C_FILES = () CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES) @@ -139,13 +135,19 @@ if "linux" in sys.platform: if not "win32" in sys.platform: EXTENSION_LIBRARIES += ('m',) if "win32" in sys.platform: - EXTENSION_LIBRARIES += ('ws2_32',) + EXTENSION_LIBRARIES += ('advapi32', 'ws2_32',) -DEFINE_MACROS = (('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600), ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),) +DEFINE_MACROS = ( + ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600), + ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),) if "win32" in sys.platform: - DEFINE_MACROS += (('OPENSSL_WINDOWS', 1), ('WIN32_LEAN_AND_MEAN', 1),) + DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1),) if '64bit' in platform.architecture()[0]: DEFINE_MACROS += (('MS_WIN64', 1),) + elif sys.version_info >= (3, 5): + # For some reason, this is needed to get access to inet_pton/inet_ntop + # on msvc, but only for 32 bits + DEFINE_MACROS += (('NTDDI_VERSION', 0x06000000),) LDFLAGS = tuple(EXTRA_LINK_ARGS) CFLAGS = tuple(EXTRA_COMPILE_ARGS) @@ -154,7 +156,6 @@ if "linux" in sys.platform or "darwin" in sys.platform: pymodinit = '__attribute__((visibility ("default"))) {}'.format(pymodinit_type) DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),) - # By default, Python3 distutils enforces compatibility of # c plugins (.so files) with the OSX version Python3 was built with. # For Python3.4, this is OSX 10.6, but we need Thread Local Support (__thread) @@ -163,56 +164,32 @@ if 'darwin' in sys.platform and PY3: if mac_target and (pkg_resources.parse_version(mac_target) < pkg_resources.parse_version('10.7.0')): os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7' - - -def cython_extensions(): - module_names = list(CYTHON_EXTENSION_MODULE_NAMES) - extra_sources = list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES) - include_dirs = list(EXTENSION_INCLUDE_DIRECTORIES) - libraries = list(EXTENSION_LIBRARIES) - define_macros = list(DEFINE_MACROS) - build_with_cython = bool(BUILD_WITH_CYTHON) - # Set compiler directives linetrace argument only if we care about tracing; - # this is due to Cython having different behavior between linetrace being - # False and linetrace being unset. See issue #5689. - cython_compiler_directives = {} - if ENABLE_CYTHON_TRACING: - define_macros = define_macros + [('CYTHON_TRACE_NOGIL', 1)] - cython_compiler_directives['linetrace'] = True - pyx_module_files = [os.path.join(PYTHON_STEM, - name.replace('.', '/') + '.pyx') - for name in module_names] - c_module_files = [os.path.join(PYTHON_STEM, - name.replace('.', '/') + '.c') - for name in module_names] - if not build_with_cython: - for module_file in c_module_files: - if not os.path.isfile(module_file): - sys.stderr.write('Cython-generated files are missing; ' - 'forcing Cython build...\n') - build_with_cython = True - break - module_files = pyx_module_files if build_with_cython else c_module_files + os.environ['_PYTHON_HOST_PLATFORM'] = re.sub( + r'macosx-[0-9]+\.[0-9]+-(.+)', + r'macosx-10.7-\1', + util.get_platform()) + +def cython_extensions_and_necessity(): + cython_module_files = [os.path.join(PYTHON_STEM, + name.replace('.', '/') + '.pyx') + for name in CYTHON_EXTENSION_MODULE_NAMES] extensions = [ _extension.Extension( name=module_name, - sources=[module_file] + extra_sources, - include_dirs=include_dirs, libraries=libraries, - define_macros=define_macros, + sources=[module_file] + list(CYTHON_HELPER_C_FILES) + list(CORE_C_FILES), + include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES), + libraries=list(EXTENSION_LIBRARIES), + define_macros=list(DEFINE_MACROS), extra_compile_args=list(CFLAGS), extra_link_args=list(LDFLAGS), - ) for (module_name, module_file) in zip(module_names, module_files) + ) for (module_name, module_file) in zip(list(CYTHON_EXTENSION_MODULE_NAMES), cython_module_files) ] - if build_with_cython: - import Cython.Build - return Cython.Build.cythonize( - extensions, - include_path=include_dirs, - compiler_directives=cython_compiler_directives) - else: - return extensions + need_cython = BUILD_WITH_CYTHON + if not BUILD_WITH_CYTHON: + need_cython = need_cython or not commands.check_and_update_cythonization(extensions) + return commands.try_cythonize(extensions, linetracing=ENABLE_CYTHON_TRACING, mandatory=BUILD_WITH_CYTHON), need_cython -CYTHON_EXTENSION_MODULES = cython_extensions() +CYTHON_EXTENSION_MODULES, need_cython = cython_extensions_and_necessity() PACKAGE_DIRECTORIES = { '': PYTHON_STEM, @@ -224,7 +201,7 @@ INSTALL_REQUIRES = ( 'futures>=2.2.0', # TODO(atash): eventually split the grpcio package into a metapackage # depending on protobuf and the runtime component (independent of protobuf) - 'protobuf>=3.0.0a3', + 'protobuf>=3.0.0', ) SETUP_REQUIRES = INSTALL_REQUIRES + ( @@ -232,6 +209,15 @@ SETUP_REQUIRES = INSTALL_REQUIRES + ( 'sphinx_rtd_theme>=0.1.8', 'six>=1.10', ) +if BUILD_WITH_CYTHON: + sys.stderr.write( + "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, " + "but do not have Cython installed. We won't stop you from using " + "other commands, but the extension files will fail to build.\n") +elif need_cython: + sys.stderr.write( + 'We could not find Cython. Setup may take 10-20 minutes.\n') + SETUP_REQUIRES += ('cython>=0.23',) COMMAND_CLASS = { 'doc': commands.SphinxDocumentation, @@ -242,12 +228,13 @@ COMMAND_CLASS = { } # Ensure that package data is copied over before any commands have been run: -credentials_dir = os.path.join(PYTHON_STEM, 'grpc/_cython/_credentials') +credentials_dir = os.path.join(PYTHON_STEM, 'grpc', '_cython', '_credentials') try: os.mkdir(credentials_dir) except OSError: pass -shutil.copyfile('etc/roots.pem', os.path.join(credentials_dir, 'roots.pem')) +shutil.copyfile(os.path.join('etc', 'roots.pem'), + os.path.join(credentials_dir, 'roots.pem')) PACKAGE_DATA = { # Binaries that may or may not be present in the final installation, but are diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index c386115ec20..d0c35ea1ab3 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -130,6 +130,7 @@ grpc::string GetHeaderIncludes(File *file, const Parameters ¶ms) { static const char *headers_strs[] = { "grpc++/impl/codegen/async_stream.h", "grpc++/impl/codegen/async_unary_call.h", + "grpc++/impl/codegen/method_handler_impl.h", "grpc++/impl/codegen/proto_utils.h", "grpc++/impl/codegen/rpc_method.h", "grpc++/impl/codegen/service_type.h", @@ -604,6 +605,57 @@ void PrintHeaderServerMethodAsync(Printer *printer, const Method *method, printer->Print(*vars, "};\n"); } +void PrintHeaderServerMethodStreamedUnary( + Printer *printer, const Method *method, + std::map *vars) { + (*vars)["Method"] = method->name(); + (*vars)["Request"] = method->input_type_name(); + (*vars)["Response"] = method->output_type_name(); + if (method->NoStreaming()) { + printer->Print(*vars, "template \n"); + printer->Print(*vars, + "class WithStreamedUnaryMethod_$Method$ : " + "public BaseClass {\n"); + printer->Print( + " private:\n" + " void BaseClassMustBeDerivedFromService(const Service *service) " + "{}\n"); + printer->Print(" public:\n"); + printer->Indent(); + printer->Print(*vars, + "WithStreamedUnaryMethod_$Method$() {\n" + " ::grpc::Service::MarkMethodStreamedUnary($Idx$,\n" + " new ::grpc::StreamedUnaryHandler< $Request$, " + "$Response$>(std::bind" + "(&WithStreamedUnaryMethod_$Method$::" + "Streamed$Method$, this, std::placeholders::_1, " + "std::placeholders::_2)));\n" + "}\n"); + printer->Print(*vars, + "~WithStreamedUnaryMethod_$Method$() GRPC_OVERRIDE {\n" + " BaseClassMustBeDerivedFromService(this);\n" + "}\n"); + printer->Print( + *vars, + "// disable regular version of this method\n" + "::grpc::Status $Method$(" + "::grpc::ServerContext* context, const $Request$* request, " + "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n" + " abort();\n" + " return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n" + "}\n"); + printer->Print(*vars, + "// replace default version of method with streamed unary\n" + "virtual ::grpc::Status Streamed$Method$(" + "::grpc::ServerContext* context, " + "::grpc::ServerUnaryStreamer< " + "$Request$,$Response$>* server_unary_streamer)" + " = 0;\n"); + printer->Outdent(); + printer->Print(*vars, "};\n"); + } +} + void PrintHeaderServerMethodGeneric( Printer *printer, const Method *method, std::map *vars) { @@ -770,6 +822,28 @@ void PrintHeaderService(Printer *printer, const Service *service, PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars); } + // Server side - Streamed Unary + for (int i = 0; i < service->method_count(); ++i) { + (*vars)["Idx"] = as_string(i); + PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(), + vars); + } + + printer->Print("typedef "); + for (int i = 0; i < service->method_count(); ++i) { + (*vars)["method_name"] = service->method(i).get()->name(); + if (service->method(i)->NoStreaming()) { + printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<"); + } + } + printer->Print("Service"); + for (int i = 0; i < service->method_count(); ++i) { + if (service->method(i)->NoStreaming()) { + printer->Print(" >"); + } + } + printer->Print(" StreamedUnaryService;\n"); + printer->Outdent(); printer->Print("};\n"); printer->Print(service->GetTrailingComments().c_str()); @@ -1080,6 +1154,9 @@ void PrintSourceService(Printer *printer, const Service *service, (*vars)["Idx"] = as_string(i); if (method->NoStreaming()) { (*vars)["StreamingType"] = "NORMAL_RPC"; + // NOTE: There is no reason to consider streamed-unary as a separate + // category here since this part is setting up the client-side stub + // and this appears as a NORMAL_RPC from the client-side. } else if (method->ClientOnlyStreaming()) { (*vars)["StreamingType"] = "CLIENT_STREAMING"; } else if (method->ServerOnlyStreaming()) { diff --git a/src/compiler/node_generator.cc b/src/compiler/node_generator.cc index c3852020a3a..d7af125c3ae 100644 --- a/src/compiler/node_generator.cc +++ b/src/compiler/node_generator.cc @@ -114,8 +114,8 @@ map GetAllMessages( const MethodDescriptor *method = service->method(method_num); const Descriptor *input_type = method->input_type(); const Descriptor *output_type = method->output_type(); - message_types[input_type->name()] = input_type; - message_types[output_type->name()] = output_type; + message_types[input_type->full_name()] = input_type; + message_types[output_type->full_name()] = output_type; } } return message_types; @@ -127,7 +127,7 @@ grpc::string MessageIdentifierName(const grpc::string &name) { grpc::string NodeObjectPath(const Descriptor *descriptor) { grpc::string module_alias = ModuleAlias(descriptor->file()->name()); - grpc::string name = descriptor->name(); + grpc::string name = descriptor->full_name(); grpc_generator::StripPrefix(&name, descriptor->file()->package() + "."); return module_alias + "." + name; } @@ -135,8 +135,9 @@ grpc::string NodeObjectPath(const Descriptor *descriptor) { // Prints out the message serializer and deserializer functions void PrintMessageTransformer(const Descriptor *descriptor, Printer *out) { map template_vars; - template_vars["identifier_name"] = MessageIdentifierName(descriptor->name()); - template_vars["name"] = descriptor->name(); + grpc::string full_name = descriptor->full_name(); + template_vars["identifier_name"] = MessageIdentifierName(full_name); + template_vars["name"] = full_name; template_vars["node_name"] = NodeObjectPath(descriptor); // Print the serializer out->Print(template_vars, "function serialize_$identifier_name$(arg) {\n"); @@ -169,9 +170,9 @@ void PrintMethod(const MethodDescriptor *method, Printer *out) { vars["service_name"] = method->service()->full_name(); vars["name"] = method->name(); vars["input_type"] = NodeObjectPath(input_type); - vars["input_type_id"] = MessageIdentifierName(input_type->name()); + vars["input_type_id"] = MessageIdentifierName(input_type->full_name()); vars["output_type"] = NodeObjectPath(output_type); - vars["output_type_id"] = MessageIdentifierName(output_type->name()); + vars["output_type_id"] = MessageIdentifierName(output_type->full_name()); vars["client_stream"] = method->client_streaming() ? "true" : "false"; vars["server_stream"] = method->server_streaming() ? "true" : "false"; out->Print("{\n"); diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h index ff6939ed9fe..aa3c22fea6d 100644 --- a/src/compiler/ruby_generator_helpers-inl.h +++ b/src/compiler/ruby_generator_helpers-inl.h @@ -48,7 +48,7 @@ inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file, file->name().find_last_of(".proto") == file->name().size() - 1) { *file_name_or_error = file->name().substr(0, file->name().size() - proto_suffix_length) + - "_services.rb"; + "_services_pb.rb"; return true; } else { *file_name_or_error = "Invalid proto file name: must end with .proto"; @@ -58,7 +58,7 @@ inline bool ServicesFilename(const grpc::protobuf::FileDescriptor *file, inline grpc::string MessagesRequireName( const grpc::protobuf::FileDescriptor *file) { - return Replace(file->name(), ".proto", ""); + return Replace(file->name(), ".proto", "_pb"); } // Get leading or trailing comments in a string. Comment lines start with "# ". diff --git a/src/core/ext/census/base_resources.c b/src/core/ext/census/base_resources.c new file mode 100644 index 00000000000..f9aa4bb9945 --- /dev/null +++ b/src/core/ext/census/base_resources.c @@ -0,0 +1,71 @@ +/* + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/ext/census/base_resources.h" + +#include +#include + +#include +#include + +#include "src/core/ext/census/resource.h" + +// Add base RPC resource definitions for use by RPC runtime. +// +// TODO(aveitch): All of these are currently hardwired definitions encoded in +// the code in this file. These should be converted to use an external +// configuration mechanism, in which these resources are defined in a text +// file, which is compiled to .pb format and read by still-to-be-written +// configuration functions. + +// Define all base resources. This should be called by census initialization. +void define_base_resources() { + google_census_Resource_BasicUnit numerator = + google_census_Resource_BasicUnit_SECS; + resource r = {"client_rpc_latency", // name + "Client RPC latency in seconds", // description + 0, // prefix + 1, // n_numerators + &numerator, // numerators + 0, // n_denominators + NULL}; // denominators + define_resource(&r); + r = (resource){"server_rpc_latency", // name + "Server RPC latency in seconds", // description + 0, // prefix + 1, // n_numerators + &numerator, // numerators + 0, // n_denominators + NULL}; // denominators + define_resource(&r); +} diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/core/ext/census/base_resources.h similarity index 86% rename from src/python/grpcio/grpc/_cython/imports.generated.c rename to src/core/ext/census/base_resources.h index c0080b5a47a..e5a7696db43 100644 --- a/src/python/grpcio/grpc/_cython/imports.generated.c +++ b/src/core/ext/census/base_resources.h @@ -1,5 +1,4 @@ /* - * * Copyright 2016, Google Inc. * All rights reserved. * @@ -31,7 +30,10 @@ * */ -/* TODO(atash) remove cruft */ -#include +#ifndef GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H +#define GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H + +/* Define all base resources. This should be called by census initialization. */ +void define_base_resources(); -#include "imports.generated.h" +#endif /* GRPC_CORE_EXT_CENSUS_BASE_RESOURCES_H */ diff --git a/src/core/ext/census/gen/README.md b/src/core/ext/census/gen/README.md index 72bef6542d0..fdbac1084cd 100644 --- a/src/core/ext/census/gen/README.md +++ b/src/core/ext/census/gen/README.md @@ -4,3 +4,7 @@ Files generated for use by Census stats and trace recording subsystem. * census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto $PWD/src/core/ext/census/gen src/core/ext/census/gen` +* trace_context.pb.{h,c} - Generated from + src/core/ext/census/trace_context.proto, using the script + `tools/codegen/core/gen_nano_proto.sh src/proto/census/trace_context.proto + $PWD/src/core/ext/census/gen src/core/ext/census/gen` diff --git a/src/core/ext/census/gen/census.pb.c b/src/core/ext/census/gen/census.pb.c index d614636c908..647f0635b74 100644 --- a/src/core/ext/census/gen/census.pb.c +++ b/src/core/ext/census/gen/census.pb.c @@ -53,29 +53,24 @@ const pb_field_t google_census_Timestamp_fields[3] = { PB_LAST_FIELD }; -const pb_field_t google_census_Metric_fields[5] = { - PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Metric, name, name, 0), - PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Metric, description, name, 0), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, unit, description, &google_census_Metric_MeasurementUnit_fields), - PB_FIELD( 4, INT32 , OPTIONAL, STATIC , OTHER, google_census_Metric, id, unit, 0), +const pb_field_t google_census_Resource_fields[4] = { + PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Resource, name, name, 0), + PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Resource, description, name, 0), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Resource, unit, description, &google_census_Resource_MeasurementUnit_fields), PB_LAST_FIELD }; -const pb_field_t google_census_Metric_BasicUnit_fields[2] = { - PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, google_census_Metric_BasicUnit, type, type, 0), +const pb_field_t google_census_Resource_MeasurementUnit_fields[4] = { + PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, google_census_Resource_MeasurementUnit, prefix, prefix, 0), + PB_FIELD( 2, UENUM , REPEATED, CALLBACK, OTHER, google_census_Resource_MeasurementUnit, numerator, prefix, 0), + PB_FIELD( 3, UENUM , REPEATED, CALLBACK, OTHER, google_census_Resource_MeasurementUnit, denominator, numerator, 0), PB_LAST_FIELD }; -const pb_field_t google_census_Metric_MeasurementUnit_fields[4] = { - PB_FIELD( 1, INT32 , OPTIONAL, STATIC , FIRST, google_census_Metric_MeasurementUnit, prefix, prefix, 0), - PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, numerator, prefix, &google_census_Metric_BasicUnit_fields), - PB_FIELD( 3, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, denominator, numerator, &google_census_Metric_BasicUnit_fields), - PB_LAST_FIELD -}; - -const pb_field_t google_census_AggregationDescriptor_fields[3] = { - PB_ONEOF_FIELD(options, 1, MESSAGE , ONEOF, STATIC , FIRST, google_census_AggregationDescriptor, bucket_boundaries, bucket_boundaries, &google_census_AggregationDescriptor_BucketBoundaries_fields), - PB_ONEOF_FIELD(options, 2, MESSAGE , ONEOF, STATIC , FIRST, google_census_AggregationDescriptor, interval_boundaries, interval_boundaries, &google_census_AggregationDescriptor_IntervalBoundaries_fields), +const pb_field_t google_census_AggregationDescriptor_fields[4] = { + PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, google_census_AggregationDescriptor, type, type, 0), + PB_ONEOF_FIELD(options, 2, MESSAGE , ONEOF, STATIC , OTHER, google_census_AggregationDescriptor, bucket_boundaries, type, &google_census_AggregationDescriptor_BucketBoundaries_fields), + PB_ONEOF_FIELD(options, 3, MESSAGE , ONEOF, STATIC , OTHER, google_census_AggregationDescriptor, interval_boundaries, type, &google_census_AggregationDescriptor_IntervalBoundaries_fields), PB_LAST_FIELD }; @@ -124,25 +119,27 @@ const pb_field_t google_census_Tag_fields[3] = { const pb_field_t google_census_View_fields[6] = { PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_View, name, name, 0), PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, description, name, 0), - PB_FIELD( 3, INT32 , OPTIONAL, STATIC , OTHER, google_census_View, metric_id, description, 0), - PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_View, aggregation, metric_id, &google_census_AggregationDescriptor_fields), + PB_FIELD( 3, STRING , OPTIONAL, CALLBACK, OTHER, google_census_View, resource_name, description, 0), + PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_View, aggregation, resource_name, &google_census_AggregationDescriptor_fields), PB_FIELD( 5, STRING , REPEATED, CALLBACK, OTHER, google_census_View, tag_key, aggregation, 0), PB_LAST_FIELD }; -const pb_field_t google_census_Aggregation_fields[6] = { +const pb_field_t google_census_Aggregation_fields[7] = { PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Aggregation, name, name, 0), PB_FIELD( 2, STRING , OPTIONAL, CALLBACK, OTHER, google_census_Aggregation, description, name, 0), - PB_ONEOF_FIELD(data, 3, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields), - PB_ONEOF_FIELD(data, 4, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields), - PB_FIELD( 5, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields), + PB_ONEOF_FIELD(data, 3, UINT64 , ONEOF, STATIC , OTHER, google_census_Aggregation, count, description, 0), + PB_ONEOF_FIELD(data, 4, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields), + PB_ONEOF_FIELD(data, 5, MESSAGE , ONEOF, STATIC , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields), + PB_FIELD( 6, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields), PB_LAST_FIELD }; -const pb_field_t google_census_ViewAggregations_fields[4] = { - PB_FIELD( 1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_ViewAggregations, aggregation, aggregation, &google_census_Aggregation_fields), - PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_ViewAggregations, start, aggregation, &google_census_Timestamp_fields), - PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_ViewAggregations, end, start, &google_census_Timestamp_fields), +const pb_field_t google_census_Metric_fields[5] = { + PB_FIELD( 1, STRING , OPTIONAL, CALLBACK, FIRST, google_census_Metric, view_name, view_name, 0), + PB_FIELD( 2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric, aggregation, view_name, &google_census_Aggregation_fields), + PB_FIELD( 3, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, start, aggregation, &google_census_Timestamp_fields), + PB_FIELD( 4, MESSAGE , OPTIONAL, STATIC , OTHER, google_census_Metric, end, start, &google_census_Timestamp_fields), PB_LAST_FIELD }; @@ -156,7 +153,7 @@ const pb_field_t google_census_ViewAggregations_fields[4] = { * numbers or field sizes that are larger than what can fit in 8 or 16 bit * field descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_ViewAggregations, aggregation) < 65536 && pb_membersize(google_census_ViewAggregations, start) < 65536 && pb_membersize(google_census_ViewAggregations, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations) +PB_STATIC_ASSERT((pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Resource, unit) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_Metric, aggregation) < 65536 && pb_membersize(google_census_Metric, start) < 65536 && pb_membersize(google_census_Metric, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Resource_google_census_Resource_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_Metric) #endif #if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) @@ -167,7 +164,7 @@ PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 65536 && pb_member * numbers or field sizes that are larger than what can fit in the default * 8 bit descriptors. */ -PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_ViewAggregations, aggregation) < 256 && pb_membersize(google_census_ViewAggregations, start) < 256 && pb_membersize(google_census_ViewAggregations, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations) +PB_STATIC_ASSERT((pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Resource, unit) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_Metric, aggregation) < 256 && pb_membersize(google_census_Metric, start) < 256 && pb_membersize(google_census_Metric, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Resource_google_census_Resource_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_Metric) #endif diff --git a/src/core/ext/census/gen/census.pb.h b/src/core/ext/census/gen/census.pb.h index d040fe29e74..dae583f33d3 100644 --- a/src/core/ext/census/gen/census.pb.h +++ b/src/core/ext/census/gen/census.pb.h @@ -45,14 +45,21 @@ extern "C" { #endif /* Enum definitions */ -typedef enum _google_census_Metric_BasicUnit_Measure { - google_census_Metric_BasicUnit_Measure_UNKNOWN = 0, - google_census_Metric_BasicUnit_Measure_BITS = 1, - google_census_Metric_BasicUnit_Measure_BYTES = 2, - google_census_Metric_BasicUnit_Measure_SECS = 3, - google_census_Metric_BasicUnit_Measure_CORES = 4, - google_census_Metric_BasicUnit_Measure_MAX_UNITS = 5 -} google_census_Metric_BasicUnit_Measure; +typedef enum _google_census_Resource_BasicUnit { + google_census_Resource_BasicUnit_UNKNOWN = 0, + google_census_Resource_BasicUnit_BITS = 1, + google_census_Resource_BasicUnit_BYTES = 2, + google_census_Resource_BasicUnit_SECS = 3, + google_census_Resource_BasicUnit_CORES = 4, + google_census_Resource_BasicUnit_MAX_UNITS = 5 +} google_census_Resource_BasicUnit; + +typedef enum _google_census_AggregationDescriptor_AggregationType { + google_census_AggregationDescriptor_AggregationType_UNKNOWN = 0, + google_census_AggregationDescriptor_AggregationType_COUNT = 1, + google_census_AggregationDescriptor_AggregationType_DISTRIBUTION = 2, + google_census_AggregationDescriptor_AggregationType_INTERVAL = 3 +} google_census_AggregationDescriptor_AggregationType; /* Struct definitions */ typedef struct _google_census_AggregationDescriptor_BucketBoundaries { @@ -68,6 +75,8 @@ typedef struct _google_census_IntervalStats { } google_census_IntervalStats; typedef struct _google_census_AggregationDescriptor { + bool has_type; + google_census_AggregationDescriptor_AggregationType type; pb_size_t which_options; union { google_census_AggregationDescriptor_BucketBoundaries bucket_boundaries; @@ -89,17 +98,12 @@ typedef struct _google_census_Duration { int32_t nanos; } google_census_Duration; -typedef struct _google_census_Metric_BasicUnit { - bool has_type; - google_census_Metric_BasicUnit_Measure type; -} google_census_Metric_BasicUnit; - -typedef struct _google_census_Metric_MeasurementUnit { +typedef struct _google_census_Resource_MeasurementUnit { bool has_prefix; int32_t prefix; pb_callback_t numerator; pb_callback_t denominator; -} google_census_Metric_MeasurementUnit; +} google_census_Resource_MeasurementUnit; typedef struct _google_census_Tag { bool has_key; @@ -135,37 +139,36 @@ typedef struct _google_census_IntervalStats_Window { } google_census_IntervalStats_Window; typedef struct _google_census_Metric { + pb_callback_t view_name; + pb_callback_t aggregation; + bool has_start; + google_census_Timestamp start; + bool has_end; + google_census_Timestamp end; +} google_census_Metric; + +typedef struct _google_census_Resource { pb_callback_t name; pb_callback_t description; bool has_unit; - google_census_Metric_MeasurementUnit unit; - bool has_id; - int32_t id; -} google_census_Metric; + google_census_Resource_MeasurementUnit unit; +} google_census_Resource; typedef struct _google_census_View { pb_callback_t name; pb_callback_t description; - bool has_metric_id; - int32_t metric_id; + pb_callback_t resource_name; bool has_aggregation; google_census_AggregationDescriptor aggregation; pb_callback_t tag_key; } google_census_View; -typedef struct _google_census_ViewAggregations { - pb_callback_t aggregation; - bool has_start; - google_census_Timestamp start; - bool has_end; - google_census_Timestamp end; -} google_census_ViewAggregations; - typedef struct _google_census_Aggregation { pb_callback_t name; pb_callback_t description; pb_size_t which_data; union { + uint64_t count; google_census_Distribution distribution; google_census_IntervalStats interval_stats; } data; @@ -177,10 +180,9 @@ typedef struct _google_census_Aggregation { /* Initializer values for message structs */ #define google_census_Duration_init_default {false, 0, false, 0} #define google_census_Timestamp_init_default {false, 0, false, 0} -#define google_census_Metric_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_default, false, 0} -#define google_census_Metric_BasicUnit_init_default {false, (google_census_Metric_BasicUnit_Measure)0} -#define google_census_Metric_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} -#define google_census_AggregationDescriptor_init_default {0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}} +#define google_census_Resource_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_default} +#define google_census_Resource_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} +#define google_census_AggregationDescriptor_init_default {false, (google_census_AggregationDescriptor_AggregationType)0, 0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}} #define google_census_AggregationDescriptor_BucketBoundaries_init_default {{{NULL}, NULL}} #define google_census_AggregationDescriptor_IntervalBoundaries_init_default {{{NULL}, NULL}} #define google_census_Distribution_init_default {false, 0, false, 0, false, google_census_Distribution_Range_init_default, {{NULL}, NULL}} @@ -188,15 +190,14 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_init_default {{{NULL}, NULL}} #define google_census_IntervalStats_Window_init_default {false, google_census_Duration_init_default, false, 0, false, 0} #define google_census_Tag_init_default {false, "", false, ""} -#define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}} -#define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_default}, {{NULL}, NULL}} -#define google_census_ViewAggregations_init_default {{{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default} +#define google_census_View_init_default {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}} +#define google_census_Aggregation_init_default {{{NULL}, NULL}, {{NULL}, NULL}, 0, {0}, {{NULL}, NULL}} +#define google_census_Metric_init_default {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default} #define google_census_Duration_init_zero {false, 0, false, 0} #define google_census_Timestamp_init_zero {false, 0, false, 0} -#define google_census_Metric_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_zero, false, 0} -#define google_census_Metric_BasicUnit_init_zero {false, (google_census_Metric_BasicUnit_Measure)0} -#define google_census_Metric_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} -#define google_census_AggregationDescriptor_init_zero {0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}} +#define google_census_Resource_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Resource_MeasurementUnit_init_zero} +#define google_census_Resource_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}} +#define google_census_AggregationDescriptor_init_zero {false, (google_census_AggregationDescriptor_AggregationType)0, 0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}} #define google_census_AggregationDescriptor_BucketBoundaries_init_zero {{{NULL}, NULL}} #define google_census_AggregationDescriptor_IntervalBoundaries_init_zero {{{NULL}, NULL}} #define google_census_Distribution_init_zero {false, 0, false, 0, false, google_census_Distribution_Range_init_zero, {{NULL}, NULL}} @@ -204,25 +205,25 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_init_zero {{{NULL}, NULL}} #define google_census_IntervalStats_Window_init_zero {false, google_census_Duration_init_zero, false, 0, false, 0} #define google_census_Tag_init_zero {false, "", false, ""} -#define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}} -#define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_zero}, {{NULL}, NULL}} -#define google_census_ViewAggregations_init_zero {{{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero} +#define google_census_View_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, {{NULL}, NULL}, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}} +#define google_census_Aggregation_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, 0, {0}, {{NULL}, NULL}} +#define google_census_Metric_init_zero {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero} /* Field tags (for use in manual encoding/decoding) */ #define google_census_AggregationDescriptor_BucketBoundaries_bounds_tag 1 #define google_census_AggregationDescriptor_IntervalBoundaries_window_size_tag 1 #define google_census_IntervalStats_window_tag 1 -#define google_census_AggregationDescriptor_bucket_boundaries_tag 1 +#define google_census_AggregationDescriptor_bucket_boundaries_tag 2 -#define google_census_AggregationDescriptor_interval_boundaries_tag 2 +#define google_census_AggregationDescriptor_interval_boundaries_tag 3 +#define google_census_AggregationDescriptor_type_tag 1 #define google_census_Distribution_Range_min_tag 1 #define google_census_Distribution_Range_max_tag 2 #define google_census_Duration_seconds_tag 1 #define google_census_Duration_nanos_tag 2 -#define google_census_Metric_BasicUnit_type_tag 1 -#define google_census_Metric_MeasurementUnit_prefix_tag 1 -#define google_census_Metric_MeasurementUnit_numerator_tag 2 -#define google_census_Metric_MeasurementUnit_denominator_tag 3 +#define google_census_Resource_MeasurementUnit_prefix_tag 1 +#define google_census_Resource_MeasurementUnit_numerator_tag 2 +#define google_census_Resource_MeasurementUnit_denominator_tag 3 #define google_census_Tag_key_tag 1 #define google_census_Tag_value_tag 2 #define google_census_Timestamp_seconds_tag 1 @@ -234,32 +235,33 @@ typedef struct _google_census_Aggregation { #define google_census_IntervalStats_Window_window_size_tag 1 #define google_census_IntervalStats_Window_count_tag 2 #define google_census_IntervalStats_Window_mean_tag 3 -#define google_census_Metric_name_tag 1 -#define google_census_Metric_description_tag 2 -#define google_census_Metric_unit_tag 3 -#define google_census_Metric_id_tag 4 +#define google_census_Metric_view_name_tag 1 +#define google_census_Metric_aggregation_tag 2 +#define google_census_Metric_start_tag 3 +#define google_census_Metric_end_tag 4 +#define google_census_Resource_name_tag 1 +#define google_census_Resource_description_tag 2 +#define google_census_Resource_unit_tag 3 #define google_census_View_name_tag 1 #define google_census_View_description_tag 2 -#define google_census_View_metric_id_tag 3 +#define google_census_View_resource_name_tag 3 #define google_census_View_aggregation_tag 4 #define google_census_View_tag_key_tag 5 -#define google_census_ViewAggregations_aggregation_tag 1 -#define google_census_ViewAggregations_start_tag 2 -#define google_census_ViewAggregations_end_tag 3 -#define google_census_Aggregation_distribution_tag 3 +#define google_census_Aggregation_count_tag 3 + +#define google_census_Aggregation_distribution_tag 4 -#define google_census_Aggregation_interval_stats_tag 4 +#define google_census_Aggregation_interval_stats_tag 5 #define google_census_Aggregation_name_tag 1 #define google_census_Aggregation_description_tag 2 -#define google_census_Aggregation_tag_tag 5 +#define google_census_Aggregation_tag_tag 6 /* Struct field encoding specification for nanopb */ extern const pb_field_t google_census_Duration_fields[3]; extern const pb_field_t google_census_Timestamp_fields[3]; -extern const pb_field_t google_census_Metric_fields[5]; -extern const pb_field_t google_census_Metric_BasicUnit_fields[2]; -extern const pb_field_t google_census_Metric_MeasurementUnit_fields[4]; -extern const pb_field_t google_census_AggregationDescriptor_fields[3]; +extern const pb_field_t google_census_Resource_fields[4]; +extern const pb_field_t google_census_Resource_MeasurementUnit_fields[4]; +extern const pb_field_t google_census_AggregationDescriptor_fields[4]; extern const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2]; extern const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2]; extern const pb_field_t google_census_Distribution_fields[5]; @@ -268,13 +270,12 @@ extern const pb_field_t google_census_IntervalStats_fields[2]; extern const pb_field_t google_census_IntervalStats_Window_fields[4]; extern const pb_field_t google_census_Tag_fields[3]; extern const pb_field_t google_census_View_fields[6]; -extern const pb_field_t google_census_Aggregation_fields[6]; -extern const pb_field_t google_census_ViewAggregations_fields[4]; +extern const pb_field_t google_census_Aggregation_fields[7]; +extern const pb_field_t google_census_Metric_fields[5]; /* Maximum encoded size of messages (where known) */ #define google_census_Duration_size 22 #define google_census_Timestamp_size 22 -#define google_census_Metric_BasicUnit_size 2 #define google_census_Distribution_Range_size 18 #define google_census_IntervalStats_Window_size 44 #define google_census_Tag_size 516 diff --git a/src/core/ext/census/gen/trace_context.pb.c b/src/core/ext/census/gen/trace_context.pb.c new file mode 100644 index 00000000000..c8aea324cee --- /dev/null +++ b/src/core/ext/census/gen/trace_context.pb.c @@ -0,0 +1,81 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.5-dev */ + +#include "src/core/ext/census/gen/trace_context.pb.h" + +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_trace_TraceId_fields[3] = { + PB_FIELD( 1, FIXED64 , OPTIONAL, STATIC , FIRST, google_trace_TraceId, hi, hi, 0), + PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceId, lo, hi, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_trace_TraceContext_fields[4] = { + PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, google_trace_TraceContext, trace_id, trace_id, &google_trace_TraceId_fields), + PB_FIELD( 2, FIXED64 , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, span_id, trace_id, 0), + PB_FIELD( 3, BOOL , OPTIONAL, STATIC , OTHER, google_trace_TraceContext, is_sampled, span_id, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_trace_TraceContext, trace_id) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_trace_TraceId_google_trace_TraceContext) +#endif + + diff --git a/src/core/ext/census/gen/trace_context.pb.h b/src/core/ext/census/gen/trace_context.pb.h new file mode 100644 index 00000000000..263c4c58cbf --- /dev/null +++ b/src/core/ext/census/gen/trace_context.pb.h @@ -0,0 +1,99 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.5-dev */ + +#ifndef GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H +#define GRPC_CORE_EXT_CENSUS_GEN_TRACE_CONTEXT_PB_H +#include "third_party/nanopb/pb.h" +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Struct definitions */ +typedef struct _google_trace_TraceId { + bool has_hi; + uint64_t hi; + bool has_lo; + uint64_t lo; +} google_trace_TraceId; + +typedef struct _google_trace_TraceContext { + bool has_trace_id; + google_trace_TraceId trace_id; + bool has_span_id; + uint64_t span_id; + bool has_is_sampled; + bool is_sampled; +} google_trace_TraceContext; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_trace_TraceId_init_default {false, 0, false, 0} +#define google_trace_TraceContext_init_default {false, google_trace_TraceId_init_default, false, 0, false, 0} +#define google_trace_TraceId_init_zero {false, 0, false, 0} +#define google_trace_TraceContext_init_zero {false, google_trace_TraceId_init_zero, false, 0, false, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_trace_TraceId_hi_tag 1 +#define google_trace_TraceId_lo_tag 2 +#define google_trace_TraceContext_trace_id_tag 1 +#define google_trace_TraceContext_span_id_tag 2 +#define google_trace_TraceContext_is_sampled_tag 3 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_trace_TraceId_fields[3]; +extern const pb_field_t google_trace_TraceContext_fields[4]; + +/* Maximum encoded size of messages (where known) */ +#define google_trace_TraceId_size 18 +#define google_trace_TraceContext_size 31 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define TRACE_CONTEXT_MESSAGES \ + + +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c index f51d850e013..9dacc17eb4a 100644 --- a/src/core/ext/census/grpc_filter.c +++ b/src/core/ext/census/grpc_filter.c @@ -127,38 +127,40 @@ static void server_start_transport_op(grpc_exec_ctx *exec_ctx, grpc_call_next_op(exec_ctx, elem, op); } -static void client_init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *client_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *d = elem->call_data; GPR_ASSERT(d != NULL); memset(d, 0, sizeof(*d)); d->start_ts = gpr_now(GPR_CLOCK_REALTIME); + return GRPC_ERROR_NONE; } static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *ignored) { call_data *d = elem->call_data; GPR_ASSERT(d != NULL); /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */ } -static void server_init_call_elem(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *server_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *d = elem->call_data; GPR_ASSERT(d != NULL); memset(d, 0, sizeof(*d)); d->start_ts = gpr_now(GPR_CLOCK_REALTIME); /* TODO(hongyu): call census_tracing_start_op here. */ grpc_closure_init(&d->finish_recv, server_on_done_recv, elem); + return GRPC_ERROR_NONE; } static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *ignored) { call_data *d = elem->call_data; GPR_ASSERT(d != NULL); diff --git a/src/core/ext/census/initialize.c b/src/core/ext/census/initialize.c index 896276e44a1..55cbbe8e959 100644 --- a/src/core/ext/census/initialize.c +++ b/src/core/ext/census/initialize.c @@ -32,19 +32,31 @@ */ #include +#include "src/core/ext/census/base_resources.h" +#include "src/core/ext/census/resource.h" static int features_enabled = CENSUS_FEATURE_NONE; int census_initialize(int features) { if (features_enabled != CENSUS_FEATURE_NONE) { // Must have been a previous call to census_initialize; return error - return 1; + return -1; } - features_enabled = features; - return 0; + features_enabled = features & CENSUS_FEATURE_ALL; + if (features & CENSUS_FEATURE_STATS) { + initialize_resources(); + define_base_resources(); + } + + return features_enabled; } -void census_shutdown(void) { features_enabled = CENSUS_FEATURE_NONE; } +void census_shutdown(void) { + if (features_enabled & CENSUS_FEATURE_STATS) { + shutdown_resources(); + } + features_enabled = CENSUS_FEATURE_NONE; +} int census_supported(void) { /* TODO(aveitch): improve this as we implement features... */ diff --git a/src/core/ext/census/placeholders.c b/src/core/ext/census/placeholders.c index fe23d13971a..9f99c5bdcfb 100644 --- a/src/core/ext/census/placeholders.c +++ b/src/core/ext/census/placeholders.c @@ -62,48 +62,3 @@ int census_trace_scan_start(int consume) { (void)consume; abort(); } - -const census_aggregation *census_view_aggregrations(const census_view *view) { - (void)view; - abort(); -} - -census_view *census_view_create(uint32_t metric_id, const census_context *tags, - const census_aggregation *aggregations, - size_t naggregations) { - (void)metric_id; - (void)tags; - (void)aggregations; - (void)naggregations; - abort(); -} - -const census_context *census_view_tags(const census_view *view) { - (void)view; - abort(); -} - -void census_view_delete(census_view *view) { - (void)view; - abort(); -} - -const census_view_data *census_view_get_data(const census_view *view) { - (void)view; - abort(); -} - -size_t census_view_metric(const census_view *view) { - (void)view; - abort(); -} - -size_t census_view_naggregations(const census_view *view) { - (void)view; - abort(); -} - -void census_view_reset(census_view *view) { - (void)view; - abort(); -} diff --git a/src/core/ext/census/resource.c b/src/core/ext/census/resource.c new file mode 100644 index 00000000000..ed44f004f91 --- /dev/null +++ b/src/core/ext/census/resource.c @@ -0,0 +1,312 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/ext/census/resource.h" +#include "third_party/nanopb/pb_decode.h" + +#include +#include +#include +#include + +#include +#include + +// Protect local resource data structures. +static gpr_mu resource_lock; + +// Deleteing and creating resources are relatively rare events, and should not +// be done in the critical path of performance sensitive code. We record +// current resource id's used in a simple array, and just search it each time +// we need to assign a new id, or look up a resource. +static resource **resources = NULL; + +// Number of entries in *resources +static size_t n_resources = 0; + +// Number of defined resources +static size_t n_defined_resources = 0; + +void initialize_resources(void) { + gpr_mu_init(&resource_lock); + gpr_mu_lock(&resource_lock); + GPR_ASSERT(resources == NULL && n_resources == 0 && n_defined_resources == 0); + gpr_mu_unlock(&resource_lock); +} + +// Delete a resource given it's ID. The ID must be a valid resource ID. Must be +// called with resource_lock held. +static void delete_resource_locked(size_t rid) { + GPR_ASSERT(resources[rid] != NULL); + gpr_free(resources[rid]->name); + gpr_free(resources[rid]->description); + gpr_free(resources[rid]->numerators); + gpr_free(resources[rid]->denominators); + gpr_free(resources[rid]); + resources[rid] = NULL; + n_defined_resources--; +} + +void shutdown_resources(void) { + gpr_mu_lock(&resource_lock); + for (size_t i = 0; i < n_resources; i++) { + if (resources[i] != NULL) { + delete_resource_locked(i); + } + } + GPR_ASSERT(n_defined_resources == 0); + gpr_free(resources); + resources = NULL; + n_resources = 0; + gpr_mu_unlock(&resource_lock); +} + +// Check the contents of string fields in a resource proto. +static bool validate_string(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + resource *vresource = (resource *)*arg; + switch (field->tag) { + case google_census_Resource_name_tag: + // Name must have at least one character + if (stream->bytes_left == 0) { + gpr_log(GPR_INFO, "Zero-length Resource name."); + return false; + } + vresource->name = gpr_malloc(stream->bytes_left + 1); + vresource->name[stream->bytes_left] = '\0'; + if (!pb_read(stream, (uint8_t *)vresource->name, stream->bytes_left)) { + return false; + } + // Can't have same name as an existing resource. + for (size_t i = 0; i < n_resources; i++) { + resource *compare = resources[i]; + if (compare == vresource || compare == NULL) continue; + if (strcmp(compare->name, vresource->name) == 0) { + gpr_log(GPR_INFO, "Duplicate Resource name %s.", vresource->name); + return false; + } + } + break; + case google_census_Resource_description_tag: + if (stream->bytes_left == 0) { + return true; + } + vresource->description = gpr_malloc(stream->bytes_left + 1); + vresource->description[stream->bytes_left] = '\0'; + if (!pb_read(stream, (uint8_t *)vresource->description, + stream->bytes_left)) { + return false; + } + break; + default: + // No other string fields in Resource. Print warning and skip. + gpr_log(GPR_INFO, "Unknown string field type in Resource protobuf."); + if (!pb_read(stream, NULL, stream->bytes_left)) { + return false; + } + break; + } + return true; +} + +// Decode numerators/denominators in a stream. The `count` and `bup` +// (BasicUnit pointer) are pointers to the approriate fields in a resource +// struct. +static bool validate_units_helper(pb_istream_t *stream, int *count, + google_census_Resource_BasicUnit **bup) { + while (stream->bytes_left) { + (*count)++; + // Have to allocate a new array of values. Normal case is 0 or 1, so + // this should normally not be an issue. + google_census_Resource_BasicUnit *new_bup = + gpr_malloc((size_t)*count * sizeof(google_census_Resource_BasicUnit)); + if (*count != 1) { + memcpy(new_bup, *bup, + (size_t)(*count - 1) * sizeof(google_census_Resource_BasicUnit)); + gpr_free(*bup); + } + *bup = new_bup; + uint64_t value; + if (!pb_decode_varint(stream, &value)) { + return false; + } + *(*bup + *count - 1) = (google_census_Resource_BasicUnit)value; + } + return true; +} + +// Validate units field of a Resource proto. +static bool validate_units(pb_istream_t *stream, const pb_field_t *field, + void **arg) { + resource *vresource = (resource *)(*arg); + switch (field->tag) { + case google_census_Resource_MeasurementUnit_numerator_tag: + return validate_units_helper(stream, &vresource->n_numerators, + &vresource->numerators); + break; + case google_census_Resource_MeasurementUnit_denominator_tag: + return validate_units_helper(stream, &vresource->n_denominators, + &vresource->denominators); + break; + default: + gpr_log(GPR_ERROR, "Unknown field type."); + return false; + break; + } + return true; +} + +// Validate the contents of a Resource proto. `id` is the intended resource id. +static bool validate_resource_pb(const uint8_t *resource_pb, + size_t resource_pb_size, size_t id) { + GPR_ASSERT(id < n_resources); + if (resource_pb == NULL) { + return false; + } + google_census_Resource vresource; + vresource.name.funcs.decode = &validate_string; + vresource.name.arg = resources[id]; + vresource.description.funcs.decode = &validate_string; + vresource.description.arg = resources[id]; + vresource.unit.numerator.funcs.decode = &validate_units; + vresource.unit.numerator.arg = resources[id]; + vresource.unit.denominator.funcs.decode = &validate_units; + vresource.unit.denominator.arg = resources[id]; + + pb_istream_t stream = + pb_istream_from_buffer((uint8_t *)resource_pb, resource_pb_size); + if (!pb_decode(&stream, google_census_Resource_fields, &vresource)) { + return false; + } + // A Resource must have a name, a unit, with at least one numerator. + return (resources[id]->name != NULL && vresource.has_unit && + resources[id]->n_numerators > 0); +} + +// Allocate a blank resource, and return associated ID. Must be called with +// resource_lock held. +size_t allocate_resource(void) { + // use next_id to optimize expected placement of next new resource. + static size_t next_id = 0; + size_t id = n_resources; // resource ID - initialize to invalid value. + // Expand resources if needed. + if (n_resources == n_defined_resources) { + size_t new_n_resources = n_resources ? n_resources * 2 : 2; + resource **new_resources = gpr_malloc(new_n_resources * sizeof(resource *)); + memcpy(new_resources, resources, n_resources * sizeof(resource *)); + memset(new_resources + n_resources, 0, + (new_n_resources - n_resources) * sizeof(resource *)); + gpr_free(resources); + resources = new_resources; + n_resources = new_n_resources; + id = n_defined_resources; + } else { + GPR_ASSERT(n_defined_resources < n_resources); + // Find a free id. + for (size_t base = 0; base < n_resources; base++) { + id = (next_id + base) % n_resources; + if (resources[id] == NULL) break; + } + } + GPR_ASSERT(id < n_resources && resources[id] == NULL); + resources[id] = gpr_malloc(sizeof(resource)); + memset(resources[id], 0, sizeof(resource)); + n_defined_resources++; + next_id = (id + 1) % n_resources; + return id; +} + +int32_t census_define_resource(const uint8_t *resource_pb, + size_t resource_pb_size) { + if (resource_pb == NULL) { + return -1; + } + gpr_mu_lock(&resource_lock); + size_t id = allocate_resource(); + // Validate pb, extract name. + if (!validate_resource_pb(resource_pb, resource_pb_size, id)) { + delete_resource_locked(id); + gpr_mu_unlock(&resource_lock); + return -1; + } + gpr_mu_unlock(&resource_lock); + return (int32_t)id; +} + +void census_delete_resource(int32_t rid) { + gpr_mu_lock(&resource_lock); + if (rid >= 0 && (size_t)rid < n_resources && resources[rid] != NULL) { + delete_resource_locked((size_t)rid); + } + gpr_mu_unlock(&resource_lock); +} + +int32_t census_resource_id(const char *name) { + gpr_mu_lock(&resource_lock); + for (int32_t id = 0; (size_t)id < n_resources; id++) { + if (resources[id] != NULL && strcmp(resources[id]->name, name) == 0) { + gpr_mu_unlock(&resource_lock); + return id; + } + } + gpr_mu_unlock(&resource_lock); + return -1; +} + +int32_t define_resource(const resource *base) { + GPR_ASSERT(base != NULL && base->name != NULL && base->n_numerators > 0 && + base->numerators != NULL); + gpr_mu_lock(&resource_lock); + size_t id = allocate_resource(); + size_t len = strlen(base->name) + 1; + resources[id]->name = gpr_malloc(len); + memcpy(resources[id]->name, base->name, len); + if (base->description) { + len = strlen(base->description) + 1; + resources[id]->description = gpr_malloc(len); + memcpy(resources[id]->description, base->description, len); + } + resources[id]->prefix = base->prefix; + resources[id]->n_numerators = base->n_numerators; + len = (size_t)base->n_numerators * sizeof(*base->numerators); + resources[id]->numerators = gpr_malloc(len); + memcpy(resources[id]->numerators, base->numerators, len); + resources[id]->n_denominators = base->n_denominators; + if (base->n_denominators != 0) { + len = (size_t)base->n_denominators * sizeof(*base->denominators); + resources[id]->denominators = gpr_malloc(len); + memcpy(resources[id]->denominators, base->denominators, len); + } + gpr_mu_unlock(&resource_lock); + return (int32_t)id; +} diff --git a/src/core/ext/census/resource.h b/src/core/ext/census/resource.h new file mode 100644 index 00000000000..591bff07da5 --- /dev/null +++ b/src/core/ext/census/resource.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* Census-internal resource definition and manipluation functions. */ +#ifndef GRPC_CORE_EXT_CENSUS_RESOURCE_H +#define GRPC_CORE_EXT_CENSUS_RESOURCE_H + +#include +#include "src/core/ext/census/gen/census.pb.h" + +/* Internal representation of a resource. */ +typedef struct { + char *name; + char *description; + int32_t prefix; + int n_numerators; + google_census_Resource_BasicUnit *numerators; + int n_denominators; + google_census_Resource_BasicUnit *denominators; +} resource; + +/* Initialize and shutdown the resources subsystem. */ +void initialize_resources(void); +void shutdown_resources(void); + +/* Add a new resource, given a proposed resource structure. Returns the + resource ID, or -ve on failure. + TODO(aveitch): this function exists to support addition of the base + resources. It should be removed when we have the ability to add resources + from configuration files. */ +int32_t define_resource(const resource *base); + +#endif /* GRPC_CORE_EXT_CENSUS_RESOURCE_H */ diff --git a/src/core/ext/client_config/README.md b/src/core/ext/client_config/README.md index 7024fd540d8..eda01e3e715 100644 --- a/src/core/ext/client_config/README.md +++ b/src/core/ext/client_config/README.md @@ -12,7 +12,7 @@ data might include: - a load balancing policy to decide which server to send a request to - a set of filters to mutate outgoing requests (say, by adding metadata) -The resolver provides this data as a stream of grpc_client_config objects to +The resolver provides this data as a stream of grpc_resolver_result objects to the channel. We represent configuration as a stream so that it can be changed by the resolver during execution, by reacting to external events (such as a new configuration file being pushed to some store). @@ -22,7 +22,7 @@ Load Balancing -------------- Load balancing configuration is provided by a grpc_lb_policy object, stored as -part of grpc_client_config. +part of grpc_resolver_result. The primary job of the load balancing policies is to pick a target server given only the initial metadata for a request. It does this by providing a grpc_subchannel diff --git a/src/core/ext/client_config/channel_connectivity.c b/src/core/ext/client_config/channel_connectivity.c index c1220e3a8c3..ce3c13a4ee3 100644 --- a/src/core/ext/client_config/channel_connectivity.c +++ b/src/core/ext/client_config/channel_connectivity.c @@ -59,7 +59,7 @@ grpc_connectivity_state grpc_channel_check_connectivity_state( } gpr_log(GPR_ERROR, "grpc_channel_check_connectivity_state called on something that is " - "not a (u)client channel, but '%s'", + "not a client channel, but '%s'", client_channel_elem->filter->name); grpc_exec_ctx_finish(&exec_ctx); return GRPC_CHANNEL_SHUTDOWN; diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c index a096435c984..61e012578e0 100644 --- a/src/core/ext/client_config/client_channel.c +++ b/src/core/ext/client_config/client_channel.c @@ -33,6 +33,7 @@ #include "src/core/ext/client_config/client_channel.h" +#include #include #include @@ -41,10 +42,11 @@ #include #include -#include "src/core/ext/client_config/subchannel_call_holder.h" +#include "src/core/ext/client_config/subchannel.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/connected_channel.h" #include "src/core/lib/iomgr/iomgr.h" +#include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/surface/channel.h" @@ -52,30 +54,31 @@ /* Client channel implementation */ -typedef grpc_subchannel_call_holder call_data; +/************************************************************************* + * CHANNEL-WIDE FUNCTIONS + */ typedef struct client_channel_channel_data { /** resolver for this channel */ grpc_resolver *resolver; /** have we started resolving this channel */ - int started_resolving; + bool started_resolving; /** mutex protecting client configuration, including all variables below in this data structure */ - gpr_mu mu_config; - /** currently active load balancer - guarded by mu_config */ + gpr_mu mu; + /** currently active load balancer - guarded by mu */ grpc_lb_policy *lb_policy; - /** incoming configuration - set by resolver.next - guarded by mu_config */ - grpc_client_config *incoming_configuration; + /** incoming resolver result - set by resolver.next(), guarded by mu */ + grpc_resolver_result *resolver_result; /** a list of closures that are all waiting for config to come in */ grpc_closure_list waiting_for_config_closures; /** resolver callback */ - grpc_closure on_config_changed; + grpc_closure on_resolver_result_changed; /** connectivity state being tracked */ grpc_connectivity_state_tracker state_tracker; /** when an lb_policy arrives, should we try to exit idle */ - int exit_idle_when_lb_policy_arrives; + bool exit_idle_when_lb_policy_arrives; /** owning stack */ grpc_channel_stack *owning_stack; /** interested parties (owned) */ @@ -83,10 +86,8 @@ typedef struct client_channel_channel_data { } channel_data; /** We create one watcher for each new lb_policy that is returned from a - resolver, - to watch for state changes from the lb_policy. When a state change is seen, - we - update the channel, and create a new watcher */ + resolver, to watch for state changes from the lb_policy. When a state + change is seen, we update the channel, and create a new watcher. */ typedef struct { channel_data *chand; grpc_closure on_changed; @@ -94,22 +95,6 @@ typedef struct { grpc_lb_policy *lb_policy; } lb_policy_connectivity_watcher; -typedef struct { - grpc_closure closure; - grpc_call_element *elem; -} waiting_call; - -static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { - return grpc_subchannel_call_holder_get_peer(exec_ctx, elem->call_data); -} - -static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, - grpc_call_element *elem, - grpc_transport_stream_op *op) { - GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - grpc_subchannel_call_holder_perform_op(exec_ctx, elem->call_data, op); -} - static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand, grpc_lb_policy *lb_policy, grpc_connectivity_state current_state); @@ -156,9 +141,9 @@ static void on_lb_policy_state_changed(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { lb_policy_connectivity_watcher *w = arg; - gpr_mu_lock(&w->chand->mu_config); + gpr_mu_lock(&w->chand->mu); on_lb_policy_state_changed_locked(exec_ctx, w, error); - gpr_mu_unlock(&w->chand->mu_config); + gpr_mu_unlock(&w->chand->mu); GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy"); gpr_free(w); @@ -178,17 +163,17 @@ static void watch_lb_policy(grpc_exec_ctx *exec_ctx, channel_data *chand, &w->on_changed); } -static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { +static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { channel_data *chand = arg; grpc_lb_policy *lb_policy = NULL; grpc_lb_policy *old_lb_policy; grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; - int exit_idle = 0; + bool exit_idle = false; grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy"); - if (chand->incoming_configuration != NULL) { - lb_policy = grpc_client_config_get_lb_policy(chand->incoming_configuration); + if (chand->resolver_result != NULL) { + lb_policy = grpc_resolver_result_get_lb_policy(chand->resolver_result); if (lb_policy != NULL) { GRPC_LB_POLICY_REF(lb_policy, "channel"); GRPC_LB_POLICY_REF(lb_policy, "config_change"); @@ -197,17 +182,17 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, grpc_lb_policy_check_connectivity(exec_ctx, lb_policy, &state_error); } - grpc_client_config_unref(exec_ctx, chand->incoming_configuration); + grpc_resolver_result_unref(exec_ctx, chand->resolver_result); } - chand->incoming_configuration = NULL; + chand->resolver_result = NULL; if (lb_policy != NULL) { grpc_pollset_set_add_pollset_set(exec_ctx, lb_policy->interested_parties, chand->interested_parties); } - gpr_mu_lock(&chand->mu_config); + gpr_mu_lock(&chand->mu); old_lb_policy = chand->lb_policy; chand->lb_policy = lb_policy; if (lb_policy != NULL) { @@ -222,8 +207,8 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, } if (lb_policy != NULL && chand->exit_idle_when_lb_policy_arrives) { GRPC_LB_POLICY_REF(lb_policy, "exit_idle"); - exit_idle = 1; - chand->exit_idle_when_lb_policy_arrives = 0; + exit_idle = true; + chand->exit_idle_when_lb_policy_arrives = false; } if (error == GRPC_ERROR_NONE && chand->resolver) { @@ -233,10 +218,9 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, watch_lb_policy(exec_ctx, chand, lb_policy, state); } GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - grpc_resolver_next(exec_ctx, chand->resolver, - &chand->incoming_configuration, - &chand->on_config_changed); - gpr_mu_unlock(&chand->mu_config); + grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result, + &chand->on_resolver_result_changed); + gpr_mu_unlock(&chand->mu); } else { if (chand->resolver != NULL) { grpc_resolver_shutdown(exec_ctx, chand->resolver); @@ -249,7 +233,7 @@ static void cc_on_config_changed(grpc_exec_ctx *exec_ctx, void *arg, GRPC_ERROR_CREATE_REFERENCING("Got config after disconnection", refs, GPR_ARRAY_SIZE(refs)), "resolver_gone"); - gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&chand->mu); } if (exit_idle) { @@ -284,7 +268,7 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, op->bind_pollset); } - gpr_mu_lock(&chand->mu_config); + gpr_mu_lock(&chand->mu); if (op->on_connectivity_state_change != NULL) { grpc_connectivity_state_notify_on_state_change( exec_ctx, &chand->state_tracker, op->connectivity_state, @@ -329,7 +313,189 @@ static void cc_start_transport_op(grpc_exec_ctx *exec_ctx, } GRPC_ERROR_UNREF(op->disconnect_with_error); } - gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&chand->mu); +} + +/* Constructor for channel_data */ +static void cc_init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + channel_data *chand = elem->channel_data; + + memset(chand, 0, sizeof(*chand)); + + GPR_ASSERT(args->is_last); + GPR_ASSERT(elem->filter == &grpc_client_channel_filter); + + gpr_mu_init(&chand->mu); + grpc_closure_init(&chand->on_resolver_result_changed, + on_resolver_result_changed, chand); + chand->owning_stack = args->channel_stack; + + grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, + "client_channel"); + chand->interested_parties = grpc_pollset_set_create(); +} + +/* Destructor for channel_data */ +static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + channel_data *chand = elem->channel_data; + + if (chand->resolver != NULL) { + grpc_resolver_shutdown(exec_ctx, chand->resolver); + GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); + } + if (chand->lb_policy != NULL) { + grpc_pollset_set_del_pollset_set(exec_ctx, + chand->lb_policy->interested_parties, + chand->interested_parties); + GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); + } + grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); + grpc_pollset_set_destroy(chand->interested_parties); + gpr_mu_destroy(&chand->mu); +} + +/************************************************************************* + * PER-CALL FUNCTIONS + */ + +#define GET_CALL(call_data) \ + ((grpc_subchannel_call *)(gpr_atm_acq_load(&(call_data)->subchannel_call))) + +#define CANCELLED_CALL ((grpc_subchannel_call *)1) + +typedef enum { + GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING, + GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL +} subchannel_creation_phase; + +/** Call data. Holds a pointer to grpc_subchannel_call and the + associated machinery to create such a pointer. + Handles queueing of stream ops until a call object is ready, waiting + for initial metadata before trying to create a call object, + and handling cancellation gracefully. */ +typedef struct client_channel_call_data { + /** either 0 for no call, 1 for cancelled, or a pointer to a + grpc_subchannel_call */ + gpr_atm subchannel_call; + + gpr_mu mu; + + subchannel_creation_phase creation_phase; + grpc_connected_subchannel *connected_subchannel; + grpc_polling_entity *pollent; + + grpc_transport_stream_op *waiting_ops; + size_t waiting_ops_count; + size_t waiting_ops_capacity; + + grpc_closure next_step; + + grpc_call_stack *owning_call; +} call_data; + +static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) { + GPR_TIMER_BEGIN("add_waiting_locked", 0); + if (calld->waiting_ops_count == calld->waiting_ops_capacity) { + calld->waiting_ops_capacity = GPR_MAX(3, 2 * calld->waiting_ops_capacity); + calld->waiting_ops = + gpr_realloc(calld->waiting_ops, + calld->waiting_ops_capacity * sizeof(*calld->waiting_ops)); + } + calld->waiting_ops[calld->waiting_ops_count++] = *op; + GPR_TIMER_END("add_waiting_locked", 0); +} + +static void fail_locked(grpc_exec_ctx *exec_ctx, call_data *calld, + grpc_error *error) { + size_t i; + for (i = 0; i < calld->waiting_ops_count; i++) { + grpc_transport_stream_op_finish_with_failure( + exec_ctx, &calld->waiting_ops[i], GRPC_ERROR_REF(error)); + } + calld->waiting_ops_count = 0; + GRPC_ERROR_UNREF(error); +} + +typedef struct { + grpc_transport_stream_op *ops; + size_t nops; + grpc_subchannel_call *call; +} retry_ops_args; + +static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) { + retry_ops_args *a = args; + size_t i; + for (i = 0; i < a->nops; i++) { + grpc_subchannel_call_process_op(exec_ctx, a->call, &a->ops[i]); + } + GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops"); + gpr_free(a->ops); + gpr_free(a); +} + +static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) { + retry_ops_args *a = gpr_malloc(sizeof(*a)); + a->ops = calld->waiting_ops; + a->nops = calld->waiting_ops_count; + a->call = GET_CALL(calld); + if (a->call == CANCELLED_CALL) { + gpr_free(a); + fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED); + return; + } + calld->waiting_ops = NULL; + calld->waiting_ops_count = 0; + calld->waiting_ops_capacity = 0; + GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops"); + grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a), + GRPC_ERROR_NONE, NULL); +} + +static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + call_data *calld = arg; + gpr_mu_lock(&calld->mu); + GPR_ASSERT(calld->creation_phase == + GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); + calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + if (calld->connected_subchannel == NULL) { + gpr_atm_no_barrier_store(&calld->subchannel_call, 1); + fail_locked(exec_ctx, calld, GRPC_ERROR_CREATE_REFERENCING( + "Failed to create subchannel", &error, 1)); + } else if (1 == gpr_atm_acq_load(&calld->subchannel_call)) { + /* already cancelled before subchannel became ready */ + fail_locked(exec_ctx, calld, + GRPC_ERROR_CREATE_REFERENCING( + "Cancelled before creating subchannel", &error, 1)); + } else { + grpc_subchannel_call *subchannel_call = NULL; + grpc_error *new_error = grpc_connected_subchannel_create_call( + exec_ctx, calld->connected_subchannel, calld->pollent, + &subchannel_call); + if (new_error != GRPC_ERROR_NONE) { + new_error = grpc_error_add_child(new_error, error); + subchannel_call = CANCELLED_CALL; + fail_locked(exec_ctx, calld, new_error); + } + gpr_atm_rel_store(&calld->subchannel_call, + (gpr_atm)(uintptr_t)subchannel_call); + retry_waiting_locked(exec_ctx, calld); + } + gpr_mu_unlock(&calld->mu); + GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel"); +} + +static char *cc_get_peer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + call_data *calld = elem->call_data; + grpc_subchannel_call *subchannel_call = GET_CALL(calld); + if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) { + return NULL; + } else { + return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call); + } } typedef struct { @@ -341,11 +507,11 @@ typedef struct { grpc_closure closure; } continue_picking_args; -static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *arg, - grpc_metadata_batch *initial_metadata, - uint32_t initial_metadata_flags, - grpc_connected_subchannel **connected_subchannel, - grpc_closure *on_ready); +static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_metadata_batch *initial_metadata, + uint32_t initial_metadata_flags, + grpc_connected_subchannel **connected_subchannel, + grpc_closure *on_ready); static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { @@ -354,22 +520,21 @@ static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg, /* cancelled, do nothing */ } else if (error != GRPC_ERROR_NONE) { grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error), NULL); - } else if (cc_pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata, - cpa->initial_metadata_flags, - cpa->connected_subchannel, cpa->on_ready)) { + } else if (pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata, + cpa->initial_metadata_flags, + cpa->connected_subchannel, cpa->on_ready)) { grpc_exec_ctx_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE, NULL); } gpr_free(cpa); } -static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, - grpc_metadata_batch *initial_metadata, - uint32_t initial_metadata_flags, - grpc_connected_subchannel **connected_subchannel, - grpc_closure *on_ready) { - GPR_TIMER_BEGIN("cc_pick_subchannel", 0); +static bool pick_subchannel(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + grpc_metadata_batch *initial_metadata, + uint32_t initial_metadata_flags, + grpc_connected_subchannel **connected_subchannel, + grpc_closure *on_ready) { + GPR_TIMER_BEGIN("pick_subchannel", 0); - grpc_call_element *elem = elemp; channel_data *chand = elem->channel_data; call_data *calld = elem->call_data; continue_picking_args *cpa; @@ -377,7 +542,7 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, GPR_ASSERT(connected_subchannel); - gpr_mu_lock(&chand->mu_config); + gpr_mu_lock(&chand->mu); if (initial_metadata == NULL) { if (chand->lb_policy != NULL) { grpc_lb_policy_cancel_pick(exec_ctx, chand->lb_policy, @@ -392,28 +557,27 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, GRPC_ERROR_CREATE("Pick cancelled"), NULL); } } - gpr_mu_unlock(&chand->mu_config); - GPR_TIMER_END("cc_pick_subchannel", 0); - return 1; + gpr_mu_unlock(&chand->mu); + GPR_TIMER_END("pick_subchannel", 0); + return true; } if (chand->lb_policy != NULL) { grpc_lb_policy *lb_policy = chand->lb_policy; int r; - GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel"); - gpr_mu_unlock(&chand->mu_config); + GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel"); + gpr_mu_unlock(&chand->mu); r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollent, initial_metadata, initial_metadata_flags, connected_subchannel, on_ready); - GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel"); - GPR_TIMER_END("cc_pick_subchannel", 0); + GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel"); + GPR_TIMER_END("pick_subchannel", 0); return r; } if (chand->resolver != NULL && !chand->started_resolving) { - chand->started_resolving = 1; + chand->started_resolving = true; GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - grpc_resolver_next(exec_ctx, chand->resolver, - &chand->incoming_configuration, - &chand->on_config_changed); + grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result, + &chand->on_resolver_result_changed); } if (chand->resolver != NULL) { cpa = gpr_malloc(sizeof(*cpa)); @@ -429,65 +593,145 @@ static int cc_pick_subchannel(grpc_exec_ctx *exec_ctx, void *elemp, grpc_exec_ctx_sched(exec_ctx, on_ready, GRPC_ERROR_CREATE("Disconnected"), NULL); } - gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&chand->mu); - GPR_TIMER_END("cc_pick_subchannel", 0); - return 0; + GPR_TIMER_END("pick_subchannel", 0); + return false; } -/* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { - grpc_subchannel_call_holder_init(elem->call_data, cc_pick_subchannel, elem, - args->call_stack); -} - -/* Destructor for call_data */ -static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, - void *and_free_memory) { - grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data); - gpr_free(and_free_memory); +// The logic here is fairly complicated, due to (a) the fact that we +// need to handle the case where we receive the send op before the +// initial metadata op, and (b) the need for efficiency, especially in +// the streaming case. +// TODO(ctiller): Explain this more thoroughly. +static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + call_data *calld = elem->call_data; + GRPC_CALL_LOG_OP(GPR_INFO, elem, op); + /* try to (atomically) get the call */ + grpc_subchannel_call *call = GET_CALL(calld); + GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0); + if (call == CANCELLED_CALL) { + grpc_transport_stream_op_finish_with_failure(exec_ctx, op, + GRPC_ERROR_CANCELLED); + GPR_TIMER_END("cc_start_transport_stream_op", 0); + return; + } + if (call != NULL) { + grpc_subchannel_call_process_op(exec_ctx, call, op); + GPR_TIMER_END("cc_start_transport_stream_op", 0); + return; + } + /* we failed; lock and figure out what to do */ + gpr_mu_lock(&calld->mu); +retry: + /* need to recheck that another thread hasn't set the call */ + call = GET_CALL(calld); + if (call == CANCELLED_CALL) { + gpr_mu_unlock(&calld->mu); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op, + GRPC_ERROR_CANCELLED); + GPR_TIMER_END("cc_start_transport_stream_op", 0); + return; + } + if (call != NULL) { + gpr_mu_unlock(&calld->mu); + grpc_subchannel_call_process_op(exec_ctx, call, op); + GPR_TIMER_END("cc_start_transport_stream_op", 0); + return; + } + /* if this is a cancellation, then we can raise our cancelled flag */ + if (op->cancel_error != GRPC_ERROR_NONE) { + if (!gpr_atm_rel_cas(&calld->subchannel_call, 0, + (gpr_atm)(uintptr_t)CANCELLED_CALL)) { + goto retry; + } else { + switch (calld->creation_phase) { + case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING: + fail_locked(exec_ctx, calld, GRPC_ERROR_REF(op->cancel_error)); + break; + case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL: + pick_subchannel(exec_ctx, elem, NULL, 0, &calld->connected_subchannel, + NULL); + break; + } + gpr_mu_unlock(&calld->mu); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op, + GRPC_ERROR_CANCELLED); + GPR_TIMER_END("cc_start_transport_stream_op", 0); + return; + } + } + /* if we don't have a subchannel, try to get one */ + if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && + calld->connected_subchannel == NULL && + op->send_initial_metadata != NULL) { + calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; + grpc_closure_init(&calld->next_step, subchannel_ready, calld); + GRPC_CALL_STACK_REF(calld->owning_call, "pick_subchannel"); + if (pick_subchannel(exec_ctx, elem, op->send_initial_metadata, + op->send_initial_metadata_flags, + &calld->connected_subchannel, &calld->next_step)) { + calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel"); + } + } + /* if we've got a subchannel, then let's ask it to create a call */ + if (calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && + calld->connected_subchannel != NULL) { + grpc_subchannel_call *subchannel_call = NULL; + grpc_error *error = grpc_connected_subchannel_create_call( + exec_ctx, calld->connected_subchannel, calld->pollent, + &subchannel_call); + if (error != GRPC_ERROR_NONE) { + subchannel_call = CANCELLED_CALL; + fail_locked(exec_ctx, calld, GRPC_ERROR_REF(error)); + grpc_transport_stream_op_finish_with_failure(exec_ctx, op, error); + } + gpr_atm_rel_store(&calld->subchannel_call, + (gpr_atm)(uintptr_t)subchannel_call); + retry_waiting_locked(exec_ctx, calld); + goto retry; + } + /* nothing to be done but wait */ + add_waiting_locked(calld, op); + gpr_mu_unlock(&calld->mu); + GPR_TIMER_END("cc_start_transport_stream_op", 0); } -/* Constructor for channel_data */ -static void init_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem, - grpc_channel_element_args *args) { - channel_data *chand = elem->channel_data; - - memset(chand, 0, sizeof(*chand)); - - GPR_ASSERT(args->is_last); - GPR_ASSERT(elem->filter == &grpc_client_channel_filter); - - gpr_mu_init(&chand->mu_config); - grpc_closure_init(&chand->on_config_changed, cc_on_config_changed, chand); - chand->owning_stack = args->channel_stack; - - grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE, - "client_channel"); - chand->interested_parties = grpc_pollset_set_create(); +/* Constructor for call_data */ +static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + call_data *calld = elem->call_data; + gpr_atm_rel_store(&calld->subchannel_call, 0); + gpr_mu_init(&calld->mu); + calld->connected_subchannel = NULL; + calld->waiting_ops = NULL; + calld->waiting_ops_count = 0; + calld->waiting_ops_capacity = 0; + calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; + calld->owning_call = args->call_stack; + calld->pollent = NULL; + return GRPC_ERROR_NONE; } -/* Destructor for channel_data */ -static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, - grpc_channel_element *elem) { - channel_data *chand = elem->channel_data; - - if (chand->resolver != NULL) { - grpc_resolver_shutdown(exec_ctx, chand->resolver); - GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel"); - } - if (chand->lb_policy != NULL) { - grpc_pollset_set_del_pollset_set(exec_ctx, - chand->lb_policy->interested_parties, - chand->interested_parties); - GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); +/* Destructor for call_data */ +static void cc_destroy_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + const grpc_call_final_info *final_info, + void *and_free_memory) { + call_data *calld = elem->call_data; + grpc_subchannel_call *call = GET_CALL(calld); + if (call != NULL && call != CANCELLED_CALL) { + GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call"); } - grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker); - grpc_pollset_set_destroy(chand->interested_parties); - gpr_mu_destroy(&chand->mu_config); + GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING); + gpr_mu_destroy(&calld->mu); + GPR_ASSERT(calld->waiting_ops_count == 0); + gpr_free(calld->waiting_ops); + gpr_free(and_free_memory); } static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, @@ -497,16 +741,20 @@ static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, calld->pollent = pollent; } +/************************************************************************* + * EXPORTED SYMBOLS + */ + const grpc_channel_filter grpc_client_channel_filter = { cc_start_transport_stream_op, cc_start_transport_op, sizeof(call_data), - init_call_elem, + cc_init_call_elem, cc_set_pollset_or_pollset_set, - destroy_call_elem, + cc_destroy_call_elem, sizeof(channel_data), - init_channel_elem, - destroy_channel_elem, + cc_init_channel_elem, + cc_destroy_channel_elem, cc_get_peer, "client-channel", }; @@ -517,41 +765,40 @@ void grpc_client_channel_set_resolver(grpc_exec_ctx *exec_ctx, /* post construction initialization: set the transport setup pointer */ grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack); channel_data *chand = elem->channel_data; - gpr_mu_lock(&chand->mu_config); + gpr_mu_lock(&chand->mu); GPR_ASSERT(!chand->resolver); chand->resolver = resolver; GRPC_RESOLVER_REF(resolver, "channel"); if (!grpc_closure_list_empty(chand->waiting_for_config_closures) || chand->exit_idle_when_lb_policy_arrives) { - chand->started_resolving = 1; + chand->started_resolving = true; GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - grpc_resolver_next(exec_ctx, resolver, &chand->incoming_configuration, - &chand->on_config_changed); + grpc_resolver_next(exec_ctx, resolver, &chand->resolver_result, + &chand->on_resolver_result_changed); } - gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&chand->mu); } grpc_connectivity_state grpc_client_channel_check_connectivity_state( grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) { channel_data *chand = elem->channel_data; grpc_connectivity_state out; - gpr_mu_lock(&chand->mu_config); + gpr_mu_lock(&chand->mu); out = grpc_connectivity_state_check(&chand->state_tracker, NULL); if (out == GRPC_CHANNEL_IDLE && try_to_connect) { if (chand->lb_policy != NULL) { grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy); } else { - chand->exit_idle_when_lb_policy_arrives = 1; + chand->exit_idle_when_lb_policy_arrives = true; if (!chand->started_resolving && chand->resolver != NULL) { GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver"); - chand->started_resolving = 1; - grpc_resolver_next(exec_ctx, chand->resolver, - &chand->incoming_configuration, - &chand->on_config_changed); + chand->started_resolving = true; + grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result, + &chand->on_resolver_result_changed); } } } - gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&chand->mu); return out; } @@ -586,8 +833,8 @@ void grpc_client_channel_watch_connectivity_state( grpc_closure_init(&w->my_closure, on_external_watch_complete, w); GRPC_CHANNEL_STACK_REF(w->chand->owning_stack, "external_connectivity_watcher"); - gpr_mu_lock(&chand->mu_config); + gpr_mu_lock(&chand->mu); grpc_connectivity_state_notify_on_state_change( exec_ctx, &chand->state_tracker, state, &w->my_closure); - gpr_mu_unlock(&chand->mu_config); + gpr_mu_unlock(&chand->mu); } diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h index 3cfd041d3a9..a2f5446fc6c 100644 --- a/src/core/ext/client_config/lb_policy.h +++ b/src/core/ext/client_config/lb_policy.h @@ -73,7 +73,7 @@ struct grpc_lb_policy_vtable { void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_closure *closure); - /** try to enter a READY connectivity state */ + /** Try to enter a READY connectivity state */ void (*exit_idle)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); /** check the current connectivity of the lb_policy */ @@ -82,7 +82,9 @@ struct grpc_lb_policy_vtable { grpc_error **connectivity_error); /** call notify when the connectivity state of a channel changes from *state. - Updates *state with the new state of the policy */ + Updates *state with the new state of the policy. Calling with a NULL \a + state cancels the subscription. + */ void (*notify_on_state_change)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connectivity_state *state, @@ -125,7 +127,7 @@ void grpc_lb_policy_init(grpc_lb_policy *policy, /** Given initial metadata in \a initial_metadata, find an appropriate target for this rpc, and 'return' it by calling \a on_complete after setting \a target. - Picking can be asynchronous. Any IO should be done under \a pollset. */ + Picking can be asynchronous. Any IO should be done under \a pollent. */ int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_polling_entity *pollent, grpc_metadata_batch *initial_metadata, @@ -147,8 +149,11 @@ void grpc_lb_policy_cancel_picks(grpc_exec_ctx *exec_ctx, uint32_t initial_metadata_flags_mask, uint32_t initial_metadata_flags_eq); +/** Try to enter a READY connectivity state */ void grpc_lb_policy_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy); +/* Call notify when the connectivity state of a channel changes from \a *state. + * Updates \a *state with the new state of the policy */ void grpc_lb_policy_notify_on_state_change(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy, grpc_connectivity_state *state, diff --git a/src/core/ext/client_config/lb_policy_factory.h b/src/core/ext/client_config/lb_policy_factory.h index 1c89b28b59a..da1de3579a0 100644 --- a/src/core/ext/client_config/lb_policy_factory.h +++ b/src/core/ext/client_config/lb_policy_factory.h @@ -43,8 +43,6 @@ typedef struct grpc_lb_policy_factory grpc_lb_policy_factory; typedef struct grpc_lb_policy_factory_vtable grpc_lb_policy_factory_vtable; -/** grpc_lb_policy provides grpc_client_config objects to grpc_channel - objects */ struct grpc_lb_policy_factory { const grpc_lb_policy_factory_vtable *vtable; }; diff --git a/src/core/ext/client_config/resolver.c b/src/core/ext/client_config/resolver.c index eb004455bd0..7534ea62af5 100644 --- a/src/core/ext/client_config/resolver.c +++ b/src/core/ext/client_config/resolver.c @@ -76,7 +76,7 @@ void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx, } void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, + grpc_resolver_result **result, grpc_closure *on_complete) { - resolver->vtable->next(exec_ctx, resolver, target_config, on_complete); + resolver->vtable->next(exec_ctx, resolver, result, on_complete); } diff --git a/src/core/ext/client_config/resolver.h b/src/core/ext/client_config/resolver.h index 6ecb5d2774f..88ac262d513 100644 --- a/src/core/ext/client_config/resolver.h +++ b/src/core/ext/client_config/resolver.h @@ -34,14 +34,14 @@ #ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H #define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H -#include "src/core/ext/client_config/client_config.h" +#include "src/core/ext/client_config/resolver_result.h" #include "src/core/ext/client_config/subchannel.h" #include "src/core/lib/iomgr/iomgr.h" typedef struct grpc_resolver grpc_resolver; typedef struct grpc_resolver_vtable grpc_resolver_vtable; -/** grpc_resolver provides grpc_client_config objects to grpc_channel +/** grpc_resolver provides grpc_resolver_result objects to grpc_channel objects */ struct grpc_resolver { const grpc_resolver_vtable *vtable; @@ -53,7 +53,7 @@ struct grpc_resolver_vtable { void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); void (*channel_saw_error)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); void (*next)(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, grpc_closure *on_complete); + grpc_resolver_result **result, grpc_closure *on_complete); }; #ifdef GRPC_RESOLVER_REFCOUNT_DEBUG @@ -82,13 +82,13 @@ void grpc_resolver_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver); /** Get the next client config. Called by the channel to fetch a new - configuration. Expected to set *target_config with a new configuration, + configuration. Expected to set *result with a new configuration, and then schedule on_complete for execution. - If resolution is fatally broken, set *target_config to NULL and + If resolution is fatally broken, set *result to NULL and schedule on_complete. */ void grpc_resolver_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, + grpc_resolver_result **result, grpc_closure *on_complete); #endif /* GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_H */ diff --git a/src/core/ext/client_config/resolver_factory.h b/src/core/ext/client_config/resolver_factory.h index 4eb6979aad8..f69bf795649 100644 --- a/src/core/ext/client_config/resolver_factory.h +++ b/src/core/ext/client_config/resolver_factory.h @@ -41,7 +41,7 @@ typedef struct grpc_resolver_factory grpc_resolver_factory; typedef struct grpc_resolver_factory_vtable grpc_resolver_factory_vtable; -/** grpc_resolver provides grpc_client_config objects to grpc_channel +/** grpc_resolver provides grpc_resolver_result objects to grpc_channel objects */ struct grpc_resolver_factory { const grpc_resolver_factory_vtable *vtable; diff --git a/src/core/ext/client_config/client_config.c b/src/core/ext/client_config/resolver_result.c similarity index 73% rename from src/core/ext/client_config/client_config.c rename to src/core/ext/client_config/resolver_result.c index f9b8e686988..c6c4166e834 100644 --- a/src/core/ext/client_config/client_config.c +++ b/src/core/ext/client_config/resolver_result.c @@ -31,44 +31,45 @@ * */ -#include "src/core/ext/client_config/client_config.h" +#include "src/core/ext/client_config/resolver_result.h" #include #include -struct grpc_client_config { +struct grpc_resolver_result { gpr_refcount refs; grpc_lb_policy *lb_policy; }; -grpc_client_config *grpc_client_config_create() { - grpc_client_config *c = gpr_malloc(sizeof(*c)); +grpc_resolver_result *grpc_resolver_result_create() { + grpc_resolver_result *c = gpr_malloc(sizeof(*c)); memset(c, 0, sizeof(*c)); gpr_ref_init(&c->refs, 1); return c; } -void grpc_client_config_ref(grpc_client_config *c) { gpr_ref(&c->refs); } +void grpc_resolver_result_ref(grpc_resolver_result *c) { gpr_ref(&c->refs); } -void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, grpc_client_config *c) { +void grpc_resolver_result_unref(grpc_exec_ctx *exec_ctx, + grpc_resolver_result *c) { if (gpr_unref(&c->refs)) { if (c->lb_policy != NULL) { - GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "client_config"); + GRPC_LB_POLICY_UNREF(exec_ctx, c->lb_policy, "resolver_result"); } gpr_free(c); } } -void grpc_client_config_set_lb_policy(grpc_client_config *c, - grpc_lb_policy *lb_policy) { +void grpc_resolver_result_set_lb_policy(grpc_resolver_result *c, + grpc_lb_policy *lb_policy) { GPR_ASSERT(c->lb_policy == NULL); if (lb_policy) { - GRPC_LB_POLICY_REF(lb_policy, "client_config"); + GRPC_LB_POLICY_REF(lb_policy, "resolver_result"); } c->lb_policy = lb_policy; } -grpc_lb_policy *grpc_client_config_get_lb_policy(grpc_client_config *c) { +grpc_lb_policy *grpc_resolver_result_get_lb_policy(grpc_resolver_result *c) { return c->lb_policy; } diff --git a/src/core/ext/client_config/client_config.h b/src/core/ext/client_config/resolver_result.h similarity index 68% rename from src/core/ext/client_config/client_config.h rename to src/core/ext/client_config/resolver_result.h index a6290cbcf00..402f7dbd7e6 100644 --- a/src/core/ext/client_config/client_config.h +++ b/src/core/ext/client_config/resolver_result.h @@ -31,23 +31,22 @@ * */ -#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_CLIENT_CONFIG_H -#define GRPC_CORE_EXT_CLIENT_CONFIG_CLIENT_CONFIG_H +#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H +#define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H #include "src/core/ext/client_config/lb_policy.h" -/** Total configuration for a client. Provided, and updated, by - grpc_resolver */ -typedef struct grpc_client_config grpc_client_config; +/** Results reported from a grpc_resolver. */ +typedef struct grpc_resolver_result grpc_resolver_result; -grpc_client_config *grpc_client_config_create(); -void grpc_client_config_ref(grpc_client_config *client_config); -void grpc_client_config_unref(grpc_exec_ctx *exec_ctx, - grpc_client_config *client_config); +grpc_resolver_result *grpc_resolver_result_create(); +void grpc_resolver_result_ref(grpc_resolver_result *client_config); +void grpc_resolver_result_unref(grpc_exec_ctx *exec_ctx, + grpc_resolver_result *client_config); -void grpc_client_config_set_lb_policy(grpc_client_config *client_config, - grpc_lb_policy *lb_policy); -grpc_lb_policy *grpc_client_config_get_lb_policy( - grpc_client_config *client_config); +void grpc_resolver_result_set_lb_policy(grpc_resolver_result *client_config, + grpc_lb_policy *lb_policy); +grpc_lb_policy *grpc_resolver_result_get_lb_policy( + grpc_resolver_result *client_config); -#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_CLIENT_CONFIG_H */ +#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_RESULT_H */ diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c index d089cd4399e..df35904b85d 100644 --- a/src/core/ext/client_config/subchannel.c +++ b/src/core/ext/client_config/subchannel.c @@ -702,19 +702,26 @@ grpc_connected_subchannel *grpc_subchannel_get_connected_subchannel( return GET_CONNECTED_SUBCHANNEL(c, acq); } -grpc_subchannel_call *grpc_connected_subchannel_create_call( +grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con, - grpc_polling_entity *pollent) { + grpc_polling_entity *pollent, grpc_subchannel_call **call) { grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con); - grpc_subchannel_call *call = - gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); - grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call); - call->connection = con; + *call = gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size); + grpc_call_stack *callstk = SUBCHANNEL_CALL_TO_CALL_STACK(*call); + (*call)->connection = con; // Ref is added below. + grpc_error *error = + grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, *call, + NULL, NULL, callstk); + if (error != GRPC_ERROR_NONE) { + const char *error_string = grpc_error_string(error); + gpr_log(GPR_ERROR, "error: %s", error_string); + grpc_error_free_string(error_string); + gpr_free(*call); + return error; + } GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call"); - grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call, - NULL, NULL, callstk); grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent); - return call; + return GRPC_ERROR_NONE; } grpc_call_stack *grpc_subchannel_call_get_call_stack( diff --git a/src/core/ext/client_config/subchannel.h b/src/core/ext/client_config/subchannel.h index b6d39f5dc52..ae1d96e6400 100644 --- a/src/core/ext/client_config/subchannel.h +++ b/src/core/ext/client_config/subchannel.h @@ -108,9 +108,9 @@ void grpc_subchannel_call_unref(grpc_exec_ctx *exec_ctx, GRPC_SUBCHANNEL_REF_EXTRA_ARGS); /** construct a subchannel call */ -grpc_subchannel_call *grpc_connected_subchannel_create_call( +grpc_error *grpc_connected_subchannel_create_call( grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel, - grpc_polling_entity *pollent); + grpc_polling_entity *pollent, grpc_subchannel_call **subchannel_call); /** process a transport level op */ void grpc_connected_subchannel_process_transport_op( diff --git a/src/core/ext/client_config/subchannel_call_holder.c b/src/core/ext/client_config/subchannel_call_holder.c deleted file mode 100644 index b96a0ad0937..00000000000 --- a/src/core/ext/client_config/subchannel_call_holder.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "src/core/ext/client_config/subchannel_call_holder.h" - -#include - -#include "src/core/lib/profiling/timers.h" - -#define GET_CALL(holder) \ - ((grpc_subchannel_call *)(gpr_atm_acq_load(&(holder)->subchannel_call))) - -#define CANCELLED_CALL ((grpc_subchannel_call *)1) - -static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *holder, - grpc_error *error); -static void retry_ops(grpc_exec_ctx *exec_ctx, void *retry_ops_args, - grpc_error *error); - -static void add_waiting_locked(grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op); -static void fail_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder, grpc_error *error); -static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); - -void grpc_subchannel_call_holder_init( - grpc_subchannel_call_holder *holder, - grpc_subchannel_call_holder_pick_subchannel pick_subchannel, - void *pick_subchannel_arg, grpc_call_stack *owning_call) { - gpr_atm_rel_store(&holder->subchannel_call, 0); - holder->pick_subchannel = pick_subchannel; - holder->pick_subchannel_arg = pick_subchannel_arg; - gpr_mu_init(&holder->mu); - holder->connected_subchannel = NULL; - holder->waiting_ops = NULL; - holder->waiting_ops_count = 0; - holder->waiting_ops_capacity = 0; - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - holder->owning_call = owning_call; - holder->pollent = NULL; -} - -void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder) { - grpc_subchannel_call *call = GET_CALL(holder); - if (call != NULL && call != CANCELLED_CALL) { - GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "holder"); - } - GPR_ASSERT(holder->creation_phase == - GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING); - gpr_mu_destroy(&holder->mu); - GPR_ASSERT(holder->waiting_ops_count == 0); - gpr_free(holder->waiting_ops); -} - -void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op) { - /* try to (atomically) get the call */ - grpc_subchannel_call *call = GET_CALL(holder); - GPR_TIMER_BEGIN("grpc_subchannel_call_holder_perform_op", 0); - if (call == CANCELLED_CALL) { - grpc_transport_stream_op_finish_with_failure(exec_ctx, op, - GRPC_ERROR_CANCELLED); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - if (call != NULL) { - grpc_subchannel_call_process_op(exec_ctx, call, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - /* we failed; lock and figure out what to do */ - gpr_mu_lock(&holder->mu); -retry: - /* need to recheck that another thread hasn't set the call */ - call = GET_CALL(holder); - if (call == CANCELLED_CALL) { - gpr_mu_unlock(&holder->mu); - grpc_transport_stream_op_finish_with_failure(exec_ctx, op, - GRPC_ERROR_CANCELLED); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - if (call != NULL) { - gpr_mu_unlock(&holder->mu); - grpc_subchannel_call_process_op(exec_ctx, call, op); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - /* if this is a cancellation, then we can raise our cancelled flag */ - if (op->cancel_error != GRPC_ERROR_NONE) { - if (!gpr_atm_rel_cas(&holder->subchannel_call, 0, 1)) { - goto retry; - } else { - switch (holder->creation_phase) { - case GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING: - fail_locked(exec_ctx, holder, GRPC_ERROR_REF(op->cancel_error)); - break; - case GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL: - holder->pick_subchannel(exec_ctx, holder->pick_subchannel_arg, NULL, - 0, &holder->connected_subchannel, NULL); - break; - } - gpr_mu_unlock(&holder->mu); - grpc_transport_stream_op_finish_with_failure(exec_ctx, op, - GRPC_ERROR_CANCELLED); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); - return; - } - } - /* if we don't have a subchannel, try to get one */ - if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && - holder->connected_subchannel == NULL && - op->send_initial_metadata != NULL) { - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL; - grpc_closure_init(&holder->next_step, subchannel_ready, holder); - GRPC_CALL_STACK_REF(holder->owning_call, "pick_subchannel"); - if (holder->pick_subchannel( - exec_ctx, holder->pick_subchannel_arg, op->send_initial_metadata, - op->send_initial_metadata_flags, &holder->connected_subchannel, - &holder->next_step)) { - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel"); - } - } - /* if we've got a subchannel, then let's ask it to create a call */ - if (holder->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING && - holder->connected_subchannel != NULL) { - gpr_atm_rel_store( - &holder->subchannel_call, - (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( - exec_ctx, holder->connected_subchannel, holder->pollent)); - retry_waiting_locked(exec_ctx, holder); - goto retry; - } - /* nothing to be done but wait */ - add_waiting_locked(holder, op); - gpr_mu_unlock(&holder->mu); - GPR_TIMER_END("grpc_subchannel_call_holder_perform_op", 0); -} - -static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg, - grpc_error *error) { - grpc_subchannel_call_holder *holder = arg; - gpr_mu_lock(&holder->mu); - GPR_ASSERT(holder->creation_phase == - GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL); - holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING; - if (holder->connected_subchannel == NULL) { - gpr_atm_no_barrier_store(&holder->subchannel_call, 1); - fail_locked(exec_ctx, holder, - GRPC_ERROR_CREATE_REFERENCING("Failed to create subchannel", - &error, 1)); - } else if (1 == gpr_atm_acq_load(&holder->subchannel_call)) { - /* already cancelled before subchannel became ready */ - fail_locked(exec_ctx, holder, - GRPC_ERROR_CREATE_REFERENCING( - "Cancelled before creating subchannel", &error, 1)); - } else { - gpr_atm_rel_store( - &holder->subchannel_call, - (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call( - exec_ctx, holder->connected_subchannel, holder->pollent)); - retry_waiting_locked(exec_ctx, holder); - } - gpr_mu_unlock(&holder->mu); - GRPC_CALL_STACK_UNREF(exec_ctx, holder->owning_call, "pick_subchannel"); -} - -typedef struct { - grpc_transport_stream_op *ops; - size_t nops; - grpc_subchannel_call *call; -} retry_ops_args; - -static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder) { - retry_ops_args *a = gpr_malloc(sizeof(*a)); - a->ops = holder->waiting_ops; - a->nops = holder->waiting_ops_count; - a->call = GET_CALL(holder); - if (a->call == CANCELLED_CALL) { - gpr_free(a); - fail_locked(exec_ctx, holder, GRPC_ERROR_CANCELLED); - return; - } - holder->waiting_ops = NULL; - holder->waiting_ops_count = 0; - holder->waiting_ops_capacity = 0; - GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops"); - grpc_exec_ctx_sched(exec_ctx, grpc_closure_create(retry_ops, a), - GRPC_ERROR_NONE, NULL); -} - -static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) { - retry_ops_args *a = args; - size_t i; - for (i = 0; i < a->nops; i++) { - grpc_subchannel_call_process_op(exec_ctx, a->call, &a->ops[i]); - } - GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops"); - gpr_free(a->ops); - gpr_free(a); -} - -static void add_waiting_locked(grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op) { - GPR_TIMER_BEGIN("add_waiting_locked", 0); - if (holder->waiting_ops_count == holder->waiting_ops_capacity) { - holder->waiting_ops_capacity = GPR_MAX(3, 2 * holder->waiting_ops_capacity); - holder->waiting_ops = - gpr_realloc(holder->waiting_ops, holder->waiting_ops_capacity * - sizeof(*holder->waiting_ops)); - } - holder->waiting_ops[holder->waiting_ops_count++] = *op; - GPR_TIMER_END("add_waiting_locked", 0); -} - -static void fail_locked(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder, - grpc_error *error) { - size_t i; - for (i = 0; i < holder->waiting_ops_count; i++) { - grpc_transport_stream_op_finish_with_failure( - exec_ctx, &holder->waiting_ops[i], GRPC_ERROR_REF(error)); - } - holder->waiting_ops_count = 0; - GRPC_ERROR_UNREF(error); -} - -char *grpc_subchannel_call_holder_get_peer( - grpc_exec_ctx *exec_ctx, grpc_subchannel_call_holder *holder) { - grpc_subchannel_call *subchannel_call = GET_CALL(holder); - - if (subchannel_call == NULL || subchannel_call == CANCELLED_CALL) { - return NULL; - } else { - return grpc_subchannel_call_get_peer(exec_ctx, subchannel_call); - } -} diff --git a/src/core/ext/client_config/subchannel_call_holder.h b/src/core/ext/client_config/subchannel_call_holder.h deleted file mode 100644 index 8d2deb02f38..00000000000 --- a/src/core/ext/client_config/subchannel_call_holder.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H -#define GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H - -#include "src/core/ext/client_config/subchannel.h" -#include "src/core/lib/iomgr/polling_entity.h" - -/** Pick a subchannel for grpc_subchannel_call_holder; - Return 1 if subchannel is available immediately (in which case on_ready - should not be called), or 0 otherwise (in which case on_ready should be - called when the subchannel is available) */ -typedef int (*grpc_subchannel_call_holder_pick_subchannel)( - grpc_exec_ctx *exec_ctx, void *arg, grpc_metadata_batch *initial_metadata, - uint32_t initial_metadata_flags, - grpc_connected_subchannel **connected_subchannel, grpc_closure *on_ready); - -typedef enum { - GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING, - GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL -} grpc_subchannel_call_holder_creation_phase; - -/** Wrapper for holding a pointer to grpc_subchannel_call, and the - associated machinery to create such a pointer. - Handles queueing of stream ops until a call object is ready, waiting - for initial metadata before trying to create a call object, - and handling cancellation gracefully. - - The channel filter uses this as their call_data. */ -typedef struct grpc_subchannel_call_holder { - /** either 0 for no call, 1 for cancelled, or a pointer to a - grpc_subchannel_call */ - gpr_atm subchannel_call; - /** Helper function to choose the subchannel on which to create - the call object. Channel filter delegates to the load - balancing policy (once it's ready). */ - grpc_subchannel_call_holder_pick_subchannel pick_subchannel; - void *pick_subchannel_arg; - - gpr_mu mu; - - grpc_subchannel_call_holder_creation_phase creation_phase; - grpc_connected_subchannel *connected_subchannel; - grpc_polling_entity *pollent; - - grpc_transport_stream_op *waiting_ops; - size_t waiting_ops_count; - size_t waiting_ops_capacity; - - grpc_closure next_step; - - grpc_call_stack *owning_call; -} grpc_subchannel_call_holder; - -void grpc_subchannel_call_holder_init( - grpc_subchannel_call_holder *holder, - grpc_subchannel_call_holder_pick_subchannel pick_subchannel, - void *pick_subchannel_arg, grpc_call_stack *owning_call); -void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); - -void grpc_subchannel_call_holder_perform_op(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder, - grpc_transport_stream_op *op); -char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx, - grpc_subchannel_call_holder *holder); - -#endif /* GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H */ diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c new file mode 100644 index 00000000000..af913d8a9df --- /dev/null +++ b/src/core/ext/lb_policy/grpclb/grpclb.c @@ -0,0 +1,1042 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/** Implementation of the gRPC LB policy. + * + * This policy takes as input a set of resolved addresses {a1..an} for which the + * LB set was set (it's the resolver's responsibility to ensure this). That is + * to say, {a1..an} represent a collection of LB servers. + * + * An internal channel (\a glb_lb_policy.lb_channel) is created over {a1..an}. + * This channel behaves just like a regular channel. In particular, the + * constructed URI over the addresses a1..an will use the default pick first + * policy to select from this list of LB server backends. + * + * The first time the policy gets a request for a pick, a ping, or to exit the + * idle state, \a query_for_backends() is called. It creates an instance of \a + * lb_client_data, an internal struct meant to contain the data associated with + * the internal communication with the LB server. This instance is created via + * \a lb_client_data_create(). There, the call over lb_channel to pick-first + * from {a1..an} is created, the \a LoadBalancingRequest message is assembled + * and all necessary callbacks for the progress of the internal call configured. + * + * Back in \a query_for_backends(), the internal *streaming* call to the LB + * server (whichever address from {a1..an} pick-first chose) is kicked off. + * It'll progress over the callbacks configured in \a lb_client_data_create() + * (see the field docstrings of \a lb_client_data for more details). + * + * If the call fails with UNIMPLEMENTED, the original call will also fail. + * There's a misconfiguration somewhere: at least one of {a1..an} isn't a LB + * server, which contradicts the LB bit being set. If the internal call times + * out, the usual behavior of pick-first applies, continuing to pick from the + * list {a1..an}. + * + * Upon sucesss, a \a LoadBalancingResponse is expected in \a res_recv_cb. An + * invalid one results in the termination of the streaming call. A new streaming + * call should be created if possible, failing the original call otherwise. + * For a valid \a LoadBalancingResponse, the server list of actual backends is + * extracted. A Round Robin policy will be created from this list. There are two + * possible scenarios: + * + * 1. This is the first server list received. There was no previous instance of + * the Round Robin policy. \a rr_handover() will instantiate the RR policy + * and perform all the pending operations over it. + * 2. There's already a RR policy instance active. We need to introduce the new + * one build from the new serverlist, but taking care not to disrupt the + * operations in progress over the old RR instance. This is done by + * decreasing the reference count on the old policy. The moment no more + * references are held on the old RR policy, it'll be destroyed and \a + * rr_connectivity_changed notified with a \a GRPC_CHANNEL_SHUTDOWN state. + * At this point we can transition to a new RR instance safely, which is done + * once again via \a rr_handover(). + * + * + * Once a RR policy instance is in place (and getting updated as described), + * calls to for a pick, a ping or a cancellation will be serviced right away by + * forwarding them to the RR instance. Any time there's no RR policy available + * (ie, right after the creation of the gRPCLB policy, if an empty serverlist + * is received, etc), pick/ping requests are added to a list of pending + * picks/pings to be flushed and serviced as part of \a rr_handover() the moment + * the RR policy instance becomes available. + * + * \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the + * high level design and details. */ + +/* TODO(dgq): + * - Implement LB service forwarding (point 2c. in the doc's diagram). + */ + +#include + +#include +#include +#include +#include +#include + +#include "src/core/ext/client_config/client_channel_factory.h" +#include "src/core/ext/client_config/lb_policy_registry.h" +#include "src/core/ext/client_config/parse_address.h" +#include "src/core/ext/lb_policy/grpclb/grpclb.h" +#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/surface/call.h" +#include "src/core/lib/surface/channel.h" + +int grpc_lb_glb_trace = 0; + +typedef struct wrapped_rr_closure_arg { + /* the original closure. Usually a on_complete/notify cb for pick() and ping() + * calls against the internal RR instance, respectively. */ + grpc_closure *wrapped_closure; + + /* The RR instance related to the closure */ + grpc_lb_policy *rr_policy; + + /* when not NULL, represents a pending_{pick,ping} node to be freed upon + * closure execution */ + void *owning_pending_node; /* to be freed if not NULL */ +} wrapped_rr_closure_arg; + +/* The \a on_complete closure passed as part of the pick requires keeping a + * reference to its associated round robin instance. We wrap this closure in + * order to unref the round robin instance upon its invocation */ +static void wrapped_rr_closure(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + wrapped_rr_closure_arg *wc_arg = arg; + if (wc_arg->rr_policy != NULL) { + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", + (intptr_t)wc_arg->rr_policy); + } + GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "wrapped_rr_closure"); + } + GPR_ASSERT(wc_arg->wrapped_closure != NULL); + grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, error, NULL); + gpr_free(wc_arg->owning_pending_node); +} + +/* Linked list of pending pick requests. It stores all information needed to + * eventually call (Round Robin's) pick() on them. They mainly stay pending + * waiting for the RR policy to be created/updated. + * + * One particularity is the wrapping of the user-provided \a on_complete closure + * (in \a wrapped_on_complete and \a wrapped_on_complete_arg). This is needed in + * order to correctly unref the RR policy instance upon completion of the pick. + * See \a wrapped_rr_closure for details. */ +typedef struct pending_pick { + struct pending_pick *next; + + /* polling entity for the pick()'s async notification */ + grpc_polling_entity *pollent; + + /* the initial metadata for the pick. See grpc_lb_policy_pick() */ + grpc_metadata_batch *initial_metadata; + + /* bitmask passed to pick() and used for selective cancelling. See + * grpc_lb_policy_cancel_picks() */ + uint32_t initial_metadata_flags; + + /* output argument where to store the pick()ed connected subchannel, or NULL + * upon error. */ + grpc_connected_subchannel **target; + + /* a closure wrapping the original on_complete one to be invoked once the + * pick() has completed (regardless of success) */ + grpc_closure wrapped_on_complete; + + /* args for wrapped_on_complete */ + wrapped_rr_closure_arg wrapped_on_complete_arg; +} pending_pick; + +static void add_pending_pick(pending_pick **root, grpc_polling_entity *pollent, + grpc_metadata_batch *initial_metadata, + uint32_t initial_metadata_flags, + grpc_connected_subchannel **target, + grpc_closure *on_complete) { + pending_pick *pp = gpr_malloc(sizeof(*pp)); + memset(pp, 0, sizeof(pending_pick)); + memset(&pp->wrapped_on_complete_arg, 0, sizeof(wrapped_rr_closure_arg)); + pp->next = *root; + pp->pollent = pollent; + pp->target = target; + pp->initial_metadata = initial_metadata; + pp->initial_metadata_flags = initial_metadata_flags; + pp->wrapped_on_complete_arg.wrapped_closure = on_complete; + grpc_closure_init(&pp->wrapped_on_complete, wrapped_rr_closure, + &pp->wrapped_on_complete_arg); + *root = pp; +} + +/* Same as the \a pending_pick struct but for ping operations */ +typedef struct pending_ping { + struct pending_ping *next; + + /* a closure wrapping the original on_complete one to be invoked once the + * ping() has completed (regardless of success) */ + grpc_closure wrapped_notify; + + /* args for wrapped_notify */ + wrapped_rr_closure_arg wrapped_notify_arg; +} pending_ping; + +static void add_pending_ping(pending_ping **root, grpc_closure *notify) { + pending_ping *pping = gpr_malloc(sizeof(*pping)); + memset(pping, 0, sizeof(pending_ping)); + memset(&pping->wrapped_notify_arg, 0, sizeof(wrapped_rr_closure_arg)); + pping->next = *root; + grpc_closure_init(&pping->wrapped_notify, wrapped_rr_closure, + &pping->wrapped_notify_arg); + pping->wrapped_notify_arg.wrapped_closure = notify; + *root = pping; +} + +/* + * glb_lb_policy + */ +typedef struct rr_connectivity_data rr_connectivity_data; +struct lb_client_data; +static const grpc_lb_policy_vtable glb_lb_policy_vtable; +typedef struct glb_lb_policy { + /** base policy: must be first */ + grpc_lb_policy base; + + /** mutex protecting remaining members */ + gpr_mu mu; + + grpc_client_channel_factory *cc_factory; + + /** for communicating with the LB server */ + grpc_channel *lb_channel; + + /** the RR policy to use of the backend servers returned by the LB server */ + grpc_lb_policy *rr_policy; + + bool started_picking; + + /** our connectivity state tracker */ + grpc_connectivity_state_tracker state_tracker; + + /** stores the deserialized response from the LB. May be NULL until one such + * response has arrived. */ + grpc_grpclb_serverlist *serverlist; + + /** list of picks that are waiting on RR's policy connectivity */ + pending_pick *pending_picks; + + /** list of pings that are waiting on RR's policy connectivity */ + pending_ping *pending_pings; + + /** client data associated with the LB server communication */ + struct lb_client_data *lb_client; + + /** for tracking of the RR connectivity */ + rr_connectivity_data *rr_connectivity; + + /* a wrapped (see \a wrapped_rr_closure) on-complete closure for readily + * available RR picks */ + grpc_closure wrapped_on_complete; + + /* arguments for the wrapped_on_complete closure */ + wrapped_rr_closure_arg wc_arg; +} glb_lb_policy; + +/* Keeps track and reacts to changes in connectivity of the RR instance */ +struct rr_connectivity_data { + grpc_closure on_change; + grpc_connectivity_state state; + glb_lb_policy *glb_policy; +}; + +static grpc_lb_policy *create_rr(grpc_exec_ctx *exec_ctx, + const grpc_grpclb_serverlist *serverlist, + glb_lb_policy *glb_policy) { + /* TODO(dgq): support mixed ip version */ + GPR_ASSERT(serverlist != NULL && serverlist->num_servers > 0); + char **host_ports = gpr_malloc(sizeof(char *) * serverlist->num_servers); + for (size_t i = 0; i < serverlist->num_servers; ++i) { + gpr_join_host_port(&host_ports[i], serverlist->servers[i]->ip_address, + serverlist->servers[i]->port); + } + + size_t uri_path_len; + char *concat_ipports = gpr_strjoin_sep( + (const char **)host_ports, serverlist->num_servers, ",", &uri_path_len); + + grpc_lb_policy_args args; + args.client_channel_factory = glb_policy->cc_factory; + args.addresses = gpr_malloc(sizeof(grpc_resolved_addresses)); + args.addresses->naddrs = serverlist->num_servers; + args.addresses->addrs = + gpr_malloc(sizeof(grpc_resolved_address) * args.addresses->naddrs); + size_t out_addrs_idx = 0; + for (size_t i = 0; i < serverlist->num_servers; ++i) { + grpc_uri uri; + struct sockaddr_storage sa; + size_t sa_len; + uri.path = host_ports[i]; + if (parse_ipv4(&uri, &sa, &sa_len)) { /* TODO(dgq): add support for ipv6 */ + memcpy(args.addresses->addrs[out_addrs_idx].addr, &sa, sa_len); + args.addresses->addrs[out_addrs_idx].len = sa_len; + ++out_addrs_idx; + } else { + gpr_log(GPR_ERROR, "Invalid LB service address '%s', ignoring.", + host_ports[i]); + } + } + + grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args); + + gpr_free(concat_ipports); + for (size_t i = 0; i < serverlist->num_servers; i++) { + gpr_free(host_ports[i]); + } + gpr_free(host_ports); + gpr_free(args.addresses->addrs); + gpr_free(args.addresses); + return rr; +} + +static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy, + grpc_error *error) { + GRPC_ERROR_REF(error); + glb_policy->rr_policy = + create_rr(exec_ctx, glb_policy->serverlist, glb_policy); + + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Created RR policy (0x%" PRIxPTR ")", + (intptr_t)glb_policy->rr_policy); + } + GPR_ASSERT(glb_policy->rr_policy != NULL); + glb_policy->rr_connectivity->state = grpc_lb_policy_check_connectivity( + exec_ctx, glb_policy->rr_policy, &error); + grpc_lb_policy_notify_on_state_change( + exec_ctx, glb_policy->rr_policy, &glb_policy->rr_connectivity->state, + &glb_policy->rr_connectivity->on_change); + grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker, + glb_policy->rr_connectivity->state, error, + "rr_handover"); + grpc_lb_policy_exit_idle(exec_ctx, glb_policy->rr_policy); + + /* flush pending ops */ + pending_pick *pp; + while ((pp = glb_policy->pending_picks)) { + glb_policy->pending_picks = pp->next; + GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_pick"); + pp->wrapped_on_complete_arg.rr_policy = glb_policy->rr_policy; + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "", + (intptr_t)glb_policy->rr_policy); + } + grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pp->pollent, + pp->initial_metadata, pp->initial_metadata_flags, + pp->target, &pp->wrapped_on_complete); + pp->wrapped_on_complete_arg.owning_pending_node = pp; + } + + pending_ping *pping; + while ((pping = glb_policy->pending_pings)) { + glb_policy->pending_pings = pping->next; + GRPC_LB_POLICY_REF(glb_policy->rr_policy, "rr_handover_pending_ping"); + pping->wrapped_notify_arg.rr_policy = glb_policy->rr_policy; + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Pending ping about to PING from 0x%" PRIxPTR "", + (intptr_t)glb_policy->rr_policy); + } + grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy, + &pping->wrapped_notify); + pping->wrapped_notify_arg.owning_pending_node = pping; + } + GRPC_ERROR_UNREF(error); +} + +static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + rr_connectivity_data *rr_conn_data = arg; + glb_lb_policy *glb_policy = rr_conn_data->glb_policy; + if (rr_conn_data->state == GRPC_CHANNEL_SHUTDOWN) { + if (glb_policy->serverlist != NULL) { + /* a RR policy is shutting down but there's a serverlist available -> + * perform a handover */ + rr_handover(exec_ctx, glb_policy, error); + } else { + /* shutting down and no new serverlist available. Bail out. */ + gpr_free(rr_conn_data); + } + } else { + if (error == GRPC_ERROR_NONE) { + /* RR not shutting down. Mimic the RR's policy state */ + grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker, + rr_conn_data->state, error, + "rr_connectivity_changed"); + /* resubscribe */ + grpc_lb_policy_notify_on_state_change(exec_ctx, glb_policy->rr_policy, + &rr_conn_data->state, + &rr_conn_data->on_change); + } else { /* error */ + gpr_free(rr_conn_data); + } + } + GRPC_ERROR_UNREF(error); +} + +static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx, + grpc_lb_policy_factory *factory, + grpc_lb_policy_args *args) { + glb_lb_policy *glb_policy = gpr_malloc(sizeof(*glb_policy)); + memset(glb_policy, 0, sizeof(*glb_policy)); + + /* All input addresses in args->addresses come from a resolver that claims + * they are LB services. It's the resolver's responsibility to make sure this + * policy is only instantiated and used in that case. + * + * Create a client channel over them to communicate with a LB service */ + glb_policy->cc_factory = args->client_channel_factory; + GPR_ASSERT(glb_policy->cc_factory != NULL); + if (args->addresses->naddrs == 0) { + return NULL; + } + + /* construct a target from the args->addresses, in the form + * ipvX://ip1:port1,ip2:port2,... + * TODO(dgq): support mixed ip version */ + char **addr_strs = gpr_malloc(sizeof(char *) * args->addresses->naddrs); + addr_strs[0] = + grpc_sockaddr_to_uri((const struct sockaddr *)&args->addresses->addrs[0]); + for (size_t i = 1; i < args->addresses->naddrs; i++) { + GPR_ASSERT(grpc_sockaddr_to_string( + &addr_strs[i], + (const struct sockaddr *)&args->addresses->addrs[i], + true) == 0); + } + size_t uri_path_len; + char *target_uri_str = gpr_strjoin_sep( + (const char **)addr_strs, args->addresses->naddrs, ",", &uri_path_len); + + /* will pick using pick_first */ + glb_policy->lb_channel = grpc_client_channel_factory_create_channel( + exec_ctx, glb_policy->cc_factory, target_uri_str, + GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, NULL); + + gpr_free(target_uri_str); + for (size_t i = 0; i < args->addresses->naddrs; i++) { + gpr_free(addr_strs[i]); + } + gpr_free(addr_strs); + + if (glb_policy->lb_channel == NULL) { + gpr_free(glb_policy); + return NULL; + } + + rr_connectivity_data *rr_connectivity = + gpr_malloc(sizeof(rr_connectivity_data)); + memset(rr_connectivity, 0, sizeof(rr_connectivity_data)); + grpc_closure_init(&rr_connectivity->on_change, rr_connectivity_changed, + rr_connectivity); + rr_connectivity->glb_policy = glb_policy; + glb_policy->rr_connectivity = rr_connectivity; + + grpc_lb_policy_init(&glb_policy->base, &glb_lb_policy_vtable); + gpr_mu_init(&glb_policy->mu); + grpc_connectivity_state_init(&glb_policy->state_tracker, GRPC_CHANNEL_IDLE, + "grpclb"); + return &glb_policy->base; +} + +static void glb_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + GPR_ASSERT(glb_policy->pending_picks == NULL); + GPR_ASSERT(glb_policy->pending_pings == NULL); + grpc_channel_destroy(glb_policy->lb_channel); + glb_policy->lb_channel = NULL; + grpc_connectivity_state_destroy(exec_ctx, &glb_policy->state_tracker); + if (glb_policy->serverlist != NULL) { + grpc_grpclb_destroy_serverlist(glb_policy->serverlist); + } + gpr_mu_destroy(&glb_policy->mu); + gpr_free(glb_policy); +} + +static void lb_client_data_destroy(struct lb_client_data *lb_client); +static void glb_shutdown(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + + pending_pick *pp = glb_policy->pending_picks; + glb_policy->pending_picks = NULL; + pending_ping *pping = glb_policy->pending_pings; + glb_policy->pending_pings = NULL; + gpr_mu_unlock(&glb_policy->mu); + + while (pp != NULL) { + pending_pick *next = pp->next; + *pp->target = NULL; + grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, GRPC_ERROR_NONE, + NULL); + gpr_free(pp); + pp = next; + } + + while (pping != NULL) { + pending_ping *next = pping->next; + grpc_exec_ctx_sched(exec_ctx, &pping->wrapped_notify, GRPC_ERROR_NONE, + NULL); + pping = next; + } + + if (glb_policy->rr_policy) { + /* unsubscribe */ + grpc_lb_policy_notify_on_state_change( + exec_ctx, glb_policy->rr_policy, NULL, + &glb_policy->rr_connectivity->on_change); + GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->rr_policy, "glb_shutdown"); + } + + lb_client_data_destroy(glb_policy->lb_client); + glb_policy->lb_client = NULL; + + grpc_connectivity_state_set( + exec_ctx, &glb_policy->state_tracker, GRPC_CHANNEL_SHUTDOWN, + GRPC_ERROR_CREATE("Channel Shutdown"), "glb_shutdown"); +} + +static void glb_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_connected_subchannel **target) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + pending_pick *pp = glb_policy->pending_picks; + glb_policy->pending_picks = NULL; + while (pp != NULL) { + pending_pick *next = pp->next; + if (pp->target == target) { + grpc_polling_entity_del_from_pollset_set( + exec_ctx, pp->pollent, glb_policy->base.interested_parties); + *target = NULL; + grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, + GRPC_ERROR_CANCELLED, NULL); + gpr_free(pp); + } else { + pp->next = glb_policy->pending_picks; + glb_policy->pending_picks = pp; + } + pp = next; + } + gpr_mu_unlock(&glb_policy->mu); +} + +static grpc_call *lb_client_data_get_call(struct lb_client_data *lb_client); +static void glb_cancel_picks(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + uint32_t initial_metadata_flags_mask, + uint32_t initial_metadata_flags_eq) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + if (glb_policy->lb_client != NULL) { + /* cancel the call to the load balancer service, if any */ + grpc_call_cancel(lb_client_data_get_call(glb_policy->lb_client), NULL); + } + pending_pick *pp = glb_policy->pending_picks; + glb_policy->pending_picks = NULL; + while (pp != NULL) { + pending_pick *next = pp->next; + if ((pp->initial_metadata_flags & initial_metadata_flags_mask) == + initial_metadata_flags_eq) { + grpc_polling_entity_del_from_pollset_set( + exec_ctx, pp->pollent, glb_policy->base.interested_parties); + grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete, + GRPC_ERROR_CANCELLED, NULL); + gpr_free(pp); + } else { + pp->next = glb_policy->pending_picks; + glb_policy->pending_picks = pp; + } + pp = next; + } + gpr_mu_unlock(&glb_policy->mu); +} + +static void query_for_backends(grpc_exec_ctx *exec_ctx, + glb_lb_policy *glb_policy); +static void start_picking(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy) { + glb_policy->started_picking = true; + query_for_backends(exec_ctx, glb_policy); +} + +static void glb_exit_idle(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + if (!glb_policy->started_picking) { + start_picking(exec_ctx, glb_policy); + } + gpr_mu_unlock(&glb_policy->mu); +} + +static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_polling_entity *pollent, + grpc_metadata_batch *initial_metadata, + uint32_t initial_metadata_flags, + grpc_connected_subchannel **target, + grpc_closure *on_complete) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + int r; + + if (glb_policy->rr_policy != NULL) { + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "about to PICK from 0x%" PRIxPTR "", + (intptr_t)glb_policy->rr_policy); + } + GRPC_LB_POLICY_REF(glb_policy->rr_policy, "glb_pick"); + memset(&glb_policy->wc_arg, 0, sizeof(wrapped_rr_closure_arg)); + glb_policy->wc_arg.rr_policy = glb_policy->rr_policy; + glb_policy->wc_arg.wrapped_closure = on_complete; + grpc_closure_init(&glb_policy->wrapped_on_complete, wrapped_rr_closure, + &glb_policy->wc_arg); + r = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pollent, + initial_metadata, initial_metadata_flags, target, + &glb_policy->wrapped_on_complete); + if (r != 0) { + /* the call to grpc_lb_policy_pick has been sychronous. Unreffing the RR + * policy and notify the original callback */ + glb_policy->wc_arg.wrapped_closure = NULL; + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")", + (intptr_t)glb_policy->wc_arg.rr_policy); + } + GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->wc_arg.rr_policy, "glb_pick"); + grpc_exec_ctx_sched(exec_ctx, glb_policy->wc_arg.wrapped_closure, + GRPC_ERROR_NONE, NULL); + } + } else { + grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent, + glb_policy->base.interested_parties); + add_pending_pick(&glb_policy->pending_picks, pollent, initial_metadata, + initial_metadata_flags, target, on_complete); + + if (!glb_policy->started_picking) { + start_picking(exec_ctx, glb_policy); + } + r = 0; + } + gpr_mu_unlock(&glb_policy->mu); + return r; +} + +static grpc_connectivity_state glb_check_connectivity( + grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_error **connectivity_error) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + grpc_connectivity_state st; + gpr_mu_lock(&glb_policy->mu); + st = grpc_connectivity_state_check(&glb_policy->state_tracker, + connectivity_error); + gpr_mu_unlock(&glb_policy->mu); + return st; +} + +static void glb_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol, + grpc_closure *closure) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + if (glb_policy->rr_policy) { + grpc_lb_policy_ping_one(exec_ctx, glb_policy->rr_policy, closure); + } else { + add_pending_ping(&glb_policy->pending_pings, closure); + if (!glb_policy->started_picking) { + start_picking(exec_ctx, glb_policy); + } + } + gpr_mu_unlock(&glb_policy->mu); +} + +static void glb_notify_on_state_change(grpc_exec_ctx *exec_ctx, + grpc_lb_policy *pol, + grpc_connectivity_state *current, + grpc_closure *notify) { + glb_lb_policy *glb_policy = (glb_lb_policy *)pol; + gpr_mu_lock(&glb_policy->mu); + grpc_connectivity_state_notify_on_state_change( + exec_ctx, &glb_policy->state_tracker, current, notify); + + gpr_mu_unlock(&glb_policy->mu); +} + +/* + * lb_client_data + * + * Used internally for the client call to the LB */ +typedef struct lb_client_data { + gpr_mu mu; + + /* called once initial metadata's been sent */ + grpc_closure md_sent; + + /* called once initial metadata's been received */ + grpc_closure md_rcvd; + + /* called once the LoadBalanceRequest has been sent to the LB server. See + * src/proto/grpc/.../load_balancer.proto */ + grpc_closure req_sent; + + /* A response from the LB server has been received (or error). Process it */ + grpc_closure res_rcvd; + + /* After the client has sent a close to the LB server */ + grpc_closure close_sent; + + /* ... and the status from the LB server has been received */ + grpc_closure srv_status_rcvd; + + grpc_call *lb_call; /* streaming call to the LB server, */ + gpr_timespec deadline; /* for the streaming call to the LB server */ + + grpc_metadata_array initial_metadata_recv; /* initial MD from LB server */ + grpc_metadata_array trailing_metadata_recv; /* trailing MD from LB server */ + + /* what's being sent to the LB server. Note that its value may vary if the LB + * server indicates a redirect. */ + grpc_byte_buffer *request_payload; + + /* response from the LB server, if any. Processed in res_recv_cb() */ + grpc_byte_buffer *response_payload; + + /* the call's status and status detailset in srv_status_rcvd_cb() */ + grpc_status_code status; + char *status_details; + size_t status_details_capacity; + + /* pointer back to the enclosing policy */ + glb_lb_policy *glb_policy; +} lb_client_data; + +static void md_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); +static void md_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); +static void req_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); +static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error); +static void close_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); +static void srv_status_rcvd_cb(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error); + +static lb_client_data *lb_client_data_create(glb_lb_policy *glb_policy) { + lb_client_data *lb_client = gpr_malloc(sizeof(lb_client_data)); + memset(lb_client, 0, sizeof(lb_client_data)); + + gpr_mu_init(&lb_client->mu); + grpc_closure_init(&lb_client->md_sent, md_sent_cb, lb_client); + + grpc_closure_init(&lb_client->md_rcvd, md_recv_cb, lb_client); + grpc_closure_init(&lb_client->req_sent, req_sent_cb, lb_client); + grpc_closure_init(&lb_client->res_rcvd, res_recv_cb, lb_client); + grpc_closure_init(&lb_client->close_sent, close_sent_cb, lb_client); + grpc_closure_init(&lb_client->srv_status_rcvd, srv_status_rcvd_cb, lb_client); + + /* TODO(dgq): get the deadline from the client config instead of fabricating + * one here. */ + lb_client->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(3, GPR_TIMESPAN)); + + /* Note the following LB call progresses every time there's activity in \a + * glb_policy->base.interested_parties, which is comprised of the polling + * entities passed to glb_pick(). */ + lb_client->lb_call = grpc_channel_create_pollset_set_call( + glb_policy->lb_channel, NULL, GRPC_PROPAGATE_DEFAULTS, + glb_policy->base.interested_parties, "/BalanceLoad", + NULL, /* FIXME(dgq): which "host" value to use? */ + lb_client->deadline, NULL); + + grpc_metadata_array_init(&lb_client->initial_metadata_recv); + grpc_metadata_array_init(&lb_client->trailing_metadata_recv); + + grpc_grpclb_request *request = grpc_grpclb_request_create( + "load.balanced.service.name"); /* FIXME(dgq): get the name of the load + balanced service from the resolver */ + gpr_slice request_payload_slice = grpc_grpclb_request_encode(request); + lb_client->request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + gpr_slice_unref(request_payload_slice); + grpc_grpclb_request_destroy(request); + + lb_client->status_details = NULL; + lb_client->status_details_capacity = 0; + lb_client->glb_policy = glb_policy; + return lb_client; +} + +static void lb_client_data_destroy(lb_client_data *lb_client) { + grpc_call_destroy(lb_client->lb_call); + grpc_metadata_array_destroy(&lb_client->initial_metadata_recv); + grpc_metadata_array_destroy(&lb_client->trailing_metadata_recv); + + grpc_byte_buffer_destroy(lb_client->request_payload); + + gpr_free(lb_client->status_details); + gpr_mu_destroy(&lb_client->mu); + gpr_free(lb_client); +} +static grpc_call *lb_client_data_get_call(lb_client_data *lb_client) { + return lb_client->lb_call; +} + +/* + * Auxiliary functions and LB client callbacks. + */ +static void query_for_backends(grpc_exec_ctx *exec_ctx, + glb_lb_policy *glb_policy) { + GPR_ASSERT(glb_policy->lb_channel != NULL); + + glb_policy->lb_client = lb_client_data_create(glb_policy); + grpc_call_error call_error; + grpc_op ops[1]; + memset(ops, 0, sizeof(ops)); + grpc_op *op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + call_error = grpc_call_start_batch_and_execute( + exec_ctx, glb_policy->lb_client->lb_call, ops, (size_t)(op - ops), + &glb_policy->lb_client->md_sent); + GPR_ASSERT(GRPC_CALL_OK == call_error); + + op = ops; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = + &glb_policy->lb_client->trailing_metadata_recv; + op->data.recv_status_on_client.status = &glb_policy->lb_client->status; + op->data.recv_status_on_client.status_details = + &glb_policy->lb_client->status_details; + op->data.recv_status_on_client.status_details_capacity = + &glb_policy->lb_client->status_details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + call_error = grpc_call_start_batch_and_execute( + exec_ctx, glb_policy->lb_client->lb_call, ops, (size_t)(op - ops), + &glb_policy->lb_client->srv_status_rcvd); + GPR_ASSERT(GRPC_CALL_OK == call_error); +} + +static void md_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + lb_client_data *lb_client = arg; + GPR_ASSERT(lb_client->lb_call); + grpc_op ops[1]; + memset(ops, 0, sizeof(ops)); + grpc_op *op = ops; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &lb_client->initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + grpc_call_error call_error = grpc_call_start_batch_and_execute( + exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops), + &lb_client->md_rcvd); + GPR_ASSERT(GRPC_CALL_OK == call_error); +} + +static void md_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + lb_client_data *lb_client = arg; + GPR_ASSERT(lb_client->lb_call); + grpc_op ops[1]; + memset(ops, 0, sizeof(ops)); + grpc_op *op = ops; + + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = lb_client->request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + grpc_call_error call_error = grpc_call_start_batch_and_execute( + exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops), + &lb_client->req_sent); + GPR_ASSERT(GRPC_CALL_OK == call_error); +} + +static void req_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + lb_client_data *lb_client = arg; + + grpc_op ops[1]; + memset(ops, 0, sizeof(ops)); + grpc_op *op = ops; + + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &lb_client->response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + grpc_call_error call_error = grpc_call_start_batch_and_execute( + exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops), + &lb_client->res_rcvd); + GPR_ASSERT(GRPC_CALL_OK == call_error); +} + +static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + lb_client_data *lb_client = arg; + grpc_op ops[2]; + memset(ops, 0, sizeof(ops)); + grpc_op *op = ops; + if (lb_client->response_payload != NULL) { + /* Received data from the LB server. Look inside + * lb_client->response_payload, for + * a serverlist. */ + grpc_byte_buffer_reader bbr; + grpc_byte_buffer_reader_init(&bbr, lb_client->response_payload); + gpr_slice response_slice = grpc_byte_buffer_reader_readall(&bbr); + grpc_byte_buffer_destroy(lb_client->response_payload); + grpc_grpclb_serverlist *serverlist = + grpc_grpclb_response_parse_serverlist(response_slice); + if (serverlist != NULL) { + gpr_slice_unref(response_slice); + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, "Serverlist with %zu servers received", + serverlist->num_servers); + } + + /* update serverlist */ + if (serverlist->num_servers > 0) { + if (grpc_grpclb_serverlist_equals(lb_client->glb_policy->serverlist, + serverlist)) { + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, + "Incoming server list identical to current, ignoring."); + } + } else { /* new serverlist */ + if (lb_client->glb_policy->serverlist != NULL) { + /* dispose of the old serverlist */ + grpc_grpclb_destroy_serverlist(lb_client->glb_policy->serverlist); + } + /* and update the copy in the glb_lb_policy instance */ + lb_client->glb_policy->serverlist = serverlist; + } + if (lb_client->glb_policy->rr_policy == NULL) { + /* initial "handover", in this case from a null RR policy, meaning + * it'll just create the first RR policy instance */ + rr_handover(exec_ctx, lb_client->glb_policy, error); + } else { + /* unref the RR policy, eventually leading to its substitution with a + * new one constructed from the received serverlist (see + * rr_connectivity_changed) */ + GRPC_LB_POLICY_UNREF(exec_ctx, lb_client->glb_policy->rr_policy, + "serverlist_received"); + } + } else { + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, + "Received empty server list. Picks will stay pending until a " + "response with > 0 servers is received"); + } + } + + /* keep listening for serverlist updates */ + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &lb_client->response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + const grpc_call_error call_error = grpc_call_start_batch_and_execute( + exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops), + &lb_client->res_rcvd); /* loop */ + GPR_ASSERT(GRPC_CALL_OK == call_error); + return; + } + + GPR_ASSERT(serverlist == NULL); + gpr_log(GPR_ERROR, "Invalid LB response received: '%s'", + gpr_dump_slice(response_slice, GPR_DUMP_ASCII)); + gpr_slice_unref(response_slice); + + /* Disconnect from server returning invalid response. */ + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + grpc_call_error call_error = grpc_call_start_batch_and_execute( + exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops), + &lb_client->close_sent); + GPR_ASSERT(GRPC_CALL_OK == call_error); + } + /* empty payload: call cancelled by server. Cleanups happening in + * srv_status_rcvd_cb */ +} + +static void close_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, + "Close from LB client sent. Waiting from server status now"); + } +} + +static void srv_status_rcvd_cb(grpc_exec_ctx *exec_ctx, void *arg, + grpc_error *error) { + lb_client_data *lb_client = arg; + if (grpc_lb_glb_trace) { + gpr_log(GPR_INFO, + "status from lb server received. Status = %d, Details = '%s', " + "Capaticy " + "= %zu", + lb_client->status, lb_client->status_details, + lb_client->status_details_capacity); + } + /* TODO(dgq): deal with stream termination properly (fire up another one? fail + * the original call?) */ +} + +/* Code wiring the policy with the rest of the core */ +static const grpc_lb_policy_vtable glb_lb_policy_vtable = { + glb_destroy, glb_shutdown, glb_pick, + glb_cancel_pick, glb_cancel_picks, glb_ping_one, + glb_exit_idle, glb_check_connectivity, glb_notify_on_state_change}; + +static void glb_factory_ref(grpc_lb_policy_factory *factory) {} + +static void glb_factory_unref(grpc_lb_policy_factory *factory) {} + +static const grpc_lb_policy_factory_vtable glb_factory_vtable = { + glb_factory_ref, glb_factory_unref, glb_create, "grpclb"}; + +static grpc_lb_policy_factory glb_lb_policy_factory = {&glb_factory_vtable}; + +grpc_lb_policy_factory *grpc_glb_lb_factory_create() { + return &glb_lb_policy_factory; +} + +/* Plugin registration */ +void grpc_lb_policy_grpclb_init() { + grpc_register_lb_policy(grpc_glb_lb_factory_create()); + grpc_register_tracer("glb", &grpc_lb_glb_trace); +} + +void grpc_lb_policy_grpclb_shutdown() {} diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/core/ext/lb_policy/grpclb/grpclb.h similarity index 78% rename from src/python/grpcio/grpc/_cython/imports.generated.h rename to src/core/ext/lb_policy/grpclb/grpclb.h index 8e5c9a8ce2b..83552b4fa02 100644 --- a/src/python/grpcio/grpc/_cython/imports.generated.h +++ b/src/core/ext/lb_policy/grpclb/grpclb.h @@ -31,20 +31,14 @@ * */ -/* TODO(atash) remove cruft */ -#ifndef PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ -#define PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ +#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H +#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H -#include +#include "src/core/ext/client_config/lb_policy_factory.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include +/** Returns a load balancing factory for the glb policy, which tries to connect + * to a load balancing server to decide the next successfully connected + * subchannel to pick. */ +grpc_lb_policy_factory *grpc_glb_lb_factory_create(); -#endif +#endif /* GRPC_CORE_EXT_LB_POLICY_GRPCLB_GRPCLB_H */ diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.c b/src/core/ext/lb_policy/grpclb/load_balancer_api.c index 59b89997dd9..f4720a13455 100644 --- a/src/core/ext/lb_policy/grpclb/load_balancer_api.c +++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.c @@ -38,9 +38,15 @@ #include typedef struct decode_serverlist_arg { - int first_pass; - int i; + /* The first pass counts the number of servers in the server list. The second + * one allocates and decodes. */ + bool first_pass; + /* The decoding callback is invoked once per server in serverlist. Remember + * which index of the serverlist are we currently decoding */ + size_t decoding_idx; + /* Populated after the first pass. Number of server in the input serverlist */ size_t num_servers; + /* The decoded serverlist */ grpc_grpclb_server **servers; } decode_serverlist_arg; @@ -48,23 +54,24 @@ typedef struct decode_serverlist_arg { static bool decode_serverlist(pb_istream_t *stream, const pb_field_t *field, void **arg) { decode_serverlist_arg *dec_arg = *arg; - if (dec_arg->first_pass != 0) { /* first pass */ + if (dec_arg->first_pass) { /* count how many server do we have */ grpc_grpclb_server server; if (!pb_decode(stream, grpc_lb_v1_Server_fields, &server)) { return false; } dec_arg->num_servers++; - } else { /* second pass */ + } else { /* second pass. Actually decode. */ grpc_grpclb_server *server = gpr_malloc(sizeof(grpc_grpclb_server)); + memset(server, 0, sizeof(grpc_grpclb_server)); GPR_ASSERT(dec_arg->num_servers > 0); - if (dec_arg->i == 0) { /* first iteration of second pass */ + if (dec_arg->decoding_idx == 0) { /* first iteration of second pass */ dec_arg->servers = gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers); } if (!pb_decode(stream, grpc_lb_v1_Server_fields, server)) { return false; } - dec_arg->servers[dec_arg->i++] = server; + dec_arg->servers[dec_arg->decoding_idx++] = server; } return true; @@ -102,57 +109,59 @@ void grpc_grpclb_request_destroy(grpc_grpclb_request *request) { gpr_free(request); } -grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response) { - bool status; +typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response; +grpc_grpclb_initial_response *grpc_grpclb_initial_response_parse( + gpr_slice encoded_grpc_grpclb_response) { pb_istream_t stream = - pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response), - GPR_SLICE_LENGTH(encoded_response)); - grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response)); - memset(res, 0, sizeof(*res)); - status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, res); - if (!status) { - grpc_grpclb_response_destroy(res); + pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_grpc_grpclb_response), + GPR_SLICE_LENGTH(encoded_grpc_grpclb_response)); + grpc_grpclb_response res; + memset(&res, 0, sizeof(grpc_grpclb_response)); + if (!pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res)) { return NULL; } - return res; + grpc_grpclb_initial_response *initial_res = + gpr_malloc(sizeof(grpc_grpclb_initial_response)); + memcpy(initial_res, &res.initial_response, + sizeof(grpc_grpclb_initial_response)); + + return initial_res; } grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( - gpr_slice encoded_response) { + gpr_slice encoded_grpc_grpclb_response) { bool status; decode_serverlist_arg arg; pb_istream_t stream = - pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_response), - GPR_SLICE_LENGTH(encoded_response)); + pb_istream_from_buffer(GPR_SLICE_START_PTR(encoded_grpc_grpclb_response), + GPR_SLICE_LENGTH(encoded_grpc_grpclb_response)); pb_istream_t stream_at_start = stream; - grpc_grpclb_response *res = gpr_malloc(sizeof(grpc_grpclb_response)); - memset(res, 0, sizeof(*res)); + grpc_grpclb_response res; + memset(&res, 0, sizeof(grpc_grpclb_response)); memset(&arg, 0, sizeof(decode_serverlist_arg)); - res->server_list.servers.funcs.decode = decode_serverlist; - res->server_list.servers.arg = &arg; - arg.first_pass = 1; - status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, res); + res.server_list.servers.funcs.decode = decode_serverlist; + res.server_list.servers.arg = &arg; + arg.first_pass = true; + status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res); if (!status) { - grpc_grpclb_response_destroy(res); return NULL; } - arg.first_pass = 0; + arg.first_pass = false; status = - pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields, res); + pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields, &res); if (!status) { - grpc_grpclb_response_destroy(res); return NULL; } grpc_grpclb_serverlist *sl = gpr_malloc(sizeof(grpc_grpclb_serverlist)); + memset(sl, 0, sizeof(*sl)); sl->num_servers = arg.num_servers; sl->servers = arg.servers; - if (res->server_list.has_expiration_interval) { - sl->expiration_interval = res->server_list.expiration_interval; + if (res.server_list.has_expiration_interval) { + sl->expiration_interval = res.server_list.expiration_interval; } - grpc_grpclb_response_destroy(res); return sl; } @@ -167,6 +176,72 @@ void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist) { gpr_free(serverlist); } -void grpc_grpclb_response_destroy(grpc_grpclb_response *response) { +grpc_grpclb_serverlist *grpc_grpclb_serverlist_copy( + const grpc_grpclb_serverlist *sl) { + grpc_grpclb_serverlist *copy = gpr_malloc(sizeof(grpc_grpclb_serverlist)); + memset(copy, 0, sizeof(grpc_grpclb_serverlist)); + copy->num_servers = sl->num_servers; + memcpy(©->expiration_interval, &sl->expiration_interval, + sizeof(grpc_grpclb_duration)); + copy->servers = gpr_malloc(sizeof(grpc_grpclb_server *) * sl->num_servers); + for (size_t i = 0; i < sl->num_servers; i++) { + copy->servers[i] = gpr_malloc(sizeof(grpc_grpclb_server)); + memcpy(copy->servers[i], sl->servers[i], sizeof(grpc_grpclb_server)); + } + return copy; +} + +bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist *lhs, + const grpc_grpclb_serverlist *rhs) { + if ((lhs == NULL) || (rhs == NULL)) { + return false; + } + if (lhs->num_servers != rhs->num_servers) { + return false; + } + if (grpc_grpclb_duration_compare(&lhs->expiration_interval, + &rhs->expiration_interval) != 0) { + return false; + } + for (size_t i = 0; i < lhs->num_servers; i++) { + if (!grpc_grpclb_server_equals(lhs->servers[i], rhs->servers[i])) { + return false; + } + } + return true; +} + +bool grpc_grpclb_server_equals(const grpc_grpclb_server *lhs, + const grpc_grpclb_server *rhs) { + return memcmp(lhs, rhs, sizeof(grpc_grpclb_server)) == 0; +} + +int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs, + const grpc_grpclb_duration *rhs) { + GPR_ASSERT(lhs && rhs); + if (lhs->has_seconds && rhs->has_seconds) { + if (lhs->seconds < rhs->seconds) return -1; + if (lhs->seconds > rhs->seconds) return 1; + } else if (lhs->has_seconds) { + return 1; + } else if (rhs->has_seconds) { + return -1; + } + + GPR_ASSERT(lhs->seconds == rhs->seconds); + if (lhs->has_nanos && rhs->has_nanos) { + if (lhs->nanos < rhs->nanos) return -1; + if (lhs->nanos > rhs->nanos) return 1; + } else if (lhs->has_nanos) { + return 1; + } else if (rhs->has_nanos) { + return -1; + } + + return 0; +} + +void grpc_grpclb_initial_response_destroy( + grpc_grpclb_initial_response *response) { gpr_free(response); } diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/lb_policy/grpclb/load_balancer_api.h index 71b5616d0c8..9726c87a37f 100644 --- a/src/core/ext/lb_policy/grpclb/load_balancer_api.h +++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.h @@ -46,7 +46,7 @@ extern "C" { #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128 typedef grpc_lb_v1_LoadBalanceRequest grpc_grpclb_request; -typedef grpc_lb_v1_LoadBalanceResponse grpc_grpclb_response; +typedef grpc_lb_v1_InitialLoadBalanceResponse grpc_grpclb_initial_response; typedef grpc_lb_v1_Server grpc_grpclb_server; typedef grpc_lb_v1_Duration grpc_grpclb_duration; typedef struct grpc_grpclb_serverlist { @@ -64,19 +64,37 @@ gpr_slice grpc_grpclb_request_encode(const grpc_grpclb_request *request); /** Destroy \a request */ void grpc_grpclb_request_destroy(grpc_grpclb_request *request); -/** Parse (ie, decode) the bytes in \a encoded_response as a \a - * grpc_grpclb_response */ -grpc_grpclb_response *grpc_grpclb_response_parse(gpr_slice encoded_response); +/** Parse (ie, decode) the bytes in \a encoded_grpc_grpclb_response as a \a + * grpc_grpclb_initial_response */ +grpc_grpclb_initial_response *grpc_grpclb_initial_response_parse( + gpr_slice encoded_grpc_grpclb_response); + +/** Parse the list of servers from an encoded \a grpc_grpclb_response */ +grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( + gpr_slice encoded_grpc_grpclb_response); + +/** Return a copy of \a sl. The caller is responsible for calling \a + * grpc_grpclb_destroy_serverlist on the returned copy. */ +grpc_grpclb_serverlist *grpc_grpclb_serverlist_copy( + const grpc_grpclb_serverlist *sl); + +bool grpc_grpclb_serverlist_equals(const grpc_grpclb_serverlist *lhs, + const grpc_grpclb_serverlist *rhs); + +bool grpc_grpclb_server_equals(const grpc_grpclb_server *lhs, + const grpc_grpclb_server *rhs); /** Destroy \a serverlist */ void grpc_grpclb_destroy_serverlist(grpc_grpclb_serverlist *serverlist); -/** Parse the list of servers from an encoded \a grpc_grpclb_response */ -grpc_grpclb_serverlist *grpc_grpclb_response_parse_serverlist( - gpr_slice encoded_response); +/** Compare \a lhs against \a rhs and return 0 if \a lhs and \a rhs are equal, + * < 0 if \a lhs represents a duration shorter than \a rhs and > 0 otherwise */ +int grpc_grpclb_duration_compare(const grpc_grpclb_duration *lhs, + const grpc_grpclb_duration *rhs); -/** Destroy \a response */ -void grpc_grpclb_response_destroy(grpc_grpclb_response *response); +/** Destroy \a initial_response */ +void grpc_grpclb_initial_response_destroy( + grpc_grpclb_initial_response *response); #ifdef __cplusplus } diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/load_reporting/load_reporting.c index 9e4d32676fc..df1ea0ec9ac 100644 --- a/src/core/ext/load_reporting/load_reporting.c +++ b/src/core/ext/load_reporting/load_reporting.c @@ -42,42 +42,12 @@ #include "src/core/lib/channel/channel_stack_builder.h" #include "src/core/lib/surface/channel_init.h" -struct grpc_load_reporting_config { - grpc_load_reporting_fn fn; - void *user_data; -}; - -grpc_load_reporting_config *grpc_load_reporting_config_create( - grpc_load_reporting_fn fn, void *user_data) { - GPR_ASSERT(fn != NULL); - grpc_load_reporting_config *lrc = - gpr_malloc(sizeof(grpc_load_reporting_config)); - lrc->fn = fn; - lrc->user_data = user_data; - return lrc; -} - -grpc_load_reporting_config *grpc_load_reporting_config_copy( - grpc_load_reporting_config *src) { - return grpc_load_reporting_config_create(src->fn, src->user_data); -} - -void grpc_load_reporting_config_destroy(grpc_load_reporting_config *lrc) { - gpr_free(lrc); -} - -void grpc_load_reporting_config_call( - grpc_load_reporting_config *lrc, - const grpc_load_reporting_call_data *call_data) { - lrc->fn(call_data, lrc->user_data); -} - static bool is_load_reporting_enabled(const grpc_channel_args *a) { if (a == NULL) return false; for (size_t i = 0; i < a->num_args; i++) { if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_LOAD_REPORTING)) { - return a->args[i].type == GRPC_ARG_POINTER && - a->args[i].value.pointer.p != NULL; + return a->args[i].type == GRPC_ARG_INTEGER && + a->args[i].value.integer != 0; } } return false; @@ -94,37 +64,17 @@ static bool maybe_add_load_reporting_filter(grpc_channel_stack_builder *builder, return true; } -static void lrd_arg_destroy(void *p) { grpc_load_reporting_config_destroy(p); } - -static void *lrd_arg_copy(void *p) { - return grpc_load_reporting_config_copy(p); -} - -static int lrd_arg_cmp(void *a, void *b) { - grpc_load_reporting_config *lhs = a; - grpc_load_reporting_config *rhs = b; - return !(lhs->fn == rhs->fn && lhs->user_data == rhs->user_data); -} - -static const grpc_arg_pointer_vtable lrd_ptr_vtable = { - lrd_arg_copy, lrd_arg_destroy, lrd_arg_cmp}; - -grpc_arg grpc_load_reporting_config_create_arg( - grpc_load_reporting_config *lrc) { +grpc_arg grpc_load_reporting_enable_arg() { grpc_arg arg; - arg.type = GRPC_ARG_POINTER; + arg.type = GRPC_ARG_INTEGER; arg.key = GRPC_ARG_ENABLE_LOAD_REPORTING; - arg.value.pointer.p = lrc; - arg.value.pointer.vtable = &lrd_ptr_vtable; + arg.value.integer = 1; return arg; } /* Plugin registration */ void grpc_load_reporting_plugin_init(void) { - grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, - maybe_add_load_reporting_filter, - (void *)&grpc_load_reporting_filter); grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, maybe_add_load_reporting_filter, (void *)&grpc_load_reporting_filter); diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/load_reporting/load_reporting.h index 316cd89bd72..e37817d8c2f 100644 --- a/src/core/ext/load_reporting/load_reporting.h +++ b/src/core/ext/load_reporting/load_reporting.h @@ -34,42 +34,47 @@ #ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H #define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H -#include "src/core/lib/iomgr/closure.h" -#include "src/core/lib/surface/call.h" +#include +#include "src/core/lib/channel/channel_stack.h" -typedef struct grpc_load_reporting_config grpc_load_reporting_config; +/** Metadata key for initial metadata coming from clients */ +/* TODO(dgq): change to the final value TBD */ +#define GRPC_LOAD_REPORTING_INITIAL_MD_KEY "load-reporting-initial" -/** Call information to be passed to the provided load reporting function upon - * completion of the call */ -typedef struct grpc_load_reporting_call_data { - const grpc_call_stats *stats; /**< Stats for the call */ - const char *trailing_md_string; /**< LR trailing metadata info */ -} grpc_load_reporting_call_data; +/** Metadata key for trailing metadata from servers */ +/* TODO(dgq): change to the final value TBD */ +#define GRPC_LOAD_REPORTING_TRAILING_MD_KEY "load-reporting-trailing" -/** Custom function to be called by the load reporting filter. */ -typedef void (*grpc_load_reporting_fn)( - const grpc_load_reporting_call_data *call_data, void *user_data); +/** Identifiers for the invocation point of the users LR callback */ +typedef enum grpc_load_reporting_source { + GRPC_LR_POINT_UNKNOWN = 0, + GRPC_LR_POINT_CHANNEL_CREATION, + GRPC_LR_POINT_CHANNEL_DESTRUCTION, + GRPC_LR_POINT_CALL_CREATION, + GRPC_LR_POINT_CALL_DESTRUCTION +} grpc_load_reporting_source; -/** Register \a fn as the function to be invoked by the load reporting filter. - * \a fn will be invoked at the beginning and at the end of the call. - * - * For the first invocation, \a fn's first argument - * (grpc_load_reporting_call_data*) will be NULL. \a user_data is always passed - * as-is. */ -grpc_load_reporting_config *grpc_load_reporting_config_create( - grpc_load_reporting_fn fn, void *user_data); +/** Call information to be passed to the provided LR callback. */ +typedef struct grpc_load_reporting_call_data { + const grpc_load_reporting_source source; /**< point of last data update. */ + + /** Unique identifier for the channel associated with the data */ + intptr_t channel_id; -grpc_load_reporting_config *grpc_load_reporting_config_copy( - grpc_load_reporting_config *src); + /** Unique identifier for the call associated with the data. If the call + * hasn't been created yet, it'll have a value of zero. */ + intptr_t call_id; -void grpc_load_reporting_config_destroy(grpc_load_reporting_config *lrc); + /** Only valid when \a source is \a GRPC_LR_POINT_CALL_DESTRUCTION, that is, + * once the call has completed */ + const grpc_call_final_info *final_info; -/** Invoke the function registered by \a grpc_load_reporting_init. */ -void grpc_load_reporting_config_call( - grpc_load_reporting_config *lrc, - const grpc_load_reporting_call_data *call_data); + const char *initial_md_string; /**< value string for LR's initial md key */ + const char *trailing_md_string; /**< value string for LR's trailing md key */ + const char *method_name; /**< Corresponds to :path header */ +} grpc_load_reporting_call_data; /** Return a \a grpc_arg enabling load reporting */ -grpc_arg grpc_load_reporting_config_create_arg(grpc_load_reporting_config *lrc); +grpc_arg grpc_load_reporting_enable_arg(); #endif /* GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H */ diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c index f372f88c3a6..394f0cb8327 100644 --- a/src/core/ext/load_reporting/load_reporting_filter.c +++ b/src/core/ext/load_reporting/load_reporting_filter.c @@ -31,6 +31,7 @@ * */ +#include #include #include #include @@ -42,38 +43,112 @@ #include "src/core/lib/profiling/timers.h" #include "src/core/lib/transport/static_metadata.h" -typedef struct call_data { const char *trailing_md_string; } call_data; +typedef struct call_data { + intptr_t id; /**< an id unique to the call */ + char *trailing_md_string; + char *initial_md_string; + const char *service_method; + + /* stores the recv_initial_metadata op's ready closure, which we wrap with our + * own (on_initial_md_ready) in order to capture the incoming initial metadata + * */ + grpc_closure *ops_recv_initial_metadata_ready; + + /* to get notified of the availability of the incoming initial metadata. */ + grpc_closure on_initial_md_ready; + grpc_metadata_batch *recv_initial_metadata; +} call_data; + typedef struct channel_data { - gpr_mu mu; - grpc_load_reporting_config *lrc; + intptr_t id; /**< an id unique to the channel */ } channel_data; -static void invoke_lr_fn_locked(grpc_load_reporting_config *lrc, - grpc_load_reporting_call_data *lr_call_data) { - GPR_TIMER_BEGIN("load_reporting_config_fn", 0); - grpc_load_reporting_config_call(lrc, lr_call_data); - GPR_TIMER_END("load_reporting_config_fn", 0); +typedef struct { + grpc_call_element *elem; + grpc_exec_ctx *exec_ctx; +} recv_md_filter_args; + +static grpc_mdelem *recv_md_filter(void *user_data, grpc_mdelem *md) { + recv_md_filter_args *a = user_data; + grpc_call_element *elem = a->elem; + call_data *calld = elem->call_data; + + if (md->key == GRPC_MDSTR_PATH) { + calld->service_method = grpc_mdstr_as_c_string(md->value); + } else if (md->key == GRPC_MDSTR_LOAD_REPORTING_INITIAL) { + calld->initial_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value)); + return NULL; + } + + return md; +} + +static void on_initial_md_ready(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_error *err) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + + if (err == GRPC_ERROR_NONE) { + recv_md_filter_args a; + a.elem = elem; + a.exec_ctx = exec_ctx; + grpc_metadata_batch_filter(calld->recv_initial_metadata, recv_md_filter, + &a); + if (calld->service_method == NULL) { + err = + grpc_error_add_child(err, GRPC_ERROR_CREATE("Missing :path header")); + } + } else { + GRPC_ERROR_REF(err); + } + calld->ops_recv_initial_metadata_ready->cb( + exec_ctx, calld->ops_recv_initial_metadata_ready->cb_arg, err); + GRPC_ERROR_UNREF(err); } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; memset(calld, 0, sizeof(call_data)); + + calld->id = (intptr_t)args->call_stack; + grpc_closure_init(&calld->on_initial_md_ready, on_initial_md_ready, elem); + + /* TODO(dgq): do something with the data + channel_data *chand = elem->channel_data; + grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CALL_CREATION, + (intptr_t)chand->id, + (intptr_t)calld->id, + NULL, + NULL, + NULL, + NULL}; + */ + + return GRPC_ERROR_NONE; } /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) { - channel_data *chand = elem->channel_data; + const grpc_call_final_info *final_info, + void *ignored) { call_data *calld = elem->call_data; - grpc_load_reporting_call_data lr_call_data = {stats, - calld->trailing_md_string}; - - gpr_mu_lock(&chand->mu); - invoke_lr_fn_locked(chand->lrc, &lr_call_data); - gpr_mu_unlock(&chand->mu); + /* TODO(dgq): do something with the data + channel_data *chand = elem->channel_data; + grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CALL_DESTRUCTION, + (intptr_t)chand->id, + (intptr_t)calld->id, + final_info, + calld->initial_md_string, + calld->trailing_md_string, + calld->service_method}; + */ + + gpr_free(calld->initial_md_string); + gpr_free(calld->trailing_md_string); } /* Constructor for channel_data */ @@ -85,37 +160,40 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, channel_data *chand = elem->channel_data; memset(chand, 0, sizeof(channel_data)); - gpr_mu_init(&chand->mu); - for (size_t i = 0; i < args->channel_args->num_args; i++) { - if (0 == strcmp(args->channel_args->args[i].key, - GRPC_ARG_ENABLE_LOAD_REPORTING)) { - grpc_load_reporting_config *arg_lrc = - args->channel_args->args[i].value.pointer.p; - chand->lrc = grpc_load_reporting_config_copy(arg_lrc); - GPR_ASSERT(chand->lrc != NULL); - break; - } - } - GPR_ASSERT(chand->lrc != NULL); /* arg actually found */ - - gpr_mu_lock(&chand->mu); - invoke_lr_fn_locked(chand->lrc, NULL); - gpr_mu_unlock(&chand->mu); + chand->id = (intptr_t)args->channel_stack; + + /* TODO(dgq): do something with the data + grpc_load_reporting_call_data lr_call_data = {GRPC_LR_POINT_CHANNEL_CREATION, + (intptr_t)chand, + 0, + NULL, + NULL, + NULL, + NULL}; + */ } /* Destructor for channel data */ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) { + /* TODO(dgq): do something with the data channel_data *chand = elem->channel_data; - gpr_mu_destroy(&chand->mu); - grpc_load_reporting_config_destroy(chand->lrc); + grpc_load_reporting_call_data lr_call_data = { + GRPC_LR_POINT_CHANNEL_DESTRUCTION, + (intptr_t)chand->id, + 0, + NULL, + NULL, + NULL, + NULL}; + */ } static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) { grpc_call_element *elem = user_data; call_data *calld = elem->call_data; - if (md->key == GRPC_MDSTR_LOAD_REPORTING) { + if (md->key == GRPC_MDSTR_LOAD_REPORTING_TRAILING) { calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value)); return NULL; } @@ -127,8 +205,14 @@ static void lr_start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op) { GPR_TIMER_BEGIN("lr_start_transport_stream_op", 0); + call_data *calld = elem->call_data; - if (op->send_trailing_metadata) { + if (op->recv_initial_metadata) { + calld->recv_initial_metadata = op->recv_initial_metadata; + /* substitute our callback for the higher callback */ + calld->ops_recv_initial_metadata_ready = op->recv_initial_metadata_ready; + op->recv_initial_metadata_ready = &calld->on_initial_md_ready; + } else if (op->send_trailing_metadata) { grpc_metadata_batch_filter(op->send_trailing_metadata, lr_trailing_md_filter, elem); } diff --git a/src/core/ext/load_reporting/load_reporting_filter.h b/src/core/ext/load_reporting/load_reporting_filter.h index f69cd6fdc6d..160ed32af99 100644 --- a/src/core/ext/load_reporting/load_reporting_filter.h +++ b/src/core/ext/load_reporting/load_reporting_filter.h @@ -34,6 +34,7 @@ #ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H #define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H +#include "src/core/ext/load_reporting/load_reporting.h" #include "src/core/lib/channel/channel_stack.h" extern const grpc_channel_filter grpc_load_reporting_filter; diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c index 31ac968670f..79682e78b5d 100644 --- a/src/core/ext/resolver/dns/native/dns_resolver.c +++ b/src/core/ext/resolver/dns/native/dns_resolver.c @@ -67,16 +67,16 @@ typedef struct { gpr_mu mu; /** are we currently resolving? */ int resolving; - /** which version of resolved_config have we published? */ + /** which version of the result have we published? */ int published_version; - /** which version of resolved_config is current? */ + /** which version of the result is current? */ int resolved_version; /** pending next completion, or NULL */ grpc_closure *next_completion; - /** target config address for next completion */ - grpc_client_config **target_config; - /** current (fully resolved) config */ - grpc_client_config *resolved_config; + /** target result address for next completion */ + grpc_resolver_result **target_result; + /** current (fully resolved) result */ + grpc_resolver_result *resolved_result; /** retry timer */ bool have_retry_timer; grpc_timer retry_timer; @@ -97,7 +97,7 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r); static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, - grpc_client_config **target_config, + grpc_resolver_result **target_result, grpc_closure *on_complete); static const grpc_resolver_vtable dns_resolver_vtable = { @@ -110,7 +110,7 @@ static void dns_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver) { grpc_timer_cancel(exec_ctx, &r->retry_timer); } if (r->next_completion != NULL) { - *r->target_config = NULL; + *r->target_result = NULL; grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_CREATE("Resolver Shutdown"), NULL); r->next_completion = NULL; @@ -130,13 +130,13 @@ static void dns_channel_saw_error(grpc_exec_ctx *exec_ctx, } static void dns_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, + grpc_resolver_result **target_result, grpc_closure *on_complete) { dns_resolver *r = (dns_resolver *)resolver; gpr_mu_lock(&r->mu); GPR_ASSERT(!r->next_completion); r->next_completion = on_complete; - r->target_config = target_config; + r->target_result = target_result; if (r->resolved_version == 0 && !r->resolving) { gpr_backoff_reset(&r->backoff_state); dns_start_resolving_locked(exec_ctx, r); @@ -165,7 +165,7 @@ static void dns_on_retry_timer(grpc_exec_ctx *exec_ctx, void *arg, static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { dns_resolver *r = arg; - grpc_client_config *config = NULL; + grpc_resolver_result *result = NULL; grpc_lb_policy *lb_policy; gpr_mu_lock(&r->mu); GPR_ASSERT(r->resolving); @@ -173,14 +173,14 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, grpc_resolved_addresses *addresses = r->addresses; if (addresses != NULL) { grpc_lb_policy_args lb_policy_args; - config = grpc_client_config_create(); + result = grpc_resolver_result_create(); memset(&lb_policy_args, 0, sizeof(lb_policy_args)); lb_policy_args.addresses = addresses; lb_policy_args.client_channel_factory = r->client_channel_factory; lb_policy = grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args); if (lb_policy != NULL) { - grpc_client_config_set_lb_policy(config, lb_policy); + grpc_resolver_result_set_lb_policy(result, lb_policy); GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction"); } grpc_resolved_addresses_destroy(addresses); @@ -203,10 +203,10 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg, grpc_timer_init(exec_ctx, &r->retry_timer, next_try, dns_on_retry_timer, r, now); } - if (r->resolved_config) { - grpc_client_config_unref(exec_ctx, r->resolved_config); + if (r->resolved_result) { + grpc_resolver_result_unref(exec_ctx, r->resolved_result); } - r->resolved_config = config; + r->resolved_result = result; r->resolved_version++; dns_maybe_finish_next_locked(exec_ctx, r); gpr_mu_unlock(&r->mu); @@ -228,9 +228,9 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, dns_resolver *r) { if (r->next_completion != NULL && r->resolved_version != r->published_version) { - *r->target_config = r->resolved_config; - if (r->resolved_config) { - grpc_client_config_ref(r->resolved_config); + *r->target_result = r->resolved_result; + if (r->resolved_result) { + grpc_resolver_result_ref(r->resolved_result); } grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL); r->next_completion = NULL; @@ -241,8 +241,8 @@ static void dns_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) { dns_resolver *r = (dns_resolver *)gr; gpr_mu_destroy(&r->mu); - if (r->resolved_config) { - grpc_client_config_unref(exec_ctx, r->resolved_config); + if (r->resolved_result) { + grpc_resolver_result_unref(exec_ctx, r->resolved_result); } grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory); gpr_free(r->name); diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c index 1f7cce2f43a..3807522d2bd 100644 --- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c +++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c @@ -66,8 +66,8 @@ typedef struct { int published; /** pending next completion, or NULL */ grpc_closure *next_completion; - /** target config address for next completion */ - grpc_client_config **target_config; + /** target result address for next completion */ + grpc_resolver_result **target_result; } sockaddr_resolver; static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *r); @@ -79,7 +79,7 @@ static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, grpc_resolver *r); static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx, grpc_resolver *r); static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *r, - grpc_client_config **target_config, + grpc_resolver_result **target_result, grpc_closure *on_complete); static const grpc_resolver_vtable sockaddr_resolver_vtable = { @@ -91,7 +91,7 @@ static void sockaddr_shutdown(grpc_exec_ctx *exec_ctx, sockaddr_resolver *r = (sockaddr_resolver *)resolver; gpr_mu_lock(&r->mu); if (r->next_completion != NULL) { - *r->target_config = NULL; + *r->target_result = NULL; grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL); r->next_completion = NULL; } @@ -108,13 +108,13 @@ static void sockaddr_channel_saw_error(grpc_exec_ctx *exec_ctx, } static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, - grpc_client_config **target_config, + grpc_resolver_result **target_result, grpc_closure *on_complete) { sockaddr_resolver *r = (sockaddr_resolver *)resolver; gpr_mu_lock(&r->mu); GPR_ASSERT(!r->next_completion); r->next_completion = on_complete; - r->target_config = target_config; + r->target_result = target_result; sockaddr_maybe_finish_next_locked(exec_ctx, r); gpr_mu_unlock(&r->mu); } @@ -122,17 +122,17 @@ static void sockaddr_next(grpc_exec_ctx *exec_ctx, grpc_resolver *resolver, static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx, sockaddr_resolver *r) { if (r->next_completion != NULL && !r->published) { - grpc_client_config *cfg = grpc_client_config_create(); + grpc_resolver_result *result = grpc_resolver_result_create(); grpc_lb_policy_args lb_policy_args; memset(&lb_policy_args, 0, sizeof(lb_policy_args)); lb_policy_args.addresses = r->addresses; lb_policy_args.client_channel_factory = r->client_channel_factory; grpc_lb_policy *lb_policy = grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args); - grpc_client_config_set_lb_policy(cfg, lb_policy); + grpc_resolver_result_set_lb_policy(result, lb_policy); GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr"); r->published = 1; - *r->target_config = cfg; + *r->target_result = result; grpc_exec_ctx_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE, NULL); r->next_completion = NULL; } diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c index 85f9efb3b63..cbaa75a90af 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c @@ -45,6 +45,7 @@ #include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/compress_filter.h" +#include "src/core/lib/channel/handshaker.h" #include "src/core/lib/channel/http_client_filter.h" #include "src/core/lib/iomgr/tcp_client.h" #include "src/core/lib/surface/api_trace.h" @@ -63,6 +64,8 @@ typedef struct { grpc_endpoint *tcp; grpc_closure connected; + + grpc_handshake_manager *handshake_mgr; } connector; static void connector_ref(grpc_connector *con) { @@ -74,6 +77,7 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } } @@ -83,9 +87,29 @@ static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, connector_unref(exec_ctx, arg); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, + grpc_error *error) { + connector *c = user_data; + if (error != GRPC_ERROR_NONE) { + grpc_channel_args_destroy(args); + gpr_free(read_buffer); + } else { + c->result->transport = + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 1); + GPR_ASSERT(c->result->transport); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, + read_buffer); + c->result->channel_args = args; + } + grpc_closure *notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); +} + static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_closure *notify; grpc_endpoint *tcp = c->tcp; if (tcp != NULL) { if (!GPR_SLICE_IS_EMPTY(c->args.initial_connect_string)) { @@ -97,19 +121,17 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector_ref(arg); grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); + } else { + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } - c->result->transport = - grpc_create_chttp2_transport(exec_ctx, c->args.channel_args, tcp, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); - GPR_ASSERT(c->result->transport); - c->result->channel_args = grpc_channel_args_copy(c->args.channel_args); } else { memset(c->result, 0, sizeof(*c->result)); + grpc_closure *notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } - notify = c->notify; - c->notify = NULL; - grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } static void connector_shutdown(grpc_exec_ctx *exec_ctx, grpc_connector *con) {} @@ -171,6 +193,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel( memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; gpr_ref_init(&c->refs, 1); + c->handshake_mgr = grpc_handshake_manager_create(); args->args = final_args; s = grpc_subchannel_create(exec_ctx, &c->base, args); grpc_connector_unref(exec_ctx, &c->base); diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c index ca435c25cec..b2c5e5b088c 100644 --- a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c @@ -75,7 +75,7 @@ grpc_channel *grpc_insecure_channel_create_from_fd( grpc_channel *channel = grpc_channel_create( &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport); grpc_channel_args_destroy(final_args); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c index 9acacbd92d4..9e2bdd758f9 100644 --- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c +++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c @@ -44,6 +44,7 @@ #include "src/core/ext/client_config/resolver_registry.h" #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/iomgr/tcp_client.h" #include "src/core/lib/security/context/security_context.h" #include "src/core/lib/security/credentials/credentials.h" @@ -69,6 +70,11 @@ typedef struct { grpc_endpoint *newly_connecting_endpoint; grpc_closure connected_closure; + + grpc_handshake_manager *handshake_mgr; + + // TODO(roth): Remove once we eliminate on_secure_handshake_done(). + grpc_channel_args *tmp_args; } connector; static void connector_ref(grpc_connector *con) { @@ -80,6 +86,8 @@ static void connector_unref(grpc_exec_ctx *exec_ctx, grpc_connector *con) { connector *c = (connector *)con; if (gpr_unref(&c->refs)) { /* c->initial_string_buffer does not need to be destroyed */ + grpc_channel_args_destroy(c->tmp_args); + grpc_handshake_manager_destroy(exec_ctx, c->handshake_mgr); gpr_free(c); } } @@ -89,7 +97,6 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context) { connector *c = arg; - grpc_closure *notify; gpr_mu_lock(&c->mu); grpc_error *error = GRPC_ERROR_NONE; if (c->connecting_endpoint == NULL) { @@ -107,28 +114,47 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *arg, gpr_mu_unlock(&c->mu); c->result->transport = grpc_create_chttp2_transport( exec_ctx, c->args.channel_args, secure_endpoint, 1); - grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL, - 0); + grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL); auth_context_arg = grpc_auth_context_to_arg(auth_context); - c->result->channel_args = grpc_channel_args_copy_and_add( - c->args.channel_args, &auth_context_arg, 1); + c->result->channel_args = + grpc_channel_args_copy_and_add(c->tmp_args, &auth_context_arg, 1); } - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, + grpc_error *error) { + connector *c = user_data; + c->tmp_args = args; + if (error != GRPC_ERROR_NONE) { + gpr_free(read_buffer); + grpc_closure *notify = c->notify; + c->notify = NULL; + grpc_exec_ctx_sched(exec_ctx, notify, error, NULL); + } else { + // TODO(roth, jboeuf): Convert security connector handshaking to use new + // handshake API, and then move the code from on_secure_handshake_done() + // into this function. + grpc_channel_security_connector_do_handshake( + exec_ctx, c->security_connector, endpoint, read_buffer, + c->args.deadline, on_secure_handshake_done, c); + } +} + static void on_initial_connect_string_sent(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, c->connecting_endpoint, c->args.deadline, - on_secure_handshake_done, c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, c->connecting_endpoint, c->args.channel_args, + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { connector *c = arg; - grpc_closure *notify; grpc_endpoint *tcp = c->newly_connecting_endpoint; if (tcp != NULL) { gpr_mu_lock(&c->mu); @@ -144,13 +170,13 @@ static void connected(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_endpoint_write(exec_ctx, tcp, &c->initial_string_buffer, &c->initial_string_sent); } else { - grpc_channel_security_connector_do_handshake( - exec_ctx, c->security_connector, tcp, c->args.deadline, - on_secure_handshake_done, c); + grpc_handshake_manager_do_handshake( + exec_ctx, c->handshake_mgr, tcp, c->args.channel_args, + c->args.deadline, NULL /* acceptor */, on_handshake_done, c); } } else { memset(c->result, 0, sizeof(*c->result)); - notify = c->notify; + grpc_closure *notify = c->notify; c->notify = NULL; grpc_exec_ctx_sched(exec_ctx, notify, GRPC_ERROR_REF(error), NULL); } @@ -229,6 +255,7 @@ static grpc_subchannel *client_channel_factory_create_subchannel( memset(c, 0, sizeof(*c)); c->base.vtable = &connector_vtable; c->security_connector = f->security_connector; + c->handshake_mgr = grpc_handshake_manager_create(); gpr_mu_init(&c->mu); gpr_ref_init(&c->refs, 1); args->args = final_args; diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c index e5c987925c3..f0e07429faf 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2.c @@ -37,35 +37,76 @@ #include #include #include + #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/channel/http_server_filter.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/tcp_server.h" #include "src/core/lib/surface/api_trace.h" #include "src/core/lib/surface/server.h" -static void new_transport(grpc_exec_ctx *exec_ctx, void *server, - grpc_endpoint *tcp, grpc_pollset *accepting_pollset, - grpc_tcp_server_acceptor *acceptor) { - /* - * Beware that the call to grpc_create_chttp2_transport() has to happen before - * grpc_tcp_server_destroy(). This is fine here, but similar code - * asynchronously doing a handshake instead of calling grpc_tcp_server_start() - * (as in server_secure_chttp2.c) needs to add synchronization to avoid this - * case. - */ - grpc_transport *transport = grpc_create_chttp2_transport( - exec_ctx, grpc_server_get_channel_args(server), tcp, 0); - grpc_server_setup_transport(exec_ctx, server, transport, accepting_pollset, - grpc_server_get_channel_args(server)); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); +typedef struct server_connect_state { + grpc_server *server; + grpc_pollset *accepting_pollset; + grpc_tcp_server_acceptor *acceptor; + grpc_handshake_manager *handshake_mgr; +} server_connect_state; + +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, + grpc_error *error) { + server_connect_state *state = user_data; + if (error != GRPC_ERROR_NONE) { + const char *error_str = grpc_error_string(error); + gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str); + grpc_error_free_string(error_str); + GRPC_ERROR_UNREF(error); + grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); + gpr_free(read_buffer); + } else { + // Beware that the call to grpc_create_chttp2_transport() has to happen + // before grpc_tcp_server_destroy(). This is fine here, but similar code + // asynchronously doing a handshake instead of calling + // grpc_tcp_server_start() (as in server_secure_chttp2.c) needs to add + // synchronization to avoid this case. + grpc_transport *transport = + grpc_create_chttp2_transport(exec_ctx, args, endpoint, 0); + grpc_server_setup_transport(exec_ctx, state->server, transport, + state->accepting_pollset, + grpc_server_get_channel_args(state->server)); + grpc_chttp2_transport_start_reading(exec_ctx, transport, read_buffer); + } + // Clean up. + grpc_channel_args_destroy(args); + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + gpr_free(state); +} + +static void on_accept(grpc_exec_ctx *exec_ctx, void *server, grpc_endpoint *tcp, + grpc_pollset *accepting_pollset, + grpc_tcp_server_acceptor *acceptor) { + server_connect_state *state = gpr_malloc(sizeof(server_connect_state)); + state->server = server; + state->accepting_pollset = accepting_pollset; + state->acceptor = acceptor; + state->handshake_mgr = grpc_handshake_manager_create(); + // TODO(roth): We should really get this timeout value from channel + // args instead of hard-coding it. + const gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(120, GPR_TIMESPAN)); + grpc_handshake_manager_do_handshake( + exec_ctx, state->handshake_mgr, tcp, grpc_server_get_channel_args(server), + deadline, acceptor, on_handshake_done, state); } /* Server callback: start listening on our ports */ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) { grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, new_transport, + grpc_tcp_server_start(exec_ctx, tcp, pollsets, pollset_count, on_accept, server); } @@ -74,6 +115,7 @@ static void start(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *tcpp, grpc_closure *destroy_done) { grpc_tcp_server *tcp = tcpp; + grpc_tcp_server_shutdown_listeners(exec_ctx, tcp); grpc_tcp_server_unref(exec_ctx, tcp); grpc_exec_ctx_sched(exec_ctx, destroy_done, GRPC_ERROR_NONE, NULL); } diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c index 96bf4d6f308..4350543c27a 100644 --- a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c +++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c @@ -67,7 +67,7 @@ void grpc_server_add_insecure_channel_from_fd(grpc_server *server, &exec_ctx, server_args, server_endpoint, 0 /* is_client */); grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, grpc_cq_pollset(cq)); grpc_server_setup_transport(&exec_ctx, server, transport, NULL, server_args); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c index c42810e9130..da3e284fcf2 100644 --- a/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c +++ b/src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c @@ -42,6 +42,7 @@ #include #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/channel/http_server_filter.h" #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/iomgr/resolve_address.h" @@ -58,7 +59,7 @@ typedef struct server_secure_state { grpc_tcp_server *tcp; grpc_server_security_connector *sc; grpc_server_credentials *creds; - int is_shutdown; + bool is_shutdown; gpr_mu mu; gpr_refcount refcount; grpc_closure destroy_closure; @@ -68,6 +69,12 @@ typedef struct server_secure_state { typedef struct server_secure_connect { server_secure_state *state; grpc_pollset *accepting_pollset; + grpc_tcp_server_acceptor *acceptor; + grpc_handshake_manager *handshake_mgr; + // TODO(roth): Remove the following two fields when we eliminate + // grpc_server_security_connector_do_handshake(). + gpr_timespec deadline; + grpc_channel_args *args; } server_secure_connect; static void state_ref(server_secure_state *state) { gpr_ref(&state->refcount); } @@ -89,25 +96,22 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *secure_endpoint, grpc_auth_context *auth_context) { server_secure_connect *state = statep; - grpc_transport *transport; if (status == GRPC_SECURITY_OK) { if (secure_endpoint) { gpr_mu_lock(&state->state->mu); if (!state->state->is_shutdown) { - transport = grpc_create_chttp2_transport( + grpc_transport *transport = grpc_create_chttp2_transport( exec_ctx, grpc_server_get_channel_args(state->state->server), secure_endpoint, 0); - grpc_channel_args *args_copy; grpc_arg args_to_add[2]; args_to_add[0] = grpc_server_credentials_to_arg(state->state->creds); args_to_add[1] = grpc_auth_context_to_arg(auth_context); - args_copy = grpc_channel_args_copy_and_add( - grpc_server_get_channel_args(state->state->server), args_to_add, - GPR_ARRAY_SIZE(args_to_add)); + grpc_channel_args *args_copy = grpc_channel_args_copy_and_add( + state->args, args_to_add, GPR_ARRAY_SIZE(args_to_add)); grpc_server_setup_transport(exec_ctx, state->state->server, transport, state->accepting_pollset, args_copy); grpc_channel_args_destroy(args_copy); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL); } else { /* We need to consume this here, because the server may already have * gone away. */ @@ -118,10 +122,40 @@ static void on_secure_handshake_done(grpc_exec_ctx *exec_ctx, void *statep, } else { gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); } + grpc_channel_args_destroy(state->args); state_unref(state->state); gpr_free(state); } +static void on_handshake_done(grpc_exec_ctx *exec_ctx, grpc_endpoint *endpoint, + grpc_channel_args *args, + gpr_slice_buffer *read_buffer, void *user_data, + grpc_error *error) { + server_secure_connect *state = user_data; + if (error != GRPC_ERROR_NONE) { + const char *error_str = grpc_error_string(error); + gpr_log(GPR_ERROR, "Handshaking failed: %s", error_str); + grpc_error_free_string(error_str); + GRPC_ERROR_UNREF(error); + grpc_channel_args_destroy(args); + gpr_free(read_buffer); + grpc_handshake_manager_shutdown(exec_ctx, state->handshake_mgr); + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + state_unref(state->state); + gpr_free(state); + return; + } + grpc_handshake_manager_destroy(exec_ctx, state->handshake_mgr); + state->handshake_mgr = NULL; + // TODO(roth, jboeuf): Convert security connector handshaking to use new + // handshake API, and then move the code from on_secure_handshake_done() + // into this function. + state->args = args; + grpc_server_security_connector_do_handshake( + exec_ctx, state->state->sc, state->acceptor, endpoint, read_buffer, + state->deadline, on_secure_handshake_done, state); +} + static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, grpc_pollset *accepting_pollset, grpc_tcp_server_acceptor *acceptor) { @@ -129,11 +163,16 @@ static void on_accept(grpc_exec_ctx *exec_ctx, void *statep, grpc_endpoint *tcp, state->state = statep; state_ref(state->state); state->accepting_pollset = accepting_pollset; - grpc_server_security_connector_do_handshake( - exec_ctx, state->state->sc, acceptor, tcp, - gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), - gpr_time_from_seconds(120, GPR_TIMESPAN)), - on_secure_handshake_done, state); + state->acceptor = acceptor; + state->handshake_mgr = grpc_handshake_manager_create(); + // TODO(roth): We should really get this timeout value from channel + // args instead of hard-coding it. + state->deadline = gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(120, GPR_TIMESPAN)); + grpc_handshake_manager_do_handshake( + exec_ctx, state->handshake_mgr, tcp, + grpc_server_get_channel_args(state->state->server), state->deadline, + acceptor, on_handshake_done, state); } /* Server callback: start listening on our ports */ @@ -162,10 +201,11 @@ static void destroy(grpc_exec_ctx *exec_ctx, grpc_server *server, void *statep, server_secure_state *state = statep; grpc_tcp_server *tcp; gpr_mu_lock(&state->mu); - state->is_shutdown = 1; + state->is_shutdown = true; state->destroy_callback = callback; tcp = state->tcp; gpr_mu_unlock(&state->mu); + grpc_tcp_server_shutdown_listeners(exec_ctx, tcp); grpc_tcp_server_unref(exec_ctx, tcp); } @@ -226,7 +266,7 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, state->tcp = tcp; state->sc = sc; state->creds = grpc_server_credentials_ref(creds); - state->is_shutdown = 0; + state->is_shutdown = false; gpr_mu_init(&state->mu); gpr_ref_init(&state->refcount, 1); diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c index be8a8f84987..00999e3b940 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c @@ -46,12 +46,12 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/ext/transport/chttp2/transport/internal.h" #include "src/core/ext/transport/chttp2/transport/status_conversion.h" -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/lib/http/parser.h" #include "src/core/lib/iomgr/workqueue.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/support/string.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/timeout_encoding.h" #include "src/core/lib/transport/transport_impl.h" #define DEFAULT_WINDOW 65535 @@ -94,7 +94,8 @@ static void initiate_writing(grpc_exec_ctx *exec_ctx, void *t, static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t); static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, grpc_error *error); + grpc_chttp2_transport *t, grpc_error *error, + const char *reason); /** Set a transport level setting, and push it to our peer */ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, @@ -407,6 +408,19 @@ static void init_transport(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE, (uint32_t)channel_args->args[i].value.integer); } + } else if (0 == strcmp(channel_args->args[i].key, + GRPC_ARG_HTTP2_MAX_FRAME_SIZE)) { + if (channel_args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_HTTP2_MAX_FRAME_SIZE); + } else if (channel_args->args[i].value.integer < 16384 || + channel_args->args[i].value.integer > 16777215) { + gpr_log(GPR_ERROR, "%s: must be between 16384 and 16777215", + GRPC_ARG_HTTP2_MAX_FRAME_SIZE); + } else { + push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE, + (uint32_t)channel_args->args[i].value.integer); + } } } } @@ -876,7 +890,7 @@ static void start_writing(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) { set_write_state(t, GRPC_CHTTP2_WRITING_INACTIVE, "start_writing:nothing_to_write"); } - end_waiting_for_write(exec_ctx, t, GRPC_ERROR_CREATE("Nothing to write")); + end_waiting_for_write(exec_ctx, t, GRPC_ERROR_NONE, "Nothing to write"); if (t->ep && !t->endpoint_reading) { destroy_endpoint(exec_ctx, t); } @@ -925,11 +939,18 @@ static void push_setting(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t, } } +/* error may be GRPC_ERROR_NONE if there is no error allocated yet. + In that case, use "reason" as the text for a new error. */ static void end_waiting_for_write(grpc_exec_ctx *exec_ctx, - grpc_chttp2_transport *t, grpc_error *error) { + grpc_chttp2_transport *t, grpc_error *error, + const char *reason) { grpc_chttp2_stream_global *stream_global; while (grpc_chttp2_list_pop_closed_waiting_for_writing(&t->global, &stream_global)) { + if (error == GRPC_ERROR_NONE && reason != NULL) { + /* create error object. */ + error = GRPC_ERROR_CREATE(reason); + } fail_pending_writes(exec_ctx, &t->global, stream_global, GRPC_ERROR_REF(error)); GRPC_CHTTP2_STREAM_UNREF(exec_ctx, stream_global, "finish_writes"); @@ -951,7 +972,7 @@ static void terminate_writing_with_lock(grpc_exec_ctx *exec_ctx, grpc_chttp2_cleanup_writing(exec_ctx, &t->global, &t->writing); - end_waiting_for_write(exec_ctx, t, error); + end_waiting_for_write(exec_ctx, t, error, NULL); switch (t->executor.write_state) { case GRPC_CHTTP2_WRITING_INACTIVE: @@ -2005,6 +2026,7 @@ static grpc_error *try_http_parsing(grpc_exec_ctx *exec_ctx, static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_chttp2_transport *t = arg; + grpc_error *err = GRPC_ERROR_NONE; GPR_TIMER_BEGIN("reading_action.parse", 0); size_t i = 0; grpc_error *errors[3] = {GRPC_ERROR_REF(error), GRPC_ERROR_NONE, @@ -2013,15 +2035,13 @@ static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, errors[1] = grpc_chttp2_perform_read(exec_ctx, &t->parsing, t->read_buffer.slices[i]); }; - if (i != t->read_buffer.count) { + if (errors[1] == GRPC_ERROR_NONE) { + err = GRPC_ERROR_REF(error); + } else { errors[2] = try_http_parsing(exec_ctx, t); + err = GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, + GPR_ARRAY_SIZE(errors)); } - grpc_error *err = - errors[0] == GRPC_ERROR_NONE && errors[1] == GRPC_ERROR_NONE && - errors[2] == GRPC_ERROR_NONE - ? GRPC_ERROR_NONE - : GRPC_ERROR_CREATE_REFERENCING("Failed parsing HTTP/2", errors, - GPR_ARRAY_SIZE(errors)); for (i = 0; i < GPR_ARRAY_SIZE(errors); i++) { GRPC_ERROR_UNREF(errors[i]); } @@ -2539,9 +2559,12 @@ grpc_transport *grpc_create_chttp2_transport( void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, grpc_transport *transport, - gpr_slice *slices, size_t nslices) { + gpr_slice_buffer *read_buffer) { grpc_chttp2_transport *t = (grpc_chttp2_transport *)transport; REF_TRANSPORT(t, "reading_action"); /* matches unref inside reading_action */ - gpr_slice_buffer_addn(&t->read_buffer, slices, nslices); + if (read_buffer != NULL) { + gpr_slice_buffer_move_into(read_buffer, &t->read_buffer); + gpr_free(read_buffer); + } reading_action(exec_ctx, t, GRPC_ERROR_NONE); } diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.h b/src/core/ext/transport/chttp2/transport/chttp2_transport.h index 5da4276f826..4e2d0954bf1 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.h +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.h @@ -44,8 +44,10 @@ grpc_transport *grpc_create_chttp2_transport( grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args, grpc_endpoint *ep, int is_client); +/// Takes ownership of \a read_buffer, which (if non-NULL) contains +/// leftover bytes previously read from the endpoint (e.g., by handshakers). void grpc_chttp2_transport_start_reading(grpc_exec_ctx *exec_ctx, grpc_transport *transport, - gpr_slice *slices, size_t nslices); + gpr_slice_buffer *read_buffer); #endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CHTTP2_TRANSPORT_H */ diff --git a/src/core/ext/transport/chttp2/transport/frame.h b/src/core/ext/transport/chttp2/transport/frame.h index 7776609367b..507aae41003 100644 --- a/src/core/ext/transport/chttp2/transport/frame.h +++ b/src/core/ext/transport/chttp2/transport/frame.h @@ -52,8 +52,6 @@ typedef struct grpc_chttp2_transport_parsing grpc_chttp2_transport_parsing; #define GRPC_CHTTP2_FRAME_GOAWAY 7 #define GRPC_CHTTP2_FRAME_WINDOW_UPDATE 8 -#define GRPC_CHTTP2_MAX_PAYLOAD_LENGTH ((1 << 14) - 1) - #define GRPC_CHTTP2_DATA_FLAG_END_STREAM 1 #define GRPC_CHTTP2_FLAG_ACK 1 #define GRPC_CHTTP2_DATA_FLAG_END_HEADERS 4 diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c index ebeee37f0d9..581471ba02d 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c @@ -47,10 +47,10 @@ #include "src/core/ext/transport/chttp2/transport/bin_encoder.h" #include "src/core/ext/transport/chttp2/transport/hpack_table.h" -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/ext/transport/chttp2/transport/varint.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/timeout_encoding.h" #define HASH_FRAGMENT_1(x) ((x)&255) #define HASH_FRAGMENT_2(x) ((x >> 8) & 255) @@ -78,6 +78,8 @@ typedef struct { uint32_t stream_id; gpr_slice_buffer *output; grpc_transport_one_way_stats *stats; + /* maximum size of a frame */ + size_t max_frame_size; } framer_state; /* fills p (which is expected to be 9 bytes long) with a data frame header */ @@ -123,7 +125,7 @@ static void begin_frame(framer_state *st) { needed */ static void ensure_space(framer_state *st, size_t need_bytes) { if (st->output->length - st->output_length_at_start_of_frame + need_bytes <= - GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) { + st->max_frame_size) { return; } finish_frame(st, 0, 0); @@ -149,8 +151,8 @@ static void add_header_data(framer_state *st, gpr_slice slice) { size_t len = GPR_SLICE_LENGTH(slice); size_t remaining; if (len == 0) return; - remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH + - st->output_length_at_start_of_frame - st->output->length; + remaining = st->max_frame_size + st->output_length_at_start_of_frame - + st->output->length; if (len <= remaining) { st->stats->header_bytes += len; gpr_slice_buffer_add(st->output, slice); @@ -456,9 +458,9 @@ static void hpack_enc(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem, static void deadline_enc(grpc_chttp2_hpack_compressor *c, gpr_timespec deadline, framer_state *st) { - char timeout_str[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; + char timeout_str[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; grpc_mdelem *mdelem; - grpc_chttp2_encode_timeout( + grpc_http2_encode_timeout( gpr_time_sub(deadline, gpr_now(deadline.clock_type)), timeout_str); mdelem = grpc_mdelem_from_metadata_strings( GRPC_MDSTR_GRPC_TIMEOUT, grpc_mdstr_from_string(timeout_str)); @@ -542,6 +544,7 @@ void grpc_chttp2_hpack_compressor_set_max_table_size( void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t stream_id, grpc_metadata_batch *metadata, int is_eof, + size_t max_frame_size, grpc_transport_one_way_stats *stats, gpr_slice_buffer *outbuf) { framer_state st; @@ -555,6 +558,7 @@ void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, st.output = outbuf; st.is_first_frame = 1; st.stats = stats; + st.max_frame_size = max_frame_size; /* Encode a metadata batch; store the returned values, representing a metadata element that needs to be unreffed back into the metadata diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h index 0f7b0b063ab..4c3a9315495 100644 --- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h +++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h @@ -91,6 +91,7 @@ void grpc_chttp2_hpack_compressor_set_max_usable_size( void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id, grpc_metadata_batch *metadata, int is_eof, + size_t max_frame_size, grpc_transport_one_way_stats *stats, gpr_slice_buffer *outbuf); diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h index e1dcf5262a1..d67c014e548 100644 --- a/src/core/ext/transport/chttp2/transport/internal.h +++ b/src/core/ext/transport/chttp2/transport/internal.h @@ -223,6 +223,8 @@ typedef struct { uint8_t is_client; /** callback for when writing is done */ grpc_closure done_cb; + /** maximum frame size */ + uint32_t max_frame_size; } grpc_chttp2_transport_writing; struct grpc_chttp2_transport_parsing { diff --git a/src/core/ext/transport/chttp2/transport/parsing.c b/src/core/ext/transport/chttp2/transport/parsing.c index e1fc0ddee20..482cd55c447 100644 --- a/src/core/ext/transport/chttp2/transport/parsing.c +++ b/src/core/ext/transport/chttp2/transport/parsing.c @@ -41,9 +41,9 @@ #include "src/core/ext/transport/chttp2/transport/http2_errors.h" #include "src/core/ext/transport/chttp2/transport/status_conversion.h" -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" #include "src/core/lib/profiling/timers.h" #include "src/core/lib/transport/static_metadata.h" +#include "src/core/lib/transport/timeout_encoding.h" #define TRANSPORT_FROM_PARSING(tp) \ ((grpc_chttp2_transport *)((char *)(tp)-offsetof(grpc_chttp2_transport, \ @@ -668,8 +668,8 @@ static void on_initial_header(void *tp, grpc_mdelem *md) { if (!cached_timeout) { /* not already parsed: parse it now, and store the result away */ cached_timeout = gpr_malloc(sizeof(gpr_timespec)); - if (!grpc_chttp2_decode_timeout(grpc_mdstr_as_c_string(md->value), - cached_timeout)) { + if (!grpc_http2_decode_timeout(grpc_mdstr_as_c_string(md->value), + cached_timeout)) { gpr_log(GPR_ERROR, "Ignoring bad timeout value '%s'", grpc_mdstr_as_c_string(md->value)); *cached_timeout = gpr_inf_future(GPR_TIMESPAN); diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c index e0d87725e9d..311b26e354a 100644 --- a/src/core/ext/transport/chttp2/transport/writing.c +++ b/src/core/ext/transport/chttp2/transport/writing.c @@ -51,6 +51,10 @@ int grpc_chttp2_unlocking_check_writes( GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0); + transport_writing->max_frame_size = + transport_global->settings[GRPC_ACKED_SETTINGS] + [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE]; + /* simple writes are queued to qbuf, and flushed here */ gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf); GPR_ASSERT(transport_global->qbuf.count == 0); @@ -202,17 +206,19 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx, GPR_TIMER_BEGIN("finalize_outbuf", 0); + bool is_first_data_frame = true; while ( grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) { uint32_t max_outgoing = - (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH, + (uint32_t)GPR_MIN(transport_writing->max_frame_size, GPR_MIN(stream_writing->outgoing_window, transport_writing->outgoing_window)); /* send initial metadata if it's available */ if (stream_writing->send_initial_metadata != NULL) { grpc_chttp2_encode_header( &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_initial_metadata, 0, &stream_writing->stats, + stream_writing->send_initial_metadata, 0, + transport_writing->max_frame_size, &stream_writing->stats, &transport_writing->outbuf); stream_writing->send_initial_metadata = NULL; stream_writing->sent_initial_metadata = 1; @@ -266,6 +272,11 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx, stream_writing->id, &stream_writing->flow_controlled_buffer, send_bytes, is_last_frame, &stream_writing->stats, &transport_writing->outbuf); + if (is_first_data_frame) { + /* TODO(dgq): this is a hack. It'll be fix in a future refactoring */ + stream_writing->stats.data_bytes -= 5; /* discount grpc framing */ + is_first_data_frame = false; + } GRPC_CHTTP2_FLOW_DEBIT_STREAM("write", transport_writing, stream_writing, outgoing_window, send_bytes); @@ -297,7 +308,8 @@ static void finalize_outbuf(grpc_exec_ctx *exec_ctx, } else { grpc_chttp2_encode_header( &transport_writing->hpack_compressor, stream_writing->id, - stream_writing->send_trailing_metadata, 1, &stream_writing->stats, + stream_writing->send_trailing_metadata, 1, + transport_writing->max_frame_size, &stream_writing->stats, &transport_writing->outbuf); } if (!transport_writing->is_client && !stream_writing->read_closed) { diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c index 25d8aca2508..029c15014ed 100644 --- a/src/core/ext/transport/cronet/transport/cronet_transport.c +++ b/src/core/ext/transport/cronet/transport/cronet_transport.c @@ -46,617 +46,964 @@ #include "src/core/lib/support/string.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/transport/metadata_batch.h" +#include "src/core/lib/transport/static_metadata.h" #include "src/core/lib/transport/transport_impl.h" #include "third_party/objective_c/Cronet/cronet_c_for_grpc.h" #define GRPC_HEADER_SIZE_IN_BYTES 5 -// Global flag that gets set with GRPC_TRACE env variable -int grpc_cronet_trace = 1; +#define CRONET_LOG(...) \ + do { \ + if (grpc_cronet_trace) gpr_log(__VA_ARGS__); \ + } while (0) -// Cronet transport object +/* TODO (makdharma): Hook up into the wider tracing mechanism */ +int grpc_cronet_trace = 0; + +enum e_op_result { + ACTION_TAKEN_WITH_CALLBACK, + ACTION_TAKEN_NO_CALLBACK, + NO_ACTION_POSSIBLE +}; + +enum e_op_id { + OP_SEND_INITIAL_METADATA = 0, + OP_SEND_MESSAGE, + OP_SEND_TRAILING_METADATA, + OP_RECV_MESSAGE, + OP_RECV_INITIAL_METADATA, + OP_RECV_TRAILING_METADATA, + OP_CANCEL_ERROR, + OP_ON_COMPLETE, + OP_FAILED, + OP_SUCCEEDED, + OP_CANCELED, + OP_RECV_MESSAGE_AND_ON_COMPLETE, + OP_READ_REQ_MADE, + OP_NUM_OPS +}; + +/* Cronet callbacks. See cronet_c_for_grpc.h for documentation for each. */ + +static void on_request_headers_sent(cronet_bidirectional_stream *); +static void on_response_headers_received( + cronet_bidirectional_stream *, + const cronet_bidirectional_stream_header_array *, const char *); +static void on_write_completed(cronet_bidirectional_stream *, const char *); +static void on_read_completed(cronet_bidirectional_stream *, char *, int); +static void on_response_trailers_received( + cronet_bidirectional_stream *, + const cronet_bidirectional_stream_header_array *); +static void on_succeeded(cronet_bidirectional_stream *); +static void on_failed(cronet_bidirectional_stream *, int); +static void on_canceled(cronet_bidirectional_stream *); +static cronet_bidirectional_stream_callback cronet_callbacks = { + on_request_headers_sent, + on_response_headers_received, + on_read_completed, + on_write_completed, + on_response_trailers_received, + on_succeeded, + on_failed, + on_canceled}; + +/* Cronet transport object */ struct grpc_cronet_transport { grpc_transport base; /* must be first element in this structure */ cronet_engine *engine; char *host; }; - typedef struct grpc_cronet_transport grpc_cronet_transport; -enum send_state { - CRONET_SEND_IDLE = 0, - CRONET_REQ_STARTED, - CRONET_SEND_HEADER, - CRONET_WRITE, - CRONET_WRITE_COMPLETED, +/* TODO (makdharma): reorder structure for memory efficiency per + http://www.catb.org/esr/structure-packing/#_structure_reordering: */ +struct read_state { + /* vars to store data coming from server */ + char *read_buffer; + bool length_field_received; + int received_bytes; + int remaining_bytes; + int length_field; + char grpc_header_bytes[GRPC_HEADER_SIZE_IN_BYTES]; + char *payload_field; + bool read_stream_closed; + + /* vars for holding data destined for the application */ + struct grpc_slice_buffer_stream sbs; + gpr_slice_buffer read_slice_buffer; + + /* vars for trailing metadata */ + grpc_chttp2_incoming_metadata_buffer trailing_metadata; + bool trailing_metadata_valid; + + /* vars for initial metadata */ + grpc_chttp2_incoming_metadata_buffer initial_metadata; }; -enum recv_state { - CRONET_RECV_IDLE = 0, - CRONET_RECV_READ_LENGTH, - CRONET_RECV_READ_DATA, - CRONET_RECV_CLOSED, +struct write_state { + char *write_buffer; }; -static const char *recv_state_name[] = { - "CRONET_RECV_IDLE", "CRONET_RECV_READ_LENGTH", "CRONET_RECV_READ_DATA,", - "CRONET_RECV_CLOSED"}; +/* track state of one stream op */ +struct op_state { + bool state_op_done[OP_NUM_OPS]; + bool state_callback_received[OP_NUM_OPS]; + /* data structure for storing data coming from server */ + struct read_state rs; + /* data structure for storing data going to the server */ + struct write_state ws; +}; -// Enum that identifies calling function. -enum e_caller { - PERFORM_STREAM_OP, - ON_READ_COMPLETE, - ON_RESPONSE_HEADERS_RECEIVED, - ON_RESPONSE_TRAILERS_RECEIVED +struct op_and_state { + grpc_transport_stream_op op; + struct op_state state; + bool done; + struct stream_obj *s; /* Pointer back to the stream object */ + struct op_and_state *next; /* next op_and_state in the linked list */ }; -enum callback_id { - CB_SEND_INITIAL_METADATA = 0, - CB_SEND_MESSAGE, - CB_SEND_TRAILING_METADATA, - CB_RECV_MESSAGE, - CB_RECV_INITIAL_METADATA, - CB_RECV_TRAILING_METADATA, - CB_NUM_CALLBACKS +struct op_storage { + int num_pending_ops; + struct op_and_state *head; }; struct stream_obj { - // we store received bytes here as they trickle in. - gpr_slice_buffer write_slice_buffer; + struct op_and_state *oas; + grpc_transport_stream_op *curr_op; + grpc_cronet_transport curr_ct; + grpc_stream *curr_gs; cronet_bidirectional_stream *cbs; - gpr_slice slice; - gpr_slice_buffer read_slice_buffer; - struct grpc_slice_buffer_stream sbs; - char *read_buffer; - int remaining_read_bytes; - int total_read_bytes; - - char *write_buffer; - size_t write_buffer_size; - - // Hold the URL - char *url; - - bool response_headers_received; - bool read_requested; - bool response_trailers_received; - bool read_closed; - - // Recv message stuff - grpc_byte_buffer **recv_message; - // Initial metadata stuff - grpc_metadata_batch *recv_initial_metadata; - // Trailing metadata stuff - grpc_metadata_batch *recv_trailing_metadata; - grpc_chttp2_incoming_metadata_buffer imb; - - // This mutex protects receive state machine execution - gpr_mu recv_mu; - // we can queue up up to 2 callbacks for each OP - grpc_closure *callback_list[CB_NUM_CALLBACKS][2]; - - // storage for header - cronet_bidirectional_stream_header *headers; - uint32_t num_headers; cronet_bidirectional_stream_header_array header_array; - // state tracking - enum recv_state cronet_recv_state; - enum send_state cronet_send_state; -}; -typedef struct stream_obj stream_obj; + /* Stream level state. Some state will be tracked both at stream and stream_op + * level */ + struct op_state state; -static void next_send_step(stream_obj *s); -static void next_recv_step(stream_obj *s, enum e_caller caller); + /* OP storage */ + struct op_storage storage; -static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_pollset *pollset) {} + /* Mutex to protect storage */ + gpr_mu mu; +}; +typedef struct stream_obj stream_obj; -static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx, - grpc_transport *gt, grpc_stream *gs, - grpc_pollset_set *pollset_set) {} +static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, + struct op_and_state *oas); -static void enqueue_callbacks(grpc_closure *callback_list[]) { - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - if (callback_list[0]) { - grpc_exec_ctx_sched(&exec_ctx, callback_list[0], GRPC_ERROR_NONE, NULL); - callback_list[0] = NULL; - } - if (callback_list[1]) { - grpc_exec_ctx_sched(&exec_ctx, callback_list[1], GRPC_ERROR_NONE, NULL); - callback_list[1] = NULL; +/* + Utility function to translate enum into string for printing +*/ +static const char *op_result_string(enum e_op_result i) { + switch (i) { + case ACTION_TAKEN_WITH_CALLBACK: + return "ACTION_TAKEN_WITH_CALLBACK"; + case ACTION_TAKEN_NO_CALLBACK: + return "ACTION_TAKEN_NO_CALLBACK"; + case NO_ACTION_POSSIBLE: + return "NO_ACTION_POSSIBLE"; } - grpc_exec_ctx_finish(&exec_ctx); + GPR_UNREACHABLE_CODE(return "UNKNOWN"); } -static void on_canceled(cronet_bidirectional_stream *stream) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_canceled %p", stream); +static const char *op_id_string(enum e_op_id i) { + switch (i) { + case OP_SEND_INITIAL_METADATA: + return "OP_SEND_INITIAL_METADATA"; + case OP_SEND_MESSAGE: + return "OP_SEND_MESSAGE"; + case OP_SEND_TRAILING_METADATA: + return "OP_SEND_TRAILING_METADATA"; + case OP_RECV_MESSAGE: + return "OP_RECV_MESSAGE"; + case OP_RECV_INITIAL_METADATA: + return "OP_RECV_INITIAL_METADATA"; + case OP_RECV_TRAILING_METADATA: + return "OP_RECV_TRAILING_METADATA"; + case OP_CANCEL_ERROR: + return "OP_CANCEL_ERROR"; + case OP_ON_COMPLETE: + return "OP_ON_COMPLETE"; + case OP_FAILED: + return "OP_FAILED"; + case OP_SUCCEEDED: + return "OP_SUCCEEDED"; + case OP_CANCELED: + return "OP_CANCELED"; + case OP_RECV_MESSAGE_AND_ON_COMPLETE: + return "OP_RECV_MESSAGE_AND_ON_COMPLETE"; + case OP_READ_REQ_MADE: + return "OP_READ_REQ_MADE"; + case OP_NUM_OPS: + return "OP_NUM_OPS"; } + return "UNKNOWN"; } -static void on_failed(cronet_bidirectional_stream *stream, int net_error) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_failed %p, error = %d", stream, net_error); - } +/* + Add a new stream op to op storage. +*/ +static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) { + struct op_storage *storage = &s->storage; + /* add new op at the beginning of the linked list. The memory is freed + in remove_from_storage */ + struct op_and_state *new_op = gpr_malloc(sizeof(struct op_and_state)); + memcpy(&new_op->op, op, sizeof(grpc_transport_stream_op)); + memset(&new_op->state, 0, sizeof(new_op->state)); + new_op->s = s; + new_op->done = false; + gpr_mu_lock(&s->mu); + new_op->next = storage->head; + storage->head = new_op; + storage->num_pending_ops++; + CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op, + storage->num_pending_ops); + gpr_mu_unlock(&s->mu); } -static void on_succeeded(cronet_bidirectional_stream *stream) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "on_succeeded %p", stream); +/* + Traverse the linked list and delete op and free memory +*/ +static void remove_from_storage(struct stream_obj *s, + struct op_and_state *oas) { + struct op_and_state *curr; + if (s->storage.head == NULL || oas == NULL) { + return; } -} - -static void on_response_trailers_received( - cronet_bidirectional_stream *stream, - const cronet_bidirectional_stream_header_array *trailers) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_response_trailers_received"); + if (s->storage.head == oas) { + s->storage.head = oas->next; + gpr_free(oas); + s->storage.num_pending_ops--; + CRONET_LOG(GPR_DEBUG, "Freed %p. Now %d in the queue", oas, + s->storage.num_pending_ops); + } else { + for (curr = s->storage.head; curr != NULL; curr = curr->next) { + if (curr->next == oas) { + curr->next = oas->next; + s->storage.num_pending_ops--; + CRONET_LOG(GPR_DEBUG, "Freed %p. Now %d in the queue", oas, + s->storage.num_pending_ops); + gpr_free(oas); + break; + } else if (curr->next == NULL) { + CRONET_LOG(GPR_ERROR, "Reached end of LL and did not find op to free"); + } + } } - stream_obj *s = (stream_obj *)stream->annotation; +} - memset(&s->imb, 0, sizeof(s->imb)); - grpc_chttp2_incoming_metadata_buffer_init(&s->imb); - unsigned int i = 0; - for (i = 0; i < trailers->count; i++) { - grpc_chttp2_incoming_metadata_buffer_add( - &s->imb, grpc_mdelem_from_metadata_strings( - grpc_mdstr_from_string(trailers->headers[i].key), - grpc_mdstr_from_string(trailers->headers[i].value))); +/* + Cycle through ops and try to take next action. Break when either + an action with callback is taken, or no action is possible. + This can be executed from the Cronet network thread via cronet callback + or on the application supplied thread via the perform_stream_op function. +*/ +static void execute_from_storage(stream_obj *s) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_mu_lock(&s->mu); + for (struct op_and_state *curr = s->storage.head; curr != NULL;) { + CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done); + GPR_ASSERT(curr->done == 0); + enum e_op_result result = execute_stream_op(&exec_ctx, curr); + CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr, + op_result_string(result)); + /* if this op is done, then remove it and free memory */ + if (curr->done) { + struct op_and_state *next = curr->next; + remove_from_storage(s, curr); + curr = next; + } + /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */ + if (result == NO_ACTION_POSSIBLE) { + curr = curr->next; + } else if (result == ACTION_TAKEN_WITH_CALLBACK) { + break; + } } - s->response_trailers_received = true; - next_recv_step(s, ON_RESPONSE_TRAILERS_RECEIVED); + gpr_mu_unlock(&s->mu); + grpc_exec_ctx_finish(&exec_ctx); } -static void on_write_completed(cronet_bidirectional_stream *stream, - const char *data) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: on_write_completed"); - } +/* + Cronet callback +*/ +static void on_failed(cronet_bidirectional_stream *stream, int net_error) { + CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error); stream_obj *s = (stream_obj *)stream->annotation; - enqueue_callbacks(s->callback_list[CB_SEND_MESSAGE]); - s->cronet_send_state = CRONET_WRITE_COMPLETED; - next_send_step(s); + cronet_bidirectional_stream_destroy(s->cbs); + s->state.state_callback_received[OP_FAILED] = true; + s->cbs = NULL; + if (s->header_array.headers) { + gpr_free(s->header_array.headers); + s->header_array.headers = NULL; + } + if (s->state.ws.write_buffer) { + gpr_free(s->state.ws.write_buffer); + s->state.ws.write_buffer = NULL; + } + execute_from_storage(s); } -static void process_recv_message(stream_obj *s, const uint8_t *recv_data) { - gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->total_read_bytes); - uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); - if (s->total_read_bytes > 0) { - // Only copy if there is non-zero number of bytes - memcpy(dst_p, recv_data, (size_t)s->total_read_bytes); - gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice); +/* + Cronet callback +*/ +static void on_canceled(cronet_bidirectional_stream *stream) { + CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream); + stream_obj *s = (stream_obj *)stream->annotation; + cronet_bidirectional_stream_destroy(s->cbs); + s->state.state_callback_received[OP_CANCELED] = true; + s->cbs = NULL; + if (s->header_array.headers) { + gpr_free(s->header_array.headers); + s->header_array.headers = NULL; } - grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0); - *s->recv_message = (grpc_byte_buffer *)&s->sbs; + if (s->state.ws.write_buffer) { + gpr_free(s->state.ws.write_buffer); + s->state.ws.write_buffer = NULL; + } + execute_from_storage(s); } -static int parse_grpc_header(const uint8_t *data) { - const uint8_t *p = data + 1; - int length = 0; - length |= ((uint8_t)*p++) << 24; - length |= ((uint8_t)*p++) << 16; - length |= ((uint8_t)*p++) << 8; - length |= ((uint8_t)*p++); - return length; +/* + Cronet callback +*/ +static void on_succeeded(cronet_bidirectional_stream *stream) { + CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream); + stream_obj *s = (stream_obj *)stream->annotation; + cronet_bidirectional_stream_destroy(s->cbs); + s->state.state_callback_received[OP_SUCCEEDED] = true; + s->cbs = NULL; + execute_from_storage(s); } -static void on_read_completed(cronet_bidirectional_stream *stream, char *data, - int count) { +/* + Cronet callback +*/ +static void on_request_headers_sent(cronet_bidirectional_stream *stream) { + CRONET_LOG(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream); stream_obj *s = (stream_obj *)stream->annotation; - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_read_completed count=%d, total=%d, remaining=%d", - count, s->total_read_bytes, s->remaining_read_bytes); - } - if (count > 0) { - GPR_ASSERT(s->recv_message); - s->remaining_read_bytes -= count; - next_recv_step(s, ON_READ_COMPLETE); - } else { - s->read_closed = true; - next_recv_step(s, ON_READ_COMPLETE); + s->state.state_op_done[OP_SEND_INITIAL_METADATA] = true; + s->state.state_callback_received[OP_SEND_INITIAL_METADATA] = true; + /* Free the memory allocated for headers */ + if (s->header_array.headers) { + gpr_free(s->header_array.headers); + s->header_array.headers = NULL; } + execute_from_storage(s); } +/* + Cronet callback +*/ static void on_response_headers_received( cronet_bidirectional_stream *stream, const cronet_bidirectional_stream_header_array *headers, const char *negotiated_protocol) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: on_response_headers_received"); - } + CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream, + headers, negotiated_protocol); stream_obj *s = (stream_obj *)stream->annotation; - enqueue_callbacks(s->callback_list[CB_RECV_INITIAL_METADATA]); - s->response_headers_received = true; - next_recv_step(s, ON_RESPONSE_HEADERS_RECEIVED); -} - -static void on_request_headers_sent(cronet_bidirectional_stream *stream) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: on_request_headers_sent"); + memset(&s->state.rs.initial_metadata, 0, + sizeof(s->state.rs.initial_metadata)); + grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata); + for (size_t i = 0; i < headers->count; i++) { + grpc_chttp2_incoming_metadata_buffer_add( + &s->state.rs.initial_metadata, + grpc_mdelem_from_metadata_strings( + grpc_mdstr_from_string(headers->headers[i].key), + grpc_mdstr_from_string(headers->headers[i].value))); } - stream_obj *s = (stream_obj *)stream->annotation; - enqueue_callbacks(s->callback_list[CB_SEND_INITIAL_METADATA]); - s->cronet_send_state = CRONET_SEND_HEADER; - next_send_step(s); + s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true; + execute_from_storage(s); } -// Callback function pointers (invoked by cronet in response to events) -static cronet_bidirectional_stream_callback callbacks = { - on_request_headers_sent, - on_response_headers_received, - on_read_completed, - on_write_completed, - on_response_trailers_received, - on_succeeded, - on_failed, - on_canceled}; - -static void invoke_closing_callback(stream_obj *s) { - grpc_chttp2_incoming_metadata_buffer_publish(&s->imb, - s->recv_trailing_metadata); - if (s->callback_list[CB_RECV_TRAILING_METADATA]) { - enqueue_callbacks(s->callback_list[CB_RECV_TRAILING_METADATA]); +/* + Cronet callback +*/ +static void on_write_completed(cronet_bidirectional_stream *stream, + const char *data) { + stream_obj *s = (stream_obj *)stream->annotation; + CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data); + if (s->state.ws.write_buffer) { + gpr_free(s->state.ws.write_buffer); + s->state.ws.write_buffer = NULL; } + s->state.state_callback_received[OP_SEND_MESSAGE] = true; + execute_from_storage(s); } -static void set_recv_state(stream_obj *s, enum recv_state state) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "next_state = %s", recv_state_name[state]); +/* + Cronet callback +*/ +static void on_read_completed(cronet_bidirectional_stream *stream, char *data, + int count) { + stream_obj *s = (stream_obj *)stream->annotation; + CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data, + count); + s->state.state_callback_received[OP_RECV_MESSAGE] = true; + if (count > 0) { + s->state.rs.received_bytes += count; + s->state.rs.remaining_bytes -= count; + if (s->state.rs.remaining_bytes > 0) { + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs); + s->state.state_op_done[OP_READ_REQ_MADE] = true; + cronet_bidirectional_stream_read( + s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes, + s->state.rs.remaining_bytes); + } else { + execute_from_storage(s); + } + } else { + s->state.rs.read_stream_closed = true; + execute_from_storage(s); } - s->cronet_recv_state = state; } -// This is invoked from perform_stream_op, and all on_xxxx callbacks. -static void next_recv_step(stream_obj *s, enum e_caller caller) { - gpr_mu_lock(&s->recv_mu); - switch (s->cronet_recv_state) { - case CRONET_RECV_IDLE: - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_IDLE"); - } - if (caller == PERFORM_STREAM_OP || - caller == ON_RESPONSE_HEADERS_RECEIVED) { - if (s->read_closed && s->response_trailers_received) { - invoke_closing_callback(s); - set_recv_state(s, CRONET_RECV_CLOSED); - } else if (s->response_headers_received == true && - s->read_requested == true) { - set_recv_state(s, CRONET_RECV_READ_LENGTH); - s->total_read_bytes = s->remaining_read_bytes = - GRPC_HEADER_SIZE_IN_BYTES; - GPR_ASSERT(s->read_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); - } - cronet_bidirectional_stream_read(s->cbs, s->read_buffer, - s->remaining_read_bytes); - } - } - break; - case CRONET_RECV_READ_LENGTH: - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_LENGTH"); - } - if (caller == ON_READ_COMPLETE) { - if (s->read_closed) { - invoke_closing_callback(s); - enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]); - set_recv_state(s, CRONET_RECV_CLOSED); - } else { - GPR_ASSERT(s->remaining_read_bytes == 0); - set_recv_state(s, CRONET_RECV_READ_DATA); - s->total_read_bytes = s->remaining_read_bytes = - parse_grpc_header((const uint8_t *)s->read_buffer); - s->read_buffer = - gpr_realloc(s->read_buffer, (uint32_t)s->remaining_read_bytes); - GPR_ASSERT(s->read_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); - } - if (s->remaining_read_bytes > 0) { - cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer, - s->remaining_read_bytes); - } else { - // Calling the closing callback directly since this is a 0 byte read - // for an empty message. - process_recv_message(s, NULL); - enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]); - invoke_closing_callback(s); - set_recv_state(s, CRONET_RECV_CLOSED); - } - } - } - break; - case CRONET_RECV_READ_DATA: - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_DATA"); - } - if (caller == ON_READ_COMPLETE) { - if (s->remaining_read_bytes > 0) { - int offset = s->total_read_bytes - s->remaining_read_bytes; - GPR_ASSERT(s->read_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()"); - } - cronet_bidirectional_stream_read( - s->cbs, (char *)s->read_buffer + offset, s->remaining_read_bytes); - } else { - gpr_slice_buffer_init(&s->read_slice_buffer); - uint8_t *p = (uint8_t *)s->read_buffer; - process_recv_message(s, p); - set_recv_state(s, CRONET_RECV_IDLE); - enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]); - } - } - break; - case CRONET_RECV_CLOSED: - break; - default: - GPR_ASSERT(0); // Should not reach here - break; +/* + Cronet callback +*/ +static void on_response_trailers_received( + cronet_bidirectional_stream *stream, + const cronet_bidirectional_stream_header_array *trailers) { + CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream, + trailers); + stream_obj *s = (stream_obj *)stream->annotation; + memset(&s->state.rs.trailing_metadata, 0, + sizeof(s->state.rs.trailing_metadata)); + s->state.rs.trailing_metadata_valid = false; + grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata); + for (size_t i = 0; i < trailers->count; i++) { + CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key, + trailers->headers[i].value); + grpc_chttp2_incoming_metadata_buffer_add( + &s->state.rs.trailing_metadata, + grpc_mdelem_from_metadata_strings( + grpc_mdstr_from_string(trailers->headers[i].key), + grpc_mdstr_from_string(trailers->headers[i].value))); + s->state.rs.trailing_metadata_valid = true; } - gpr_mu_unlock(&s->recv_mu); + s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true; + execute_from_storage(s); } -// This function takes the data from s->write_slice_buffer and assembles into -// a contiguous byte stream with 5 byte gRPC header prepended. -static void create_grpc_frame(stream_obj *s) { - gpr_slice slice = gpr_slice_buffer_take_first(&s->write_slice_buffer); - uint8_t *raw_data = GPR_SLICE_START_PTR(slice); +/* + Utility function that takes the data from s->write_slice_buffer and assembles + into a contiguous byte stream with 5 byte gRPC header prepended. +*/ +static void create_grpc_frame(gpr_slice_buffer *write_slice_buffer, + char **pp_write_buffer, + size_t *p_write_buffer_size) { + gpr_slice slice = gpr_slice_buffer_take_first(write_slice_buffer); size_t length = GPR_SLICE_LENGTH(slice); - s->write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES; - s->write_buffer = gpr_realloc(s->write_buffer, s->write_buffer_size); - uint8_t *p = (uint8_t *)s->write_buffer; - // Append 5 byte header + *p_write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES; + /* This is freed in the on_write_completed callback */ + char *write_buffer = gpr_malloc(length + GRPC_HEADER_SIZE_IN_BYTES); + *pp_write_buffer = write_buffer; + uint8_t *p = (uint8_t *)write_buffer; + /* Append 5 byte header */ *p++ = 0; *p++ = (uint8_t)(length >> 24); *p++ = (uint8_t)(length >> 16); *p++ = (uint8_t)(length >> 8); *p++ = (uint8_t)(length); - // append actual data - memcpy(p, raw_data, length); + /* append actual data */ + memcpy(p, GPR_SLICE_START_PTR(slice), length); } -static void do_write(stream_obj *s) { - gpr_slice_buffer *sb = &s->write_slice_buffer; - GPR_ASSERT(sb->count <= 1); - if (sb->count > 0) { - create_grpc_frame(s); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write"); - } - cronet_bidirectional_stream_write(s->cbs, s->write_buffer, - (int)s->write_buffer_size, false); - } -} - -// -static void next_send_step(stream_obj *s) { - switch (s->cronet_send_state) { - case CRONET_SEND_IDLE: - GPR_ASSERT( - s->cbs); // cronet_bidirectional_stream is not initialized yet. - s->cronet_send_state = CRONET_REQ_STARTED; - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start to %s", s->url); - } - cronet_bidirectional_stream_start(s->cbs, s->url, 0, "POST", - &s->header_array, false); - // we no longer need the memory that was allocated earlier. - gpr_free(s->header_array.headers); - break; - case CRONET_SEND_HEADER: - do_write(s); - s->cronet_send_state = CRONET_WRITE; - break; - case CRONET_WRITE_COMPLETED: - do_write(s); - break; - default: - GPR_ASSERT(0); - break; - } -} - -static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head, - const char *host, - stream_obj *s) { +/* + Convert metadata in a format that Cronet can consume +*/ +static void convert_metadata_to_cronet_headers( + grpc_linked_mdelem *head, const char *host, char **pp_url, + cronet_bidirectional_stream_header **pp_headers, size_t *p_num_headers) { grpc_linked_mdelem *curr = head; - // Walk the linked list and get number of header fields - uint32_t num_headers_available = 0; + /* Walk the linked list and get number of header fields */ + size_t num_headers_available = 0; while (curr != NULL) { curr = curr->next; num_headers_available++; } - // Allocate enough memory - s->headers = (cronet_bidirectional_stream_header *)gpr_malloc( - sizeof(cronet_bidirectional_stream_header) * num_headers_available); - - // Walk the linked list again, this time copying the header fields. - // s->num_headers - // can be less than num_headers_available, as some headers are not used for - // cronet + /* Allocate enough memory. It is freed in the on_request_headers_sent callback + */ + cronet_bidirectional_stream_header *headers = + (cronet_bidirectional_stream_header *)gpr_malloc( + sizeof(cronet_bidirectional_stream_header) * num_headers_available); + *pp_headers = headers; + + /* Walk the linked list again, this time copying the header fields. + s->num_headers can be less than num_headers_available, as some headers + are not used for cronet. + TODO (makdharma): Eliminate need to traverse the LL second time for perf. + */ curr = head; - s->num_headers = 0; - while (s->num_headers < num_headers_available) { + size_t num_headers = 0; + while (num_headers < num_headers_available) { grpc_mdelem *mdelem = curr->md; curr = curr->next; const char *key = grpc_mdstr_as_c_string(mdelem->key); const char *value = grpc_mdstr_as_c_string(mdelem->value); - if (strcmp(key, ":scheme") == 0 || strcmp(key, ":method") == 0 || - strcmp(key, ":authority") == 0) { - // Cronet populates these fields on its own. + if (mdelem->key == GRPC_MDSTR_METHOD || mdelem->key == GRPC_MDSTR_SCHEME || + mdelem->key == GRPC_MDSTR_AUTHORITY) { + /* Cronet populates these fields on its own */ continue; } - if (strcmp(key, ":path") == 0) { - // Create URL by appending :path value to the hostname - gpr_asprintf(&s->url, "https://%s%s", host, value); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "extracted URL = %s", s->url); - } + if (mdelem->key == GRPC_MDSTR_PATH) { + /* Create URL by appending :path value to the hostname */ + gpr_asprintf(pp_url, "https://%s%s", host, value); continue; } - s->headers[s->num_headers].key = key; - s->headers[s->num_headers].value = value; - s->num_headers++; + CRONET_LOG(GPR_DEBUG, "header %s = %s", key, value); + headers[num_headers].key = key; + headers[num_headers].value = value; + num_headers++; if (curr == NULL) { break; } } + *p_num_headers = (size_t)num_headers; } -static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, grpc_transport_stream_op *op) { - grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; - GPR_ASSERT(ct->engine); - stream_obj *s = (stream_obj *)gs; - if (op->recv_trailing_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - recv_trailing_metadata: on_complete=%p", - op->on_complete); +static int parse_grpc_header(const uint8_t *data) { + const uint8_t *p = data + 1; + int length = 0; + length |= ((uint8_t)*p++) << 24; + length |= ((uint8_t)*p++) << 16; + length |= ((uint8_t)*p++) << 8; + length |= ((uint8_t)*p++); + return length; +} + +/* + Op Execution: Decide if one of the actions contained in the stream op can be + executed. This is the heart of the state machine. +*/ +static bool op_can_be_run(grpc_transport_stream_op *curr_op, + struct op_state *stream_state, + struct op_state *op_state, enum e_op_id op_id) { + bool result = true; + /* When call is canceled, every op can be run, except under following + conditions + */ + bool is_canceled_of_failed = stream_state->state_op_done[OP_CANCEL_ERROR] || + stream_state->state_callback_received[OP_FAILED]; + if (is_canceled_of_failed) { + if (op_id == OP_SEND_INITIAL_METADATA) result = false; + if (op_id == OP_SEND_MESSAGE) result = false; + if (op_id == OP_SEND_TRAILING_METADATA) result = false; + if (op_id == OP_CANCEL_ERROR) result = false; + /* already executed */ + if (op_id == OP_RECV_INITIAL_METADATA && + stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) + result = false; + if (op_id == OP_RECV_MESSAGE && + stream_state->state_op_done[OP_RECV_MESSAGE]) + result = false; + if (op_id == OP_RECV_TRAILING_METADATA && + stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) + result = false; + } else if (op_id == OP_SEND_INITIAL_METADATA) { + /* already executed */ + if (stream_state->state_op_done[OP_SEND_INITIAL_METADATA]) result = false; + } else if (op_id == OP_RECV_INITIAL_METADATA) { + /* already executed */ + if (stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false; + /* we haven't sent headers yet. */ + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; + /* we haven't received headers yet. */ + else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) + result = false; + } else if (op_id == OP_SEND_MESSAGE) { + /* already executed (note we're checking op specific state, not stream + state) */ + if (op_state->state_op_done[OP_SEND_MESSAGE]) result = false; + /* we haven't sent headers yet. */ + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; + } else if (op_id == OP_RECV_MESSAGE) { + /* already executed */ + if (op_state->state_op_done[OP_RECV_MESSAGE]) result = false; + /* we haven't received headers yet. */ + else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA]) + result = false; + } else if (op_id == OP_RECV_TRAILING_METADATA) { + /* already executed */ + if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false; + /* we have asked for but haven't received message yet. */ + else if (stream_state->state_op_done[OP_READ_REQ_MADE] && + !stream_state->state_op_done[OP_RECV_MESSAGE]) + result = false; + /* we haven't received trailers yet. */ + else if (!stream_state->state_callback_received[OP_RECV_TRAILING_METADATA]) + result = false; + /* we haven't received on_succeeded yet. */ + else if (!stream_state->state_callback_received[OP_SUCCEEDED]) + result = false; + } else if (op_id == OP_SEND_TRAILING_METADATA) { + /* already executed */ + if (stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false; + /* we haven't sent initial metadata yet */ + else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) + result = false; + /* we haven't sent message yet */ + else if (curr_op->send_message && + !stream_state->state_op_done[OP_SEND_MESSAGE]) + result = false; + /* we haven't got on_write_completed for the send yet */ + else if (stream_state->state_op_done[OP_SEND_MESSAGE] && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) + result = false; + } else if (op_id == OP_CANCEL_ERROR) { + /* already executed */ + if (stream_state->state_op_done[OP_CANCEL_ERROR]) result = false; + } else if (op_id == OP_ON_COMPLETE) { + /* already executed (note we're checking op specific state, not stream + state) */ + if (op_state->state_op_done[OP_ON_COMPLETE]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; } - s->recv_trailing_metadata = op->recv_trailing_metadata; - GPR_ASSERT(!s->callback_list[CB_RECV_TRAILING_METADATA][0]); - s->callback_list[CB_RECV_TRAILING_METADATA][0] = op->on_complete; - } - if (op->recv_message) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - recv_message: on_complete=%p", - op->on_complete); + /* Check if every op that was asked for is done. */ + else if (curr_op->send_initial_metadata && + !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } else if (curr_op->send_message && + !op_state->state_op_done[OP_SEND_MESSAGE]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } else if (curr_op->send_message && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } else if (curr_op->send_trailing_metadata && + !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } else if (curr_op->recv_initial_metadata && + !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } else if (curr_op->recv_message && + !stream_state->state_op_done[OP_RECV_MESSAGE]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } else if (curr_op->recv_trailing_metadata) { + /* We aren't done with trailing metadata yet */ + if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } + /* We've asked for actual message in an earlier op, and it hasn't been + delivered yet. */ + else if (stream_state->state_op_done[OP_READ_REQ_MADE]) { + /* If this op is not the one asking for read, (which means some earlier + op has asked), and the read hasn't been delivered. */ + if (!curr_op->recv_message && + !stream_state->state_callback_received[OP_SUCCEEDED]) { + CRONET_LOG(GPR_DEBUG, "Because"); + result = false; + } + } } - s->recv_message = (grpc_byte_buffer **)op->recv_message; - GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][0]); - GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][1]); - s->callback_list[CB_RECV_MESSAGE][0] = op->recv_message_ready; - s->callback_list[CB_RECV_MESSAGE][1] = op->on_complete; - s->read_requested = true; - next_recv_step(s, PERFORM_STREAM_OP); + /* We should see at least one on_write_completed for the trailers that we + sent */ + else if (curr_op->send_trailing_metadata && + !stream_state->state_callback_received[OP_SEND_MESSAGE]) + result = false; } - if (op->recv_initial_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - recv_initial_metadata:=%p", - op->on_complete); + CRONET_LOG(GPR_DEBUG, "op_can_be_run %s : %s", op_id_string(op_id), + result ? "YES" : "NO"); + return result; +} + +/* + TODO (makdharma): Break down this function in smaller chunks for readability. +*/ +static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx, + struct op_and_state *oas) { + grpc_transport_stream_op *stream_op = &oas->op; + struct stream_obj *s = oas->s; + struct op_state *stream_state = &s->state; + enum e_op_result result = NO_ACTION_POSSIBLE; + if (stream_op->send_initial_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_SEND_INITIAL_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_INITIAL_METADATA", oas); + /* This OP is the beginning. Reset various states */ + memset(&s->header_array, 0, sizeof(s->header_array)); + memset(&stream_state->rs, 0, sizeof(stream_state->rs)); + memset(&stream_state->ws, 0, sizeof(stream_state->ws)); + memset(stream_state->state_op_done, 0, sizeof(stream_state->state_op_done)); + memset(stream_state->state_callback_received, 0, + sizeof(stream_state->state_callback_received)); + /* Start new cronet stream. It is destroyed in on_succeeded, on_canceled, + * on_failed */ + GPR_ASSERT(s->cbs == NULL); + s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs, + &cronet_callbacks); + CRONET_LOG(GPR_DEBUG, "%p = cronet_bidirectional_stream_create()", s->cbs); + char *url; + s->header_array.headers = NULL; + convert_metadata_to_cronet_headers( + stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url, + &s->header_array.headers, &s->header_array.count); + s->header_array.capacity = s->header_array.count; + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_start(%p, %s)", s->cbs, + url); + cronet_bidirectional_stream_start(s->cbs, url, 0, "POST", &s->header_array, + false); + stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_op->recv_initial_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_RECV_INITIAL_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_INITIAL_METADATA", oas); + if (!stream_state->state_op_done[OP_CANCEL_ERROR]) { + grpc_chttp2_incoming_metadata_buffer_publish( + &oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata); + grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready, + GRPC_ERROR_NONE, NULL); + } else { + grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready, + GRPC_ERROR_CANCELLED, NULL); } - s->recv_initial_metadata = op->recv_initial_metadata; - GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][0]); - GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][1]); - s->callback_list[CB_RECV_INITIAL_METADATA][0] = - op->recv_initial_metadata_ready; - s->callback_list[CB_RECV_INITIAL_METADATA][1] = op->on_complete; - } - if (op->send_initial_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - send_initial_metadata: on_complete=%p", - op->on_complete); + stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true; + result = ACTION_TAKEN_NO_CALLBACK; + } else if (stream_op->send_message && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_SEND_MESSAGE)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_MESSAGE", oas); + gpr_slice_buffer write_slice_buffer; + gpr_slice slice; + gpr_slice_buffer_init(&write_slice_buffer); + grpc_byte_stream_next(NULL, stream_op->send_message, &slice, + stream_op->send_message->length, NULL); + /* Check that compression flag is OFF. We don't support compression yet. */ + if (stream_op->send_message->flags != 0) { + gpr_log(GPR_ERROR, "Compression is not supported"); + GPR_ASSERT(stream_op->send_message->flags == 0); } - s->num_headers = 0; - convert_metadata_to_cronet_headers(op->send_initial_metadata->list.head, - ct->host, s); - s->header_array.count = s->num_headers; - s->header_array.capacity = s->num_headers; - s->header_array.headers = s->headers; - GPR_ASSERT(!s->callback_list[CB_SEND_INITIAL_METADATA][0]); - s->callback_list[CB_SEND_INITIAL_METADATA][0] = op->on_complete; - } - if (op->send_message) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "perform_stream_op - send_message: on_complete=%p", - op->on_complete); + gpr_slice_buffer_add(&write_slice_buffer, slice); + if (write_slice_buffer.count != 1) { + /* Empty request not handled yet */ + gpr_log(GPR_ERROR, "Empty request is not supported"); + GPR_ASSERT(write_slice_buffer.count == 1); + } + if (write_slice_buffer.count > 0) { + size_t write_buffer_size; + create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer, + &write_buffer_size); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, %p)", + s->cbs, stream_state->ws.write_buffer); + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; + cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer, + (int)write_buffer_size, false); + result = ACTION_TAKEN_WITH_CALLBACK; } - grpc_byte_stream_next(exec_ctx, op->send_message, &s->slice, - op->send_message->length, NULL); - // Check that compression flag is not ON. We don't support compression yet. - // TODO (makdharma): add compression support - GPR_ASSERT(op->send_message->flags == 0); - gpr_slice_buffer_add(&s->write_slice_buffer, s->slice); - if (s->cbs == NULL) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create"); + stream_state->state_op_done[OP_SEND_MESSAGE] = true; + oas->state.state_op_done[OP_SEND_MESSAGE] = true; + } else if (stream_op->recv_message && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_RECV_MESSAGE)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_MESSAGE", oas); + if (stream_state->state_op_done[OP_CANCEL_ERROR]) { + grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_CANCELLED, NULL); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + } else if (stream_state->rs.read_stream_closed == true) { + /* No more data will be received */ + CRONET_LOG(GPR_DEBUG, "read stream closed"); + grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_NONE, NULL); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; + } else if (stream_state->rs.length_field_received == false) { + if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES && + stream_state->rs.remaining_bytes == 0) { + /* Start a read operation for data */ + stream_state->rs.length_field_received = true; + stream_state->rs.length_field = stream_state->rs.remaining_bytes = + parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer); + CRONET_LOG(GPR_DEBUG, "length field = %d", + stream_state->rs.length_field); + if (stream_state->rs.length_field > 0) { + stream_state->rs.read_buffer = + gpr_malloc((size_t)stream_state->rs.length_field); + GPR_ASSERT(stream_state->rs.read_buffer); + stream_state->rs.remaining_bytes = stream_state->rs.length_field; + stream_state->rs.received_bytes = 0; + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs); + stream_state->state_op_done[OP_READ_REQ_MADE] = + true; /* Indicates that at least one read request has been made */ + cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, + stream_state->rs.remaining_bytes); + result = ACTION_TAKEN_WITH_CALLBACK; + } else { + stream_state->rs.remaining_bytes = 0; + CRONET_LOG(GPR_DEBUG, "read operation complete. Empty response."); + gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); + grpc_slice_buffer_stream_init(&stream_state->rs.sbs, + &stream_state->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)stream_op->recv_message) = + (grpc_byte_buffer *)&stream_state->rs.sbs; + grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_NONE, NULL); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; + result = ACTION_TAKEN_NO_CALLBACK; + } + } else if (stream_state->rs.remaining_bytes == 0) { + /* Start a read operation for first 5 bytes (GRPC header) */ + stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes; + stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES; + stream_state->rs.received_bytes = 0; + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs); + stream_state->state_op_done[OP_READ_REQ_MADE] = + true; /* Indicates that at least one read request has been made */ + cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer, + stream_state->rs.remaining_bytes); } - s->cbs = cronet_bidirectional_stream_create(ct->engine, s, &callbacks); - GPR_ASSERT(s->cbs); - s->read_closed = false; - s->response_trailers_received = false; - s->response_headers_received = false; - s->cronet_send_state = CRONET_SEND_IDLE; - s->cronet_recv_state = CRONET_RECV_IDLE; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_state->rs.remaining_bytes == 0) { + CRONET_LOG(GPR_DEBUG, "read operation complete"); + gpr_slice read_data_slice = + gpr_slice_malloc((uint32_t)stream_state->rs.length_field); + uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice); + memcpy(dst_p, stream_state->rs.read_buffer, + (size_t)stream_state->rs.length_field); + gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer); + gpr_slice_buffer_add(&stream_state->rs.read_slice_buffer, + read_data_slice); + grpc_slice_buffer_stream_init(&stream_state->rs.sbs, + &stream_state->rs.read_slice_buffer, 0); + *((grpc_byte_buffer **)stream_op->recv_message) = + (grpc_byte_buffer *)&stream_state->rs.sbs; + grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready, + GRPC_ERROR_NONE, NULL); + stream_state->state_op_done[OP_RECV_MESSAGE] = true; + oas->state.state_op_done[OP_RECV_MESSAGE] = true; + /* Clear read state of the stream, so next read op (if it were to come) + * will work */ + stream_state->rs.received_bytes = stream_state->rs.remaining_bytes = + stream_state->rs.length_field_received = 0; + result = ACTION_TAKEN_NO_CALLBACK; } - GPR_ASSERT(!s->callback_list[CB_SEND_MESSAGE][0]); - s->callback_list[CB_SEND_MESSAGE][0] = op->on_complete; - next_send_step(s); - } - if (op->send_trailing_metadata) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, - "perform_stream_op - send_trailing_metadata: on_complete=%p", - op->on_complete); + } else if (stream_op->recv_trailing_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_RECV_TRAILING_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_RECV_TRAILING_METADATA", oas); + if (oas->s->state.rs.trailing_metadata_valid) { + grpc_chttp2_incoming_metadata_buffer_publish( + &oas->s->state.rs.trailing_metadata, + stream_op->recv_trailing_metadata); + stream_state->rs.trailing_metadata_valid = false; } - GPR_ASSERT(!s->callback_list[CB_SEND_TRAILING_METADATA][0]); - s->callback_list[CB_SEND_TRAILING_METADATA][0] = op->on_complete; + stream_state->state_op_done[OP_RECV_TRAILING_METADATA] = true; + result = ACTION_TAKEN_NO_CALLBACK; + } else if (stream_op->send_trailing_metadata && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_SEND_TRAILING_METADATA)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_TRAILING_METADATA", oas); + CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, 0)", s->cbs); + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; + cronet_bidirectional_stream_write(s->cbs, "", 0, true); + stream_state->state_op_done[OP_SEND_TRAILING_METADATA] = true; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_op->cancel_error && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_CANCEL_ERROR)) { + CRONET_LOG(GPR_DEBUG, "running: %p OP_CANCEL_ERROR", oas); + CRONET_LOG(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs); if (s->cbs) { - // Send an "empty" write to the far end to signal that we're done. - // This will induce the server to send down trailers. - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write"); - } - cronet_bidirectional_stream_write(s->cbs, "abc", 0, true); - } else { - // We never created a stream. This was probably an empty request. - invoke_closing_callback(s); + cronet_bidirectional_stream_cancel(s->cbs); } + stream_state->state_op_done[OP_CANCEL_ERROR] = true; + result = ACTION_TAKEN_WITH_CALLBACK; + } else if (stream_op->on_complete && + op_can_be_run(stream_op, stream_state, &oas->state, + OP_ON_COMPLETE)) { + /* All actions in this stream_op are complete. Call the on_complete callback + */ + CRONET_LOG(GPR_DEBUG, "running: %p OP_ON_COMPLETE", oas); + grpc_exec_ctx_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE, + NULL); + oas->state.state_op_done[OP_ON_COMPLETE] = true; + oas->done = true; + /* reset any send message state, only if this ON_COMPLETE is about a send. + */ + if (stream_op->send_message) { + stream_state->state_callback_received[OP_SEND_MESSAGE] = false; + stream_state->state_op_done[OP_SEND_MESSAGE] = false; + } + result = ACTION_TAKEN_NO_CALLBACK; + /* If this is the on_complete callback being called for a received message - + make a note */ + if (stream_op->recv_message) + stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true; + } else { + result = NO_ACTION_POSSIBLE; } + return result; } +/* + Functions used by upper layers to access transport functionality. +*/ + static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, grpc_stream *gs, grpc_stream_refcount *refcount, const void *server_data) { stream_obj *s = (stream_obj *)gs; - memset(s->callback_list, 0, sizeof(s->callback_list)); + memset(&s->storage, 0, sizeof(s->storage)); + s->storage.head = NULL; + memset(&s->state, 0, sizeof(s->state)); + s->curr_op = NULL; s->cbs = NULL; - gpr_mu_init(&s->recv_mu); - s->read_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES); - s->write_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES); - gpr_slice_buffer_init(&s->write_slice_buffer); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "cronet_transport - init_stream"); - } + memset(&s->header_array, 0, sizeof(s->header_array)); + memset(&s->state.rs, 0, sizeof(s->state.rs)); + memset(&s->state.ws, 0, sizeof(s->state.ws)); + memset(s->state.state_op_done, 0, sizeof(s->state.state_op_done)); + memset(s->state.state_callback_received, 0, + sizeof(s->state.state_callback_received)); + gpr_mu_init(&s->mu); return 0; } -static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, - grpc_stream *gs, void *and_free_memory) { - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "Destroy stream"); - } +static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_pollset *pollset) {} + +static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx, + grpc_transport *gt, grpc_stream *gs, + grpc_pollset_set *pollset_set) {} + +static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, grpc_transport_stream_op *op) { + CRONET_LOG(GPR_DEBUG, "perform_stream_op"); stream_obj *s = (stream_obj *)gs; - s->cbs = NULL; - gpr_free(s->read_buffer); - gpr_free(s->write_buffer); - gpr_free(s->url); - gpr_mu_destroy(&s->recv_mu); - if (and_free_memory) { - gpr_free(and_free_memory); - } + s->curr_gs = gs; + memcpy(&s->curr_ct, gt, sizeof(grpc_cronet_transport)); + add_to_storage(s, op); + execute_from_storage(s); } -static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { - grpc_cronet_transport *ct = (grpc_cronet_transport *)gt; - gpr_free(ct->host); - if (grpc_cronet_trace) { - gpr_log(GPR_DEBUG, "Destroy transport"); - } +static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_stream *gs, void *and_free_memory) {} + +static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {} + +static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *gt) { + return NULL; } +static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt, + grpc_transport_op *op) {} + const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj), "cronet_http", init_stream, set_pollset_do_nothing, set_pollset_set_do_nothing, perform_stream_op, - NULL, + perform_op, destroy_stream, destroy_transport, - NULL}; + get_peer}; diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h index 653d04f4279..aec61ee7c62 100644 --- a/src/core/lib/channel/channel_args.h +++ b/src/core/lib/channel/channel_args.h @@ -37,6 +37,8 @@ #include #include +// Channel args are intentionally immutable, to avoid the need for locking. + /** Copy the arguments in \a src into a new instance */ grpc_channel_args *grpc_channel_args_copy(const grpc_channel_args *src); diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c index 87175d79433..98f304f2da0 100644 --- a/src/core/lib/channel/channel_stack.c +++ b/src/core/lib/channel/channel_stack.c @@ -157,12 +157,13 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, } } -void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - grpc_call_context_element *context, - const void *transport_server_data, - grpc_call_stack *call_stack) { +grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, + int initial_refs, grpc_iomgr_cb_func destroy, + void *destroy_arg, + grpc_call_context_element *context, + const void *transport_server_data, + grpc_call_stack *call_stack) { grpc_channel_element *channel_elems = CHANNEL_ELEMS_FROM_STACK(channel_stack); grpc_call_element_args args; size_t count = channel_stack->count; @@ -178,6 +179,7 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, ROUND_UP_TO_ALIGNMENT_SIZE(count * sizeof(grpc_call_element)); /* init per-filter data */ + grpc_error *first_error = GRPC_ERROR_NONE; for (i = 0; i < count; i++) { args.call_stack = call_stack; args.server_transport_data = transport_server_data; @@ -185,10 +187,19 @@ void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, call_elems[i].filter = channel_elems[i].filter; call_elems[i].channel_data = channel_elems[i].channel_data; call_elems[i].call_data = user_data; - call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); + grpc_error *error = + call_elems[i].filter->init_call_elem(exec_ctx, &call_elems[i], &args); + if (error != GRPC_ERROR_NONE) { + if (first_error == GRPC_ERROR_NONE) { + first_error = error; + } else { + GRPC_ERROR_UNREF(error); + } + } user_data += ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data); } + return first_error; } void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, @@ -217,7 +228,7 @@ void grpc_call_stack_ignore_set_pollset_or_pollset_set( grpc_polling_entity *pollent) {} void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, - const grpc_call_stats *call_stats, + const grpc_call_final_info *final_info, void *and_free_memory) { grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack); size_t count = stack->count; @@ -225,7 +236,7 @@ void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, /* destroy per-filter data */ for (i = 0; i < count; i++) { - elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], call_stats, + elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], final_info, i == count - 1 ? and_free_memory : NULL); } } diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index d72c015b677..6b73cce380f 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -51,6 +51,10 @@ #include "src/core/lib/iomgr/polling_entity.h" #include "src/core/lib/transport/transport.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct grpc_channel_element grpc_channel_element; typedef struct grpc_call_element grpc_call_element; @@ -75,9 +79,14 @@ typedef struct { typedef struct { grpc_transport_stream_stats transport_stream_stats; gpr_timespec latency; /* From call creating to enqueing of received status */ - grpc_status_code final_status; } grpc_call_stats; +/** Information about the call upon completion. */ +typedef struct { + grpc_call_stats stats; + grpc_status_code final_status; +} grpc_call_final_info; + /* Channel filters specify: 1. the amount of memory needed in the channel & call (via the sizeof_XXX members) @@ -110,8 +119,9 @@ typedef struct { on a client; if it is non-NULL, then it points to memory owned by the transport and is on the server. Most filters want to ignore this argument. */ - void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args); + grpc_error *(*init_call_elem)(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args); void (*set_pollset_or_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_polling_entity *pollent); @@ -119,16 +129,17 @@ typedef struct { The filter does not need to do any chaining. The bottom filter of a stack will be passed a non-NULL pointer to \a and_free_memory that should be passed to gpr_free when destruction - is complete. */ + is complete. \a final_info contains data about the completed call, mainly + for reporting purposes. */ void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *and_free_memory); /* sizeof(per channel data) */ size_t sizeof_channel_data; /* Initialize per-channel data. - elem is initialized at the start of the call, and elem->channel_data is - what needs initializing. + elem is initialized at the creating of the channel, and elem->channel_data + is what needs initializing. is_first, is_last designate this elements position in the stack, and are useful for asserting correct configuration by upper layer code. The filter does not need to do any chaining */ @@ -209,12 +220,13 @@ void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx, /* Initialize a call stack given a channel stack. transport_server_data is expected to be NULL on a client, or an opaque transport owned pointer on the server. */ -void grpc_call_stack_init(grpc_exec_ctx *exec_ctx, - grpc_channel_stack *channel_stack, int initial_refs, - grpc_iomgr_cb_func destroy, void *destroy_arg, - grpc_call_context_element *context, - const void *transport_server_data, - grpc_call_stack *call_stack); +grpc_error *grpc_call_stack_init(grpc_exec_ctx *exec_ctx, + grpc_channel_stack *channel_stack, + int initial_refs, grpc_iomgr_cb_func destroy, + void *destroy_arg, + grpc_call_context_element *context, + const void *transport_server_data, + grpc_call_stack *call_stack); /* Set a pollset or a pollset_set for a call stack: must occur before the first * op is started */ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, @@ -243,7 +255,7 @@ void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, /* Destroy a call stack */ void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack, - const grpc_call_stats *call_stats, + const grpc_call_final_info *final_info, void *and_free_memory); /* Ignore set pollset{_set} - used by filters if they don't care about pollsets @@ -283,4 +295,8 @@ extern int grpc_trace_channel; #define GRPC_CALL_LOG_OP(sev, elem, op) \ if (grpc_trace_channel) grpc_call_log_op(sev, elem, op) +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_H */ diff --git a/src/core/lib/channel/channel_stack_builder.h b/src/core/lib/channel/channel_stack_builder.h index 0e6bfd9aa69..4a00f7bfdbd 100644 --- a/src/core/lib/channel/channel_stack_builder.h +++ b/src/core/lib/channel/channel_stack_builder.h @@ -39,6 +39,10 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" +#ifdef __cplusplus +extern "C" { +#endif + /// grpc_channel_stack_builder offers a programmatic interface to selected /// and order channel filters typedef struct grpc_channel_stack_builder grpc_channel_stack_builder; @@ -158,4 +162,8 @@ void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder); extern int grpc_trace_channel_stack_builder; +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H */ diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c index 32ebe53ee64..134180e619d 100644 --- a/src/core/lib/channel/compress_filter.c +++ b/src/core/lib/channel/compress_filter.c @@ -256,8 +256,9 @@ static void compress_start_transport_stream_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; @@ -266,11 +267,14 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, calld->has_compression_algorithm = 0; grpc_closure_init(&calld->got_slice, got_slice, elem); grpc_closure_init(&calld->send_done, send_done, elem); + + return GRPC_ERROR_NONE; } /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) { + const grpc_call_final_info *final_info, + void *ignored) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; gpr_slice_buffer_destroy(&calld->slices); diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c index 0a7d27a1dc5..918379c8457 100644 --- a/src/core/lib/channel/connected_channel.c +++ b/src/core/lib/channel/connected_channel.c @@ -81,16 +81,16 @@ static void con_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; - int r; - - r = grpc_transport_init_stream( + int r = grpc_transport_init_stream( exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld), &args->call_stack->refcount, args->server_transport_data); - GPR_ASSERT(r == 0); + return r == 0 ? GRPC_ERROR_NONE + : GRPC_ERROR_CREATE("transport stream initialization failed"); } static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, @@ -104,7 +104,7 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *and_free_memory) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h index c50e84279d4..071c5f695c5 100644 --- a/src/core/lib/channel/context.h +++ b/src/core/lib/channel/context.h @@ -34,10 +34,19 @@ #ifndef GRPC_CORE_LIB_CHANNEL_CONTEXT_H #define GRPC_CORE_LIB_CHANNEL_CONTEXT_H -/* Call object context pointers */ +/// Call object context pointers. + +/// Call context is represented as an array of \a grpc_call_context_elements. +/// This enum represents the indexes into the array, where each index +/// contains a different type of value. typedef enum { + /// Value is either a \a grpc_client_security_context or a + /// \a grpc_server_security_context. GRPC_CONTEXT_SECURITY = 0, + + /// Value is a \a census_context. GRPC_CONTEXT_TRACING, + GRPC_CONTEXT_COUNT } grpc_context_index; diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c new file mode 100644 index 00000000000..c0979f5e806 --- /dev/null +++ b/src/core/lib/channel/handshaker.c @@ -0,0 +1,203 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/channel/handshaker.h" + +// +// grpc_handshaker +// + +void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, + grpc_handshaker* handshaker) { + handshaker->vtable = vtable; +} + +void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker) { + handshaker->vtable->destroy(exec_ctx, handshaker); +} + +void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker) { + handshaker->vtable->shutdown(exec_ctx, handshaker); +} + +void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker, + grpc_endpoint* endpoint, + grpc_channel_args* args, + gpr_slice_buffer* read_buffer, + gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data) { + handshaker->vtable->do_handshake(exec_ctx, handshaker, endpoint, args, + read_buffer, deadline, acceptor, cb, + user_data); +} + +// +// grpc_handshake_manager +// + +// State used while chaining handshakers. +struct grpc_handshaker_state { + // The index of the handshaker to invoke next. + size_t index; + // The deadline for all handshakers. + gpr_timespec deadline; + // The acceptor to call the handshakers with. + grpc_tcp_server_acceptor* acceptor; + // The final callback and user_data to invoke after the last handshaker. + grpc_handshaker_done_cb final_cb; + void* final_user_data; +}; + +struct grpc_handshake_manager { + // An array of handshakers added via grpc_handshake_manager_add(). + size_t count; + grpc_handshaker** handshakers; + // State used while chaining handshakers. + struct grpc_handshaker_state* state; +}; + +grpc_handshake_manager* grpc_handshake_manager_create() { + grpc_handshake_manager* mgr = gpr_malloc(sizeof(grpc_handshake_manager)); + memset(mgr, 0, sizeof(*mgr)); + return mgr; +} + +static bool is_power_of_2(size_t n) { return (n & (n - 1)) == 0; } + +void grpc_handshake_manager_add(grpc_handshake_manager* mgr, + grpc_handshaker* handshaker) { + // To avoid allocating memory for each handshaker we add, we double + // the number of elements every time we need more. + size_t realloc_count = 0; + if (mgr->count == 0) { + realloc_count = 2; + } else if (mgr->count >= 2 && is_power_of_2(mgr->count)) { + realloc_count = mgr->count * 2; + } + if (realloc_count > 0) { + mgr->handshakers = + gpr_realloc(mgr->handshakers, realloc_count * sizeof(grpc_handshaker*)); + } + mgr->handshakers[mgr->count++] = handshaker; +} + +void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr) { + for (size_t i = 0; i < mgr->count; ++i) { + grpc_handshaker_destroy(exec_ctx, mgr->handshakers[i]); + } + gpr_free(mgr->handshakers); + gpr_free(mgr); +} + +void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr) { + for (size_t i = 0; i < mgr->count; ++i) { + grpc_handshaker_shutdown(exec_ctx, mgr->handshakers[i]); + } + if (mgr->state != NULL) { + gpr_free(mgr->state); + mgr->state = NULL; + } +} + +// A function used as the handshaker-done callback when chaining +// handshakers together. +static void call_next_handshaker(grpc_exec_ctx* exec_ctx, + grpc_endpoint* endpoint, + grpc_channel_args* args, + gpr_slice_buffer* read_buffer, void* user_data, + grpc_error* error) { + grpc_handshake_manager* mgr = user_data; + GPR_ASSERT(mgr->state != NULL); + GPR_ASSERT(mgr->state->index < mgr->count); + // If we got an error, skip all remaining handshakers and invoke the + // caller-supplied callback immediately. + if (error != GRPC_ERROR_NONE) { + mgr->state->final_cb(exec_ctx, endpoint, args, read_buffer, + mgr->state->final_user_data, error); + return; + } + grpc_handshaker_done_cb cb = call_next_handshaker; + // If this is the last handshaker, use the caller-supplied callback + // and user_data instead of chaining back to this function again. + if (mgr->state->index == mgr->count - 1) { + cb = mgr->state->final_cb; + user_data = mgr->state->final_user_data; + } + // Invoke handshaker. + grpc_handshaker_do_handshake( + exec_ctx, mgr->handshakers[mgr->state->index], endpoint, args, + read_buffer, mgr->state->deadline, mgr->state->acceptor, cb, user_data); + ++mgr->state->index; + // If this is the last handshaker, clean up state. + if (mgr->state->index == mgr->count) { + gpr_free(mgr->state); + mgr->state = NULL; + } +} + +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, const grpc_channel_args* args, + gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data) { + grpc_channel_args* args_copy = grpc_channel_args_copy(args); + gpr_slice_buffer* read_buffer = malloc(sizeof(*read_buffer)); + gpr_slice_buffer_init(read_buffer); + if (mgr->count == 0) { + // No handshakers registered, so we just immediately call the done + // callback with the passed-in endpoint. + cb(exec_ctx, endpoint, args_copy, read_buffer, user_data, GRPC_ERROR_NONE); + } else { + GPR_ASSERT(mgr->state == NULL); + mgr->state = gpr_malloc(sizeof(struct grpc_handshaker_state)); + memset(mgr->state, 0, sizeof(*mgr->state)); + mgr->state->deadline = deadline; + mgr->state->acceptor = acceptor; + mgr->state->final_cb = cb; + mgr->state->final_user_data = user_data; + call_next_handshaker(exec_ctx, endpoint, args_copy, read_buffer, mgr, + GRPC_ERROR_NONE); + } +} diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h new file mode 100644 index 00000000000..b276f6028c1 --- /dev/null +++ b/src/core/lib/channel/handshaker.h @@ -0,0 +1,150 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H +#define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H + +#include +#include +#include + +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/tcp_server.h" + +/// Handshakers are used to perform initial handshakes on a connection +/// before the client sends the initial request. Some examples of what +/// a handshaker can be used for includes support for HTTP CONNECT on +/// the client side and various types of security initialization. +/// +/// In general, handshakers should be used via a handshake manager. + +/// +/// grpc_handshaker +/// + +typedef struct grpc_handshaker grpc_handshaker; + +/// Callback type invoked when a handshaker is done. +/// Takes ownership of \a args and \a read_buffer. +typedef void (*grpc_handshaker_done_cb)(grpc_exec_ctx* exec_ctx, + grpc_endpoint* endpoint, + grpc_channel_args* args, + gpr_slice_buffer* read_buffer, + void* user_data, grpc_error* error); + +struct grpc_handshaker_vtable { + /// Destroys the handshaker. + void (*destroy)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + + /// Shuts down the handshaker (e.g., to clean up when the operation is + /// aborted in the middle). + void (*shutdown)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker); + + /// Performs handshaking. When finished, calls \a cb with \a user_data. + /// Takes ownership of \a args. + /// Takes ownership of \a read_buffer, which contains leftover bytes read + /// from the endpoint by the previous handshaker. + /// \a acceptor will be NULL for client-side handshakers. + void (*do_handshake)(grpc_exec_ctx* exec_ctx, grpc_handshaker* handshaker, + grpc_endpoint* endpoint, grpc_channel_args* args, + gpr_slice_buffer* read_buffer, gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); +}; + +/// Base struct. To subclass, make this the first member of the +/// implementation struct. +struct grpc_handshaker { + const struct grpc_handshaker_vtable* vtable; +}; + +/// Called by concrete implementations to initialize the base struct. +void grpc_handshaker_init(const struct grpc_handshaker_vtable* vtable, + grpc_handshaker* handshaker); + +/// Convenient wrappers for invoking methods via the vtable. +/// These probably do not need to be called from anywhere but +/// grpc_handshake_manager. +void grpc_handshaker_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker); +void grpc_handshaker_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker); +void grpc_handshaker_do_handshake(grpc_exec_ctx* exec_ctx, + grpc_handshaker* handshaker, + grpc_endpoint* endpoint, + grpc_channel_args* args, + gpr_slice_buffer* read_buffer, + gpr_timespec deadline, + grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); + +/// +/// grpc_handshake_manager +/// + +typedef struct grpc_handshake_manager grpc_handshake_manager; + +/// Creates a new handshake manager. Caller takes ownership. +grpc_handshake_manager* grpc_handshake_manager_create(); + +/// Adds a handshaker to the handshake manager. +/// Takes ownership of \a handshaker. +void grpc_handshake_manager_add(grpc_handshake_manager* mgr, + grpc_handshaker* handshaker); + +/// Destroys the handshake manager. +void grpc_handshake_manager_destroy(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr); + +/// Shuts down the handshake manager (e.g., to clean up when the operation is +/// aborted in the middle). +/// The caller must still call grpc_handshake_manager_destroy() after +/// calling this function. +void grpc_handshake_manager_shutdown(grpc_exec_ctx* exec_ctx, + grpc_handshake_manager* mgr); + +/// Invokes handshakers in the order they were added. +/// Does NOT take ownership of \a args. Instead, makes a copy before +/// invoking the first handshaker. +/// \a acceptor will be NULL for client-side handshakers. +/// Invokes \a cb with \a user_data after either a handshaker fails or +/// all handshakers have completed successfully. +void grpc_handshake_manager_do_handshake( + grpc_exec_ctx* exec_ctx, grpc_handshake_manager* mgr, + grpc_endpoint* endpoint, const grpc_channel_args* args, + gpr_timespec deadline, grpc_tcp_server_acceptor* acceptor, + grpc_handshaker_done_cb cb, void* user_data); + +#endif /* GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H */ diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c index 8057e251f0b..edcc741ff6f 100644 --- a/src/core/lib/channel/http_client_filter.c +++ b/src/core/lib/channel/http_client_filter.c @@ -43,6 +43,9 @@ #define EXPECTED_CONTENT_TYPE "application/grpc" #define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1 +/* default maximum size of payload eligable for GET request */ +static const size_t kMaxPayloadSizeForGet = 2048; + typedef struct call_data { grpc_linked_mdelem method; grpc_linked_mdelem scheme; @@ -50,20 +53,39 @@ typedef struct call_data { grpc_linked_mdelem te_trailers; grpc_linked_mdelem content_type; grpc_linked_mdelem user_agent; + grpc_linked_mdelem payload_bin; grpc_metadata_batch *recv_initial_metadata; + uint8_t *payload_bytes; + + /* Vars to read data off of send_message */ + grpc_transport_stream_op send_op; + uint32_t send_length; + uint32_t send_flags; + gpr_slice incoming_slice; + grpc_slice_buffer_stream replacement_stream; + gpr_slice_buffer slices; + /* flag that indicates that all slices of send_messages aren't availble */ + bool send_message_blocked; /** Closure to call when finished with the hc_on_recv hook */ grpc_closure *on_done_recv; + grpc_closure *on_complete; + grpc_closure *post_send; + /** Receive closures are chained: we inject this closure as the on_done_recv up-call on transport_op, and remember to call our on_done_recv member after handling it. */ grpc_closure hc_on_recv; + grpc_closure hc_on_complete; + grpc_closure got_slice; + grpc_closure send_done; } call_data; typedef struct channel_data { grpc_mdelem *static_scheme; grpc_mdelem *user_agent; + size_t max_payload_size_for_get; } channel_data; typedef struct { @@ -119,6 +141,24 @@ static void hc_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, calld->on_done_recv->cb(exec_ctx, calld->on_done_recv->cb_arg, error); } +static void hc_on_complete(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_error *error) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + if (calld->payload_bytes) { + gpr_free(calld->payload_bytes); + calld->payload_bytes = NULL; + } + calld->on_complete->cb(exec_ctx, calld->on_complete->cb_arg, error); +} + +static void send_done(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { + grpc_call_element *elem = elemp; + call_data *calld = elem->call_data; + gpr_slice_buffer_reset_and_unref(&calld->slices); + calld->post_send->cb(exec_ctx, calld->post_send->cb_arg, error); +} + static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { /* eat the things we'd like to set ourselves */ if (md->key == GRPC_MDSTR_METHOD) return NULL; @@ -129,22 +169,104 @@ static grpc_mdelem *client_strip_filter(void *user_data, grpc_mdelem *md) { return md; } -static void hc_mutate_op(grpc_call_element *elem, +static void continue_send_message(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem) { + call_data *calld = elem->call_data; + uint8_t *wrptr = calld->payload_bytes; + while (grpc_byte_stream_next(exec_ctx, calld->send_op.send_message, + &calld->incoming_slice, ~(size_t)0, + &calld->got_slice)) { + memcpy(wrptr, GPR_SLICE_START_PTR(calld->incoming_slice), + GPR_SLICE_LENGTH(calld->incoming_slice)); + wrptr += GPR_SLICE_LENGTH(calld->incoming_slice); + gpr_slice_buffer_add(&calld->slices, calld->incoming_slice); + if (calld->send_length == calld->slices.length) { + calld->send_message_blocked = false; + break; + } + } +} + +static void got_slice(grpc_exec_ctx *exec_ctx, void *elemp, grpc_error *error) { + grpc_call_element *elem = elemp; + call_data *calld = elem->call_data; + calld->send_message_blocked = false; + gpr_slice_buffer_add(&calld->slices, calld->incoming_slice); + if (calld->send_length == calld->slices.length) { + /* Pass down the original send_message op that was blocked.*/ + grpc_slice_buffer_stream_init(&calld->replacement_stream, &calld->slices, + calld->send_flags); + calld->send_op.send_message = &calld->replacement_stream.base; + calld->post_send = calld->send_op.on_complete; + calld->send_op.on_complete = &calld->send_done; + grpc_call_next_op(exec_ctx, elem, &calld->send_op); + } else { + continue_send_message(exec_ctx, elem); + } +} + +static void hc_mutate_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, grpc_transport_stream_op *op) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *channeld = elem->channel_data; + if (op->send_initial_metadata != NULL) { + /* Decide which HTTP VERB to use. We use GET if the request is marked + cacheable, and the operation contains both initial metadata and send + message, and the payload is below the size threshold, and all the data + for this request is immediately available. */ + grpc_mdelem *method = GRPC_MDELEM_METHOD_POST; + calld->send_message_blocked = false; + if ((op->send_initial_metadata_flags & + GRPC_INITIAL_METADATA_CACHEABLE_REQUEST) && + op->send_message != NULL && + op->send_message->length < channeld->max_payload_size_for_get) { + method = GRPC_MDELEM_METHOD_GET; + calld->send_message_blocked = true; + } else if (op->send_initial_metadata_flags & + GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST) { + method = GRPC_MDELEM_METHOD_PUT; + } + + /* Attempt to read the data from send_message and create a header field. */ + if (method == GRPC_MDELEM_METHOD_GET) { + /* allocate memory to hold the entire payload */ + calld->payload_bytes = gpr_malloc(op->send_message->length); + + /* read slices of send_message and copy into payload_bytes */ + calld->send_op = *op; + calld->send_length = op->send_message->length; + calld->send_flags = op->send_message->flags; + continue_send_message(exec_ctx, elem); + + if (calld->send_message_blocked == false) { + /* when all the send_message data is available, then create a MDELEM and + append to headers */ + grpc_mdelem *payload_bin = grpc_mdelem_from_metadata_strings( + GRPC_MDSTR_GRPC_PAYLOAD_BIN, + grpc_mdstr_from_buffer(calld->payload_bytes, + op->send_message->length)); + grpc_metadata_batch_add_tail(op->send_initial_metadata, + &calld->payload_bin, payload_bin); + calld->on_complete = op->on_complete; + op->on_complete = &calld->hc_on_complete; + op->send_message = NULL; + } else { + /* Not all data is available. Fall back to POST. */ + gpr_log(GPR_DEBUG, + "Request is marked Cacheable but not all data is available.\ + Falling back to POST"); + method = GRPC_MDELEM_METHOD_POST; + } + } + grpc_metadata_batch_filter(op->send_initial_metadata, client_strip_filter, elem); /* Send : prefixed headers, which have to be before any application layer headers. */ - grpc_metadata_batch_add_head( - op->send_initial_metadata, &calld->method, - op->send_initial_metadata_flags & - GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST - ? GRPC_MDELEM_METHOD_PUT - : GRPC_MDELEM_METHOD_POST); + grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->method, + method); grpc_metadata_batch_add_head(op->send_initial_metadata, &calld->scheme, channeld->static_scheme); grpc_metadata_batch_add_tail(op->send_initial_metadata, &calld->te_trailers, @@ -169,22 +291,41 @@ static void hc_start_transport_op(grpc_exec_ctx *exec_ctx, grpc_transport_stream_op *op) { GPR_TIMER_BEGIN("hc_start_transport_op", 0); GRPC_CALL_LOG_OP(GPR_INFO, elem, op); - hc_mutate_op(elem, op); + hc_mutate_op(exec_ctx, elem, op); GPR_TIMER_END("hc_start_transport_op", 0); - grpc_call_next_op(exec_ctx, elem, op); + call_data *calld = elem->call_data; + if (op->send_message != NULL && calld->send_message_blocked) { + /* Don't forward the op. send_message contains slices that aren't ready + yet. The call will be forwarded by the op_complete of slice read call. + */ + } else { + grpc_call_next_op(exec_ctx, elem, op); + } } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; calld->on_done_recv = NULL; + calld->on_complete = NULL; + calld->payload_bytes = NULL; + gpr_slice_buffer_init(&calld->slices); grpc_closure_init(&calld->hc_on_recv, hc_on_recv, elem); + grpc_closure_init(&calld->hc_on_complete, hc_on_complete, elem); + grpc_closure_init(&calld->got_slice, got_slice, elem); + grpc_closure_init(&calld->send_done, send_done, elem); + return GRPC_ERROR_NONE; } /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) {} + const grpc_call_final_info *final_info, + void *ignored) { + call_data *calld = elem->call_data; + gpr_slice_buffer_destroy(&calld->slices); +} static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { unsigned i; @@ -207,6 +348,22 @@ static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) { return GRPC_MDELEM_SCHEME_HTTP; } +static size_t max_payload_size_from_args(const grpc_channel_args *args) { + if (args != NULL) { + for (size_t i = 0; i < args->num_args; ++i) { + if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET)) { + if (args->args[i].type != GRPC_ARG_INTEGER) { + gpr_log(GPR_ERROR, "%s: must be an integer", + GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET); + } else { + return (size_t)args->args[i].value.integer; + } + } + } + } + return kMaxPayloadSizeForGet; +} + static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args, const char *transport_name) { gpr_strvec v; @@ -230,8 +387,9 @@ static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args, } } - gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s)", is_first ? "" : " ", - grpc_version_string(), GPR_PLATFORM_STRING, transport_name); + gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s; %s)", is_first ? "" : " ", + grpc_version_string(), GPR_PLATFORM_STRING, transport_name, + grpc_g_stands_for()); is_first = 0; gpr_strvec_add(&v, tmp); @@ -264,6 +422,8 @@ static void init_channel_elem(grpc_exec_ctx *exec_ctx, GPR_ASSERT(!args->is_last); GPR_ASSERT(args->optional_transport != NULL); chand->static_scheme = scheme_from_args(args->channel_args); + chand->max_payload_size_for_get = + max_payload_size_from_args(args->channel_args); chand->user_agent = grpc_mdelem_from_metadata_strings( GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args, diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h index 47081175ea9..9e6e106e9cb 100644 --- a/src/core/lib/channel/http_client_filter.h +++ b/src/core/lib/channel/http_client_filter.h @@ -41,4 +41,7 @@ extern const grpc_channel_filter grpc_http_client_filter; /* Channel arg to override the http2 :scheme header */ #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme" +/* Channel arg to determine maximum size of payload eligable for GET request */ +#define GRPC_ARG_MAX_PAYLOAD_SIZE_FOR_GET "grpc.max_payload_size_for_get" + #endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */ diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c index d0beebd817f..0f2bf97824b 100644 --- a/src/core/lib/channel/http_server_filter.c +++ b/src/core/lib/channel/http_server_filter.c @@ -49,17 +49,32 @@ typedef struct call_data { uint8_t seen_scheme; uint8_t seen_te_trailers; uint8_t seen_authority; + uint8_t seen_payload_bin; grpc_linked_mdelem status; grpc_linked_mdelem content_type; + /* flag to ensure payload_bin is delivered only once */ + uint8_t payload_bin_delivered; + grpc_metadata_batch *recv_initial_metadata; bool *recv_idempotent_request; + bool *recv_cacheable_request; /** Closure to call when finished with the hs_on_recv hook */ grpc_closure *on_done_recv; + /** Closure to call when we retrieve read message from the payload-bin header + */ + grpc_closure *recv_message_ready; + grpc_closure *on_complete; + grpc_byte_stream **pp_recv_message; + gpr_slice_buffer read_slice_buffer; + grpc_slice_buffer_stream read_stream; + /** Receive closures are chained: we inject this closure as the on_done_recv up-call on transport_op, and remember to call our on_done_recv member after handling it. */ grpc_closure hs_on_recv; + grpc_closure hs_on_complete; + grpc_closure hs_recv_message_ready; } call_data; typedef struct channel_data { uint8_t unused; } channel_data; @@ -76,16 +91,20 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { /* Check if it is one of the headers we care about. */ if (md == GRPC_MDELEM_TE_TRAILERS || md == GRPC_MDELEM_METHOD_POST || - md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_SCHEME_HTTP || - md == GRPC_MDELEM_SCHEME_HTTPS || + md == GRPC_MDELEM_METHOD_PUT || md == GRPC_MDELEM_METHOD_GET || + md == GRPC_MDELEM_SCHEME_HTTP || md == GRPC_MDELEM_SCHEME_HTTPS || md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) { /* swallow it */ if (md == GRPC_MDELEM_METHOD_POST) { calld->seen_method = 1; *calld->recv_idempotent_request = false; + *calld->recv_cacheable_request = false; } else if (md == GRPC_MDELEM_METHOD_PUT) { calld->seen_method = 1; *calld->recv_idempotent_request = true; + } else if (md == GRPC_MDELEM_METHOD_GET) { + calld->seen_method = 1; + *calld->recv_cacheable_request = true; } else if (md->key == GRPC_MDSTR_SCHEME) { calld->seen_scheme = 1; } else if (md == GRPC_MDELEM_TE_TRAILERS) { @@ -137,6 +156,16 @@ static grpc_mdelem *server_filter(void *user_data, grpc_mdelem *md) { GRPC_MDSTR_AUTHORITY, GRPC_MDSTR_REF(md->value)); calld->seen_authority = 1; return authority; + } else if (md->key == GRPC_MDSTR_GRPC_PAYLOAD_BIN) { + /* Retrieve the payload from the value of the 'grpc-internal-payload-bin' + header field */ + calld->seen_payload_bin = 1; + gpr_slice_buffer_init(&calld->read_slice_buffer); + gpr_slice_buffer_add(&calld->read_slice_buffer, + gpr_slice_ref(md->value->slice)); + grpc_slice_buffer_stream_init(&calld->read_stream, + &calld->read_slice_buffer, 0); + return NULL; } else { return md; } @@ -189,6 +218,36 @@ static void hs_on_recv(grpc_exec_ctx *exec_ctx, void *user_data, GRPC_ERROR_UNREF(err); } +static void hs_on_complete(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_error *err) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + /* Call recv_message_ready if we got the payload via the header field */ + if (calld->seen_payload_bin && calld->recv_message_ready != NULL) { + *calld->pp_recv_message = calld->payload_bin_delivered + ? NULL + : (grpc_byte_stream *)&calld->read_stream; + calld->recv_message_ready->cb(exec_ctx, calld->recv_message_ready->cb_arg, + err); + calld->recv_message_ready = NULL; + calld->payload_bin_delivered = true; + } + calld->on_complete->cb(exec_ctx, calld->on_complete->cb_arg, err); +} + +static void hs_recv_message_ready(grpc_exec_ctx *exec_ctx, void *user_data, + grpc_error *err) { + grpc_call_element *elem = user_data; + call_data *calld = elem->call_data; + if (calld->seen_payload_bin) { + /* do nothing. This is probably a GET request, and payload will be returned + in hs_on_complete callback. */ + } else { + calld->recv_message_ready->cb(exec_ctx, calld->recv_message_ready->cb_arg, + err); + } +} + static void hs_mutate_op(grpc_call_element *elem, grpc_transport_stream_op *op) { /* grab pointers to our data from the call element */ @@ -206,11 +265,25 @@ static void hs_mutate_op(grpc_call_element *elem, if (op->recv_initial_metadata) { /* substitute our callback for the higher callback */ GPR_ASSERT(op->recv_idempotent_request != NULL); + GPR_ASSERT(op->recv_cacheable_request != NULL); calld->recv_initial_metadata = op->recv_initial_metadata; calld->recv_idempotent_request = op->recv_idempotent_request; + calld->recv_cacheable_request = op->recv_cacheable_request; calld->on_done_recv = op->recv_initial_metadata_ready; op->recv_initial_metadata_ready = &calld->hs_on_recv; } + + if (op->recv_message) { + calld->recv_message_ready = op->recv_message_ready; + calld->pp_recv_message = op->recv_message; + if (op->recv_message_ready) { + op->recv_message_ready = &calld->hs_recv_message_ready; + } + if (op->on_complete) { + calld->on_complete = op->on_complete; + op->on_complete = &calld->hs_on_complete; + } + } } static void hs_start_transport_op(grpc_exec_ctx *exec_ctx, @@ -224,18 +297,23 @@ static void hs_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; /* initialize members */ memset(calld, 0, sizeof(*calld)); grpc_closure_init(&calld->hs_on_recv, hs_on_recv, elem); + grpc_closure_init(&calld->hs_on_complete, hs_on_complete, elem); + grpc_closure_init(&calld->hs_recv_message_ready, hs_recv_message_ready, elem); + return GRPC_ERROR_NONE; } /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) {} + const grpc_call_final_info *final_info, + void *ignored) {} /* Constructor for channel_data */ static void init_channel_elem(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/http/httpcli_security_connector.c b/src/core/lib/http/httpcli_security_connector.c index a57d93bb7bb..0006e809a6a 100644 --- a/src/core/lib/http/httpcli_security_connector.c +++ b/src/core/lib/http/httpcli_security_connector.c @@ -61,6 +61,7 @@ static void httpcli_ssl_destroy(grpc_security_connector *sc) { static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { @@ -69,6 +70,7 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, tsi_result result = TSI_OK; tsi_handshaker *handshaker; if (c->handshaker_factory == NULL) { + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); return; } @@ -77,10 +79,12 @@ static void httpcli_ssl_do_handshake(grpc_exec_ctx *exec_ctx, if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", tsi_result_to_string(result)); + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, deadline, cb, user_data); + nonsecure_endpoint, read_buffer, deadline, cb, + user_data); } } @@ -183,7 +187,7 @@ static void ssl_handshake(grpc_exec_ctx *exec_ctx, void *arg, pem_root_certs, pem_root_certs_size, host, &sc) == GRPC_SECURITY_OK); grpc_channel_security_connector_do_handshake( - exec_ctx, sc, tcp, deadline, on_secure_transport_setup_done, c); + exec_ctx, sc, tcp, NULL, deadline, on_secure_transport_setup_done, c); GRPC_SECURITY_CONNECTOR_UNREF(&sc->base, "httpcli"); } diff --git a/src/core/lib/iomgr/error.h b/src/core/lib/iomgr/error.h index 13f898e31ad..6c769accdb6 100644 --- a/src/core/lib/iomgr/error.h +++ b/src/core/lib/iomgr/error.h @@ -47,7 +47,8 @@ /// if a grpc_error is passed to a grpc_closure callback function (functions /// with the signature: /// void (*f)(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error)) -/// then those functions do not automatically own a ref to error +/// then those functions do not own a ref to error (but are free to manually +/// take a reference). /// if a grpc_error is passed to *ANY OTHER FUNCTION* then that function takes /// ownership of the error /// Errors have: @@ -171,6 +172,8 @@ grpc_error *grpc_error_set_time(grpc_error *src, grpc_error_times which, gpr_timespec value) GRPC_MUST_USE_RESULT; grpc_error *grpc_error_set_str(grpc_error *src, grpc_error_strs which, const char *value) GRPC_MUST_USE_RESULT; +/// Returns NULL if the specified string is not set. +/// Caller does NOT own return value. const char *grpc_error_get_str(grpc_error *error, grpc_error_strs which); /// Add a child error: an error that is believed to have contributed to this /// error occurring. Allows root causing high level errors from lower level diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c index 6a63c4d1d18..eba347125e3 100644 --- a/src/core/lib/iomgr/ev_epoll_linux.c +++ b/src/core/lib/iomgr/ev_epoll_linux.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -927,7 +928,8 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, fd->polling_island = NULL; } - grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, error, NULL); + grpc_exec_ctx_sched(exec_ctx, fd->on_done_closure, GRPC_ERROR_REF(error), + NULL); gpr_mu_unlock(&fd->mu); UNREF_BY(fd, 2, reason); /* Drop the reference */ @@ -939,6 +941,7 @@ static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd, PI_UNREF(exec_ctx, unref_pi, "fd_orphan"); } GRPC_LOG_IF_ERROR("fd_orphan", GRPC_ERROR_REF(error)); + GRPC_ERROR_UNREF(error); } static grpc_error *fd_shutdown_error(bool shutdown) { @@ -1352,8 +1355,10 @@ static void pollset_work_and_unlock(grpc_exec_ctx *exec_ctx, gpr_mu_unlock(&pollset->mu); do { + GRPC_SCHEDULING_START_BLOCKING_REGION; ep_rv = epoll_pwait(epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, timeout_ms, sig_mask); + GRPC_SCHEDULING_END_BLOCKING_REGION; if (ep_rv < 0) { if (errno != EINTR) { gpr_asprintf(&err_msg, diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c index 4b593f4b2c2..16a5e3083e6 100644 --- a/src/core/lib/iomgr/ev_poll_posix.c +++ b/src/core/lib/iomgr/ev_poll_posix.c @@ -844,6 +844,11 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, *worker_hdl = &worker; grpc_error *error = GRPC_ERROR_NONE; + /* Avoid malloc for small number of elements. */ + enum { inline_elements = 96 }; + struct pollfd pollfd_space[inline_elements]; + struct grpc_fd_watcher watcher_space[inline_elements]; + /* pollset->mu already held */ int added_worker = 0; int locked = 1; @@ -899,15 +904,23 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, int r; size_t i, fd_count; nfds_t pfd_count; - /* TODO(ctiller): inline some elements to avoid an allocation */ grpc_fd_watcher *watchers; struct pollfd *pfds; timeout = poll_deadline_to_millis_timeout(deadline, now); - /* TODO(ctiller): perform just one malloc here if we exceed the inline - * case */ - pfds = gpr_malloc(sizeof(*pfds) * (pollset->fd_count + 2)); - watchers = gpr_malloc(sizeof(*watchers) * (pollset->fd_count + 2)); + + if (pollset->fd_count + 2 <= inline_elements) { + pfds = pollfd_space; + watchers = watcher_space; + } else { + /* Allocate one buffer to hold both pfds and watchers arrays */ + const size_t pfd_size = sizeof(*pfds) * (pollset->fd_count + 2); + const size_t watch_size = sizeof(*watchers) * (pollset->fd_count + 2); + void *buf = gpr_malloc(pfd_size + watch_size); + pfds = buf; + watchers = (void *)((char *)buf + pfd_size); + } + fd_count = 0; pfd_count = 2; pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd); @@ -974,8 +987,11 @@ static grpc_error *pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, } } - gpr_free(pfds); - gpr_free(watchers); + if (pfds != pollfd_space) { + /* pfds and watchers are in the same memory block pointed to by pfds */ + gpr_free(pfds); + } + GPR_TIMER_END("maybe_work_and_unlock", 0); locked = 0; } else { diff --git a/src/core/lib/iomgr/network_status_tracker.c b/src/core/lib/iomgr/network_status_tracker.c index 90c074b007d..b4bb7e3cf7b 100644 --- a/src/core/lib/iomgr/network_status_tracker.c +++ b/src/core/lib/iomgr/network_status_tracker.c @@ -56,6 +56,15 @@ void grpc_network_status_init(void) { // TODO(makarandd): Install callback with OS to monitor network status. } +void grpc_destroy_network_status_monitor() { + for (endpoint_ll_node *curr = head; curr != NULL;) { + endpoint_ll_node *next = curr->next; + gpr_free(curr); + curr = next; + } + gpr_mu_destroy(&g_endpoint_mutex); +} + void grpc_network_status_register_endpoint(grpc_endpoint *ep) { gpr_mu_lock(&g_endpoint_mutex); if (head == NULL) { diff --git a/src/core/lib/iomgr/tcp_posix.c b/src/core/lib/iomgr/tcp_posix.c index ec21e039448..974d5ae4798 100644 --- a/src/core/lib/iomgr/tcp_posix.c +++ b/src/core/lib/iomgr/tcp_posix.c @@ -284,7 +284,7 @@ static void tcp_read(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep, } /* returns true if done, false if pending; if returning true, *error is set */ -#define MAX_WRITE_IOVEC 1024 +#define MAX_WRITE_IOVEC 1000 static bool tcp_flush(grpc_tcp *tcp, grpc_error **error) { struct msghdr msg; struct iovec iov[MAX_WRITE_IOVEC]; diff --git a/src/core/lib/iomgr/tcp_server.h b/src/core/lib/iomgr/tcp_server.h index 875a6ca14a7..5a25d39a0c4 100644 --- a/src/core/lib/iomgr/tcp_server.h +++ b/src/core/lib/iomgr/tcp_server.h @@ -105,4 +105,8 @@ void grpc_tcp_server_shutdown_starting_add(grpc_tcp_server *s, a call (exec_ctx!=NULL) to shutdown_complete. */ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s); +/* Shutdown the fds of listeners. */ +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s); + #endif /* GRPC_CORE_LIB_IOMGR_TCP_SERVER_H */ diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c index cb2ff782d60..2d3f6cf9a7d 100644 --- a/src/core/lib/iomgr/tcp_server_posix.c +++ b/src/core/lib/iomgr/tcp_server_posix.c @@ -90,10 +90,12 @@ struct grpc_tcp_listener { grpc_closure read_closure; grpc_closure destroyed_closure; struct grpc_tcp_listener *next; - /* When we add a listener, more than one can be created, mainly because of - IPv6. A sibling will still be in the normal list, but will be flagged - as such. Any action, such as ref or unref, will affect all of the - siblings in the list. */ + /* sibling is a linked list of all listeners for a given port. add_port and + clone_port place all new listeners in the same sibling list. A member of + the 'sibling' list is also a member of the 'next' list. The head of each + sibling list has is_sibling==0, and subsequent members of sibling lists + have is_sibling==1. is_sibling allows separate sibling lists to be + identified while iterating through 'next'. */ struct grpc_tcp_listener *sibling; int is_sibling; }; @@ -138,15 +140,17 @@ struct grpc_tcp_server { }; static gpr_once check_init = GPR_ONCE_INIT; -static bool has_so_reuseport; +static bool has_so_reuseport = false; static void init(void) { +#ifndef GPR_MANYLINUX1 int s = socket(AF_INET, SOCK_STREAM, 0); if (s >= 0) { has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT", grpc_set_socket_reuse_port(s, 1)); close(s); } +#endif } grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete, @@ -306,7 +310,7 @@ static grpc_error *prepare_socket(int fd, const struct sockaddr *addr, GPR_ASSERT(fd >= 0); - if (so_reuseport) { + if (so_reuseport && !grpc_is_unix_socket(addr)) { err = grpc_set_socket_reuse_port(fd, 1); if (err != GRPC_ERROR_NONE) goto error; } @@ -480,6 +484,9 @@ static grpc_error *add_socket_to_server(grpc_tcp_server *s, int fd, return err; } +/* Insert count new listeners after listener. Every new listener will have the + same listen address as listener (SO_REUSEPORT must be enabled). Every new + listener is a sibling of listener. */ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { grpc_tcp_listener *sp = NULL; char *addr_str; @@ -506,6 +513,11 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp = gpr_malloc(sizeof(grpc_tcp_listener)); sp->next = listener->next; listener->next = sp; + /* sp (the new listener) is a sibling of 'listener' (the original + listener). */ + sp->is_sibling = 1; + sp->sibling = listener->sibling; + listener->sibling = sp; sp->server = listener->server; sp->fd = fd; sp->emfd = grpc_fd_create(fd, name); @@ -514,8 +526,6 @@ static grpc_error *clone_port(grpc_tcp_listener *listener, unsigned count) { sp->port = port; sp->port_index = listener->port_index; sp->fd_index = listener->fd_index + count - i; - sp->is_sibling = 1; - sp->sibling = listener->is_sibling ? listener->sibling : listener; GPR_ASSERT(sp->emfd); while (listener->server->tail->next != NULL) { listener->server->tail = listener->server->tail->next; @@ -685,7 +695,8 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, s->pollset_count = pollset_count; sp = s->head; while (sp != NULL) { - if (s->so_reuseport && pollset_count > 1) { + if (s->so_reuseport && !grpc_is_unix_socket(&sp->addr.sockaddr) && + pollset_count > 1) { GPR_ASSERT(GRPC_LOG_IF_ERROR( "clone_port", clone_port(sp, (unsigned)(pollset_count - 1)))); for (i = 0; i < pollset_count; i++) { @@ -741,4 +752,17 @@ void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) { } } +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s) { + gpr_mu_lock(&s->mu); + /* shutdown all fd's */ + if (s->active_ports) { + grpc_tcp_listener *sp; + for (sp = s->head; sp; sp = sp->next) { + grpc_fd_shutdown(exec_ctx, sp->emfd); + } + } + gpr_mu_unlock(&s->mu); +} + #endif diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c index 7b0966704c2..1b125e7005b 100644 --- a/src/core/lib/iomgr/tcp_server_windows.c +++ b/src/core/lib/iomgr/tcp_server_windows.c @@ -540,4 +540,7 @@ void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s, gpr_mu_unlock(&s->mu); } +void grpc_tcp_server_shutdown_listeners(grpc_exec_ctx *exec_ctx, + grpc_tcp_server *s) {} + #endif /* GPR_WINSOCK_SOCKET */ diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c index 1ebccf2ee2e..48032412a2e 100644 --- a/src/core/lib/iomgr/udp_server.c +++ b/src/core/lib/iomgr/udp_server.c @@ -60,6 +60,7 @@ #include #include #include +#include "src/core/lib/iomgr/error.h" #include "src/core/lib/iomgr/ev_posix.h" #include "src/core/lib/iomgr/resolve_address.h" #include "src/core/lib/iomgr/sockaddr_utils.h" @@ -128,7 +129,7 @@ grpc_udp_server *grpc_udp_server_create(void) { } static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { - grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1, NULL); + grpc_exec_ctx_sched(exec_ctx, s->shutdown_complete, GRPC_ERROR_NONE, NULL); gpr_mu_destroy(&s->mu); gpr_cv_destroy(&s->cv); @@ -138,7 +139,7 @@ static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_udp_server *s) { } static void destroyed_port(grpc_exec_ctx *exec_ctx, void *server, - bool success) { + grpc_error *error) { grpc_udp_server *s = server; gpr_mu_lock(&s->mu); s->destroyed_ports++; @@ -217,14 +218,23 @@ static int prepare_socket(int fd, const struct sockaddr *addr, goto error; } - if (!grpc_set_socket_nonblocking(fd, 1) || !grpc_set_socket_cloexec(fd, 1)) { - gpr_log(GPR_ERROR, "Unable to configure socket %d: %s", fd, - strerror(errno)); + if (grpc_set_socket_nonblocking(fd, 1) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set nonblocking %d: %s", fd, strerror(errno)); + goto error; + } + if (grpc_set_socket_cloexec(fd, 1) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set cloexec %d: %s", fd, strerror(errno)); + goto error; } - if (grpc_set_socket_ip_pktinfo_if_possible(fd) && - addr->sa_family == AF_INET6) { - grpc_set_socket_ipv6_recvpktinfo_if_possible(fd); + if (grpc_set_socket_ip_pktinfo_if_possible(fd) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set ip_pktinfo."); + goto error; + } else if (addr->sa_family == AF_INET6) { + if (grpc_set_socket_ipv6_recvpktinfo_if_possible(fd) != GRPC_ERROR_NONE) { + gpr_log(GPR_ERROR, "Unable to set ipv6_recvpktinfo."); + goto error; + } } GPR_ASSERT(addr_len < ~(socklen_t)0); @@ -241,13 +251,13 @@ static int prepare_socket(int fd, const struct sockaddr *addr, goto error; } - if (!grpc_set_socket_sndbuf(fd, buffer_size_bytes)) { + if (grpc_set_socket_sndbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes", buffer_size_bytes); goto error; } - if (!grpc_set_socket_rcvbuf(fd, buffer_size_bytes)) { + if (grpc_set_socket_rcvbuf(fd, buffer_size_bytes) != GRPC_ERROR_NONE) { gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes", buffer_size_bytes); goto error; @@ -263,10 +273,10 @@ error: } /* event manager callback when reads are ready */ -static void on_read(grpc_exec_ctx *exec_ctx, void *arg, bool success) { +static void on_read(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { server_port *sp = arg; - if (!success) { + if (error != GRPC_ERROR_NONE) { gpr_mu_lock(&sp->server->mu); if (0 == --sp->server->active_ports) { gpr_mu_unlock(&sp->server->mu); @@ -369,7 +379,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, /* Try listening on IPv6 first. */ addr = (struct sockaddr *)&wild6; addr_len = sizeof(wild6); - fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); + // TODO(rjshade): Test and propagate the returned grpc_error*: + grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd); allocated_port1 = add_socket_to_server(s, fd, addr, addr_len, read_cb, orphan_cb); if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) { @@ -384,7 +395,8 @@ int grpc_udp_server_add_port(grpc_udp_server *s, const void *addr, addr_len = sizeof(wild4); } - fd = grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode); + // TODO(rjshade): Test and propagate the returned grpc_error*: + grpc_create_dualstack_socket(addr, SOCK_DGRAM, IPPROTO_UDP, &dsmode, &fd); if (fd < 0) { gpr_log(GPR_ERROR, "Unable to create socket: %s", strerror(errno)); } diff --git a/src/core/lib/json/json_reader.c b/src/core/lib/json/json_reader.c index bc04bccc65e..5b42ca53ff5 100644 --- a/src/core/lib/json/json_reader.c +++ b/src/core/lib/json/json_reader.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -171,8 +171,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { switch (reader->state) { case GRPC_JSON_STATE_OBJECT_KEY_STRING: case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate != 0) + if (reader->unicode_high_surrogate != 0) { return GRPC_JSON_PARSE_ERROR; + } json_reader_string_add_char(reader, c); break; @@ -289,8 +290,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { break; case GRPC_JSON_STATE_OBJECT_KEY_STRING: - if (reader->unicode_high_surrogate != 0) + if (reader->unicode_high_surrogate != 0) { return GRPC_JSON_PARSE_ERROR; + } if (c == '"') { reader->state = GRPC_JSON_STATE_OBJECT_KEY_END; json_reader_set_key(reader); @@ -302,8 +304,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { break; case GRPC_JSON_STATE_VALUE_STRING: - if (reader->unicode_high_surrogate != 0) + if (reader->unicode_high_surrogate != 0) { return GRPC_JSON_PARSE_ERROR; + } if (c == '"') { reader->state = GRPC_JSON_STATE_VALUE_END; json_reader_set_string(reader); @@ -383,8 +386,9 @@ grpc_json_reader_status grpc_json_reader_run(grpc_json_reader *reader) { } else { reader->state = GRPC_JSON_STATE_VALUE_STRING; } - if (reader->unicode_high_surrogate && c != 'u') + if (reader->unicode_high_surrogate && c != 'u') { return GRPC_JSON_PARSE_ERROR; + } switch (c) { case '"': case '/': diff --git a/src/core/lib/security/context/security_context.c b/src/core/lib/security/context/security_context.c index 127b13ee503..2204fadf54c 100644 --- a/src/core/lib/security/context/security_context.c +++ b/src/core/lib/security/context/security_context.c @@ -99,6 +99,9 @@ void grpc_client_security_context_destroy(void *ctx) { grpc_client_security_context *c = (grpc_client_security_context *)ctx; grpc_call_credentials_unref(c->creds); GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context"); + if (c->extension.instance != NULL && c->extension.destroy != NULL) { + c->extension.destroy(c->extension.instance); + } gpr_free(ctx); } @@ -114,6 +117,9 @@ grpc_server_security_context *grpc_server_security_context_create(void) { void grpc_server_security_context_destroy(void *ctx) { grpc_server_security_context *c = (grpc_server_security_context *)ctx; GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "server_security_context"); + if (c->extension.instance != NULL && c->extension.destroy != NULL) { + c->extension.destroy(c->extension.instance); + } gpr_free(ctx); } diff --git a/src/core/lib/security/context/security_context.h b/src/core/lib/security/context/security_context.h index ef0c06b1fb6..1e131a0c230 100644 --- a/src/core/lib/security/context/security_context.h +++ b/src/core/lib/security/context/security_context.h @@ -37,6 +37,10 @@ #include "src/core/lib/iomgr/pollset.h" #include "src/core/lib/security/credentials/credentials.h" +#ifdef __cplusplus +extern "C" { +#endif + /* --- grpc_auth_context --- High level authentication context object. Can optionally be chained. */ @@ -80,6 +84,16 @@ void grpc_auth_context_unref(grpc_auth_context *policy); 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 + later by a higher level method on a grpc_call object. */ + +typedef struct { + void *instance; + void (*destroy)(void *); +} grpc_security_context_extension; + /* --- grpc_client_security_context --- Internal client-side security context. */ @@ -87,6 +101,7 @@ void grpc_auth_property_reset(grpc_auth_property *property); typedef struct { grpc_call_credentials *creds; grpc_auth_context *auth_context; + grpc_security_context_extension extension; } grpc_client_security_context; grpc_client_security_context *grpc_client_security_context_create(void); @@ -98,6 +113,7 @@ void grpc_client_security_context_destroy(void *ctx); typedef struct { grpc_auth_context *auth_context; + grpc_security_context_extension extension; } grpc_server_security_context; grpc_server_security_context *grpc_server_security_context_create(void); @@ -111,4 +127,8 @@ grpc_auth_context *grpc_auth_context_from_arg(const grpc_arg *arg); grpc_auth_context *grpc_find_auth_context_in_args( const grpc_channel_args *args); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_SECURITY_CONTEXT_SECURITY_CONTEXT_H */ diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c index ed7929aa27e..2a1bf4d4e34 100644 --- a/src/core/lib/security/transport/client_auth_filter.c +++ b/src/core/lib/security/transport/client_auth_filter.c @@ -267,10 +267,12 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; memset(calld, 0, sizeof(*calld)); + return GRPC_ERROR_NONE; } static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, @@ -282,7 +284,8 @@ static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx, /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) { + const grpc_call_final_info *final_info, + void *ignored) { call_data *calld = elem->call_data; grpc_call_credentials_unref(calld->creds); if (calld->host != NULL) { diff --git a/src/core/lib/security/transport/handshake.c b/src/core/lib/security/transport/handshake.c index b374ca7633b..fbeec312b6f 100644 --- a/src/core/lib/security/transport/handshake.c +++ b/src/core/lib/security/transport/handshake.c @@ -325,8 +325,9 @@ static void on_timeout(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { void grpc_do_security_handshake( grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_security_connector *connector, bool is_client_side, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data) { + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, + void *user_data) { grpc_security_connector_handshake_list *handshake_node; grpc_security_handshake *h = gpr_malloc(sizeof(grpc_security_handshake)); memset(h, 0, sizeof(grpc_security_handshake)); @@ -346,6 +347,10 @@ void grpc_do_security_handshake( gpr_slice_buffer_init(&h->left_overs); gpr_slice_buffer_init(&h->outgoing); gpr_slice_buffer_init(&h->incoming); + if (read_buffer != NULL) { + gpr_slice_buffer_move_into(read_buffer, &h->incoming); + gpr_free(read_buffer); + } if (!is_client_side) { grpc_server_security_connector *server_connector = (grpc_server_security_connector *)connector; @@ -357,8 +362,9 @@ void grpc_do_security_handshake( gpr_mu_unlock(&server_connector->mu); } send_handshake_bytes_to_peer(exec_ctx, h); - grpc_timer_init(exec_ctx, &h->timer, deadline, on_timeout, h, - gpr_now(deadline.clock_type)); + grpc_timer_init(exec_ctx, &h->timer, + gpr_convert_clock_type(deadline, GPR_CLOCK_MONOTONIC), + on_timeout, h, gpr_now(GPR_CLOCK_MONOTONIC)); } void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/security/transport/handshake.h b/src/core/lib/security/transport/handshake.h index c0906dd6af0..53092f54214 100644 --- a/src/core/lib/security/transport/handshake.h +++ b/src/core/lib/security/transport/handshake.h @@ -37,12 +37,13 @@ #include "src/core/lib/iomgr/endpoint.h" #include "src/core/lib/security/transport/security_connector.h" -/* Calls the callback upon completion. Takes owership of handshaker. */ +/* Calls the callback upon completion. Takes owership of handshaker and + * read_buffer. */ void grpc_do_security_handshake( grpc_exec_ctx *exec_ctx, tsi_handshaker *handshaker, grpc_security_connector *connector, bool is_client_side, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data); + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake); diff --git a/src/core/lib/security/transport/secure_endpoint.c b/src/core/lib/security/transport/secure_endpoint.c index bc50f9d1b00..0169ccd9ef9 100644 --- a/src/core/lib/security/transport/secure_endpoint.c +++ b/src/core/lib/security/transport/secure_endpoint.c @@ -128,7 +128,7 @@ static void flush_read_staging_buffer(secure_endpoint *ep, uint8_t **cur, static void call_read_cb(grpc_exec_ctx *exec_ctx, secure_endpoint *ep, grpc_error *error) { - if (false && grpc_trace_secure_endpoint) { + if (grpc_trace_secure_endpoint) { size_t i; for (i = 0; i < ep->read_buffer->count; i++) { char *data = gpr_dump_slice(ep->read_buffer->slices[i], @@ -256,7 +256,7 @@ static void endpoint_write(grpc_exec_ctx *exec_ctx, grpc_endpoint *secure_ep, gpr_slice_buffer_reset_and_unref(&ep->output_buffer); - if (false && grpc_trace_secure_endpoint) { + if (grpc_trace_secure_endpoint) { for (i = 0; i < slices->count; i++) { char *data = gpr_dump_slice(slices->slices[i], GPR_DUMP_HEX | GPR_DUMP_ASCII); diff --git a/src/core/lib/security/transport/security_connector.c b/src/core/lib/security/transport/security_connector.c index f0ee6770e5f..0eca46eb525 100644 --- a/src/core/lib/security/transport/security_connector.c +++ b/src/core/lib/security/transport/security_connector.c @@ -127,25 +127,29 @@ void grpc_server_security_connector_shutdown( void grpc_channel_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data) { + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, + void *user_data) { if (sc == NULL || nonsecure_endpoint == NULL) { + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { - sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, deadline, cb, user_data); + sc->do_handshake(exec_ctx, sc, nonsecure_endpoint, read_buffer, deadline, + cb, user_data); } } void grpc_server_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, - gpr_timespec deadline, grpc_security_handshake_done_cb cb, - void *user_data) { + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data) { if (sc == NULL || nonsecure_endpoint == NULL) { + gpr_free(read_buffer); cb(exec_ctx, user_data, GRPC_SECURITY_ERROR, NULL, NULL); } else { - sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, deadline, cb, - user_data); + sc->do_handshake(exec_ctx, sc, acceptor, nonsecure_endpoint, read_buffer, + deadline, cb, user_data); } } @@ -312,23 +316,23 @@ static void fake_channel_check_call_host(grpc_exec_ctx *exec_ctx, static void fake_channel_do_handshake(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(1), &sc->base, - true, nonsecure_endpoint, deadline, cb, user_data); + true, nonsecure_endpoint, read_buffer, deadline, + cb, user_data); } -static void fake_server_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - gpr_timespec deadline, - grpc_security_handshake_done_cb cb, - void *user_data) { +static void fake_server_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data) { grpc_do_security_handshake(exec_ctx, tsi_create_fake_handshaker(0), &sc->base, - false, nonsecure_endpoint, deadline, cb, - user_data); + false, nonsecure_endpoint, read_buffer, deadline, + cb, user_data); } static grpc_security_connector_vtable fake_channel_vtable = { @@ -418,6 +422,7 @@ static grpc_security_status ssl_create_handshaker( static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data) { @@ -430,30 +435,32 @@ static void ssl_channel_do_handshake(grpc_exec_ctx *exec_ctx, : c->target_name, &handshaker); if (status != GRPC_SECURITY_OK) { + gpr_free(read_buffer); cb(exec_ctx, user_data, status, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, true, - nonsecure_endpoint, deadline, cb, user_data); + nonsecure_endpoint, read_buffer, deadline, cb, + user_data); } } -static void ssl_server_do_handshake(grpc_exec_ctx *exec_ctx, - grpc_server_security_connector *sc, - grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, - gpr_timespec deadline, - grpc_security_handshake_done_cb cb, - void *user_data) { +static void ssl_server_do_handshake( + grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, + grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data) { grpc_ssl_server_security_connector *c = (grpc_ssl_server_security_connector *)sc; tsi_handshaker *handshaker; grpc_security_status status = ssl_create_handshaker(c->handshaker_factory, false, NULL, &handshaker); if (status != GRPC_SECURITY_OK) { + gpr_free(read_buffer); cb(exec_ctx, user_data, status, NULL, NULL); } else { grpc_do_security_handshake(exec_ctx, handshaker, &sc->base, false, - nonsecure_endpoint, deadline, cb, user_data); + nonsecure_endpoint, read_buffer, deadline, cb, + user_data); } } diff --git a/src/core/lib/security/transport/security_connector.h b/src/core/lib/security/transport/security_connector.h index c2ddf5ee1eb..0b5b44bf1a0 100644 --- a/src/core/lib/security/transport/security_connector.h +++ b/src/core/lib/security/transport/security_connector.h @@ -143,7 +143,8 @@ struct grpc_channel_security_connector { grpc_security_call_host_check_cb cb, void *user_data); void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *sc, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, + grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); }; @@ -156,8 +157,8 @@ void grpc_channel_security_connector_check_call_host( /* Handshake. */ void grpc_channel_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_channel_security_connector *connector, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, - grpc_security_handshake_done_cb cb, void *user_data); + grpc_endpoint *nonsecure_endpoint, gpr_slice_buffer *read_buffer, + gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); /* --- server_security_connector object. --- @@ -174,14 +175,16 @@ struct grpc_server_security_connector { void (*do_handshake)(grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, - grpc_endpoint *nonsecure_endpoint, gpr_timespec deadline, + grpc_endpoint *nonsecure_endpoint, + gpr_slice_buffer *read_buffer, gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); }; void grpc_server_security_connector_do_handshake( grpc_exec_ctx *exec_ctx, grpc_server_security_connector *sc, grpc_tcp_server_acceptor *acceptor, grpc_endpoint *nonsecure_endpoint, - gpr_timespec deadline, grpc_security_handshake_done_cb cb, void *user_data); + gpr_slice_buffer *read_buffer, gpr_timespec deadline, + grpc_security_handshake_done_cb cb, void *user_data); void grpc_server_security_connector_shutdown( grpc_exec_ctx *exec_ctx, grpc_server_security_connector *connector); diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c index 12e789bde92..def16c82299 100644 --- a/src/core/lib/security/transport/server_auth_filter.c +++ b/src/core/lib/security/transport/server_auth_filter.c @@ -199,8 +199,9 @@ static void auth_start_transport_op(grpc_exec_ctx *exec_ctx, } /* Constructor for call_data */ -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { /* grab pointers to our data from the call element */ call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; @@ -222,11 +223,14 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, args->context[GRPC_CONTEXT_SECURITY].value = server_ctx; args->context[GRPC_CONTEXT_SECURITY].destroy = grpc_server_security_context_destroy; + + return GRPC_ERROR_NONE; } /* Destructor for call_data */ static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) {} + const grpc_call_final_info *final_info, + void *ignored) {} /* Constructor for channel_data */ static void init_channel_elem(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/support/log.c b/src/core/lib/support/log.c index bae0957df72..899f1218b60 100644 --- a/src/core/lib/support/log.c +++ b/src/core/lib/support/log.c @@ -79,17 +79,18 @@ void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print) { void gpr_log_verbosity_init() { char *verbosity = gpr_getenv("GRPC_VERBOSITY"); - if (verbosity == NULL) return; - gpr_atm min_severity_to_print = GPR_LOG_VERBOSITY_UNSET; - if (strcmp(verbosity, "DEBUG") == 0) { - min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG; - } else if (strcmp(verbosity, "INFO") == 0) { - min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO; - } else if (strcmp(verbosity, "ERROR") == 0) { - min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR; + gpr_atm min_severity_to_print = GPR_LOG_SEVERITY_ERROR; + if (verbosity != NULL) { + if (strcmp(verbosity, "DEBUG") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_DEBUG; + } else if (strcmp(verbosity, "INFO") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_INFO; + } else if (strcmp(verbosity, "ERROR") == 0) { + min_severity_to_print = (gpr_atm)GPR_LOG_SEVERITY_ERROR; + } + gpr_free(verbosity); } - gpr_free(verbosity); if ((gpr_atm_no_barrier_load(&g_min_severity_to_print)) == GPR_LOG_VERBOSITY_UNSET) { gpr_atm_no_barrier_store(&g_min_severity_to_print, min_severity_to_print); diff --git a/src/core/lib/support/log_linux.c b/src/core/lib/support/log_linux.c index 508fae4eec3..299b3773736 100644 --- a/src/core/lib/support/log_linux.c +++ b/src/core/lib/support/log_linux.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/src/core/lib/support/percent_encoding.c b/src/core/lib/support/percent_encoding.c new file mode 100644 index 00000000000..3c19f264f9f --- /dev/null +++ b/src/core/lib/support/percent_encoding.c @@ -0,0 +1,180 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/lib/support/percent_encoding.h" + +#include + +const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff, + 0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8] = { + 0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +static bool is_unreserved_character(uint8_t c, + const uint8_t *unreserved_bytes) { + return ((unreserved_bytes[c / 8] >> (c % 8)) & 1) != 0; +} + +gpr_slice gpr_percent_encode_slice(gpr_slice slice, + const uint8_t *unreserved_bytes) { + static const uint8_t hex[] = "0123456789ABCDEF"; + + // first pass: count the number of bytes needed to output this string + size_t output_length = 0; + const uint8_t *slice_start = GPR_SLICE_START_PTR(slice); + const uint8_t *slice_end = GPR_SLICE_END_PTR(slice); + const uint8_t *p; + bool any_reserved_bytes = false; + for (p = slice_start; p < slice_end; p++) { + bool unres = is_unreserved_character(*p, unreserved_bytes); + output_length += unres ? 1 : 3; + any_reserved_bytes |= !unres; + } + // no unreserved bytes: return the string unmodified + if (!any_reserved_bytes) { + return gpr_slice_ref(slice); + } + // second pass: actually encode + gpr_slice out = gpr_slice_malloc(output_length); + uint8_t *q = GPR_SLICE_START_PTR(out); + for (p = slice_start; p < slice_end; p++) { + if (is_unreserved_character(*p, unreserved_bytes)) { + *q++ = *p; + } else { + *q++ = '%'; + *q++ = hex[*p >> 4]; + *q++ = hex[*p & 15]; + } + } + GPR_ASSERT(q == GPR_SLICE_END_PTR(out)); + return out; +} + +static bool valid_hex(const uint8_t *p, const uint8_t *end) { + if (p >= end) return false; + return (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') || + (*p >= 'A' && *p <= 'F'); +} + +static uint8_t dehex(uint8_t c) { + if (c >= '0' && c <= '9') return (uint8_t)(c - '0'); + if (c >= 'A' && c <= 'F') return (uint8_t)(c - 'A' + 10); + if (c >= 'a' && c <= 'f') return (uint8_t)(c - 'a' + 10); + GPR_UNREACHABLE_CODE(return 255); +} + +bool gpr_strict_percent_decode_slice(gpr_slice slice_in, + const uint8_t *unreserved_bytes, + gpr_slice *slice_out) { + const uint8_t *p = GPR_SLICE_START_PTR(slice_in); + const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in); + size_t out_length = 0; + bool any_percent_encoded_stuff = false; + while (p != in_end) { + if (*p == '%') { + if (!valid_hex(++p, in_end)) return false; + if (!valid_hex(++p, in_end)) return false; + p++; + out_length++; + any_percent_encoded_stuff = true; + } else if (is_unreserved_character(*p, unreserved_bytes)) { + p++; + out_length++; + } else { + return false; + } + } + if (!any_percent_encoded_stuff) { + *slice_out = gpr_slice_ref(slice_in); + return true; + } + p = GPR_SLICE_START_PTR(slice_in); + *slice_out = gpr_slice_malloc(out_length); + uint8_t *q = GPR_SLICE_START_PTR(*slice_out); + while (p != in_end) { + if (*p == '%') { + *q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2])); + p += 3; + } else { + *q++ = *p++; + } + } + GPR_ASSERT(q == GPR_SLICE_END_PTR(*slice_out)); + return true; +} + +gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in) { + const uint8_t *p = GPR_SLICE_START_PTR(slice_in); + const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in); + size_t out_length = 0; + bool any_percent_encoded_stuff = false; + while (p != in_end) { + if (*p == '%') { + if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) { + p++; + out_length++; + } else { + p += 3; + out_length++; + any_percent_encoded_stuff = true; + } + } else { + p++; + out_length++; + } + } + if (!any_percent_encoded_stuff) { + return gpr_slice_ref(slice_in); + } + p = GPR_SLICE_START_PTR(slice_in); + gpr_slice out = gpr_slice_malloc(out_length); + uint8_t *q = GPR_SLICE_START_PTR(out); + while (p != in_end) { + if (*p == '%') { + if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) { + *q++ = *p++; + } else { + *q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2])); + p += 3; + } + } else { + *q++ = *p++; + } + } + GPR_ASSERT(q == GPR_SLICE_END_PTR(out)); + return out; +} diff --git a/src/core/lib/support/percent_encoding.h b/src/core/lib/support/percent_encoding.h new file mode 100644 index 00000000000..000bf14ede4 --- /dev/null +++ b/src/core/lib/support/percent_encoding.h @@ -0,0 +1,78 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H +#define GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H + +/* Percent encoding and decoding of slices. + Transforms arbitrary strings into safe-for-transmission strings by using + variants of percent encoding (RFC 3986). + Two major variants are supplied: one that strictly matches URL encoding, + and another which applies percent encoding only to non-http2 header + bytes (the 'compatible' variant) */ + +#include + +#include + +/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in + gpr_percent_encode_slice, gpr_strict_percent_decode_slice). + Flags [A-Za-z0-9-_.~] as unreserved bytes for the percent encoding routines + */ +extern const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8]; +/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in + gpr_percent_encode_slice, gpr_strict_percent_decode_slice). + Flags ascii7 non-control characters excluding '%' as unreserved bytes for the + percent encoding routines */ +extern const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8]; + +/* Percent-encode a slice, returning the new slice (this cannot fail): + unreserved_bytes is a bitfield indicating which bytes are considered + unreserved and thus do not need percent encoding */ +gpr_slice gpr_percent_encode_slice(gpr_slice slice, + const uint8_t *unreserved_bytes); +/* Percent-decode a slice, strictly. + If the input is legal (contains no unreserved bytes, and legal % encodings), + returns true and sets *slice_out to the decoded slice. + If the input is not legal, returns false and leaves *slice_out untouched. + unreserved_bytes is a bitfield indicating which bytes are considered + unreserved and thus do not need percent encoding */ +bool gpr_strict_percent_decode_slice(gpr_slice slice_in, + const uint8_t *unreserved_bytes, + gpr_slice *slice_out); +/* Percent-decode a slice, permissively. + If a % triplet can not be decoded, pass it through verbatim. + This cannot fail. */ +gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in); + +#endif /* GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H */ diff --git a/src/core/lib/support/slice.c b/src/core/lib/support/slice.c index b9a7c77bda6..8a2c0a90865 100644 --- a/src/core/lib/support/slice.c +++ b/src/core/lib/support/slice.c @@ -94,14 +94,16 @@ static void new_slice_unref(void *p) { } } -gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { +gpr_slice gpr_slice_new_with_user_data(void *p, size_t len, + void (*destroy)(void *), + void *user_data) { gpr_slice slice; new_slice_refcount *rc = gpr_malloc(sizeof(new_slice_refcount)); gpr_ref_init(&rc->refs, 1); rc->rc.ref = new_slice_ref; rc->rc.unref = new_slice_unref; rc->user_destroy = destroy; - rc->user_data = p; + rc->user_data = user_data; slice.refcount = &rc->rc; slice.data.refcounted.bytes = p; @@ -109,6 +111,11 @@ gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { return slice; } +gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) { + /* Pass "p" to *destroy when the slice is no longer needed. */ + return gpr_slice_new_with_user_data(p, len, destroy, p); +} + /* gpr_slice_new_with_len support structures - we create a refcount object extended with the user provided data pointer & destroy function */ typedef struct new_with_len_slice_refcount { diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c index fc9df76dc18..772681109a0 100644 --- a/src/core/lib/surface/call.c +++ b/src/core/lib/surface/call.c @@ -154,8 +154,9 @@ struct grpc_call { /* Received call statuses from various sources */ received_status status[STATUS_SOURCE_COUNT]; - /* Call stats: only valid after trailing metadata received */ - grpc_call_stats stats; + /* Call data useful used for reporting. Only valid after the call has + * completed */ + grpc_call_final_info final_info; /* Compression algorithm for *incoming* data */ grpc_compression_algorithm incoming_compression_algorithm; @@ -263,9 +264,19 @@ grpc_call *grpc_call_create( gpr_convert_clock_type(send_deadline, GPR_CLOCK_MONOTONIC); GRPC_CHANNEL_INTERNAL_REF(channel, "call"); /* initial refcount dropped by grpc_call_destroy */ - grpc_call_stack_init(&exec_ctx, channel_stack, 1, destroy_call, call, - call->context, server_transport_data, - CALL_STACK_FROM_CALL(call)); + grpc_error *error = grpc_call_stack_init( + &exec_ctx, channel_stack, 1, destroy_call, call, call->context, + server_transport_data, CALL_STACK_FROM_CALL(call)); + if (error != GRPC_ERROR_NONE) { + intptr_t status; + if (!grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &status)) + status = GRPC_STATUS_UNKNOWN; + const char *error_str = + grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); + close_with_status(&exec_ctx, call, (grpc_status_code)status, + error_str == NULL ? "unknown error" : error_str); + GRPC_ERROR_UNREF(error); + } if (cq != NULL) { GPR_ASSERT( pollset_set_alternative == NULL && @@ -361,6 +372,25 @@ void grpc_call_internal_unref(grpc_exec_ctx *exec_ctx, grpc_call *c REF_ARG) { GRPC_CALL_STACK_UNREF(exec_ctx, CALL_STACK_FROM_CALL(c), REF_REASON); } +static void get_final_status(grpc_call *call, + void (*set_value)(grpc_status_code code, + void *user_data), + void *set_value_user_data) { + int i; + for (i = 0; i < STATUS_SOURCE_COUNT; i++) { + if (call->status[i].is_set) { + set_value(call->status[i].code, set_value_user_data); + return; + } + } + if (call->is_client) { + set_value(GRPC_STATUS_UNKNOWN, set_value_user_data); + } else { + set_value(GRPC_STATUS_OK, set_value_user_data); + } +} + +static void set_status_value_directly(grpc_status_code status, void *dest); static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, grpc_error *error) { size_t i; @@ -392,7 +422,11 @@ static void destroy_call(grpc_exec_ctx *exec_ctx, void *call, GRPC_CQ_INTERNAL_UNREF(c->cq, "bind"); } grpc_channel *channel = c->channel; - grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->stats, c); + + get_final_status(call, set_status_value_directly, + &c->final_info.final_status); + + grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->final_info, c); GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call"); GPR_TIMER_END("destroy_call", 0); } @@ -414,24 +448,6 @@ static void set_status_details(grpc_call *call, status_source source, } } -static void get_final_status(grpc_call *call, - void (*set_value)(grpc_status_code code, - void *user_data), - void *set_value_user_data) { - int i; - for (i = 0; i < STATUS_SOURCE_COUNT; i++) { - if (call->status[i].is_set) { - set_value(call->status[i].code, set_value_user_data); - return; - } - } - if (call->is_client) { - set_value(GRPC_STATUS_UNKNOWN, set_value_user_data); - } else { - set_value(GRPC_STATUS_OK, set_value_user_data); - } -} - static void set_status_from_error(grpc_call *call, status_source source, grpc_error *error) { intptr_t status; @@ -1361,6 +1377,9 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, int num_completion_callbacks_needed = 1; grpc_call_error error = GRPC_CALL_OK; + // sent_initial_metadata guards against variable reuse. + grpc_metadata compression_md; + GPR_TIMER_BEGIN("grpc_call_start_batch", 0); GRPC_CALL_LOG_BATCH(GPR_INFO, call, ops, nops, notify_tag); @@ -1406,8 +1425,7 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, goto done_with_error; } /* process compression level */ - grpc_metadata compression_md; - memset(&compression_md, 0, sizeof(grpc_metadata)); + memset(&compression_md, 0, sizeof(compression_md)); size_t additional_metadata_count = 0; grpc_compression_level effective_compression_level; bool level_set = false; @@ -1608,7 +1626,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, bctl->recv_final_op = 1; stream_op.recv_trailing_metadata = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; - stream_op.collect_stats = &call->stats.transport_stream_stats; + stream_op.collect_stats = + &call->final_info.stats.transport_stream_stats; break; case GRPC_OP_RECV_CLOSE_ON_SERVER: /* Flag validation: currently allow no flags */ @@ -1630,7 +1649,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx *exec_ctx, bctl->recv_final_op = 1; stream_op.recv_trailing_metadata = &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */]; - stream_op.collect_stats = &call->stats.transport_stream_stats; + stream_op.collect_stats = + &call->final_info.stats.transport_stream_stats; break; } } diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h index 7eff7b88836..4c629743462 100644 --- a/src/core/lib/surface/channel.h +++ b/src/core/lib/surface/channel.h @@ -42,6 +42,14 @@ grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target, grpc_channel_stack_type channel_stack_type, grpc_transport *optional_transport); +/** Create a call given a grpc_channel, in order to call \a method. + Progress is tied to activity on \a pollset_set. The returned call object is + meant to be used with \a grpc_call_start_batch_and_execute, which relies on + callbacks to signal completions. \a method and \a host need + only live through the invocation of this function. If \a parent_call is + non-NULL, it must be a server-side call. It will be used to propagate + properties from the server call to this new client call, depending on the + value of \a propagation_mask (see propagation_bits.h for possible values) */ grpc_call *grpc_channel_create_pollset_set_call( grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask, grpc_pollset_set *pollset_set, const char *method, const char *host, diff --git a/src/core/lib/surface/channel_init.h b/src/core/lib/surface/channel_init.h index 3a18a61ddb8..b53f2aefb92 100644 --- a/src/core/lib/surface/channel_init.h +++ b/src/core/lib/surface/channel_init.h @@ -40,6 +40,10 @@ #define GRPC_CHANNEL_INIT_BUILTIN_PRIORITY 10000 +#ifdef __cplusplus +extern "C" { +#endif + /// This module provides a way for plugins (and the grpc core library itself) /// to register mutators for channel stacks. /// It also provides a universal entry path to run those mutators to build @@ -84,4 +88,8 @@ bool grpc_channel_init_create_stack(grpc_exec_ctx *exec_ctx, grpc_channel_stack_builder *builder, grpc_channel_stack_type type); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_INIT_H */ diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c index 5ea4cba5d1a..19b78369dda 100644 --- a/src/core/lib/surface/lame_client.c +++ b/src/core/lib/surface/lame_client.c @@ -107,11 +107,14 @@ static void lame_start_transport_op(grpc_exec_ctx *exec_ctx, GRPC_ERROR_UNREF(op->disconnect_with_error); } -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) {} +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + return GRPC_ERROR_NONE; +} static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *and_free_memory) { gpr_free(and_free_memory); } diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c index 2f108af48a1..55e6d990571 100644 --- a/src/core/lib/surface/server.c +++ b/src/core/lib/surface/server.c @@ -149,6 +149,7 @@ struct call_data { grpc_metadata_batch *recv_initial_metadata; bool recv_idempotent_request; + bool recv_cacheable_request; grpc_metadata_array initial_metadata; request_matcher *request_matcher; @@ -272,7 +273,7 @@ static void shutdown_cleanup(grpc_exec_ctx *exec_ctx, void *arg, } static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, - int send_goaway, grpc_error *send_disconnect) { + bool send_goaway, grpc_error *send_disconnect) { grpc_transport_op op; struct shutdown_cleanup_args *sc; grpc_channel_element *elem; @@ -293,7 +294,7 @@ static void send_shutdown(grpc_exec_ctx *exec_ctx, grpc_channel *channel, static void channel_broadcaster_shutdown(grpc_exec_ctx *exec_ctx, channel_broadcaster *cb, - int send_goaway, + bool send_goaway, grpc_error *force_disconnect) { size_t i; @@ -497,9 +498,12 @@ static void publish_call(grpc_exec_ctx *exec_ctx, grpc_server *server, &rc->data.batch.details->method_capacity, calld->path); rc->data.batch.details->deadline = calld->deadline; rc->data.batch.details->flags = - 0 | (calld->recv_idempotent_request - ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST - : 0); + (calld->recv_idempotent_request + ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST + : 0) | + (calld->recv_cacheable_request + ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST + : 0); break; case REGISTERED_CALL: *rc->data.registered.deadline = calld->deadline; @@ -779,6 +783,7 @@ static void server_mutate_op(grpc_call_element *elem, calld->on_done_recv_initial_metadata = op->recv_initial_metadata_ready; op->recv_initial_metadata_ready = &calld->server_on_recv_initial_metadata; op->recv_idempotent_request = &calld->recv_idempotent_request; + op->recv_cacheable_request = &calld->recv_cacheable_request; } } @@ -856,8 +861,9 @@ static void channel_connectivity_changed(grpc_exec_ctx *exec_ctx, void *cd, } } -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { call_data *calld = elem->call_data; channel_data *chand = elem->channel_data; memset(calld, 0, sizeof(call_data)); @@ -869,10 +875,12 @@ static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, server_on_recv_initial_metadata, elem); server_ref(chand->server); + return GRPC_ERROR_NONE; } static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) { + const grpc_call_final_info *final_info, + void *ignored) { channel_data *chand = elem->channel_data; call_data *calld = elem->call_data; @@ -1249,7 +1257,8 @@ void grpc_server_shutdown_and_notify(grpc_server *server, l->destroy(&exec_ctx, server, l->arg, &l->destroy_done); } - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 1, 0); + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, true /* send_goaway */, + GRPC_ERROR_NONE); done: grpc_exec_ctx_finish(&exec_ctx); @@ -1265,7 +1274,7 @@ void grpc_server_cancel_all_calls(grpc_server *server) { channel_broadcaster_init(server, &broadcaster); gpr_mu_unlock(&server->mu_global); - channel_broadcaster_shutdown(&exec_ctx, &broadcaster, 0, + channel_broadcaster_shutdown(&exec_ctx, &broadcaster, false /* send_goaway */, GRPC_ERROR_CREATE("Cancelling all calls")); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/src/core/lib/surface/version.c b/src/core/lib/surface/version.c index 19420750545..41242684da5 100644 --- a/src/core/lib/surface/version.c +++ b/src/core/lib/surface/version.c @@ -37,3 +37,5 @@ #include const char *grpc_version_string(void) { return "1.1.0-dev"; } + +const char *grpc_g_stands_for(void) { return "good"; } diff --git a/src/core/lib/transport/byte_stream.h b/src/core/lib/transport/byte_stream.h index 95519a9eaf7..e64dce62837 100644 --- a/src/core/lib/transport/byte_stream.h +++ b/src/core/lib/transport/byte_stream.h @@ -59,13 +59,9 @@ struct grpc_byte_stream { * on_complete will not be called), 0 if the bytes will be available * asynchronously. * - * on entry, *remaining can be set as a hint as to the maximum number + * max_size_hint can be set as a hint as to the maximum number * of bytes that would be acceptable to read. * - * fills *buffer, *length, *remaining with the bytes, length of bytes - * and length of data remaining to be read before either returning 1 - * or calling on_complete. - * * once a slice is returned into *slice, it is owned by the caller. */ int grpc_byte_stream_next(grpc_exec_ctx *exec_ctx, diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h index 6d82f4d6819..2b0921c8d74 100644 --- a/src/core/lib/transport/metadata.h +++ b/src/core/lib/transport/metadata.h @@ -37,6 +37,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /* This file provides a mechanism for tracking metadata through the grpc stack. It's not intended for consumption outside of the library. @@ -164,4 +168,8 @@ void grpc_mdctx_global_shutdown(void); extern gpr_slice (*grpc_chttp2_base64_encode_and_huffman_compress)( gpr_slice input); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_H */ diff --git a/src/core/lib/transport/metadata_batch.c b/src/core/lib/transport/metadata_batch.c index e4398abeb78..84b5a74d513 100644 --- a/src/core/lib/transport/metadata_batch.c +++ b/src/core/lib/transport/metadata_batch.c @@ -33,6 +33,7 @@ #include "src/core/lib/transport/metadata_batch.h" +#include #include #include @@ -187,7 +188,7 @@ void grpc_metadata_batch_clear(grpc_metadata_batch *batch) { grpc_metadata_batch_filter(batch, no_metadata_for_you, NULL); } -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { +bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch) { return batch->list.head == NULL && gpr_time_cmp(gpr_inf_future(batch->deadline.clock_type), batch->deadline) == 0; diff --git a/src/core/lib/transport/metadata_batch.h b/src/core/lib/transport/metadata_batch.h index 7af823f7ca4..0424b4db986 100644 --- a/src/core/lib/transport/metadata_batch.h +++ b/src/core/lib/transport/metadata_batch.h @@ -34,12 +34,18 @@ #ifndef GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H #define GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H +#include + #include #include #include #include #include "src/core/lib/transport/metadata.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef struct grpc_linked_mdelem { grpc_mdelem *md; struct grpc_linked_mdelem *next; @@ -64,7 +70,7 @@ typedef struct grpc_metadata_batch { void grpc_metadata_batch_init(grpc_metadata_batch *batch); void grpc_metadata_batch_destroy(grpc_metadata_batch *batch); void grpc_metadata_batch_clear(grpc_metadata_batch *batch); -int grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); +bool grpc_metadata_batch_is_empty(grpc_metadata_batch *batch); /* Returns the transport size of the batch. */ size_t grpc_metadata_batch_size(grpc_metadata_batch *batch); @@ -125,4 +131,8 @@ void grpc_metadata_batch_assert_ok(grpc_metadata_batch *comd); } while (0) #endif +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_METADATA_BATCH_H */ diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c index c5f16e530d7..fce591f3469 100644 --- a/src/core/lib/transport/static_metadata.c +++ b/src/core/lib/transport/static_metadata.c @@ -45,21 +45,21 @@ grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = { - 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, 4, 8, 6, 2, 4, 8, 6, 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, 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, 4, 8, 6, 2, 4, 8, 6, 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}; const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] = - {11, 35, 10, 35, 12, 35, 12, 49, 13, 35, 14, 35, 15, 35, 16, 35, 17, 35, - 19, 35, 20, 35, 21, 35, 24, 35, 25, 35, 26, 35, 27, 35, 28, 35, 29, 35, - 30, 18, 30, 35, 31, 35, 32, 35, 36, 35, 37, 35, 38, 35, 39, 35, 42, 33, - 42, 34, 42, 48, 42, 53, 42, 54, 42, 55, 42, 56, 43, 33, 43, 48, 43, 53, - 46, 0, 46, 1, 46, 2, 50, 35, 57, 35, 58, 35, 59, 35, 60, 35, 61, 35, - 62, 35, 63, 35, 64, 35, 65, 35, 66, 35, 67, 40, 67, 69, 67, 72, 68, 80, - 68, 81, 70, 35, 71, 35, 73, 35, 74, 35, 75, 35, 76, 35, 77, 41, 77, 51, - 77, 52, 78, 35, 79, 35, 82, 3, 82, 4, 82, 5, 82, 6, 82, 7, 82, 8, - 82, 9, 83, 35, 84, 85, 86, 35, 87, 35, 88, 35, 89, 35, 90, 35}; + {11, 33, 10, 33, 12, 33, 12, 50, 13, 33, 14, 33, 15, 33, 16, 33, 17, 33, + 19, 33, 20, 33, 21, 33, 22, 33, 23, 33, 24, 33, 25, 33, 26, 33, 27, 33, + 28, 18, 28, 33, 29, 33, 30, 33, 34, 33, 35, 33, 36, 33, 37, 33, 40, 31, + 40, 32, 40, 49, 40, 54, 40, 55, 40, 56, 40, 57, 42, 31, 42, 49, 42, 54, + 46, 0, 46, 1, 46, 2, 51, 33, 58, 33, 59, 33, 60, 33, 61, 33, 62, 33, + 63, 33, 64, 33, 65, 33, 66, 33, 67, 33, 68, 33, 69, 38, 69, 71, 69, 74, + 70, 82, 70, 83, 72, 33, 73, 33, 75, 33, 76, 33, 77, 33, 78, 33, 79, 39, + 79, 52, 79, 53, 80, 33, 81, 33, 84, 3, 84, 4, 84, 5, 84, 6, 84, 7, + 84, 8, 84, 9, 85, 33, 86, 87, 88, 33, 89, 33, 90, 33, 91, 33, 92, 33}; const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { "0", @@ -84,8 +84,6 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { ":authority", "authorization", "cache-control", - "census-bin", - "census-binary-bin", "content-disposition", "content-encoding", "content-language", @@ -105,11 +103,14 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { "GET", "grpc", "grpc-accept-encoding", + "grpc-census-bin", "grpc-encoding", "grpc-internal-encoding-request", "grpc-message", + "grpc-payload-bin", "grpc-status", "grpc-timeout", + "grpc-tracing-bin", "gzip", "gzip, deflate", "host", @@ -126,7 +127,8 @@ const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = { "if-unmodified-since", "last-modified", "link", - "load-reporting", + "load-reporting-initial", + "load-reporting-trailing", "location", "max-forwards", ":method", diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h index 5ff0d2f3bc3..54b6f38be17 100644 --- a/src/core/lib/transport/static_metadata.h +++ b/src/core/lib/transport/static_metadata.h @@ -44,7 +44,7 @@ #include "src/core/lib/transport/metadata.h" -#define GRPC_STATIC_MDSTR_COUNT 91 +#define GRPC_STATIC_MDSTR_COUNT 93 extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; /* "0" */ #define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0]) @@ -90,147 +90,151 @@ extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT]; #define GRPC_MDSTR_AUTHORIZATION (&grpc_static_mdstr_table[20]) /* "cache-control" */ #define GRPC_MDSTR_CACHE_CONTROL (&grpc_static_mdstr_table[21]) -/* "census-bin" */ -#define GRPC_MDSTR_CENSUS_BIN (&grpc_static_mdstr_table[22]) -/* "census-binary-bin" */ -#define GRPC_MDSTR_CENSUS_BINARY_BIN (&grpc_static_mdstr_table[23]) /* "content-disposition" */ -#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[24]) +#define GRPC_MDSTR_CONTENT_DISPOSITION (&grpc_static_mdstr_table[22]) /* "content-encoding" */ -#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[25]) +#define GRPC_MDSTR_CONTENT_ENCODING (&grpc_static_mdstr_table[23]) /* "content-language" */ -#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[26]) +#define GRPC_MDSTR_CONTENT_LANGUAGE (&grpc_static_mdstr_table[24]) /* "content-length" */ -#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[27]) +#define GRPC_MDSTR_CONTENT_LENGTH (&grpc_static_mdstr_table[25]) /* "content-location" */ -#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[28]) +#define GRPC_MDSTR_CONTENT_LOCATION (&grpc_static_mdstr_table[26]) /* "content-range" */ -#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[29]) +#define GRPC_MDSTR_CONTENT_RANGE (&grpc_static_mdstr_table[27]) /* "content-type" */ -#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[30]) +#define GRPC_MDSTR_CONTENT_TYPE (&grpc_static_mdstr_table[28]) /* "cookie" */ -#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[31]) +#define GRPC_MDSTR_COOKIE (&grpc_static_mdstr_table[29]) /* "date" */ -#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[32]) +#define GRPC_MDSTR_DATE (&grpc_static_mdstr_table[30]) /* "deflate" */ -#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[33]) +#define GRPC_MDSTR_DEFLATE (&grpc_static_mdstr_table[31]) /* "deflate,gzip" */ -#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[34]) +#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (&grpc_static_mdstr_table[32]) /* "" */ -#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[35]) +#define GRPC_MDSTR_EMPTY (&grpc_static_mdstr_table[33]) /* "etag" */ -#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[36]) +#define GRPC_MDSTR_ETAG (&grpc_static_mdstr_table[34]) /* "expect" */ -#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[37]) +#define GRPC_MDSTR_EXPECT (&grpc_static_mdstr_table[35]) /* "expires" */ -#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[38]) +#define GRPC_MDSTR_EXPIRES (&grpc_static_mdstr_table[36]) /* "from" */ -#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[39]) +#define GRPC_MDSTR_FROM (&grpc_static_mdstr_table[37]) /* "GET" */ -#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[40]) +#define GRPC_MDSTR_GET (&grpc_static_mdstr_table[38]) /* "grpc" */ -#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[41]) +#define GRPC_MDSTR_GRPC (&grpc_static_mdstr_table[39]) /* "grpc-accept-encoding" */ -#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[42]) +#define GRPC_MDSTR_GRPC_ACCEPT_ENCODING (&grpc_static_mdstr_table[40]) +/* "grpc-census-bin" */ +#define GRPC_MDSTR_GRPC_CENSUS_BIN (&grpc_static_mdstr_table[41]) /* "grpc-encoding" */ -#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[43]) +#define GRPC_MDSTR_GRPC_ENCODING (&grpc_static_mdstr_table[42]) /* "grpc-internal-encoding-request" */ -#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[44]) +#define GRPC_MDSTR_GRPC_INTERNAL_ENCODING_REQUEST (&grpc_static_mdstr_table[43]) /* "grpc-message" */ -#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[45]) +#define GRPC_MDSTR_GRPC_MESSAGE (&grpc_static_mdstr_table[44]) +/* "grpc-payload-bin" */ +#define GRPC_MDSTR_GRPC_PAYLOAD_BIN (&grpc_static_mdstr_table[45]) /* "grpc-status" */ #define GRPC_MDSTR_GRPC_STATUS (&grpc_static_mdstr_table[46]) /* "grpc-timeout" */ #define GRPC_MDSTR_GRPC_TIMEOUT (&grpc_static_mdstr_table[47]) +/* "grpc-tracing-bin" */ +#define GRPC_MDSTR_GRPC_TRACING_BIN (&grpc_static_mdstr_table[48]) /* "gzip" */ -#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[48]) +#define GRPC_MDSTR_GZIP (&grpc_static_mdstr_table[49]) /* "gzip, deflate" */ -#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[49]) +#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (&grpc_static_mdstr_table[50]) /* "host" */ -#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[50]) +#define GRPC_MDSTR_HOST (&grpc_static_mdstr_table[51]) /* "http" */ -#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[51]) +#define GRPC_MDSTR_HTTP (&grpc_static_mdstr_table[52]) /* "https" */ -#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[52]) +#define GRPC_MDSTR_HTTPS (&grpc_static_mdstr_table[53]) /* "identity" */ -#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[53]) +#define GRPC_MDSTR_IDENTITY (&grpc_static_mdstr_table[54]) /* "identity,deflate" */ -#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[54]) +#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (&grpc_static_mdstr_table[55]) /* "identity,deflate,gzip" */ #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \ - (&grpc_static_mdstr_table[55]) + (&grpc_static_mdstr_table[56]) /* "identity,gzip" */ -#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[56]) +#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (&grpc_static_mdstr_table[57]) /* "if-match" */ -#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[57]) +#define GRPC_MDSTR_IF_MATCH (&grpc_static_mdstr_table[58]) /* "if-modified-since" */ -#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[58]) +#define GRPC_MDSTR_IF_MODIFIED_SINCE (&grpc_static_mdstr_table[59]) /* "if-none-match" */ -#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[59]) +#define GRPC_MDSTR_IF_NONE_MATCH (&grpc_static_mdstr_table[60]) /* "if-range" */ -#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[60]) +#define GRPC_MDSTR_IF_RANGE (&grpc_static_mdstr_table[61]) /* "if-unmodified-since" */ -#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[61]) +#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (&grpc_static_mdstr_table[62]) /* "last-modified" */ -#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62]) +#define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[63]) /* "link" */ -#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63]) -/* "load-reporting" */ -#define GRPC_MDSTR_LOAD_REPORTING (&grpc_static_mdstr_table[64]) +#define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[64]) +/* "load-reporting-initial" */ +#define GRPC_MDSTR_LOAD_REPORTING_INITIAL (&grpc_static_mdstr_table[65]) +/* "load-reporting-trailing" */ +#define GRPC_MDSTR_LOAD_REPORTING_TRAILING (&grpc_static_mdstr_table[66]) /* "location" */ -#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[65]) +#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[67]) /* "max-forwards" */ -#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[66]) +#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[68]) /* ":method" */ -#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[67]) +#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[69]) /* ":path" */ -#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[68]) +#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[70]) /* "POST" */ -#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[69]) +#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[71]) /* "proxy-authenticate" */ -#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[70]) +#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[72]) /* "proxy-authorization" */ -#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[71]) +#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[73]) /* "PUT" */ -#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[72]) +#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[74]) /* "range" */ -#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[73]) +#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[75]) /* "referer" */ -#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[74]) +#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[76]) /* "refresh" */ -#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[75]) +#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[77]) /* "retry-after" */ -#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[76]) +#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[78]) /* ":scheme" */ -#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[77]) +#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[79]) /* "server" */ -#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[78]) +#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[80]) /* "set-cookie" */ -#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[79]) +#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[81]) /* "/" */ -#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[80]) +#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[82]) /* "/index.html" */ -#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[81]) +#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[83]) /* ":status" */ -#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[82]) +#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[84]) /* "strict-transport-security" */ -#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[83]) +#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[85]) /* "te" */ -#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[84]) +#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[86]) /* "trailers" */ -#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[85]) +#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[87]) /* "transfer-encoding" */ -#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[86]) +#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[88]) /* "user-agent" */ -#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[87]) +#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[89]) /* "vary" */ -#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[88]) +#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[90]) /* "via" */ -#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[89]) +#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[91]) /* "www-authenticate" */ -#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[90]) +#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[92]) -#define GRPC_STATIC_MDELEM_COUNT 80 +#define GRPC_STATIC_MDELEM_COUNT 81 extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT]; extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; /* "accept-charset": "" */ @@ -335,73 +339,76 @@ extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT]; #define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45]) /* "link": "" */ #define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46]) -/* "load-reporting": "" */ -#define GRPC_MDELEM_LOAD_REPORTING_EMPTY (&grpc_static_mdelem_table[47]) +/* "load-reporting-initial": "" */ +#define GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY (&grpc_static_mdelem_table[47]) +/* "load-reporting-trailing": "" */ +#define GRPC_MDELEM_LOAD_REPORTING_TRAILING_EMPTY \ + (&grpc_static_mdelem_table[48]) /* "location": "" */ -#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[48]) +#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[49]) /* "max-forwards": "" */ -#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[49]) +#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[50]) /* ":method": "GET" */ -#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[50]) +#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[51]) /* ":method": "POST" */ -#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[51]) +#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[52]) /* ":method": "PUT" */ -#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[52]) +#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[53]) /* ":path": "/" */ -#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[53]) +#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[54]) /* ":path": "/index.html" */ -#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[54]) +#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[55]) /* "proxy-authenticate": "" */ -#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[55]) +#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[56]) /* "proxy-authorization": "" */ -#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[56]) +#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[57]) /* "range": "" */ -#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[57]) +#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[58]) /* "referer": "" */ -#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[58]) +#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[59]) /* "refresh": "" */ -#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[59]) +#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[60]) /* "retry-after": "" */ -#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[60]) +#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[61]) /* ":scheme": "grpc" */ -#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[61]) +#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[62]) /* ":scheme": "http" */ -#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[62]) +#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[63]) /* ":scheme": "https" */ -#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[63]) +#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[64]) /* "server": "" */ -#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[64]) +#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[65]) /* "set-cookie": "" */ -#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[65]) +#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[66]) /* ":status": "200" */ -#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[66]) +#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[67]) /* ":status": "204" */ -#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[67]) +#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[68]) /* ":status": "206" */ -#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[68]) +#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[69]) /* ":status": "304" */ -#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[69]) +#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[70]) /* ":status": "400" */ -#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[70]) +#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[71]) /* ":status": "404" */ -#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[71]) +#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[72]) /* ":status": "500" */ -#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[72]) +#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[73]) /* "strict-transport-security": "" */ #define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \ - (&grpc_static_mdelem_table[73]) + (&grpc_static_mdelem_table[74]) /* "te": "trailers" */ -#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[74]) +#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[75]) /* "transfer-encoding": "" */ -#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[75]) +#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[76]) /* "user-agent": "" */ -#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[76]) +#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[77]) /* "vary": "" */ -#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[77]) +#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[78]) /* "via": "" */ -#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[78]) +#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[79]) /* "www-authenticate": "" */ -#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[79]) +#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[80]) extern const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2]; diff --git a/src/core/ext/transport/chttp2/transport/timeout_encoding.c b/src/core/lib/transport/timeout_encoding.c similarity index 96% rename from src/core/ext/transport/chttp2/transport/timeout_encoding.c rename to src/core/lib/transport/timeout_encoding.c index b7f79124939..b58ebbd0a8f 100644 --- a/src/core/ext/transport/chttp2/transport/timeout_encoding.c +++ b/src/core/lib/transport/timeout_encoding.c @@ -31,7 +31,7 @@ * */ -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" +#include "src/core/lib/transport/timeout_encoding.h" #include #include @@ -117,7 +117,7 @@ static void enc_micros(char *buffer, int64_t x) { } } -void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer) { +void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer) { if (timeout.tv_sec < 0) { enc_tiny(buffer); } else if (timeout.tv_sec == 0) { @@ -136,7 +136,7 @@ static int is_all_whitespace(const char *p) { return *p == 0; } -int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout) { +int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout) { int32_t x = 0; const uint8_t *p = (const uint8_t *)buffer; int have_digit = 0; diff --git a/src/core/ext/transport/chttp2/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h similarity index 77% rename from src/core/ext/transport/chttp2/transport/timeout_encoding.h rename to src/core/lib/transport/timeout_encoding.h index df2324c7912..92f02f6ecd1 100644 --- a/src/core/ext/transport/chttp2/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -31,17 +31,17 @@ * */ -#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TIMEOUT_ENCODING_H -#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TIMEOUT_ENCODING_H +#ifndef GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H +#define GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H #include #include "src/core/lib/support/string.h" -#define GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) +#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) -/* Encode/decode timeouts to the GRPC over HTTP2 format; +/* Encode/decode timeouts to the GRPC over HTTP/2 format; encoding may round up arbitrarily */ -void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer); -int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout); +void grpc_http2_encode_timeout(gpr_timespec timeout, char *buffer); +int grpc_http2_decode_timeout(const char *buffer, gpr_timespec *timeout); -#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_TIMEOUT_ENCODING_H */ +#endif /* GRPC_CORE_LIB_TRANSPORT_TIMEOUT_ENCODING_H */ diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h index 08c0a237c97..26ed6cb839e 100644 --- a/src/core/lib/transport/transport.h +++ b/src/core/lib/transport/transport.h @@ -43,6 +43,10 @@ #include "src/core/lib/transport/byte_stream.h" #include "src/core/lib/transport/metadata_batch.h" +#ifdef __cplusplus +extern "C" { +#endif + /* forward declarations */ typedef struct grpc_transport grpc_transport; @@ -120,6 +124,7 @@ typedef struct grpc_transport_stream_op { /** Receive initial metadata from the stream, into provided metadata batch. */ grpc_metadata_batch *recv_initial_metadata; bool *recv_idempotent_request; + bool *recv_cacheable_request; /** Should be enqueued when initial metadata is ready to be processed. */ grpc_closure *recv_initial_metadata_ready; @@ -138,7 +143,7 @@ typedef struct grpc_transport_stream_op { /** If != GRPC_ERROR_NONE, cancel this stream */ grpc_error *cancel_error; - /** If != GRPC_ERROR, send grpc-status, grpc-message, and close this + /** If != GRPC_ERROR_NONE, send grpc-status, grpc-message, and close this stream for both reading and writing */ grpc_error *close_error; @@ -158,7 +163,7 @@ typedef struct grpc_transport_op { /** should we send a goaway? after a goaway is sent, once there are no more active calls on the transport, the transport should disconnect */ - int send_goaway; + bool send_goaway; /** what should the goaway contain? */ grpc_status_code goaway_status; gpr_slice *goaway_message; @@ -268,4 +273,8 @@ void grpc_transport_destroy(grpc_exec_ctx *exec_ctx, grpc_transport *transport); char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *transport); +#ifdef __cplusplus +} +#endif + #endif /* GRPC_CORE_LIB_TRANSPORT_TRANSPORT_H */ diff --git a/src/core/plugin_registry/grpc_plugin_registry.c b/src/core/plugin_registry/grpc_plugin_registry.c index 905cd59e23d..7a7a9ce477a 100644 --- a/src/core/plugin_registry/grpc_plugin_registry.c +++ b/src/core/plugin_registry/grpc_plugin_registry.c @@ -37,6 +37,8 @@ extern void grpc_chttp2_plugin_init(void); extern void grpc_chttp2_plugin_shutdown(void); extern void grpc_client_config_init(void); extern void grpc_client_config_shutdown(void); +extern void grpc_lb_policy_grpclb_init(void); +extern void grpc_lb_policy_grpclb_shutdown(void); extern void grpc_lb_policy_pick_first_init(void); extern void grpc_lb_policy_pick_first_shutdown(void); extern void grpc_lb_policy_round_robin_init(void); @@ -55,6 +57,8 @@ void grpc_register_built_in_plugins(void) { grpc_chttp2_plugin_shutdown); grpc_register_plugin(grpc_client_config_init, grpc_client_config_shutdown); + grpc_register_plugin(grpc_lb_policy_grpclb_init, + grpc_lb_policy_grpclb_shutdown); grpc_register_plugin(grpc_lb_policy_pick_first_init, grpc_lb_policy_pick_first_shutdown); grpc_register_plugin(grpc_lb_policy_round_robin_init, diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c index 79950787258..ad4ddf0ff48 100644 --- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c +++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c @@ -43,6 +43,8 @@ extern void grpc_resolver_sockaddr_init(void); extern void grpc_resolver_sockaddr_shutdown(void); extern void grpc_load_reporting_plugin_init(void); extern void grpc_load_reporting_plugin_shutdown(void); +extern void grpc_lb_policy_grpclb_init(void); +extern void grpc_lb_policy_grpclb_shutdown(void); extern void grpc_lb_policy_pick_first_init(void); extern void grpc_lb_policy_pick_first_shutdown(void); extern void grpc_lb_policy_round_robin_init(void); @@ -61,6 +63,8 @@ void grpc_register_built_in_plugins(void) { grpc_resolver_sockaddr_shutdown); grpc_register_plugin(grpc_load_reporting_plugin_init, grpc_load_reporting_plugin_shutdown); + grpc_register_plugin(grpc_lb_policy_grpclb_init, + grpc_lb_policy_grpclb_shutdown); grpc_register_plugin(grpc_lb_policy_pick_first_init, grpc_lb_policy_pick_first_shutdown); grpc_register_plugin(grpc_lb_policy_round_robin_init, diff --git a/src/cpp/common/channel_filter.cc b/src/cpp/common/channel_filter.cc new file mode 100644 index 00000000000..25cd49cb7c9 --- /dev/null +++ b/src/cpp/common/channel_filter.cc @@ -0,0 +1,112 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include "src/core/lib/channel/channel_stack.h" +#include "src/cpp/common/channel_filter.h" + +namespace grpc { + +// MetadataBatch + +grpc_linked_mdelem *MetadataBatch::AddMetadata(const string &key, + const string &value) { + grpc_linked_mdelem *storage = new grpc_linked_mdelem; + memset(storage, 0, sizeof(grpc_linked_mdelem)); + storage->md = grpc_mdelem_from_strings(key.c_str(), value.c_str()); + grpc_metadata_batch_link_head(batch_, storage); + return storage; +} + +// ChannelData + +void ChannelData::StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + TransportOp *op) { + grpc_channel_next_op(exec_ctx, elem, op->op()); +} + +// CallData + +void CallData::StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + TransportStreamOp *op) { + grpc_call_next_op(exec_ctx, elem, op->op()); +} + +void CallData::SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { + grpc_call_stack_ignore_set_pollset_or_pollset_set(exec_ctx, elem, pollent); +} + +char *CallData::GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + return grpc_call_next_get_peer(exec_ctx, elem); +} + +// internal code used by RegisterChannelFilter() + +namespace internal { + +// Note: Implicitly initialized to nullptr due to static lifetime. +std::vector *channel_filters; + +namespace { + +bool MaybeAddFilter(grpc_channel_stack_builder *builder, void *arg) { + const FilterRecord &filter = *(FilterRecord *)arg; + if (filter.include_filter) { + const grpc_channel_args *args = + grpc_channel_stack_builder_get_channel_arguments(builder); + if (!filter.include_filter(*args)) return true; + } + return grpc_channel_stack_builder_prepend_filter(builder, &filter.filter, + nullptr, nullptr); +} + +} // namespace + +void ChannelFilterPluginInit() { + for (size_t i = 0; i < channel_filters->size(); ++i) { + FilterRecord &filter = (*channel_filters)[i]; + grpc_channel_init_register_stage(filter.stack_type, filter.priority, + MaybeAddFilter, (void *)&filter); + } +} + +void ChannelFilterPluginShutdown() {} + +} // namespace internal + +} // namespace grpc diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h new file mode 100644 index 00000000000..ec2af63afd6 --- /dev/null +++ b/src/cpp/common/channel_filter.h @@ -0,0 +1,389 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_CHANNEL_FILTER_H +#define GRPCXX_CHANNEL_FILTER_H + +#include +#include +#include + +#include +#include + +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/surface/channel_init.h" +#include "src/core/lib/transport/metadata_batch.h" + +/// An interface to define filters. +/// +/// To define a filter, implement a subclass of each of \c CallData and +/// \c ChannelData. Then register the filter using something like this: +/// \code{.cpp} +/// RegisterChannelFilter( +/// "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); +/// \endcode + +/// Forward declaration to avoid including the file +/// "src/core/lib/security/context/security_context.h" +struct grpc_client_security_context; +struct grpc_server_security_context; + +namespace grpc { + +/// A C++ wrapper for the \c grpc_metadata_batch struct. +class MetadataBatch { + public: + /// Borrows a pointer to \a batch, but does NOT take ownership. + /// The caller must ensure that \a batch continues to exist for as + /// long as the MetadataBatch object does. + explicit MetadataBatch(grpc_metadata_batch *batch) : batch_(batch) {} + + grpc_metadata_batch *batch() const { return batch_; } + + /// Adds metadata and returns the newly allocated storage. + /// The caller takes ownership of the result, which must exist for the + /// lifetime of the gRPC call. + grpc_linked_mdelem *AddMetadata(const string &key, const string &value); + + class const_iterator : public std::iterator { + public: + const grpc_mdelem &operator*() const { return *elem_->md; } + const grpc_mdelem *operator->() const { return elem_->md; } + + const_iterator &operator++() { + elem_ = elem_->next; + return *this; + } + const_iterator operator++(int) { + const_iterator tmp(*this); + operator++(); + return tmp; + } + const_iterator &operator--() { + elem_ = elem_->prev; + return *this; + } + const_iterator operator--(int) { + const_iterator tmp(*this); + operator--(); + return tmp; + } + + bool operator==(const const_iterator &other) const { + return elem_ == other.elem_; + } + bool operator!=(const const_iterator &other) const { + return elem_ != other.elem_; + } + + private: + friend class MetadataBatch; + explicit const_iterator(grpc_linked_mdelem *elem) : elem_(elem) {} + + grpc_linked_mdelem *elem_; + }; + + const_iterator begin() const { return const_iterator(batch_->list.head); } + const_iterator end() const { return const_iterator(nullptr); } + + private: + grpc_metadata_batch *batch_; // Not owned. +}; + +/// A C++ wrapper for the \c grpc_transport_op struct. +class TransportOp { + public: + /// Borrows a pointer to \a op, but does NOT take ownership. + /// The caller must ensure that \a op continues to exist for as + /// long as the TransportOp object does. + explicit TransportOp(grpc_transport_op *op) : op_(op) {} + + grpc_transport_op *op() const { return op_; } + + // TODO(roth): Add a C++ wrapper for grpc_error? + grpc_error *disconnect_with_error() const { + return op_->disconnect_with_error; + } + bool send_goaway() const { return op_->send_goaway; } + + // TODO(roth): Add methods for additional fields as needed. + + private: + grpc_transport_op *op_; // Not owned. +}; + +/// A C++ wrapper for the \c grpc_transport_stream_op struct. +class TransportStreamOp { + public: + /// Borrows a pointer to \a op, but does NOT take ownership. + /// The caller must ensure that \a op continues to exist for as + /// long as the TransportStreamOp object does. + explicit TransportStreamOp(grpc_transport_stream_op *op) + : op_(op), + send_initial_metadata_(op->send_initial_metadata), + send_trailing_metadata_(op->send_trailing_metadata), + recv_initial_metadata_(op->recv_initial_metadata), + recv_trailing_metadata_(op->recv_trailing_metadata) {} + + grpc_transport_stream_op *op() const { return op_; } + + grpc_closure *on_complete() const { return op_->on_complete; } + void set_on_complete(grpc_closure *closure) { op_->on_complete = closure; } + + MetadataBatch *send_initial_metadata() { + return op_->send_initial_metadata == nullptr ? nullptr + : &send_initial_metadata_; + } + MetadataBatch *send_trailing_metadata() { + return op_->send_trailing_metadata == nullptr ? nullptr + : &send_trailing_metadata_; + } + MetadataBatch *recv_initial_metadata() { + return op_->recv_initial_metadata == nullptr ? nullptr + : &recv_initial_metadata_; + } + MetadataBatch *recv_trailing_metadata() { + return op_->recv_trailing_metadata == nullptr ? nullptr + : &recv_trailing_metadata_; + } + + uint32_t *send_initial_metadata_flags() const { + return &op_->send_initial_metadata_flags; + } + + grpc_closure *recv_initial_metadata_ready() const { + return op_->recv_initial_metadata_ready; + } + void set_recv_initial_metadata_ready(grpc_closure *closure) { + op_->recv_initial_metadata_ready = closure; + } + + grpc_byte_stream *send_message() const { return op_->send_message; } + void set_send_message(grpc_byte_stream *send_message) { + op_->send_message = send_message; + } + + /// To be called only on clients and servers, respectively. + grpc_client_security_context *client_security_context() const { + return (grpc_client_security_context *)op_->context[GRPC_CONTEXT_SECURITY] + .value; + } + grpc_server_security_context *server_security_context() const { + return (grpc_server_security_context *)op_->context[GRPC_CONTEXT_SECURITY] + .value; + } + + census_context *get_census_context() const { + return (census_context *)op_->context[GRPC_CONTEXT_TRACING].value; + } + + private: + grpc_transport_stream_op *op_; // Not owned. + MetadataBatch send_initial_metadata_; + MetadataBatch send_trailing_metadata_; + MetadataBatch recv_initial_metadata_; + MetadataBatch recv_trailing_metadata_; +}; + +/// Represents channel data. +class ChannelData { + public: + virtual ~ChannelData() { + if (peer_) gpr_free((void *)peer_); + } + + /// Caller does NOT take ownership of result. + const char *peer() const { return peer_; } + + // TODO(roth): Find a way to avoid passing elem into these methods. + virtual void StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, TransportOp *op); + + protected: + /// Takes ownership of \a peer. + ChannelData(const grpc_channel_args &args, const char *peer) : peer_(peer) {} + + private: + const char *peer_; +}; + +/// Represents call data. +class CallData { + public: + virtual ~CallData() {} + + /// Initializes the call data. + virtual grpc_error *Init() { return GRPC_ERROR_NONE; } + + // TODO(roth): Find a way to avoid passing elem into these methods. + + /// Starts a new stream operation. + virtual void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + TransportStreamOp *op); + + /// Sets a pollset or pollset set. + virtual void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent); + + /// Gets the peer name. + virtual char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem); + + protected: + explicit CallData(const ChannelData &) {} +}; + +namespace internal { + +// Defines static members for passing to C core. +// Members of this class correspond to the members of the C +// grpc_channel_filter struct. +template +class ChannelFilter GRPC_FINAL { + public: + static const size_t channel_data_size = sizeof(ChannelDataType); + + static void InitChannelElement(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) { + const char *peer = + args->optional_transport + ? grpc_transport_get_peer(exec_ctx, args->optional_transport) + : nullptr; + // Construct the object in the already-allocated memory. + new (elem->channel_data) ChannelDataType(*args->channel_args, peer); + } + + static void DestroyChannelElement(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) { + reinterpret_cast(elem->channel_data)->~ChannelDataType(); + } + + static void StartTransportOp(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_transport_op *op) { + ChannelDataType *channel_data = (ChannelDataType *)elem->channel_data; + TransportOp op_wrapper(op); + channel_data->StartTransportOp(exec_ctx, elem, &op_wrapper); + } + + static const size_t call_data_size = sizeof(CallDataType); + + static grpc_error *InitCallElement(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + const ChannelDataType &channel_data = + *(ChannelDataType *)elem->channel_data; + // Construct the object in the already-allocated memory. + CallDataType *call_data = new (elem->call_data) CallDataType(channel_data); + return call_data->Init(); + } + + static void DestroyCallElement(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + const grpc_call_final_info *final_info, + void *and_free_memory) { + reinterpret_cast(elem->call_data)->~CallDataType(); + } + + static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_transport_stream_op *op) { + CallDataType *call_data = (CallDataType *)elem->call_data; + TransportStreamOp op_wrapper(op); + call_data->StartTransportStreamOp(exec_ctx, elem, &op_wrapper); + } + + static void SetPollsetOrPollsetSet(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_polling_entity *pollent) { + CallDataType *call_data = (CallDataType *)elem->call_data; + call_data->SetPollsetOrPollsetSet(exec_ctx, elem, pollent); + } + + static char *GetPeer(grpc_exec_ctx *exec_ctx, grpc_call_element *elem) { + CallDataType *call_data = (CallDataType *)elem->call_data; + return call_data->GetPeer(exec_ctx, elem); + } +}; + +struct FilterRecord { + grpc_channel_stack_type stack_type; + int priority; + std::function include_filter; + grpc_channel_filter filter; +}; +extern std::vector *channel_filters; + +void ChannelFilterPluginInit(); +void ChannelFilterPluginShutdown(); + +} // namespace internal + +/// Registers a new filter. +/// Must be called by only one thread at a time. +/// The \a include_filter argument specifies a function that will be called +/// to determine at run-time whether or not to add the filter. If the +/// value is nullptr, the filter will be added unconditionally. +template +void RegisterChannelFilter( + const char *name, grpc_channel_stack_type stack_type, int priority, + std::function include_filter) { + // If we haven't been called before, initialize channel_filters and + // call grpc_register_plugin(). + if (internal::channel_filters == nullptr) { + grpc_register_plugin(internal::ChannelFilterPluginInit, + internal::ChannelFilterPluginShutdown); + internal::channel_filters = new std::vector(); + } + // Add an entry to channel_filters. The filter will be added when the + // C-core initialization code calls ChannelFilterPluginInit(). + typedef internal::ChannelFilter FilterType; + internal::FilterRecord filter_record = { + stack_type, + priority, + include_filter, + {FilterType::StartTransportStreamOp, FilterType::StartTransportOp, + FilterType::call_data_size, FilterType::InitCallElement, + FilterType::SetPollsetOrPollsetSet, FilterType::DestroyCallElement, + FilterType::channel_data_size, FilterType::InitChannelElement, + FilterType::DestroyChannelElement, FilterType::GetPeer, name}}; + internal::channel_filters->push_back(filter_record); +} + +} // namespace grpc + +#endif // GRPCXX_CHANNEL_FILTER_H diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h index 23c130513d1..f66f3c2c9ae 100644 --- a/src/cpp/ext/proto_server_reflection.h +++ b/src/cpp/ext/proto_server_reflection.h @@ -30,13 +30,31 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ + +/* + - If the generated header `grpc++/ext/reflection.grpc.pb.h` needs to be + installed, target `grpc++_reflection` in `build.yaml` should use the + filegroup `grpc++_reflection_proto`, and GRPC_NO_GENERATED_CODE should not + be defined. + - If the server reflection library needs to generate `reflection.grpc.pb.h` + from `reflection.proto` at compile time, the generated header + `grpc++/ext/reflection.grpc.pb.h` should not be installed. In this case, + target `grpc++_reflection` should depend on `grpc++_reflection_codegen`, and + GRPC_NO_GENERATED_CODE should be defined. +*/ + #ifndef GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H #define GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H #include #include +// GRPC_NO_GENERATED_CODE indicates generated pb files should not be used +#ifdef GRPC_NO_GENERATED_CODE +#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" +#else #include +#endif // GRPC_NO_GENERATED_CODE #include namespace grpc { diff --git a/src/cpp/ext/reflection.pb.cc b/src/cpp/ext/reflection.pb.cc index b73a65d0a02..a84494f9a98 100644 --- a/src/cpp/ext/reflection.pb.cc +++ b/src/cpp/ext/reflection.pb.cc @@ -98,6 +98,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection* } // namespace +void protobuf_AssignDesc_reflection_2eproto() GOOGLE_ATTRIBUTE_COLD; void protobuf_AssignDesc_reflection_2eproto() { protobuf_AddDesc_reflection_2eproto(); const ::google::protobuf::FileDescriptor* file = @@ -253,6 +254,7 @@ inline void protobuf_AssignDescriptorsOnce() { &protobuf_AssignDesc_reflection_2eproto); } +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( @@ -296,6 +298,7 @@ void protobuf_ShutdownFile_reflection_2eproto() { delete ErrorResponse_reflection_; } +void protobuf_AddDesc_reflection_2eproto() GOOGLE_ATTRIBUTE_COLD; void protobuf_AddDesc_reflection_2eproto() { static bool already_here = false; if (already_here) return; @@ -366,16 +369,6 @@ struct StaticDescriptorInitializer_reflection_2eproto { } } static_descriptor_initializer_reflection_2eproto_; -namespace { - -static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD; -static void MergeFromFail(int line) { - GOOGLE_CHECK(false) << __FILE__ << ":" << line; -} - -} // namespace - - // =================================================================== #if !defined(_MSC_VER) || _MSC_VER >= 1900 @@ -684,8 +677,8 @@ void ServerReflectionRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionRequest) } -::google::protobuf::uint8* ServerReflectionRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServerReflectionRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionRequest) // optional string host = 1; if (this->host().size() > 0) { @@ -723,8 +716,8 @@ void ServerReflectionRequest::SerializeWithCachedSizes( // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5; if (has_file_containing_extension()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *message_request_.file_containing_extension_, target); + InternalWriteMessageNoVirtualToArray( + 5, *message_request_.file_containing_extension_, false, target); } // optional string all_extension_numbers_of_type = 6; @@ -812,7 +805,9 @@ int ServerReflectionRequest::ByteSize() const { void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServerReflectionRequest* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -827,7 +822,9 @@ void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) void ServerReflectionRequest::MergeFrom(const ServerReflectionRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } switch (from.message_request_case()) { case kFileByFilename: { set_file_by_filename(from.file_by_filename()); @@ -1486,8 +1483,8 @@ void ExtensionRequest::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionRequest) } -::google::protobuf::uint8* ExtensionRequest::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ExtensionRequest::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionRequest) // optional string containing_type = 1; if (this->containing_type().size() > 0) { @@ -1535,7 +1532,9 @@ int ExtensionRequest::ByteSize() const { void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ExtensionRequest* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -1550,7 +1549,9 @@ void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) { void ExtensionRequest::MergeFrom(const ExtensionRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.containing_type().size() > 0) { containing_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.containing_type_); @@ -1937,8 +1938,8 @@ void ServerReflectionResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionResponse) } -::google::protobuf::uint8* ServerReflectionResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServerReflectionResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionResponse) // optional string valid_host = 1; if (this->valid_host().size() > 0) { @@ -1954,36 +1955,36 @@ void ServerReflectionResponse::SerializeWithCachedSizes( // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2; if (this->has_original_request()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 2, *this->original_request_, target); + InternalWriteMessageNoVirtualToArray( + 2, *this->original_request_, false, target); } // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4; if (has_file_descriptor_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 4, *message_response_.file_descriptor_response_, target); + InternalWriteMessageNoVirtualToArray( + 4, *message_response_.file_descriptor_response_, false, target); } // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5; if (has_all_extension_numbers_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 5, *message_response_.all_extension_numbers_response_, target); + InternalWriteMessageNoVirtualToArray( + 5, *message_response_.all_extension_numbers_response_, false, target); } // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6; if (has_list_services_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 6, *message_response_.list_services_response_, target); + InternalWriteMessageNoVirtualToArray( + 6, *message_response_.list_services_response_, false, target); } // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7; if (has_error_response()) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 7, *message_response_.error_response_, target); + InternalWriteMessageNoVirtualToArray( + 7, *message_response_.error_response_, false, target); } // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ServerReflectionResponse) @@ -2049,7 +2050,9 @@ int ServerReflectionResponse::ByteSize() const { void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServerReflectionResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2064,7 +2067,9 @@ void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from void ServerReflectionResponse::MergeFrom(const ServerReflectionResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } switch (from.message_response_case()) { case kFileDescriptorResponse: { mutable_file_descriptor_response()->::grpc::reflection::v1alpha::FileDescriptorResponse::MergeFrom(from.file_descriptor_response()); @@ -2550,8 +2555,8 @@ void FileDescriptorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.FileDescriptorResponse) } -::google::protobuf::uint8* FileDescriptorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* FileDescriptorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.FileDescriptorResponse) // repeated bytes file_descriptor_proto = 1; for (int i = 0; i < this->file_descriptor_proto_size(); i++) { @@ -2582,7 +2587,9 @@ int FileDescriptorResponse::ByteSize() const { void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const FileDescriptorResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2597,7 +2604,9 @@ void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) void FileDescriptorResponse::MergeFrom(const FileDescriptorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } file_descriptor_proto_.MergeFrom(from.file_descriptor_proto_); } @@ -2863,8 +2872,8 @@ void ExtensionNumberResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionNumberResponse) } -::google::protobuf::uint8* ExtensionNumberResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ExtensionNumberResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionNumberResponse) // optional string base_type_name = 1; if (this->base_type_name().size() > 0) { @@ -2931,7 +2940,9 @@ int ExtensionNumberResponse::ByteSize() const { void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ExtensionNumberResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -2946,7 +2957,9 @@ void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) void ExtensionNumberResponse::MergeFrom(const ExtensionNumberResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } extension_number_.MergeFrom(from.extension_number_); if (from.base_type_name().size() > 0) { @@ -3199,14 +3212,14 @@ void ListServiceResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ListServiceResponse) } -::google::protobuf::uint8* ListServiceResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ListServiceResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ListServiceResponse) // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1; for (unsigned int i = 0, n = this->service_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteMessageNoVirtualToArray( - 1, this->service(i), target); + InternalWriteMessageNoVirtualToArray( + 1, this->service(i), false, target); } // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ListServiceResponse) @@ -3233,7 +3246,9 @@ int ListServiceResponse::ByteSize() const { void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ListServiceResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3248,7 +3263,9 @@ void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { void ListServiceResponse::MergeFrom(const ListServiceResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } service_.MergeFrom(from.service_); } @@ -3459,8 +3476,8 @@ void ServiceResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServiceResponse) } -::google::protobuf::uint8* ServiceResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ServiceResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServiceResponse) // optional string name = 1; if (this->name().size() > 0) { @@ -3496,7 +3513,9 @@ int ServiceResponse::ByteSize() const { void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ServiceResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3511,7 +3530,9 @@ void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) { void ServiceResponse::MergeFrom(const ServiceResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServiceResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.name().size() > 0) { name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); @@ -3762,8 +3783,8 @@ void ErrorResponse::SerializeWithCachedSizes( // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ErrorResponse) } -::google::protobuf::uint8* ErrorResponse::SerializeWithCachedSizesToArray( - ::google::protobuf::uint8* target) const { +::google::protobuf::uint8* ErrorResponse::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ErrorResponse) // optional int32 error_code = 1; if (this->error_code() != 0) { @@ -3811,7 +3832,9 @@ int ErrorResponse::ByteSize() const { void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { // @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ErrorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } const ErrorResponse* source = ::google::protobuf::internal::DynamicCastToGenerated( &from); @@ -3826,7 +3849,9 @@ void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) { void ErrorResponse::MergeFrom(const ErrorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ErrorResponse) - if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__); + if (GOOGLE_PREDICT_FALSE(&from == this)) { + ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__); + } if (from.error_code() != 0) { set_error_code(from.error_code()); } diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 45bb858e2ed..1a014da3b8c 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -35,10 +35,9 @@ #include #include -#include #include +#include -#include "include/grpc/support/useful.h" #include "src/cpp/server/thread_pool_interface.h" namespace grpc { @@ -154,14 +153,12 @@ std::unique_ptr ServerBuilder::BuildAndStart() { (*option)->UpdateArguments(&args); (*option)->UpdatePlugins(&plugins_); } - if (!thread_pool) { - for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) { - if ((*plugin)->has_sync_methods()) { - thread_pool.reset(CreateDefaultThreadPool()); - has_sync_methods = true; - break; - } + for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) { + if (!thread_pool && (*plugin)->has_sync_methods()) { + thread_pool.reset(CreateDefaultThreadPool()); + has_sync_methods = true; } + (*plugin)->UpdateChannelArguments(&args); } if (max_message_size_ > 0) { args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_); diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc index 43117fd1e95..1ca6a2b906e 100644 --- a/src/cpp/server/server_context.cc +++ b/src/cpp/server/server_context.cc @@ -129,7 +129,8 @@ ServerContext::ServerContext() deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)), call_(nullptr), cq_(nullptr), - sent_initial_metadata_(false) {} + sent_initial_metadata_(false), + compression_level_set_(false) {} ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata, size_t metadata_count) @@ -139,7 +140,8 @@ ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata, deadline_(deadline), call_(nullptr), cq_(nullptr), - sent_initial_metadata_(false) { + sent_initial_metadata_(false), + compression_level_set_(false) { for (size_t i = 0; i < metadata_count; i++) { client_metadata_.insert(std::pair( metadata[i].key, @@ -194,15 +196,6 @@ bool ServerContext::IsCancelled() const { } } -void ServerContext::set_compression_level(grpc_compression_level level) { - // TODO(dgq): get rid of grpc_call_compression_for_level and propagate the - // compression level by adding a new argument to - // CallOpSendInitialMetadata::SendInitialMetadata. - const grpc_compression_algorithm algorithm_for_level = - grpc_call_compression_for_level(call_, level); - set_compression_algorithm(algorithm_for_level); -} - void ServerContext::set_compression_algorithm( grpc_compression_algorithm algorithm) { char* algorithm_name = NULL; diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc index c2cd20ee07f..91ed66b7663 100644 --- a/src/cpp/util/byte_buffer.cc +++ b/src/cpp/util/byte_buffer.cc @@ -37,12 +37,19 @@ namespace grpc { ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) { - // TODO(yangg) maybe expose some core API to simplify this - std::vector c_slices(nslices); - for (size_t i = 0; i < nslices; i++) { - c_slices[i] = slices[i].slice_; - } - buffer_ = grpc_raw_byte_buffer_create(c_slices.data(), nslices); + // The following assertions check that the representation of a grpc::Slice is + // identical to that of a gpr_slice: it has a gpr_slice field, and nothing + // else. + static_assert(std::is_same::value, + "Slice must have same representation as gpr_slice"); + static_assert(sizeof(Slice) == sizeof(gpr_slice), + "Slice must have same representation as gpr_slice"); + // The const_cast is legal if grpc_raw_byte_buffer_create() does no more + // than its advertised side effect of increasing the reference count of the + // slices it processes, and such an increase does not affect the semantics + // seen by the caller of this constructor. + buffer_ = grpc_raw_byte_buffer_create( + reinterpret_cast(const_cast(slices)), nslices); } ByteBuffer::~ByteBuffer() { @@ -95,4 +102,10 @@ ByteBuffer& ByteBuffer::operator=(const ByteBuffer& buf) { return *this; } +void ByteBuffer::Swap(ByteBuffer* other) { + grpc_byte_buffer* tmp = other->buffer_; + other->buffer_ = buffer_; + buffer_ = tmp; +} + } // namespace grpc diff --git a/src/csharp/.nuget/packages.config b/src/csharp/.nuget/packages.config deleted file mode 100644 index 6154b3561f4..00000000000 --- a/src/csharp/.nuget/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj index 1fa14fc3dfb..a44aaf1fdd4 100644 --- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj +++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj @@ -39,30 +39,37 @@ ..\keys\Grpc.snk - - False + + + + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - False - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll + + ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - - diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec index 4baed3704c4..a1f5668e2e0 100644 --- a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec +++ b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec @@ -15,7 +15,7 @@ Copyright 2015, Google Inc. gRPC RPC Protocol HTTP/2 Auth OAuth2 - + diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config index c20d9ceed6a..11c6375c638 100644 --- a/src/csharp/Grpc.Auth/packages.config +++ b/src/csharp/Grpc.Auth/packages.config @@ -1,7 +1,10 @@  - - + + + + + \ No newline at end of file diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json index 08429f1d466..595e29f50af 100644 --- a/src/csharp/Grpc.Auth/project.json +++ b/src/csharp/Grpc.Auth/project.json @@ -23,18 +23,13 @@ }, "dependencies": { "Grpc.Core": "1.1.0-dev", - "Google.Apis.Auth": "1.11.1" + "Google.Apis.Auth": "1.16.0" }, "frameworks": { "net45": { }, "netstandard1.5": { - "imports": [ - "net45" - ], "dependencies": { - "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24027", - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Tasks": "4.0.11-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs index 064bc13cabb..d7ebdb4201e 100644 --- a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs +++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs @@ -40,7 +40,7 @@ namespace Grpc.Core.Tests { public class AppDomainUnloadTest { -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 [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 f6c226567d9..d99bf8e4e19 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -40,7 +40,7 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll @@ -108,4 +108,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Core.Tests/NUnitMain.cs b/src/csharp/Grpc.Core.Tests/NUnitMain.cs index 24a9f846d10..870c726ac0e 100644 --- a/src/csharp/Grpc.Core.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Core.Tests/NUnitMain.cs @@ -49,7 +49,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 TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs index 501992c5695..f1eb13dffcf 100644 --- a/src/csharp/Grpc.Core.Tests/SanityTest.cs +++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs @@ -46,7 +46,7 @@ namespace Grpc.Core.Tests public class SanityTest { // TODO: make sanity test work for CoreCLR as well -#if !NETSTANDARD1_5 +#if !NETCOREAPP1_0 /// /// 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, @@ -59,9 +59,10 @@ namespace Grpc.Core.Tests public void TestsJsonUpToDate() { var discoveredTests = DiscoverAllTestClasses(); - string discoveredTestsJson = JsonConvert.SerializeObject(discoveredTests, Formatting.Indented); + var testsFromFile + = JsonConvert.DeserializeObject>>(ReadTestsJson()); - Assert.AreEqual(discoveredTestsJson, ReadTestsJson()); + Assert.AreEqual(discoveredTests, testsFromFile); } /// diff --git a/src/csharp/Grpc.Core.Tests/packages.config b/src/csharp/Grpc.Core.Tests/packages.config index aa7d951fdc7..456ffcd8d02 100644 --- a/src/csharp/Grpc.Core.Tests/packages.config +++ b/src/csharp/Grpc.Core.Tests/packages.config @@ -1,7 +1,10 @@  - + - \ No newline at end of file + + + + diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json index f58bcbb5159..014e2262e9f 100644 --- a/src/csharp/Grpc.Core.Tests/project.json +++ b/src/csharp/Grpc.Core.Tests/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -54,16 +54,20 @@ }, "Newtonsoft.Json": "8.0.3", "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnitLite": "3.2.0-*", + "NUnit.ConsoleRunner": "3.2.0", + "OpenCover": "4.6.519", + "ReportGenerator": "2.4.4.0" }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } }, diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 1952ee37121..622813fb381 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -40,7 +40,7 @@ - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll @@ -152,4 +152,4 @@ roots.pem - \ No newline at end of file + diff --git a/src/csharp/Grpc.Core/Grpc.Core.nuspec b/src/csharp/Grpc.Core/Grpc.Core.nuspec index 47593f787b1..a8459c4d9cd 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.nuspec +++ b/src/csharp/Grpc.Core/Grpc.Core.nuspec @@ -15,7 +15,7 @@ Copyright 2015, Google Inc. gRPC RPC Protocol HTTP/2 - + @@ -25,11 +25,11 @@ - - - - - - + + + + + + diff --git a/src/csharp/Grpc.Core/Grpc.Core.targets b/src/csharp/Grpc.Core/Grpc.Core.targets index 501fc505482..3367d51a80e 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.targets +++ b/src/csharp/Grpc.Core/Grpc.Core.targets @@ -1,29 +1,29 @@  - + PreserveNewest - nativelibs\windows_x86\grpc_csharp_ext.dll + grpc_csharp_ext.x86.dll - + PreserveNewest - nativelibs\windows_x64\grpc_csharp_ext.dll + grpc_csharp_ext.x64.dll - + PreserveNewest - nativelibs\linux_x86\libgrpc_csharp_ext.so + libgrpc_csharp_ext.x86.so - + PreserveNewest - nativelibs\linux_x64\libgrpc_csharp_ext.so + libgrpc_csharp_ext.x64.so - + PreserveNewest - nativelibs\macosx_x86\libgrpc_csharp_ext.dylib + libgrpc_csharp_ext.x86.dylib - + PreserveNewest - nativelibs\macosx_x64\libgrpc_csharp_ext.dylib + libgrpc_csharp_ext.x64.dylib \ No newline at end of file diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index eeed6997123..574e900a0e7 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -47,7 +47,6 @@ namespace Grpc.Core /// public class GrpcEnvironment { - const LogLevel DefaultLogLevel = LogLevel.Info; const int MinDefaultThreadPoolSize = 4; static object staticLock = new object(); @@ -58,7 +57,7 @@ namespace Grpc.Core static readonly HashSet registeredChannels = new HashSet(); static readonly HashSet registeredServers = new HashSet(); - static ILogger logger = new LogLevelFilterLogger(new ConsoleLogger(), DefaultLogLevel); + static ILogger logger = new NullLogger(); readonly object myLock = new object(); readonly GrpcThreadPool threadPool; diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs index a6d79258162..509baf7cb1f 100644 --- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs +++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs @@ -44,9 +44,6 @@ namespace Grpc.Core.Internal /// internal sealed class NativeExtension { - const string NativeLibrariesDir = "nativelibs"; - const string DnxStyleNativeLibrariesDir = "../../build/native/bin/"; - static readonly ILogger Logger = GrpcEnvironment.Logger.ForType(); static readonly object staticLock = new object(); static volatile NativeExtension instance; @@ -98,20 +95,25 @@ namespace Grpc.Core.Internal private static UnmanagedLibrary Load() { // TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property). - - var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString()); - + // 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 // alongside the compiled assembly. - var classicPath = Path.Combine(assemblyDirectory, NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); + // With dotnet cli projects, 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()); // DNX-style project.json 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. - var dnxStylePath = Path.Combine(assemblyDirectory, DnxStyleNativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename()); - return new UnmanagedLibrary(new string[] {classicPath, dnxStylePath}); + // TODO: Support .NET Core applications, which act slightly differently. We may be okay if "dotnet publish" + // is used, but "dotnet run" leaves the native libraries in-package, while copying assemblies. + string platform = GetPlatformString(); + string relativeDirectory = string.Format("../../runtimes/{0}/native", platform); + var dnxStylePath = Path.Combine(assemblyDirectory, relativeDirectory, GetNativeLibraryFilename()); + string[] paths = new[] { classicPath, dnxStylePath }; + return new UnmanagedLibrary(paths); } private static string GetAssemblyPath() @@ -147,7 +149,7 @@ namespace Grpc.Core.Internal { if (PlatformApis.IsWindows) { - return "windows"; + return "win"; } if (PlatformApis.IsLinux) { @@ -155,7 +157,7 @@ namespace Grpc.Core.Internal } if (PlatformApis.IsMacOSX) { - return "macosx"; + return "osx"; } throw new InvalidOperationException("Unsupported platform."); } @@ -176,17 +178,18 @@ namespace Grpc.Core.Internal // platform specific file name of the extension library private static string GetNativeLibraryFilename() { + string architecture = GetArchitectureString(); if (PlatformApis.IsWindows) { - return "grpc_csharp_ext.dll"; + return string.Format("grpc_csharp_ext.{0}.dll", architecture); } if (PlatformApis.IsLinux) { - return "libgrpc_csharp_ext.so"; + return string.Format("libgrpc_csharp_ext.{0}.so", architecture); } if (PlatformApis.IsMacOSX) { - return "libgrpc_csharp_ext.dylib"; + return string.Format("libgrpc_csharp_ext.{0}.dylib", architecture); } throw new InvalidOperationException("Unsupported platform."); } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs index 65607ed1204..f457c9dbf1e 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs @@ -159,215 +159,107 @@ namespace Grpc.Core.Internal public NativeMethods(UnmanagedLibrary library) { - if (PlatformApis.IsLinux || PlatformApis.IsMacOSX) - { - this.grpcsharp_init = GetMethodDelegate(library); - this.grpcsharp_shutdown = GetMethodDelegate(library); - this.grpcsharp_version_string = GetMethodDelegate(library); - - this.grpcsharp_batch_context_create = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_call = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_method = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_host = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_deadline = GetMethodDelegate(library); - this.grpcsharp_batch_context_server_rpc_new_request_metadata = GetMethodDelegate(library); - this.grpcsharp_batch_context_recv_close_on_server_cancelled = GetMethodDelegate(library); - this.grpcsharp_batch_context_destroy = GetMethodDelegate(library); - - this.grpcsharp_composite_call_credentials_create = GetMethodDelegate(library); - this.grpcsharp_call_credentials_release = GetMethodDelegate(library); - - this.grpcsharp_call_cancel = GetMethodDelegate(library); - this.grpcsharp_call_cancel_with_status = GetMethodDelegate(library); - this.grpcsharp_call_start_unary = GetMethodDelegate(library); - this.grpcsharp_call_start_client_streaming = GetMethodDelegate(library); - this.grpcsharp_call_start_server_streaming = GetMethodDelegate(library); - this.grpcsharp_call_start_duplex_streaming = GetMethodDelegate(library); - this.grpcsharp_call_send_message = GetMethodDelegate(library); - this.grpcsharp_call_send_close_from_client = GetMethodDelegate(library); - this.grpcsharp_call_send_status_from_server = GetMethodDelegate(library); - this.grpcsharp_call_recv_message = GetMethodDelegate(library); - this.grpcsharp_call_recv_initial_metadata = GetMethodDelegate(library); - this.grpcsharp_call_start_serverside = GetMethodDelegate(library); - this.grpcsharp_call_send_initial_metadata = GetMethodDelegate(library); - this.grpcsharp_call_set_credentials = GetMethodDelegate(library); - this.grpcsharp_call_get_peer = GetMethodDelegate(library); - this.grpcsharp_call_destroy = GetMethodDelegate(library); - - this.grpcsharp_channel_args_create = GetMethodDelegate(library); - this.grpcsharp_channel_args_set_string = GetMethodDelegate(library); - this.grpcsharp_channel_args_set_integer = GetMethodDelegate(library); - this.grpcsharp_channel_args_destroy = GetMethodDelegate(library); - - this.grpcsharp_override_default_ssl_roots = GetMethodDelegate(library); - this.grpcsharp_ssl_credentials_create = GetMethodDelegate(library); - this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate(library); - this.grpcsharp_channel_credentials_release = GetMethodDelegate(library); - - this.grpcsharp_insecure_channel_create = GetMethodDelegate(library); - this.grpcsharp_secure_channel_create = GetMethodDelegate(library); - this.grpcsharp_channel_create_call = GetMethodDelegate(library); - this.grpcsharp_channel_check_connectivity_state = GetMethodDelegate(library); - this.grpcsharp_channel_watch_connectivity_state = GetMethodDelegate(library); - this.grpcsharp_channel_get_target = GetMethodDelegate(library); - this.grpcsharp_channel_destroy = GetMethodDelegate(library); - - this.grpcsharp_sizeof_grpc_event = GetMethodDelegate(library); - - this.grpcsharp_completion_queue_create = GetMethodDelegate(library); - this.grpcsharp_completion_queue_shutdown = GetMethodDelegate(library); - this.grpcsharp_completion_queue_next = GetMethodDelegate(library); - this.grpcsharp_completion_queue_pluck = GetMethodDelegate(library); - this.grpcsharp_completion_queue_destroy = GetMethodDelegate(library); - - this.gprsharp_free = GetMethodDelegate(library); - - this.grpcsharp_metadata_array_create = GetMethodDelegate(library); - this.grpcsharp_metadata_array_add = GetMethodDelegate(library); - this.grpcsharp_metadata_array_count = GetMethodDelegate(library); - this.grpcsharp_metadata_array_get_key = GetMethodDelegate(library); - this.grpcsharp_metadata_array_get_value = GetMethodDelegate(library); - this.grpcsharp_metadata_array_get_value_length = GetMethodDelegate(library); - this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate(library); - - this.grpcsharp_redirect_log = GetMethodDelegate(library); - - this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate(library); - this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate(library); - - this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate(library); - this.grpcsharp_server_credentials_release = GetMethodDelegate(library); - - this.grpcsharp_server_create = GetMethodDelegate(library); - this.grpcsharp_server_register_completion_queue = GetMethodDelegate(library); - this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate(library); - this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate(library); - this.grpcsharp_server_start = GetMethodDelegate(library); - this.grpcsharp_server_request_call = GetMethodDelegate(library); - this.grpcsharp_server_cancel_all_calls = GetMethodDelegate(library); - this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate(library); - this.grpcsharp_server_destroy = GetMethodDelegate(library); - - this.gprsharp_now = GetMethodDelegate(library); - this.gprsharp_inf_future = GetMethodDelegate(library); - this.gprsharp_inf_past = GetMethodDelegate(library); - this.gprsharp_convert_clock_type = GetMethodDelegate(library); - this.gprsharp_sizeof_timespec = GetMethodDelegate(library); - - this.grpcsharp_test_callback = GetMethodDelegate(library); - this.grpcsharp_test_nop = GetMethodDelegate(library); - } - else - { - // Windows or fallback - this.grpcsharp_init = PInvokeMethods.grpcsharp_init; - this.grpcsharp_shutdown = PInvokeMethods.grpcsharp_shutdown; - this.grpcsharp_version_string = PInvokeMethods.grpcsharp_version_string; - - this.grpcsharp_batch_context_create = PInvokeMethods.grpcsharp_batch_context_create; - this.grpcsharp_batch_context_recv_initial_metadata = PInvokeMethods.grpcsharp_batch_context_recv_initial_metadata; - this.grpcsharp_batch_context_recv_message_length = PInvokeMethods.grpcsharp_batch_context_recv_message_length; - this.grpcsharp_batch_context_recv_message_to_buffer = PInvokeMethods.grpcsharp_batch_context_recv_message_to_buffer; - this.grpcsharp_batch_context_recv_status_on_client_status = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_status; - this.grpcsharp_batch_context_recv_status_on_client_details = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_details; - this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_trailing_metadata; - this.grpcsharp_batch_context_server_rpc_new_call = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_call; - this.grpcsharp_batch_context_server_rpc_new_method = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_method; - this.grpcsharp_batch_context_server_rpc_new_host = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_host; - this.grpcsharp_batch_context_server_rpc_new_deadline = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_deadline; - this.grpcsharp_batch_context_server_rpc_new_request_metadata = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_request_metadata; - this.grpcsharp_batch_context_recv_close_on_server_cancelled = PInvokeMethods.grpcsharp_batch_context_recv_close_on_server_cancelled; - this.grpcsharp_batch_context_destroy = PInvokeMethods.grpcsharp_batch_context_destroy; - - this.grpcsharp_composite_call_credentials_create = PInvokeMethods.grpcsharp_composite_call_credentials_create; - this.grpcsharp_call_credentials_release = PInvokeMethods.grpcsharp_call_credentials_release; - - this.grpcsharp_call_cancel = PInvokeMethods.grpcsharp_call_cancel; - this.grpcsharp_call_cancel_with_status = PInvokeMethods.grpcsharp_call_cancel_with_status; - this.grpcsharp_call_start_unary = PInvokeMethods.grpcsharp_call_start_unary; - this.grpcsharp_call_start_client_streaming = PInvokeMethods.grpcsharp_call_start_client_streaming; - this.grpcsharp_call_start_server_streaming = PInvokeMethods.grpcsharp_call_start_server_streaming; - this.grpcsharp_call_start_duplex_streaming = PInvokeMethods.grpcsharp_call_start_duplex_streaming; - this.grpcsharp_call_send_message = PInvokeMethods.grpcsharp_call_send_message; - this.grpcsharp_call_send_close_from_client = PInvokeMethods.grpcsharp_call_send_close_from_client; - this.grpcsharp_call_send_status_from_server = PInvokeMethods.grpcsharp_call_send_status_from_server; - this.grpcsharp_call_recv_message = PInvokeMethods.grpcsharp_call_recv_message; - this.grpcsharp_call_recv_initial_metadata = PInvokeMethods.grpcsharp_call_recv_initial_metadata; - this.grpcsharp_call_start_serverside = PInvokeMethods.grpcsharp_call_start_serverside; - this.grpcsharp_call_send_initial_metadata = PInvokeMethods.grpcsharp_call_send_initial_metadata; - this.grpcsharp_call_set_credentials = PInvokeMethods.grpcsharp_call_set_credentials; - this.grpcsharp_call_get_peer = PInvokeMethods.grpcsharp_call_get_peer; - this.grpcsharp_call_destroy = PInvokeMethods.grpcsharp_call_destroy; - - this.grpcsharp_channel_args_create = PInvokeMethods.grpcsharp_channel_args_create; - this.grpcsharp_channel_args_set_string = PInvokeMethods.grpcsharp_channel_args_set_string; - this.grpcsharp_channel_args_set_integer = PInvokeMethods.grpcsharp_channel_args_set_integer; - this.grpcsharp_channel_args_destroy = PInvokeMethods.grpcsharp_channel_args_destroy; - - this.grpcsharp_override_default_ssl_roots = PInvokeMethods.grpcsharp_override_default_ssl_roots; - this.grpcsharp_ssl_credentials_create = PInvokeMethods.grpcsharp_ssl_credentials_create; - this.grpcsharp_composite_channel_credentials_create = PInvokeMethods.grpcsharp_composite_channel_credentials_create; - this.grpcsharp_channel_credentials_release = PInvokeMethods.grpcsharp_channel_credentials_release; - - this.grpcsharp_insecure_channel_create = PInvokeMethods.grpcsharp_insecure_channel_create; - this.grpcsharp_secure_channel_create = PInvokeMethods.grpcsharp_secure_channel_create; - this.grpcsharp_channel_create_call = PInvokeMethods.grpcsharp_channel_create_call; - this.grpcsharp_channel_check_connectivity_state = PInvokeMethods.grpcsharp_channel_check_connectivity_state; - this.grpcsharp_channel_watch_connectivity_state = PInvokeMethods.grpcsharp_channel_watch_connectivity_state; - this.grpcsharp_channel_get_target = PInvokeMethods.grpcsharp_channel_get_target; - this.grpcsharp_channel_destroy = PInvokeMethods.grpcsharp_channel_destroy; - - this.grpcsharp_sizeof_grpc_event = PInvokeMethods.grpcsharp_sizeof_grpc_event; - - this.grpcsharp_completion_queue_create = PInvokeMethods.grpcsharp_completion_queue_create; - this.grpcsharp_completion_queue_shutdown = PInvokeMethods.grpcsharp_completion_queue_shutdown; - this.grpcsharp_completion_queue_next = PInvokeMethods.grpcsharp_completion_queue_next; - this.grpcsharp_completion_queue_pluck = PInvokeMethods.grpcsharp_completion_queue_pluck; - this.grpcsharp_completion_queue_destroy = PInvokeMethods.grpcsharp_completion_queue_destroy; - - this.gprsharp_free = PInvokeMethods.gprsharp_free; - - this.grpcsharp_metadata_array_create = PInvokeMethods.grpcsharp_metadata_array_create; - this.grpcsharp_metadata_array_add = PInvokeMethods.grpcsharp_metadata_array_add; - this.grpcsharp_metadata_array_count = PInvokeMethods.grpcsharp_metadata_array_count; - this.grpcsharp_metadata_array_get_key = PInvokeMethods.grpcsharp_metadata_array_get_key; - this.grpcsharp_metadata_array_get_value = PInvokeMethods.grpcsharp_metadata_array_get_value; - this.grpcsharp_metadata_array_get_value_length = PInvokeMethods.grpcsharp_metadata_array_get_value_length; - this.grpcsharp_metadata_array_destroy_full = PInvokeMethods.grpcsharp_metadata_array_destroy_full; - - this.grpcsharp_redirect_log = PInvokeMethods.grpcsharp_redirect_log; - - this.grpcsharp_metadata_credentials_create_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_create_from_plugin; - this.grpcsharp_metadata_credentials_notify_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_notify_from_plugin; - - this.grpcsharp_ssl_server_credentials_create = PInvokeMethods.grpcsharp_ssl_server_credentials_create; - this.grpcsharp_server_credentials_release = PInvokeMethods.grpcsharp_server_credentials_release; - - this.grpcsharp_server_create = PInvokeMethods.grpcsharp_server_create; - this.grpcsharp_server_register_completion_queue = PInvokeMethods.grpcsharp_server_register_completion_queue; - this.grpcsharp_server_add_insecure_http2_port = PInvokeMethods.grpcsharp_server_add_insecure_http2_port; - this.grpcsharp_server_add_secure_http2_port = PInvokeMethods.grpcsharp_server_add_secure_http2_port; - this.grpcsharp_server_start = PInvokeMethods.grpcsharp_server_start; - this.grpcsharp_server_request_call = PInvokeMethods.grpcsharp_server_request_call; - this.grpcsharp_server_cancel_all_calls = PInvokeMethods.grpcsharp_server_cancel_all_calls; - this.grpcsharp_server_shutdown_and_notify_callback = PInvokeMethods.grpcsharp_server_shutdown_and_notify_callback; - this.grpcsharp_server_destroy = PInvokeMethods.grpcsharp_server_destroy; - - this.gprsharp_now = PInvokeMethods.gprsharp_now; - this.gprsharp_inf_future = PInvokeMethods.gprsharp_inf_future; - this.gprsharp_inf_past = PInvokeMethods.gprsharp_inf_past; - this.gprsharp_convert_clock_type = PInvokeMethods.gprsharp_convert_clock_type; - this.gprsharp_sizeof_timespec = PInvokeMethods.gprsharp_sizeof_timespec; - - this.grpcsharp_test_callback = PInvokeMethods.grpcsharp_test_callback; - this.grpcsharp_test_nop = PInvokeMethods.grpcsharp_test_nop; - } + this.grpcsharp_init = GetMethodDelegate(library); + this.grpcsharp_shutdown = GetMethodDelegate(library); + this.grpcsharp_version_string = GetMethodDelegate(library); + + this.grpcsharp_batch_context_create = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_call = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_method = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_host = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_deadline = GetMethodDelegate(library); + this.grpcsharp_batch_context_server_rpc_new_request_metadata = GetMethodDelegate(library); + this.grpcsharp_batch_context_recv_close_on_server_cancelled = GetMethodDelegate(library); + this.grpcsharp_batch_context_destroy = GetMethodDelegate(library); + + this.grpcsharp_composite_call_credentials_create = GetMethodDelegate(library); + this.grpcsharp_call_credentials_release = GetMethodDelegate(library); + + this.grpcsharp_call_cancel = GetMethodDelegate(library); + this.grpcsharp_call_cancel_with_status = GetMethodDelegate(library); + this.grpcsharp_call_start_unary = GetMethodDelegate(library); + this.grpcsharp_call_start_client_streaming = GetMethodDelegate(library); + this.grpcsharp_call_start_server_streaming = GetMethodDelegate(library); + this.grpcsharp_call_start_duplex_streaming = GetMethodDelegate(library); + this.grpcsharp_call_send_message = GetMethodDelegate(library); + this.grpcsharp_call_send_close_from_client = GetMethodDelegate(library); + this.grpcsharp_call_send_status_from_server = GetMethodDelegate(library); + this.grpcsharp_call_recv_message = GetMethodDelegate(library); + this.grpcsharp_call_recv_initial_metadata = GetMethodDelegate(library); + this.grpcsharp_call_start_serverside = GetMethodDelegate(library); + this.grpcsharp_call_send_initial_metadata = GetMethodDelegate(library); + this.grpcsharp_call_set_credentials = GetMethodDelegate(library); + this.grpcsharp_call_get_peer = GetMethodDelegate(library); + this.grpcsharp_call_destroy = GetMethodDelegate(library); + + this.grpcsharp_channel_args_create = GetMethodDelegate(library); + this.grpcsharp_channel_args_set_string = GetMethodDelegate(library); + this.grpcsharp_channel_args_set_integer = GetMethodDelegate(library); + this.grpcsharp_channel_args_destroy = GetMethodDelegate(library); + + this.grpcsharp_override_default_ssl_roots = GetMethodDelegate(library); + this.grpcsharp_ssl_credentials_create = GetMethodDelegate(library); + this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate(library); + this.grpcsharp_channel_credentials_release = GetMethodDelegate(library); + + this.grpcsharp_insecure_channel_create = GetMethodDelegate(library); + this.grpcsharp_secure_channel_create = GetMethodDelegate(library); + this.grpcsharp_channel_create_call = GetMethodDelegate(library); + this.grpcsharp_channel_check_connectivity_state = GetMethodDelegate(library); + this.grpcsharp_channel_watch_connectivity_state = GetMethodDelegate(library); + this.grpcsharp_channel_get_target = GetMethodDelegate(library); + this.grpcsharp_channel_destroy = GetMethodDelegate(library); + + this.grpcsharp_sizeof_grpc_event = GetMethodDelegate(library); + + this.grpcsharp_completion_queue_create = GetMethodDelegate(library); + this.grpcsharp_completion_queue_shutdown = GetMethodDelegate(library); + this.grpcsharp_completion_queue_next = GetMethodDelegate(library); + this.grpcsharp_completion_queue_pluck = GetMethodDelegate(library); + this.grpcsharp_completion_queue_destroy = GetMethodDelegate(library); + + this.gprsharp_free = GetMethodDelegate(library); + + this.grpcsharp_metadata_array_create = GetMethodDelegate(library); + this.grpcsharp_metadata_array_add = GetMethodDelegate(library); + this.grpcsharp_metadata_array_count = GetMethodDelegate(library); + this.grpcsharp_metadata_array_get_key = GetMethodDelegate(library); + this.grpcsharp_metadata_array_get_value = GetMethodDelegate(library); + this.grpcsharp_metadata_array_get_value_length = GetMethodDelegate(library); + this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate(library); + + this.grpcsharp_redirect_log = GetMethodDelegate(library); + + this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate(library); + this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate(library); + + this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate(library); + this.grpcsharp_server_credentials_release = GetMethodDelegate(library); + + this.grpcsharp_server_create = GetMethodDelegate(library); + this.grpcsharp_server_register_completion_queue = GetMethodDelegate(library); + this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate(library); + this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate(library); + this.grpcsharp_server_start = GetMethodDelegate(library); + this.grpcsharp_server_request_call = GetMethodDelegate(library); + this.grpcsharp_server_cancel_all_calls = GetMethodDelegate(library); + this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate(library); + this.grpcsharp_server_destroy = GetMethodDelegate(library); + + this.gprsharp_now = GetMethodDelegate(library); + this.gprsharp_inf_future = GetMethodDelegate(library); + this.gprsharp_inf_past = GetMethodDelegate(library); + this.gprsharp_convert_clock_type = GetMethodDelegate(library); + this.gprsharp_sizeof_timespec = GetMethodDelegate(library); + + this.grpcsharp_test_callback = GetMethodDelegate(library); + this.grpcsharp_test_nop = GetMethodDelegate(library); } /// @@ -516,317 +408,5 @@ namespace Grpc.Core.Internal public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback); public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr); } - - /// - /// Default PInvoke bindings for native methods that are used on Windows. - /// Alternatively, they can also be used as a fallback on Mono - /// (if libgrpc_csharp_ext is installed on your system, or is made accessible through e.g. LD_LIBRARY_PATH environment variable - /// or using Mono's dllMap feature). - /// - private class PInvokeMethods - { - // Environment - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_init(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_shutdown(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_version_string(); // returns not-owned const char* - - // BatchContextSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern BatchContextSafeHandle grpcsharp_batch_context_create(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen); - - [DllImport("grpc_csharp_ext.dll")] - public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char* - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char* - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char* - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_batch_context_destroy(IntPtr ctx); - - // CallCredentialsSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_call_credentials_release(IntPtr credentials); - - // CallSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_cancel(CallSafeHandle call); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_unary(CallSafeHandle call, - BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_client_streaming(CallSafeHandle call, - BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_server_streaming(CallSafeHandle call, - BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, - MetadataArraySafeHandle metadataArray, WriteFlags writeFlags); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call, - BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_message(CallSafeHandle call, - BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, bool sendEmptyInitialMetadata); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_close_from_client(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_status_from_server(CallSafeHandle call, - BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, - byte[] optionalSendBuffer, UIntPtr optionalSendBufferLen, WriteFlags writeFlags); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_recv_message(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_start_serverside(CallSafeHandle call, - BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_send_initial_metadata(CallSafeHandle call, - BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_call_destroy(IntPtr call); - - // ChannelArgsSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_args_destroy(IntPtr args); - - // ChannelCredentialsSafeHandle - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_override_default_ssl_roots(string pemRootCerts); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey); - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_credentials_release(IntPtr credentials); - - // ChannelSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs); - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline); - - [DllImport("grpc_csharp_ext.dll")] - public static extern ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState, - Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_channel_destroy(IntPtr channel); - - // CompletionQueueEvent - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_sizeof_grpc_event(); - - // CompletionQueueSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create(); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_completion_queue_destroy(IntPtr cq); - - // CStringSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern void gprsharp_free(IntPtr ptr); - - // MetadataArraySafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength); - - [DllImport("grpc_csharp_ext.dll")] - public static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index); - - [DllImport("grpc_csharp_ext.dll")] - public static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_metadata_array_destroy_full(IntPtr array); - - // NativeLogRedirector - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_redirect_log(GprLogDelegate callback); - - // NativeMetadataCredentialsPlugin - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor); - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails); - - // ServerCredentialsSafeHandle - - [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)] - public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_credentials_release(IntPtr credentials); - - // ServerSafeHandle - - [DllImport("grpc_csharp_ext.dll")] - public static extern ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_start(ServerSafeHandle server); - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_cancel_all_calls(ServerSafeHandle server); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx); - - [DllImport("grpc_csharp_ext.dll")] - public static extern void grpcsharp_server_destroy(IntPtr server); - - // Timespec - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_now(ClockType clockType); - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_inf_future(ClockType clockType); - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_inf_past(ClockType clockType); - - [DllImport("grpc_csharp_ext.dll")] - public static extern Timespec gprsharp_convert_clock_type(Timespec t, ClockType targetClock); - - [DllImport("grpc_csharp_ext.dll")] - public static extern int gprsharp_sizeof_timespec(); - - // Testing - - [DllImport("grpc_csharp_ext.dll")] - public static extern CallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback); - - [DllImport("grpc_csharp_ext.dll")] - public static extern IntPtr grpcsharp_test_nop(IntPtr ptr); - } } } diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 5a807461015..dc629bd714f 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -82,6 +82,32 @@ namespace Grpc.Core.Internal /// public IntPtr LoadSymbol(string symbolName) { + if (PlatformApis.IsWindows) + { + // See http://stackoverflow.com/questions/10473310 for background on this. + if (PlatformApis.Is64Bit) + { + return Windows.GetProcAddress(this.handle, symbolName); + } + else + { + // Yes, we could potentially predict the size... but it's a lot simpler to just try + // all the candidates. Most functions have a suffix of @0, @4 or @8 so we won't be trying + // many options - and if it takes a little bit longer to fail if we've really got the wrong + // library, that's not a big problem. This is only called once per function in the native library. + symbolName = "_" + symbolName + "@"; + for (int stackSize = 0; stackSize < 128; stackSize += 4) + { + IntPtr candidate = Windows.GetProcAddress(this.handle, symbolName + stackSize); + if (candidate != IntPtr.Zero) + { + return candidate; + } + } + // Fail. + return IntPtr.Zero; + } + } if (PlatformApis.IsLinux) { if (PlatformApis.IsMono) @@ -142,13 +168,18 @@ namespace Grpc.Core.Internal return path; } } - throw new FileNotFoundException(String.Format("Error loading native library. Not found in any of the possible locations {0}", libraryPathAlternatives)); + throw new FileNotFoundException( + String.Format("Error loading native library. Not found in any of the possible locations: {0}", + string.Join(",", libraryPathAlternatives))); } private static class Windows { [DllImport("kernel32.dll")] internal static extern IntPtr LoadLibrary(string filename); + + [DllImport("kernel32.dll")] + internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName); } private static class Linux diff --git a/src/csharp/Grpc.Core/NativeDeps.Linux.targets b/src/csharp/Grpc.Core/NativeDeps.Linux.targets index a3848c6f2ed..e0c9132b1d5 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Linux.targets +++ b/src/csharp/Grpc.Core/NativeDeps.Linux.targets @@ -3,7 +3,7 @@ PreserveNewest - nativelibs\linux_x64\libgrpc_csharp_ext.so + libgrpc_csharp_ext.x64.so \ No newline at end of file diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.targets b/src/csharp/Grpc.Core/NativeDeps.Mac.targets index c3c6264fd3f..e22c7384fc5 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Mac.targets +++ b/src/csharp/Grpc.Core/NativeDeps.Mac.targets @@ -3,7 +3,7 @@ PreserveNewest - nativelibs\macosx_x86\libgrpc_csharp_ext.dylib + libgrpc_csharp_ext.x86.dylib \ No newline at end of file diff --git a/src/csharp/Grpc.Core/NativeDeps.Windows.targets b/src/csharp/Grpc.Core/NativeDeps.Windows.targets index f6a3405e29f..93db0935bc1 100644 --- a/src/csharp/Grpc.Core/NativeDeps.Windows.targets +++ b/src/csharp/Grpc.Core/NativeDeps.Windows.targets @@ -3,7 +3,7 @@ PreserveNewest - nativelibs\windows_x86\grpc_csharp_ext.dll + grpc_csharp_ext.x86.dll \ No newline at end of file diff --git a/src/csharp/Grpc.Core/packages.config b/src/csharp/Grpc.Core/packages.config index 80daf048d0b..65147740217 100644 --- a/src/csharp/Grpc.Core/packages.config +++ b/src/csharp/Grpc.Core/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json index 4545d26aa5d..50c328abe16 100644 --- a/src/csharp/Grpc.Core/project.json +++ b/src/csharp/Grpc.Core/project.json @@ -14,12 +14,12 @@ "files": { "mappings": { "build/net45/": "Grpc.Core.targets", - "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll", - "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll", - "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", - "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", - "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", - "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" + "runtimes/win/native/grpc_csharp_ext.x86.dll": "../nativelibs/windows_x86/grpc_csharp_ext.dll", + "runtimes/win/native/grpc_csharp_ext.x64.dll": "../nativelibs/windows_x64/grpc_csharp_ext.dll", + "runtimes/linux/native/libgrpc_csharp_ext.x86.so": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", + "runtimes/linux/native/libgrpc_csharp_ext.x64.so": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", + "runtimes/osx/native/libgrpc_csharp_ext.x86.dylib": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", + "runtimes/osx/native/libgrpc_csharp_ext.x64.dylib": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" } } }, @@ -31,17 +31,14 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, "netstandard1.5": { - "imports": [ - "portable-net45" - ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Thread": "4.0.0-rc2-24027" + "NETStandard.Library": "1.6.0", + "System.Threading.Thread": "4.0.0" } } } diff --git a/src/csharp/Grpc.Examples.MathClient/packages.config b/src/csharp/Grpc.Examples.MathClient/packages.config new file mode 100644 index 00000000000..79ece06bef6 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathClient/packages.config @@ -0,0 +1,3 @@ + + + diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json index b865cd50118..c0725a1468d 100644 --- a/src/csharp/Grpc.Examples.MathClient/project.json +++ b/src/csharp/Grpc.Examples.MathClient/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -55,12 +55,10 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { - "imports": [ - "portable-net45" - ], + "netcoreapp1.0": { "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Examples.MathServer/packages.config b/src/csharp/Grpc.Examples.MathServer/packages.config new file mode 100644 index 00000000000..79ece06bef6 --- /dev/null +++ b/src/csharp/Grpc.Examples.MathServer/packages.config @@ -0,0 +1,3 @@ + + + diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json index b865cd50118..c0725a1468d 100644 --- a/src/csharp/Grpc.Examples.MathServer/project.json +++ b/src/csharp/Grpc.Examples.MathServer/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -55,12 +55,10 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { - "imports": [ - "portable-net45" - ], + "netcoreapp1.0": { "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj index 4c7d89309af..a114d96127d 100644 --- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj +++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj @@ -36,18 +36,18 @@ - - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + + ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + @@ -75,4 +75,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs index 1a522cab932..7ba1074d441 100644 --- a/src/csharp/Grpc.Examples.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.Examples.Tests/NUnitMain.cs @@ -49,7 +49,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 TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config index 668601af8e7..f14517d2e2e 100644 --- a/src/csharp/Grpc.Examples.Tests/packages.config +++ b/src/csharp/Grpc.Examples.Tests/packages.config @@ -1,7 +1,7 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json index cc518eb6ff7..1cd1848e99f 100644 --- a/src/csharp/Grpc.Examples.Tests/project.json +++ b/src/csharp/Grpc.Examples.Tests/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,12 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj index 3dfa84e896e..dcbef5fc0b3 100644 --- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj +++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj @@ -37,10 +37,6 @@ ..\keys\Grpc.snk - - False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll @@ -48,7 +44,10 @@ False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll + + + ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll @@ -72,4 +71,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config index a70dcbd4c68..d17347f08ff 100644 --- a/src/csharp/Grpc.Examples/packages.config +++ b/src/csharp/Grpc.Examples/packages.config @@ -1,6 +1,6 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json index 7d3f4dcbb1e..ce0cfa860dc 100644 --- a/src/csharp/Grpc.Examples/project.json +++ b/src/csharp/Grpc.Examples/project.json @@ -1,12 +1,17 @@ { "buildOptions": { }, + "runtimes": { + "win7-x64": { }, + "debian.8-x64": { }, + "osx.10.11-x64": { } + }, "dependencies": { "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0-beta3" + "Google.Protobuf": "3.0.0" }, "frameworks": { "net45": { @@ -15,12 +20,10 @@ "System.IO": "" } }, - "netstandard1.5": { - "imports": [ - "portable-net45" - ], + "netcoreapp1.0": { "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj index aefacfbcc01..93c3b3a55fc 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj +++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj @@ -44,15 +44,15 @@ - - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll - ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + + ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + diff --git a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs index 44634671ce5..dca61e3f966 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs +++ b/src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs @@ -49,7 +49,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 TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.HealthCheck.Tests/packages.config b/src/csharp/Grpc.HealthCheck.Tests/packages.config index 2bcfec8829b..e796d6b1358 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/packages.config +++ b/src/csharp/Grpc.HealthCheck.Tests/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json index fbf8d92f04d..faa44003044 100644 --- a/src/csharp/Grpc.HealthCheck.Tests/project.json +++ b/src/csharp/Grpc.HealthCheck.Tests/project.json @@ -14,10 +14,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -33,10 +33,10 @@ }, "copyToOutput": { "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,12 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj index 7db8b2d38e2..54a29849643 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj @@ -38,21 +38,20 @@ ..\keys\Grpc.snk - - False - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll - False - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll + + ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + @@ -82,4 +81,4 @@ --> - \ No newline at end of file + diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec index 7b3b391009e..4ffd18ccb21 100644 --- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec +++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.nuspec @@ -16,7 +16,7 @@ - + diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config index a52d9e508ff..f8e353bf267 100644 --- a/src/csharp/Grpc.HealthCheck/packages.config +++ b/src/csharp/Grpc.HealthCheck/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json index 0e03e89d6a7..9d631229d8e 100644 --- a/src/csharp/Grpc.HealthCheck/project.json +++ b/src/csharp/Grpc.HealthCheck/project.json @@ -23,7 +23,7 @@ }, "dependencies": { "Grpc.Core": "1.1.0-dev", - "Google.Protobuf": "3.0.0-beta3" + "Google.Protobuf": "3.0.0" }, "frameworks": { "net45": { @@ -33,11 +33,8 @@ } }, "netstandard1.5": { - "imports": [ - "portable-net45" - ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj index 91fb3ce5bcf..ae58073b52d 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj @@ -39,30 +39,37 @@ ..\keys\Grpc.snk - - False + + + + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - False - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll + + ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - - diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config index c20d9ceed6a..11c6375c638 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config +++ b/src/csharp/Grpc.IntegrationTesting.Client/packages.config @@ -1,7 +1,10 @@  - - + + + + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json index 4a2846feea0..e54b5bd2964 100644 --- a/src/csharp/Grpc.IntegrationTesting.Client/project.json +++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,13 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj index dda26a68923..593bf0939db 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj @@ -58,7 +58,6 @@ - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config deleted file mode 100644 index e204447bb34..00000000000 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config new file mode 100644 index 00000000000..79ece06bef6 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/packages.config @@ -0,0 +1,3 @@ + + + diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json index 4a2846feea0..e54b5bd2964 100644 --- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json +++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,13 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj index f73d99dbd1a..d5c40ba9483 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj +++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj @@ -39,30 +39,37 @@ ..\keys\Grpc.snk - - False + + + + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - False - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll + + ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll - - False - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll + + ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - - diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config index c20d9ceed6a..11c6375c638 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config +++ b/src/csharp/Grpc.IntegrationTesting.Server/packages.config @@ -1,7 +1,10 @@  - - + + + + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json index 4a2846feea0..e54b5bd2964 100644 --- a/src/csharp/Grpc.IntegrationTesting.Server/project.json +++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,13 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config b/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config new file mode 100644 index 00000000000..79ece06bef6 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/packages.config @@ -0,0 +1,3 @@ + + + diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json index 4a2846feea0..e54b5bd2964 100644 --- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json +++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,13 +57,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs index eb7b55a2863..ac6c8d07401 100644 --- a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs @@ -48,8 +48,6 @@ namespace Grpc.IntegrationTesting { TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient(); - // TODO: replace Moq by some mocking library with CoreCLR support. -#if !NETSTANDARD1_5 [Test] public void ExpandedParamOverloadCanBeMocked() { @@ -72,7 +70,6 @@ namespace Grpc.IntegrationTesting Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest(), new CallOptions())); } -#endif [Test] public void DefaultMethodStubThrows_UnaryCall() diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 3a0764230d6..afd85fb4848 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -38,12 +38,6 @@ ..\keys\Grpc.snk - - ..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll - - - ..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll - @@ -51,18 +45,6 @@ ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll - - - ..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll - - - ..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll - - - ..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll @@ -70,11 +52,44 @@ ..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll - ..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll ..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll + + ..\packages\CommandLineParser.Unofficial.2.0.275\lib\net45\CommandLineParser.Unofficial.dll + + + ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll + + + ..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll + + + ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll + + + ..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + + + ..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll + + + ..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll + + + ..\packages\Moq.4.6.38-alpha\lib\net45\Moq.dll + @@ -149,4 +164,4 @@ - \ No newline at end of file + diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs index e27fe5b3d80..79fd18b6d52 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs @@ -56,24 +56,24 @@ namespace Grpc.IntegrationTesting { private class ClientOptions { - [Option("server_host", DefaultValue = "127.0.0.1")] + [Option("server_host", Default = "127.0.0.1")] public string ServerHost { get; set; } - [Option("server_host_override", DefaultValue = TestCredentials.DefaultHostOverride)] + [Option("server_host_override", Default = TestCredentials.DefaultHostOverride)] public string ServerHostOverride { get; set; } [Option("server_port", Required = true)] public int ServerPort { get; set; } - [Option("test_case", DefaultValue = "large_unary")] + [Option("test_case", Default = "large_unary")] public string TestCase { get; set; } // Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls) - [Option("use_tls", DefaultValue = false)] + [Option("use_tls", Default = false)] public bool? UseTls { get; set; } // Deliberately using nullable bool type to allow --use_test_ca=true syntax (as opposed to --use_test_ca) - [Option("use_test_ca", DefaultValue = false)] + [Option("use_test_ca", Default = false)] public bool? UseTestCa { get; set; } [Option("default_service_account", Required = false)] @@ -84,19 +84,6 @@ namespace Grpc.IntegrationTesting [Option("service_account_key_file", Required = false)] public string ServiceAccountKeyFile { get; set; } - - [HelpOption] - public string GetUsage() - { - var help = new HelpText - { - Heading = "gRPC C# interop testing client", - AddDashesToOption = true - }; - help.AddPreOptionsLine("Usage:"); - help.AddOptions(this); - return help; - } } ClientOptions options; @@ -108,14 +95,13 @@ namespace Grpc.IntegrationTesting public static void Run(string[] args) { - var options = new ClientOptions(); - if (!Parser.Default.ParseArguments(args, options)) - { - Environment.Exit(1); - } - - var interopClient = new InteropClient(options); - interopClient.Run().Wait(); + var parserResult = Parser.Default.ParseArguments(args) + .WithNotParsed(errors => Environment.Exit(1)) + .WithParsed(options => + { + var interopClient = new InteropClient(options); + interopClient.Run().Wait(); + }); } private async Task Run() @@ -145,26 +131,16 @@ namespace Grpc.IntegrationTesting if (options.TestCase == "jwt_token_creds") { -#if !NETSTANDARD1_5 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); Assert.IsTrue(googleCredential.IsCreateScopedRequired); credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials()); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } if (options.TestCase == "compute_engine_creds") { -#if !NETSTANDARD1_5 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); Assert.IsFalse(googleCredential.IsCreateScopedRequired); credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials()); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } return credentials; } @@ -395,7 +371,6 @@ namespace Grpc.IntegrationTesting public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope) { -#if !NETSTANDARD1_5 Console.WriteLine("running oauth2_auth_token"); ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope }); string oauth2Token = await credential.GetAccessTokenForRequestAsync(); @@ -413,15 +388,10 @@ namespace Grpc.IntegrationTesting Assert.True(oauthScope.Contains(response.OauthScope)); Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username); Console.WriteLine("Passed!"); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope) { -#if !NETSTANDARD1_5 Console.WriteLine("running per_rpc_creds"); ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync(); @@ -435,10 +405,6 @@ namespace Grpc.IntegrationTesting Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username); Console.WriteLine("Passed!"); -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client) @@ -731,17 +697,12 @@ namespace Grpc.IntegrationTesting // extracts the client_email field from service account file used for auth test cases private static string GetEmailFromServiceAccountFile() { -#if !NETSTANDARD1_5 string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS"); Assert.IsNotNull(keyFile); var jobject = JObject.Parse(File.ReadAllText(keyFile)); string email = jobject.GetValue("client_email").Value(); Assert.IsTrue(email.Length > 0); // spec requires nonempty client email. return email; -#else - // TODO(jtattermusch): implement this - throw new NotImplementedException("Not supported on CoreCLR yet"); -#endif } private static Metadata CreateTestMetadata() diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs index cd47e31c2be..4118f99c2b2 100644 --- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs +++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs @@ -51,25 +51,12 @@ namespace Grpc.IntegrationTesting { private class ServerOptions { - [Option("port", DefaultValue = 8070)] + [Option("port", Default = 8070)] public int Port { get; set; } // Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls) - [Option("use_tls", DefaultValue = false)] + [Option("use_tls", Default = false)] public bool? UseTls { get; set; } - - [HelpOption] - public string GetUsage() - { - var help = new HelpText - { - Heading = "gRPC C# interop testing server", - AddDashesToOption = true - }; - help.AddPreOptionsLine("Usage:"); - help.AddOptions(this); - return help; - } } ServerOptions options; @@ -81,14 +68,13 @@ namespace Grpc.IntegrationTesting public static void Run(string[] args) { - var options = new ServerOptions(); - if (!Parser.Default.ParseArguments(args, options)) - { - Environment.Exit(1); - } - - var interopServer = new InteropServer(options); - interopServer.Run(); + var parserResult = Parser.Default.ParseArguments(args) + .WithNotParsed(errors => Environment.Exit(1)) + .WithParsed(options => + { + var interopServer = new InteropServer(options); + interopServer.Run(); + }); } private void Run() diff --git a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs index 100ff0b5de9..21c8adb45c7 100644 --- a/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs +++ b/src/csharp/Grpc.IntegrationTesting/NUnitMain.cs @@ -49,7 +49,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 TextWriterLogger(Console.Error)); -#if NETSTANDARD1_5 +#if NETCOREAPP1_0 return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In); #else return new AutoRun().Execute(args); diff --git a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs index a7c9fa894de..865556c2426 100644 --- a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs +++ b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs @@ -52,21 +52,8 @@ namespace Grpc.IntegrationTesting { private class ServerOptions { - [Option("driver_port", DefaultValue = 0)] + [Option("driver_port", Default = 0)] public int DriverPort { get; set; } - - [HelpOption] - public string GetUsage() - { - var help = new HelpText - { - Heading = "gRPC C# performance testing worker", - AddDashesToOption = true - }; - help.AddPreOptionsLine("Usage:"); - help.AddOptions(this); - return help; - } } ServerOptions options; @@ -78,14 +65,13 @@ namespace Grpc.IntegrationTesting public static void Run(string[] args) { - var options = new ServerOptions(); - if (!Parser.Default.ParseArguments(args, options)) - { - Environment.Exit(1); - } - - var workerServer = new QpsWorker(options); - workerServer.RunAsync().Wait(); + var parserResult = Parser.Default.ParseArguments(args) + .WithNotParsed((x) => Environment.Exit(1)) + .WithParsed(options => + { + var workerServer = new QpsWorker(options); + workerServer.RunAsync().Wait(); + }); } private async Task RunAsync() diff --git a/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs b/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs index 74ee040ae49..750613b0784 100644 --- a/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs @@ -54,36 +54,23 @@ namespace Grpc.IntegrationTesting private class ClientOptions { - [Option("server_addresses", DefaultValue = "localhost:8080")] + [Option("server_addresses", Default = "localhost:8080")] public string ServerAddresses { get; set; } - [Option("test_cases", DefaultValue = "large_unary:100")] + [Option("test_cases", Default = "large_unary:100")] public string TestCases { get; set; } - [Option("test_duration_secs", DefaultValue = -1)] + [Option("test_duration_secs", Default = -1)] public int TestDurationSecs { get; set; } - [Option("num_channels_per_server", DefaultValue = 1)] + [Option("num_channels_per_server", Default = 1)] public int NumChannelsPerServer { get; set; } - [Option("num_stubs_per_channel", DefaultValue = 1)] + [Option("num_stubs_per_channel", Default = 1)] public int NumStubsPerChannel { get; set; } - [Option("metrics_port", DefaultValue = 8081)] + [Option("metrics_port", Default = 8081)] public int MetricsPort { get; set; } - - [HelpOption] - public string GetUsage() - { - var help = new HelpText - { - Heading = "gRPC C# stress test client", - AddDashesToOption = true - }; - help.AddPreOptionsLine("Usage:"); - help.AddOptions(this); - return help; - } } ClientOptions options; @@ -105,23 +92,21 @@ namespace Grpc.IntegrationTesting public static void Run(string[] args) { - var options = new ClientOptions(); - if (!Parser.Default.ParseArguments(args, options)) - { - Environment.Exit(1); - } - - GrpcPreconditions.CheckArgument(options.NumChannelsPerServer > 0); - GrpcPreconditions.CheckArgument(options.NumStubsPerChannel > 0); + var parserResult = Parser.Default.ParseArguments(args) + .WithNotParsed((x) => Environment.Exit(1)) + .WithParsed(options => { + GrpcPreconditions.CheckArgument(options.NumChannelsPerServer > 0); + GrpcPreconditions.CheckArgument(options.NumStubsPerChannel > 0); - var serverAddresses = options.ServerAddresses.Split(','); - GrpcPreconditions.CheckArgument(serverAddresses.Length > 0, "You need to provide at least one server address"); + var serverAddresses = options.ServerAddresses.Split(','); + GrpcPreconditions.CheckArgument(serverAddresses.Length > 0, "You need to provide at least one server address"); - var testCases = ParseWeightedTestCases(options.TestCases); - GrpcPreconditions.CheckArgument(testCases.Count > 0, "You need to provide at least one test case"); + var testCases = ParseWeightedTestCases(options.TestCases); + GrpcPreconditions.CheckArgument(testCases.Count > 0, "You need to provide at least one test case"); - var interopClient = new StressTestClient(options, serverAddresses.ToList(), testCases); - interopClient.Run().Wait(); + var interopClient = new StressTestClient(options, serverAddresses.ToList(), testCases); + interopClient.Run().Wait(); + }); } async Task Run() diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config index 3161c5b7557..a39fb3a23e9 100644 --- a/src/csharp/Grpc.IntegrationTesting/packages.config +++ b/src/csharp/Grpc.IntegrationTesting/packages.config @@ -1,13 +1,17 @@  - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json index 6297600ddc3..abc217b092a 100644 --- a/src/csharp/Grpc.IntegrationTesting/project.json +++ b/src/csharp/Grpc.IntegrationTesting/project.json @@ -15,10 +15,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -35,10 +35,10 @@ "copyToOutput": { "include": "data/*", "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } @@ -57,29 +57,27 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0-beta3", - "CommandLineParser": "1.9.71", + "Google.Protobuf": "3.0.0", + "CommandLineParser.Unofficial": "2.0.275", + "Moq": "4.6.38-alpha", "NUnit": "3.2.0", "NUnitLite": "3.2.0-*" }, "frameworks": { "net45": { - "dependencies": { - "Moq": "4.2.1510.2205" - }, "frameworkAssemblies": { "System.Runtime": "", "System.IO": "" } }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Linq.Expressions": "4.0.11-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0", + "System.Linq.Expressions": "4.1.0" } } } diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat index f05c0241b65..b92189c840e 100644 --- a/src/csharp/build_packages.bat +++ b/src/csharp/build_packages.bat @@ -31,10 +31,7 @@ @rem Current package versions set VERSION=1.1.0-dev -set PROTOBUF_VERSION=3.0.0-beta3 - -@rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well. -set VERSION_WITH_BETA=%VERSION%-beta +set PROTOBUF_VERSION=3.0.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe @@ -58,7 +55,6 @@ xcopy /Y /I ..\..\architecture=x64,language=protoc,platform=macos\artifacts\* pr @rem Fetch all dependencies %NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error -%NUGET% restore Grpc.sln || goto :error setlocal @@ -73,7 +69,7 @@ endlocal %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error %NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error -%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error +%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error %NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc index 3c8f0c56da4..81fc552fd10 100644 --- a/src/node/ext/call_credentials.cc +++ b/src/node/ext/call_credentials.cc @@ -68,6 +68,8 @@ using v8::Value; Nan::Callback *CallCredentials::constructor; Persistent CallCredentials::fun_tpl; +static Callback *plugin_callback; + CallCredentials::CallCredentials(grpc_call_credentials *credentials) : wrapped_credentials(credentials) {} @@ -88,6 +90,11 @@ void CallCredentials::Init(Local exports) { Nan::New(CreateFromPlugin)).ToLocalChecked()); Nan::Set(exports, Nan::New("CallCredentials").ToLocalChecked(), ctr); constructor = new Nan::Callback(ctr); + + Local callback_tpl = + Nan::New(PluginCallback); + plugin_callback = new Callback( + Nan::GetFunction(callback_tpl).ToLocalChecked()); } bool CallCredentials::HasInstance(Local val) { @@ -195,23 +202,28 @@ NAN_METHOD(PluginCallback) { return Nan::ThrowTypeError( "The callback's third argument must be an object"); } + if (!info[3]->IsObject()) { + return Nan::ThrowTypeError( + "The callback's fourth argument must be an object"); + } shared_ptr resources(new Resources); grpc_status_code code = static_cast( Nan::To(info[0]).FromJust()); Utf8String details_utf8_str(info[1]); char *details = *details_utf8_str; grpc_metadata_array array; + Local callback_data = Nan::To(info[3]).ToLocalChecked(); if (!CreateMetadataArray(Nan::To(info[2]).ToLocalChecked(), &array, resources)){ return Nan::ThrowError("Failed to parse metadata"); } grpc_credentials_plugin_metadata_cb cb = reinterpret_cast( - Nan::Get(info.Callee(), + Nan::Get(callback_data, Nan::New("cb").ToLocalChecked() ).ToLocalChecked().As()->Value()); void *user_data = - Nan::Get(info.Callee(), + Nan::Get(callback_data, Nan::New("user_data").ToLocalChecked() ).ToLocalChecked().As()->Value(); cb(user_data, array.metadata, array.count, code, details); @@ -227,17 +239,17 @@ NAUV_WORK_CB(SendPluginCallback) { while (!callbacks.empty()) { plugin_callback_data *data = callbacks.front(); callbacks.pop_front(); - // Attach cb and user_data to plugin_callback so that it can access them later - v8::Local plugin_callback = Nan::GetFunction( - Nan::New(PluginCallback)).ToLocalChecked(); - Nan::Set(plugin_callback, Nan::New("cb").ToLocalChecked(), + Local callback_data = Nan::New(); + Nan::Set(callback_data, Nan::New("cb").ToLocalChecked(), Nan::New(reinterpret_cast(data->cb))); - Nan::Set(plugin_callback, Nan::New("user_data").ToLocalChecked(), + Nan::Set(callback_data, Nan::New("user_data").ToLocalChecked(), Nan::New(data->user_data)); - const int argc = 2; + const int argc = 3; v8::Local argv[argc] = { Nan::New(data->service_url).ToLocalChecked(), - plugin_callback + callback_data, + // Get Local from Nan::Callback* + **plugin_callback }; Nan::Callback *callback = state->callback; callback->Call(argc, argv); diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json index 67f5301df7e..e6733598092 100644 --- a/src/node/health_check/package.json +++ b/src/node/health_check/package.json @@ -15,15 +15,15 @@ } ], "dependencies": { - "grpc": "^0.15.0", + "grpc": "^1.1.0-dev", "lodash": "^3.9.3", - "google-protobuf": "^3.0.0-alpha.5" + "google-protobuf": "^3.0.0" }, - "files": { + "files": [ "LICENSE", "health.js", "v1" - }, + ], "main": "src/node/index.js", "license": "BSD-3-Clause" } diff --git a/src/node/src/credentials.js b/src/node/src/credentials.js index b746d0625df..51ff1da01ec 100644 --- a/src/node/src/credentials.js +++ b/src/node/src/credentials.js @@ -71,6 +71,8 @@ var Metadata = require('./metadata.js'); var common = require('./common.js'); +var _ = require('lodash'); + /** * Create an SSL Credentials object. If using a client-side certificate, both * the second and third arguments must be passed. @@ -92,13 +94,14 @@ exports.createSsl = ChannelCredentials.createSsl; * @return {CallCredentials} The credentials object */ exports.createFromMetadataGenerator = function(metadata_generator) { - return CallCredentials.createFromPlugin(function(service_url, callback) { + return CallCredentials.createFromPlugin(function(service_url, cb_data, + callback) { metadata_generator({service_url: service_url}, function(error, metadata) { var code = grpc.status.OK; var message = ''; if (error) { message = error.message; - if (error.hasOwnProperty('code')) { + if (error.hasOwnProperty('code') && _.isFinite(error.code)) { code = error.code; } else { code = grpc.status.UNAUTHENTICATED; @@ -107,7 +110,7 @@ exports.createFromMetadataGenerator = function(metadata_generator) { metadata = new Metadata(); } } - callback(code, message, metadata._getCoreRepresentation()); + callback(code, message, metadata._getCoreRepresentation(), cb_data); }); }); }; diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js index 0a21572582e..305843f665e 100644 --- a/src/node/test/credentials_test.js +++ b/src/node/test/credentials_test.js @@ -71,7 +71,10 @@ var fakeSuccessfulGoogleCredentials = { var fakeFailingGoogleCredentials = { getRequestMetadata: function(service_url, callback) { setTimeout(function() { - callback(new Error('Authentication failure')); + // Google credentials currently adds string error codes to auth errors + var error = new Error('Authentication failure'); + error.code = 'ENOENT'; + callback(error); }, 0); } }; diff --git a/src/node/tools/bin/protoc.js b/src/node/tools/bin/protoc.js index 53fc5dc4280..7f8356867aa 100755 --- a/src/node/tools/bin/protoc.js +++ b/src/node/tools/bin/protoc.js @@ -47,7 +47,11 @@ var exe_ext = process.platform === 'win32' ? '.exe' : ''; var protoc = path.resolve(__dirname, 'protoc' + exe_ext); -var child_process = execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { +var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext); + +var args = ['--plugin=protoc-gen-grpc=' + plugin].concat(process.argv.slice(2)); + +var child_process = execFile(protoc, args, function(error, stdout, stderr) { if (error) { throw error; } diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec index 72cadb93199..0c3c3216abe 100644 --- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec +++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec @@ -36,7 +36,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 = '0.14.0' + v = '1.0.0' s.version = v s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.' s.description = <<-DESC @@ -82,10 +82,9 @@ Pod::Spec.new do |s| s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' } repo = 'grpc/grpc' - release = 'release-0_14_1' file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip" s.source = { - :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}", + :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}", # TODO(jcanizales): Add sha1 or sha256 # :sha1 => '??', } @@ -96,7 +95,7 @@ Pod::Spec.new do |s| s.preserve_paths = plugin # Restrict the protoc version to the one supported by this plugin. - s.dependency '!ProtoCompiler', '3.0.0-beta-3.1' + s.dependency '!ProtoCompiler', '3.0.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' diff --git a/src/objective-c/!ProtoCompiler.podspec b/src/objective-c/!ProtoCompiler.podspec index 5e59b25aee2..5018dedc066 100644 --- a/src/objective-c/!ProtoCompiler.podspec +++ b/src/objective-c/!ProtoCompiler.podspec @@ -36,7 +36,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' - v = '3.0.0-beta-3.1' + v = '3.0.0' s.version = v s.summary = 'The Protobuf Compiler (protoc) generates Objective-C files from .proto files' s.description = <<-DESC @@ -97,10 +97,9 @@ Pod::Spec.new do |s| s.authors = { 'The Protocol Buffers contributors' => 'protobuf@googlegroups.com' } repo = 'google/protobuf' - release = "v#{v}" file = "protoc-#{v}-osx-x86_64.zip" s.source = { - :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}", + :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}", # TODO(jcanizales): Add sha1 or sha256 # :sha1 => '??', } @@ -109,7 +108,7 @@ Pod::Spec.new do |s| 'google/**/*.proto' # Well-known protobuf types # Restrict the protobuf runtime version to the one supported by this version of protoc. - s.dependency 'Protobuf', v + s.dependency 'Protobuf', '~> 3.0' # For the Protobuf dependency not to complain: s.ios.deployment_target = '7.1' s.osx.deployment_target = '10.9' @@ -121,7 +120,7 @@ Pod::Spec.new do |s| repo_root = '../..' plugin = 'grpc_objective_c_plugin' s.prepare_command = <<-CMD - if [ ! -f protoc ]; then + if [ ! -f bin/protoc ]; then cd #{repo_root} # This will build protoc from the Protobuf submodule of gRPC, and put it in # #{repo_root}/bins/opt/protobuf. @@ -130,7 +129,9 @@ Pod::Spec.new do |s| # _we do not want_. Find a way for this to always build from source. make #{plugin} cd - + else + mv bin/protoc . + mv include/google . fi CMD - end diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec index 42b4434d0d3..e14f39b898c 100644 --- a/src/objective-c/BoringSSL.podspec +++ b/src/objective-c/BoringSSL.podspec @@ -31,7 +31,7 @@ Pod::Spec.new do |s| s.name = 'BoringSSL' - version = '4.0' + version = '6.0' s.version = version s.summary = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.' # Adapted from the homepage: @@ -67,8 +67,11 @@ Pod::Spec.new do |s| # "The name and email addresses of the library maintainers, not the Podspec maintainer." s.authors = 'Adam Langley', 'David Benjamin', 'Matt Braithwaite' - s.source = { :git => 'https://boringssl.googlesource.com/boringssl', - :tag => "version_for_cocoapods_#{version}" } + s.source = { + :git => 'https://boringssl.googlesource.com/boringssl', + :tag => "version_for_cocoapods_#{version}", + # :commit => '4ac2dc4c0d48ca45da4f66c40e60d6b425fa94a3', + } name = 'openssl' @@ -219,7 +222,7 @@ Pod::Spec.new do |s| * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ - /* This file was generated by err_data_generate.go. */ + /* This file was generated by err_data_generate.go. */ #include #include @@ -385,42 +388,42 @@ Pod::Spec.new do |s| 0x28340c19, 0x283480ac, 0x283500ea, - 0x2c322775, - 0x2c32a783, - 0x2c332795, - 0x2c33a7a7, - 0x2c3427bb, - 0x2c34a7cd, - 0x2c3527e8, - 0x2c35a7fa, - 0x2c36280d, + 0x2c322843, + 0x2c32a851, + 0x2c332863, + 0x2c33a875, + 0x2c342889, + 0x2c34a89b, + 0x2c3528b6, + 0x2c35a8c8, + 0x2c3628db, 0x2c36832d, - 0x2c37281a, - 0x2c37a82c, - 0x2c38283f, - 0x2c38a856, - 0x2c392864, - 0x2c39a874, - 0x2c3a2886, - 0x2c3aa89a, - 0x2c3b28ab, - 0x2c3ba8ca, - 0x2c3c28de, - 0x2c3ca8f4, - 0x2c3d290d, - 0x2c3da92a, - 0x2c3e293b, - 0x2c3ea949, - 0x2c3f2961, - 0x2c3fa979, - 0x2c402986, + 0x2c3728e8, + 0x2c37a8fa, + 0x2c38290d, + 0x2c38a924, + 0x2c392932, + 0x2c39a942, + 0x2c3a2954, + 0x2c3aa968, + 0x2c3b2979, + 0x2c3ba998, + 0x2c3c29ac, + 0x2c3ca9c2, + 0x2c3d29db, + 0x2c3da9f8, + 0x2c3e2a09, + 0x2c3eaa17, + 0x2c3f2a2f, + 0x2c3faa47, + 0x2c402a54, 0x2c4090e7, - 0x2c412997, - 0x2c41a9aa, + 0x2c412a65, + 0x2c41aa78, 0x2c4210c0, - 0x2c42a9bb, + 0x2c42aa89, 0x2c430720, - 0x2c43a8bc, + 0x2c43a98a, 0x30320000, 0x30328015, 0x3033001f, @@ -573,166 +576,174 @@ Pod::Spec.new do |s| 0x403b9861, 0x403c0064, 0x403c8083, - 0x403d186d, - 0x403d9883, - 0x403e1892, - 0x403e98a5, - 0x403f18bf, - 0x403f98cd, - 0x404018e2, - 0x404098f6, - 0x40411913, - 0x4041992e, - 0x40421947, - 0x4042995a, - 0x4043196e, - 0x40439986, - 0x4044199d, + 0x403d1890, + 0x403d98a6, + 0x403e18b5, + 0x403e98c8, + 0x403f18e2, + 0x403f98f0, + 0x40401905, + 0x40409919, + 0x40411936, + 0x40419951, + 0x4042196a, + 0x4042997d, + 0x40431991, + 0x404399a9, + 0x404419c0, 0x404480ac, - 0x404519b2, - 0x404599c4, - 0x404619e8, - 0x40469a08, - 0x40471a16, - 0x40479a2a, - 0x40481a3f, - 0x40489a58, - 0x40491a6f, - 0x40499a89, - 0x404a1aa0, - 0x404a9abe, - 0x404b1ad6, - 0x404b9aed, - 0x404c1b03, - 0x404c9b15, - 0x404d1b36, - 0x404d9b58, - 0x404e1b6c, - 0x404e9b79, - 0x404f1b90, - 0x404f9ba0, - 0x40501bca, - 0x40509bde, - 0x40511bf9, - 0x40519c09, - 0x40521c20, - 0x40529c32, - 0x40531c4a, - 0x40539c5d, - 0x40541c72, - 0x40549c95, - 0x40551ca3, - 0x40559cc0, - 0x40561ccd, - 0x40569ce6, - 0x40571cfe, - 0x40579d11, - 0x40581d26, - 0x40589d38, - 0x40591d48, - 0x40599d61, - 0x405a1d75, - 0x405a9d85, - 0x405b1d9d, - 0x405b9dae, - 0x405c1dc1, - 0x405c9dd2, - 0x405d1ddf, - 0x405d9df6, - 0x405e1e16, + 0x404519d5, + 0x404599e7, + 0x40461a0b, + 0x40469a2b, + 0x40471a39, + 0x40479a60, + 0x40481a89, + 0x40489aa2, + 0x40491ab9, + 0x40499ad3, + 0x404a1aea, + 0x404a9b08, + 0x404b1b20, + 0x404b9b37, + 0x404c1b4d, + 0x404c9b5f, + 0x404d1b80, + 0x404d9ba2, + 0x404e1bb6, + 0x404e9bc3, + 0x404f1bf0, + 0x404f9c19, + 0x40501c43, + 0x40509c57, + 0x40511c72, + 0x40519c82, + 0x40521c99, + 0x40529cbd, + 0x40531cd5, + 0x40539ce8, + 0x40541cfd, + 0x40549d20, + 0x40551d2e, + 0x40559d4b, + 0x40561d58, + 0x40569d71, + 0x40571d89, + 0x40579d9c, + 0x40581db1, + 0x40589dc3, + 0x40591df2, + 0x40599e0b, + 0x405a1e1f, + 0x405a9e2f, + 0x405b1e47, + 0x405b9e58, + 0x405c1e6b, + 0x405c9e7c, + 0x405d1e89, + 0x405d9ea0, + 0x405e1ec0, 0x405e8a95, - 0x405f1e37, - 0x405f9e44, - 0x40601e52, - 0x40609e74, - 0x40611e9c, - 0x40619eb1, - 0x40621ec8, - 0x40629ed9, - 0x40631eea, - 0x40639eff, - 0x40641f16, - 0x40649f27, - 0x40651f42, - 0x40659f59, - 0x40661f71, - 0x40669f9b, - 0x40671fc6, - 0x40679fe7, - 0x40681ffa, - 0x4068a01b, - 0x4069204d, - 0x4069a07b, - 0x406a209c, - 0x406aa0bc, - 0x406b2244, - 0x406ba267, - 0x406c227d, - 0x406ca4a9, - 0x406d24d8, - 0x406da500, - 0x406e2519, - 0x406ea531, - 0x406f2550, - 0x406fa565, - 0x40702578, - 0x4070a595, + 0x405f1ee1, + 0x405f9eee, + 0x40601efc, + 0x40609f1e, + 0x40611f46, + 0x40619f5b, + 0x40621f72, + 0x40629f83, + 0x40631f94, + 0x40639fa9, + 0x40641fc0, + 0x40649fd1, + 0x40651fec, + 0x4065a003, + 0x4066201b, + 0x4066a045, + 0x40672070, + 0x4067a091, + 0x406820a4, + 0x4068a0c5, + 0x406920f7, + 0x4069a125, + 0x406a2146, + 0x406aa166, + 0x406b22ee, + 0x406ba311, + 0x406c2327, + 0x406ca553, + 0x406d2582, + 0x406da5aa, + 0x406e25c3, + 0x406ea5db, + 0x406f25fa, + 0x406fa60f, + 0x40702622, + 0x4070a63f, 0x40710800, - 0x4071a5a7, - 0x407225ba, - 0x4072a5d3, - 0x407325eb, + 0x4071a651, + 0x40722664, + 0x4072a67d, + 0x40732695, 0x4073936d, - 0x407425ff, - 0x4074a619, - 0x4075262a, - 0x4075a63e, - 0x4076264c, + 0x407426a9, + 0x4074a6c3, + 0x407526d4, + 0x4075a6e8, + 0x407626f6, 0x407691aa, - 0x40772671, - 0x4077a693, - 0x407826ae, - 0x4078a6c3, - 0x407926da, - 0x4079a6f0, - 0x407a26fc, - 0x407aa70f, - 0x407b2724, - 0x407ba736, - 0x407c274b, - 0x407ca754, - 0x407d2036, - 0x407d9bb0, - 0x41f4216f, - 0x41f92201, - 0x41fe20f4, - 0x41fea2d0, - 0x41ff23c1, - 0x42032188, - 0x420821aa, - 0x4208a1e6, - 0x420920d8, - 0x4209a220, - 0x420a212f, - 0x420aa10f, - 0x420b214f, - 0x420ba1c8, - 0x420c23dd, - 0x420ca29d, - 0x420d22b7, - 0x420da2ee, - 0x42122308, - 0x421723a4, - 0x4217a34a, - 0x421c236c, - 0x421f2327, - 0x422123f4, - 0x42262387, - 0x422b248d, - 0x422ba456, - 0x422c2475, - 0x422ca430, - 0x422d240f, + 0x4077271b, + 0x4077a73d, + 0x40782758, + 0x4078a791, + 0x407927a8, + 0x4079a7be, + 0x407a27ca, + 0x407aa7dd, + 0x407b27f2, + 0x407ba804, + 0x407c2819, + 0x407ca822, + 0x407d20e0, + 0x407d9c29, + 0x407e276d, + 0x407e9dd3, + 0x407f1a4d, + 0x407f986d, + 0x40801c00, + 0x40809a75, + 0x40811cab, + 0x40819bda, + 0x41f42219, + 0x41f922ab, + 0x41fe219e, + 0x41fea37a, + 0x41ff246b, + 0x42032232, + 0x42082254, + 0x4208a290, + 0x42092182, + 0x4209a2ca, + 0x420a21d9, + 0x420aa1b9, + 0x420b21f9, + 0x420ba272, + 0x420c2487, + 0x420ca347, + 0x420d2361, + 0x420da398, + 0x421223b2, + 0x4217244e, + 0x4217a3f4, + 0x421c2416, + 0x421f23d1, + 0x4221249e, + 0x42262431, + 0x422b2537, + 0x422ba500, + 0x422c251f, + 0x422ca4da, + 0x422d24b9, 0x4432072b, 0x4432873a, 0x44330746, @@ -775,69 +786,69 @@ Pod::Spec.new do |s| 0x4c3d136d, 0x4c3d937c, 0x4c3e1389, - 0x503229cd, - 0x5032a9dc, - 0x503329e7, - 0x5033a9f7, - 0x50342a10, - 0x5034aa2a, - 0x50352a38, - 0x5035aa4e, - 0x50362a60, - 0x5036aa76, - 0x50372a8f, - 0x5037aaa2, - 0x50382aba, - 0x5038aacb, - 0x50392ae0, - 0x5039aaf4, - 0x503a2b14, - 0x503aab2a, - 0x503b2b42, - 0x503bab54, - 0x503c2b70, - 0x503cab87, - 0x503d2ba0, - 0x503dabb6, - 0x503e2bc3, - 0x503eabd9, - 0x503f2beb, + 0x50322a9b, + 0x5032aaaa, + 0x50332ab5, + 0x5033aac5, + 0x50342ade, + 0x5034aaf8, + 0x50352b06, + 0x5035ab1c, + 0x50362b2e, + 0x5036ab44, + 0x50372b5d, + 0x5037ab70, + 0x50382b88, + 0x5038ab99, + 0x50392bae, + 0x5039abc2, + 0x503a2be2, + 0x503aabf8, + 0x503b2c10, + 0x503bac22, + 0x503c2c3e, + 0x503cac55, + 0x503d2c6e, + 0x503dac84, + 0x503e2c91, + 0x503eaca7, + 0x503f2cb9, 0x503f8382, - 0x50402bfe, - 0x5040ac0e, - 0x50412c28, - 0x5041ac37, - 0x50422c51, - 0x5042ac6e, - 0x50432c7e, - 0x5043ac8e, - 0x50442c9d, + 0x50402ccc, + 0x5040acdc, + 0x50412cf6, + 0x5041ad05, + 0x50422d1f, + 0x5042ad3c, + 0x50432d4c, + 0x5043ad5c, + 0x50442d6b, 0x5044843f, - 0x50452cb1, - 0x5045accf, - 0x50462ce2, - 0x5046acf8, - 0x50472d0a, - 0x5047ad1f, - 0x50482d45, - 0x5048ad53, - 0x50492d66, - 0x5049ad7b, - 0x504a2d91, - 0x504aada1, - 0x504b2dc1, - 0x504badd4, - 0x504c2df7, - 0x504cae25, - 0x504d2e37, - 0x504dae54, - 0x504e2e6f, - 0x504eae8b, - 0x504f2e9d, - 0x504faeb4, - 0x50502ec3, + 0x50452d7f, + 0x5045ad9d, + 0x50462db0, + 0x5046adc6, + 0x50472dd8, + 0x5047aded, + 0x50482e13, + 0x5048ae21, + 0x50492e34, + 0x5049ae49, + 0x504a2e5f, + 0x504aae6f, + 0x504b2e8f, + 0x504baea2, + 0x504c2ec5, + 0x504caef3, + 0x504d2f05, + 0x504daf22, + 0x504e2f3d, + 0x504eaf59, + 0x504f2f6b, + 0x504faf82, + 0x50502f91, 0x505086ef, - 0x50512ed6, + 0x50512fa4, 0x58320ec9, 0x68320e8b, 0x68328c25, @@ -1198,6 +1209,7 @@ Pod::Spec.new do |s| "BAD_SSL_FILETYPE\\0" "BAD_WRITE_RETRY\\0" "BIO_NOT_SET\\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0" "CA_DN_LENGTH_MISMATCH\\0" "CA_DN_TOO_LONG\\0" "CCS_RECEIVED_EARLY\\0" @@ -1218,7 +1230,9 @@ Pod::Spec.new do |s| "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\\0" "DH_P_TOO_LONG\\0" "DIGEST_CHECK_FAILED\\0" + "DOWNGRADE_DETECTED\\0" "DTLS_MESSAGE_TOO_BIG\\0" + "DUPLICATE_EXTENSION\\0" "ECC_CERT_NOT_FOR_SIGNING\\0" "EMS_STATE_INCONSISTENT\\0" "ENCRYPTED_LENGTH_TOO_LONG\\0" @@ -1233,7 +1247,9 @@ Pod::Spec.new do |s| "HTTPS_PROXY_REQUEST\\0" "HTTP_REQUEST\\0" "INAPPROPRIATE_FALLBACK\\0" + "INVALID_ALPN_PROTOCOL\\0" "INVALID_COMMAND\\0" + "INVALID_COMPRESSION_LIST\\0" "INVALID_MESSAGE\\0" "INVALID_OUTER_RECORD_TYPE\\0" "INVALID_SSL_SESSION\\0" @@ -1241,6 +1257,7 @@ Pod::Spec.new do |s| "LENGTH_MISMATCH\\0" "LIBRARY_HAS_NO_CIPHERS\\0" "MISSING_EXTENSION\\0" + "MISSING_KEY_SHARE\\0" "MISSING_RSA_CERTIFICATE\\0" "MISSING_TMP_DH_KEY\\0" "MISSING_TMP_ECDH_KEY\\0" @@ -1254,6 +1271,7 @@ Pod::Spec.new do |s| "NO_CIPHERS_AVAILABLE\\0" "NO_CIPHERS_PASSED\\0" "NO_CIPHER_MATCH\\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\\0" "NO_COMPRESSION_SPECIFIED\\0" "NO_METHOD_SPECIFIED\\0" "NO_P256_SUPPORT\\0" @@ -1344,6 +1362,7 @@ Pod::Spec.new do |s| "UNSUPPORTED_COMPRESSION_ALGORITHM\\0" "UNSUPPORTED_ELLIPTIC_CURVE\\0" "UNSUPPORTED_PROTOCOL\\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\\0" "WRONG_CERTIFICATE_TYPE\\0" "WRONG_CIPHER_RETURNED\\0" "WRONG_CURVE\\0" diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h index 646bf43b547..4a3f3fa4a1a 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.h @@ -43,7 +43,10 @@ * Use the provided @c userAgentPrefix at the beginning of the HTTP User Agent string for all calls * to the specified @c host. */ -+ (void)setUserAgentPrefix:(NSString *)userAgentPrefix forHost:(NSString *)host; ++ (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host; + +/** The default response size limit is 4MB. Set this to override that default. */ ++ (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host; + (void)closeOpenConnections DEPRECATED_MSG_ATTRIBUTE("The API for this feature is experimental, " "and might be removed or modified at any " diff --git a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m index bcc3b915075..7fab357e932 100644 --- a/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m +++ b/src/objective-c/GRPCClient/GRPCCall+ChannelArg.m @@ -37,15 +37,16 @@ @implementation GRPCCall (ChannelArg) -+ (void)setUserAgentPrefix:(NSString *)userAgentPrefix forHost:(NSString *)host { - if (!host) { - [NSException raise:NSInvalidArgumentException - format:@"host and userAgentPrefix must be provided."]; - } ++ (void)setUserAgentPrefix:(nonnull NSString *)userAgentPrefix forHost:(nonnull NSString *)host { GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; hostConfig.userAgentPrefix = userAgentPrefix; } ++ (void)setResponseSizeLimit:(NSUInteger)limit forHost:(nonnull NSString *)host { + GRPCHost *hostConfig = [GRPCHost hostWithAddress:host]; + hostConfig.responseSizeLimitOverride = @(limit); +} + + (void)closeOpenConnections { [GRPCHost flushChannelCache]; } diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.h b/src/objective-c/GRPCClient/GRPCCall+Tests.h index ccc5723ec70..184ad09c5c8 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.h +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.h @@ -57,4 +57,10 @@ * more than one invocation of the methods of this category. */ + (void)useInsecureConnectionsForHost:(NSString *)host; + +/** + * Resets all host configurations to their default values, and flushes all connections from the + * cache. + */ ++ (void)resetHostSettings; @end diff --git a/src/objective-c/GRPCClient/GRPCCall+Tests.m b/src/objective-c/GRPCClient/GRPCCall+Tests.m index b9456691bd8..656cba8fec6 100644 --- a/src/objective-c/GRPCClient/GRPCCall+Tests.m +++ b/src/objective-c/GRPCClient/GRPCCall+Tests.m @@ -61,4 +61,7 @@ hostConfig.secure = NO; } ++ (void)resetHostSettings { + [GRPCHost resetAllHostSettings]; +} @end diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m index da9473f9a27..05a1d10f6de 100644 --- a/src/objective-c/GRPCClient/GRPCCall.m +++ b/src/objective-c/GRPCClient/GRPCCall.m @@ -208,13 +208,9 @@ NSString * const kGRPCTrailersKey = @"io.grpc.TrailersKey"; // don't want to throw, because the app shouldn't crash for a behavior // that's on the hands of any server to have. Instead we finish and ask // the server to cancel. - // - // TODO(jcanizales): No canonical code is appropriate for this situation - // (because it's just a client problem). Use another domain and an - // appropriately-documented code. [weakSelf finishWithError:[NSError errorWithDomain:kGRPCErrorDomain - code:GRPCErrorCodeInternal - userInfo:nil]]; + code:GRPCErrorCodeResourceExhausted + userInfo:@{NSLocalizedDescriptionKey: @"Client does not have enough memory to hold the server response."}]]; [weakSelf cancelCall]; return; } diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h index 40e78a92d6d..5bada2dd50c 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.h +++ b/src/objective-c/GRPCClient/private/GRPCChannel.h @@ -59,8 +59,8 @@ struct grpc_channel_credentials; * Creates a secure channel to the specified @c host using Cronet as a transport mechanism. */ #ifdef GRPC_COMPILE_WITH_CRONET -+ (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host - channelArgs:(NSDictionary *)channelArgs; ++ (nullable GRPCChannel *)secureCronetChannelWithHost:(nonnull NSString *)host + channelArgs:(nonnull NSDictionary *)channelArgs; #endif /** * Creates a secure channel to the specified @c host using the specified @c credentials and diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m index 7b7b79e1c62..e49aceefe18 100644 --- a/src/objective-c/GRPCClient/private/GRPCChannel.m +++ b/src/objective-c/GRPCClient/private/GRPCChannel.m @@ -47,7 +47,7 @@ #endif #import "GRPCCompletionQueue.h" -void freeChannelArgs(grpc_channel_args *channel_args) { +static void FreeChannelArgs(grpc_channel_args *channel_args) { for (size_t i = 0; i < channel_args->num_args; ++i) { grpc_arg *arg = &channel_args->args[i]; gpr_free(arg->key); @@ -65,7 +65,7 @@ void freeChannelArgs(grpc_channel_args *channel_args) { * value responds to @c @selector(intValue). Otherwise, an exception will be raised. The caller of * this function is responsible for calling @c freeChannelArgs on a non-NULL returned value. */ -grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { +static grpc_channel_args *BuildChannelArgs(NSDictionary *dictionary) { if (!dictionary) { return NULL; } @@ -115,10 +115,12 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { } if (self = [super init]) { - _channelArgs = buildChannelArgs(channelArgs); + _channelArgs = BuildChannelArgs(channelArgs); _host = [host copy]; - _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs, - NULL); + _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine, + _host.UTF8String, + _channelArgs, + NULL); } return self; @@ -138,7 +140,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { } if (self = [super init]) { - _channelArgs = buildChannelArgs(channelArgs); + _channelArgs = BuildChannelArgs(channelArgs); _host = [host copy]; if (secure) { _unmanagedChannel = grpc_secure_channel_create(credentials, _host.UTF8String, _channelArgs, @@ -155,7 +157,7 @@ grpc_channel_args * buildChannelArgs(NSDictionary *dictionary) { // TODO(jcanizales): Be sure to add a test with a server that closes the connection prematurely, // as in the past that made this call to crash. grpc_channel_destroy(_unmanagedChannel); - freeChannelArgs(_channelArgs); + FreeChannelArgs(_channelArgs); } #ifdef GRPC_COMPILE_WITH_CRONET diff --git a/src/objective-c/GRPCClient/private/GRPCHost.h b/src/objective-c/GRPCClient/private/GRPCHost.h index 350c69bf8e8..c8b5dd315b0 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.h +++ b/src/objective-c/GRPCClient/private/GRPCHost.h @@ -42,6 +42,7 @@ struct grpc_channel_credentials; @interface GRPCHost : NSObject + (void)flushChannelCache; ++ (void)resetAllHostSettings; @property(nonatomic, readonly) NSString *address; @property(nonatomic, copy, nullable) NSString *userAgentPrefix; @@ -53,6 +54,10 @@ struct grpc_channel_credentials; @property(nonatomic, copy, nullable) NSString *hostNameOverride; +/** The default response size limit is 4MB. Set this to override that default. */ +@property(nonatomic, strong, nullable) NSNumber *responseSizeLimitOverride; + + - (nullable instancetype)init NS_UNAVAILABLE; /** Host objects initialized with the same address are the same. */ + (nullable instancetype)hostWithAddress:(NSString *)address; diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m index 08c699f99e2..9cd9593d172 100644 --- a/src/objective-c/GRPCClient/private/GRPCHost.m +++ b/src/objective-c/GRPCClient/private/GRPCHost.m @@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN // TODO(jcanizales): Generate the version in a standalone header, from templates. Like // templates/src/core/surface/version.c.template . -#define GRPC_OBJC_VERSION_STRING @"0.13.0" +#define GRPC_OBJC_VERSION_STRING @"1.0.0" static NSMutableDictionary *kHostCache; @@ -113,6 +113,12 @@ static NSMutableDictionary *kHostCache; } } ++ (void)resetAllHostSettings { + @synchronized (kHostCache) { + kHostCache = [NSMutableDictionary dictionary]; + } +} + - (nullable grpc_call *)unmanagedCallWithPath:(NSString *)path completionQueue:(GRPCCompletionQueue *)queue { GRPCChannel *channel; @@ -209,6 +215,10 @@ static NSMutableDictionary *kHostCache; if (_secure && _hostNameOverride) { args[@GRPC_SSL_TARGET_NAME_OVERRIDE_ARG] = _hostNameOverride; } + + if (_responseSizeLimitOverride) { + args[@GRPC_ARG_MAX_MESSAGE_LENGTH] = _responseSizeLimitOverride; + } return args; } diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m index e7232f26832..83d1b655e8d 100644 --- a/src/objective-c/ProtoRPC/ProtoRPC.m +++ b/src/objective-c/ProtoRPC/ProtoRPC.m @@ -33,7 +33,11 @@ #import "ProtoRPC.h" -#import +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import +#endif #import #import diff --git a/src/objective-c/README.md b/src/objective-c/README.md index a0ca5f448a0..3624475b9cc 100644 --- a/src/objective-c/README.md +++ b/src/objective-c/README.md @@ -48,7 +48,7 @@ Pod::Spec.new do |s| src = '.' # We'll use protoc with the gRPC plugin. - s.dependency '!ProtoCompiler-gRPCPlugin', '~> 0.14' + s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0' # Pods directory corresponding to this app's Podfile, relative to the location of this podspec. pods_root = '/Pods' @@ -82,10 +82,6 @@ Pod::Spec.new do |s| ms.requires_arc = false # The generated files depend on the protobuf runtime. ms.dependency 'Protobuf' - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with @@ -98,6 +94,13 @@ Pod::Spec.new do |s| ss.dependency 'gRPC-ProtoRPC' ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end ``` diff --git a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m index f3242e4fa95..6ee1545d251 100644 --- a/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m +++ b/src/objective-c/RxLibrary/transformations/GRXMappingWriter.m @@ -33,10 +33,6 @@ #import "GRXMappingWriter.h" -static id (^kIdentity)(id value) = ^id(id value) { - return value; -}; - @interface GRXForwardingWriter () @end @@ -51,7 +47,9 @@ static id (^kIdentity)(id value) = ^id(id value) { // Designated initializer - (instancetype)initWithWriter:(GRXWriter *)writer map:(id (^)(id value))map { if ((self = [super initWithWriter:writer])) { - _map = map ?: kIdentity; + _map = map ?: ^id(id value) { + return value; + }; } return self; } diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec index 6e783fb5adb..ea6181316a4 100644 --- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" @@ -35,10 +35,6 @@ Pod::Spec.new do |s| ms.header_mappings_dir = '.' ms.requires_arc = false ms.dependency 'Protobuf' - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end s.subspec 'Services' do |ss| @@ -48,4 +44,11 @@ Pod::Spec.new do |s| ss.dependency 'gRPC-ProtoRPC' ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/src/objective-c/examples/RemoteTestClient/test.proto b/src/objective-c/examples/RemoteTestClient/test.proto index 514c3b80955..5c359c5c129 100644 --- a/src/objective-c/examples/RemoteTestClient/test.proto +++ b/src/objective-c/examples/RemoteTestClient/test.proto @@ -31,7 +31,7 @@ // of unary/streaming requests/responses. syntax = "proto3"; -import "empty.proto"; +import "google/protobuf/empty.proto"; import "messages.proto"; package grpc.testing; @@ -42,7 +42,7 @@ option objc_class_prefix = "RMT"; // performance with various types of payload. service TestService { // One empty request followed by one empty response. - rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty); + rpc EmptyCall(google.protobuf.Empty) returns (google.protobuf.Empty); // One request followed by one response. rpc UnaryCall(SimpleRequest) returns (SimpleResponse); diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile index 8740b2f9638..f6f0c00d5d0 100644 --- a/src/objective-c/examples/Sample/Podfile +++ b/src/objective-c/examples/Sample/Podfile @@ -3,6 +3,8 @@ platform :ios, '8.0' install! 'cocoapods', :deterministic_uuids => false +use_frameworks! if ENV['FRAMEWORKS'] == 'YES' + # Location of gRPC's repo root relative to this file. GRPC_LOCAL_SRC = '../../../..' diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj index 5c2a6d14f96..ab7159cda2f 100644 --- a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - 426A5020E0E158A101BCA1D9 /* libPods-Sample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C20055928615A6F8434E26B4 /* libPods-Sample.a */; }; + 3F035697392F601049D3DDE1 /* Pods_Sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC1B27EA0C428429B07BC34B /* Pods_Sample.framework */; }; 6369A2701A9322E20015FC5C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A26F1A9322E20015FC5C /* main.m */; }; 6369A2731A9322E20015FC5C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2721A9322E20015FC5C /* AppDelegate.m */; }; 6369A2761A9322E20015FC5C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2751A9322E20015FC5C /* ViewController.m */; }; @@ -26,7 +26,7 @@ 6369A2751A9322E20015FC5C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 6369A2781A9322E20015FC5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 6369A27A1A9322E20015FC5C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - C20055928615A6F8434E26B4 /* libPods-Sample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Sample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + CC1B27EA0C428429B07BC34B /* Pods_Sample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Sample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E3C01DF315C4E7433BCEC6E6 /* Pods-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Sample/Pods-Sample.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -35,7 +35,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 426A5020E0E158A101BCA1D9 /* libPods-Sample.a in Frameworks */, + 3F035697392F601049D3DDE1 /* Pods_Sample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -95,7 +95,7 @@ C4C2C5219053E079C9EFB930 /* Frameworks */ = { isa = PBXGroup; children = ( - C20055928615A6F8434E26B4 /* libPods-Sample.a */, + CC1B27EA0C428429B07BC34B /* Pods_Sample.framework */, ); name = Frameworks; sourceTree = ""; @@ -129,7 +129,7 @@ 6369A2621A9322E20015FC5C /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0610; + LastUpgradeCheck = 0730; ORGANIZATIONNAME = gRPC; TargetAttributes = { 6369A2691A9322E20015FC5C = { @@ -260,6 +260,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_OPTIMIZATION_LEVEL = 0; @@ -325,6 +326,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Sample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -336,6 +338,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Sample/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "org.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/src/objective-c/examples/Sample/Sample/Info.plist b/src/objective-c/examples/Sample/Sample/Info.plist index 4436635ab4e..2cdf09dc2fc 100644 --- a/src/objective-c/examples/Sample/Sample/Info.plist +++ b/src/objective-c/examples/Sample/Sample/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - org.grpc.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m index 433a8a2ba3b..70244ee62dd 100644 --- a/src/objective-c/examples/Sample/Sample/ViewController.m +++ b/src/objective-c/examples/Sample/Sample/ViewController.m @@ -66,9 +66,9 @@ // Same example call using the generic gRPC client library: - ProtoMethod *method = [[ProtoMethod alloc] initWithPackage:@"grpc.testing" - service:@"TestService" - method:@"UnaryCall"]; + GRPCProtoMethod *method = [[GRPCProtoMethod alloc] initWithPackage:@"grpc.testing" + service:@"TestService" + method:@"UnaryCall"]; GRXWriter *requestsWriter = [GRXWriter writerWithValue:[request data]]; diff --git a/src/objective-c/examples/SwiftSample/Info.plist b/src/objective-c/examples/SwiftSample/Info.plist index 10f0450b346..2cdf09dc2fc 100644 --- a/src/objective-c/examples/SwiftSample/Info.plist +++ b/src/objective-c/examples/SwiftSample/Info.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier - io.grpc.$(PRODUCT_NAME:rfc1034identifier) + $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/src/objective-c/examples/SwiftSample/Podfile b/src/objective-c/examples/SwiftSample/Podfile index 2f783340f56..b08a346ae2a 100644 --- a/src/objective-c/examples/SwiftSample/Podfile +++ b/src/objective-c/examples/SwiftSample/Podfile @@ -3,6 +3,8 @@ platform :ios, '8.0' install! 'cocoapods', :deterministic_uuids => false +use_frameworks! + # Location of gRPC's repo root relative to this file. GRPC_LOCAL_SRC = '../../../..' diff --git a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj index 2a1b30f2cf9..afc3da71168 100644 --- a/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj +++ b/src/objective-c/examples/SwiftSample/SwiftSample.xcodeproj/project.pbxproj @@ -7,11 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 2C0B024CB798839E17F76126 /* Pods_SwiftSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B394F343BDE186C5436DBDB9 /* Pods_SwiftSample.framework */; }; 633BFFC81B950B210007E424 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633BFFC71B950B210007E424 /* AppDelegate.swift */; }; 633BFFCA1B950B210007E424 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 633BFFC91B950B210007E424 /* ViewController.swift */; }; 633BFFCD1B950B210007E424 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 633BFFCB1B950B210007E424 /* Main.storyboard */; }; 633BFFCF1B950B210007E424 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 633BFFCE1B950B210007E424 /* Images.xcassets */; }; - 92EDB1408A1E1E7DDAB25D9C /* libPods-SwiftSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 69BB5C6CA3C1F97E007AC527 /* libPods-SwiftSample.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -21,9 +21,8 @@ 633BFFC91B950B210007E424 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 633BFFCC1B950B210007E424 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 633BFFCE1B950B210007E424 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6367AD231B951655007FD3A4 /* Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Bridging-Header.h"; sourceTree = ""; }; - 69BB5C6CA3C1F97E007AC527 /* libPods-SwiftSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-SwiftSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A7E614A494D89D01BB395761 /* Pods-SwiftSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftSample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftSample/Pods-SwiftSample.debug.xcconfig"; sourceTree = ""; }; + B394F343BDE186C5436DBDB9 /* Pods_SwiftSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SwiftSample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; C314E3E246AF23AC29B38FCF /* Pods-SwiftSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SwiftSample.release.xcconfig"; path = "Pods/Target Support Files/Pods-SwiftSample/Pods-SwiftSample.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -32,7 +31,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 92EDB1408A1E1E7DDAB25D9C /* libPods-SwiftSample.a in Frameworks */, + 2C0B024CB798839E17F76126 /* Pods_SwiftSample.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -74,7 +73,6 @@ 633BFFCB1B950B210007E424 /* Main.storyboard */, 633BFFCE1B950B210007E424 /* Images.xcassets */, 633BFFC51B950B210007E424 /* Supporting Files */, - 6367AD231B951655007FD3A4 /* Bridging-Header.h */, ); name = SwiftSample; sourceTree = SOURCE_ROOT; @@ -90,7 +88,7 @@ 9D63A7F6423989BA306810CA /* Frameworks */ = { isa = PBXGroup; children = ( - 69BB5C6CA3C1F97E007AC527 /* libPods-SwiftSample.a */, + B394F343BDE186C5436DBDB9 /* Pods_SwiftSample.framework */, ); name = Frameworks; sourceTree = ""; @@ -125,7 +123,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 0640; + LastUpgradeCheck = 0730; ORGANIZATIONNAME = gRPC; TargetAttributes = { 633BFFC11B950B210007E424 = { @@ -256,6 +254,7 @@ COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -325,8 +324,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = ""; USER_HEADER_SEARCH_PATHS = ""; }; name = Debug; @@ -338,8 +338,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = "io.grpc.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = ""; USER_HEADER_SEARCH_PATHS = ""; }; name = Release; diff --git a/src/objective-c/examples/SwiftSample/ViewController.swift b/src/objective-c/examples/SwiftSample/ViewController.swift index 2a95d2de516..66d4fa9412c 100644 --- a/src/objective-c/examples/SwiftSample/ViewController.swift +++ b/src/objective-c/examples/SwiftSample/ViewController.swift @@ -33,6 +33,8 @@ import UIKit +import RemoteTest + class ViewController: UIViewController { override func viewDidLoad() { @@ -60,7 +62,7 @@ class ViewController: UIViewController { // Same but manipulating headers: - var RPC : ProtoRPC! // Needed to convince Swift to capture by reference (__block) + var RPC : GRPCProtoCall! // Needed to convince Swift to capture by reference (__block) RPC = service.RPCToUnaryCallWithRequest(request) { response, error in if let response = response { NSLog("2. Finished successfully with response:\n\(response)") @@ -79,7 +81,7 @@ class ViewController: UIViewController { // Same example call using the generic gRPC client library: - let method = ProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall") + let method = GRPCProtoMethod(package: "grpc.testing", service: "TestService", method: "UnaryCall") let requestsWriter = GRXWriter(value: request.data()) @@ -89,7 +91,7 @@ class ViewController: UIViewController { call.startWithWriteable(GRXWriteable { response, error in if let response = response as? NSData { - NSLog("3. Received response:\n\(RMTSimpleResponse(data: response, error: nil))") + NSLog("3. Received response:\n\(try! RMTSimpleResponse(data: response))") } else { NSLog("3. Finished with error: \(error!)") } diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist b/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist new file mode 100644 index 00000000000..fbeeb96ba6c --- /dev/null +++ b/src/objective-c/tests/CoreCronetEnd2EndTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + gRPC.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/src/objective-c/tests/GRPCClientTests.m b/src/objective-c/tests/GRPCClientTests.m index 1167a715bb9..916a335802a 100644 --- a/src/objective-c/tests/GRPCClientTests.m +++ b/src/objective-c/tests/GRPCClientTests.m @@ -292,15 +292,6 @@ static GRPCProtoMethod *kUnaryCallMethod; // TODO(makarandd): Move to a different file that contains only unit tests - (void)testExceptions { - // Try to set userAgentPrefix for host that is nil. This should cause - // an exception. - @try { - [GRPCCall setUserAgentPrefix:@"Foo" forHost:nil]; - XCTFail(@"Did not receive an exception when host is nil"); - } @catch(NSException *theException) { - NSLog(@"Received exception as expected: %@", theException.name); - } - // Try to set parameters to nil for GRPCCall. This should cause an exception @try { (void)[[GRPCCall alloc] initWithHost:nil diff --git a/src/objective-c/tests/InteropTests.h b/src/objective-c/tests/InteropTests.h index 6d54343b135..ecab606a78b 100644 --- a/src/objective-c/tests/InteropTests.h +++ b/src/objective-c/tests/InteropTests.h @@ -46,4 +46,11 @@ * Override in a subclass to perform these tests against a specific address. */ + (NSString *)host; + +/** + * Bytes of overhead of test proto responses due to encoding. This is used to excercise the behavior + * when responses are just above or below the max response size. For some reason, the local and + * remote servers enconde responses with different overhead (?), so this is defined per-subclass. + */ +- (int32_t)encodingOverhead; @end diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m index 494743d6041..f04a7e6441f 100644 --- a/src/objective-c/tests/InteropTests.m +++ b/src/objective-c/tests/InteropTests.m @@ -80,10 +80,6 @@ #pragma mark Tests -#ifdef GRPC_COMPILE_WITH_CRONET -static cronet_engine *cronetEngine = NULL; -#endif - @implementation InteropTests { RMTTestService *_service; } @@ -92,15 +88,22 @@ static cronet_engine *cronetEngine = NULL; return nil; } +- (int32_t)encodingOverhead { + return 0; +} + - (void)setUp { + self.continueAfterFailure = NO; + + [GRPCCall resetHostSettings]; + _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil; #ifdef GRPC_COMPILE_WITH_CRONET if (cronetEngine == NULL) { // Cronet setup [Cronet setHttp2Enabled:YES]; [Cronet start]; - cronetEngine = [Cronet getGlobalEngine]; - [GRPCCall useCronetWithEngine:cronetEngine]; + [GRPCCall useCronetWithEngine:[Cronet getGlobalEngine]]; } #endif } @@ -146,6 +149,64 @@ static cronet_engine *cronetEngine = NULL; [self waitForExpectationsWithTimeout:16 handler:nil]; } +- (void)test4MBResponsesAreAccepted { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"MaxResponseSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead; // 4MB - encoding overhead + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:16 handler:nil]; +} + +- (void)testResponsesOverMaxSizeFailWithActionableMessage { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ResponseOverMaxSize"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const int32_t kPayloadSize = 4 * 1024 * 1024 - self.encodingOverhead + 1; // 1B over max size + request.responseSize = kPayloadSize; + + [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { + // TODO(jcanizales): Catch the error and rethrow it with an actionable message: + // - Use +[GRPCCall setResponseSizeLimit:forHost:] to set a higher limit. + // - If you're developing the server, consider using response streaming, or let clients filter + // responses by setting a google.protobuf.FieldMask in the request: + // https://github.com/google/protobuf/blob/master/src/google/protobuf/field_mask.proto + XCTAssertEqualObjects(error.localizedDescription, @"Max message size exceeded"); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:16 handler:nil]; +} + +- (void)testResponsesOver4MBAreAcceptedIfOptedIn { + XCTAssertNotNil(self.class.host); + __weak XCTestExpectation *expectation = + [self expectationWithDescription:@"HigherResponseSizeLimit"]; + + RMTSimpleRequest *request = [RMTSimpleRequest message]; + const size_t kPayloadSize = 5 * 1024 * 1024; // 5MB + request.responseSize = kPayloadSize; + + [GRPCCall setResponseSizeLimit:6 * 1024 * 1024 forHost:self.class.host]; + + [_service unaryCallWithRequest:request handler:^(RMTSimpleResponse *response, NSError *error) { + XCTAssertNil(error, @"Finished with unexpected error: %@", error); + XCTAssertEqual(response.payload.body.length, kPayloadSize); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:16 handler:nil]; +} + - (void)testClientStreamingRPC { XCTAssertNotNil(self.class.host); __weak XCTestExpectation *expectation = [self expectationWithDescription:@"ClientStreaming"]; diff --git a/src/objective-c/tests/InteropTestsLocalCleartext.m b/src/objective-c/tests/InteropTestsLocalCleartext.m index 56927a8af6d..b41210f50f8 100644 --- a/src/objective-c/tests/InteropTestsLocalCleartext.m +++ b/src/objective-c/tests/InteropTestsLocalCleartext.m @@ -47,11 +47,15 @@ static NSString * const kLocalCleartextHost = @"localhost:5050"; return kLocalCleartextHost; } +- (int32_t)encodingOverhead { + return 10; // bytes +} + - (void)setUp { + [super setUp]; + // Register test server as non-SSL. [GRPCCall useInsecureConnectionsForHost:kLocalCleartextHost]; - - [super setUp]; } @end diff --git a/src/objective-c/tests/InteropTestsLocalSSL.m b/src/objective-c/tests/InteropTestsLocalSSL.m index f0f4b1d71f0..1479c5896c3 100644 --- a/src/objective-c/tests/InteropTestsLocalSSL.m +++ b/src/objective-c/tests/InteropTestsLocalSSL.m @@ -47,14 +47,18 @@ static NSString * const kLocalSSLHost = @"localhost:5051"; return kLocalSSLHost; } +- (int32_t)encodingOverhead { + return 10; // bytes +} + - (void)setUp { + [super setUp]; + // Register test server certificates and name. NSBundle *bundle = [NSBundle bundleForClass:self.class]; NSString *certsPath = [bundle pathForResource:@"TestCertificates.bundle/test-certificates" ofType:@"pem"]; [GRPCCall useTestCertsPath:certsPath testName:@"foo.test.google.fr" forHost:kLocalSSLHost]; - - [super setUp]; } - (void)testExceptions { diff --git a/src/objective-c/tests/InteropTestsRemote.m b/src/objective-c/tests/InteropTestsRemote.m index 758cc9346ad..70f84753bb6 100644 --- a/src/objective-c/tests/InteropTestsRemote.m +++ b/src/objective-c/tests/InteropTestsRemote.m @@ -47,4 +47,8 @@ static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com"; return kRemoteSSLHost; } +- (int32_t)encodingOverhead { + return 12; // bytes +} + @end diff --git a/src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist b/src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist new file mode 100644 index 00000000000..ba72822e872 --- /dev/null +++ b/src/objective-c/tests/InteropTestsRemoteWithCronet/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/src/objective-c/examples/SwiftSample/Bridging-Header.h b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m similarity index 80% rename from src/objective-c/examples/SwiftSample/Bridging-Header.h rename to src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m index 65f768a760b..fab8ad8d25f 100644 --- a/src/objective-c/examples/SwiftSample/Bridging-Header.h +++ b/src/objective-c/tests/InteropTestsRemoteWithCronet/InteropTestsRemoteWithCronet.m @@ -31,15 +31,20 @@ * */ -#ifndef SwiftSample_Bridging_Header_h -#define SwiftSample_Bridging_Header_h +#import -#import -#import -#import -#import -#import -#import -#import +#import "InteropTests.h" -#endif +static NSString * const kRemoteSSLHost = @"grpc-test.sandbox.googleapis.com"; + +/** Tests in InteropTests.m, sending the RPCs to a remote SSL server. */ +@interface InteropTestsRemoteWithCronet : InteropTests +@end + +@implementation InteropTestsRemoteWithCronet + ++ (NSString *)host { + return kRemoteSSLHost; +} + +@end diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile index 17b9740d52e..17478fab12d 100644 --- a/src/objective-c/tests/Podfile +++ b/src/objective-c/tests/Podfile @@ -14,6 +14,7 @@ GRPC_LOCAL_SRC = '../../..' InteropTestsRemote InteropTestsLocalSSL InteropTestsLocalCleartext + InteropTestsRemoteWithCronet ).each do |target_name| target target_name do pod 'Protobuf', :path => "#{GRPC_LOCAL_SRC}/third_party/protobuf", :inhibit_warnings => true @@ -22,17 +23,29 @@ GRPC_LOCAL_SRC = '../../..' pod '!ProtoCompiler-gRPCPlugin', :path => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true - pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" pod 'gRPC', :path => GRPC_LOCAL_SRC pod 'gRPC-Core', :path => GRPC_LOCAL_SRC pod 'gRPC-RxLibrary', :path => GRPC_LOCAL_SRC pod 'gRPC-ProtoRPC', :path => GRPC_LOCAL_SRC - pod 'RemoteTest', :path => "RemoteTestClient" + + if target_name == 'InteropTestsRemoteWithCronet' + pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + end end end +target 'CoreCronetEnd2EndTests' do + pod 'BoringSSL', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c", :inhibit_warnings => true + pod 'CronetFramework', :podspec => "#{GRPC_LOCAL_SRC}/src/objective-c" + pod 'gRPC-Core', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Interface', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Cronet-Implementation', :path => GRPC_LOCAL_SRC + pod 'gRPC-Core/Tests', :path => GRPC_LOCAL_SRC +end + # gRPC-Core.podspec needs to be modified to be successfully used for local development. A Podfile's # pre_install hook lets us do that. The block passed to it runs after the podspecs are downloaded # and before they are installed in the user project. @@ -69,7 +82,11 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['GCC_TREAT_WARNINGS_AS_ERRORS'] = 'YES' end - if target.name == 'gRPC-Core' + + # CocoaPods creates duplicated library targets of gRPC-Core when the test targets include + # non-default subspecs of gRPC-Core. All of these library targets start with prefix 'gRPC-Core.' + # and require the same error suppresion. + if target.name == 'gRPC-Core' or target.name.start_with?('gRPC-Core.') target.build_configurations.each do |config| # TODO(zyc): Remove this setting after the issue is resolved # GPR_UNREACHABLE_CODE causes "Control may reach end of non-void @@ -77,5 +94,15 @@ post_install do |installer| config.build_settings['GCC_WARN_ABOUT_RETURN_TYPE'] = 'NO' end end + + # Activate Cronet for the dedicated build configuration 'Cronet', which will be used solely by + # the test target 'InteropTestsRemoteWithCronet' + if target.name == 'gRPC' + target.build_configurations.each do |config| + if config.name == 'Cronet' + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] = '$(inherited) COCOAPODS=1 GRPC_COMPILE_WITH_CRONET=1' + end + end + end end end diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec index 7d84a5ae4dc..2e0a050b0c7 100644 --- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec +++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec @@ -11,7 +11,7 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients. - s.dependency "!ProtoCompiler-gRPCPlugin", "~> 0.14" + s.dependency "!ProtoCompiler-gRPCPlugin" repo_root = '../../../..' bin_dir = "#{repo_root}/bins/$CONFIG" @@ -35,10 +35,6 @@ Pod::Spec.new do |s| ms.header_mappings_dir = "." ms.requires_arc = false ms.dependency "Protobuf" - # This is needed by all pods that depend on Protobuf: - ms.pod_target_xcconfig = { - 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', - } end s.subspec "Services" do |ss| @@ -48,4 +44,11 @@ Pod::Spec.new do |s| ss.dependency "gRPC-ProtoRPC" ss.dependency "#{s.name}/Messages" end + + s.pod_target_xcconfig = { + # This is needed by all pods that depend on Protobuf: + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1', + # This is needed by all pods that depend on gRPC-RxLibrary: + 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES', + } end diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj index f9389a4977f..c4a6567ae0e 100644 --- a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj +++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj @@ -7,11 +7,18 @@ objects = { /* Begin PBXBuildFile section */ + 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */; }; 0F9232F984C08643FD40C34F /* libPods-InteropTestsRemote.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */; }; 16A9E77B6E336B3C0B9BA6E0 /* libPods-InteropTestsLocalSSL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DBEDE45BDA60DF1E1C8950C0 /* libPods-InteropTestsLocalSSL.a */; }; 20DFDF829DD993A4A00D5662 /* libPods-RxLibraryUnitTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */; }; 333E8FC01C8285B7C547D799 /* libPods-InteropTestsLocalCleartext.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */; }; 3D7C85F6AA68C4A205E3BA16 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */; }; + 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */; }; + 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EE84BF41D4717E40050C6CC /* InteropTestsRemoteWithCronet.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */; }; + 5EE84BF61D4717E40050C6CC /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; + 5EE84BFE1D471D400050C6CC /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; }; + 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */; }; 6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; }; 63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; }; 635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; }; @@ -38,6 +45,20 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; + 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 635697BF1B14FC11007A7283 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 635697C61B14FC11007A7283; + remoteInfo = Tests; + }; 63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 635697BF1B14FC11007A7283 /* Project object */; @@ -91,12 +112,24 @@ 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = ""; }; 07D10A965323BEA7FE59A74B /* Pods-RxLibraryUnitTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.debug.xcconfig"; sourceTree = ""; }; 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.debug.xcconfig"; sourceTree = ""; }; + 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.cronet.xcconfig"; sourceTree = ""; }; + 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.debug.xcconfig"; sourceTree = ""; }; 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.release.xcconfig"; sourceTree = ""; }; + 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.cronet.xcconfig"; sourceTree = ""; }; + 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.release.xcconfig"; sourceTree = ""; }; + 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.cronet.xcconfig"; sourceTree = ""; }; 51A275E86C141416ED63FF76 /* Pods-InteropTestsLocalCleartext.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.release.xcconfig"; sourceTree = ""; }; 553BBBED24E4162D1F769D65 /* Pods-InteropTestsLocalSSL.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.debug.xcconfig"; sourceTree = ""; }; + 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests.cronet.xcconfig"; sourceTree = ""; }; 5761E98978DDDF136A58CB7E /* Pods-AllTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.release.xcconfig"; sourceTree = ""; }; + 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreCronetEnd2EndTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CoreCronetEnd2EndTests.m; sourceTree = ""; }; + 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = InteropTestsRemoteWithCronet.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InteropTestsRemoteWithCronet.m; sourceTree = ""; }; + 5EE84BF51D4717E40050C6CC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = ""; }; 63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = ""; }; @@ -113,8 +146,12 @@ 63E240CC1B6C4D3A005F3B0E /* InteropTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InteropTests.h; sourceTree = ""; }; 63E240CD1B6C4E2B005F3B0E /* InteropTestsLocalSSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTestsLocalSSL.m; sourceTree = ""; }; 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = TestCertificates.bundle; sourceTree = ""; }; + 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RxLibraryUnitTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests.cronet.xcconfig"; sourceTree = ""; }; 7A2E97E3F469CC2A758D77DE /* Pods-InteropTestsLocalSSL.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalSSL.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL.release.xcconfig"; sourceTree = ""; }; + 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemoteWithCronet.a"; sourceTree = BUILT_PRODUCTS_DIR; }; A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RxLibraryUnitTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.cronet.xcconfig"; sourceTree = ""; }; + AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemoteWithCronet.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet.release.xcconfig"; sourceTree = ""; }; B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.debug.xcconfig"; sourceTree = ""; }; CAE086D5B470DA367D415AB0 /* libPods-AllTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-AllTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsRemote.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -123,11 +160,32 @@ E1486220285AF123EB124008 /* Pods-InteropTestsLocalCleartext.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsLocalCleartext.debug.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsLocalCleartext/Pods-InteropTestsLocalCleartext.debug.xcconfig"; sourceTree = ""; }; E4275A759BDBDF143B9B438F /* Pods-InteropTestsRemote.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InteropTestsRemote.release.xcconfig"; path = "Pods/Target Support Files/Pods-InteropTestsRemote/Pods-InteropTestsRemote.release.xcconfig"; sourceTree = ""; }; E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = ""; }; + E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AllTests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-AllTests/Pods-AllTests.cronet.xcconfig"; sourceTree = ""; }; + F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.cronet.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.cronet.xcconfig"; sourceTree = ""; }; + FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-CoreCronetEnd2EndTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FD346DB2C23F676C4842F3FF /* libPods-InteropTestsLocalCleartext.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-InteropTestsLocalCleartext.a"; sourceTree = BUILT_PRODUCTS_DIR; }; FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 5E8A5DA11D3840B4000F8BC4 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E8A5DA91D3840B4000F8BC4 /* libTests.a in Frameworks */, + 60D2A57ED559F34428C2EEC5 /* libPods-CoreCronetEnd2EndTests.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EE84BEE1D4717E40050C6CC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EE84BF61D4717E40050C6CC /* libTests.a in Frameworks */, + 09B76D9585ACE7403804D9DC /* libPods-InteropTestsRemoteWithCronet.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63423F411B150A5F006CF63C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -194,6 +252,8 @@ DBE059B4AC7A51919467EEC0 /* libPods-InteropTestsRemote.a */, A58BE6DF1C62D1739EBB2C78 /* libPods-RxLibraryUnitTests.a */, 20DFF2F3C97EF098FE5A3171 /* libPods-Tests.a */, + FBD98AC417B9882D32B19F28 /* libPods-CoreCronetEnd2EndTests.a */, + 9E9444C764F0FFF64A7EB58E /* libPods-InteropTestsRemoteWithCronet.a */, ); name = Frameworks; sourceTree = ""; @@ -215,15 +275,46 @@ 3B0861FC805389C52DB260D4 /* Pods-RxLibraryUnitTests.release.xcconfig */, 060EF32D7EC0DF67ED617507 /* Pods-Tests.debug.xcconfig */, E6733B838B28453434B556E2 /* Pods-Tests.release.xcconfig */, + 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */, + 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */, + 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */, + AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */, + E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */, + 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */, + AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */, + 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */, + 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */, + 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */, + 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */, + F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */, ); name = Pods; sourceTree = ""; }; + 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { + isa = PBXGroup; + children = ( + 5E8A5DA61D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m */, + ); + path = CoreCronetEnd2EndTests; + sourceTree = ""; + }; + 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { + isa = PBXGroup; + children = ( + 5EE84BF31D4717E40050C6CC /* InteropTestsRemoteWithCronet.m */, + 5EE84BF51D4717E40050C6CC /* Info.plist */, + ); + path = InteropTestsRemoteWithCronet; + sourceTree = ""; + }; 635697BE1B14FC11007A7283 = { isa = PBXGroup; children = ( 635697C91B14FC11007A7283 /* Tests */, 63E240CF1B6C63DC005F3B0E /* TestCertificates.bundle */, + 5E8A5DA51D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, + 5EE84BF21D4717E40050C6CC /* InteropTestsRemoteWithCronet */, 635697C81B14FC11007A7283 /* Products */, 51E4650F34F854F41FF053B3 /* Pods */, 136D535E19727099B941D7B1 /* Frameworks */, @@ -239,6 +330,8 @@ 63DC84231BE15267000708E8 /* InteropTestsRemote.xctest */, 63DC84341BE15294000708E8 /* InteropTestsLocalSSL.xctest */, 63DC84431BE152B5000708E8 /* InteropTestsLocalCleartext.xctest */, + 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */, + 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */, ); name = Products; sourceTree = ""; @@ -270,6 +363,48 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */; + buildPhases = ( + F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */, + 5E8A5DA01D3840B4000F8BC4 /* Sources */, + 5E8A5DA11D3840B4000F8BC4 /* Frameworks */, + 5E8A5DA21D3840B4000F8BC4 /* Resources */, + E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */, + 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */, + ); + name = CoreCronetEnd2EndTests; + productName = CoreCronetEnd2EndTests; + productReference = 5E8A5DA41D3840B4000F8BC4 /* CoreCronetEnd2EndTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 5EE84BF01D4717E40050C6CC /* InteropTestsRemoteWithCronet */ = { + isa = PBXNativeTarget; + buildConfigurationList = 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */; + buildPhases = ( + C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */, + 5EE84BED1D4717E40050C6CC /* Sources */, + 5EE84BEE1D4717E40050C6CC /* Frameworks */, + 5EE84BEF1D4717E40050C6CC /* Resources */, + 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */, + DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */, + ); + name = InteropTestsRemoteWithCronet; + productName = InteropTestsRemoteWithCronet; + productReference = 5EE84BF11D4717E40050C6CC /* InteropTestsRemoteWithCronet.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 63423F431B150A5F006CF63C /* AllTests */ = { isa = PBXNativeTarget; buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */; @@ -403,6 +538,12 @@ LastUpgradeCheck = 0630; ORGANIZATIONNAME = gRPC; TargetAttributes = { + 5E8A5DA31D3840B4000F8BC4 = { + CreatedOnToolsVersion = 7.3.1; + }; + 5EE84BF01D4717E40050C6CC = { + CreatedOnToolsVersion = 7.3.1; + }; 63423F431B150A5F006CF63C = { CreatedOnToolsVersion = 6.3.1; }; @@ -441,11 +582,27 @@ 63DC84221BE15267000708E8 /* InteropTestsRemote */, 63DC84331BE15294000708E8 /* InteropTestsLocalSSL */, 63DC84421BE152B5000708E8 /* InteropTestsLocalCleartext */, + 5E8A5DA31D3840B4000F8BC4 /* CoreCronetEnd2EndTests */, + 5EE84BF01D4717E40050C6CC /* InteropTestsRemoteWithCronet */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 5E8A5DA21D3840B4000F8BC4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EE84BEF1D4717E40050C6CC /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63423F421B150A5F006CF63C /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -486,6 +643,21 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 31F8D1C407195CBF0C02929B /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 4C406327D3907A5E5FBA8AC9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -561,6 +733,21 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsLocalSSL/Pods-InteropTestsLocalSSL-resources.sh\"\n"; showEnvVarsInLog = 0; }; + 6DFE9E77CAB5760196D79E0F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; 7418AC7B3844B29E48D24FC7 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -696,6 +883,21 @@ shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; showEnvVarsInLog = 0; }; + C0F7B1FF6F88CC5FBF362F4C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; C2E09DC4BD239F71160F0CC1 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -741,9 +943,71 @@ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RxLibraryUnitTests/Pods-RxLibraryUnitTests-resources.sh\"\n"; showEnvVarsInLog = 0; }; + DB4D0E73C229F2FF3B364AB3 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-InteropTestsRemoteWithCronet/Pods-InteropTestsRemoteWithCronet-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + E63468C760D0724F18861822 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CoreCronetEnd2EndTests/Pods-CoreCronetEnd2EndTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + F58F17E425446B15028B9F74 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 5E8A5DA01D3840B4000F8BC4 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E8A5DA71D3840B4000F8BC4 /* CoreCronetEnd2EndTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5EE84BED1D4717E40050C6CC /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5EE84BFE1D471D400050C6CC /* InteropTests.m in Sources */, + 5EE84BF41D4717E40050C6CC /* InteropTestsRemoteWithCronet.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 63423F401B150A5F006CF63C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -804,6 +1068,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 5E8A5DAB1D3840B4000F8BC4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5E8A5DAA1D3840B4000F8BC4 /* PBXContainerItemProxy */; + }; + 5EE84BF81D4717E40050C6CC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 635697C61B14FC11007A7283 /* Tests */; + targetProxy = 5EE84BF71D4717E40050C6CC /* PBXContainerItemProxy */; + }; 63423F4C1B150A5F006CF63C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 635697C61B14FC11007A7283 /* Tests */; @@ -832,6 +1106,248 @@ /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ + 5E8A5DAC1D3840B4000F8BC4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0D2284C3DF7E57F0ED504E39 /* Pods-CoreCronetEnd2EndTests.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; + }; + name = Debug; + }; + 5E8A5DAD1D3840B4000F8BC4 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4AD97096D13D7416DC91A72A /* Pods-CoreCronetEnd2EndTests.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; + }; + name = Release; + }; + 5EC3C7A01D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.3; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Cronet; + }; + 5EC3C7A11D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F671D4CAD2864FB203B920B4 /* Pods-Tests.cronet.xcconfig */; + buildSettings = { + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Cronet; + }; + 5EC3C7A21D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7E4D3FD76E3B745D992AF5F /* Pods-AllTests.cronet.xcconfig */; + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A31D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 79C68EFFCB5533475D810B79 /* Pods-RxLibraryUnitTests.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.RxLibraryUnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A41D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4ADEA1C8BBE10D90940AC68E /* Pods-InteropTestsRemote.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A51D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 14B09A58FEE53A7A6B838920 /* Pods-InteropTestsLocalSSL.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalSSL; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A61D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AA7CB64B4DD9915AE7C03163 /* Pods-InteropTestsLocalCleartext.cronet.xcconfig */; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsLocalCleartext; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EC3C7A71D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 573450F334B331D0BED8B961 /* Pods-CoreCronetEnd2EndTests.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + INFOPLIST_FILE = CoreCronetEnd2EndTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.CoreCronetEnd2EndTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + USER_HEADER_SEARCH_PATHS = "$(inherited) \"${PODS_ROOT}/../../../..\""; + }; + name = Cronet; + }; + 5EC3C7A81D4FC18C000330E2 /* Cronet */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3F27B2E744482771EB93C394 /* Pods-InteropTestsRemoteWithCronet.cronet.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "GRPC_COMPILE_WITH_CRONET=1", + ); + INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Cronet; + }; + 5EE84BF91D4717E40050C6CC /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 17F60BF2871F6AF85FB3FA12 /* Pods-InteropTestsRemoteWithCronet.debug.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + ); + INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 5EE84BFA1D4717E40050C6CC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AC414EF7A6BF76ED02B6E480 /* Pods-InteropTestsRemoteWithCronet.release.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "$(inherited)", + "COCOAPODS=1", + "$(inherited)", + "GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1", + "GRPC_COMPILE_WITH_CRONET=1", + ); + INFOPLIST_FILE = InteropTestsRemoteWithCronet/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = io.grpc.InteropTestsRemoteWithCronet; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; 63423F4E1B150A5F006CF63C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = B94C27C06733CF98CE1B2757 /* Pods-AllTests.debug.xcconfig */; @@ -1071,10 +1587,31 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 5E8A5DAE1D3840B4000F8BC4 /* Build configuration list for PBXNativeTarget "CoreCronetEnd2EndTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5E8A5DAC1D3840B4000F8BC4 /* Debug */, + 5EC3C7A71D4FC18C000330E2 /* Cronet */, + 5E8A5DAD1D3840B4000F8BC4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 5EE84BFB1D4717E40050C6CC /* Build configuration list for PBXNativeTarget "InteropTestsRemoteWithCronet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 5EE84BF91D4717E40050C6CC /* Debug */, + 5EC3C7A81D4FC18C000330E2 /* Cronet */, + 5EE84BFA1D4717E40050C6CC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */ = { isa = XCConfigurationList; buildConfigurations = ( 63423F4E1B150A5F006CF63C /* Debug */, + 5EC3C7A21D4FC18C000330E2 /* Cronet */, 63423F4F1B150A5F006CF63C /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1084,6 +1621,7 @@ isa = XCConfigurationList; buildConfigurations = ( 635697D91B14FC11007A7283 /* Debug */, + 5EC3C7A01D4FC18C000330E2 /* Cronet */, 635697DA1B14FC11007A7283 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1093,6 +1631,7 @@ isa = XCConfigurationList; buildConfigurations = ( 635697DC1B14FC11007A7283 /* Debug */, + 5EC3C7A11D4FC18C000330E2 /* Cronet */, 635697DD1B14FC11007A7283 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1102,6 +1641,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC841C1BE15179000708E8 /* Debug */, + 5EC3C7A31D4FC18C000330E2 /* Cronet */, 63DC841D1BE15179000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1111,6 +1651,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC842C1BE15267000708E8 /* Debug */, + 5EC3C7A41D4FC18C000330E2 /* Cronet */, 63DC842D1BE15267000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1120,6 +1661,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC843D1BE15294000708E8 /* Debug */, + 5EC3C7A51D4FC18C000330E2 /* Cronet */, 63DC843E1BE15294000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; @@ -1129,6 +1671,7 @@ isa = XCConfigurationList; buildConfigurations = ( 63DC844C1BE152B5000708E8 /* Debug */, + 5EC3C7A61D4FC18C000330E2 /* Cronet */, 63DC844D1BE152B5000708E8 /* Release */, ); defaultConfigurationIsVisible = 0; diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme index e6a052a8ce1..d1d616c4cf2 100644 --- a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/AllTests.xcscheme @@ -38,12 +38,6 @@ ReferencedContainer = "container:Tests.xcodeproj"> - - - - diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme new file mode 100644 index 00000000000..a1da2e0c97c --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/CoreCronetEnd2EndTests.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme new file mode 100644 index 00000000000..1d211115f75 --- /dev/null +++ b/src/objective-c/tests/Tests.xcodeproj/xcshareddata/xcschemes/InteropTestsRemoteWithCronet.xcscheme @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/objective-c/tests/build_example_test.sh b/src/objective-c/tests/build_example_test.sh index 5c3766b4c0b..ae75941ec61 100755 --- a/src/objective-c/tests/build_example_test.sh +++ b/src/objective-c/tests/build_example_test.sh @@ -31,44 +31,33 @@ # Don't run this script standalone. Instead, run from the repository root: # ./tools/run_tests/run_tests.py -l objc -set -eo pipefail +set -evo pipefail cd `dirname $0` -BINDIR=`pwd`/../../../bins/$CONFIG -TMP_PATH=$PATH - -# If `protoc` is not found, add bins/$CONFIG/protobuf/protoc to the search path -hash protoc 2>/dev/null || TMP_PATH=$BINDIR/protobuf:$TMP_PATH - -# If `protoc-gen-objcgrpc` is not found, make a symlink from -# bins/$CONGIF/grpc_objective_c_plugin and add it to the search path -PATH=$TMP_PATH hash protoc-gen-objcgrpc 2>/dev/null || { - ln -sf $BINDIR/grpc_objective_c_plugin $BINDIR/protoc-gen-objcgrpc - TMP_PATH=$BINDIR:$TMP_PATH -} - SCHEME=HelloWorld \ EXAMPLE_PATH=examples/objective-c/helloworld \ - PATH=$TMP_PATH \ ./build_one_example.sh SCHEME=RouteGuideClient \ EXAMPLE_PATH=examples/objective-c/route_guide \ - PATH=$TMP_PATH \ ./build_one_example.sh SCHEME=AuthSample \ EXAMPLE_PATH=examples/objective-c/auth_sample \ - PATH=$TMP_PATH \ + ./build_one_example.sh + +rm -f ../examples/RemoteTestClient/*.{h,m} + +SCHEME=Sample \ + EXAMPLE_PATH=src/objective-c/examples/Sample \ ./build_one_example.sh SCHEME=Sample \ EXAMPLE_PATH=src/objective-c/examples/Sample \ - PATH=$TMP_PATH \ + FRAMEWORKS=YES \ ./build_one_example.sh SCHEME=SwiftSample \ EXAMPLE_PATH=src/objective-c/examples/SwiftSample \ - PATH=$TMP_PATH \ ./build_one_example.sh diff --git a/src/objective-c/tests/build_one_example.sh b/src/objective-c/tests/build_one_example.sh index 24fb8b7bab4..9fef6582a38 100755 --- a/src/objective-c/tests/build_one_example.sh +++ b/src/objective-c/tests/build_one_example.sh @@ -31,7 +31,7 @@ # Don't run this script standalone. Instead, run from the repository root: # ./tools/run_tests/run_tests.py -l objc -set -e +set -ev # Params: # EXAMPLE_PATH - directory of the example @@ -54,7 +54,7 @@ pod install set -o pipefail XCODEBUILD_FILTER='(^===|^\*\*|\bfatal\b|\berror\b|\bwarning\b|\bfail)' xcodebuild \ - clean build \ + build \ -workspace *.xcworkspace \ -scheme $SCHEME \ -destination name="iPhone 6" \ diff --git a/src/objective-c/tests/build_tests.sh b/src/objective-c/tests/build_tests.sh index 8547bfd3a83..bc5bc044943 100755 --- a/src/objective-c/tests/build_tests.sh +++ b/src/objective-c/tests/build_tests.sh @@ -44,26 +44,10 @@ hash xcodebuild 2>/dev/null || { exit 1 } -BINDIR=../../../bins/$CONFIG - -if [ ! -f $BINDIR/protobuf/protoc ]; then - hash protoc 2>/dev/null || { - echo >&2 "Can't find protoc. Make sure run_tests.py is making" \ - "grpc_objective_c_plugin before calling this script." - exit 1 - } - # When protoc is already installed, make doesn't compile one. Put a link - # there so the podspecs can do codegen using that path. - mkdir -p $BINDIR/protobuf - ln -s `which protoc` $BINDIR/protobuf/protoc -fi - -[ -f $BINDIR/interop_server ] || { - echo >&2 "Can't find the test server. Make sure run_tests.py is making" \ - "interop_server before calling this script. It needs to be done" \ - "before because pod install of gRPC renames some C gRPC files" \ - "and not the server's code references to them." - exit 1 -} +# clean the directory +rm -rf Pods +rm -rf Tests.xcworkspace +rm -f Podfile.lock +rm -f RemoteTestClient/*.{h,m} pod install diff --git a/src/objective-c/tests/run_tests.sh b/src/objective-c/tests/run_tests.sh index c4fc5644f28..a265149f488 100755 --- a/src/objective-c/tests/run_tests.sh +++ b/src/objective-c/tests/run_tests.sh @@ -31,13 +31,21 @@ # Don't run this script standalone. Instead, run from the repository root: # ./tools/run_tests/run_tests.py -l objc -set -e +set -ev cd $(dirname $0) # Run the tests server. -../../../bins/$CONFIG/interop_server --port=5050 & -../../../bins/$CONFIG/interop_server --port=5051 --use_tls & + +BINDIR=../../../bins/$CONFIG + +[ -f $BINDIR/interop_server ] || { + echo >&2 "Can't find the test server. Make sure run_tests.py is making" \ + "interop_server before calling this script." + exit 1 +} +$BINDIR/interop_server --port=5050 & +$BINDIR/interop_server --port=5051 --use_tls & # Kill them when this script exits. trap 'kill -9 `jobs -p`' EXIT diff --git a/src/php/README.md b/src/php/README.md index 8abedc40a3b..7e9819b256d 100644 --- a/src/php/README.md +++ b/src/php/README.md @@ -9,23 +9,12 @@ GA ## Environment -Prerequisite: `php` >=5.5, `phpize`, `pecl`, `phpunit` - -**Linux (Debian):** - -```sh -$ sudo apt-get install php5 php5-dev php-pear -``` - -**Linux (CentOS):** - -```sh -$ yum install php55w -$ yum --enablerepo=remi,remi-php55 install php-devel php-pear -``` - -**Mac OS X:** +Prerequisite: +* `php` 5.5 or above, 7.0 or above +* `pear` and `pecl` +* `phpunit` +**PEAR:** ```sh $ curl -O http://pear.php.net/go-pear.phar $ sudo php -d detect_unicode=0 go-pear.phar @@ -72,13 +61,7 @@ $ sudo make install ### gRPC PHP extension -Install the gRPC PHP extension from PECL - -```sh -$ sudo pecl install grpc -``` - -Or, compile from source +Compile the gRPC PHP extension ```sh $ cd grpc/src/php/ext/grpc @@ -148,12 +131,8 @@ Alternatively, you can download `protoc` binaries from [the protocol buffers Git You need to install `protoc-gen-php` to generate stub class `.php` files from service definition `.proto` files. ```sh -$ cd grpc/src/php/vendor/stanley-cheung/protobuf-php # if you had run `composer install` in the previous step - -OR - -$ git clone https://github.com/stanley-cheung/Protobuf-PHP # clone from github repo - +$ git clone https://github.com/stanley-cheung/Protobuf-PHP +$ cd Protobuf-PHP $ gem install rake ronn $ rake pear:package version=1.0 $ sudo pear install Protobuf-1.0.tgz @@ -175,7 +154,7 @@ Run a local server serving the math services. Please see [Node][] for how to run ```sh $ cd grpc $ npm install -$ nodejs src/node/test/math/math_server.js +$ node src/node/test/math/math_server.js ``` ### Run test client @@ -212,7 +191,7 @@ Make sure the Node math server is still running, as above. ```sh $ cd grpc $ npm install -$ nodejs src/node/test/math/math_server.js +$ node src/node/test/math/math_server.js ``` Make sure you have run `composer install` to generate the `vendor/autoload.php` file @@ -282,7 +261,7 @@ Make sure the Node math server is still running, as above. ```sh $ cd grpc $ npm install -$ nodejs src/node/test/math/math_server.js +$ node src/node/test/math/math_server.js ``` Make sure you have run `composer install` to generate the `vendor/autoload.php` file diff --git a/src/php/bin/determine_extension_dir.sh b/src/php/bin/determine_extension_dir.sh index b4342ac89fa..a59882506f9 100755 --- a/src/php/bin/determine_extension_dir.sh +++ b/src/php/bin/determine_extension_dir.sh @@ -29,11 +29,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. set -e default_extension_dir=$(php-config --extension-dir) -if command -v brew > /dev/null && \ - brew ls --versions | grep php5[56]-grpc > /dev/null; then - # the grpc php extension was installed by homebrew - : -elif [ ! -e $default_extension_dir/grpc.so ]; then +if [ ! -e $default_extension_dir/grpc.so ]; then # the grpc extension is not found in the default PHP extension dir # try the source modules directory module_dir=../ext/grpc/modules diff --git a/src/php/composer.json b/src/php/composer.json index 23bfcedbe6b..571f30013fa 100644 --- a/src/php/composer.json +++ b/src/php/composer.json @@ -5,10 +5,12 @@ "keywords": ["rpc"], "homepage": "http://grpc.io", "license": "BSD-3-Clause", - "version": "1.0.0", + "version": "1.1.0", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master", + "stanley-cheung/protobuf-php": "v0.6" + }, + "require-dev": { "google/auth": "v0.9" }, "autoload": { diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c index 2cd45f10dc4..31c59fe5adc 100644 --- a/src/php/ext/grpc/call.c +++ b/src/php/ext/grpc/call.c @@ -58,63 +58,44 @@ #include "byte_buffer.h" zend_class_entry *grpc_ce_call; +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers call_ce_handlers; +#endif /* Frees and destroys an instance of wrapped_grpc_call */ -void free_wrapped_grpc_call(void *object TSRMLS_DC) { - wrapped_grpc_call *call = (wrapped_grpc_call *)object; - if (call->owned && call->wrapped != NULL) { - grpc_call_destroy(call->wrapped); +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call) + if (p->owned && p->wrapped != NULL) { + grpc_call_destroy(p->wrapped); } - efree(call); -} +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instance of wrapped_grpc_call to be associated with an object * of a class specified by class_type */ -zend_object_value create_wrapped_grpc_call(zend_class_entry *class_type - TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_call *intern; - - intern = (wrapped_grpc_call *)emalloc(sizeof(wrapped_grpc_call)); - memset(intern, 0, sizeof(wrapped_grpc_call)); - +php_grpc_zend_object create_wrapped_grpc_call(zend_class_entry *class_type + TSRMLS_DC) { + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_call, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; -} - -/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the struct - should be destroyed at the end of the object's lifecycle */ -zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) { - zval *call_object; - MAKE_STD_ZVAL(call_object); - object_init_ex(call_object, grpc_ce_call); - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(call_object TSRMLS_CC); - call->wrapped = wrapped; - call->owned = owned; - return call_object; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_call, call_ce_handlers); } /* Creates and returns a PHP array object with the data in a * grpc_metadata_array. Returns NULL on failure */ -zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) { +zval *grpc_parse_metadata_array(grpc_metadata_array + *metadata_array TSRMLS_DC) { int count = metadata_array->count; grpc_metadata *elements = metadata_array->metadata; - int i; zval *array; - zval **data = NULL; + PHP_GRPC_MAKE_STD_ZVAL(array); + array_init(array); + int i; HashTable *array_hash; zval *inner_array; char *str_key; char *str_val; size_t key_len; - MAKE_STD_ZVAL(array); - array_init(array); + zval *data = NULL; + array_hash = Z_ARRVAL_P(array); grpc_metadata *elem; for (i = 0; i < count; i++) { @@ -124,9 +105,9 @@ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) { memcpy(str_key, elem->key, key_len); str_val = ecalloc(elem->value_length + 1, sizeof(char)); memcpy(str_val, elem->value, elem->value_length); - if (zend_hash_find(array_hash, str_key, key_len, (void **)data) == - SUCCESS) { - if (Z_TYPE_P(*data) != IS_ARRAY) { + if (php_grpc_zend_hash_find(array_hash, str_key, key_len, (void **)&data) + == SUCCESS) { + if (Z_TYPE_P(data) != IS_ARRAY) { zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Metadata hash somehow contains wrong types.", 1 TSRMLS_CC); @@ -134,11 +115,13 @@ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) { efree(str_val); return NULL; } - add_next_index_stringl(*data, str_val, elem->value_length, false); + php_grpc_add_next_index_stringl(data, str_val, elem->value_length, + false); } else { - MAKE_STD_ZVAL(inner_array); + PHP_GRPC_MAKE_STD_ZVAL(inner_array); array_init(inner_array); - add_next_index_stringl(inner_array, str_val, elem->value_length, false); + php_grpc_add_next_index_stringl(inner_array, str_val, + elem->value_length, false); add_assoc_zval(array, str_key, inner_array); } } @@ -148,61 +131,68 @@ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC) { /* Populates a grpc_metadata_array with the data in a PHP array object. Returns true on success and false on failure */ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { - zval **inner_array; - zval **value; HashTable *array_hash; - HashPosition array_pointer; HashTable *inner_array_hash; - HashPosition inner_array_pointer; - char *key; - uint key_len; - ulong index; + zval *value; + zval *inner_array; if (Z_TYPE_P(array) != IS_ARRAY) { return false; } grpc_metadata_array_init(metadata); array_hash = Z_ARRVAL_P(array); - for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); - zend_hash_get_current_data_ex(array_hash, (void**)&inner_array, - &array_pointer) == SUCCESS; - zend_hash_move_forward_ex(array_hash, &array_pointer)) { - if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, - &array_pointer) != HASH_KEY_IS_STRING) { + + char *key; + int key_type; + PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key, key_type, + inner_array) + if (key_type != HASH_KEY_IS_STRING || key == NULL) { return false; } - if (Z_TYPE_P(*inner_array) != IS_ARRAY) { + if (Z_TYPE_P(inner_array) != IS_ARRAY) { return false; } - inner_array_hash = Z_ARRVAL_P(*inner_array); + inner_array_hash = Z_ARRVAL_P(inner_array); metadata->capacity += zend_hash_num_elements(inner_array_hash); - } + PHP_GRPC_HASH_FOREACH_END() + metadata->metadata = gpr_malloc(metadata->capacity * sizeof(grpc_metadata)); - for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); - zend_hash_get_current_data_ex(array_hash, (void**)&inner_array, - &array_pointer) == SUCCESS; - zend_hash_move_forward_ex(array_hash, &array_pointer)) { - if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, - &array_pointer) != HASH_KEY_IS_STRING) { + + char *key1 = NULL; + int key_type1; + PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key1, key_type1, + inner_array) + if (key_type1 != HASH_KEY_IS_STRING) { + return false; + } + if (!grpc_header_key_is_legal(key1, strlen(key1))) { return false; } - inner_array_hash = Z_ARRVAL_P(*inner_array); - for (zend_hash_internal_pointer_reset_ex(inner_array_hash, - &inner_array_pointer); - zend_hash_get_current_data_ex(inner_array_hash, (void**)&value, - &inner_array_pointer) == SUCCESS; - zend_hash_move_forward_ex(inner_array_hash, &inner_array_pointer)) { - if (Z_TYPE_P(*value) != IS_STRING) { + inner_array_hash = Z_ARRVAL_P(inner_array); + PHP_GRPC_HASH_FOREACH_VAL_START(inner_array_hash, value) + if (Z_TYPE_P(value) != IS_STRING) { return false; } - metadata->metadata[metadata->count].key = key; - metadata->metadata[metadata->count].value = Z_STRVAL_P(*value); - metadata->metadata[metadata->count].value_length = Z_STRLEN_P(*value); + metadata->metadata[metadata->count].key = key1; + metadata->metadata[metadata->count].value = Z_STRVAL_P(value); + metadata->metadata[metadata->count].value_length = Z_STRLEN_P(value); metadata->count += 1; - } - } + PHP_GRPC_HASH_FOREACH_END() + PHP_GRPC_HASH_FOREACH_END() return true; } +/* Wraps a grpc_call struct in a PHP object. Owned indicates whether the + struct should be destroyed at the end of the object's lifecycle */ +zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC) { + zval *call_object; + PHP_GRPC_MAKE_STD_ZVAL(call_object); + object_init_ex(call_object, grpc_ce_call); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(call_object); + call->wrapped = wrapped; + call->owned = owned; + return call_object; +} + /** * Constructs a new instance of the Call class. * @param Channel $channel The channel to associate the call with. Must not be @@ -211,30 +201,25 @@ bool create_metadata_array(zval *array, grpc_metadata_array *metadata) { * @param Timeval $absolute_deadline The deadline for completing the call */ PHP_METHOD(Call, __construct) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); zval *channel_obj; char *method; - int method_len; + php_grpc_int method_len; zval *deadline_obj; char *host_override = NULL; - int host_override_len = 0; + php_grpc_int host_override_len = 0; + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + /* "OsO|s" == 1 Object, 1 string, 1 Object, 1 optional string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", - &channel_obj, grpc_ce_channel, - &method, &method_len, - &deadline_obj, grpc_ce_timeval, - &host_override, &host_override_len) - == FAILURE) { - zend_throw_exception( - spl_ce_InvalidArgumentException, - "Call expects a Channel, a String, a Timeval and an optional String", - 1 TSRMLS_CC); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OsO|s", &channel_obj, + grpc_ce_channel, &method, &method_len, + &deadline_obj, grpc_ce_timeval, &host_override, + &host_override_len) == FAILURE) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Call expects a Channel, a String, a Timeval and " + "an optional String", 1 TSRMLS_CC); return; } - wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object( - channel_obj TSRMLS_CC); + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(channel_obj); if (channel->wrapped == NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, "Call cannot be constructed from a closed Channel", @@ -242,12 +227,11 @@ PHP_METHOD(Call, __construct) { return; } add_property_zval(getThis(), "channel", channel_obj); - wrapped_grpc_timeval *deadline = - (wrapped_grpc_timeval *)zend_object_store_get_object( - deadline_obj TSRMLS_CC); - call->wrapped = grpc_channel_create_call( - channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, completion_queue, method, - host_override, deadline->wrapped, NULL); + wrapped_grpc_timeval *deadline = Z_WRAPPED_GRPC_TIMEVAL_P(deadline_obj); + call->wrapped = + grpc_channel_create_call(channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS, + completion_queue, method, host_override, + deadline->wrapped, NULL); call->owned = true; } @@ -257,22 +241,26 @@ PHP_METHOD(Call, __construct) { * @return object Object with results of all actions */ PHP_METHOD(Call, startBatch) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); + zval *result; + PHP_GRPC_MAKE_STD_ZVAL(result); + object_init(result); + php_grpc_ulong index; + zval *recv_status; + PHP_GRPC_MAKE_STD_ZVAL(recv_status); + object_init(recv_status); + zval *value; + zval *inner_value; + zval *message_value; + zval *message_flags; + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + grpc_op ops[8]; size_t op_num = 0; zval *array; - zval **value; - zval **inner_value; HashTable *array_hash; - HashPosition array_pointer; HashTable *status_hash; HashTable *message_hash; - zval **message_value; - zval **message_flags; - char *key; - uint key_len; - ulong index; + grpc_metadata_array metadata; grpc_metadata_array trailing_metadata; grpc_metadata_array recv_metadata; @@ -283,17 +271,15 @@ PHP_METHOD(Call, startBatch) { grpc_byte_buffer *message; int cancelled; grpc_call_error error; - zval *result; char *message_str; size_t message_len; - zval *recv_status; + grpc_metadata_array_init(&metadata); grpc_metadata_array_init(&trailing_metadata); grpc_metadata_array_init(&recv_metadata); grpc_metadata_array_init(&recv_trailing_metadata); - MAKE_STD_ZVAL(result); - object_init(result); memset(ops, 0, sizeof(ops)); + /* "a" == 1 array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { @@ -301,136 +287,136 @@ PHP_METHOD(Call, startBatch) { "start_batch expects an array", 1 TSRMLS_CC); goto cleanup; } + array_hash = Z_ARRVAL_P(array); - for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); - zend_hash_get_current_data_ex(array_hash, (void**)&value, - &array_pointer) == SUCCESS; - zend_hash_move_forward_ex(array_hash, &array_pointer)) { - if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, - &array_pointer) != HASH_KEY_IS_LONG) { + + char *key = NULL; + int key_type; + PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(array_hash, key, key_type, index, + value) + if (key_type != HASH_KEY_IS_LONG || key != NULL) { zend_throw_exception(spl_ce_InvalidArgumentException, "batch keys must be integers", 1 TSRMLS_CC); goto cleanup; } switch(index) { - case GRPC_OP_SEND_INITIAL_METADATA: - if (!create_metadata_array(*value, &metadata)) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Bad metadata value given", 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_initial_metadata.count = - metadata.count; - ops[op_num].data.send_initial_metadata.metadata = - metadata.metadata; - break; - case GRPC_OP_SEND_MESSAGE: - if (Z_TYPE_PP(value) != IS_ARRAY) { + case GRPC_OP_SEND_INITIAL_METADATA: + if (!create_metadata_array(value, &metadata)) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Bad metadata value given", 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_initial_metadata.count = metadata.count; + ops[op_num].data.send_initial_metadata.metadata = metadata.metadata; + break; + case GRPC_OP_SEND_MESSAGE: + if (Z_TYPE_P(value) != IS_ARRAY) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected an array for send message", + 1 TSRMLS_CC); + goto cleanup; + } + message_hash = Z_ARRVAL_P(value); + if (php_grpc_zend_hash_find(message_hash, "flags", sizeof("flags"), + (void **)&message_flags) == SUCCESS) { + if (Z_TYPE_P(message_flags) != IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected an array for send message", + "Expected an int for message flags", 1 TSRMLS_CC); - goto cleanup; - } - message_hash = Z_ARRVAL_PP(value); - if (zend_hash_find(message_hash, "flags", sizeof("flags"), - (void **)&message_flags) == SUCCESS) { - if (Z_TYPE_PP(message_flags) != IS_LONG) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected an int for message flags", - 1 TSRMLS_CC); - } - ops[op_num].flags = Z_LVAL_PP(message_flags) & GRPC_WRITE_USED_MASK; } - if (zend_hash_find(message_hash, "message", sizeof("message"), - (void **)&message_value) != SUCCESS || - Z_TYPE_PP(message_value) != IS_STRING) { + ops[op_num].flags = Z_LVAL_P(message_flags) & GRPC_WRITE_USED_MASK; + } + if (php_grpc_zend_hash_find(message_hash, "message", sizeof("message"), + (void **)&message_value) != SUCCESS || + Z_TYPE_P(message_value) != IS_STRING) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Expected a string for send message", + 1 TSRMLS_CC); + goto cleanup; + } + ops[op_num].data.send_message = + string_to_byte_buffer(Z_STRVAL_P(message_value), + Z_STRLEN_P(message_value)); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + status_hash = Z_ARRVAL_P(value); + if (php_grpc_zend_hash_find(status_hash, "metadata", sizeof("metadata"), + (void **)&inner_value) == SUCCESS) { + if (!create_metadata_array(inner_value, &trailing_metadata)) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Expected a string for send message", + "Bad trailing metadata value given", 1 TSRMLS_CC); goto cleanup; } - ops[op_num].data.send_message = - string_to_byte_buffer(Z_STRVAL_PP(message_value), - Z_STRLEN_PP(message_value)); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - status_hash = Z_ARRVAL_PP(value); - if (zend_hash_find(status_hash, "metadata", sizeof("metadata"), - (void **)&inner_value) == SUCCESS) { - if (!create_metadata_array(*inner_value, &trailing_metadata)) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Bad trailing metadata value given", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.trailing_metadata = - trailing_metadata.metadata; - ops[op_num].data.send_status_from_server.trailing_metadata_count = - trailing_metadata.count; - } - if (zend_hash_find(status_hash, "code", sizeof("code"), - (void**)&inner_value) == SUCCESS) { - if (Z_TYPE_PP(inner_value) != IS_LONG) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Status code must be an integer", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.status = - Z_LVAL_PP(inner_value); - } else { + ops[op_num].data.send_status_from_server.trailing_metadata = + trailing_metadata.metadata; + ops[op_num].data.send_status_from_server.trailing_metadata_count = + trailing_metadata.count; + } + if (php_grpc_zend_hash_find(status_hash, "code", sizeof("code"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_P(inner_value) != IS_LONG) { zend_throw_exception(spl_ce_InvalidArgumentException, - "Integer status code is required", + "Status code must be an integer", 1 TSRMLS_CC); goto cleanup; } - if (zend_hash_find(status_hash, "details", sizeof("details"), - (void**)&inner_value) == SUCCESS) { - if (Z_TYPE_PP(inner_value) != IS_STRING) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "Status details must be a string", - 1 TSRMLS_CC); - goto cleanup; - } - ops[op_num].data.send_status_from_server.status_details = - Z_STRVAL_PP(inner_value); - } else { + ops[op_num].data.send_status_from_server.status = + Z_LVAL_P(inner_value); + } else { + zend_throw_exception(spl_ce_InvalidArgumentException, + "Integer status code is required", + 1 TSRMLS_CC); + goto cleanup; + } + if (php_grpc_zend_hash_find(status_hash, "details", sizeof("details"), + (void**)&inner_value) == SUCCESS) { + if (Z_TYPE_P(inner_value) != IS_STRING) { zend_throw_exception(spl_ce_InvalidArgumentException, - "String status details is required", + "Status details must be a string", 1 TSRMLS_CC); goto cleanup; } - break; - case GRPC_OP_RECV_INITIAL_METADATA: - ops[op_num].data.recv_initial_metadata = &recv_metadata; - break; - case GRPC_OP_RECV_MESSAGE: - ops[op_num].data.recv_message = &message; - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - ops[op_num].data.recv_status_on_client.trailing_metadata = - &recv_trailing_metadata; - ops[op_num].data.recv_status_on_client.status = &status; - ops[op_num].data.recv_status_on_client.status_details = - &status_details; - ops[op_num].data.recv_status_on_client.status_details_capacity = - &status_details_capacity; - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - ops[op_num].data.recv_close_on_server.cancelled = &cancelled; - break; - default: + ops[op_num].data.send_status_from_server.status_details = + Z_STRVAL_P(inner_value); + } else { zend_throw_exception(spl_ce_InvalidArgumentException, - "Unrecognized key in batch", 1 TSRMLS_CC); + "String status details is required", + 1 TSRMLS_CC); goto cleanup; + } + break; + case GRPC_OP_RECV_INITIAL_METADATA: + ops[op_num].data.recv_initial_metadata = &recv_metadata; + break; + case GRPC_OP_RECV_MESSAGE: + ops[op_num].data.recv_message = &message; + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: + ops[op_num].data.recv_status_on_client.trailing_metadata = + &recv_trailing_metadata; + ops[op_num].data.recv_status_on_client.status = &status; + ops[op_num].data.recv_status_on_client.status_details = + &status_details; + ops[op_num].data.recv_status_on_client.status_details_capacity = + &status_details_capacity; + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + ops[op_num].data.recv_close_on_server.cancelled = &cancelled; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "Unrecognized key in batch", 1 TSRMLS_CC); + goto cleanup; } ops[op_num].op = (grpc_op_type)index; ops[op_num].flags = 0; ops[op_num].reserved = NULL; op_num++; - } + PHP_GRPC_HASH_FOREACH_END() + error = grpc_call_start_batch(call->wrapped, ops, op_num, call->wrapped, NULL); if (error != GRPC_CALL_OK) { @@ -441,52 +427,65 @@ PHP_METHOD(Call, startBatch) { } grpc_completion_queue_pluck(completion_queue, call->wrapped, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); +#if PHP_MAJOR_VERSION >= 7 + zval recv_md; +#endif for (int i = 0; i < op_num; i++) { switch(ops[i].op) { - case GRPC_OP_SEND_INITIAL_METADATA: - add_property_bool(result, "send_metadata", true); - break; - case GRPC_OP_SEND_MESSAGE: - add_property_bool(result, "send_message", true); - break; - case GRPC_OP_SEND_CLOSE_FROM_CLIENT: - add_property_bool(result, "send_close", true); - break; - case GRPC_OP_SEND_STATUS_FROM_SERVER: - add_property_bool(result, "send_status", true); - break; - case GRPC_OP_RECV_INITIAL_METADATA: - array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); - add_property_zval(result, "metadata", array); - Z_DELREF_P(array); - break; - case GRPC_OP_RECV_MESSAGE: - byte_buffer_to_string(message, &message_str, &message_len); - if (message_str == NULL) { - add_property_null(result, "message"); - } else { - add_property_stringl(result, "message", message_str, message_len, - false); - } - break; - case GRPC_OP_RECV_STATUS_ON_CLIENT: - MAKE_STD_ZVAL(recv_status); - object_init(recv_status); - array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); - add_property_zval(recv_status, "metadata", array); - Z_DELREF_P(array); - add_property_long(recv_status, "code", status); - add_property_string(recv_status, "details", status_details, true); - add_property_zval(result, "status", recv_status); - Z_DELREF_P(recv_status); - break; - case GRPC_OP_RECV_CLOSE_ON_SERVER: - add_property_bool(result, "cancelled", cancelled); - break; - default: - break; + case GRPC_OP_SEND_INITIAL_METADATA: + add_property_bool(result, "send_metadata", true); + break; + case GRPC_OP_SEND_MESSAGE: + add_property_bool(result, "send_message", true); + break; + case GRPC_OP_SEND_CLOSE_FROM_CLIENT: + add_property_bool(result, "send_close", true); + break; + case GRPC_OP_SEND_STATUS_FROM_SERVER: + add_property_bool(result, "send_status", true); + break; + case GRPC_OP_RECV_INITIAL_METADATA: +#if PHP_MAJOR_VERSION < 7 + array = grpc_parse_metadata_array(&recv_metadata TSRMLS_CC); + add_property_zval(result, "metadata", array); +#else + recv_md = *grpc_parse_metadata_array(&recv_metadata); + add_property_zval(result, "metadata", &recv_md); +#endif + PHP_GRPC_DELREF(array); + break; + case GRPC_OP_RECV_MESSAGE: + byte_buffer_to_string(message, &message_str, &message_len); + if (message_str == NULL) { + add_property_null(result, "message"); + } else { + php_grpc_add_property_stringl(result, "message", message_str, + message_len, false); + } + break; + case GRPC_OP_RECV_STATUS_ON_CLIENT: +#if PHP_MAJOR_VERSION < 7 + array = grpc_parse_metadata_array(&recv_trailing_metadata TSRMLS_CC); + add_property_zval(recv_status, "metadata", array); +#else + recv_md = *grpc_parse_metadata_array(&recv_trailing_metadata); + add_property_zval(recv_status, "metadata", &recv_md); +#endif + PHP_GRPC_DELREF(array); + add_property_long(recv_status, "code", status); + php_grpc_add_property_string(recv_status, "details", status_details, + true); + add_property_zval(result, "status", recv_status); + PHP_GRPC_DELREF(recv_status); + break; + case GRPC_OP_RECV_CLOSE_ON_SERVER: + add_property_bool(result, "cancelled", cancelled); + break; + default: + break; } } + cleanup: grpc_metadata_array_destroy(&metadata); grpc_metadata_array_destroy(&trailing_metadata); @@ -511,9 +510,8 @@ cleanup: * @return string The URI of the endpoint */ PHP_METHOD(Call, getPeer) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_STRING(grpc_call_get_peer(call->wrapped), 1); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); + PHP_GRPC_RETURN_STRING(grpc_call_get_peer(call->wrapped), 1); } /** @@ -521,8 +519,7 @@ PHP_METHOD(Call, getPeer) { * has not already ended with another status. */ PHP_METHOD(Call, cancel) { - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); grpc_call_cancel(call->wrapped, NULL); } @@ -544,11 +541,8 @@ PHP_METHOD(Call, setCredentials) { } wrapped_grpc_call_credentials *creds = - (wrapped_grpc_call_credentials *)zend_object_store_get_object( - creds_obj TSRMLS_CC); - - wrapped_grpc_call *call = - (wrapped_grpc_call *)zend_object_store_get_object(getThis() TSRMLS_CC); + Z_WRAPPED_GRPC_CALL_CREDS_P(creds_obj); + wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis()); grpc_call_error error = GRPC_CALL_ERROR; error = grpc_call_set_credentials(call->wrapped, creds->wrapped); @@ -556,16 +550,18 @@ PHP_METHOD(Call, setCredentials) { } static zend_function_entry call_methods[] = { - PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) - PHP_FE_END}; + PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_call(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Call", call_methods); ce.create_object = create_wrapped_grpc_call; grpc_ce_call = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_call, call_ce_handlers); } diff --git a/src/php/ext/grpc/call.h b/src/php/ext/grpc/call.h index 36c5f2d2724..e49f9b382ae 100644 --- a/src/php/ext/grpc/call.h +++ b/src/php/ext/grpc/call.h @@ -49,23 +49,38 @@ extern zend_class_entry *grpc_ce_call; /* Wrapper struct for grpc_call that can be associated with a PHP object */ -typedef struct wrapped_grpc_call { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_call) bool owned; grpc_call *wrapped; -} wrapped_grpc_call; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_call) -/* Initializes the Call PHP class */ -void grpc_init_call(TSRMLS_D); +#if PHP_MAJOR_VERSION < 7 -/* Creates a Call object that wraps the given grpc_call struct */ -zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC); +#define Z_WRAPPED_GRPC_CALL_P(zv) \ + (wrapped_grpc_call *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_call +*wrapped_grpc_call_from_obj(zend_object *obj) { + return (wrapped_grpc_call*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_call, std)); +} + +#define Z_WRAPPED_GRPC_CALL_P(zv) wrapped_grpc_call_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Creates and returns a PHP associative array of metadata from a C array of * call metadata */ zval *grpc_parse_metadata_array(grpc_metadata_array *metadata_array TSRMLS_DC); +/* Creates a Call object that wraps the given grpc_call struct */ +zval *grpc_php_wrap_call(grpc_call *wrapped, bool owned TSRMLS_DC); + +/* Initializes the Call PHP class */ +void grpc_init_call(TSRMLS_D); + /* Populates a grpc_metadata_array with the data in a PHP array object. Returns true on success and false on failure */ bool create_metadata_array(zval *array, grpc_metadata_array *metadata); diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c index ec0e6b91813..25c92c91fec 100644 --- a/src/php/ext/grpc/call_credentials.c +++ b/src/php/ext/grpc/call_credentials.c @@ -52,44 +52,35 @@ #include zend_class_entry *grpc_ce_call_credentials; +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers call_credentials_ce_handlers; +#endif /* Frees and destroys an instance of wrapped_grpc_call_credentials */ -void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) { - wrapped_grpc_call_credentials *creds = - (wrapped_grpc_call_credentials *)object; - if (creds->wrapped != NULL) { - grpc_call_credentials_release(creds->wrapped); +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_call_credentials) + if (p->wrapped != NULL) { + grpc_call_credentials_release(p->wrapped); } - efree(creds); -} +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instance of wrapped_grpc_call_credentials to be * associated with an object of a class specified by class_type */ -zend_object_value create_wrapped_grpc_call_credentials( +php_grpc_zend_object create_wrapped_grpc_call_credentials( zend_class_entry *class_type TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_call_credentials *intern; - - intern = (wrapped_grpc_call_credentials *)emalloc( - sizeof(wrapped_grpc_call_credentials)); - memset(intern, 0, sizeof(wrapped_grpc_call_credentials)); - + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call_credentials); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_call_credentials, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_call_credentials, + call_credentials_ce_handlers); } -zval *grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_call_credentials(grpc_call_credentials + *wrapped TSRMLS_DC) { zval *credentials_object; - MAKE_STD_ZVAL(credentials_object); + PHP_GRPC_MAKE_STD_ZVAL(credentials_object); object_init_ex(credentials_object, grpc_ce_call_credentials); wrapped_grpc_call_credentials *credentials = - (wrapped_grpc_call_credentials *)zend_object_store_get_object( - credentials_object TSRMLS_CC); + Z_WRAPPED_GRPC_CALL_CREDS_P(credentials_object); credentials->wrapped = wrapped; return credentials_object; } @@ -114,15 +105,15 @@ PHP_METHOD(CallCredentials, createComposite) { return; } wrapped_grpc_call_credentials *cred1 = - (wrapped_grpc_call_credentials *)zend_object_store_get_object( - cred1_obj TSRMLS_CC); + Z_WRAPPED_GRPC_CALL_CREDS_P(cred1_obj); wrapped_grpc_call_credentials *cred2 = - (wrapped_grpc_call_credentials *)zend_object_store_get_object( - cred2_obj TSRMLS_CC); + Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj); grpc_call_credentials *creds = grpc_composite_call_credentials_create(cred1->wrapped, cred2->wrapped, NULL); - zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); + zval *creds_object; + PHP_GRPC_MAKE_STD_ZVAL(creds_object); + creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -141,13 +132,10 @@ PHP_METHOD(CallCredentials, createFromPlugin) { memset(fci_cache, 0, sizeof(zend_fcall_info_cache)); /* "f" == 1 function */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f", fci, - fci_cache, - fci->params, - fci->param_count) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "f*", fci, fci_cache, + fci->params, fci->param_count) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, - "createFromPlugin expects 1 callback", - 1 TSRMLS_CC); + "createFromPlugin expects 1 callback", 1 TSRMLS_CC); return; } @@ -165,9 +153,11 @@ PHP_METHOD(CallCredentials, createFromPlugin) { plugin.state = (void *)state; plugin.type = ""; - grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin( - plugin, NULL); - zval *creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); + grpc_call_credentials *creds = + grpc_metadata_credentials_create_from_plugin(plugin, NULL); + zval *creds_object; + PHP_GRPC_MAKE_STD_ZVAL(creds_object); + creds_object = grpc_php_wrap_call_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -181,37 +171,37 @@ void plugin_get_metadata(void *ptr, grpc_auth_metadata_context context, /* prepare to call the user callback function with info from the * grpc_auth_metadata_context */ - zval **params[1]; zval *arg; - zval *retval; - MAKE_STD_ZVAL(arg); + PHP_GRPC_MAKE_STD_ZVAL(arg); object_init(arg); - add_property_string(arg, "service_url", context.service_url, true); - add_property_string(arg, "method_name", context.method_name, true); + php_grpc_add_property_string(arg, "service_url", context.service_url, true); + php_grpc_add_property_string(arg, "method_name", context.method_name, true); + zval *retval; + PHP_GRPC_MAKE_STD_ZVAL(retval); +#if PHP_MAJOR_VERSION < 7 + zval **params[1]; params[0] = &arg; - state->fci->param_count = 1; state->fci->params = params; state->fci->retval_ptr_ptr = &retval; +#else + state->fci->params = arg; + state->fci->retval = retval; +#endif + state->fci->param_count = 1; /* call the user callback function */ zend_call_function(state->fci, state->fci_cache TSRMLS_CC); - if (Z_TYPE_P(retval) != IS_ARRAY) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "plugin callback must return metadata array", - 1 TSRMLS_CC); - } - + grpc_status_code code = GRPC_STATUS_OK; grpc_metadata_array metadata; - if (!create_metadata_array(retval, &metadata)) { - zend_throw_exception(spl_ce_InvalidArgumentException, - "invalid metadata", 1 TSRMLS_CC); + + if (Z_TYPE_P(retval) != IS_ARRAY) { + code = GRPC_STATUS_INVALID_ARGUMENT; + } else if (!create_metadata_array(retval, &metadata)) { grpc_metadata_array_destroy(&metadata); + code = GRPC_STATUS_INVALID_ARGUMENT; } - /* TODO: handle error */ - grpc_status_code code = GRPC_STATUS_OK; - /* Pass control back to core */ cb(user_data, metadata.metadata, metadata.count, code, NULL); } @@ -229,11 +219,14 @@ static zend_function_entry call_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(CallCredentials, createFromPlugin, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_FE_END}; + PHP_FE_END +}; void grpc_init_call_credentials(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\CallCredentials", call_credentials_methods); ce.create_object = create_wrapped_grpc_call_credentials; grpc_ce_call_credentials = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_call_credentials, + call_credentials_ce_handlers); } diff --git a/src/php/ext/grpc/call_credentials.h b/src/php/ext/grpc/call_credentials.h index d2f6a92449b..c1d85c0fb28 100755 --- a/src/php/ext/grpc/call_credentials.h +++ b/src/php/ext/grpc/call_credentials.h @@ -51,11 +51,27 @@ extern zend_class_entry *grpc_ce_call_credentials; /* Wrapper struct for grpc_call_credentials that can be associated * with a PHP object */ -typedef struct wrapped_grpc_call_credentials { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_call_credentials) grpc_call_credentials *wrapped; -} wrapped_grpc_call_credentials; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_call_credentials) + +#if PHP_MAJOR_VERSION < 7 + +#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \ + (wrapped_grpc_call_credentials *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_call_credentials +*wrapped_grpc_call_credentials_from_obj(zend_object *obj) { + return (wrapped_grpc_call_credentials*)( + (char*)(obj) - XtOffsetOf(wrapped_grpc_call_credentials, std)); +} + +#define Z_WRAPPED_GRPC_CALL_CREDS_P(zv) \ + wrapped_grpc_call_credentials_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Struct to hold callback function for plugin creds API */ typedef struct plugin_state { diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c index 8d94c59683e..b5a2c9f6baf 100644 --- a/src/php/ext/grpc/channel.c +++ b/src/php/ext/grpc/channel.c @@ -56,72 +56,68 @@ #include "timeval.h" zend_class_entry *grpc_ce_channel; +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers channel_ce_handlers; +#endif /* Frees and destroys an instance of wrapped_grpc_channel */ -void free_wrapped_grpc_channel(void *object TSRMLS_DC) { - wrapped_grpc_channel *channel = (wrapped_grpc_channel *)object; - if (channel->wrapped != NULL) { - grpc_channel_destroy(channel->wrapped); +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel) + if (p->wrapped != NULL) { + grpc_channel_destroy(p->wrapped); } - efree(channel); -} +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instance of wrapped_grpc_channel to be associated with an * object of a class specified by class_type */ -zend_object_value create_wrapped_grpc_channel(zend_class_entry *class_type - TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_channel *intern; - intern = (wrapped_grpc_channel *)emalloc(sizeof(wrapped_grpc_channel)); - memset(intern, 0, sizeof(wrapped_grpc_channel)); +php_grpc_zend_object create_wrapped_grpc_channel(zend_class_entry *class_type + TSRMLS_DC) { + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_channel); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_channel, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_channel, channel_ce_handlers); } -void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC) { +void php_grpc_read_args_array(zval *args_array, + grpc_channel_args *args TSRMLS_DC) { HashTable *array_hash; - HashPosition array_pointer; int args_index; - zval **data; - char *key; - uint key_len; - ulong index; array_hash = Z_ARRVAL_P(args_array); + if (!array_hash) { + zend_throw_exception(spl_ce_InvalidArgumentException, + "array_hash is NULL", 1 TSRMLS_CC); + return; + } args->num_args = zend_hash_num_elements(array_hash); args->args = ecalloc(args->num_args, sizeof(grpc_arg)); args_index = 0; - for (zend_hash_internal_pointer_reset_ex(array_hash, &array_pointer); - zend_hash_get_current_data_ex(array_hash, (void **)&data, - &array_pointer) == SUCCESS; - zend_hash_move_forward_ex(array_hash, &array_pointer)) { - if (zend_hash_get_current_key_ex(array_hash, &key, &key_len, &index, 0, - &array_pointer) != HASH_KEY_IS_STRING) { + + char *key = NULL; + zval *data; + int key_type; + + PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(array_hash, key, key_type, data) + if (key_type != HASH_KEY_IS_STRING) { zend_throw_exception(spl_ce_InvalidArgumentException, "args keys must be strings", 1 TSRMLS_CC); return; } args->args[args_index].key = key; - switch (Z_TYPE_P(*data)) { - case IS_LONG: - args->args[args_index].value.integer = (int)Z_LVAL_P(*data); - args->args[args_index].type = GRPC_ARG_INTEGER; - break; - case IS_STRING: - args->args[args_index].value.string = Z_STRVAL_P(*data); - args->args[args_index].type = GRPC_ARG_STRING; - break; - default: - zend_throw_exception(spl_ce_InvalidArgumentException, - "args values must be int or string", 1 TSRMLS_CC); - return; + switch (Z_TYPE_P(data)) { + case IS_LONG: + args->args[args_index].value.integer = (int)Z_LVAL_P(data); + args->args[args_index].type = GRPC_ARG_INTEGER; + break; + case IS_STRING: + args->args[args_index].value.string = Z_STRVAL_P(data); + args->args[args_index].type = GRPC_ARG_STRING; + break; + default: + zend_throw_exception(spl_ce_InvalidArgumentException, + "args values must be int or string", 1 TSRMLS_CC); + return; } args_index++; - } + PHP_GRPC_HASH_FOREACH_END() } /** @@ -132,16 +128,15 @@ void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_D * @param array $args The arguments to pass to the Channel (optional) */ PHP_METHOD(Channel, __construct) { - wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object( - getThis() TSRMLS_CC); + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + zval *creds_obj = NULL; char *target; - int target_length; + php_grpc_int target_length; zval *args_array = NULL; grpc_channel_args args; HashTable *array_hash; - zval **creds_obj = NULL; wrapped_grpc_channel_credentials *creds = NULL; + /* "sa" == 1 string, 1 array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sa", &target, &target_length, &args_array) == FAILURE) { @@ -150,21 +145,20 @@ PHP_METHOD(Channel, __construct) { return; } array_hash = Z_ARRVAL_P(args_array); - if (zend_hash_find(array_hash, "credentials", sizeof("credentials"), + if (php_grpc_zend_hash_find(array_hash, "credentials", sizeof("credentials"), (void **)&creds_obj) == SUCCESS) { - if (Z_TYPE_P(*creds_obj) == IS_NULL) { + if (Z_TYPE_P(creds_obj) == IS_NULL) { creds = NULL; - zend_hash_del(array_hash, "credentials", 12); - } else if (zend_get_class_entry(*creds_obj TSRMLS_CC) != - grpc_ce_channel_credentials) { + php_grpc_zend_hash_del(array_hash, "credentials", sizeof("credentials")); + } else if (PHP_GRPC_GET_CLASS_ENTRY(creds_obj) != + grpc_ce_channel_credentials) { zend_throw_exception(spl_ce_InvalidArgumentException, "credentials must be a ChannelCredentials object", 1 TSRMLS_CC); return; } else { - creds = (wrapped_grpc_channel_credentials *)zend_object_store_get_object( - *creds_obj TSRMLS_CC); - zend_hash_del(array_hash, "credentials", 12); + creds = Z_WRAPPED_GRPC_CHANNEL_CREDS_P(creds_obj); + php_grpc_zend_hash_del(array_hash, "credentials", sizeof("credentials")); } } php_grpc_read_args_array(args_array, &args TSRMLS_CC); @@ -182,9 +176,8 @@ PHP_METHOD(Channel, __construct) { * @return string The URI of the endpoint */ PHP_METHOD(Channel, getTarget) { - wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1); + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + PHP_GRPC_RETURN_STRING(grpc_channel_get_target(channel->wrapped), 1); } /** @@ -193,12 +186,12 @@ PHP_METHOD(Channel, getTarget) { * @return long The grpc connectivity state */ PHP_METHOD(Channel, getConnectivityState) { - wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - bool try_to_connect; + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + bool try_to_connect = false; + /* "|b" == 1 optional bool */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &try_to_connect) + == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "getConnectivityState expects a bool", 1 TSRMLS_CC); return; @@ -215,28 +208,26 @@ PHP_METHOD(Channel, getConnectivityState) { * before deadline */ PHP_METHOD(Channel, watchConnectivityState) { - wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); - long last_state; + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); + php_grpc_long last_state; zval *deadline_obj; + /* "lO" == 1 long 1 object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lO", &last_state, &deadline_obj, grpc_ce_timeval) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, - "watchConnectivityState expects 1 long 1 timeval", - 1 TSRMLS_CC); + "watchConnectivityState expects 1 long 1 timeval", 1 TSRMLS_CC); return; } - wrapped_grpc_timeval *deadline = - (wrapped_grpc_timeval *)zend_object_store_get_object( - deadline_obj TSRMLS_CC); - grpc_channel_watch_connectivity_state( - channel->wrapped, (grpc_connectivity_state)last_state, - deadline->wrapped, completion_queue, NULL); - grpc_event event = grpc_completion_queue_pluck( - completion_queue, NULL, - gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + wrapped_grpc_timeval *deadline = Z_WRAPPED_GRPC_TIMEVAL_P(deadline_obj); + grpc_channel_watch_connectivity_state(channel->wrapped, + (grpc_connectivity_state)last_state, + deadline->wrapped, completion_queue, + NULL); + grpc_event event = + grpc_completion_queue_pluck(completion_queue, NULL, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); RETURN_BOOL(event.success); } @@ -244,8 +235,7 @@ PHP_METHOD(Channel, watchConnectivityState) { * Close the channel */ PHP_METHOD(Channel, close) { - wrapped_grpc_channel *channel = - (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC); + wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis()); if (channel->wrapped != NULL) { grpc_channel_destroy(channel->wrapped); channel->wrapped = NULL; @@ -253,16 +243,18 @@ PHP_METHOD(Channel, close) { } static zend_function_entry channel_methods[] = { - PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) - PHP_FE_END}; + PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_channel(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Channel", channel_methods); ce.create_object = create_wrapped_grpc_channel; grpc_ce_channel = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel, channel_ce_handlers); } diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h index cc5823ee7f7..0b815657d33 100755 --- a/src/php/ext/grpc/channel.h +++ b/src/php/ext/grpc/channel.h @@ -49,16 +49,33 @@ extern zend_class_entry *grpc_ce_channel; /* Wrapper struct for grpc_channel that can be associated with a PHP object */ -typedef struct wrapped_grpc_channel { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_channel) grpc_channel *wrapped; -} wrapped_grpc_channel; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_channel) + +#if PHP_MAJOR_VERSION < 7 + +#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \ + (wrapped_grpc_channel *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_channel +*wrapped_grpc_channel_from_obj(zend_object *obj) { + return (wrapped_grpc_channel*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_channel, std)); +} + +#define Z_WRAPPED_GRPC_CHANNEL_P(zv) \ + wrapped_grpc_channel_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Initializes the Channel class */ void grpc_init_channel(TSRMLS_D); /* Iterates through a PHP array and populates args with the contents */ -void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args TSRMLS_DC); +void php_grpc_read_args_array(zval *args_array, grpc_channel_args *args + TSRMLS_DC); #endif /* NET_GRPC_PHP_GRPC_CHANNEL_H_ */ diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c index b76fb105f36..0b356aa25fc 100644 --- a/src/php/ext/grpc/channel_credentials.c +++ b/src/php/ext/grpc/channel_credentials.c @@ -52,7 +52,9 @@ #include zend_class_entry *grpc_ce_channel_credentials; - +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers channel_credentials_ce_handlers; +#endif static char *default_pem_root_certs = NULL; static grpc_ssl_roots_override_result get_ssl_roots_override( @@ -65,42 +67,30 @@ static grpc_ssl_roots_override_result get_ssl_roots_override( } /* Frees and destroys an instance of wrapped_grpc_channel_credentials */ -void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) { - wrapped_grpc_channel_credentials *creds = - (wrapped_grpc_channel_credentials *)object; - if (creds->wrapped != NULL) { - grpc_channel_credentials_release(creds->wrapped); +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_channel_credentials) + if (p->wrapped != NULL) { + grpc_channel_credentials_release(p->wrapped); } - efree(creds); -} +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instance of wrapped_grpc_channel_credentials to be * associated with an object of a class specified by class_type */ -zend_object_value create_wrapped_grpc_channel_credentials( +php_grpc_zend_object create_wrapped_grpc_channel_credentials( zend_class_entry *class_type TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_channel_credentials *intern; - - intern = (wrapped_grpc_channel_credentials *)emalloc( - sizeof(wrapped_grpc_channel_credentials)); - memset(intern, 0, sizeof(wrapped_grpc_channel_credentials)); - + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_channel_credentials); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_channel_credentials, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_channel_credentials, + channel_credentials_ce_handlers); } -zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials + *wrapped TSRMLS_DC) { zval *credentials_object; - MAKE_STD_ZVAL(credentials_object); + PHP_GRPC_MAKE_STD_ZVAL(credentials_object); object_init_ex(credentials_object, grpc_ce_channel_credentials); wrapped_grpc_channel_credentials *credentials = - (wrapped_grpc_channel_credentials *)zend_object_store_get_object( - credentials_object TSRMLS_CC); + Z_WRAPPED_GRPC_CHANNEL_CREDS_P(credentials_object); credentials->wrapped = wrapped; return credentials_object; } @@ -112,7 +102,9 @@ zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped TSRMLS */ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { char *pem_roots; - int pem_roots_length; + php_grpc_int pem_roots_length; + + /* "s" == 1 string */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &pem_roots, &pem_roots_length) == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, @@ -129,7 +121,9 @@ PHP_METHOD(ChannelCredentials, setDefaultRootsPem) { */ PHP_METHOD(ChannelCredentials, createDefault) { grpc_channel_credentials *creds = grpc_google_default_credentials_create(); - zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); + zval *creds_object; + PHP_GRPC_MAKE_STD_ZVAL(creds_object); + creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -146,11 +140,13 @@ PHP_METHOD(ChannelCredentials, createSsl) { char *pem_root_certs = NULL; grpc_ssl_pem_key_cert_pair pem_key_cert_pair; - int root_certs_length = 0, private_key_length = 0, cert_chain_length = 0; + php_grpc_int root_certs_length = 0; + php_grpc_int private_key_length = 0; + php_grpc_int cert_chain_length = 0; pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL; - /* "|s!s!s! == 3 optional nullable strings */ + /* "|s!s!s!" == 3 optional nullable strings */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!", &pem_root_certs, &root_certs_length, &pem_key_cert_pair.private_key, @@ -164,7 +160,9 @@ PHP_METHOD(ChannelCredentials, createSsl) { grpc_channel_credentials *creds = grpc_ssl_credentials_create( pem_root_certs, pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL); - zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); + zval *creds_object; + PHP_GRPC_MAKE_STD_ZVAL(creds_object); + creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -178,7 +176,7 @@ PHP_METHOD(ChannelCredentials, createComposite) { zval *cred1_obj; zval *cred2_obj; - /* "OO" == 3 Objects */ + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj, grpc_ce_channel_credentials, &cred2_obj, grpc_ce_call_credentials) == FAILURE) { @@ -187,15 +185,15 @@ PHP_METHOD(ChannelCredentials, createComposite) { return; } wrapped_grpc_channel_credentials *cred1 = - (wrapped_grpc_channel_credentials *)zend_object_store_get_object( - cred1_obj TSRMLS_CC); + Z_WRAPPED_GRPC_CHANNEL_CREDS_P(cred1_obj); wrapped_grpc_call_credentials *cred2 = - (wrapped_grpc_call_credentials *)zend_object_store_get_object( - cred2_obj TSRMLS_CC); + Z_WRAPPED_GRPC_CALL_CREDS_P(cred2_obj); grpc_channel_credentials *creds = grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped, NULL); - zval *creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); + zval *creds_object; + PHP_GRPC_MAKE_STD_ZVAL(creds_object); + creds_object = grpc_php_wrap_channel_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } @@ -218,7 +216,8 @@ static zend_function_entry channel_credentials_methods[] = { ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_ME(ChannelCredentials, createInsecure, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_FE_END}; + PHP_FE_END +}; void grpc_init_channel_credentials(TSRMLS_D) { zend_class_entry ce; @@ -227,4 +226,6 @@ void grpc_init_channel_credentials(TSRMLS_D) { grpc_set_ssl_roots_override_callback(get_ssl_roots_override); ce.create_object = create_wrapped_grpc_channel_credentials; grpc_ce_channel_credentials = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_channel_credentials, + channel_credentials_ce_handlers); } diff --git a/src/php/ext/grpc/channel_credentials.h b/src/php/ext/grpc/channel_credentials.h index d89984ce604..b043d91fa69 100755 --- a/src/php/ext/grpc/channel_credentials.h +++ b/src/php/ext/grpc/channel_credentials.h @@ -51,11 +51,27 @@ extern zend_class_entry *grpc_ce_channel_credentials; /* Wrapper struct for grpc_channel_credentials that can be associated * with a PHP object */ -typedef struct wrapped_grpc_channel_credentials { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_channel_credentials) grpc_channel_credentials *wrapped; -} wrapped_grpc_channel_credentials; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_channel_credentials) + +#if PHP_MAJOR_VERSION < 7 + +#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \ + (wrapped_grpc_channel_credentials *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_channel_credentials +*wrapped_grpc_channel_credentials_from_obj(zend_object *obj) { + return (wrapped_grpc_channel_credentials *)( + (char*)(obj) - XtOffsetOf(wrapped_grpc_channel_credentials, std)); +} + +#define Z_WRAPPED_GRPC_CHANNEL_CREDS_P(zv) \ + wrapped_grpc_channel_credentials_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Initializes the ChannelCredentials PHP class */ void grpc_init_channel_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/package.xml b/src/php/ext/grpc/package.xml deleted file mode 100644 index daf2ee5a53d..00000000000 --- a/src/php/ext/grpc/package.xml +++ /dev/null @@ -1,156 +0,0 @@ - - - grpc - pecl.php.net - A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. - Remote Procedure Calls (RPCs) provide a useful abstraction for building distributed applications and services. The libraries in this repository provide a concrete implementation of the gRPC protocol, layered over HTTP/2. These libraries enable communication between clients and servers using any combination of the supported languages. - - Stanley Cheung - stanleycheung - grpc-packages@google.com - yes - - 2016-01-13 - - - 0.7.0 - 0.7.0 - - - beta - beta - - BSD - -- Breaking change to Credentials class (removed) #3765 -- Replaced by ChannelCredentials and CallCredentials class #3765 -- New plugin based metadata auth API #4394 -- Explicit ChannelCredentials::createInsecure() call - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5.5.0 - - - 1.4.0 - - - - grpc - - - - - 0.5.0 - 0.5.0 - - - alpha - alpha - - 2015-06-16 - BSD - -First alpha release - - - - - 0.5.1 - 0.5.1 - - - alpha - alpha - - 2015-07-09 - BSD - -Update to wrap gRPC C Core version 0.10.0 - - - - - 0.6.0 - 0.6.0 - - - beta - beta - - 2015-09-24 - BSD - -- support per message compression disable -- expose per-call host override option -- expose connectivity API -- expose channel target and call peer -- add user-agent -- update to wrap gRPC C core library beta version 0.11.0 - - - - - 0.6.1 - 0.6.0 - - - beta - beta - - 2015-10-21 - BSD - -- fixed undefined constant fatal error when run with apache/nginx #2275 - - - - - 0.7.0 - 0.7.0 - - - beta - beta - - 2016-01-13 - BSD - -- Breaking change to Credentials class (removed) #3765 -- Replaced by ChannelCredentials and CallCredentials class #3765 -- New plugin based metadata auth API #4394 -- Explicit ChannelCredentials::createInsecure() call - - - - diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h new file mode 100644 index 00000000000..1d7824113fa --- /dev/null +++ b/src/php/ext/grpc/php7_wrapper.h @@ -0,0 +1,217 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + + +#ifndef PHP7_WRAPPER_GRPC_H +#define PHP7_WRAPPER_GRPC_H + +#if PHP_MAJOR_VERSION < 7 + +#define php_grpc_int int +#define php_grpc_long long +#define php_grpc_ulong ulong +#define php_grpc_zend_object zend_object_value +#define php_grpc_add_property_string(arg, name, context, b) \ + add_property_string(arg, name, context, b) +#define php_grpc_add_property_stringl(res, name, str, len, b) \ + add_property_stringl(res, name, str, len, b) +#define php_grpc_add_next_index_stringl(data, str, len, b) \ + add_next_index_stringl(data, str, len, b) + +#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val, dup) +#define PHP_GRPC_MAKE_STD_ZVAL(pzv) MAKE_STD_ZVAL(pzv) +#define PHP_GRPC_DELREF(zv) Z_DELREF_P(zv) + +#define PHP_GRPC_WRAP_OBJECT_START(name) \ + typedef struct name { \ + zend_object std; +#define PHP_GRPC_WRAP_OBJECT_END(name) \ + } name; + +#define PHP_GRPC_FREE_WRAPPED_FUNC_START(class_object) \ + void free_##class_object(void *object TSRMLS_DC) { \ + class_object *p = (class_object *)object; +#define PHP_GRPC_FREE_WRAPPED_FUNC_END() \ + zend_object_std_dtor(&p->std TSRMLS_CC); \ + efree(p); \ + } + +#define PHP_GRPC_ALLOC_CLASS_OBJECT(class_object) \ + class_object *intern; \ + zend_object_value retval; \ + intern = (class_object *)emalloc(sizeof(class_object)); \ + memset(intern, 0, sizeof(class_object)); + +#define PHP_GRPC_FREE_CLASS_OBJECT(class_object, handler) \ + retval.handle = zend_objects_store_put( \ + intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ + free_##class_object, NULL TSRMLS_CC); \ + retval.handlers = zend_get_std_object_handlers(); \ + return retval; + +#define PHP_GRPC_HASH_FOREACH_VAL_START(ht, data) \ + zval **tmp_data = NULL; \ + for (zend_hash_internal_pointer_reset(ht); \ + zend_hash_get_current_data(ht, (void**)&tmp_data) == SUCCESS; \ + zend_hash_move_forward(ht)) { \ + data = *tmp_data; + +#define PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(ht, key, key_type, data) \ + zval **tmp##key = NULL; \ + ulong index##key; \ + uint len##key; \ + for (zend_hash_internal_pointer_reset(ht); \ + zend_hash_get_current_data(ht, (void**)&tmp##key) == SUCCESS; \ + zend_hash_move_forward(ht)) { \ + key_type = zend_hash_get_current_key_ex(ht, &key, &len##key, &index##key,\ + 0, NULL); \ + data = *tmp##key; + +#define PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(ht, key, key_type, index,\ + data) \ + zval **tmp##key = NULL; \ + uint len##key; \ + for (zend_hash_internal_pointer_reset(ht); \ + zend_hash_get_current_data(ht, (void**)&tmp##key) == SUCCESS; \ + zend_hash_move_forward(ht)) { \ + key_type = zend_hash_get_current_key_ex(ht, &key, &len##key, &index,\ + 0, NULL); \ + data = *tmp##key; + +#define PHP_GRPC_HASH_FOREACH_END() } + +static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len, + void **value) { + zval **data = NULL; + if (zend_hash_find(ht, key, len, (void **)&data) == SUCCESS) { + *value = *data; + return SUCCESS; + } else { + *value = NULL; + return FAILURE; + } +} + +#define php_grpc_zend_hash_del zend_hash_del + +#define PHP_GRPC_GET_CLASS_ENTRY(object) zend_get_class_entry(object TSRMLS_CC) + +#define PHP_GRPC_INIT_HANDLER(class_object, handler_name) + +#else + +#define php_grpc_int size_t +#define php_grpc_long zend_long +#define php_grpc_ulong zend_ulong +#define php_grpc_zend_object zend_object* +#define php_grpc_add_property_string(arg, name, context, b) \ + add_property_string(arg, name, context) +#define php_grpc_add_property_stringl(res, name, str, len, b) \ + add_property_stringl(res, name, str, len) +#define php_grpc_add_next_index_stringl(data, str, len, b) \ + add_next_index_stringl(data, str, len) + +#define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val) +#define PHP_GRPC_MAKE_STD_ZVAL(pzv) \ + pzv = (zval *)emalloc(sizeof(zval)); +#define PHP_GRPC_DELREF(zv) + +#define PHP_GRPC_WRAP_OBJECT_START(name) \ + typedef struct name { +#define PHP_GRPC_WRAP_OBJECT_END(name) \ + zend_object std; \ + } name; + +#define WRAPPED_OBJECT_FROM_OBJ(class_object, obj) \ + class_object##_from_obj(obj); + +#define PHP_GRPC_FREE_WRAPPED_FUNC_START(class_object) \ + static void free_##class_object(zend_object *object) { \ + class_object *p = WRAPPED_OBJECT_FROM_OBJ(class_object, object) +#define PHP_GRPC_FREE_WRAPPED_FUNC_END() \ + zend_object_std_dtor(&p->std); \ + } + +#define PHP_GRPC_ALLOC_CLASS_OBJECT(class_object) \ + class_object *intern; \ + intern = ecalloc(1, sizeof(class_object) + \ + zend_object_properties_size(class_type)); + +#define PHP_GRPC_FREE_CLASS_OBJECT(class_object, handler) \ + intern->std.handlers = &handler; \ + return &intern->std; + +#define PHP_GRPC_HASH_FOREACH_VAL_START(ht, data) \ + ZEND_HASH_FOREACH_VAL(ht, data) { + +#define PHP_GRPC_HASH_FOREACH_STR_KEY_VAL_START(ht, key, key_type, data) \ + zend_string *(zs_##key); \ + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, (zs_##key), data) { \ + if ((zs_##key) == NULL) {key = NULL; key_type = HASH_KEY_IS_LONG;} \ + else {key = (zs_##key)->val; key_type = HASH_KEY_IS_STRING;} + +#define PHP_GRPC_HASH_FOREACH_LONG_KEY_VAL_START(ht, key, key_type, index, \ + data) \ + zend_string *(zs_##key); \ + ZEND_HASH_FOREACH_KEY_VAL(ht, index, zs_##key, data) { \ + if ((zs_##key) == NULL) {key = NULL; key_type = HASH_KEY_IS_LONG;} \ + else {key = (zs_##key)->val; key_type = HASH_KEY_IS_STRING;} + +#define PHP_GRPC_HASH_FOREACH_END() } ZEND_HASH_FOREACH_END(); + +static inline int php_grpc_zend_hash_find(HashTable *ht, char *key, int len, + void **value) { + zval *value_tmp = zend_hash_str_find(ht, key, len -1); + if (value_tmp == NULL) { + return FAILURE; + } else { + *value = (void *)value_tmp; + return SUCCESS; + } +} + +static inline int php_grpc_zend_hash_del(HashTable *ht, char *key, int len) { + return zend_hash_str_del(ht, key, len - 1); +} + +#define PHP_GRPC_GET_CLASS_ENTRY(object) Z_OBJ_P(object)->ce + +#define PHP_GRPC_INIT_HANDLER(class_object, handler_name) \ + memcpy(&handler_name, zend_get_std_object_handlers(), \ + sizeof(zend_object_handlers)); \ + handler_name.offset = XtOffsetOf(class_object, std); \ + handler_name.free_obj = free_##class_object + +#endif /* PHP_MAJOR_VERSION */ + +#endif /* PHP7_WRAPPER_GRPC_H */ diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c index 449ba3cd47b..5edfa2da7df 100644 --- a/src/php/ext/grpc/php_grpc.c +++ b/src/php/ext/grpc/php_grpc.c @@ -64,15 +64,19 @@ const zend_function_entry grpc_functions[] = { */ zend_module_entry grpc_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER, #endif - "grpc", grpc_functions, PHP_MINIT(grpc), - PHP_MSHUTDOWN(grpc), NULL, NULL, - PHP_MINFO(grpc), + "grpc", + grpc_functions, + PHP_MINIT(grpc), + PHP_MSHUTDOWN(grpc), + NULL, + NULL, + PHP_MINFO(grpc), #if ZEND_MODULE_API_NO >= 20010901 - PHP_GRPC_VERSION, + PHP_GRPC_VERSION, #endif - STANDARD_MODULE_PROPERTIES}; + STANDARD_MODULE_PROPERTIES}; /* }}} */ #ifdef COMPILE_DL_GRPC @@ -82,23 +86,24 @@ ZEND_GET_MODULE(grpc) /* {{{ PHP_INI */ /* Remove comments and fill if you need to have entries in php.ini -PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, -global_value, zend_grpc_globals, grpc_globals) - STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, -OnUpdateString, global_string, zend_grpc_globals, grpc_globals) -PHP_INI_END() + PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("grpc.global_value", "42", PHP_INI_ALL, OnUpdateLong, + global_value, zend_grpc_globals, grpc_globals) + STD_PHP_INI_ENTRY("grpc.global_string", "foobar", PHP_INI_ALL, + OnUpdateString, global_string, zend_grpc_globals, + grpc_globals) + PHP_INI_END() */ /* }}} */ /* {{{ php_grpc_init_globals */ /* Uncomment this function if you have INI entries -static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) -{ - grpc_globals->global_value = 0; - grpc_globals->global_string = NULL; -} + static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) + { + grpc_globals->global_value = 0; + grpc_globals->global_string = NULL; + } */ /* }}} */ @@ -106,7 +111,7 @@ static void php_grpc_init_globals(zend_grpc_globals *grpc_globals) */ PHP_MINIT_FUNCTION(grpc) { /* If you have INI entries, uncomment these lines - REGISTER_INI_ENTRIES(); + REGISTER_INI_ENTRIES(); */ /* Register call error constants */ grpc_init(); @@ -246,7 +251,7 @@ PHP_MINIT_FUNCTION(grpc) { */ PHP_MSHUTDOWN_FUNCTION(grpc) { /* uncomment this line if you have INI entries - UNREGISTER_INI_ENTRIES(); + UNREGISTER_INI_ENTRIES(); */ // WARNING: This function IS being called by PHP when the extension // is unloaded but the logs were somehow suppressed. @@ -265,7 +270,7 @@ PHP_MINFO_FUNCTION(grpc) { php_info_print_table_end(); /* Remove comments if you have entries in php.ini - DISPLAY_INI_ENTRIES(); + DISPLAY_INI_ENTRIES(); */ } /* }}} */ @@ -274,12 +279,3 @@ PHP_MINFO_FUNCTION(grpc) { function definition, where the functions purpose is also documented. Please follow this convention for the convenience of others editing your code. */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: noet sw=4 ts=4 fdm=marker - * vim<600: noet sw=4 ts=4 - */ diff --git a/src/php/ext/grpc/php_grpc.h b/src/php/ext/grpc/php_grpc.h index 1d4834c50fa..e57a06545e6 100644 --- a/src/php/ext/grpc/php_grpc.h +++ b/src/php/ext/grpc/php_grpc.h @@ -57,6 +57,8 @@ extern zend_module_entry grpc_module_entry; #include "php.h" +#include "php7_wrapper.h" + #include "grpc/grpc.h" #define RETURN_DESTROY_ZVAL(val) \ @@ -72,8 +74,8 @@ PHP_MSHUTDOWN_FUNCTION(grpc); PHP_MINFO_FUNCTION(grpc); /* - Declare any global variables you may need between the BEGIN - and END macros here: + Declare any global variables you may need between the BEGIN + and END macros here: ZEND_BEGIN_MODULE_GLOBALS(grpc) ZEND_END_MODULE_GLOBALS(grpc) diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c index c13e7cd1f92..fc20c42b169 100644 --- a/src/php/ext/grpc/server.c +++ b/src/php/ext/grpc/server.c @@ -57,37 +57,29 @@ #include "timeval.h" zend_class_entry *grpc_ce_server; +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers server_ce_handlers; +#endif /* Frees and destroys an instance of wrapped_grpc_server */ -void free_wrapped_grpc_server(void *object TSRMLS_DC) { - wrapped_grpc_server *server = (wrapped_grpc_server *)object; - if (server->wrapped != NULL) { - grpc_server_shutdown_and_notify(server->wrapped, completion_queue, NULL); - grpc_server_cancel_all_calls(server->wrapped); +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_server) + if (p->wrapped != NULL) { + grpc_server_shutdown_and_notify(p->wrapped, completion_queue, NULL); + grpc_server_cancel_all_calls(p->wrapped); grpc_completion_queue_pluck(completion_queue, NULL, gpr_inf_future(GPR_CLOCK_REALTIME), NULL); - grpc_server_destroy(server->wrapped); + grpc_server_destroy(p->wrapped); } - efree(server); -} +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instance of wrapped_grpc_call to be associated with an object * of a class specified by class_type */ -zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type - TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_server *intern; - - intern = (wrapped_grpc_server *)emalloc(sizeof(wrapped_grpc_server)); - memset(intern, 0, sizeof(wrapped_grpc_server)); - +php_grpc_zend_object create_wrapped_grpc_server(zend_class_entry *class_type + TSRMLS_DC) { + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_server); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_server, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_server, server_ce_handlers); } /** @@ -95,10 +87,10 @@ zend_object_value create_wrapped_grpc_server(zend_class_entry *class_type * @param array $args The arguments to pass to the server (optional) */ PHP_METHOD(Server, __construct) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); zval *args_array = NULL; grpc_channel_args args; + /* "|a" == 1 optional array */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a", &args_array) == FAILURE) { @@ -110,6 +102,8 @@ PHP_METHOD(Server, __construct) { if (args_array == NULL) { server->wrapped = grpc_server_create(NULL, NULL); } else { + //TODO(thinkerou): deal it if key of array is long, crash now on php7 + // and update unit test case php_grpc_read_args_array(args_array, &args TSRMLS_CC); server->wrapped = grpc_server_create(&args, NULL); efree(args.args); @@ -126,15 +120,16 @@ PHP_METHOD(Server, __construct) { */ PHP_METHOD(Server, requestCall) { grpc_call_error error_code; - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); grpc_call *call; grpc_call_details details; grpc_metadata_array metadata; - zval *result; grpc_event event; - MAKE_STD_ZVAL(result); + + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); + zval *result; + PHP_GRPC_MAKE_STD_ZVAL(result); object_init(result); + grpc_call_details_init(&details); grpc_metadata_array_init(&metadata); error_code = @@ -146,20 +141,37 @@ PHP_METHOD(Server, requestCall) { goto cleanup; } event = grpc_completion_queue_pluck(completion_queue, NULL, - gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + gpr_inf_future(GPR_CLOCK_REALTIME), + NULL); if (!event.success) { zend_throw_exception(spl_ce_LogicException, "Failed to request a call for some reason", 1 TSRMLS_CC); goto cleanup; } + php_grpc_add_property_string(result, "method", details.method, true); + php_grpc_add_property_string(result, "host", details.host, true); +#if PHP_MAJOR_VERSION < 7 add_property_zval(result, "call", grpc_php_wrap_call(call, true TSRMLS_CC)); - add_property_string(result, "method", details.method, true); - add_property_string(result, "host", details.host, true); add_property_zval(result, "absolute_deadline", grpc_php_wrap_timeval(details.deadline TSRMLS_CC)); - add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata TSRMLS_CC)); -cleanup: + add_property_zval(result, "metadata", grpc_parse_metadata_array(&metadata + TSRMLS_CC)); +#else + zval zv_call; + zval zv_timeval; + zval zv_md; + //TODO(thinkerou): why use zval* to unit test error? + zv_call = *grpc_php_wrap_call(call, true); + zv_timeval = *grpc_php_wrap_timeval(details.deadline); + zv_md = *grpc_parse_metadata_array(&metadata); + + add_property_zval(result, "call", &zv_call); + add_property_zval(result, "absolute_deadline", &zv_timeval); + add_property_zval(result, "metadata", &zv_md); +#endif + + cleanup: grpc_call_details_destroy(&details); grpc_metadata_array_destroy(&metadata); RETURN_DESTROY_ZVAL(result); @@ -171,13 +183,13 @@ cleanup: * @return true on success, false on failure */ PHP_METHOD(Server, addHttp2Port) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; - int addr_len; + php_grpc_int addr_len; + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); + /* "s" == 1 string */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) == - FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &addr_len) + == FAILURE) { zend_throw_exception(spl_ce_InvalidArgumentException, "add_http2_port expects a string", 1 TSRMLS_CC); return; @@ -186,11 +198,11 @@ PHP_METHOD(Server, addHttp2Port) { } PHP_METHOD(Server, addSecureHttp2Port) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); const char *addr; - int addr_len; + php_grpc_int addr_len; zval *creds_obj; + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); + /* "sO" == 1 string, 1 object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO", &addr, &addr_len, &creds_obj, grpc_ce_server_credentials) == @@ -201,8 +213,7 @@ PHP_METHOD(Server, addSecureHttp2Port) { return; } wrapped_grpc_server_credentials *creds = - (wrapped_grpc_server_credentials *)zend_object_store_get_object( - creds_obj TSRMLS_CC); + Z_WRAPPED_GRPC_SERVER_CREDS_P(creds_obj); RETURN_LONG(grpc_server_add_secure_http2_port(server->wrapped, addr, creds->wrapped)); } @@ -212,21 +223,23 @@ PHP_METHOD(Server, addSecureHttp2Port) { * @return Void */ PHP_METHOD(Server, start) { - wrapped_grpc_server *server = - (wrapped_grpc_server *)zend_object_store_get_object(getThis() TSRMLS_CC); + wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis()); grpc_server_start(server->wrapped); } static zend_function_entry server_methods[] = { - PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) PHP_FE_END}; + PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC) + PHP_FE_END +}; void grpc_init_server(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Server", server_methods); ce.create_object = create_wrapped_grpc_server; grpc_ce_server = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_server, server_ce_handlers); } diff --git a/src/php/ext/grpc/server.h b/src/php/ext/grpc/server.h index 022257f37c3..a635bc11df9 100755 --- a/src/php/ext/grpc/server.h +++ b/src/php/ext/grpc/server.h @@ -49,11 +49,26 @@ extern zend_class_entry *grpc_ce_server; /* Wrapper struct for grpc_server that can be associated with a PHP object */ -typedef struct wrapped_grpc_server { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_server) grpc_server *wrapped; -} wrapped_grpc_server; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_server) + +#if PHP_MAJOR_VERSION < 7 + +#define Z_WRAPPED_GRPC_SERVER_P(zv) \ + (wrapped_grpc_server *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_server +*wrapped_grpc_server_from_obj(zend_object *obj) { + return (wrapped_grpc_server*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_server, std)); +} + +#define Z_WRAPPED_GRPC_SERVER_P(zv) wrapped_grpc_server_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Initializes the Server class */ void grpc_init_server(TSRMLS_D); diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c index 505da10a282..b05896af4af 100644 --- a/src/php/ext/grpc/server_credentials.c +++ b/src/php/ext/grpc/server_credentials.c @@ -50,44 +50,35 @@ #include zend_class_entry *grpc_ce_server_credentials; +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers server_credentials_ce_handlers; +#endif /* Frees and destroys an instace of wrapped_grpc_server_credentials */ -void free_wrapped_grpc_server_credentials(void *object TSRMLS_DC) { - wrapped_grpc_server_credentials *creds = - (wrapped_grpc_server_credentials *)object; - if (creds->wrapped != NULL) { - grpc_server_credentials_release(creds->wrapped); +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_server_credentials) + if (p->wrapped != NULL) { + grpc_server_credentials_release(p->wrapped); } - efree(creds); -} +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instace of wrapped_grpc_server_credentials to be associated * with an object of a class specified by class_type */ -zend_object_value create_wrapped_grpc_server_credentials( +php_grpc_zend_object create_wrapped_grpc_server_credentials( zend_class_entry *class_type TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_server_credentials *intern; - - intern = (wrapped_grpc_server_credentials *)emalloc( - sizeof(wrapped_grpc_server_credentials)); - memset(intern, 0, sizeof(wrapped_grpc_server_credentials)); - + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_server_credentials); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_server_credentials, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_server_credentials, + server_credentials_ce_handlers); } -zval *grpc_php_wrap_server_credentials(grpc_server_credentials *wrapped TSRMLS_DC) { +zval *grpc_php_wrap_server_credentials(grpc_server_credentials + *wrapped TSRMLS_DC) { zval *server_credentials_object; - MAKE_STD_ZVAL(server_credentials_object); + PHP_GRPC_MAKE_STD_ZVAL(server_credentials_object); object_init_ex(server_credentials_object, grpc_ce_server_credentials); wrapped_grpc_server_credentials *server_credentials = - (wrapped_grpc_server_credentials *)zend_object_store_get_object( - server_credentials_object TSRMLS_CC); + Z_WRAPPED_GRPC_SERVER_CREDS_P(server_credentials_object); server_credentials->wrapped = wrapped; return server_credentials_object; } @@ -103,7 +94,9 @@ PHP_METHOD(ServerCredentials, createSsl) { char *pem_root_certs = 0; grpc_ssl_pem_key_cert_pair pem_key_cert_pair; - int root_certs_length = 0, private_key_length, cert_chain_length; + php_grpc_int root_certs_length = 0; + php_grpc_int private_key_length; + php_grpc_int cert_chain_length; /* "s!ss" == 1 nullable string, 2 strings */ /* TODO: support multiple key cert pairs. */ @@ -120,17 +113,23 @@ PHP_METHOD(ServerCredentials, createSsl) { grpc_server_credentials *creds = grpc_ssl_server_credentials_create_ex( pem_root_certs, &pem_key_cert_pair, 1, GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, NULL); - zval *creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC); + zval *creds_object; + PHP_GRPC_MAKE_STD_ZVAL(creds_object); + creds_object = grpc_php_wrap_server_credentials(creds TSRMLS_CC); RETURN_DESTROY_ZVAL(creds_object); } static zend_function_entry server_credentials_methods[] = { - PHP_ME(ServerCredentials, createSsl, NULL, - ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; + PHP_ME(ServerCredentials, createSsl, NULL, + ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END + }; void grpc_init_server_credentials(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\ServerCredentials", server_credentials_methods); ce.create_object = create_wrapped_grpc_server_credentials; grpc_ce_server_credentials = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_server_credentials, + server_credentials_ce_handlers); } diff --git a/src/php/ext/grpc/server_credentials.h b/src/php/ext/grpc/server_credentials.h index 7101d650008..6781a614b17 100755 --- a/src/php/ext/grpc/server_credentials.h +++ b/src/php/ext/grpc/server_credentials.h @@ -51,11 +51,27 @@ extern zend_class_entry *grpc_ce_server_credentials; /* Wrapper struct for grpc_server_credentials that can be associated with a PHP * object */ -typedef struct wrapped_grpc_server_credentials { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_server_credentials) grpc_server_credentials *wrapped; -} wrapped_grpc_server_credentials; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_server_credentials) + +#if PHP_MAJOR_VERSION < 7 + +#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \ + (wrapped_grpc_server_credentials *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_server_credentials +*wrapped_grpc_server_credentials_from_obj(zend_object *obj) { + return (wrapped_grpc_server_credentials*)( + (char*)(obj) - XtOffsetOf(wrapped_grpc_server_credentials, std)); +} + +#define Z_WRAPPED_GRPC_SERVER_CREDS_P(zv) \ + wrapped_grpc_server_credentials_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Initializes the Server_Credentials PHP class */ void grpc_init_server_credentials(TSRMLS_D); diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c index 5e242162a8c..e145d967726 100644 --- a/src/php/ext/grpc/timeval.c +++ b/src/php/ext/grpc/timeval.c @@ -51,34 +51,29 @@ #include zend_class_entry *grpc_ce_timeval; +#if PHP_MAJOR_VERSION >= 7 +static zend_object_handlers timeval_ce_handlers; +#endif /* Frees and destroys an instance of wrapped_grpc_call */ -void free_wrapped_grpc_timeval(void *object TSRMLS_DC) { efree(object); } +PHP_GRPC_FREE_WRAPPED_FUNC_START(wrapped_grpc_timeval) +PHP_GRPC_FREE_WRAPPED_FUNC_END() /* Initializes an instance of wrapped_grpc_timeval to be associated with an * object of a class specified by class_type */ -zend_object_value create_wrapped_grpc_timeval(zend_class_entry *class_type - TSRMLS_DC) { - zend_object_value retval; - wrapped_grpc_timeval *intern; - intern = (wrapped_grpc_timeval *)emalloc(sizeof(wrapped_grpc_timeval)); - memset(intern, 0, sizeof(wrapped_grpc_timeval)); +php_grpc_zend_object create_wrapped_grpc_timeval(zend_class_entry *class_type + TSRMLS_DC) { + PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_timeval); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - free_wrapped_grpc_timeval, NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); - return retval; + PHP_GRPC_FREE_CLASS_OBJECT(wrapped_grpc_timeval, timeval_ce_handlers); } zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC) { zval *timeval_object; - MAKE_STD_ZVAL(timeval_object); + PHP_GRPC_MAKE_STD_ZVAL(timeval_object); object_init_ex(timeval_object, grpc_ce_timeval); - wrapped_grpc_timeval *timeval = - (wrapped_grpc_timeval *)zend_object_store_get_object( - timeval_object TSRMLS_CC); + wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(timeval_object); memcpy(&timeval->wrapped, &wrapped, sizeof(gpr_timespec)); return timeval_object; } @@ -88,9 +83,9 @@ zval *grpc_php_wrap_timeval(gpr_timespec wrapped TSRMLS_DC) { * @param long $usec The number of microseconds in the interval */ PHP_METHOD(Timeval, __construct) { - wrapped_grpc_timeval *timeval = - (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); - long microseconds; + wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + php_grpc_long microseconds; + /* "l" == 1 long */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", µseconds) == FAILURE) { @@ -110,6 +105,7 @@ PHP_METHOD(Timeval, __construct) { */ PHP_METHOD(Timeval, add) { zval *other_obj; + /* "O" == 1 Object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &other_obj, grpc_ce_timeval) == FAILURE) { @@ -117,12 +113,13 @@ PHP_METHOD(Timeval, add) { "add expects a Timeval", 1 TSRMLS_CC); return; } - wrapped_grpc_timeval *self = - (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); - wrapped_grpc_timeval *other = - (wrapped_grpc_timeval *)zend_object_store_get_object(other_obj TSRMLS_CC); - zval *sum = - grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) TSRMLS_CC); + wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); + zval *sum; + PHP_GRPC_MAKE_STD_ZVAL(sum); + sum = + grpc_php_wrap_timeval(gpr_time_add(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(sum); } @@ -134,6 +131,7 @@ PHP_METHOD(Timeval, add) { */ PHP_METHOD(Timeval, subtract) { zval *other_obj; + /* "O" == 1 Object */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &other_obj, grpc_ce_timeval) == FAILURE) { @@ -141,12 +139,13 @@ PHP_METHOD(Timeval, subtract) { "subtract expects a Timeval", 1 TSRMLS_CC); return; } - wrapped_grpc_timeval *self = - (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); - wrapped_grpc_timeval *other = - (wrapped_grpc_timeval *)zend_object_store_get_object(other_obj TSRMLS_CC); - zval *diff = - grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) TSRMLS_CC); + wrapped_grpc_timeval *self = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); + wrapped_grpc_timeval *other = Z_WRAPPED_GRPC_TIMEVAL_P(other_obj); + zval *diff; + PHP_GRPC_MAKE_STD_ZVAL(diff); + diff = + grpc_php_wrap_timeval(gpr_time_sub(self->wrapped, other->wrapped) + TSRMLS_CC); RETURN_DESTROY_ZVAL(diff); } @@ -158,7 +157,9 @@ PHP_METHOD(Timeval, subtract) { * @return long */ PHP_METHOD(Timeval, compare) { - zval *a_obj, *b_obj; + zval *a_obj; + zval *b_obj; + /* "OO" == 2 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &a_obj, grpc_ce_timeval, &b_obj, @@ -167,10 +168,8 @@ PHP_METHOD(Timeval, compare) { "compare expects two Timevals", 1 TSRMLS_CC); return; } - wrapped_grpc_timeval *a = - (wrapped_grpc_timeval *)zend_object_store_get_object(a_obj TSRMLS_CC); - wrapped_grpc_timeval *b = - (wrapped_grpc_timeval *)zend_object_store_get_object(b_obj TSRMLS_CC); + wrapped_grpc_timeval *a = Z_WRAPPED_GRPC_TIMEVAL_P(a_obj); + wrapped_grpc_timeval *b = Z_WRAPPED_GRPC_TIMEVAL_P(b_obj); long result = gpr_time_cmp(a->wrapped, b->wrapped); RETURN_LONG(result); } @@ -183,7 +182,10 @@ PHP_METHOD(Timeval, compare) { * @return bool True if $a and $b are within $threshold, False otherwise */ PHP_METHOD(Timeval, similar) { - zval *a_obj, *b_obj, *thresh_obj; + zval *a_obj; + zval *b_obj; + zval *thresh_obj; + /* "OOO" == 3 Objects */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OOO", &a_obj, grpc_ce_timeval, &b_obj, grpc_ce_timeval, @@ -192,13 +194,9 @@ PHP_METHOD(Timeval, similar) { "compare expects three Timevals", 1 TSRMLS_CC); return; } - wrapped_grpc_timeval *a = - (wrapped_grpc_timeval *)zend_object_store_get_object(a_obj TSRMLS_CC); - wrapped_grpc_timeval *b = - (wrapped_grpc_timeval *)zend_object_store_get_object(b_obj TSRMLS_CC); - wrapped_grpc_timeval *thresh = - (wrapped_grpc_timeval *)zend_object_store_get_object( - thresh_obj TSRMLS_CC); + wrapped_grpc_timeval *a = Z_WRAPPED_GRPC_TIMEVAL_P(a_obj); + wrapped_grpc_timeval *b = Z_WRAPPED_GRPC_TIMEVAL_P(b_obj); + wrapped_grpc_timeval *thresh = Z_WRAPPED_GRPC_TIMEVAL_P(thresh_obj); int result = gpr_time_similar(a->wrapped, b->wrapped, thresh->wrapped); RETURN_BOOL(result); } @@ -208,7 +206,9 @@ PHP_METHOD(Timeval, similar) { * @return Timeval The current time */ PHP_METHOD(Timeval, now) { - zval *now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC); + zval *now; + PHP_GRPC_MAKE_STD_ZVAL(now); + now = grpc_php_wrap_timeval(gpr_now(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(now); } @@ -217,7 +217,9 @@ PHP_METHOD(Timeval, now) { * @return Timeval Zero length time interval */ PHP_METHOD(Timeval, zero) { - zval *grpc_php_timeval_zero = + zval *grpc_php_timeval_zero; + PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_zero); + grpc_php_timeval_zero = grpc_php_wrap_timeval(gpr_time_0(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_ZVAL(grpc_php_timeval_zero, false, /* Copy original before returning? */ @@ -229,7 +231,9 @@ PHP_METHOD(Timeval, zero) { * @return Timeval Infinite future time value */ PHP_METHOD(Timeval, infFuture) { - zval *grpc_php_timeval_inf_future = + zval *grpc_php_timeval_inf_future; + PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_future); + grpc_php_timeval_inf_future = grpc_php_wrap_timeval(gpr_inf_future(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_future); } @@ -239,7 +243,9 @@ PHP_METHOD(Timeval, infFuture) { * @return Timeval Infinite past time value */ PHP_METHOD(Timeval, infPast) { - zval *grpc_php_timeval_inf_past = + zval *grpc_php_timeval_inf_past; + PHP_GRPC_MAKE_STD_ZVAL(grpc_php_timeval_inf_past); + grpc_php_timeval_inf_past = grpc_php_wrap_timeval(gpr_inf_past(GPR_CLOCK_REALTIME) TSRMLS_CC); RETURN_DESTROY_ZVAL(grpc_php_timeval_inf_past); } @@ -249,28 +255,30 @@ PHP_METHOD(Timeval, infPast) { * @return void */ PHP_METHOD(Timeval, sleepUntil) { - wrapped_grpc_timeval *this = - (wrapped_grpc_timeval *)zend_object_store_get_object(getThis() TSRMLS_CC); + wrapped_grpc_timeval *this = Z_WRAPPED_GRPC_TIMEVAL_P(getThis()); gpr_sleep_until(this->wrapped); } static zend_function_entry timeval_methods[] = { - PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) - PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) - PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) PHP_FE_END}; + PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) + PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC) + PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_FE_END +}; void grpc_init_timeval(TSRMLS_D) { zend_class_entry ce; INIT_CLASS_ENTRY(ce, "Grpc\\Timeval", timeval_methods); ce.create_object = create_wrapped_grpc_timeval; grpc_ce_timeval = zend_register_internal_class(&ce TSRMLS_CC); + PHP_GRPC_INIT_HANDLER(wrapped_grpc_timeval, timeval_ce_handlers); } void grpc_shutdown_timeval(TSRMLS_D) {} diff --git a/src/php/ext/grpc/timeval.h b/src/php/ext/grpc/timeval.h index 7456eb6d58c..63a1d702f37 100755 --- a/src/php/ext/grpc/timeval.h +++ b/src/php/ext/grpc/timeval.h @@ -50,11 +50,27 @@ extern zend_class_entry *grpc_ce_timeval; /* Wrapper struct for timeval that can be associated with a PHP object */ -typedef struct wrapped_grpc_timeval { - zend_object std; - +PHP_GRPC_WRAP_OBJECT_START(wrapped_grpc_timeval) gpr_timespec wrapped; -} wrapped_grpc_timeval; +PHP_GRPC_WRAP_OBJECT_END(wrapped_grpc_timeval) + +#if PHP_MAJOR_VERSION < 7 + +#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \ + (wrapped_grpc_timeval *)zend_object_store_get_object(zv TSRMLS_CC) + +#else + +static inline wrapped_grpc_timeval +*wrapped_grpc_timeval_from_obj(zend_object *obj) { + return (wrapped_grpc_timeval*)((char*)(obj) - + XtOffsetOf(wrapped_grpc_timeval, std)); +} + +#define Z_WRAPPED_GRPC_TIMEVAL_P(zv) \ + wrapped_grpc_timeval_from_obj(Z_OBJ_P((zv))) + +#endif /* PHP_MAJOR_VERSION */ /* Initialize the Timeval PHP class */ void grpc_init_timeval(TSRMLS_D); diff --git a/src/php/lib/Grpc/AbstractCall.php b/src/php/lib/Grpc/AbstractCall.php index c86d2988055..c58ee567424 100644 --- a/src/php/lib/Grpc/AbstractCall.php +++ b/src/php/lib/Grpc/AbstractCall.php @@ -34,8 +34,15 @@ namespace Grpc; +/** + * Class AbstractCall + * @package Grpc + */ abstract class AbstractCall { + /** + * @var Call + */ protected $call; protected $deserialize; protected $metadata; @@ -51,13 +58,15 @@ abstract class AbstractCall * the response * @param array $options Call options (optional) */ - public function __construct(Channel $channel, - $method, - $deserialize, - $options = []) - { - if (isset($options['timeout']) && - is_numeric($timeout = $options['timeout'])) { + public function __construct( + Channel $channel, + $method, + $deserialize, + $options = [] + ) { + if (array_key_exists('timeout', $options) && + is_numeric($timeout = $options['timeout']) + ) { $now = Timeval::now(); $delta = new Timeval($timeout); $deadline = $now->add($delta); @@ -68,17 +77,19 @@ abstract class AbstractCall $this->deserialize = $deserialize; $this->metadata = null; $this->trailing_metadata = null; - if (isset($options['call_credentials_callback']) && + if (array_key_exists('call_credentials_callback', $options) && is_callable($call_credentials_callback = - $options['call_credentials_callback'])) { + $options['call_credentials_callback']) + ) { $call_credentials = CallCredentials::createFromPlugin( - $call_credentials_callback); + $call_credentials_callback + ); $this->call->setCredentials($call_credentials); } } /** - * @return The metadata sent by the server. + * @return mixed The metadata sent by the server. */ public function getMetadata() { @@ -86,7 +97,7 @@ abstract class AbstractCall } /** - * @return The trailing metadata sent by the server. + * @return mixed The trailing metadata sent by the server. */ public function getTrailingMetadata() { @@ -114,7 +125,7 @@ abstract class AbstractCall * * @param string $value The binary value to deserialize * - * @return The deserialized value + * @return mixed The deserialized value */ protected function deserializeResponse($value) { diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php old mode 100755 new mode 100644 index df3fe85d447..d850eebc788 --- a/src/php/lib/Grpc/BaseStub.php +++ b/src/php/lib/Grpc/BaseStub.php @@ -41,6 +41,7 @@ namespace Grpc; class BaseStub { private $hostname; + private $hostname_override; private $channel; // a callback function @@ -75,6 +76,9 @@ class BaseStub } else { $opts['grpc.primary_user_agent'] = ''; } + if (!empty($opts['grpc.ssl_target_name_override'])) { + $this->hostname_override = $opts['grpc.ssl_target_name_override']; + } $opts['grpc.primary_user_agent'] .= 'grpc-php/'.$package_config['version']; if (!array_key_exists('credentials', $opts)) { @@ -84,8 +88,8 @@ class BaseStub } if ($channel) { if (!is_a($channel, 'Channel')) { - throw new \Exception("The channel argument is not a". - "Channel object"); + throw new \Exception('The channel argument is not a'. + 'Channel object'); } $this->channel = $channel; } else { @@ -173,7 +177,12 @@ class BaseStub } $service_name = substr($method, 0, $last_slash_idx); - return 'https://'.$this->hostname.$service_name; + if ($this->hostname_override) { + $hostname = $this->hostname_override; + } else { + $hostname = $this->hostname; + } + return 'https://'.$hostname.$service_name; } /** diff --git a/src/php/lib/Grpc/BidiStreamingCall.php b/src/php/lib/Grpc/BidiStreamingCall.php index 95e51c5088d..5d6ecfb275b 100644 --- a/src/php/lib/Grpc/BidiStreamingCall.php +++ b/src/php/lib/Grpc/BidiStreamingCall.php @@ -45,7 +45,7 @@ class BidiStreamingCall extends AbstractCall * * @param array $metadata Metadata to send with the call, if applicable */ - public function start($metadata = []) + public function start(array $metadata = []) { $this->call->startBatch([ OP_SEND_INITIAL_METADATA => $metadata, @@ -55,7 +55,7 @@ class BidiStreamingCall extends AbstractCall /** * Reads the next value from the server. * - * @return The next value from the server, or null if there is none + * @return mixed The next value from the server, or null if there is none */ public function read() { @@ -82,7 +82,7 @@ class BidiStreamingCall extends AbstractCall public function write($data, $options = []) { $message_array = ['message' => $data->serialize()]; - if (isset($options['flags'])) { + if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ @@ -103,8 +103,8 @@ class BidiStreamingCall extends AbstractCall /** * Wait for the server to send the status, and return it. * - * @return object The status object, with integer $code, string $details, - * and array $metadata members + * @return \stdClass The status object, with integer $code, string $details, + * and array $metadata members */ public function getStatus() { @@ -113,6 +113,7 @@ class BidiStreamingCall extends AbstractCall ]); $this->trailing_metadata = $status_event->status->metadata; + return $status_event->status; } } diff --git a/src/php/lib/Grpc/ClientStreamingCall.php b/src/php/lib/Grpc/ClientStreamingCall.php index 315a406735f..c96e26d0330 100644 --- a/src/php/lib/Grpc/ClientStreamingCall.php +++ b/src/php/lib/Grpc/ClientStreamingCall.php @@ -60,10 +60,10 @@ class ClientStreamingCall extends AbstractCall * @param array $options an array of options, possible keys: * 'flags' => a number */ - public function write($data, $options = []) + public function write($data, array $options = []) { $message_array = ['message' => $data->serialize()]; - if (isset($options['flags'])) { + if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $this->call->startBatch([ @@ -74,7 +74,7 @@ class ClientStreamingCall extends AbstractCall /** * Wait for the server to respond with data and a status. * - * @return [response data, status] + * @return array [response data, status] */ public function wait() { @@ -88,6 +88,7 @@ class ClientStreamingCall extends AbstractCall $status = $event->status; $this->trailing_metadata = $status->metadata; + return [$this->deserializeResponse($event->message), $status]; } } diff --git a/src/php/lib/Grpc/ServerStreamingCall.php b/src/php/lib/Grpc/ServerStreamingCall.php index 53599fe4ae8..5f0d42c528a 100644 --- a/src/php/lib/Grpc/ServerStreamingCall.php +++ b/src/php/lib/Grpc/ServerStreamingCall.php @@ -36,14 +36,14 @@ namespace Grpc; /** * Represents an active call that sends a single message and then gets a stream - * of reponses. + * of responses. */ class ServerStreamingCall extends AbstractCall { /** * Start the call. * - * @param $data The data to send + * @param mixed $data The data to send * @param array $metadata Metadata to send with the call, if applicable * @param array $options an array of options, possible keys: * 'flags' => a number @@ -51,7 +51,7 @@ class ServerStreamingCall extends AbstractCall public function start($data, $metadata = [], $options = []) { $message_array = ['message' => $data->serialize()]; - if (isset($options['flags'])) { + if (array_key_exists('flags', $options)) { $message_array['flags'] = $options['flags']; } $event = $this->call->startBatch([ @@ -64,7 +64,7 @@ class ServerStreamingCall extends AbstractCall } /** - * @return An iterator of response values + * @return mixed An iterator of response values */ public function responses() { @@ -82,8 +82,8 @@ class ServerStreamingCall extends AbstractCall /** * Wait for the server to send the status, and return it. * - * @return object The status object, with integer $code, string $details, - * and array $metadata members + * @return \stdClass The status object, with integer $code, string $details, + * and array $metadata members */ public function getStatus() { @@ -92,6 +92,7 @@ class ServerStreamingCall extends AbstractCall ]); $this->trailing_metadata = $status_event->status->metadata; + return $status_event->status; } } diff --git a/src/php/lib/Grpc/UnaryCall.php b/src/php/lib/Grpc/UnaryCall.php index b114b771b84..487b89ebc1b 100644 --- a/src/php/lib/Grpc/UnaryCall.php +++ b/src/php/lib/Grpc/UnaryCall.php @@ -43,7 +43,7 @@ class UnaryCall extends AbstractCall /** * Start the call. * - * @param $data The data to send + * @param mixed $data The data to send * @param array $metadata Metadata to send with the call, if applicable * @param array $options an array of options, possible keys: * 'flags' => a number @@ -66,7 +66,7 @@ class UnaryCall extends AbstractCall /** * Wait for the server to respond with data and a status. * - * @return [response data, status] + * @return array [response data, status] */ public function wait() { @@ -77,6 +77,7 @@ class UnaryCall extends AbstractCall $status = $event->status; $this->trailing_metadata = $status->metadata; + return [$this->deserializeResponse($event->message), $status]; } } diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 43b3199d92c..94ceeda02c7 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -54,6 +54,15 @@ function hardAssert($value, $error_message) } } +function hardAssertIfStatusOk($status) +{ + if ($status->code !== Grpc\STATUS_OK) { + echo "Call did not complete successfully. Status object:\n"; + var_dump($status); + exit(1); + } +} + /** * Run the empty_unary test. * @@ -62,7 +71,7 @@ function hardAssert($value, $error_message) function emptyUnary($stub) { list($result, $status) = $stub->EmptyCall(new grpc\testing\EmptyMessage())->wait(); - hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully'); + hardAssertIfStatusOk($status); hardAssert($result !== null, 'Call completed with a null response'); } @@ -99,13 +108,13 @@ function performLargeUnary($stub, $fillUsername = false, $fillOauthScope = false $request->setFillUsername($fillUsername); $request->setFillOauthScope($fillOauthScope); - $options = false; + $options = []; if ($callback) { $options['call_credentials_callback'] = $callback; } list($result, $status) = $stub->UnaryCall($request, [], $options)->wait(); - hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully'); + hardAssertIfStatusOk($status); hardAssert($result !== null, 'Call returned a null response'); $payload = $result->getPayload(); hardAssert($payload->getType() === grpc\testing\PayloadType::COMPRESSABLE, @@ -197,7 +206,12 @@ function updateAuthMetadataCallback($context) $methodName = $context->method_name; $auth_credentials = ApplicationDefaultCredentials::getCredentials(); - return $auth_credentials->updateMetadata($metadata = [], $authUri); + $metadata = []; + $result = $auth_credentials->updateMetadata([], $authUri); + foreach ($result as $key => $value) { + $metadata[strtolower($key)] = $value; + } + return $metadata; } /** @@ -242,7 +256,7 @@ function clientStreaming($stub) $call->write($request); } list($result, $status) = $call->wait(); - hardAssert($status->code === Grpc\STATUS_OK, 'Call did not complete successfully'); + hardAssertIfStatusOk($status); hardAssert($result->getAggregatedPayloadSize() === 74922, 'aggregated_payload_size was incorrect'); } @@ -275,8 +289,7 @@ function serverStreaming($stub) 'Response '.$i.' had the wrong length'); $i += 1; } - hardAssert($call->getStatus()->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); + hardAssertIfStatusOk($call->getStatus()); } /** @@ -312,8 +325,7 @@ function pingPong($stub) } $call->writesDone(); hardAssert($call->read() === null, 'Server returned too many responses'); - hardAssert($call->getStatus()->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); + hardAssertIfStatusOk($call->getStatus()); } /** @@ -326,8 +338,7 @@ function emptyStream($stub) $call = $stub->FullDuplexCall(); $call->writesDone(); hardAssert($call->read() === null, 'Server returned too many responses'); - hardAssert($call->getStatus()->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); + hardAssertIfStatusOk($call->getStatus()); } /** @@ -419,8 +430,7 @@ function customMetadata($stub) 'Incorrect initial metadata value'); list($result, $status) = $call->wait(); - hardAssert($status->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); + hardAssertIfStatusOk($status); $trailing_metadata = $call->getTrailingMetadata(); hardAssert(array_key_exists($ECHO_TRAILING_KEY, $trailing_metadata), @@ -435,8 +445,7 @@ function customMetadata($stub) $streaming_call->write($streaming_request); $streaming_call->writesDone(); - hardAssert($streaming_call->getStatus()->code === Grpc\STATUS_OK, - 'Call did not complete successfully'); + hardAssertIfStatusOk($streaming_call->getStatus()); $streaming_trailing_metadata = $streaming_call->getTrailingMetadata(); hardAssert(array_key_exists($ECHO_TRAILING_KEY, @@ -450,7 +459,7 @@ function statusCodeAndMessage($stub) { $echo_status = new grpc\testing\EchoStatus(); $echo_status->setCode(2); - $echo_status->setMessage("test status message"); + $echo_status->setMessage('test status message'); $request = new grpc\testing\SimpleRequest(); $request->setResponseStatus($echo_status); @@ -460,7 +469,7 @@ function statusCodeAndMessage($stub) hardAssert($status->code === 2, 'Received unexpected status code'); - hardAssert($status->details === "test status message", + hardAssert($status->details === 'test status message', 'Received unexpected status details'); $streaming_call = $stub->FullDuplexCall(); @@ -473,7 +482,7 @@ function statusCodeAndMessage($stub) $status = $streaming_call->getStatus(); hardAssert($status->code === 2, 'Received unexpected status code'); - hardAssert($status->details === "test status message", + hardAssert($status->details === 'test status message', 'Received unexpected status details'); } @@ -570,9 +579,9 @@ function _makeStub($args) } if ($test_case == 'unimplemented_method') { - $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts); + $stub = new grpc\testing\UnimplementedServiceClient($server_address, $opts); } else { - $stub = new grpc\testing\TestServiceClient($server_address, $opts); + $stub = new grpc\testing\TestServiceClient($server_address, $opts); } return $stub; diff --git a/src/php/tests/unit_tests/CallCredentials2Test.php b/src/php/tests/unit_tests/CallCredentials2Test.php index a57e2b9b4ee..b3b98a22cae 100644 --- a/src/php/tests/unit_tests/CallCredentials2Test.php +++ b/src/php/tests/unit_tests/CallCredentials2Test.php @@ -132,4 +132,69 @@ class CallCredentials2Test extends PHPUnit_Framework_TestCase unset($call); unset($server_call); } + + public function invalidKeyCallbackFunc($context) + { + $this->assertTrue(is_string($context->service_url)); + $this->assertTrue(is_string($context->method_name)); + + return ['K1' => ['v1']]; + } + + public function testCallbackWithInvalidKey() + { + $deadline = Grpc\Timeval::infFuture(); + $status_text = 'xyz'; + $call = new Grpc\Call($this->channel, + '/abc/dummy_method', + $deadline, + $this->host_override); + + $call_credentials = Grpc\CallCredentials::createFromPlugin( + array($this, 'invalidKeyCallbackFunc')); + $call->setCredentials($call_credentials); + + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); + $this->assertTrue($event->status->code == Grpc\STATUS_UNAUTHENTICATED); + } + + public function invalidReturnCallbackFunc($context) + { + $this->assertTrue(is_string($context->service_url)); + $this->assertTrue(is_string($context->method_name)); + + return "a string"; + } + + public function testCallbackWithInvalidReturnValue() + { + $deadline = Grpc\Timeval::infFuture(); + $status_text = 'xyz'; + $call = new Grpc\Call($this->channel, + '/abc/dummy_method', + $deadline, + $this->host_override); + + $call_credentials = Grpc\CallCredentials::createFromPlugin( + array($this, 'invalidReturnCallbackFunc')); + $call->setCredentials($call_credentials); + + $event = $call->startBatch([ + Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + Grpc\OP_RECV_STATUS_ON_CLIENT => true, + ]); + + $this->assertTrue($event->send_metadata); + $this->assertTrue($event->send_close); + $this->assertTrue($event->status->code == Grpc\STATUS_UNAUTHENTICATED); + } + } diff --git a/src/php/tests/unit_tests/CallCredentials3Test.php b/src/php/tests/unit_tests/CallCredentials3Test.php deleted file mode 100644 index 8f5e109bf5c..00000000000 --- a/src/php/tests/unit_tests/CallCredentials3Test.php +++ /dev/null @@ -1,135 +0,0 @@ -credentials = Grpc\ChannelCredentials::createSsl( - file_get_contents(dirname(__FILE__).'/../data/ca.pem')); - $server_credentials = Grpc\ServerCredentials::createSsl( - null, - file_get_contents(dirname(__FILE__).'/../data/server1.key'), - file_get_contents(dirname(__FILE__).'/../data/server1.pem')); - $this->server = new Grpc\Server(); - $this->port = $this->server->addSecureHttp2Port('0.0.0.0:0', - $server_credentials); - $this->server->start(); - $this->host_override = 'foo.test.google.fr'; - $this->channel = new Grpc\Channel( - 'localhost:'.$this->port, - [ - 'grpc.ssl_target_name_override' => $this->host_override, - 'grpc.default_authority' => $this->host_override, - 'credentials' => $this->credentials, - ] - ); - } - - public function tearDown() - { - unset($this->channel); - unset($this->server); - } - - public function callbackFunc($context) - { - $this->assertTrue(is_string($context->service_url)); - $this->assertTrue(is_string($context->method_name)); - - return ['k1' => ['v1'], 'k2' => ['v2']]; - } - - public function testCreateFromPlugin() - { - $deadline = Grpc\Timeval::infFuture(); - $status_text = 'xyz'; - $call = new Grpc\Call($this->channel, - '/abc/dummy_method', - $deadline, - $this->host_override); - - $call_credentials = Grpc\CallCredentials::createFromPlugin( - [$this, 'callbackFunc']); - $call->setCredentials($call_credentials); - - $event = $call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, - ]); - - $this->assertTrue($event->send_metadata); - $this->assertTrue($event->send_close); - - $event = $this->server->requestCall(); - - $this->assertTrue(is_array($event->metadata)); - $metadata = $event->metadata; - $this->assertTrue(array_key_exists('k1', $metadata)); - $this->assertTrue(array_key_exists('k2', $metadata)); - $this->assertSame($metadata['k1'], ['v1']); - $this->assertSame($metadata['k2'], ['v2']); - - $this->assertSame('/abc/dummy_method', $event->method); - $server_call = $event->call; - - $event = $server_call->startBatch([ - Grpc\OP_SEND_INITIAL_METADATA => [], - Grpc\OP_SEND_STATUS_FROM_SERVER => [ - 'metadata' => [], - 'code' => Grpc\STATUS_OK, - 'details' => $status_text, - ], - Grpc\OP_RECV_CLOSE_ON_SERVER => true, - ]); - - $this->assertTrue($event->send_metadata); - $this->assertTrue($event->send_status); - $this->assertFalse($event->cancelled); - - $event = $call->startBatch([ - Grpc\OP_RECV_INITIAL_METADATA => true, - Grpc\OP_RECV_STATUS_ON_CLIENT => true, - ]); - - $this->assertSame([], $event->metadata); - $status = $event->status; - $this->assertSame([], $status->metadata); - $this->assertSame(Grpc\STATUS_OK, $status->code); - $this->assertSame($status_text, $status->details); - - unset($call); - unset($server_call); - } -} diff --git a/src/php/tests/unit_tests/CallCredentialsTest.php b/src/php/tests/unit_tests/CallCredentialsTest.php index 5fec06cd133..1994c8afe56 100644 --- a/src/php/tests/unit_tests/CallCredentialsTest.php +++ b/src/php/tests/unit_tests/CallCredentialsTest.php @@ -148,7 +148,8 @@ class CallCredentialsTest extends PHPUnit_Framework_TestCase $this->call_credentials, $call_credentials2 ); - $this->assertSame('Grpc\CallCredentials', get_class($call_credentials3)); + $this->assertSame('Grpc\CallCredentials', + get_class($call_credentials3)); } /** diff --git a/src/php/tests/unit_tests/CallTest.php b/src/php/tests/unit_tests/CallTest.php old mode 100755 new mode 100644 index fa026f09350..1205f0cd8eb --- a/src/php/tests/unit_tests/CallTest.php +++ b/src/php/tests/unit_tests/CallTest.php @@ -50,6 +50,18 @@ class CallTest extends PHPUnit_Framework_TestCase Grpc\Timeval::infFuture()); } + public function tearDown() + { + unset($this->call); + unset($this->channel); + } + + public function testConstructor() + { + $this->assertSame('Grpc\Call', get_class($this->call)); + $this->assertObjectHasAttribute('channel', $this->call); + } + public function testAddEmptyMetadata() { $batch = [ @@ -81,7 +93,8 @@ class CallTest extends PHPUnit_Framework_TestCase { $batch = [ Grpc\OP_SEND_INITIAL_METADATA => ['key1' => ['value1'], - 'key2' => ['value2', 'value3'], ], + 'key2' => ['value2', + 'value3'], ], ]; $result = $this->call->startBatch($batch); $this->assertTrue($result->send_metadata); @@ -100,7 +113,7 @@ class CallTest extends PHPUnit_Framework_TestCase /** * @expectedException InvalidArgumentException */ - public function testInvalidMetadataKey() + public function testInvalidStartBatchKey() { $batch = [ 'invalid' => ['key1' => 'value1'], @@ -108,6 +121,28 @@ class CallTest extends PHPUnit_Framework_TestCase $result = $this->call->startBatch($batch); } + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidMetadataStrKey() + { + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => ['Key' => ['value1', 'value2']], + ]; + $result = $this->call->startBatch($batch); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidMetadataIntKey() + { + $batch = [ + Grpc\OP_SEND_INITIAL_METADATA => [1 => ['value1', 'value2']], + ]; + $result = $this->call->startBatch($batch); + } + /** * @expectedException InvalidArgumentException */ @@ -118,4 +153,38 @@ class CallTest extends PHPUnit_Framework_TestCase ]; $result = $this->call->startBatch($batch); } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstuctor() + { + $this->call = new Grpc\Call(); + $this->assertNull($this->call); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstuctor2() + { + $this->call = new Grpc\Call('hi', 'hi', 'hi'); + $this->assertNull($this->call); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidSetCredentials() + { + $this->call->setCredentials('hi'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidSetCredentials2() + { + $this->call->setCredentials([]); + } } diff --git a/src/php/tests/unit_tests/ChannelCredentialsTest.php b/src/php/tests/unit_tests/ChannelCredentialsTest.php index 56c1d8f006d..e822929ccda 100644 --- a/src/php/tests/unit_tests/ChannelCredentialsTest.php +++ b/src/php/tests/unit_tests/ChannelCredentialsTest.php @@ -42,10 +42,23 @@ class ChanellCredentialsTest extends PHPUnit_Framework_TestCase { } - public function testCreateDefault() + public function testCreateSslWith3Null() { - $channel_credentials = Grpc\ChannelCredentials::createDefault(); - $this->assertSame('Grpc\ChannelCredentials', get_class($channel_credentials)); + $channel_credentials = Grpc\ChannelCredentials::createSsl(null, null, + null); + $this->assertNotNull($channel_credentials); + } + + public function testCreateSslWith3NullString() + { + $channel_credentials = Grpc\ChannelCredentials::createSsl('', '', ''); + $this->assertNotNull($channel_credentials); + } + + public function testCreateInsecure() + { + $channel_credentials = Grpc\ChannelCredentials::createInsecure(); + $this->assertNull($channel_credentials); } /** @@ -64,10 +77,4 @@ class ChanellCredentialsTest extends PHPUnit_Framework_TestCase $channel_credentials = Grpc\ChannelCredentials::createComposite( 'something', 'something'); } - - public function testCreateInsecure() - { - $channel_credentials = Grpc\ChannelCredentials::createInsecure(); - $this->assertNull($channel_credentials); - } } diff --git a/src/php/tests/unit_tests/ChannelTest.php b/src/php/tests/unit_tests/ChannelTest.php index a1f9053c398..4b35b1a28cc 100644 --- a/src/php/tests/unit_tests/ChannelTest.php +++ b/src/php/tests/unit_tests/ChannelTest.php @@ -40,6 +40,7 @@ class ChannelTest extends PHPUnit_Framework_TestCase public function tearDown() { + unset($this->channel); } public function testInsecureCredentials() @@ -53,6 +54,82 @@ class ChannelTest extends PHPUnit_Framework_TestCase $this->assertSame('Grpc\Channel', get_class($this->channel)); } + public function testGetConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithInt() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(123); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithString() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState('hello'); + $this->assertEquals(0, $state); + } + + public function testGetConnectivityStateWithBool() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $state = $this->channel->getConnectivityState(true); + $this->assertEquals(0, $state); + } + + public function testGetTarget() + { + $this->channel = new Grpc\Channel('localhost:8888', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $target = $this->channel->getTarget(); + $this->assertTrue(is_string($target)); + } + + public function testWatchConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $time = new Grpc\Timeval(1000); + $state = $this->channel->watchConnectivityState(123, $time); + $this->assertTrue($state); + unset($time); + } + + public function testClose() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->assertNotNull($this->channel); + $this->channel->close(); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstructorWithNull() + { + $this->channel = new Grpc\Channel(); + $this->assertNull($this->channel); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidConstructorWith() + { + $this->channel = new Grpc\Channel('localhost', 'invalid'); + $this->assertNull($this->channel); + } + /** * @expectedException InvalidArgumentException */ @@ -78,4 +155,34 @@ class ChannelTest extends PHPUnit_Framework_TestCase ] ); } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidGetConnectivityStateWithArray() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->getConnectivityState([]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidWatchConnectivityState() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->watchConnectivityState([]); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidWatchConnectivityState2() + { + $this->channel = new Grpc\Channel('localhost:0', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + $this->channel->watchConnectivityState(1, 'hi'); + } } diff --git a/src/php/tests/unit_tests/EndToEndTest.php b/src/php/tests/unit_tests/EndToEndTest.php old mode 100755 new mode 100644 index 2b09f9d112a..09364580c01 --- a/src/php/tests/unit_tests/EndToEndTest.php +++ b/src/php/tests/unit_tests/EndToEndTest.php @@ -521,7 +521,8 @@ class EndToEndTest extends PHPUnit_Framework_TestCase public function testGetConnectivityState() { - $this->assertTrue($this->channel->getConnectivityState() == Grpc\CHANNEL_IDLE); + $this->assertTrue($this->channel->getConnectivityState() == + Grpc\CHANNEL_IDLE); } public function testWatchConnectivityStateFailed() diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php old mode 100755 new mode 100644 diff --git a/src/php/tests/unit_tests/ServerTest.php b/src/php/tests/unit_tests/ServerTest.php index 76aaa069704..f2346ab113e 100644 --- a/src/php/tests/unit_tests/ServerTest.php +++ b/src/php/tests/unit_tests/ServerTest.php @@ -36,10 +36,70 @@ class ServerTest extends PHPUnit_Framework_TestCase { public function setUp() { + $this->server = null; } public function tearDown() { + unset($this->server); + } + + public function testConstructorWithNull() + { + $this->server = new Grpc\Server(); + $this->assertNotNull($this->server); + } + + public function testConstructorWithNullArray() + { + $this->server = new Grpc\Server([]); + $this->assertNotNull($this->server); + } + + public function testConstructorWithArray() + { + // key of array must be string + $this->server = new Grpc\Server(['ip' => '127.0.0.1', + 'port' => '8080', ]); + $this->assertNotNull($this->server); + } + + public function testRequestCall() + { + $this->server = new Grpc\Server(); + $port = $this->server->addHttp2Port('0.0.0.0:8888'); + $this->server->start(); + $channel = new Grpc\Channel('localhost:8888', + ['credentials' => Grpc\ChannelCredentials::createInsecure()]); + + $deadline = Grpc\Timeval::infFuture(); + $call = new Grpc\Call($channel, 'dummy_method', $deadline); + + $event = $call->startBatch([Grpc\OP_SEND_INITIAL_METADATA => [], + Grpc\OP_SEND_CLOSE_FROM_CLIENT => true, + ]); + + $c = $this->server->requestCall(); + $this->assertObjectHasAttribute('call', $c); + $this->assertObjectHasAttribute('method', $c); + $this->assertSame('dummy_method', $c->method); + $this->assertObjectHasAttribute('host', $c); + $this->assertTrue(is_string($c->host)); + $this->assertObjectHasAttribute('absolute_deadline', $c); + $this->assertObjectHasAttribute('metadata', $c); + + unset($call); + unset($channel); + } + + private function createSslObj() + { + $server_credentials = Grpc\ServerCredentials::createSsl( + null, + file_get_contents(dirname(__FILE__).'/../data/server1.key'), + file_get_contents(dirname(__FILE__).'/../data/server1.pem')); + + return $server_credentials; } /** @@ -47,7 +107,8 @@ class ServerTest extends PHPUnit_Framework_TestCase */ public function testInvalidConstructor() { - $server = new Grpc\Server('invalid_host'); + $this->server = new Grpc\Server('invalid_host'); + $this->assertNull($this->server); } /** @@ -56,7 +117,7 @@ class ServerTest extends PHPUnit_Framework_TestCase public function testInvalidAddHttp2Port() { $this->server = new Grpc\Server([]); - $this->port = $this->server->addHttp2Port(['0.0.0.0:0']); + $port = $this->server->addHttp2Port(['0.0.0.0:0']); } /** @@ -65,6 +126,24 @@ class ServerTest extends PHPUnit_Framework_TestCase public function testInvalidAddSecureHttp2Port() { $this->server = new Grpc\Server([]); - $this->port = $this->server->addSecureHttp2Port(['0.0.0.0:0']); + $port = $this->server->addSecureHttp2Port(['0.0.0.0:0']); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidAddSecureHttp2Port2() + { + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0'); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testInvalidAddSecureHttp2Port3() + { + $this->server = new Grpc\Server(); + $port = $this->server->addSecureHttp2Port('0.0.0.0:0', 'invalid'); } } diff --git a/src/php/tests/unit_tests/TimevalTest.php b/src/php/tests/unit_tests/TimevalTest.php old mode 100755 new mode 100644 index a3dbce079f4..2d19f64c799 --- a/src/php/tests/unit_tests/TimevalTest.php +++ b/src/php/tests/unit_tests/TimevalTest.php @@ -33,6 +33,57 @@ */ class TimevalTest extends PHPUnit_Framework_TestCase { + public function setUp() + { + } + + public function tearDown() + { + unset($this->time); + } + + public function testConstructorWithInt() + { + $this->time = new Grpc\Timeval(1234); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithNegative() + { + $this->time = new Grpc\Timeval(-123); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithZero() + { + $this->time = new Grpc\Timeval(0); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithOct() + { + $this->time = new Grpc\Timeval(0123); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithHex() + { + $this->time = new Grpc\Timeval(0x1A); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + + public function testConstructorWithFloat() + { + $this->time = new Grpc\Timeval(123.456); + $this->assertNotNull($this->time); + $this->assertSame('Grpc\Timeval', get_class($this->time)); + } + public function testCompareSame() { $zero = Grpc\Timeval::zero(); @@ -70,6 +121,7 @@ class TimevalTest extends PHPUnit_Framework_TestCase public function testNowAndAdd() { $now = Grpc\Timeval::now(); + $this->assertNotNull($now); $delta = new Grpc\Timeval(1000); $deadline = $now->add($delta); $this->assertGreaterThan(0, Grpc\Timeval::compare($deadline, $now)); @@ -154,5 +206,6 @@ class TimevalTest extends PHPUnit_Framework_TestCase public function testSimilarInvalidParam() { $a = Grpc\Timeval::similar(1000, 1100, 1200); + $this->assertNull($delta); } } diff --git a/src/proto/census/census.proto b/src/proto/census/census.proto index c869d851ff1..c2a594b6415 100644 --- a/src/proto/census/census.proto +++ b/src/proto/census/census.proto @@ -33,12 +33,12 @@ package google.census; // All the census protos. // -// Nomenclature note: capitalized names below (like Metric) are protos. +// Nomenclature note: capitalized names below (like Resource) are protos. // -// Census lets you define a Metric - something which can be measured, like the +// Census lets you define a Resource - something which can be measured, like the // latency of an RPC, the number of CPU cycles spent on an operation, or // anything else you care to measure. You can record individual instances of -// measurements (a double value) for every metric of interest. These +// measurements (a double value) for every Resource of interest. These // individual measurements are aggregated together into an Aggregation. There // are two Aggregation types available: Distribution (describes the // distribution of all measurements, possibly with a histogram) and @@ -47,8 +47,8 @@ package google.census; // // You can define how your stats are broken down by Tag values and which // Aggregations to use through a View. The corresponding combination of -// Metric/View/Aggregation which is available to census clients is called a -// ViewAggregation. +// Resource/View/Aggregation which is available to census clients is called a +// Metric. // The following two types are copied from @@ -85,26 +85,23 @@ message Timestamp { int32 nanos = 2; } -// Describes a metric -message Metric { - // name of metric, e.g. rpc_latency, cpu. +// Describes a Resource. +message Resource { + // name of resource, e.g. rpc_latency, cpu. Must be unique. string name = 1; - // More detailed description of the metric, used in documentation. + // More detailed description of the resource, used in documentation. string description = 2; // Fundamental units of measurement supported by Census // TODO(aveitch): expand this to include other S.I. units? - message BasicUnit { - enum Measure { - UNKNOWN = 0; - BITS = 1; - BYTES = 2; - SECS = 3; - CORES = 4; - MAX_UNITS = 5; - } - Measure type = 1; + enum BasicUnit { + UNKNOWN = 0; + BITS = 1; + BYTES = 2; + SECS = 3; + CORES = 4; + MAX_UNITS = 5; } // MeasurementUnit lets you build compound units of the form @@ -124,7 +121,7 @@ message Metric { // denominator: SECS // denominator: SECS // - // To specify multiples (in power of 10) units, specify a non-zero prefix + // To specify multiples (in power of 10) of units, specify a non-zero prefix // value, for example: // // - MB/s (i.e. megabytes / s): @@ -141,32 +138,40 @@ message Metric { repeated BasicUnit denominator = 3; } - // The units in which the Metric value is reported. + // The units in which Resource values are measured. MeasurementUnit unit = 3; - - // Metrics will be assigned an ID when registered. Invalid if <= 0. - int32 id = 4; } -// An Aggregation summarizes a series of individual Metric measurements, an +// An Aggregation summarizes a series of individual Resource measurements, an // AggregationDescriptor describes an Aggregation. message AggregationDescriptor { - // At most one set of options. If neither option is set, a default type - // of Distribution (without a histogram component) will be used. + enum AggregationType { + // Unspecified. Should not be used. + UNKNOWN = 0; + // A count of measurements made. + COUNT = 1; + // A Distribution. + DISTRIBUTION = 2; + // Counts over fixed time intervals. + INTERVAL = 3; + } + // The type of Aggregation. + AggregationType type = 1; + + // At most one set of options. It is illegal to specifiy an option for + // COUNT Aggregations. interval_boundaries must be set for INTERVAL types. + // bucket_boundaries are optional for DISTRIBUTION types. oneof options { - // Defines the histogram bucket boundaries for Distributions. - BucketBoundaries bucket_boundaries = 1; + // Defines histogram bucket boundaries for Distributions. + BucketBoundaries bucket_boundaries = 2; // Defines the time windows to record for IntervalStats. - IntervalBoundaries interval_boundaries = 2; + IntervalBoundaries interval_boundaries = 3; } // A Distribution may optionally contain a histogram of the values in the - // population. The bucket boundaries for that histogram is described by - // `bucket_boundaries`. - // - // Describes histogram bucket boundaries. Defines `size(bounds) + 1` (= N) - // buckets (for size(bounds) >= 1; if size(bounds) == 0, then no histogram - // will be defined. The boundaries for bucket index i are: + // population. The bucket boundaries for that histogram are described by + // `bucket_boundaries`. This defines `size(bounds) + 1` (= N) buckets. The + // boundaries for bucket index i are: // // [-infinity, bounds[i]) for i == 0 // [bounds[i-1], bounds[i]) for 0 < i < N-2 @@ -196,8 +201,8 @@ message AggregationDescriptor { // a specified set of histogram buckets, as defined in // Aggregation.bucket_options. // -// The summary statistics are the count, mean, sum of the squared deviation from -// the mean, the minimum, and the maximum of the set of population of values. +// The summary statistics are the count, mean, minimum, and the maximum of the +// set of population of values. // // Although it is not forbidden, it is generally a bad idea to include // non-finite values (infinities or NaNs) in the population of values, as this @@ -243,7 +248,7 @@ message Distribution { message IntervalStats { // Summary statistic over a single time window. message Window { - // The window duration. + // The window duration. Must be positive. Duration window_size = 1; // The number of measurements in this window. int64 count = 2; @@ -251,7 +256,7 @@ message IntervalStats { double mean = 3; } - // Full set of windows for this metric. + // Full set of windows for this aggregation. repeated Window window = 1; } @@ -264,24 +269,24 @@ message Tag { // A View specifies an Aggregation and a set of tag keys. The Aggregation will // be broken down by the unique set of matching tag values for each measurement. message View { - // Name of view. + // Name of view. Must be unique. string name = 1; // More detailed description, for documentation purposes. string description = 2; - // ID of Metric to associate with this View. - int32 metric_id = 3; + // Name of Resource to be broken down for this view. + string resource_name = 3; // Aggregation type to associate with this View. AggregationDescriptor aggregation = 4; - // Tag keys to match with a given Metric. If no keys are specified, then all - // stats for the Metric are recorded. Keys must be unique. + // Tag keys to match with a given Resource measurement. If no keys are + // specified, then all stats are recorded. Keys must be unique. repeated string tag_key = 5; } -// An Aggregation summarizes a series of individual Metric measures. +// An Aggregation summarizes a series of individual Resource measurements. message Aggregation { // Name of this aggregation. string name = 1; @@ -291,23 +296,27 @@ message Aggregation { // The data for this Aggregation. oneof data { - Distribution distribution = 3; - IntervalStats interval_stats = 4; + uint64 count = 3; + Distribution distribution = 4; + IntervalStats interval_stats = 5; } // Tags associated with this Aggregation. - repeated Tag tag = 5; + repeated Tag tag = 6; } -// A ViewAggregations represents all the Aggregations for a particular view. -message ViewAggregations { +// A Metric represents all the Aggregations for a particular view. +message Metric { + // View associated with this Metric. + string view_name = 1; + // Aggregations - each will have a unique set of tag values for the tag_keys // associated with the corresponding View. - repeated Aggregation aggregation = 1; + repeated Aggregation aggregation = 2; - // Start and end timestamps over which the value was accumulated. These + // Start and end timestamps over which the metric was accumulated. These // values are not relevant/defined for IntervalStats aggregations, which are // always accumulated over a fixed time period. - Timestamp start = 2; - Timestamp end = 3; + Timestamp start = 3; + Timestamp end = 4; } diff --git a/src/proto/census/trace_context.options b/src/proto/census/trace_context.options new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/objective-c/examples/RemoteTestClient/empty.proto b/src/proto/census/trace_context.proto similarity index 77% rename from src/objective-c/examples/RemoteTestClient/empty.proto rename to src/proto/census/trace_context.proto index a678048289e..a5d5a9595db 100644 --- a/src/objective-c/examples/RemoteTestClient/empty.proto +++ b/src/proto/census/trace_context.proto @@ -1,4 +1,4 @@ -// Copyright 2015, Google Inc. +// Copyright 2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -29,16 +29,20 @@ syntax = "proto3"; -package grpc.testing; +package google.trace; -option objc_class_prefix = "RMT"; +// A TraceId uniquely represents a single Trace. It is a 128-bit nonce. +message TraceId { + fixed64 hi = 1; + fixed64 lo = 2; +} -// An empty message that you can re-use to avoid defining duplicated empty -// messages in your project. A typical example is to use it as argument or the -// return value of a service API. For instance: -// -// service Foo { -// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { }; -// }; -// -message Empty {} +// Tracing information that is propagated with RPC's. +message TraceContext { + // Trace identifer. Must be present. + TraceId trace_id = 1; + // ID of parent (client) span. Must be present. + fixed64 span_id = 2; + // true if this trace is sampled. + bool is_sampled = 3; +} diff --git a/src/python/grpcio/.gitignore b/src/python/grpcio/.gitignore index 7cd8fab2735..3309795948c 100644 --- a/src/python/grpcio/.gitignore +++ b/src/python/grpcio/.gitignore @@ -14,3 +14,4 @@ doc/ _grpcio_metadata.py htmlcov/ grpc/_cython/_credentials +poison.c diff --git a/src/python/grpcio/_unixccompiler_patch.py b/src/python/grpcio/_spawn_patch.py similarity index 55% rename from src/python/grpcio/_unixccompiler_patch.py rename to src/python/grpcio/_spawn_patch.py index 0ce5d63e981..24306f0dd95 100644 --- a/src/python/grpcio/_unixccompiler_patch.py +++ b/src/python/grpcio/_spawn_patch.py @@ -27,47 +27,47 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Covers inadequacies in distutils.""" +"""Patches the spawn() command for windows compilers. + +Windows has an 8191 character command line limit, but some compilers +support an @command_file directive where command_file is a file +containing the full command line. +""" from distutils import ccompiler -from distutils import errors -from distutils import unixccompiler import os import os.path import shutil import sys import tempfile -def _unix_commandfile_spawn(self, command): - """Wrapper around distutils.util.spawn that attempts to use command files. +MAX_COMMAND_LENGTH = 8191 - Meant to replace the CCompiler method `spawn` on UnixCCompiler and its - derivatives (e.g. the MinGW32 compiler). +_classic_spawn = ccompiler.CCompiler.spawn - Some commands like `gcc` (and friends like `clang`) support command files to - work around shell command length limits. - """ - command_base = os.path.basename(command[0].strip()) - if command_base == 'ccache': - command_base = command[:2] - command_args = command[2:] - elif command_base.startswith('ccache') or command_base in ['gcc', 'clang', 'clang++', 'g++']: - command_base = command[:1] - command_args = command[1:] +def _commandfile_spawn(self, command): + command_length = sum([len(arg) for arg in command]) + if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH: + # Even if this command doesn't support the @command_file, it will + # fail as is so we try blindly + print('Command line length exceeded, using command file') + print(' '.join(command)) + temporary_directory = tempfile.mkdtemp() + command_filename = os.path.abspath( + os.path.join(temporary_directory, 'command')) + with open(command_filename, 'w') as command_file: + escaped_args = ['"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]] + command_file.write(' '.join(escaped_args)) + modified_command = command[:1] + ['@{}'.format(command_filename)] + try: + _classic_spawn(self, modified_command) + finally: + shutil.rmtree(temporary_directory) else: - return ccompiler.CCompiler.spawn(self, command) - temporary_directory = tempfile.mkdtemp() - command_filename = os.path.abspath(os.path.join(temporary_directory, 'command')) - with open(command_filename, 'w') as command_file: - escaped_args = [arg.replace('\\', '\\\\') for arg in command_args] - command_file.write(' '.join(escaped_args)) - modified_command = command_base + ['@{}'.format(command_filename)] - result = ccompiler.CCompiler.spawn(self, modified_command) - shutil.rmtree(temporary_directory) - return result + _classic_spawn(self, command) -def monkeypatch_unix_compiler(): +def monkeypatch_spawn(): """Monkeypatching is dumb, but it's either that or we become maintainers of something much, much bigger.""" - unixccompiler.UnixCCompiler.spawn = _unix_commandfile_spawn + ccompiler.CCompiler.spawn = _commandfile_spawn diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py index 86a73fa8360..d36ac233050 100644 --- a/src/python/grpcio/commands.py +++ b/src/python/grpcio/commands.py @@ -184,6 +184,71 @@ class BuildPy(build_py.build_py): build_py.build_py.run(self) +def _poison_extensions(extensions, message): + """Includes a file that will always fail to compile in all extensions.""" + poison_filename = os.path.join(PYTHON_STEM, 'poison.c') + with open(poison_filename, 'w') as poison: + poison.write('#error {}'.format(message)) + for extension in extensions: + extension.sources = [poison_filename] + +def check_and_update_cythonization(extensions): + """Replace .pyx files with their generated counterparts and return whether or + not cythonization still needs to occur.""" + for extension in extensions: + generated_pyx_sources = [] + other_sources = [] + for source in extension.sources: + base, file_ext = os.path.splitext(source) + if file_ext == '.pyx': + generated_pyx_source = next( + (base + gen_ext for gen_ext in ('.c', '.cpp',) + if os.path.isfile(base + gen_ext)), None) + if generated_pyx_source: + generated_pyx_sources.append(generated_pyx_source) + else: + sys.stderr.write('Cython-generated files are missing...\n') + return False + else: + other_sources.append(source) + extension.sources = generated_pyx_sources + other_sources + sys.stderr.write('Found cython-generated files...\n') + return True + +def try_cythonize(extensions, linetracing=False, mandatory=True): + """Attempt to cythonize the extensions. + + Args: + extensions: A list of `distutils.extension.Extension`. + linetracing: A bool indicating whether or not to enable linetracing. + mandatory: Whether or not having Cython-generated files is mandatory. If it + is, extensions will be poisoned when they can't be fully generated. + """ + try: + # Break import style to ensure we have access to Cython post-setup_requires + import Cython.Build + except ImportError: + if mandatory: + sys.stderr.write( + "This package needs to generate C files with Cython but it cannot. " + "Poisoning extension sources to disallow extension commands...") + _poison_extensions( + extensions, + "Extensions have been poisoned due to missing Cython-generated code.") + return extensions + cython_compiler_directives = {} + if linetracing: + additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')] + cython_compiler_directives['linetrace'] = True + return Cython.Build.cythonize( + extensions, + include_path=[ + include_dir for extension in extensions for include_dir in extension.include_dirs + ], + compiler_directives=cython_compiler_directives + ) + + class BuildExt(build_ext.build_ext): """Custom build_ext command to enable compiler-specific flags.""" @@ -201,6 +266,8 @@ class BuildExt(build_ext.build_ext): if compiler in BuildExt.LINK_OPTIONS: for extension in self.extensions: extension.extra_link_args += list(BuildExt.LINK_OPTIONS[compiler]) + if not check_and_update_cythonization(self.extensions): + self.extensions = try_cythonize(self.extensions) try: build_ext.build_ext.build_extensions(self) except Exception as error: diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index fd015129f02..513839df7d9 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -345,7 +345,7 @@ class Call(six.with_metaclass(abc.ABCMeta, RpcContext)): This method blocks until the value is available. Returns: - The bytes of the details of the RPC. + The details string of the RPC. """ raise NotImplementedError() @@ -764,7 +764,7 @@ class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)): details to transmit. Args: - details: The details bytes of the RPC to be transmitted to + details: The details string of the RPC to be transmitted to the invocation side of the RPC. """ raise NotImplementedError() diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py index 29dbc3a668b..3117dd1cb31 100644 --- a/src/python/grpcio/grpc/_channel.py +++ b/src/python/grpcio/grpc/_channel.py @@ -353,12 +353,12 @@ class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call): else: return max(self._deadline - time.time(), 0) - def add_cancellation_callback(self, callback): + def add_callback(self, callback): with self._state.condition: if self._state.callbacks is None: return False else: - self._state.callbacks.append(lambda unused_future: callback()) + self._state.callbacks.append(lambda: callback()) return True def initial_metadata(self): diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi index ba60986143c..cc3bd7a0672 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi @@ -34,6 +34,7 @@ cdef class Call: def __cinit__(self): # Create an *empty* call + grpc_init() self.c_call = NULL self.references = [] @@ -106,6 +107,7 @@ cdef class Call: def __dealloc__(self): if self.c_call != NULL: grpc_call_destroy(self.c_call) + grpc_shutdown() # The object *should* always be valid from Python. Used for debugging. @property diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi index 54164014313..3df937eb14f 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi @@ -34,6 +34,7 @@ cdef class Channel: def __cinit__(self, bytes target, ChannelArgs arguments=None, ChannelCredentials channel_credentials=None): + grpc_init() cdef grpc_channel_args *c_arguments = NULL cdef char *c_target = NULL self.c_channel = NULL @@ -103,3 +104,4 @@ cdef class Channel: def __dealloc__(self): if self.c_channel != NULL: grpc_channel_destroy(self.c_channel) + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi index 5955021ceb7..a258ba40639 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi @@ -38,6 +38,7 @@ cdef int _INTERRUPT_CHECK_PERIOD_MS = 200 cdef class CompletionQueue: def __cinit__(self): + grpc_init() with nogil: self.c_completion_queue = grpc_completion_queue_create(NULL) self.is_shutting_down = False @@ -129,3 +130,4 @@ cdef class CompletionQueue: self.c_completion_queue, c_deadline, NULL) self._interpret_event(event) grpc_completion_queue_destroy(self.c_completion_queue) + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 035ac49a8bf..04872b9c09a 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -33,6 +33,7 @@ cimport cpython cdef class ChannelCredentials: def __cinit__(self): + grpc_init() self.c_credentials = NULL self.c_ssl_pem_key_cert_pair.private_key = NULL self.c_ssl_pem_key_cert_pair.certificate_chain = NULL @@ -47,11 +48,13 @@ cdef class ChannelCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_channel_credentials_release(self.c_credentials) + grpc_shutdown() cdef class CallCredentials: def __cinit__(self): + grpc_init() self.c_credentials = NULL self.references = [] @@ -64,17 +67,20 @@ cdef class CallCredentials: def __dealloc__(self): if self.c_credentials != NULL: grpc_call_credentials_release(self.c_credentials) + grpc_shutdown() cdef class ServerCredentials: def __cinit__(self): + grpc_init() self.c_credentials = NULL self.references = [] def __dealloc__(self): if self.c_credentials != NULL: grpc_server_credentials_release(self.c_credentials) + grpc_shutdown() cdef class CredentialsMetadataPlugin: @@ -90,6 +96,7 @@ cdef class CredentialsMetadataPlugin: successful). name (bytes): Plugin name. """ + grpc_init() if not callable(plugin_callback): raise ValueError('expected callable plugin_callback') self.plugin_callback = plugin_callback @@ -105,10 +112,14 @@ cdef class CredentialsMetadataPlugin: cpython.Py_INCREF(self) return result + def __dealloc__(self): + grpc_shutdown() + cdef class AuthMetadataContext: def __cinit__(self): + grpc_init() self.context.service_url = NULL self.context.method_name = NULL @@ -120,6 +131,9 @@ cdef class AuthMetadataContext: def method_name(self): return self.context.method_name + def __dealloc__(self): + grpc_shutdown() + cdef void plugin_get_metadata( void *state, grpc_auth_metadata_context context, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index 7714504d1bb..42fced65457 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -30,19 +30,29 @@ cimport libc.time -cdef extern from "grpc/_cython/loader.h": +# Typedef types with approximately the same semantics to provide their names to +# Cython +ctypedef int int32_t +ctypedef unsigned uint32_t +ctypedef long int64_t - ctypedef int int32_t - ctypedef unsigned uint32_t - ctypedef long int64_t - int pygrpc_load_core(char*) - int pygrpc_initialize_core() +cdef extern from "grpc/support/alloc.h": void *gpr_malloc(size_t size) nogil void gpr_free(void *ptr) nogil void *gpr_realloc(void *p, size_t size) nogil + +cdef extern from "grpc/byte_buffer_reader.h": + + struct grpc_byte_buffer_reader: + # We don't care about the internals + pass + + +cdef extern from "grpc/grpc.h": + ctypedef struct gpr_slice: # don't worry about writing out the members of gpr_slice; we never access # them directly. @@ -86,7 +96,22 @@ cdef extern from "grpc/_cython/loader.h": gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b) nogil int gpr_time_cmp(gpr_timespec a, gpr_timespec b) nogil - + + ctypedef struct grpc_byte_buffer: + # We don't care about the internals. + pass + + grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, + size_t nslices) nogil + size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) nogil + void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer) nogil + + int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, + grpc_byte_buffer *buffer) nogil + int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, + gpr_slice *slice) nogil + void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) nogil + ctypedef enum grpc_status_code: GRPC_STATUS_OK GRPC_STATUS_CANCELLED @@ -107,37 +132,6 @@ cdef extern from "grpc/_cython/loader.h": GRPC_STATUS_DATA_LOSS GRPC_STATUS__DO_NOT_USE - ctypedef enum grpc_ssl_roots_override_result: - GRPC_SSL_ROOTS_OVERRIDE_OK - GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY - GRPC_SSL_ROOTS_OVERRIDE_FAILED - - ctypedef enum grpc_ssl_client_certificate_request_type: - GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, - GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY - GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY - GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY - GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY - - struct grpc_byte_buffer_reader: - # We don't care about the internals - pass - - ctypedef struct grpc_byte_buffer: - # We don't care about the internals. - pass - - grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices, - size_t nslices) nogil - size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) nogil - void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer) nogil - - int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader, - grpc_byte_buffer *buffer) nogil - int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader, - gpr_slice *slice) nogil - void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) nogil - const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING const char *GRPC_ARG_ENABLE_CENSUS const char *GRPC_ARG_MAX_CONCURRENT_STREAMS @@ -353,6 +347,21 @@ cdef extern from "grpc/_cython/loader.h": void grpc_server_cancel_all_calls(grpc_server *server) nogil void grpc_server_destroy(grpc_server *server) nogil + +cdef extern from "grpc/grpc_security.h": + + ctypedef enum grpc_ssl_roots_override_result: + GRPC_SSL_ROOTS_OVERRIDE_OK + GRPC_SSL_ROOTS_OVERRIDE_FAILED_PERMANENTLY + GRPC_SSL_ROOTS_OVERRIDE_FAILED + + ctypedef enum grpc_ssl_client_certificate_request_type: + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_BUT_DONT_VERIFY + GRPC_SSL_REQUEST_CLIENT_CERTIFICATE_AND_VERIFY + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + ctypedef struct grpc_ssl_pem_key_cert_pair: const char *private_key const char *certificate_chain "cert_chain" @@ -438,6 +447,9 @@ cdef extern from "grpc/_cython/loader.h": grpc_call_credentials *grpc_metadata_credentials_create_from_plugin( grpc_metadata_credentials_plugin plugin, void *reserved) nogil + +cdef extern from "grpc/compression.h": + ctypedef enum grpc_compression_algorithm: GRPC_COMPRESS_NONE GRPC_COMPRESS_DEFLATE @@ -472,3 +484,4 @@ cdef extern from "grpc/_cython/loader.h": int grpc_compression_options_is_algorithm_enabled( const grpc_compression_options *opts, grpc_compression_algorithm algorithm) nogil + diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi index 54b3d00dfc7..834a44123d4 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi @@ -176,12 +176,14 @@ cdef class Timespec: cdef class CallDetails: def __cinit__(self): + grpc_init() with nogil: grpc_call_details_init(&self.c_details) def __dealloc__(self): with nogil: grpc_call_details_destroy(&self.c_details) + grpc_shutdown() @property def method(self): @@ -232,6 +234,7 @@ cdef class Event: cdef class ByteBuffer: def __cinit__(self, bytes data): + grpc_init() if data is None: self.c_byte_buffer = NULL return @@ -288,6 +291,7 @@ cdef class ByteBuffer: def __dealloc__(self): if self.c_byte_buffer != NULL: grpc_byte_buffer_destroy(self.c_byte_buffer) + grpc_shutdown() cdef class SslPemKeyCertPair: @@ -319,6 +323,7 @@ cdef class ChannelArg: cdef class ChannelArgs: def __cinit__(self, args): + grpc_init() self.args = list(args) for arg in self.args: if not isinstance(arg, ChannelArg): @@ -333,6 +338,7 @@ cdef class ChannelArgs: def __dealloc__(self): with nogil: gpr_free(self.c_args.arguments) + grpc_shutdown() def __len__(self): # self.args is never stale; it's only updated from this file @@ -399,6 +405,7 @@ cdef class _MetadataIterator: cdef class Metadata: def __cinit__(self, metadata): + grpc_init() self.metadata = list(metadata) for metadatum in metadata: if not isinstance(metadatum, Metadatum): @@ -420,6 +427,7 @@ cdef class Metadata: # it'd be nice if that were documented somewhere...) # TODO(atash): document this in the C core grpc_metadata_array_destroy(&self.c_metadata_array) + grpc_shutdown() def __len__(self): return self.c_metadata_array.count @@ -437,6 +445,7 @@ cdef class Metadata: cdef class Operation: def __cinit__(self): + grpc_init() self.references = [] self._received_status_details = NULL self._received_status_details_capacity = 0 @@ -529,6 +538,7 @@ cdef class Operation: # This means that we need to clean up after receive_status_on_client. if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT: gpr_free(self._received_status_details) + grpc_shutdown() def operation_send_initial_metadata(Metadata metadata, int flags): cdef Operation op = Operation() @@ -645,6 +655,7 @@ cdef class _OperationsIterator: cdef class Operations: def __cinit__(self, operations): + grpc_init() self.operations = list(operations) # normalize iterable self.c_ops = NULL self.c_nops = 0 @@ -667,6 +678,7 @@ cdef class Operations: def __dealloc__(self): with nogil: gpr_free(self.c_ops) + grpc_shutdown() def __iter__(self): return _OperationsIterator(self) diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index 4f2d51b03f5..ca2b8311147 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -35,6 +35,7 @@ import time cdef class Server: def __cinit__(self, ChannelArgs arguments=None): + grpc_init() cdef grpc_channel_args *c_arguments = NULL self.references = [] self.registered_completion_queues = [] @@ -172,3 +173,4 @@ cdef class Server: while not self.is_shutdown: time.sleep(0) grpc_server_destroy(self.c_server) + grpc_shutdown() diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx index e055d321bc7..08089994a95 100644 --- a/src/python/grpcio/grpc/_cython/cygrpc.pyx +++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx @@ -49,11 +49,14 @@ include "grpc/_cython/_cygrpc/server.pyx.pxi" # -def _initialize(): - if not pygrpc_initialize_core(): - raise ImportError('failed to initialize core gRPC library') +cdef extern from "Python.h": + + int Py_AtExit(void(*func)()) + +def _initialize(): grpc_set_ssl_roots_override_callback( ssl_roots_override_callback) + _initialize() diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py index 73415e0be7f..e4ee44d7a3e 100644 --- a/src/python/grpcio/grpc/beta/_client_adaptations.py +++ b/src/python/grpcio/grpc/beta/_client_adaptations.py @@ -67,7 +67,7 @@ def _abortion(rpc_error_call): error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0] return face.Abortion( error_kind, rpc_error_call.initial_metadata(), - rpc_error_call.trailing_metadata(), code, rpc_error_code.details()) + rpc_error_call.trailing_metadata(), code, rpc_error_call.details()) def _abortion_error(rpc_error_call): @@ -159,9 +159,11 @@ class _Rendezvous(future.Future, face.Call): return self._call.time_remaining() def add_abortion_callback(self, abortion_callback): - registered = self._call.add_callback( - lambda: abortion_callback(_abortion(self._call))) - return None if registered else _abortion(self._call) + def done_callback(): + if self.code() is not grpc.StatusCode.OK: + abortion_callback(_abortion(self._call)) + registered = self._call.add_callback(done_callback) + return None if registered else done_callback() def protocol_context(self): return _InvocationProtocolContext() diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index b37e27c27ea..be7f30c29b3 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -51,6 +51,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/support/log_posix.c', 'src/core/lib/support/log_windows.c', 'src/core/lib/support/murmur_hash.c', + 'src/core/lib/support/percent_encoding.c', 'src/core/lib/support/slice.c', 'src/core/lib/support/slice_buffer.c', 'src/core/lib/support/stack_lockfree.c', @@ -81,6 +82,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/channel/channel_stack_builder.c', 'src/core/lib/channel/compress_filter.c', 'src/core/lib/channel/connected_channel.c', + 'src/core/lib/channel/handshaker.c', 'src/core/lib/channel/http_client_filter.c', 'src/core/lib/channel/http_server_filter.c', 'src/core/lib/compression/compression.c', @@ -161,6 +163,7 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', 'src/core/lib/transport/static_metadata.c', + 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', 'src/core/lib/transport/transport_op_string.c', 'src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c', @@ -183,7 +186,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/transport/chttp2/transport/status_conversion.c', 'src/core/ext/transport/chttp2/transport/stream_lists.c', 'src/core/ext/transport/chttp2/transport/stream_map.c', - 'src/core/ext/transport/chttp2/transport/timeout_encoding.c', 'src/core/ext/transport/chttp2/transport/varint.c', 'src/core/ext/transport/chttp2/transport/writing.c', 'src/core/ext/transport/chttp2/alpn/alpn.c', @@ -219,7 +221,6 @@ CORE_SOURCE_FILES = [ 'src/core/ext/client_config/channel_connectivity.c', 'src/core/ext/client_config/client_channel.c', 'src/core/ext/client_config/client_channel_factory.c', - 'src/core/ext/client_config/client_config.c', 'src/core/ext/client_config/client_config_plugin.c', 'src/core/ext/client_config/connector.c', 'src/core/ext/client_config/default_initial_connect_string.c', @@ -231,14 +232,15 @@ CORE_SOURCE_FILES = [ 'src/core/ext/client_config/resolver.c', 'src/core/ext/client_config/resolver_factory.c', 'src/core/ext/client_config/resolver_registry.c', + 'src/core/ext/client_config/resolver_result.c', 'src/core/ext/client_config/subchannel.c', - 'src/core/ext/client_config/subchannel_call_holder.c', 'src/core/ext/client_config/subchannel_index.c', 'src/core/ext/client_config/uri_parser.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c', 'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create.c', 'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c', + 'src/core/ext/lb_policy/grpclb/grpclb.c', 'src/core/ext/lb_policy/grpclb/load_balancer_api.c', 'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c', 'third_party/nanopb/pb_common.c', @@ -250,8 +252,10 @@ CORE_SOURCE_FILES = [ 'src/core/ext/resolver/sockaddr/sockaddr_resolver.c', 'src/core/ext/load_reporting/load_reporting.c', 'src/core/ext/load_reporting/load_reporting_filter.c', + 'src/core/ext/census/base_resources.c', 'src/core/ext/census/context.c', 'src/core/ext/census/gen/census.pb.c', + 'src/core/ext/census/gen/trace_context.pb.c', 'src/core/ext/census/grpc_context.c', 'src/core/ext/census/grpc_filter.c', 'src/core/ext/census/grpc_plugin.c', @@ -259,6 +263,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/census/mlog.c', 'src/core/ext/census/operation.c', 'src/core/ext/census/placeholders.c', + 'src/core/ext/census/resource.c', 'src/core/ext/census/tracing.c', 'src/core/plugin_registry/grpc_plugin_registry.c', 'src/boringssl/err_data.c', diff --git a/src/python/grpcio_health_checking/MANIFEST.in b/src/python/grpcio_health_checking/MANIFEST.in index 7d26647697e..7407f646d16 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 include health_commands.py -graft grpc_health +graft grpc global-exclude *.pyc diff --git a/src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py b/src/python/grpcio_health_checking/grpc/__init__.py similarity index 96% rename from src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py rename to src/python/grpcio_health_checking/grpc/__init__.py index 70865191060..fcc7048815f 100644 --- a/src/python/grpcio_health_checking/grpc_health/health/v1/__init__.py +++ b/src/python/grpcio_health_checking/grpc/__init__.py @@ -27,4 +27,4 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +__import__('pkg_resources').declare_namespace(__name__) diff --git a/src/python/grpcio_health_checking/grpc_health/__init__.py b/src/python/grpcio_health_checking/grpc/health/__init__.py similarity index 100% rename from src/python/grpcio_health_checking/grpc_health/__init__.py rename to src/python/grpcio_health_checking/grpc/health/__init__.py diff --git a/src/python/grpcio_health_checking/grpc_health/health/__init__.py b/src/python/grpcio_health_checking/grpc/health/v1/__init__.py similarity index 100% rename from src/python/grpcio_health_checking/grpc_health/health/__init__.py rename to src/python/grpcio_health_checking/grpc/health/v1/__init__.py diff --git a/src/python/grpcio_health_checking/grpc_health/health/v1/health.py b/src/python/grpcio_health_checking/grpc/health/v1/health.py similarity index 81% rename from src/python/grpcio_health_checking/grpc_health/health/v1/health.py rename to src/python/grpcio_health_checking/grpc/health/v1/health.py index 8da60c70cb1..8108ac10962 100644 --- a/src/python/grpcio_health_checking/grpc_health/health/v1/health.py +++ b/src/python/grpcio_health_checking/grpc/health/v1/health.py @@ -31,10 +31,12 @@ import threading -from grpc_health.health.v1 import health_pb2 +import grpc +from grpc.health.v1 import health_pb2 -class HealthServicer(health_pb2.BetaHealthServicer): + +class HealthServicer(health_pb2.HealthServicer): """Servicer handling RPCs for service statuses.""" def __init__(self): @@ -43,14 +45,12 @@ class HealthServicer(health_pb2.BetaHealthServicer): def Check(self, request, context): with self._server_status_lock: - if request.service not in self._server_status: - # TODO(atash): once the Python API has a way of setting the server - # status, bring us into conformance with the health check spec by - # returning the NOT_FOUND status here. - raise NotImplementedError() + status = self._server_status.get(request.service) + if status is None: + context.set_code(grpc.StatusCode.NOT_FOUND) + return health_pb2.HealthCheckResponse() else: - return health_pb2.HealthCheckResponse( - status=self._server_status[request.service]) + return health_pb2.HealthCheckResponse(status=status) def set(self, service, status): """Sets the status of a service. @@ -63,4 +63,3 @@ class HealthServicer(health_pb2.BetaHealthServicer): """ with self._server_status_lock: self._server_status[service] = status - diff --git a/examples/python/helloworld/run_codegen.sh b/src/python/grpcio_health_checking/grpc_version.py old mode 100755 new mode 100644 similarity index 86% rename from examples/python/helloworld/run_codegen.sh rename to src/python/grpcio_health_checking/grpc_version.py index 34224e5c418..be0d0ced3cb --- a/examples/python/helloworld/run_codegen.sh +++ b/src/python/grpcio_health_checking/grpc_version.py @@ -1,5 +1,4 @@ -#!/bin/bash -# Copyright 2015, Google Inc. +# Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,5 +27,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# Runs the protoc with gRPC plugin to generate protocol messages and gRPC stubs. -python -m grpc.tools.protoc -I../../protos --python_out=. --grpc_python_out=. ../../protos/helloworld.proto +# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! + +VERSION='1.1.0.dev0' diff --git a/src/python/grpcio_health_checking/health_commands.py b/src/python/grpcio_health_checking/health_commands.py index a7a59f6974b..66df25da63f 100644 --- a/src/python/grpcio_health_checking/health_commands.py +++ b/src/python/grpcio_health_checking/health_commands.py @@ -29,16 +29,10 @@ """Provides distutils command classes for the GRPC Python setup process.""" -import distutils -import glob import os -import os.path import shutil -import subprocess -import sys import setuptools -from setuptools.command import build_py 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') @@ -60,12 +54,25 @@ class CopyProtoModules(setuptools.Command): if os.path.isfile(HEALTH_PROTO): shutil.copyfile( HEALTH_PROTO, - os.path.join(ROOT_DIR, 'grpc_health/health/v1/health.proto')) + os.path.join(ROOT_DIR, 'grpc/health/v1/health.proto')) -class BuildPy(build_py.build_py): - """Custom project build command.""" +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): - self.run_command('build_proto_modules') - build_py.build_py.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_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 70b4575bf5d..8c92ee16a93 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -30,49 +30,43 @@ """Setup module for the GRPC Python package's optional health checking.""" import os -import os.path import sys -from distutils import core as _core import setuptools -import grpc.tools.command - # 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 commands module. import health_commands - -PACKAGES = ( - setuptools.find_packages('.') -) +import grpc_version PACKAGE_DIRECTORIES = { '': '.', } SETUP_REQUIRES = ( - 'grpcio-tools>=0.14.0', + 'grpcio-tools>={version}'.format(version=grpc_version.VERSION), ) INSTALL_REQUIRES = ( - 'grpcio>=0.13.1', + 'protobuf>=3.0.0', + 'grpcio>={version}'.format(version=grpc_version.VERSION), ) COMMAND_CLASS = { # Run preprocess from the repository *before* doing any packaging! 'preprocess': health_commands.CopyProtoModules, - - 'build_proto_modules': grpc.tools.command.BuildProtoModules, - 'build_py': health_commands.BuildPy, + 'build_package_protos': health_commands.BuildPackageProtos, } setuptools.setup( name='grpcio-health-checking', - version='0.14.0', - packages=list(PACKAGES), + version=grpc_version.VERSION, + license='3-clause BSD', package_dir=PACKAGE_DIRECTORIES, + packages=setuptools.find_packages('.'), + namespace_packages=['grpc'], install_requires=INSTALL_REQUIRES, setup_requires=SETUP_REQUIRES, cmdclass=COMMAND_CLASS diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py index 171829b62fc..5ee551cfe1e 100644 --- a/src/python/grpcio_tests/commands.py +++ b/src/python/grpcio_tests/commands.py @@ -138,7 +138,7 @@ class BuildPy(build_py.build_py): def run(self): try: - self.run_command('build_proto_modules') + self.run_command('build_package_protos') except CommandError as error: sys.stderr.write('warning: %s\n' % error.message) build_py.build_py.run(self) diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py index 7eef420bdb0..73842066020 100644 --- a/src/python/grpcio_tests/setup.py +++ b/src/python/grpcio_tests/setup.py @@ -31,13 +31,9 @@ import os import os.path -import shutil import sys -from distutils import core as _core -from distutils import extension as _extension import setuptools -from setuptools.command import egg_info import grpc.tools.command @@ -60,22 +56,19 @@ INSTALL_REQUIRES = ( 'coverage>=4.0', 'enum34>=1.0.4', 'futures>=2.2.0', - 'grpcio>=0.14.0', - 'grpcio-health-checking>=0.14.0', + 'grpcio>={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.0.0a3', + 'protobuf>=3.0.0', 'six>=1.10', ) -SETUP_REQUIRES = ( - 'grpcio-tools>=0.14.0', -) - COMMAND_CLASS = { # Run `preprocess` *before* doing any packaging! 'preprocess': commands.GatherProto, - 'build_proto_modules': grpc.tools.command.BuildProtoModules, + 'build_package_protos': grpc.tools.command.BuildPackageProtos, 'build_py': commands.BuildPy, 'run_interop': commands.RunInterop, 'test_lite': commands.TestLite @@ -115,7 +108,6 @@ setuptools.setup( package_dir=PACKAGE_DIRECTORIES, package_data=PACKAGE_DATA, install_requires=INSTALL_REQUIRES, - setup_requires=SETUP_REQUIRES, cmdclass=COMMAND_CLASS, tests_require=TESTS_REQUIRE, test_suite=TEST_SUITE, diff --git a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py index 1b633886635..80300d13df7 100644 --- a/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py +++ b/src/python/grpcio_tests/tests/health_check/_health_servicer_test.py @@ -27,48 +27,68 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -"""Tests of grpc_health.health.v1.health.""" +"""Tests of grpc.health.v1.health.""" import unittest -from grpc_health.health.v1 import health -from grpc_health.health.v1 import health_pb2 +import grpc +from grpc.framework.foundation import logging_pool +from grpc.health.v1 import health +from grpc.health.v1 import health_pb2 + +from tests.unit.framework.common import test_constants class HealthServicerTest(unittest.TestCase): def setUp(self): - self.servicer = health.HealthServicer() - self.servicer.set('', health_pb2.HealthCheckResponse.SERVING) - self.servicer.set('grpc.test.TestServiceServing', - health_pb2.HealthCheckResponse.SERVING) - self.servicer.set('grpc.test.TestServiceUnknown', - health_pb2.HealthCheckResponse.UNKNOWN) - self.servicer.set('grpc.test.TestServiceNotServing', - health_pb2.HealthCheckResponse.NOT_SERVING) + servicer = health.HealthServicer() + servicer.set('', health_pb2.HealthCheckResponse.SERVING) + servicer.set('grpc.test.TestServiceServing', + health_pb2.HealthCheckResponse.SERVING) + servicer.set('grpc.test.TestServiceUnknown', + health_pb2.HealthCheckResponse.UNKNOWN) + servicer.set('grpc.test.TestServiceNotServing', + health_pb2.HealthCheckResponse.NOT_SERVING) + server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY) + self._server = grpc.server(server_pool) + port = self._server.add_insecure_port('[::]:0') + health_pb2.add_HealthServicer_to_server(servicer, self._server) + self._server.start() + + channel = grpc.insecure_channel('localhost:%d' % port) + self._stub = health_pb2.HealthStub(channel) def test_empty_service(self): request = health_pb2.HealthCheckRequest() - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) def test_serving_service(self): request = health_pb2.HealthCheckRequest( service='grpc.test.TestServiceServing') - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.SERVING) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.SERVING, resp.status) def test_unknown_serivce(self): request = health_pb2.HealthCheckRequest( service='grpc.test.TestServiceUnknown') - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.UNKNOWN) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.UNKNOWN, resp.status) def test_not_serving_service(self): request = health_pb2.HealthCheckRequest( service='grpc.test.TestServiceNotServing') - resp = self.servicer.Check(request, None) - self.assertEqual(resp.status, health_pb2.HealthCheckResponse.NOT_SERVING) + resp = self._stub.Check(request) + self.assertEqual(health_pb2.HealthCheckResponse.NOT_SERVING, resp.status) + + def test_not_found_service(self): + request = health_pb2.HealthCheckRequest( + service='not-found') + with self.assertRaises(grpc.RpcError) as context: + resp = self._stub.Check(request) + + self.assertEqual(grpc.StatusCode.NOT_FOUND, context.exception.code()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py index c753d6faf05..936c895bd2e 100644 --- a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py +++ b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py @@ -29,9 +29,10 @@ """Insecure client-server interoperability as a unit test.""" +from concurrent import futures import unittest -from grpc.beta import implementations +import grpc from src.proto.grpc.testing import test_pb2 from tests.interop import _interop_test_case @@ -44,14 +45,13 @@ class InsecureInteropTest( unittest.TestCase): def setUp(self): - self.server = test_pb2.beta_create_TestService_server(methods.TestService()) + self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + test_pb2.add_TestServiceServicer_to_server( + methods.TestService(), self.server) port = self.server.add_insecure_port('[::]:0') self.server.start() - self.stub = test_pb2.beta_create_TestService_stub( - implementations.insecure_channel('localhost', port)) - - def tearDown(self): - self.server.stop(0) + self.stub = test_pb2.TestServiceStub( + grpc.insecure_channel('localhost:{}'.format(port))) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py index cb09f54a347..eaca553e1b8 100644 --- a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py +++ b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py @@ -29,17 +29,16 @@ """Secure client-server interoperability as a unit test.""" +from concurrent import futures import unittest -from grpc.beta import implementations +import grpc from src.proto.grpc.testing import test_pb2 from tests.interop import _interop_test_case from tests.interop import methods from tests.interop import resources -from tests.unit.beta import test_utilities - _SERVER_HOST_OVERRIDE = 'foo.test.google.fr' @@ -48,19 +47,18 @@ class SecureInteropTest( unittest.TestCase): def setUp(self): - self.server = test_pb2.beta_create_TestService_server(methods.TestService()) + self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + test_pb2.add_TestServiceServicer_to_server( + methods.TestService(), self.server) port = self.server.add_secure_port( - '[::]:0', implementations.ssl_server_credentials( + '[::]:0', grpc.ssl_server_credentials( [(resources.private_key(), resources.certificate_chain())])) self.server.start() - self.stub = test_pb2.beta_create_TestService_stub( - test_utilities.not_really_secure_channel( - 'localhost', port, implementations.ssl_channel_credentials( - resources.test_root_certificates()), - _SERVER_HOST_OVERRIDE)) - - def tearDown(self): - self.server.stop(0) + self.stub = test_pb2.TestServiceStub( + grpc.secure_channel( + 'localhost:{}'.format(port), + grpc.ssl_channel_credentials(resources.test_root_certificates()), + (('grpc.ssl_target_name_override', _SERVER_HOST_OVERRIDE,),))) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index 8aa1ce30c1a..9d61d189759 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -32,14 +32,12 @@ import argparse from oauth2client import client as oauth2client_client +import grpc from grpc.beta import implementations from src.proto.grpc.testing import test_pb2 from tests.interop import methods from tests.interop import resources -from tests.unit.beta import test_utilities - -_ONE_DAY_IN_SECONDS = 60 * 60 * 24 def _args(): @@ -66,41 +64,49 @@ def _args(): return parser.parse_args() +def _application_default_credentials(): + return oauth2client_client.GoogleCredentials.get_application_default() + + def _stub(args): + target = '{}:{}'.format(args.server_host, args.server_port) if args.test_case == 'oauth2_auth_token': - creds = oauth2client_client.GoogleCredentials.get_application_default() - scoped_creds = creds.create_scoped([args.oauth_scope]) - access_token = scoped_creds.get_access_token().access_token - call_creds = implementations.access_token_call_credentials(access_token) + google_credentials = _application_default_credentials() + scoped_credentials = google_credentials.create_scoped([args.oauth_scope]) + access_token = scoped_credentials.get_access_token().access_token + call_credentials = grpc.access_token_call_credentials(access_token) elif args.test_case == 'compute_engine_creds': - creds = oauth2client_client.GoogleCredentials.get_application_default() - scoped_creds = creds.create_scoped([args.oauth_scope]) - call_creds = implementations.google_call_credentials(scoped_creds) + google_credentials = _application_default_credentials() + scoped_credentials = google_credentials.create_scoped([args.oauth_scope]) + # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last + # remaining use of the Beta API. + call_credentials = implementations.google_call_credentials( + scoped_credentials) elif args.test_case == 'jwt_token_creds': - creds = oauth2client_client.GoogleCredentials.get_application_default() - call_creds = implementations.google_call_credentials(creds) + google_credentials = _application_default_credentials() + # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last + # remaining use of the Beta API. + call_credentials = implementations.google_call_credentials( + google_credentials) else: - call_creds = None + call_credentials = None if args.use_tls: if args.use_test_ca: root_certificates = resources.test_root_certificates() else: root_certificates = None # will load default roots. - channel_creds = implementations.ssl_channel_credentials(root_certificates) - if call_creds is not None: - channel_creds = implementations.composite_channel_credentials( - channel_creds, call_creds) + channel_credentials = grpc.ssl_channel_credentials(root_certificates) + if call_credentials is not None: + channel_credentials = grpc.composite_channel_credentials( + channel_credentials, call_credentials) - channel = test_utilities.not_really_secure_channel( - args.server_host, args.server_port, channel_creds, - args.server_host_override) - stub = test_pb2.beta_create_TestService_stub(channel) + channel = grpc.secure_channel( + target, channel_credentials, + (('grpc.ssl_target_name_override', args.server_host_override,),)) else: - channel = implementations.insecure_channel( - args.server_host, args.server_port) - stub = test_pb2.beta_create_TestService_stub(channel) - return stub + channel = grpc.insecure_channel(target) + return test_pb2.TestServiceStub(channel) def _test_case_from_arg(test_case_arg): diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py index 97e6c9e27ef..7edd75c56c9 100644 --- a/src/python/grpcio_tests/tests/interop/methods.py +++ b/src/python/grpcio_tests/tests/interop/methods.py @@ -29,8 +29,6 @@ """Implementations of interoperability test methods.""" -from __future__ import print_function - import enum import json import os @@ -41,26 +39,21 @@ from oauth2client import client as oauth2client_client import grpc from grpc.beta import implementations -from grpc.beta import interfaces -from grpc.framework.common import cardinality -from grpc.framework.interfaces.face import face from src.proto.grpc.testing import empty_pb2 from src.proto.grpc.testing import messages_pb2 from src.proto.grpc.testing import test_pb2 -_TIMEOUT = 7 - -class TestService(test_pb2.BetaTestServiceServicer): +class TestService(test_pb2.TestServiceServicer): def EmptyCall(self, request, context): return empty_pb2.Empty() def UnaryCall(self, request, context): if request.HasField('response_status'): - context.code(request.response_status.code) - context.details(request.response_status.message) + context.set_code(request.response_status.code) + context.set_details(request.response_status.message) return messages_pb2.SimpleResponse( payload=messages_pb2.Payload( type=messages_pb2.COMPRESSABLE, @@ -68,8 +61,8 @@ class TestService(test_pb2.BetaTestServiceServicer): def StreamingOutputCall(self, request, context): if request.HasField('response_status'): - context.code(request.response_status.code) - context.details(request.response_status.message) + context.set_code(request.response_status.code) + context.set_details(request.response_status.message) for response_parameters in request.response_parameters: yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( @@ -79,7 +72,7 @@ class TestService(test_pb2.BetaTestServiceServicer): def StreamingInputCall(self, request_iterator, context): aggregate_size = 0 for request in request_iterator: - if request.payload and request.payload.body: + if request.payload is not None and request.payload.body: aggregate_size += len(request.payload.body) return messages_pb2.StreamingInputCallResponse( aggregated_payload_size=aggregate_size) @@ -87,8 +80,8 @@ class TestService(test_pb2.BetaTestServiceServicer): def FullDuplexCall(self, request_iterator, context): for request in request_iterator: if request.HasField('response_status'): - context.code(request.response_status.code) - context.details(request.response_status.message) + context.set_code(request.response_status.code) + context.set_details(request.response_status.message) for response_parameters in request.response_parameters: yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( @@ -101,83 +94,80 @@ class TestService(test_pb2.BetaTestServiceServicer): return self.FullDuplexCall(request_iterator, context) -def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope, - protocol_options=None): - with stub: - request = messages_pb2.SimpleRequest( - response_type=messages_pb2.COMPRESSABLE, response_size=314159, - payload=messages_pb2.Payload(body=b'\x00' * 271828), - fill_username=fill_username, fill_oauth_scope=fill_oauth_scope) - response_future = stub.UnaryCall.future(request, _TIMEOUT, - protocol_options=protocol_options) - response = response_future.result() - if response.payload.type is not messages_pb2.COMPRESSABLE: - raise ValueError( - 'response payload type is "%s"!' % type(response.payload.type)) - if len(response.payload.body) != 314159: - raise ValueError( - 'response body of incorrect size %d!' % len(response.payload.body)) +def _large_unary_common_behavior( + stub, fill_username, fill_oauth_scope, call_credentials): + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, response_size=314159, + payload=messages_pb2.Payload(body=b'\x00' * 271828), + fill_username=fill_username, fill_oauth_scope=fill_oauth_scope) + response_future = stub.UnaryCall.future( + request, credentials=call_credentials) + response = response_future.result() + if response.payload.type is not messages_pb2.COMPRESSABLE: + raise ValueError( + 'response payload type is "%s"!' % type(response.payload.type)) + elif len(response.payload.body) != 314159: + raise ValueError( + 'response body of incorrect size %d!' % len(response.payload.body)) + else: return response def _empty_unary(stub): - with stub: - response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) - if not isinstance(response, empty_pb2.Empty): - raise TypeError( - 'response is of type "%s", not empty_pb2.Empty!', type(response)) + response = stub.EmptyCall(empty_pb2.Empty()) + if not isinstance(response, empty_pb2.Empty): + raise TypeError( + 'response is of type "%s", not empty_pb2.Empty!', type(response)) def _large_unary(stub): - _large_unary_common_behavior(stub, False, False) + _large_unary_common_behavior(stub, False, False, None) def _client_streaming(stub): - with stub: - payload_body_sizes = (27182, 8, 1828, 45904) - payloads = ( - messages_pb2.Payload(body=b'\x00' * size) - for size in payload_body_sizes) - requests = ( - messages_pb2.StreamingInputCallRequest(payload=payload) - for payload in payloads) - response = stub.StreamingInputCall(requests, _TIMEOUT) - if response.aggregated_payload_size != 74922: - raise ValueError( - 'incorrect size %d!' % response.aggregated_payload_size) + payload_body_sizes = (27182, 8, 1828, 45904,) + payloads = ( + messages_pb2.Payload(body=b'\x00' * size) + for size in payload_body_sizes) + requests = ( + messages_pb2.StreamingInputCallRequest(payload=payload) + for payload in payloads) + response = stub.StreamingInputCall(requests) + if response.aggregated_payload_size != 74922: + raise ValueError( + 'incorrect size %d!' % response.aggregated_payload_size) def _server_streaming(stub): - sizes = (31415, 9, 2653, 58979) - - with stub: - request = messages_pb2.StreamingOutputCallRequest( - response_type=messages_pb2.COMPRESSABLE, - response_parameters=( - messages_pb2.ResponseParameters(size=sizes[0]), - messages_pb2.ResponseParameters(size=sizes[1]), - messages_pb2.ResponseParameters(size=sizes[2]), - messages_pb2.ResponseParameters(size=sizes[3]), - )) - response_iterator = stub.StreamingOutputCall(request, _TIMEOUT) - for index, response in enumerate(response_iterator): - if response.payload.type != messages_pb2.COMPRESSABLE: - raise ValueError( - 'response body of invalid type %s!' % response.payload.type) - if len(response.payload.body) != sizes[index]: - raise ValueError( - 'response body of invalid size %d!' % len(response.payload.body)) + sizes = (31415, 9, 2653, 58979,) + + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=( + messages_pb2.ResponseParameters(size=sizes[0]), + messages_pb2.ResponseParameters(size=sizes[1]), + messages_pb2.ResponseParameters(size=sizes[2]), + messages_pb2.ResponseParameters(size=sizes[3]), + ) + ) + response_iterator = stub.StreamingOutputCall(request) + for index, response in enumerate(response_iterator): + if response.payload.type != messages_pb2.COMPRESSABLE: + raise ValueError( + 'response body of invalid type %s!' % response.payload.type) + elif len(response.payload.body) != sizes[index]: + raise ValueError( + 'response body of invalid size %d!' % len(response.payload.body)) def _cancel_after_begin(stub): - with stub: - sizes = (27182, 8, 1828, 45904) - payloads = [messages_pb2.Payload(body=b'\x00' * size) for size in sizes] - requests = [messages_pb2.StreamingInputCallRequest(payload=payload) - for payload in payloads] - responses = stub.StreamingInputCall.future(requests, _TIMEOUT) - responses.cancel() - if not responses.cancelled(): - raise ValueError('expected call to be cancelled') + sizes = (27182, 8, 1828, 45904,) + payloads = (messages_pb2.Payload(body=b'\x00' * size) for size in sizes) + requests = (messages_pb2.StreamingInputCallRequest(payload=payload) + for payload in payloads) + response_future = stub.StreamingInputCall.future(requests) + response_future.cancel() + if not response_future.cancelled(): + raise ValueError('expected call to be cancelled') class _Pipe(object): @@ -220,18 +210,17 @@ class _Pipe(object): def _ping_pong(stub): - request_response_sizes = (31415, 9, 2653, 58979) - request_payload_sizes = (27182, 8, 1828, 45904) + request_response_sizes = (31415, 9, 2653, 58979,) + request_payload_sizes = (27182, 8, 1828, 45904,) - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) - print('Starting ping-pong with response iterator %s' % response_iterator) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe) for response_size, payload_size in zip( request_response_sizes, request_payload_sizes): request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, - response_parameters=(messages_pb2.ResponseParameters( - size=response_size),), + response_parameters=( + messages_pb2.ResponseParameters(size=response_size),), payload=messages_pb2.Payload(body=b'\x00' * payload_size)) pipe.add(request) response = next(response_iterator) @@ -244,17 +233,17 @@ def _ping_pong(stub): def _cancel_after_first_response(stub): - request_response_sizes = (31415, 9, 2653, 58979) - request_payload_sizes = (27182, 8, 1828, 45904) - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) + request_response_sizes = (31415, 9, 2653, 58979,) + request_payload_sizes = (27182, 8, 1828, 45904,) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe) response_size = request_response_sizes[0] payload_size = request_payload_sizes[0] request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, - response_parameters=(messages_pb2.ResponseParameters( - size=response_size),), + response_parameters=( + messages_pb2.ResponseParameters(size=response_size),), payload=messages_pb2.Payload(body=b'\x00' * payload_size)) pipe.add(request) response = next(response_iterator) @@ -264,16 +253,17 @@ def _cancel_after_first_response(stub): try: next(response_iterator) - except Exception: - pass + except grpc.RpcError as rpc_error: + if rpc_error.code() is not grpc.StatusCode.CANCELLED: + raise else: raise ValueError('expected call to be cancelled') def _timeout_on_sleeping_server(stub): request_payload_size = 27182 - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, 0.001) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe, timeout=0.001) request = messages_pb2.StreamingOutputCallRequest( response_type=messages_pb2.COMPRESSABLE, @@ -282,15 +272,16 @@ def _timeout_on_sleeping_server(stub): time.sleep(0.1) try: next(response_iterator) - except face.ExpirationError: - pass + except grpc.RpcError as rpc_error: + if rpc_error.code() is not grpc.StatusCode.DEADLINE_EXCEEDED: + raise else: raise ValueError('expected call to exceed deadline') def _empty_stream(stub): - with stub, _Pipe() as pipe: - response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) + with _Pipe() as pipe: + response_iterator = stub.FullDuplexCall(pipe) pipe.close() try: next(response_iterator) @@ -300,65 +291,64 @@ def _empty_stream(stub): def _status_code_and_message(stub): - with stub: - message = 'test status message' - code = 2 - status = grpc.StatusCode.UNKNOWN # code = 2 - request = messages_pb2.SimpleRequest( - response_type=messages_pb2.COMPRESSABLE, - response_size=1, - payload=messages_pb2.Payload(body=b'\x00'), - response_status=messages_pb2.EchoStatus(code=code, message=message) - ) - response_future = stub.UnaryCall.future(request, _TIMEOUT) - if response_future.code() != status: - raise ValueError( - 'expected code %s, got %s' % (status, response_future.code())) - if response_future.details() != message: - raise ValueError( - 'expected message %s, got %s' % (message, response_future.details())) - - request = messages_pb2.StreamingOutputCallRequest( - response_type=messages_pb2.COMPRESSABLE, - response_parameters=( - messages_pb2.ResponseParameters(size=1),), - response_status=messages_pb2.EchoStatus(code=code, message=message)) - response_iterator = stub.StreamingOutputCall(request, _TIMEOUT) - if response_future.code() != status: - raise ValueError( - 'expected code %s, got %s' % (status, response_iterator.code())) - if response_future.details() != message: - raise ValueError( - 'expected message %s, got %s' % (message, response_iterator.details())) + message = 'test status message' + code = 2 + status = grpc.StatusCode.UNKNOWN # code = 2 + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, + response_size=1, + payload=messages_pb2.Payload(body=b'\x00'), + response_status=messages_pb2.EchoStatus(code=code, message=message) + ) + response_future = stub.UnaryCall.future(request) + if response_future.code() != status: + raise ValueError( + 'expected code %s, got %s' % (status, response_future.code())) + elif response_future.details() != message: + raise ValueError( + 'expected message %s, got %s' % (message, response_future.details())) + + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=( + messages_pb2.ResponseParameters(size=1),), + response_status=messages_pb2.EchoStatus(code=code, message=message)) + response_iterator = stub.StreamingOutputCall(request) + if response_future.code() != status: + raise ValueError( + 'expected code %s, got %s' % (status, response_iterator.code())) + elif response_future.details() != message: + raise ValueError( + 'expected message %s, got %s' % (message, response_iterator.details())) def _compute_engine_creds(stub, args): - response = _large_unary_common_behavior(stub, True, True) + response = _large_unary_common_behavior(stub, True, True, None) if args.default_service_account != response.username: raise ValueError( - 'expected username %s, got %s' % (args.default_service_account, - response.username)) + 'expected username %s, got %s' % ( + args.default_service_account, response.username)) def _oauth2_auth_token(stub, args): json_key_filename = os.environ[ oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] - response = _large_unary_common_behavior(stub, True, True) + response = _large_unary_common_behavior(stub, True, True, None) if wanted_email != response.username: raise ValueError( 'expected username %s, got %s' % (wanted_email, response.username)) if args.oauth_scope.find(response.oauth_scope) == -1: raise ValueError( - 'expected to find oauth scope "%s" in received "%s"' % - (response.oauth_scope, args.oauth_scope)) + 'expected to find oauth scope "{}" in received "{}"'.format( + response.oauth_scope, args.oauth_scope)) def _jwt_token_creds(stub, args): json_key_filename = os.environ[ oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS] wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] - response = _large_unary_common_behavior(stub, True, False) + response = _large_unary_common_behavior(stub, True, False, None) if wanted_email != response.username: raise ValueError( 'expected username %s, got %s' % (wanted_email, response.username)) @@ -370,11 +360,11 @@ def _per_rpc_creds(stub, args): wanted_email = json.load(open(json_key_filename, 'rb'))['client_email'] credentials = oauth2client_client.GoogleCredentials.get_application_default() scoped_credentials = credentials.create_scoped([args.oauth_scope]) - call_creds = implementations.google_call_credentials(scoped_credentials) - options = interfaces.grpc_call_options(disable_compression=False, - credentials=call_creds) - response = _large_unary_common_behavior(stub, True, False, - protocol_options=options) + # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last + # remaining use of the Beta API. + call_credentials = implementations.google_call_credentials( + scoped_credentials) + response = _large_unary_common_behavior(stub, True, False, call_credentials) if wanted_email != response.username: raise ValueError( 'expected username %s, got %s' % (wanted_email, response.username)) diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index ab2c3c708f4..1ae83bc57d0 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -30,10 +30,11 @@ """The Python implementation of the GRPC interoperability test server.""" import argparse +from concurrent import futures import logging import time -from grpc.beta import implementations +import grpc from src.proto.grpc.testing import test_pb2 from tests.interop import methods @@ -51,12 +52,13 @@ def serve(): default=False, type=resources.parse_bool) args = parser.parse_args() - server = test_pb2.beta_create_TestService_server(methods.TestService()) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server) if args.use_tls: private_key = resources.private_key() certificate_chain = resources.certificate_chain() - credentials = implementations.ssl_server_credentials( - [(private_key, certificate_chain)]) + credentials = grpc.ssl_server_credentials( + ((private_key, certificate_chain),)) server.add_secure_port('[::]:{}'.format(args.port), credentials) else: server.add_insecure_port('[::]:{}'.format(args.port)) @@ -68,7 +70,7 @@ def serve(): time.sleep(_ONE_DAY_IN_SECONDS) except BaseException as e: logging.info('Caught exception "%s"; stopping server...', e) - server.stop(0) + server.stop(None) logging.info('Server stopped; exiting.') if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py index 0de2532cd88..975f33b4c16 100644 --- a/src/python/grpcio_tests/tests/stress/client.py +++ b/src/python/grpcio_tests/tests/stress/client.py @@ -30,9 +30,10 @@ """Entry point for running stress tests.""" import argparse +from concurrent import futures import threading -from grpc.beta import implementations +import grpc from six.moves import queue from src.proto.grpc.testing import metrics_pb2 from src.proto.grpc.testing import test_pb2 @@ -92,24 +93,24 @@ def _parse_weighted_test_cases(test_case_args): def run_test(args): test_cases = _parse_weighted_test_cases(args.test_cases) - test_servers = args.server_addresses.split(',') + test_server_targets = args.server_addresses.split(',') # Propagate any client exceptions with a queue exception_queue = queue.Queue() stop_event = threading.Event() hist = histogram.Histogram(1, 1) runners = [] - server = metrics_pb2.beta_create_MetricsService_server( - metrics_server.MetricsServer(hist)) + server = grpc.server(futures.ThreadPoolExecutor(max_workers=25)) + metrics_pb2.add_MetricsServiceServicer_to_server( + metrics_server.MetricsServer(hist), server) server.add_insecure_port('[::]:{}'.format(args.metrics_port)) server.start() - for test_server in test_servers: - host, port = test_server.split(':', 1) + for test_server_target in test_server_targets: for _ in xrange(args.num_channels_per_server): - channel = implementations.insecure_channel(host, int(port)) + channel = grpc.insecure_channel(test_server_target) for _ in xrange(args.num_stubs_per_channel): - stub = test_pb2.beta_create_TestService_stub(channel) + stub = test_pb2.TestServiceStub(channel) runner = test_runner.TestRunner(stub, test_cases, hist, exception_queue, stop_event) runners.append(runner) @@ -128,8 +129,8 @@ def run_test(args): stop_event.set() for runner in runners: runner.join() - runner = None - server.stop(0) + runner = None + server.stop(None) if __name__ == '__main__': run_test(_args()) diff --git a/src/python/grpcio_tests/tests/stress/metrics_server.py b/src/python/grpcio_tests/tests/stress/metrics_server.py index b994e4643e5..33dd1d6f2ad 100644 --- a/src/python/grpcio_tests/tests/stress/metrics_server.py +++ b/src/python/grpcio_tests/tests/stress/metrics_server.py @@ -36,7 +36,7 @@ from src.proto.grpc.testing import metrics_pb2 GAUGE_NAME = 'python_overall_qps' -class MetricsServer(metrics_pb2.BetaMetricsServiceServicer): +class MetricsServer(metrics_pb2.MetricsServiceServicer): def __init__(self, histogram): self._start_time = time.time() diff --git a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py index 3c00f686cec..9cae96a00d8 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_connectivity_test.py @@ -32,12 +32,12 @@ import threading import time import unittest -from concurrent import futures import grpc from grpc import _channel from grpc import _server from tests.unit.framework.common import test_constants +from tests.unit import _thread_pool def _ready_in_connectivities(connectivities): @@ -104,7 +104,8 @@ class ChannelConnectivityTest(unittest.TestCase): grpc.ChannelConnectivity.READY, fifth_connectivities) def test_immediately_connectable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() first_callback = _Callback() @@ -141,9 +142,11 @@ class ChannelConnectivityTest(unittest.TestCase): fourth_connectivities) self.assertNotIn( grpc.ChannelConnectivity.SHUTDOWN, fourth_connectivities) + self.assertFalse(thread_pool.was_used()) def test_reachable_then_unreachable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() callback = _Callback() @@ -155,6 +158,7 @@ class ChannelConnectivityTest(unittest.TestCase): server.stop(None) callback.block_until_connectivities_satisfy(_last_connectivity_is_not_ready) channel.unsubscribe(callback.update) + self.assertFalse(thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py index e8982ed2ded..24f5b45b18e 100644 --- a/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py +++ b/src/python/grpcio_tests/tests/unit/_channel_ready_future_test.py @@ -31,12 +31,12 @@ import threading import unittest -from concurrent import futures import grpc from grpc import _channel from grpc import _server from tests.unit.framework.common import test_constants +from tests.unit import _thread_pool class _Callback(object): @@ -78,7 +78,8 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.running()) def test_immediately_connectable_channel_connectivity(self): - server = _server.Server(futures.ThreadPoolExecutor(max_workers=0), ()) + thread_pool = _thread_pool.RecordingThreadPool(max_workers=None) + server = _server.Server(thread_pool, ()) port = server.add_insecure_port('[::]:0') server.start() channel = grpc.insecure_channel('localhost:{}'.format(port)) @@ -97,6 +98,7 @@ class ChannelReadyFutureTest(unittest.TestCase): self.assertFalse(ready_future.cancelled()) self.assertTrue(ready_future.done()) self.assertFalse(ready_future.running()) + self.assertFalse(thread_pool.was_used()) if __name__ == '__main__': diff --git a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py index f9a8e2401bb..142387d810a 100644 --- a/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py +++ b/src/python/grpcio_tests/tests/unit/_cython/cygrpc_test.py @@ -30,6 +30,7 @@ import time import threading import unittest +import platform from grpc._cython import cygrpc from tests.unit._cython import test_utilities diff --git a/src/python/grpcio_tests/tests/unit/_thread_pool.py b/src/python/grpcio_tests/tests/unit/_thread_pool.py new file mode 100644 index 00000000000..f13cc2f86fc --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_thread_pool.py @@ -0,0 +1,48 @@ +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import threading +from concurrent import futures + + +class RecordingThreadPool(futures.Executor): + """A thread pool that records if used.""" + def __init__(self, max_workers): + self._tp_executor = futures.ThreadPoolExecutor(max_workers=max_workers) + self._lock = threading.Lock() + self._was_used = False + + def submit(self, fn, *args, **kwargs): + with self._lock: + self._was_used = True + self._tp_executor.submit(fn, *args, **kwargs) + + def was_used(self): + with self._lock: + return self._was_used diff --git a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py index d32208f9eb0..df620b19ba5 100644 --- a/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py +++ b/src/python/grpcio_tests/tests/unit/framework/interfaces/face/_future_invocation_asynchronous_event_service.py @@ -434,11 +434,13 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest. for test_messages in test_messages_sequence: request = test_messages.request() callback = _Callback() + abortion_callback = _Callback() with self._control.fail(): response_future = self._invoker.future(group, method)( request, _3069_test_constant.REALLY_SHORT_TIMEOUT) response_future.add_done_callback(callback) + response_future.add_abortion_callback(abortion_callback) self.assertIs(callback.future(), response_future) # Because the servicer fails outside of the thread from which the @@ -450,6 +452,7 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest. with self.assertRaises(face.ExpirationError): response_future.result() self.assertIsNotNone(response_future.traceback()) + self.assertIsNotNone(abortion_callback.future()) def testFailedUnaryRequestStreamResponse(self): for (group, method), test_messages_sequence in ( @@ -472,11 +475,13 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest. for test_messages in test_messages_sequence: requests = test_messages.requests() callback = _Callback() + abortion_callback = _Callback() with self._control.fail(): response_future = self._invoker.future(group, method)( iter(requests), _3069_test_constant.REALLY_SHORT_TIMEOUT) response_future.add_done_callback(callback) + response_future.add_abortion_callback(abortion_callback) self.assertIs(callback.future(), response_future) # Because the servicer fails outside of the thread from which the @@ -488,6 +493,7 @@ class TestCase(six.with_metaclass(abc.ABCMeta, test_coverage.Coverage, unittest. with self.assertRaises(face.ExpirationError): response_future.result() self.assertIsNotNone(response_future.traceback()) + self.assertIsNotNone(abortion_callback.future()) def testFailedStreamRequestStreamResponse(self): for (group, method), test_messages_sequence in ( diff --git a/src/ruby/.rubocop.yml b/src/ruby/.rubocop.yml index 34bb4775435..0f61ccfa812 100644 --- a/src/ruby/.rubocop.yml +++ b/src/ruby/.rubocop.yml @@ -5,8 +5,8 @@ inherit_from: .rubocop_todo.yml AllCops: Exclude: - 'bin/apis/**/*' - - 'bin/math.rb' - - 'bin/math_services.rb' + - 'bin/math_pb.rb' + - 'bin/math_services_pb.rb' - 'pb/grpc/health/v1/*' - 'pb/test/**/*' diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb index d7e00e42938..1f238a798ba 100755 --- a/src/ruby/bin/math_client.rb +++ b/src/ruby/bin/math_client.rb @@ -40,7 +40,7 @@ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir) $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) require 'grpc' -require 'math_services' +require 'math_services_pb' require 'optparse' include GRPC::Core::TimeConsts diff --git a/src/ruby/bin/math.rb b/src/ruby/bin/math_pb.rb old mode 100755 new mode 100644 similarity index 100% rename from src/ruby/bin/math.rb rename to src/ruby/bin/math_pb.rb diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb index 1ee4c5632d9..751a6ebcab7 100755 --- a/src/ruby/bin/math_server.rb +++ b/src/ruby/bin/math_server.rb @@ -42,7 +42,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) require 'forwardable' require 'grpc' require 'logger' -require 'math_services' +require 'math_services_pb' require 'optparse' # RubyLogger defines a logger for gRPC based on the standard ruby logger. diff --git a/src/ruby/bin/math_services.rb b/src/ruby/bin/math_services_pb.rb old mode 100755 new mode 100644 similarity index 99% rename from src/ruby/bin/math_services.rb rename to src/ruby/bin/math_services_pb.rb index 2b97602b6fb..2ba1825d4f4 --- a/src/ruby/bin/math_services.rb +++ b/src/ruby/bin/math_services_pb.rb @@ -32,7 +32,7 @@ # require 'grpc' -require 'math' +require 'math_pb' module Math module Math diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c index 18a15d01252..e6d30a174b8 100644 --- a/src/ruby/ext/grpc/rb_channel.c +++ b/src/ruby/ext/grpc/rb_channel.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "rb_grpc.h" #include "rb_call.h" #include "rb_channel_args.h" @@ -71,6 +72,7 @@ typedef struct grpc_rb_channel { /* The actual channel */ grpc_channel *wrapped; + grpc_completion_queue *queue; } grpc_rb_channel; /* Destroys Channel instances. */ @@ -83,6 +85,7 @@ static void grpc_rb_channel_free(void *p) { if (ch->wrapped != NULL) { grpc_channel_destroy(ch->wrapped); + grpc_rb_completion_queue_destroy(ch->queue); } xfree(p); @@ -165,6 +168,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) { } rb_ivar_set(self, id_target, target); wrapper->wrapped = ch; + wrapper->queue = grpc_completion_queue_create(NULL); return self; } @@ -203,16 +207,18 @@ static VALUE grpc_rb_channel_get_connectivity_state(int argc, VALUE *argv, the completion queue with success=0 */ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self, VALUE last_state, - VALUE cqueue, - VALUE deadline, - VALUE tag) { + VALUE deadline) { grpc_rb_channel *wrapper = NULL; grpc_channel *ch = NULL; grpc_completion_queue *cq = NULL; - cq = grpc_rb_get_wrapped_completion_queue(cqueue); + void *tag = wrapper; + + grpc_event event; + TypedData_Get_Struct(self, grpc_rb_channel, &grpc_channel_data_type, wrapper); ch = wrapper->wrapped; + cq = wrapper->queue; if (ch == NULL) { rb_raise(rb_eRuntimeError, "closed!"); return Qnil; @@ -222,9 +228,16 @@ static VALUE grpc_rb_channel_watch_connectivity_state(VALUE self, (grpc_connectivity_state)NUM2LONG(last_state), grpc_rb_time_timeval(deadline, /* absolute time */ 0), cq, - ROBJECT(tag)); + tag); - return Qnil; + event = rb_completion_queue_pluck(cq, tag, + gpr_inf_future(GPR_CLOCK_REALTIME), NULL); + + if (event.success) { + return Qtrue; + } else { + return Qfalse; + } } /* Create a call given a grpc_channel, in order to call method. The request diff --git a/src/ruby/ext/grpc/rb_completion_queue.h b/src/ruby/ext/grpc/rb_completion_queue.h index 9f8f6aa5fff..aa9dc6416af 100644 --- a/src/ruby/ext/grpc/rb_completion_queue.h +++ b/src/ruby/ext/grpc/rb_completion_queue.h @@ -38,9 +38,6 @@ #include -/* Gets the wrapped completion queue from the ruby wrapper */ -grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v); - void grpc_rb_completion_queue_destroy(grpc_completion_queue *cq); /** diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index 525508dbb19..17cd165a91d 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -221,7 +221,7 @@ static VALUE grpc_rb_time_val_to_time(VALUE self) { time_const); real_time = gpr_convert_clock_type(*time_const, GPR_CLOCK_REALTIME); return rb_funcall(rb_cTime, id_at, 2, INT2NUM(real_time.tv_sec), - INT2NUM(real_time.tv_nsec)); + INT2NUM(real_time.tv_nsec / 1000)); } /* Invokes inspect on the ctime version of the time val. */ diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c index 9748cb576ba..9caaf7b7835 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c @@ -61,15 +61,10 @@ census_trace_print_type census_trace_print_import; census_trace_scan_start_type census_trace_scan_start_import; census_get_trace_record_type census_get_trace_record_import; census_trace_scan_end_type census_trace_scan_end_import; +census_define_resource_type census_define_resource_import; +census_delete_resource_type census_delete_resource_import; +census_resource_id_type census_resource_id_import; census_record_values_type census_record_values_import; -census_view_create_type census_view_create_import; -census_view_delete_type census_view_delete_import; -census_view_metric_type census_view_metric_import; -census_view_naggregations_type census_view_naggregations_import; -census_view_tags_type census_view_tags_import; -census_view_aggregrations_type census_view_aggregrations_import; -census_view_get_data_type census_view_get_data_import; -census_view_reset_type census_view_reset_import; grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import; grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import; grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import; @@ -85,6 +80,7 @@ grpc_register_plugin_type grpc_register_plugin_import; grpc_init_type grpc_init_import; grpc_shutdown_type grpc_shutdown_import; grpc_version_string_type grpc_version_string_import; +grpc_g_stands_for_type grpc_g_stands_for_import; grpc_completion_queue_create_type grpc_completion_queue_create_import; grpc_completion_queue_next_type grpc_completion_queue_next_import; grpc_completion_queue_pluck_type grpc_completion_queue_pluck_import; @@ -186,6 +182,7 @@ gpr_set_log_function_type gpr_set_log_function_import; gpr_slice_ref_type gpr_slice_ref_import; gpr_slice_unref_type gpr_slice_unref_import; gpr_slice_new_type gpr_slice_new_import; +gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import; gpr_slice_new_with_len_type gpr_slice_new_with_len_import; gpr_slice_malloc_type gpr_slice_malloc_import; gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import; @@ -333,15 +330,10 @@ void grpc_rb_load_imports(HMODULE library) { census_trace_scan_start_import = (census_trace_scan_start_type) GetProcAddress(library, "census_trace_scan_start"); census_get_trace_record_import = (census_get_trace_record_type) GetProcAddress(library, "census_get_trace_record"); census_trace_scan_end_import = (census_trace_scan_end_type) GetProcAddress(library, "census_trace_scan_end"); + census_define_resource_import = (census_define_resource_type) GetProcAddress(library, "census_define_resource"); + census_delete_resource_import = (census_delete_resource_type) GetProcAddress(library, "census_delete_resource"); + census_resource_id_import = (census_resource_id_type) GetProcAddress(library, "census_resource_id"); census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values"); - census_view_create_import = (census_view_create_type) GetProcAddress(library, "census_view_create"); - census_view_delete_import = (census_view_delete_type) GetProcAddress(library, "census_view_delete"); - census_view_metric_import = (census_view_metric_type) GetProcAddress(library, "census_view_metric"); - census_view_naggregations_import = (census_view_naggregations_type) GetProcAddress(library, "census_view_naggregations"); - census_view_tags_import = (census_view_tags_type) GetProcAddress(library, "census_view_tags"); - census_view_aggregrations_import = (census_view_aggregrations_type) GetProcAddress(library, "census_view_aggregrations"); - census_view_get_data_import = (census_view_get_data_type) GetProcAddress(library, "census_view_get_data"); - census_view_reset_import = (census_view_reset_type) GetProcAddress(library, "census_view_reset"); grpc_compression_algorithm_parse_import = (grpc_compression_algorithm_parse_type) GetProcAddress(library, "grpc_compression_algorithm_parse"); grpc_compression_algorithm_name_import = (grpc_compression_algorithm_name_type) GetProcAddress(library, "grpc_compression_algorithm_name"); grpc_compression_algorithm_for_level_import = (grpc_compression_algorithm_for_level_type) GetProcAddress(library, "grpc_compression_algorithm_for_level"); @@ -357,6 +349,7 @@ void grpc_rb_load_imports(HMODULE library) { grpc_init_import = (grpc_init_type) GetProcAddress(library, "grpc_init"); grpc_shutdown_import = (grpc_shutdown_type) GetProcAddress(library, "grpc_shutdown"); grpc_version_string_import = (grpc_version_string_type) GetProcAddress(library, "grpc_version_string"); + grpc_g_stands_for_import = (grpc_g_stands_for_type) GetProcAddress(library, "grpc_g_stands_for"); grpc_completion_queue_create_import = (grpc_completion_queue_create_type) GetProcAddress(library, "grpc_completion_queue_create"); grpc_completion_queue_next_import = (grpc_completion_queue_next_type) GetProcAddress(library, "grpc_completion_queue_next"); grpc_completion_queue_pluck_import = (grpc_completion_queue_pluck_type) GetProcAddress(library, "grpc_completion_queue_pluck"); @@ -458,6 +451,7 @@ void grpc_rb_load_imports(HMODULE library) { gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref"); gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref"); gpr_slice_new_import = (gpr_slice_new_type) GetProcAddress(library, "gpr_slice_new"); + gpr_slice_new_with_user_data_import = (gpr_slice_new_with_user_data_type) GetProcAddress(library, "gpr_slice_new_with_user_data"); gpr_slice_new_with_len_import = (gpr_slice_new_with_len_type) GetProcAddress(library, "gpr_slice_new_with_len"); gpr_slice_malloc_import = (gpr_slice_malloc_type) GetProcAddress(library, "gpr_slice_malloc"); gpr_slice_from_copied_string_import = (gpr_slice_from_copied_string_type) GetProcAddress(library, "gpr_slice_from_copied_string"); diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h index 6f0974e31b4..a2f5b86497b 100644 --- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h +++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h @@ -134,33 +134,18 @@ extern census_get_trace_record_type census_get_trace_record_import; typedef void(*census_trace_scan_end_type)(); extern census_trace_scan_end_type census_trace_scan_end_import; #define census_trace_scan_end census_trace_scan_end_import +typedef int32_t(*census_define_resource_type)(const uint8_t *resource_pb, size_t resource_pb_size); +extern census_define_resource_type census_define_resource_import; +#define census_define_resource census_define_resource_import +typedef void(*census_delete_resource_type)(int32_t resource_id); +extern census_delete_resource_type census_delete_resource_import; +#define census_delete_resource census_delete_resource_import +typedef int32_t(*census_resource_id_type)(const char *name); +extern census_resource_id_type census_resource_id_import; +#define census_resource_id census_resource_id_import typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues); extern census_record_values_type census_record_values_import; #define census_record_values census_record_values_import -typedef census_view *(*census_view_create_type)(uint32_t metric_id, const census_context *tags, const census_aggregation *aggregations, size_t naggregations); -extern census_view_create_type census_view_create_import; -#define census_view_create census_view_create_import -typedef void(*census_view_delete_type)(census_view *view); -extern census_view_delete_type census_view_delete_import; -#define census_view_delete census_view_delete_import -typedef size_t(*census_view_metric_type)(const census_view *view); -extern census_view_metric_type census_view_metric_import; -#define census_view_metric census_view_metric_import -typedef size_t(*census_view_naggregations_type)(const census_view *view); -extern census_view_naggregations_type census_view_naggregations_import; -#define census_view_naggregations census_view_naggregations_import -typedef const census_context *(*census_view_tags_type)(const census_view *view); -extern census_view_tags_type census_view_tags_import; -#define census_view_tags census_view_tags_import -typedef const census_aggregation *(*census_view_aggregrations_type)(const census_view *view); -extern census_view_aggregrations_type census_view_aggregrations_import; -#define census_view_aggregrations census_view_aggregrations_import -typedef const census_view_data *(*census_view_get_data_type)(const census_view *view); -extern census_view_get_data_type census_view_get_data_import; -#define census_view_get_data census_view_get_data_import -typedef void(*census_view_reset_type)(census_view *view); -extern census_view_reset_type census_view_reset_import; -#define census_view_reset census_view_reset_import typedef int(*grpc_compression_algorithm_parse_type)(const char *name, size_t name_length, grpc_compression_algorithm *algorithm); extern grpc_compression_algorithm_parse_type grpc_compression_algorithm_parse_import; #define grpc_compression_algorithm_parse grpc_compression_algorithm_parse_import @@ -206,6 +191,9 @@ extern grpc_shutdown_type grpc_shutdown_import; typedef const char *(*grpc_version_string_type)(void); extern grpc_version_string_type grpc_version_string_import; #define grpc_version_string grpc_version_string_import +typedef const char *(*grpc_g_stands_for_type)(void); +extern grpc_g_stands_for_type grpc_g_stands_for_import; +#define grpc_g_stands_for grpc_g_stands_for_import typedef grpc_completion_queue *(*grpc_completion_queue_create_type)(void *reserved); extern grpc_completion_queue_create_type grpc_completion_queue_create_import; #define grpc_completion_queue_create grpc_completion_queue_create_import @@ -509,6 +497,9 @@ extern gpr_slice_unref_type gpr_slice_unref_import; typedef gpr_slice(*gpr_slice_new_type)(void *p, size_t len, void (*destroy)(void *)); extern gpr_slice_new_type gpr_slice_new_import; #define gpr_slice_new gpr_slice_new_import +typedef gpr_slice(*gpr_slice_new_with_user_data_type)(void *p, size_t len, void (*destroy)(void *), void *user_data); +extern gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import; +#define gpr_slice_new_with_user_data gpr_slice_new_with_user_data_import typedef gpr_slice(*gpr_slice_new_with_len_type)(void *p, size_t len, void (*destroy)(void *, size_t)); extern gpr_slice_new_with_len_type gpr_slice_new_with_len_import; #define gpr_slice_new_with_len gpr_slice_new_with_len_import diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index bf26841fd22..2a6a246e677 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -218,7 +218,7 @@ static VALUE grpc_rb_server_request_call(VALUE self) { grpc_rb_sNewServerRpc, rb_str_new2(st.details.method), rb_str_new2(st.details.host), rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec), - INT2NUM(deadline.tv_nsec)), + INT2NUM(deadline.tv_nsec / 1000)), grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call, call_queue), NULL); grpc_request_call_stack_cleanup(&st); diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb index 4260d854376..23688dc9244 100644 --- a/src/ruby/lib/grpc/generic/active_call.rb +++ b/src/ruby/lib/grpc/generic/active_call.rb @@ -58,7 +58,7 @@ module GRPC include Core::TimeConsts include Core::CallOps extend Forwardable - attr_reader(:deadline) + attr_reader :deadline, :metadata_sent, :metadata_to_send def_delegators :@call, :cancel, :metadata, :write_flag, :write_flag=, :peer, :peer_cert, :trailing_metadata @@ -101,7 +101,7 @@ module GRPC # @param metadata_received [true|false] indicates if metadata has already # been received. Should always be true for server calls def initialize(call, marshal, unmarshal, deadline, started: true, - metadata_received: false) + metadata_received: false, metadata_to_send: nil) fail(TypeError, '!Core::Call') unless call.is_a? Core::Call @call = call @deadline = deadline @@ -110,6 +110,20 @@ module GRPC @metadata_received = metadata_received @metadata_sent = started @op_notifier = nil + + fail(ArgumentError, 'Already sent md') if started && metadata_to_send + @metadata_to_send = metadata_to_send || {} unless started + @send_initial_md_mutex = Mutex.new + end + + # Sends the initial metadata that has yet to be sent. + # Does nothing if metadata has already been sent for this call. + def send_initial_metadata + @send_initial_md_mutex.synchronize do + return if @metadata_sent + @metadata_tag = ActiveCall.client_invoke(@call, @metadata_to_send) + @metadata_sent = true + end end # output_metadata are provides access to hash that can be used to @@ -187,7 +201,7 @@ module GRPC # @param marshalled [false, true] indicates if the object is already # marshalled. def remote_send(req, marshalled = false) - # TODO(murgatroid99): ensure metadata was sent + send_initial_metadata GRPC.logger.debug("sending #{req}, marshalled? #{marshalled}") payload = marshalled ? req : @marshal.call(req) @call.run_batch(SEND_MESSAGE => payload) @@ -203,6 +217,7 @@ module GRPC # list, mulitple metadata for its key are sent def send_status(code = OK, details = '', assert_finished = false, metadata: {}) + send_initial_metadata ops = { SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details, metadata) } @@ -303,7 +318,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Object] the response received from the server def request_response(req, metadata: {}) - start_call(metadata) + merge_metadata_to_send(metadata) && send_initial_metadata remote_send(req) writes_done(false) response = remote_read @@ -327,7 +342,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Object] the response received from the server def client_streamer(requests, metadata: {}) - start_call(metadata) + merge_metadata_to_send(metadata) && send_initial_metadata requests.each { |r| remote_send(r) } writes_done(false) response = remote_read @@ -353,7 +368,7 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator|nil] a response Enumerator def server_streamer(req, metadata: {}) - start_call(metadata) + merge_metadata_to_send(metadata) && send_initial_metadata remote_send(req) writes_done(false) replies = enum_for(:each_remote_read_then_finish) @@ -392,9 +407,12 @@ module GRPC # a list, multiple metadata for its key are sent # @return [Enumerator, nil] a response Enumerator def bidi_streamer(requests, metadata: {}, &blk) - start_call(metadata) - bd = BidiCall.new(@call, @marshal, @unmarshal, + merge_metadata_to_send(metadata) && send_initial_metadata + bd = BidiCall.new(@call, + @marshal, + @unmarshal, metadata_received: @metadata_received) + bd.run_on_client(requests, @op_notifier, &blk) end @@ -410,8 +428,12 @@ module GRPC # # @param gen_each_reply [Proc] generates the BiDi stream replies def run_server_bidi(gen_each_reply) - bd = BidiCall.new(@call, @marshal, @unmarshal, - metadata_received: @metadata_received) + bd = BidiCall.new(@call, + @marshal, + @unmarshal, + metadata_received: @metadata_received, + req_view: MultiReqView.new(self)) + bd.run_on_server(gen_each_reply) end @@ -428,15 +450,23 @@ module GRPC @op_notifier.notify(self) end + # Add to the metadata that will be sent from the server. + # Fails if metadata has already been sent. + # Unused by client calls. + def merge_metadata_to_send(new_metadata = {}) + @send_initial_md_mutex.synchronize do + fail('cant change metadata after already sent') if @metadata_sent + @metadata_to_send.merge!(new_metadata) + end + end + private # Starts the call if not already started # @param metadata [Hash] metadata to be sent to the server. If a value is # a list, multiple metadata for its key are sent def start_call(metadata = {}) - return if @metadata_sent - @metadata_tag = ActiveCall.client_invoke(@call, metadata) - @metadata_sent = true + merge_metadata_to_send(metadata) && send_initial_metadata end def self.view_class(*visible_methods) @@ -454,12 +484,20 @@ module GRPC # SingleReqView limits access to an ActiveCall's methods for use in server # handlers that receive just one request. SingleReqView = view_class(:cancelled?, :deadline, :metadata, - :output_metadata, :peer, :peer_cert) + :output_metadata, :peer, :peer_cert, + :send_initial_metadata, + :metadata_to_send, + :merge_metadata_to_send, + :metadata_sent) # MultiReqView limits access to an ActiveCall's methods for use in # server client_streamer handlers. MultiReqView = view_class(:cancelled?, :deadline, :each_queued_msg, - :each_remote_read, :metadata, :output_metadata) + :each_remote_read, :metadata, :output_metadata, + :send_initial_metadata, + :metadata_to_send, + :merge_metadata_to_send, + :metadata_sent) # Operation limits access to an ActiveCall's methods for use as # a Operation on the client. diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb index 425dc3e5198..d7cd9e6df2b 100644 --- a/src/ruby/lib/grpc/generic/bidi_call.rb +++ b/src/ruby/lib/grpc/generic/bidi_call.rb @@ -56,18 +56,19 @@ module GRPC # @param unmarshal [Function] f(string)->obj that unmarshals responses # @param metadata_received [true|false] indicates if metadata has already # been received. Should always be true for server calls - def initialize(call, marshal, unmarshal, metadata_received: false) + def initialize(call, marshal, unmarshal, metadata_received: false, + req_view: nil) fail(ArgumentError, 'not a call') unless call.is_a? Core::Call @call = call @marshal = marshal @op_notifier = nil # signals completion on clients - @readq = Queue.new @unmarshal = unmarshal @metadata_received = metadata_received @reads_complete = false @writes_complete = false @complete = false @done_mutex = Mutex.new + @req_view = req_view end # Begins orchestration of the Bidi stream for a client sending requests. @@ -76,13 +77,12 @@ module GRPC # block that can be invoked with each response. # # @param requests the Enumerable of requests to send - # @op_notifier a Notifier used to signal completion + # @param op_notifier a Notifier used to signal completion # @return an Enumerator of requests to yield def run_on_client(requests, op_notifier, &blk) @op_notifier = op_notifier @enq_th = Thread.new { write_loop(requests) } - @loop_th = start_read_loop - each_queued_msg(&blk) + read_loop(&blk) end # Begins orchestration of the Bidi stream for a server generating replies. @@ -97,8 +97,15 @@ module GRPC # # @param gen_each_reply [Proc] generates the BiDi stream replies. def run_on_server(gen_each_reply) - replys = gen_each_reply.call(each_queued_msg) - @loop_th = start_read_loop(is_client: false) + # Pass in the optional call object parameter if possible + if gen_each_reply.arity == 1 + replys = gen_each_reply.call(read_loop(is_client: false)) + elsif gen_each_reply.arity == 2 + replys = gen_each_reply.call(read_loop(is_client: false), @req_view) + else + fail 'Illegal arity of reply generator' + end + write_loop(replys, is_client: false) end @@ -135,24 +142,6 @@ module GRPC batch_result end - # each_queued_msg yields each message on this instances readq - # - # - messages are added to the readq by #read_loop - # - iteration ends when the instance itself is added - def each_queued_msg - return enum_for(:each_queued_msg) unless block_given? - count = 0 - loop do - GRPC.logger.debug("each_queued_msg: waiting##{count}") - count += 1 - req = @readq.pop - GRPC.logger.debug("each_queued_msg: req = #{req}") - fail req if req.is_a? StandardError - break if req.equal?(END_OF_READS) - yield req - end - end - def write_loop(requests, is_client: true) GRPC.logger.debug('bidi-write-loop: starting') count = 0 @@ -162,6 +151,7 @@ module GRPC payload = @marshal.call(req) # Fails if status already received begin + @req_view.send_initial_metadata unless @req_view.nil? @call.run_batch(SEND_MESSAGE => payload) rescue GRPC::Core::CallError => e # This is almost definitely caused by a status arriving while still @@ -190,47 +180,45 @@ module GRPC raise e end - # starts the read loop - def start_read_loop(is_client: true) - Thread.new do - GRPC.logger.debug('bidi-read-loop: starting') - begin - count = 0 - # queue the initial read before beginning the loop - loop do - GRPC.logger.debug("bidi-read-loop: #{count}") - count += 1 - batch_result = read_using_run_batch - - # handle the next message - if batch_result.message.nil? - GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}") - - if is_client - batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil) - @call.status = batch_result.status - batch_result.check_status - GRPC.logger.debug("bidi-read-loop: done status #{@call.status}") - end - - @readq.push(END_OF_READS) - GRPC.logger.debug('bidi-read-loop: done reading!') - break + # Provides an enumerator that yields results of remote reads + def read_loop(is_client: true) + return enum_for(:read_loop, + is_client: is_client) unless block_given? + GRPC.logger.debug('bidi-read-loop: starting') + begin + count = 0 + # queue the initial read before beginning the loop + loop do + GRPC.logger.debug("bidi-read-loop: #{count}") + count += 1 + batch_result = read_using_run_batch + + # handle the next message + if batch_result.message.nil? + GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}") + + if is_client + batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil) + @call.status = batch_result.status + batch_result.check_status + GRPC.logger.debug("bidi-read-loop: done status #{@call.status}") end - # push the latest read onto the queue and continue reading - res = @unmarshal.call(batch_result.message) - @readq.push(res) + GRPC.logger.debug('bidi-read-loop: done reading!') + break end - rescue StandardError => e - GRPC.logger.warn('bidi: read-loop failed') - GRPC.logger.warn(e) - @readq.push(e) # let each_queued_msg terminate with this error + + res = @unmarshal.call(batch_result.message) + yield res end - GRPC.logger.debug('bidi-read-loop: finished') - @reads_complete = true - finished + rescue StandardError => e + GRPC.logger.warn('bidi: read-loop failed') + GRPC.logger.warn(e) + raise e end + GRPC.logger.debug('bidi-read-loop: finished') + @reads_complete = true + finished end end end diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb index 9d6bd3bf590..0d7c1f7805e 100644 --- a/src/ruby/lib/grpc/generic/client_stub.rb +++ b/src/ruby/lib/grpc/generic/client_stub.rb @@ -34,7 +34,8 @@ require_relative '../version' module GRPC # rubocop:disable Metrics/ParameterLists - # ClientStub represents an endpoint used to send requests to GRPC servers. + # ClientStub represents a client connection to a gRPC server, and can be used + # to send requests. class ClientStub include Core::StatusCodes include Core::TimeConsts @@ -75,8 +76,9 @@ module GRPC # my_stub = ClientStub.new(example.host.com:50505, # :this_channel_is_insecure) # - # Any arbitrary keyword arguments are treated as channel arguments used to - # configure the RPC connection to the host. + # If a channel_override argument is passed, it will be used as the + # underlying channel. Otherwise, the channel_args argument will be used + # to construct a new underlying channel. # # There are some specific keyword args that are not used to configure the # channel: @@ -91,10 +93,17 @@ module GRPC # # @param host [String] the host the stub connects to # @param creds [Core::ChannelCredentials|Symbol] the channel credentials, or - # :this_channel_is_insecure + # :this_channel_is_insecure, which explicitly indicates that the client + # should be created with an insecure connection. Note: this argument is + # ignored if the channel_override argument is provided. # @param channel_override [Core::Channel] a pre-created channel # @param timeout [Number] the default timeout to use in requests - # @param channel_args [Hash] the channel arguments + # @param propagate_mask [Number] A bitwise combination of flags in + # GRPC::Core::PropagateMasks. Indicates how data should be propagated + # from parent server calls to child client calls if this client is being + # used within a gRPC server. + # @param channel_args [Hash] the channel arguments. Note: this argument is + # ignored if the channel_override argument is provided. def initialize(host, creds, channel_override: nil, timeout: nil, @@ -389,11 +398,11 @@ module GRPC # @param marshal [Function] f(obj)->string that marshals requests # @param unmarshal [Function] f(string)->obj that unmarshals responses # @param deadline [Time] (optional) the time the request should complete + # @param return_op [true|false] return an Operation if true # @param parent [Core::Call] a prior call whose reserved metadata # will be propagated by this one. # @param credentials [Core::CallCredentials] credentials to use when making # the call - # @param return_op [true|false] return an Operation if true # @param metadata [Hash] metadata to be sent to the server # @param blk [Block] when provided, is executed for each response # @return [Enumerator|nil|Operation] as discussed above @@ -430,7 +439,8 @@ module GRPC # @param unmarshal [Function] f(string)->obj that unmarshals responses # @param parent [Grpc::Call] a parent call, available when calls are # made from server - # @param timeout [TimeConst] + # @param credentials [Core::CallCredentials] credentials to use when making + # the call def new_active_call(method, marshal, unmarshal, deadline: nil, parent: nil, diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb index 913f55d0d3b..584fe781698 100644 --- a/src/ruby/lib/grpc/generic/rpc_desc.rb +++ b/src/ruby/lib/grpc/generic/rpc_desc.rb @@ -104,7 +104,14 @@ module GRPC end def assert_arity_matches(mth) - if request_response? || server_streamer? + # A bidi handler function can optionally be passed a second + # call object parameter for access to metadata, cancelling, etc. + if bidi_streamer? + if mth.arity != 2 && mth.arity != 1 + fail arity_error(mth, 2, "should be #{mth.name}(req, call) or " \ + "#{mth.name}(req)") + end + elsif request_response? || server_streamer? if mth.arity != 2 fail arity_error(mth, 2, "should be #{mth.name}(req, call)") end diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index c92a532a500..da0f6503db3 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -31,113 +31,10 @@ require_relative '../grpc' require_relative 'active_call' require_relative 'service' require 'thread' +require 'concurrent' # GRPC contains the General RPC module. module GRPC - # Pool is a simple thread pool. - class Pool - # Default keep alive period is 1s - DEFAULT_KEEP_ALIVE = 1 - - def initialize(size, keep_alive: DEFAULT_KEEP_ALIVE) - fail 'pool size must be positive' unless size > 0 - @jobs = Queue.new - @size = size - @stopped = false - @stop_mutex = Mutex.new # needs to be held when accessing @stopped - @stop_cond = ConditionVariable.new - @workers = [] - @keep_alive = keep_alive - end - - # Returns the number of jobs waiting - def jobs_waiting - @jobs.size - end - - # Runs the given block on the queue with the provided args. - # - # @param args the args passed blk when it is called - # @param blk the block to call - def schedule(*args, &blk) - return if blk.nil? - @stop_mutex.synchronize do - if @stopped - GRPC.logger.warn('did not schedule job, already stopped') - return - end - GRPC.logger.info('schedule another job') - @jobs << [blk, args] - end - end - - # Starts running the jobs in the thread pool. - def start - @stop_mutex.synchronize do - fail 'already stopped' if @stopped - end - until @workers.size == @size.to_i - next_thread = Thread.new do - catch(:exit) do # allows { throw :exit } to kill a thread - loop_execute_jobs - end - remove_current_thread - end - @workers << next_thread - end - end - - # Stops the jobs in the pool - def stop - GRPC.logger.info('stopping, will wait for all the workers to exit') - @workers.size.times { schedule { throw :exit } } - @stop_mutex.synchronize do # wait @keep_alive for works to stop - @stopped = true - @stop_cond.wait(@stop_mutex, @keep_alive) if @workers.size > 0 - end - forcibly_stop_workers - GRPC.logger.info('stopped, all workers are shutdown') - end - - protected - - # Forcibly shutdown any threads that are still alive. - def forcibly_stop_workers - return unless @workers.size > 0 - GRPC.logger.info("forcibly terminating #{@workers.size} worker(s)") - @workers.each do |t| - next unless t.alive? - begin - t.exit - rescue StandardError => e - GRPC.logger.warn('error while terminating a worker') - GRPC.logger.warn(e) - end - end - end - - # removes the threads from workers, and signal when all the - # threads are complete. - def remove_current_thread - @stop_mutex.synchronize do - @workers.delete(Thread.current) - @stop_cond.signal if @workers.size.zero? - end - end - - def loop_execute_jobs - loop do - begin - blk, args = @jobs.pop - blk.call(*args) - rescue StandardError => e - GRPC.logger.warn('Error in worker thread') - GRPC.logger.warn(e) - end - end - end - end - # RpcServer hosts a number of services and makes them available on the # network. class RpcServer @@ -147,11 +44,14 @@ module GRPC def_delegators :@server, :add_http2_port - # Default thread pool size is 3 - DEFAULT_POOL_SIZE = 3 + # Default max size of the thread pool size is 100 + DEFAULT_MAX_POOL_SIZE = 100 + + # Default minimum size of the thread pool is 5 + DEFAULT_MIN_POOL_SIZE = 5 - # Default max_waiting_requests size is 20 - DEFAULT_MAX_WAITING_REQUESTS = 20 + # Default max_waiting_requests size is 60 + DEFAULT_MAX_WAITING_REQUESTS = 60 # Default poll period is 1s DEFAULT_POLL_PERIOD = 1 @@ -172,22 +72,18 @@ module GRPC # The RPC server is configured using keyword arguments. # # There are some specific keyword args used to configure the RpcServer - # instance, however other arbitrary are allowed and when present are used - # to configure the listeninng connection set up by the RpcServer. + # instance. # - # * poll_period: when present, the server polls for new events with this - # period - # - # * pool_size: the size of the thread pool the server uses to run its - # threads - # - # * creds: [GRPC::Core::ServerCredentials] - # the credentials used to secure the server + # * pool_size: the maximum size of the thread pool that the server's + # thread pool can reach. # # * max_waiting_requests: the maximum number of requests that are not # being handled to allow. When this limit is exceeded, the server responds # with not available to new requests # + # * poll_period: when present, the server polls for new events with this + # period + # # * connect_md_proc: # when non-nil is a proc for determining metadata to to send back the client # on receiving an invocation req. The proc signature is: @@ -195,7 +91,8 @@ module GRPC # # * server_args: # A server arguments hash to be passed down to the underlying core server - def initialize(pool_size:DEFAULT_POOL_SIZE, + def initialize(pool_size:DEFAULT_MAX_POOL_SIZE, + min_pool_size:DEFAULT_MIN_POOL_SIZE, max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS, poll_period:DEFAULT_POLL_PERIOD, connect_md_proc:nil, @@ -203,8 +100,12 @@ module GRPC @connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc) @max_waiting_requests = max_waiting_requests @poll_period = poll_period - @pool_size = pool_size - @pool = Pool.new(@pool_size) + + @pool = Concurrent::ThreadPoolExecutor.new( + min_threads: [min_pool_size, pool_size].min, + max_threads: pool_size, + max_queue: max_waiting_requests, + fallback_policy: :discard) @run_cond = ConditionVariable.new @run_mutex = Mutex.new # running_state can take 4 values: :not_started, :running, :stopping, and @@ -225,7 +126,8 @@ module GRPC end deadline = from_relative_time(@poll_period) @server.close(deadline) - @pool.stop + @pool.shutdown + @pool.wait_for_termination end def running_state @@ -322,7 +224,6 @@ module GRPC def run @run_mutex.synchronize do fail 'cannot run without registering services' if rpc_descs.size.zero? - @pool.start @server.start transition_running_state(:running) @run_cond.broadcast @@ -334,13 +235,18 @@ module GRPC # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs def available?(an_rpc) - jobs_count, max = @pool.jobs_waiting, @max_waiting_requests + jobs_count, max = @pool.queue_length, @pool.max_queue GRPC.logger.info("waiting: #{jobs_count}, max: #{max}") - return an_rpc if @pool.jobs_waiting <= @max_waiting_requests + + # remaining capacity for ThreadPoolExecutors is -1 if unbounded + return an_rpc if @pool.remaining_capacity != 0 GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}") noop = proc { |x| x } + + # Create a new active call that knows that metadata hasn't been + # sent yet c = ActiveCall.new(an_rpc.call, noop, noop, an_rpc.deadline, - metadata_received: true) + metadata_received: true, started: false) c.send_status(GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, '') nil end @@ -351,8 +257,11 @@ module GRPC return an_rpc if rpc_descs.key?(mth) GRPC.logger.warn("UNIMPLEMENTED: #{an_rpc}") noop = proc { |x| x } + + # Create a new active call that knows that + # metadata hasn't been sent yet c = ActiveCall.new(an_rpc.call, noop, noop, an_rpc.deadline, - metadata_received: true) + metadata_received: true, started: false) c.send_status(GRPC::Core::StatusCodes::UNIMPLEMENTED, '') nil end @@ -366,7 +275,7 @@ module GRPC break if (!an_rpc.nil?) && an_rpc.call.nil? active_call = new_active_server_call(an_rpc) unless active_call.nil? - @pool.schedule(active_call) do |ac| + @pool.post(active_call) do |ac| c, mth = ac begin rpc_descs[mth].run_server_method(c, rpc_handlers[mth]) @@ -400,17 +309,20 @@ module GRPC unless @connect_md_proc.nil? connect_md = @connect_md_proc.call(an_rpc.method, an_rpc.metadata) end - an_rpc.call.run_batch(SEND_INITIAL_METADATA => connect_md) return nil unless available?(an_rpc) return nil unless implemented?(an_rpc) - # Create the ActiveCall + # Create the ActiveCall. Indicate that metadata hasnt been sent yet. GRPC.logger.info("deadline is #{an_rpc.deadline}; (now=#{Time.now})") rpc_desc = rpc_descs[an_rpc.method.to_sym] - c = ActiveCall.new(an_rpc.call, rpc_desc.marshal_proc, - rpc_desc.unmarshal_proc(:input), an_rpc.deadline, - metadata_received: true) + c = ActiveCall.new(an_rpc.call, + rpc_desc.marshal_proc, + rpc_desc.unmarshal_proc(:input), + an_rpc.deadline, + metadata_received: true, + started: false, + metadata_to_send: connect_md) mth = an_rpc.method.to_sym [c, mth] end diff --git a/src/ruby/lib/grpc/grpc.rb b/src/ruby/lib/grpc/grpc.rb index b60a828d666..f46710dc742 100644 --- a/src/ruby/lib/grpc/grpc.rb +++ b/src/ruby/lib/grpc/grpc.rb @@ -28,7 +28,12 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. begin - require_relative "#{RUBY_VERSION.sub(/\.\d$/, '')}/grpc_c" -rescue LoadError - require_relative 'grpc_c' + ruby_version_dirname = /(\d+\.\d+)/.match(RUBY_VERSION).to_s + distrib_lib_dir = File.expand_path(ruby_version_dirname, + File.dirname(__FILE__)) + if File.directory?(distrib_lib_dir) + require_relative "#{distrib_lib_dir}/grpc_c" + else + require_relative 'grpc_c' + end end diff --git a/src/ruby/pb/grpc/health/checker.rb b/src/ruby/pb/grpc/health/checker.rb index f7310d92894..4bce1744c48 100644 --- a/src/ruby/pb/grpc/health/checker.rb +++ b/src/ruby/pb/grpc/health/checker.rb @@ -28,7 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. require 'grpc' -require 'grpc/health/v1/health_services' +require 'grpc/health/v1/health_services_pb' require 'thread' module Grpc diff --git a/src/ruby/pb/grpc/health/v1/health.rb b/src/ruby/pb/grpc/health/v1/health_pb.rb similarity index 100% rename from src/ruby/pb/grpc/health/v1/health.rb rename to src/ruby/pb/grpc/health/v1/health_pb.rb diff --git a/src/ruby/pb/grpc/health/v1/health_services.rb b/src/ruby/pb/grpc/health/v1/health_services_pb.rb similarity index 98% rename from src/ruby/pb/grpc/health/v1/health_services.rb rename to src/ruby/pb/grpc/health/v1/health_services_pb.rb index 68a3956f54a..8cc01e91dc5 100644 --- a/src/ruby/pb/grpc/health/v1/health_services.rb +++ b/src/ruby/pb/grpc/health/v1/health_services_pb.rb @@ -32,7 +32,7 @@ # require 'grpc' -require 'grpc/health/v1/health' +require 'grpc/health/v1/health_pb' module Grpc module Health diff --git a/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb b/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb similarity index 93% rename from src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb rename to src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb index eb523ffa6f0..e51c2f087a0 100644 --- a/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb +++ b/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb @@ -1,5 +1,5 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# Source: grpc/testing/duplicate/echo_duplicate.proto for package 'grpc.testing.duplicate' +# Source: src/proto/grpc/testing/duplicate/echo_duplicate.proto for package 'grpc.testing.duplicate' # Original file comments: # Copyright 2015, Google Inc. # All rights reserved. @@ -34,7 +34,7 @@ # require 'grpc' -require 'grpc/testing/duplicate/echo_duplicate' +require 'src/proto/grpc/testing/duplicate/echo_duplicate_pb' module Grpc module Testing diff --git a/src/ruby/pb/grpc/testing/metrics.rb b/src/ruby/pb/grpc/testing/metrics_pb.rb similarity index 94% rename from src/ruby/pb/grpc/testing/metrics.rb rename to src/ruby/pb/grpc/testing/metrics_pb.rb index 3b3c8cd61bb..77b6c90970f 100644 --- a/src/ruby/pb/grpc/testing/metrics.rb +++ b/src/ruby/pb/grpc/testing/metrics_pb.rb @@ -1,5 +1,5 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# source: grpc/testing/metrics.proto +# source: src/proto/grpc/testing/metrics.proto require 'google/protobuf' diff --git a/src/ruby/pb/grpc/testing/metrics_services.rb b/src/ruby/pb/grpc/testing/metrics_services_pb.rb similarity index 95% rename from src/ruby/pb/grpc/testing/metrics_services.rb rename to src/ruby/pb/grpc/testing/metrics_services_pb.rb index 467b7b3ee50..e46366b1fbe 100644 --- a/src/ruby/pb/grpc/testing/metrics_services.rb +++ b/src/ruby/pb/grpc/testing/metrics_services_pb.rb @@ -1,5 +1,5 @@ # Generated by the protocol buffer compiler. DO NOT EDIT! -# Source: grpc/testing/metrics.proto for package 'grpc.testing' +# Source: src/proto/grpc/testing/metrics.proto for package 'grpc.testing' # Original file comments: # Copyright 2015-2016, Google Inc. # All rights reserved. @@ -38,7 +38,7 @@ # service. require 'grpc' -require 'grpc/testing/metrics' +require 'src/proto/grpc/testing/metrics_pb' module Grpc module Testing diff --git a/src/ruby/pb/src/proto/grpc/testing/empty.rb b/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb similarity index 100% rename from src/ruby/pb/src/proto/grpc/testing/empty.rb rename to src/ruby/pb/src/proto/grpc/testing/empty_pb.rb diff --git a/src/ruby/pb/src/proto/grpc/testing/messages.rb b/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb similarity index 100% rename from src/ruby/pb/src/proto/grpc/testing/messages.rb rename to src/ruby/pb/src/proto/grpc/testing/messages_pb.rb diff --git a/src/ruby/pb/src/proto/grpc/testing/test.rb b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb similarity index 72% rename from src/ruby/pb/src/proto/grpc/testing/test.rb rename to src/ruby/pb/src/proto/grpc/testing/test_pb.rb index 245b5ce00cd..2cc98630314 100644 --- a/src/ruby/pb/src/proto/grpc/testing/test.rb +++ b/src/ruby/pb/src/proto/grpc/testing/test_pb.rb @@ -3,8 +3,8 @@ require 'google/protobuf' -require 'src/proto/grpc/testing/empty' -require 'src/proto/grpc/testing/messages' +require 'src/proto/grpc/testing/empty_pb' +require 'src/proto/grpc/testing/messages_pb' Google::Protobuf::DescriptorPool.generated_pool.build do end diff --git a/src/ruby/pb/src/proto/grpc/testing/test_services.rb b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb similarity index 99% rename from src/ruby/pb/src/proto/grpc/testing/test_services.rb rename to src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb index 2652de5e6d2..fde328e4c5d 100644 --- a/src/ruby/pb/src/proto/grpc/testing/test_services.rb +++ b/src/ruby/pb/src/proto/grpc/testing/test_services_pb.rb @@ -35,7 +35,7 @@ # require 'grpc' -require 'src/proto/grpc/testing/test' +require 'src/proto/grpc/testing/test_pb' module Grpc module Testing diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb index 4c6d441dcb6..1e3ae656302 100755 --- a/src/ruby/pb/test/client.rb +++ b/src/ruby/pb/test/client.rb @@ -52,9 +52,9 @@ require_relative '../../lib/grpc' require 'googleauth' require 'google/protobuf' -require_relative '../src/proto/grpc/testing/empty' -require_relative '../src/proto/grpc/testing/messages' -require_relative '../src/proto/grpc/testing/test_services' +require_relative '../src/proto/grpc/testing/empty_pb' +require_relative '../src/proto/grpc/testing/messages_pb' +require_relative '../src/proto/grpc/testing/test_services_pb' AUTH_ENV = Google::Auth::CredentialsLoader::ENV_VAR diff --git a/src/ruby/pb/test/server.rb b/src/ruby/pb/test/server.rb index 11ee3d465d8..0808121661c 100755 --- a/src/ruby/pb/test/server.rb +++ b/src/ruby/pb/test/server.rb @@ -50,9 +50,9 @@ require 'optparse' require 'grpc' -require_relative '../src/proto/grpc/testing/empty' -require_relative '../src/proto/grpc/testing/messages' -require_relative '../src/proto/grpc/testing/test_services' +require_relative '../src/proto/grpc/testing/empty_pb' +require_relative '../src/proto/grpc/testing/messages_pb' +require_relative '../src/proto/grpc/testing/test_services_pb' # DebugIsTruncated extends the default Logger to truncate debug messages class DebugIsTruncated < Logger diff --git a/src/ruby/qps/client.rb b/src/ruby/qps/client.rb index 917b01271e8..7ed648acefc 100644 --- a/src/ruby/qps/client.rb +++ b/src/ruby/qps/client.rb @@ -38,7 +38,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) require 'grpc' require 'histogram' -require 'src/proto/grpc/testing/services_services' +require 'src/proto/grpc/testing/services_services_pb' class Poisson def interarrival diff --git a/src/ruby/qps/server.rb b/src/ruby/qps/server.rb index 52a89ce847c..cd98ee1fd94 100644 --- a/src/ruby/qps/server.rb +++ b/src/ruby/qps/server.rb @@ -38,9 +38,9 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) require 'grpc' require 'qps-common' -require 'src/proto/grpc/testing/messages' -require 'src/proto/grpc/testing/services_services' -require 'src/proto/grpc/testing/stats' +require 'src/proto/grpc/testing/messages_pb' +require 'src/proto/grpc/testing/services_services_pb' +require 'src/proto/grpc/testing/stats_pb' class BenchmarkServiceImpl < Grpc::Testing::BenchmarkService::Service def unary_call(req, _call) diff --git a/src/ruby/qps/src/proto/grpc/testing/control.rb b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb similarity index 97% rename from src/ruby/qps/src/proto/grpc/testing/control.rb rename to src/ruby/qps/src/proto/grpc/testing/control_pb.rb index 958fca320bc..02207a2b5d8 100644 --- a/src/ruby/qps/src/proto/grpc/testing/control.rb +++ b/src/ruby/qps/src/proto/grpc/testing/control_pb.rb @@ -3,8 +3,8 @@ require 'google/protobuf' -require 'src/proto/grpc/testing/payloads' -require 'src/proto/grpc/testing/stats' +require 'src/proto/grpc/testing/payloads_pb' +require 'src/proto/grpc/testing/stats_pb' Google::Protobuf::DescriptorPool.generated_pool.build do add_message "grpc.testing.PoissonParams" do optional :offered_load, :double, 1 @@ -109,6 +109,8 @@ Google::Protobuf::DescriptorPool.generated_pool.build do repeated :server_stats, :message, 4, "grpc.testing.ServerStats" repeated :server_cores, :int32, 5 optional :summary, :message, 6, "grpc.testing.ScenarioResultSummary" + repeated :client_success, :bool, 7 + repeated :server_success, :bool, 8 end add_enum "grpc.testing.ClientType" do value :SYNC_CLIENT, 0 diff --git a/src/ruby/qps/src/proto/grpc/testing/messages.rb b/src/ruby/qps/src/proto/grpc/testing/messages_pb.rb similarity index 100% rename from src/ruby/qps/src/proto/grpc/testing/messages.rb rename to src/ruby/qps/src/proto/grpc/testing/messages_pb.rb diff --git a/src/ruby/qps/src/proto/grpc/testing/payloads.rb b/src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb similarity index 100% rename from src/ruby/qps/src/proto/grpc/testing/payloads.rb rename to src/ruby/qps/src/proto/grpc/testing/payloads_pb.rb diff --git a/src/ruby/qps/src/proto/grpc/testing/services.rb b/src/ruby/qps/src/proto/grpc/testing/services_pb.rb similarity index 72% rename from src/ruby/qps/src/proto/grpc/testing/services.rb rename to src/ruby/qps/src/proto/grpc/testing/services_pb.rb index b2675c2afe5..5ce13bf8b04 100644 --- a/src/ruby/qps/src/proto/grpc/testing/services.rb +++ b/src/ruby/qps/src/proto/grpc/testing/services_pb.rb @@ -3,8 +3,8 @@ require 'google/protobuf' -require 'src/proto/grpc/testing/messages' -require 'src/proto/grpc/testing/control' +require 'src/proto/grpc/testing/messages_pb' +require 'src/proto/grpc/testing/control_pb' Google::Protobuf::DescriptorPool.generated_pool.build do end diff --git a/src/ruby/qps/src/proto/grpc/testing/services_services.rb b/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb similarity index 98% rename from src/ruby/qps/src/proto/grpc/testing/services_services.rb rename to src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb index 94b9a1e164e..bdbb9c86d00 100644 --- a/src/ruby/qps/src/proto/grpc/testing/services_services.rb +++ b/src/ruby/qps/src/proto/grpc/testing/services_services_pb.rb @@ -34,7 +34,7 @@ # of unary/streaming requests/responses. require 'grpc' -require 'src/proto/grpc/testing/services' +require 'src/proto/grpc/testing/services_pb' module Grpc module Testing diff --git a/src/ruby/qps/src/proto/grpc/testing/stats.rb b/src/ruby/qps/src/proto/grpc/testing/stats_pb.rb similarity index 100% rename from src/ruby/qps/src/proto/grpc/testing/stats.rb rename to src/ruby/qps/src/proto/grpc/testing/stats_pb.rb diff --git a/src/ruby/qps/worker.rb b/src/ruby/qps/worker.rb index 665fb863526..12b8087ca05 100755 --- a/src/ruby/qps/worker.rb +++ b/src/ruby/qps/worker.rb @@ -44,7 +44,7 @@ require 'facter' require 'client' require 'qps-common' require 'server' -require 'src/proto/grpc/testing/services_services' +require 'src/proto/grpc/testing/services_services_pb' class WorkerServiceImpl < Grpc::Testing::WorkerService::Service def cpu_cores diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb index 018580e0dfa..48bc61e494f 100644 --- a/src/ruby/spec/generic/active_call_spec.rb +++ b/src/ruby/spec/generic/active_call_spec.rb @@ -60,8 +60,10 @@ describe GRPC::ActiveCall do end describe '#multi_req_view' do - it 'exposes a fixed subset of the ActiveCall methods' do - want = %w(cancelled?, deadline, each_remote_read, metadata, shutdown) + it 'exposes a fixed subset of the ActiveCall.methods' do + want = %w(cancelled?, deadline, each_remote_read, metadata, \ + shutdown, peer, peer_cert, send_initial_metadata, \ + initial_metadata_sent) v = @client_call.multi_req_view want.each do |w| expect(v.methods.include?(w)) @@ -70,8 +72,10 @@ describe GRPC::ActiveCall do end describe '#single_req_view' do - it 'exposes a fixed subset of the ActiveCall methods' do - want = %w(cancelled?, deadline, metadata, shutdown) + it 'exposes a fixed subset of the ActiveCall.methods' do + want = %w(cancelled?, deadline, metadata, shutdown, \ + send_initial_metadata, metadata_to_send, \ + merge_metadata_to_send, initial_metadata_sent) v = @client_call.single_req_view want.each do |w| expect(v.methods.include?(w)) @@ -149,6 +153,146 @@ describe GRPC::ActiveCall do end end + describe 'sending initial metadata', send_initial_metadata: true do + it 'sends metadata before sending a message if it hasnt been sent yet' do + call = make_test_call + @client_call = ActiveCall.new( + call, + @pass_through, + @pass_through, + deadline, + started: false) + + metadata = { key: 'dummy_val', other: 'other_val' } + expect(@client_call.metadata_sent).to eq(false) + @client_call.merge_metadata_to_send(metadata) + + message = 'dummy message' + + expect(call).to( + receive(:run_batch) + .with( + hash_including( + CallOps::SEND_INITIAL_METADATA => metadata)).once) + + expect(call).to( + receive(:run_batch).with(hash_including( + CallOps::SEND_MESSAGE => message)).once) + @client_call.remote_send(message) + + expect(@client_call.metadata_sent).to eq(true) + end + + it 'doesnt send metadata if it thinks its already been sent' do + call = make_test_call + + @client_call = ActiveCall.new(call, + @pass_through, + @pass_through, + deadline) + + expect(@client_call.metadata_sent).to eql(true) + expect(call).to( + receive(:run_batch).with(hash_including( + CallOps::SEND_INITIAL_METADATA)).never) + + @client_call.remote_send('test message') + end + + it 'sends metadata if it is explicitly sent and ok to do so' do + call = make_test_call + + @client_call = ActiveCall.new(call, + @pass_through, + @pass_through, + deadline, + started: false) + + expect(@client_call.metadata_sent).to eql(false) + + metadata = { test_key: 'val' } + @client_call.merge_metadata_to_send(metadata) + expect(@client_call.metadata_to_send).to eq(metadata) + + expect(call).to( + receive(:run_batch).with(hash_including( + CallOps::SEND_INITIAL_METADATA => + metadata)).once) + @client_call.send_initial_metadata + end + + it 'explicit sending does nothing if metadata has already been sent' do + call = make_test_call + + @client_call = ActiveCall.new(call, + @pass_through, + @pass_through, + deadline) + + expect(@client_call.metadata_sent).to eql(true) + + blk = proc do + @client_call.send_initial_metadata + end + + expect { blk.call }.to_not raise_error + end + end + + describe '#merge_metadata_to_send', merge_metadata_to_send: true do + it 'adds to existing metadata when there is existing metadata to send' do + call = make_test_call + starting_metadata = { + k1: 'key1_val', + k2: 'key2_val', + k3: 'key3_val' + } + + @client_call = ActiveCall.new( + call, + @pass_through, @pass_through, + deadline, + started: false, + metadata_to_send: starting_metadata) + + expect(@client_call.metadata_to_send).to eq(starting_metadata) + + @client_call.merge_metadata_to_send( + k3: 'key3_new_val', + k4: 'key4_val') + + expected_md_to_send = { + k1: 'key1_val', + k2: 'key2_val', + k3: 'key3_new_val', + k4: 'key4_val' } + + expect(@client_call.metadata_to_send).to eq(expected_md_to_send) + + @client_call.merge_metadata_to_send(k5: 'key5_val') + expected_md_to_send.merge!(k5: 'key5_val') + expect(@client_call.metadata_to_send).to eq(expected_md_to_send) + end + + it 'fails when initial metadata has already been sent' do + call = make_test_call + @client_call = ActiveCall.new( + call, + @pass_through, + @pass_through, + deadline, + started: true) + + expect(@client_call.metadata_sent).to eq(true) + + blk = proc do + @client_call.merge_metadata_to_send(k1: 'key1_val') + end + + expect { blk.call }.to raise_error + end + end + describe '#client_invoke' do it 'sends metadata to the server when present' do call = make_test_call @@ -163,7 +307,26 @@ describe GRPC::ActiveCall do end end - describe '#remote_read' do + describe '#send_status', send_status: true do + it 'works when no metadata or messages have been sent yet' do + call = make_test_call + ActiveCall.client_invoke(call) + + recvd_rpc = @server.request_call + server_call = ActiveCall.new( + recvd_rpc.call, + @pass_through, + @pass_through, + deadline, + started: false) + + expect(server_call.metadata_sent).to eq(false) + blk = proc { server_call.send_status(OK) } + expect { blk.call }.to_not raise_error + end + end + + describe '#remote_read', remote_read: true do it 'reads the response sent by a server' do call = make_test_call ActiveCall.client_invoke(call) @@ -205,6 +368,31 @@ describe GRPC::ActiveCall do expect(client_call.metadata).to eq(expected) end + it 'get a status from server when nothing else sent from server' do + client_call = make_test_call + ActiveCall.client_invoke(client_call) + + recvd_rpc = @server.request_call + recvd_call = recvd_rpc.call + + server_call = ActiveCall.new( + recvd_call, + @pass_through, + @pass_through, + deadline, + started: false) + + server_call.send_status(OK, 'OK') + + # Check that we can receive initial metadata and a status + client_call.run_batch( + CallOps::RECV_INITIAL_METADATA => nil) + batch_result = client_call.run_batch( + CallOps::RECV_STATUS_ON_CLIENT => nil) + + expect(batch_result.status.code).to eq(OK) + end + it 'get a nil msg before a status when an OK status is sent' do call = make_test_call ActiveCall.client_invoke(call) @@ -329,6 +517,86 @@ describe GRPC::ActiveCall do end end + # Test sending of the initial metadata in #run_server_bidi + # from the server handler both implicitly and explicitly. + describe '#run_server_bidi metadata sending tests', run_server_bidi: true do + before(:each) do + @requests = ['first message', 'second message'] + @server_to_client_metadata = { 'test_key' => 'test_val' } + @server_status = OK + + @client_call = make_test_call + @client_call.run_batch(CallOps::SEND_INITIAL_METADATA => {}) + + recvd_rpc = @server.request_call + recvd_call = recvd_rpc.call + @server_call = ActiveCall.new( + recvd_call, + @pass_through, + @pass_through, + deadline, + metadata_received: true, + started: false, + metadata_to_send: @server_to_client_metadata) + end + + after(:each) do + # Send the requests and send a close so the server can send a status + @requests.each do |message| + @client_call.run_batch(CallOps::SEND_MESSAGE => message) + end + @client_call.run_batch(CallOps::SEND_CLOSE_FROM_CLIENT => nil) + + @server_thread.join + + # Expect that initial metadata was sent, + # the requests were echoed, and a status was sent + batch_result = @client_call.run_batch( + CallOps::RECV_INITIAL_METADATA => nil) + expect(batch_result.metadata).to eq(@server_to_client_metadata) + + @requests.each do |message| + batch_result = @client_call.run_batch( + CallOps::RECV_MESSAGE => nil) + expect(batch_result.message).to eq(message) + end + + batch_result = @client_call.run_batch( + CallOps::RECV_STATUS_ON_CLIENT => nil) + expect(batch_result.status.code).to eq(@server_status) + end + + it 'sends the initial metadata implicitly if not already sent' do + # Server handler that doesn't have access to a "call" + # It echoes the requests + fake_gen_each_reply_with_no_call_param = proc do |msgs| + msgs + end + + @server_thread = Thread.new do + @server_call.run_server_bidi( + fake_gen_each_reply_with_no_call_param) + @server_call.send_status(@server_status) + end + end + + it 'sends the metadata when sent explicitly and not already sent' do + # Fake server handler that has access to a "call" object and + # uses it to explicitly update and send the initial metadata + fake_gen_each_reply_with_call_param = proc do |msgs, call_param| + call_param.merge_metadata_to_send(@server_to_client_metadata) + call_param.send_initial_metadata + msgs + end + + @server_thread = Thread.new do + @server_call.run_server_bidi( + fake_gen_each_reply_with_call_param) + @server_call.send_status(@server_status) + end + end + end + def expect_server_to_receive(sent_text, **kw) c = expect_server_to_be_invoked(**kw) expect(c.remote_read).to eq(sent_text) diff --git a/src/ruby/spec/generic/rpc_desc_spec.rb b/src/ruby/spec/generic/rpc_desc_spec.rb index d2080b7ca2d..1a895005bc3 100644 --- a/src/ruby/spec/generic/rpc_desc_spec.rb +++ b/src/ruby/spec/generic/rpc_desc_spec.rb @@ -196,6 +196,9 @@ describe GRPC::RpcDesc do def fake_svstream(_arg1, _arg2) end + def fake_three_args(_arg1, _arg2, _arg3) + end + it 'raises when a request_response does not have 2 args' do [:fake_clstream, :no_arg].each do |mth| blk = proc do @@ -244,8 +247,8 @@ describe GRPC::RpcDesc do expect(&blk).to_not raise_error end - it 'raises when a bidi streamer does not have 1 arg' do - [:fake_svstream, :no_arg].each do |mth| + it 'raises when a bidi streamer does not have 1 or 2 args' do + [:fake_three_args, :no_arg].each do |mth| blk = proc do @bidi_streamer.assert_arity_matches(method(mth)) end @@ -259,6 +262,13 @@ describe GRPC::RpcDesc do end expect(&blk).to_not raise_error end + + it 'passes when a bidi streamer has 2 args' do + blk = proc do + @bidi_streamer.assert_arity_matches(method(:fake_svstream)) + end + expect(&blk).to_not raise_error + end end describe '#request_response?' do diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb deleted file mode 100644 index b67008de486..00000000000 --- a/src/ruby/spec/generic/rpc_server_pool_spec.rb +++ /dev/null @@ -1,138 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'grpc' - -describe GRPC::Pool do - Pool = GRPC::Pool - - describe '#new' do - it 'raises if a non-positive size is used' do - expect { Pool.new(0) }.to raise_error - expect { Pool.new(-1) }.to raise_error - expect { Pool.new(Object.new) }.to raise_error - end - - it 'is constructed OK with a positive size' do - expect { Pool.new(1) }.not_to raise_error - end - end - - describe '#jobs_waiting' do - it 'at start, it is zero' do - p = Pool.new(1) - expect(p.jobs_waiting).to be(0) - end - - it 'it increases, with each scheduled job if the pool is not running' do - p = Pool.new(1) - job = proc {} - expect(p.jobs_waiting).to be(0) - 5.times do |i| - p.schedule(&job) - expect(p.jobs_waiting).to be(i + 1) - end - end - - it 'it decreases as jobs are run' do - p = Pool.new(1) - job = proc {} - expect(p.jobs_waiting).to be(0) - 3.times do - p.schedule(&job) - end - p.start - sleep 2 - expect(p.jobs_waiting).to be(0) - end - end - - describe '#schedule' do - it 'return if the pool is already stopped' do - p = Pool.new(1) - p.stop - job = proc {} - expect { p.schedule(&job) }.to_not raise_error - end - - it 'adds jobs that get run by the pool' do - p = Pool.new(1) - p.start - o, q = Object.new, Queue.new - job = proc { q.push(o) } - p.schedule(&job) - expect(q.pop).to be(o) - p.stop - end - end - - describe '#stop' do - it 'works when there are no scheduled tasks' do - p = Pool.new(1) - expect { p.stop }.not_to raise_error - end - - it 'stops jobs when there are long running jobs' do - p = Pool.new(1) - p.start - o, q = Object.new, Queue.new - job = proc do - sleep(5) # long running - q.push(o) - end - p.schedule(&job) - sleep(1) # should ensure the long job gets scheduled - expect { p.stop }.not_to raise_error - end - end - - describe '#start' do - it 'runs pre-scheduled jobs' do - p = Pool.new(2) - o, q = Object.new, Queue.new - n = 5 # arbitrary - n.times { p.schedule(o, &q.method(:push)) } - p.start - n.times { expect(q.pop).to be(o) } - p.stop - end - - it 'runs jobs as they are scheduled ' do - p = Pool.new(2) - o, q = Object.new, Queue.new - p.start - n = 5 # arbitrary - n.times do - p.schedule(o, &q.method(:push)) - expect(q.pop).to be(o) - end - p.stop - end - end -end diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index 31157cf161e..d362e48deee 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -395,9 +395,9 @@ describe GRPC::RpcServer do it 'should return RESOURCE_EXHAUSTED on too many jobs', server: true do opts = { server_args: { a_channel_arg: 'an_arg' }, - pool_size: 1, + pool_size: 2, poll_period: 1, - max_waiting_requests: 0 + max_waiting_requests: 1 } alt_srv = RpcServer.new(**opts) alt_srv.handle(SlowService) @@ -406,24 +406,23 @@ describe GRPC::RpcServer do t = Thread.new { alt_srv.run } alt_srv.wait_till_running req = EchoMsg.new - n = 5 # arbitrary, use as many to ensure the server pool is exceeded + n = 20 # arbitrary, use as many to ensure the server pool is exceeded threads = [] - one_failed_as_unavailable = false + bad_status_code = nil n.times do threads << Thread.new do stub = SlowStub.new(alt_host, :this_channel_is_insecure) begin stub.an_rpc(req) rescue GRPC::BadStatus => e - one_failed_as_unavailable = - e.code == StatusCodes::RESOURCE_EXHAUSTED + bad_status_code = e.code end end end threads.each(&:join) alt_srv.stop t.join - expect(one_failed_as_unavailable).to be(true) + expect(bad_status_code).to be(StatusCodes::RESOURCE_EXHAUSTED) end end diff --git a/src/ruby/spec/pb/duplicate/codegen_spec.rb b/src/ruby/spec/pb/duplicate/codegen_spec.rb index 54c136c5102..ea0240965ca 100644 --- a/src/ruby/spec/pb/duplicate/codegen_spec.rb +++ b/src/ruby/spec/pb/duplicate/codegen_spec.rb @@ -44,7 +44,7 @@ describe 'Ping protobuf code generation' do # Get the current content service_path = File.join(root_dir, 'src', 'ruby', 'pb', 'grpc', 'testing', 'duplicate', - 'echo_duplicate_services.rb') + 'echo_duplicate_services_pb.rb') want = nil File.open(service_path) { |f| want = f.read } @@ -54,7 +54,7 @@ describe 'Ping protobuf code generation' do got = nil Dir.mktmpdir do |tmp_dir| gen_out = File.join(tmp_dir, 'src', 'proto', 'grpc', 'testing', - 'duplicate', 'echo_duplicate_services.rb') + 'duplicate', 'echo_duplicate_services_pb.rb') pid = spawn( 'protoc', '-I.', diff --git a/src/ruby/spec/pb/health/checker_spec.rb b/src/ruby/spec/pb/health/checker_spec.rb index de11c9fedf7..1b2fa968271 100644 --- a/src/ruby/spec/pb/health/checker_spec.rb +++ b/src/ruby/spec/pb/health/checker_spec.rb @@ -28,7 +28,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. require 'grpc' -require 'grpc/health/v1/health' +require 'grpc/health/v1/health_pb' require 'grpc/health/checker' require 'open3' require 'tmpdir' @@ -43,7 +43,7 @@ describe 'Health protobuf code generation' do skip 'protoc || grpc_ruby_plugin missing, cannot verify health code-gen' else it 'should already be loaded indirectly i.e, used by the other specs' do - expect(require('grpc/health/v1/health_services')).to be(false) + expect(require('grpc/health/v1/health_services_pb')).to be(false) end it 'should have the same content as created by code generation' do @@ -52,7 +52,7 @@ describe 'Health protobuf code generation' do # Get the current content service_path = File.join(root_dir, 'ruby', 'pb', 'grpc', - 'health', 'v1', 'health_services.rb') + 'health', 'v1', 'health_services_pb.rb') want = nil File.open(service_path) { |f| want = f.read } @@ -62,7 +62,7 @@ describe 'Health protobuf code generation' do got = nil Dir.mktmpdir do |tmp_dir| gen_out = File.join(tmp_dir, 'grpc', 'health', 'v1', - 'health_services.rb') + 'health_services_pb.rb') pid = spawn( 'protoc', '-I.', diff --git a/src/ruby/stress/metrics_server.rb b/src/ruby/stress/metrics_server.rb index 13638c4d211..2b7f78577d9 100644 --- a/src/ruby/stress/metrics_server.rb +++ b/src/ruby/stress/metrics_server.rb @@ -27,8 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -require_relative '../pb/grpc/testing/metrics.rb' -require_relative '../pb/grpc/testing/metrics_services.rb' +require_relative '../pb/grpc/testing/metrics_pb.rb' +require_relative '../pb/grpc/testing/metrics_services_pb.rb' class Gauge def get_name diff --git a/src/ruby/tools/bin/grpc_tools_ruby_protoc b/src/ruby/tools/bin/grpc_tools_ruby_protoc new file mode 100755 index 00000000000..dab06e7958d --- /dev/null +++ b/src/ruby/tools/bin/grpc_tools_ruby_protoc @@ -0,0 +1,48 @@ +#!/usr/bin/env ruby +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +require 'rbconfig' + +require_relative '../os_check' + +ext = RbConfig::CONFIG['EXEEXT'] + +protoc_name = 'protoc' + ext + +plugin_name = 'grpc_ruby_plugin' + ext + +protoc_dir = File.join(File.dirname(__FILE__), + RbConfig::CONFIG['host_cpu'] + '-' + OS.os_name) + +protoc_path = File.join(protoc_dir, protoc_name) + +plugin_path = File.join(protoc_dir, plugin_name) + +exec([ protoc_path, protoc_path ], "--plugin=protoc-gen-grpc=#{plugin_path}", *ARGV) diff --git a/src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin.rb b/src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin similarity index 100% rename from src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin.rb rename to src/ruby/tools/bin/grpc_tools_ruby_protoc_plugin diff --git a/src/ruby/tools/grpc-tools.gemspec b/src/ruby/tools/grpc-tools.gemspec index 9fa4b66392d..68e2a7a1133 100644 --- a/src/ruby/tools/grpc-tools.gemspec +++ b/src/ruby/tools/grpc-tools.gemspec @@ -18,5 +18,5 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY - s.executables = %w( grpc_tools_ruby_protoc.rb grpc_tools_ruby_protoc_plugin.rb ) + s.executables = %w( grpc_tools_ruby_protoc grpc_tools_ruby_protoc_plugin ) end diff --git a/summerofcode/2016/siddharth_shukla.md b/summerofcode/2016/siddharth_shukla.md new file mode 100644 index 00000000000..d753d8b82be --- /dev/null +++ b/summerofcode/2016/siddharth_shukla.md @@ -0,0 +1,65 @@ +Project Overview +================ +The project, titled 'GRPC Python compatibility support', involved +collaborating with the GRPC team to improve the library compatibility +for the GRPC Python library. + +Python is, originally, a specification for a programming language. This +specification has been implemented differently in different +implementations of the [language specification](https://docs.python.org/3/reference/). + +A small, and by no means exhaustive, list of some major python implementations +is: + +- [CPython](https://www.python.org/): The reference implementation +- [Jython](http://www.jython.org/): Python implemented in Java +- [Python for .NET](http://pythonnet.sourceforge.net/): CPython implementation that enables .NET library usage +- [IronPython](http://ironpython.net/): Python implemented in .NET +- [PyPy](http://pypy.org/): Python implemented completely in Python +- [Stackless](https://bitbucket.org/stackless-dev/stackless/wiki/Home): Replaces the dependency for the C call stack with it's own stack + +The development in this project revolved around +introducing changes to the codebase that enable support for latest +stable as well as development releases of the reference implementation +(CPython) of the Python programming language namely `Python 3.4`, +`Python 3.5`,and `Python 3.6` as well as the stable releases of the +PyPy implementation. Special changes were required to enable PyPy +support because PyPy has a non-deterministic garbage collector that does +not rely on reference counting unlike the CPython garbage collector. + +The changes to the codebase involved changes to the library code as well +as changes to the tests and scripts in the test infrastructure which +resulted in both the library as well as the testing infrastructure being +Python 3.x and PyPy compatible. + +The list of merged commits, as of 22.08.2016 23:59 CEST, is summarized +here for the perusal of those interested: + +- [Enable py35 and py36 testing](https://github.com/grpc/grpc/commit/c478214e475e103c5cdf477f0adc18bba2c03903) +- [Make testing toolchain python 3.x compliant](https://github.com/grpc/grpc/commit/0589e533cd65a2ca9e0e610cc1b284d016986572) +- [Add .idea folder to .gitignore](https://github.com/grpc/grpc/commit/365ef40947e22b5438a63f123679ae9a5474c47c) +- [Fix the ThreadPoolExecutor: max_workers can't be 0](https://github.com/grpc/grpc/commit/de84d566b8fad6808e5263a25a17fa231cb5713c) +- [Add PyPy to testing toolchain](https://github.com/grpc/grpc/commit/2135a1b557f8b992186d5317cb767ac4dbcdfe5c) +- [Switch init/shutdown: lib-wide -> per-object](https://github.com/grpc/grpc/commit/9eedb4ffd74aed8d246a07f8007960b2bc167f55) +- [Skip test run if running with pypy](https://github.com/grpc/grpc/commit/f0f58e68738abbc317f7f449c5104f7fbbff26bd) + +The list of unmerged pull requests is as follows: + +- [Add PyPy 5.3.1 to dockerfile and template](https://github.com/grpc/grpc/pull/7763) +- [remove skipIf from TypeSmokeTest (issue 7672)](https://github.com/grpc/grpc/pull/7831) + +The list of tasks that have pending unsubmitted pull requests is as follows: + +- Modify run_tests.py to enable testing of new languages without + affecting old branches. + + +Project Details +=============== +- Title: GRPC Python compatibility support +- Student: [Siddharth Shukla](https://github.com/thunderboltsid) +- Mentors: [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm) +- Duration: May 23 - August 23 +- Hat tip: [Ken Payson](https://github.com/kpayson64), [Jan Tattermusch](https://github.com/jtattermusch), [Nicolas Noble](https://github.com/nicolasnoble) + + diff --git a/templates/BUILD.template b/templates/BUILD.template index 23a656c3608..af23fb27994 100644 --- a/templates/BUILD.template +++ b/templates/BUILD.template @@ -38,6 +38,8 @@ licenses(["notice"]) # 3-clause BSD + exports_files(["LICENSE"]) + package(default_visibility = ["//visibility:public"]) <%! diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template index 52e8b866be1..2b6c0b1a367 100644 --- a/templates/CMakeLists.txt.template +++ b/templates/CMakeLists.txt.template @@ -42,14 +42,16 @@ <%! def get_deps(target_dict): deps = [] + if target_dict.get('baselib', False): + deps.append("${_gRPC_BASELIB_LIBRARIES}") if target_dict.get('build', None) in ['protoc']: - deps.append("libprotoc") + deps.append("${_gRPC_PROTOBUF_PROTOC_LIBRARIES}") if target_dict.get('secure', False): - deps = ["ssl"] + deps.append("${_gRPC_SSL_LIBRARIES}") if target_dict['name'] in ['grpc++', 'grpc++_unsecure', 'grpc++_codegen_lib']: - deps.append("libprotobuf") + deps.append("${_gRPC_PROTOBUF_LIBRARIES}") elif target_dict['name'] in ['grpc']: - deps.append("zlibstatic") + deps.append("${_gRPC_ZLIB_LIBRARIES}") for d in target_dict.get('deps', []): deps.append(d) return deps @@ -64,39 +66,138 @@ set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/") project(<%text>${PACKAGE_NAME} C CXX) - if(NOT BORINGSSL_ROOT_DIR) - set(BORINGSSL_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/boringssl) + if (NOT MSVC) + set(gRPC_INSTALL ON CACHE BOOL "Generate installation target") + else() + set(gRPC_INSTALL OFF CACHE BOOL "Generate installation target") endif() - if(NOT PROTOBUF_ROOT_DIR) - set(PROTOBUF_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf) + + set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library") + set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package") + + set(gRPC_SSL_PROVIDER "module" CACHE STRING "Provider of ssl library") + set_property(CACHE gRPC_SSL_PROVIDER PROPERTY STRINGS "module" "package") + + set(gRPC_PROTOBUF_PROVIDER "module" CACHE STRING "Provider of protobuf library") + set_property(CACHE gRPC_PROTOBUF_PROVIDER PROPERTY STRINGS "module" "package") + + set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library") + + if (MSVC) + add_definitions( -D_WIN32_WINNT=0x600 ) + endif() + + if (gRPC_USE_PROTO_LITE) + set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite") + add_definitions("-DGRPC_USE_PROTO_LITE") + else() + set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf") + endif() + + if("<%text>${gRPC_ZLIB_PROVIDER}" STREQUAL "module") + if(NOT ZLIB_ROOT_DIR) + set(ZLIB_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/zlib) + endif() + set(ZLIB_INCLUDE_DIR "<%text>${ZLIB_ROOT_DIR}") + if(EXISTS "<%text>${ZLIB_ROOT_DIR}/CMakeLists.txt") + add_subdirectory(<%text>${ZLIB_ROOT_DIR} third_party/zlib) + if(TARGET zlibstatic) + set(_gRPC_ZLIB_LIBRARIES zlibstatic) + endif() + else() + message(WARNING "gRPC_ZLIB_PROVIDER is \"module\" but ZLIB_ROOT_DIR is wrong") + endif() + elseif("<%text>${gRPC_ZLIB_PROVIDER}" STREQUAL "package") + find_package(ZLIB) + if(TARGET ZLIB::ZLIB) + set(_gRPC_ZLIB_LIBRARIES ZLIB::ZLIB) + endif() + set(_gRPC_FIND_ZLIB "if(NOT ZLIB_FOUND)\n find_package(ZLIB)\nendif()") endif() - if(NOT ZLIB_ROOT_DIR) - set(ZLIB_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/zlib) + + if("<%text>${gRPC_PROTOBUF_PROVIDER}" STREQUAL "module") + # Building the protobuf tests require gmock what is not part of a standard protobuf checkout. + # Disable them unless they are explicitly requested from the cmake command line (when we assume + # gmock is downloaded to the right location inside protobuf). + if(NOT protobuf_BUILD_TESTS) + set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build protobuf tests") + endif() + if(NOT PROTOBUF_ROOT_DIR) + set(PROTOBUF_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf) + endif() + if(EXISTS "<%text>${PROTOBUF_ROOT_DIR}/cmake/CMakeLists.txt") + set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries") + add_subdirectory(<%text>${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf) + if(TARGET <%text>${_gRPC_PROTOBUF_LIBRARY_NAME}) + set(_gRPC_PROTOBUF_LIBRARIES <%text>${_gRPC_PROTOBUF_LIBRARY_NAME}) + endif() + if(TARGET libprotoc) + set(_gRPC_PROTOBUF_PROTOC_LIBRARIES libprotoc) + endif() + else() + message(WARNING "gRPC_PROTOBUF_PROVIDER is \"module\" but PROTOBUF_ROOT_DIR is wrong") + endif() + elseif("<%text>${gRPC_PROTOBUF_PROVIDER}" STREQUAL "package") + find_package(protobuf CONFIG) + if(protobuf_FOUND) + if(TARGET protobuf::<%text>${_gRPC_PROTOBUF_LIBRARY_NAME}) + set(_gRPC_PROTOBUF_LIBRARIES protobuf::<%text>${_gRPC_PROTOBUF_LIBRARY_NAME}) + endif() + if(TARGET protobuf::libprotoc) + set(_gRPC_PROTOBUF_PROTOC_LIBRARIES protobuf::libprotoc) + endif() + set(_gRPC_FIND_PROTOBUF "if(NOT protobuf_FOUND)\n find_package(protobuf CONFIG)\nendif()") + else() + find_package(Protobuf MODULE) + set(_gRPC_FIND_PROTOBUF "if(NOT Protobuf_FOUND)\n find_package(Protobuf)\nendif()") + endif() + endif() + + if("<%text>${gRPC_SSL_PROVIDER}" STREQUAL "module") + if(NOT BORINGSSL_ROOT_DIR) + set(BORINGSSL_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}/third_party/boringssl) + endif() + if(EXISTS "<%text>${BORINGSSL_ROOT_DIR}/CMakeLists.txt") + add_subdirectory(<%text>${BORINGSSL_ROOT_DIR} third_party/boringssl) + if(TARGET ssl) + set(_gRPC_SSL_LIBRARIES ssl) + endif() + else() + message(WARNING "gRPC_SSL_PROVIDER is \"module\" but BORINGSSL_ROOT_DIR is wrong") + endif() + elseif("<%text>${gRPC_SSL_PROVIDER}" STREQUAL "package") + find_package(OpenSSL) + if(TARGET OpenSSL::SSL) + set(_gRPC_SSL_LIBRARIES OpenSSL::SSL) + endif() + set(_gRPC_FIND_SSL "if(NOT OpenSSL_FOUND)\n find_package(OpenSSL)\nendif()") endif() - # Building the protobuf tests require gmock what is not part of a standard protobuf checkout. - # Disable them unless they are explicitly requested from the cmake command line (when we assume - # gmock is downloaded to the right location inside protobuf). - if(NOT protobuf_BUILD_TESTS) - set(protobuf_BUILD_TESTS OFF CACHE BOOL "Build protobuf tests") + if(NOT MSVC) + set(CMAKE_C_FLAGS "<%text>${CMAKE_C_FLAGS} -std=c11") + set(CMAKE_CXX_FLAGS "<%text>${CMAKE_CXX_FLAGS} -std=c++11") endif() - add_subdirectory(<%text>${BORINGSSL_ROOT_DIR} third_party/boringssl) - add_subdirectory(<%text>${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf) - add_subdirectory(<%text>${ZLIB_ROOT_DIR} third_party/zlib) + if(WIN32 AND MSVC) + set(_gRPC_BASELIB_LIBRARIES wsock32 ws2_32) + endif() - set(CMAKE_C_FLAGS "<%text>${CMAKE_C_FLAGS} -std=c11") - set(CMAKE_CXX_FLAGS "<%text>${CMAKE_CXX_FLAGS} -std=c++11") + include(GNUInstallDirs) + if(NOT DEFINED CMAKE_INSTALL_CMAKEDIR) + set(CMAKE_INSTALL_CMAKEDIR "<%text>${CMAKE_INSTALL_LIBDIR}/cmake/gRPC") + endif() % for lib in libs: % if lib.build in ["all", "protoc", "tool"]: ${cc_library(lib)} + ${cc_install(lib)} % endif % endfor % for tgt in targets: % if tgt.build in ["all", "protoc", "tool"]: ${cc_binary(tgt)} + ${cc_install(tgt)} % endif % endfor @@ -112,7 +213,7 @@ PRIVATE <%text>${CMAKE_CURRENT_SOURCE_DIR}/include PRIVATE <%text>${BORINGSSL_ROOT_DIR}/include PRIVATE <%text>${PROTOBUF_ROOT_DIR}/src - PRIVATE <%text>${ZLIB_ROOT_DIR} + PRIVATE <%text>${ZLIB_INCLUDE_DIR} PRIVATE <%text>${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib ) @@ -123,6 +224,20 @@ % endfor ) % endif + + % if len(lib.get('public_headers', [])) > 0: + foreach(_hdr + % for hdr in lib.get('public_headers', []): + ${hdr} + % endfor + ) + string(REPLACE "include/" "" _path <%text>${_hdr}) + get_filename_component(_path <%text>${_path} PATH) + install(FILES <%text>${_hdr} + DESTINATION "<%text>${CMAKE_INSTALL_INCLUDEDIR}/${_path}" + ) + endforeach() + % endif <%def name="cc_binary(tgt)"> @@ -150,3 +265,27 @@ % endif + <%def name="cc_install(tgt)"> + if (gRPC_INSTALL) + install(TARGETS ${tgt.name} EXPORT gRPCTargets + RUNTIME DESTINATION <%text>${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION <%text>${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION <%text>${CMAKE_INSTALL_LIBDIR} + ) + endif() + + + if (gRPC_INSTALL) + install(EXPORT gRPCTargets + DESTINATION <%text>${CMAKE_INSTALL_CMAKEDIR} + NAMESPACE gRPC:: + ) + endif() + + foreach(_config gRPCConfig gRPCConfigVersion) + configure_file(tools/cmake/<%text>${_config}.cmake.in + <%text>${_config}.cmake @ONLY) + install(FILES <%text>${CMAKE_CURRENT_BINARY_DIR}/${_config}.cmake + DESTINATION <%text>${CMAKE_INSTALL_CMAKEDIR} + ) + endforeach() diff --git a/templates/Makefile.template b/templates/Makefile.template index 0cbd8bfdd55..e6a28d16bce 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -282,6 +282,29 @@ LDFLAGS += -pthread endif + # + # The steps for cross-compiling are as follows: + # First, clone and make install of grpc using the native compilers for the host. + # Also, install protoc (e.g., from a package like apt-get) + # Then clone a fresh grpc for the actual cross-compiled build + # Set the environment variable GRPC_CROSS_COMPILE to true + # Set CC, CXX, LD, LDXX, AR, and STRIP to the cross-compiling binaries + # Also set PROTOBUF_CONFIG_OPTS to indicate cross-compilation to protobuf (e.g., + # PROTOBUF_CONFIG_OPTS="--host=arm-linux --with-protoc=/usr/local/bin/protoc" ) + # Set HAS_PKG_CONFIG=false + # To build tests, go to third_party/gflags and follow its ccmake instructions + # Make sure that you enable building shared libraries and set your prefix to + # something useful like /usr/local/cross + # You will also need to set GRPC_CROSS_LDOPTS and GRPC_CROSS_AROPTS to hold + # additional required arguments for LD and AR (examples below) + # Then you can do a make from the cross-compiling fresh clone! + # + ifeq ($(GRPC_CROSS_COMPILE),true) + LDFLAGS += $(GRPC_CROSS_LDOPTS) # e.g. -L/usr/local/lib -L/usr/local/cross/lib + AROPTS = $(GRPC_CROSS_AROPTS) # e.g., rc --target=elf32-little + USE_BUILT_PROTOC = false + endif + GTEST_LIB = -Ithird_party/googletest/include -Ithird_party/googletest third_party/googletest/src/gtest-all.cc GTEST_LIB += -lgflags ifeq ($(V),1) @@ -357,7 +380,7 @@ OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib - PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0-alpha-3 protobuf + PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf else # HAS_PKG_CONFIG ifeq ($(SYSTEM),MINGW32) @@ -597,6 +620,15 @@ CPPFLAGS := -Ithird_party/googletest/include $(CPPFLAGS) + PROTOC_PLUGINS_ALL =\ + % for tgt in targets: + % if tgt.build == 'protoc': + $(BINDIR)/$(CONFIG)/${tgt.name}\ + % endif + % endfor + + PROTOC_PLUGINS_DIR = $(BINDIR)/$(CONFIG) + ifeq ($(HAS_SYSTEM_PROTOBUF),true) ifeq ($(HAS_PKG_CONFIG),true) PROTOBUF_PKG_CONFIG = true @@ -611,12 +643,19 @@ else PC_LIBS_GRPCXX = -lprotobuf endif + PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) else ifeq ($(HAS_EMBEDDED_PROTOBUF),true) PROTOBUF_DEP = $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a CPPFLAGS := -Ithird_party/protobuf/src $(CPPFLAGS) LDFLAGS := -L$(LIBDIR)/$(CONFIG)/protobuf $(LDFLAGS) + ifneq ($(USE_BUILT_PROTOC),false) PROTOC = $(BINDIR)/$(CONFIG)/protobuf/protoc + PROTOC_PLUGINS = $(PROTOC_PLUGINS_ALL) + else + PROTOC_PLUGINS = + PROTOC_PLUGINS_DIR = $(prefix)/bin + endif else NO_PROTOBUF = true endif @@ -655,22 +694,8 @@ NO_DEPS = true endif - INSTALL_OK = false - ifeq ($(HAS_VALID_PROTOC),true) - ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true) - INSTALL_OK = true - endif - endif - .SECONDARY = %.pb.h %.pb.cc - PROTOC_PLUGINS =\ - % for tgt in targets: - % if tgt.build == 'protoc': - $(BINDIR)/$(CONFIG)/${tgt.name}\ - % endif - % endfor - ifeq ($(DEP_MISSING),) all: static shared plugins\ % for tgt in targets: @@ -792,7 +817,7 @@ $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure $(E) "[MAKE] Building protobuf" - $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static) + $(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g $(PROTOBUF_LDFLAGS_EXTRA)" CPPFLAGS="$(PIC_CPPFLAGS) $(CPPFLAGS_$(CONFIG)) -g $(PROTOBUF_CPPFLAGS_EXTRA)" ./configure --disable-shared --enable-static $(PROTOBUF_CONFIG_OPTS)) $(Q)$(MAKE) -C third_party/protobuf clean $(Q)$(MAKE) -C third_party/protobuf $(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf @@ -1124,7 +1149,7 @@ $(GENDIR)/${p}.grpc.pb.cc: ${p}.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) ${' '.join('$(GENDIR)/%s.pb.cc $(GENDIR)/%s.grpc.pb.cc' % (q,q) for q in proto_deps.get(p, []))} $(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=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $< + $(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(PROTOC_PLUGINS_DIR)/grpc_cpp_plugin $< endif % endfor @@ -1161,7 +1186,7 @@ $(Q) mkdir -p `dirname $@` $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< - install: install_c install_cxx install-plugins install-certs verify-install + install: install_c install_cxx install-plugins install-certs install_c: install-headers_c install-static_c install-shared_c @@ -1279,28 +1304,6 @@ $(Q) $(INSTALL) -d $(prefix)/share/grpc $(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem - verify-install: - ifeq ($(INSTALL_OK),true) - @echo "Your system looks ready to go." - @echo - else - @echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system," - @echo "which means that you won't be able to compile .proto files for use" - @echo "with gRPC." - @echo - @echo "If you are just using pre-compiled protocol buffers, or you otherwise" - @echo "have no need to compile .proto files, you can ignore this." - @echo - @echo "If you do need protobuf for some reason, you can download and install" - @echo "it from:" - @echo - @echo " https://github.com/google/protobuf/releases" - @echo - @echo "Once you've done so, you can re-run this check by doing:" - @echo - @echo " make verify-install" - endif - clean: $(E) "[CLEAN] Cleaning build directories." $(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk @@ -1416,7 +1419,7 @@ $(E) "[AR] Creating $@" $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a - $(Q) $(AR) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) \ + $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) \ % if lib.get('baselib', False): $(LIBGPR_OBJS) \ $(ZLIB_MERGE_OBJS) \ diff --git a/templates/composer.json.template b/templates/composer.json.template index 07ab1f20eba..48d3b8892e2 100644 --- a/templates/composer.json.template +++ b/templates/composer.json.template @@ -9,7 +9,7 @@ "license": "BSD-3-Clause", "require": { "php": ">=5.5.0", - "stanley-cheung/protobuf-php": "dev-master" + "stanley-cheung/protobuf-php": "v0.6" }, "require-dev": { "google/auth": "v0.9" diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template index aefe6e965cc..1d5a47336c5 100644 --- a/templates/gRPC-Core.podspec.template +++ b/templates/gRPC-Core.podspec.template @@ -62,7 +62,7 @@ %> Pod::Spec.new do |s| s.name = 'gRPC-Core' - version = '0.14.0' + version = '1.0.0' s.version = version s.summary = 'Core cross-platform gRPC library, written in C' s.homepage = 'http://www.grpc.io' @@ -71,7 +71,7 @@ s.source = { :git => 'https://github.com/grpc/grpc.git', - :tag => "release-#{version.gsub(/\./, '_')}-objectivec-#{version}", + :tag => "v#{version}", # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules. :submodules => true, } @@ -128,6 +128,8 @@ 'ALWAYS_SEARCH_USER_PATHS' => 'NO', } + s.default_subspecs = 'Interface', 'Implementation' + # Like many other C libraries, gRPC-Core has its public headers under `include//` and its # sources and private headers in other directories outside `include/`. Cocoapods' linter doesn't # allow any header to be listed outside the `header_mappings_dir` (even though doing so works in @@ -147,11 +149,37 @@ ss.header_mappings_dir = '.' ss.libraries = 'z' ss.dependency "#{s.name}/Interface", version - ss.dependency 'BoringSSL', '~> 4.0' + ss.dependency 'BoringSSL', '~> 6.0' # To save you from scrolling, this is the last part of the podspec. ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)} ss.private_header_files = ${ruby_multiline_list(grpc_private_headers(libs), 30)} end + + s.subspec 'Cronet-Interface' do |ss| + ss.header_mappings_dir = 'include/grpc' + ss.source_files = 'include/grpc/grpc_cronet.h' + end + + s.subspec 'Cronet-Implementation' do |ss| + ss.header_mappings_dir = '.' + ss.source_files = 'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c', + 'src/core/ext/transport/cronet/transport/cronet_transport.c' + end + + s.subspec 'Tests' do |ss| + ss.header_mappings_dir = '.' + + ss.source_files = 'test/core/end2end/cq_verifier.{c,h}', + 'test/core/end2end/end2end_tests.{c,h}', + 'test/core/end2end/tests/*.{c,h}', + 'test/core/end2end/data/*.{c,h}', + 'test/core/util/test_config.{c,h}', + 'test/core/util/port.h', + 'test/core/util/port_posix.c', + 'test/core/util/port_server_client.{c,h}' + + ss.dependency 'CronetFramework' + end end diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template index ce775ffb90b..75a6054b81e 100644 --- a/templates/grpc.gemspec.template +++ b/templates/grpc.gemspec.template @@ -29,8 +29,9 @@ s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb ) s.platform = Gem::Platform::RUBY - s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3' + s.add_dependency 'google-protobuf', '~> 3.0' s.add_dependency 'googleauth', '~> 0.5.1' + s.add_dependency 'concurrent-ruby' s.add_development_dependency 'bundler', '~> 1.9' s.add_development_dependency 'facter', '~> 2.4' diff --git a/templates/package.json.template b/templates/package.json.template index f68f64d0475..e9596d4d4cb 100644 --- a/templates/package.json.template +++ b/templates/package.json.template @@ -37,7 +37,7 @@ "devDependencies": { "async": "^1.5.0", "google-auth-library": "^0.9.2", - "google-protobuf": "^3.0.0-alpha.5", + "google-protobuf": "^3.0.0", "istanbul": "^0.3.21", "jsdoc": "^3.3.2", "jshint": "^2.5.0", diff --git a/templates/package.xml.template b/templates/package.xml.template index 153823ece5b..32ed3b633e8 100644 --- a/templates/package.xml.template +++ b/templates/package.xml.template @@ -12,7 +12,7 @@ grpc-packages@google.com yes - 2016-07-13 + 2016-08-22 ${settings.php_version.php()} @@ -24,8 +24,7 @@ BSD - - GA release - - Fix shutdown hang problem #4017 + - Reject metadata keys which are not legal #7881 @@ -206,8 +205,8 @@ - 1.0.0 - 1.0.0 + 1.0.0RC1 + 1.0.0RC1 stable @@ -220,5 +219,80 @@ - Fix shutdown hang problem #4017 + + + 1.0.0RC2 + 1.0.0RC2 + + + stable + stable + + 2016-07-21 + BSD + + - PHP7 Support #7464 + + + + + 1.0.0RC3 + 1.0.0RC3 + + + stable + stable + + 2016-07-28 + BSD + + - PHP7 Support continued, reduce code duplication #7543 + + + + + 1.0.0RC4 + 1.0.0RC4 + + + stable + stable + + 2016-08-09 + BSD + + - Fixed Ubuntu compile error #7571, #7642 + + + + + 1.0.0 + 1.0.0 + + + stable + stable + + 2016-08-18 + BSD + + - gRPC 1.0.0 release + + + + + ${settings.php_version.php()} + ${settings.php_version.php()} + + + stable + stable + + 2016-08-22 + BSD + + - Reject metadata keys which are not legal #7881 + + diff --git a/templates/src/core/lib/surface/version.c.template b/templates/src/core/lib/surface/version.c.template index 5f0273e49df..12c490e6a9d 100644 --- a/templates/src/core/lib/surface/version.c.template +++ b/templates/src/core/lib/surface/version.c.template @@ -32,10 +32,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - + /* This file is autogenerated from: templates/src/core/surface/version.c.template */ - + #include - + const char *grpc_version_string(void) { return "${settings.core_version}"; } + + const char *grpc_g_stands_for(void) { return "${settings.g_stands_for}"; } diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template index d91bd8ce1df..939a0c8d280 100644 --- a/templates/src/csharp/Grpc.Auth/project.json.template +++ b/templates/src/csharp/Grpc.Auth/project.json.template @@ -25,18 +25,13 @@ }, "dependencies": { "Grpc.Core": "${settings.csharp_version}", - "Google.Apis.Auth": "1.11.1" + "Google.Apis.Auth": "1.16.0" }, "frameworks": { "net45": { }, "netstandard1.5": { - "imports": [ - "net45" - ], "dependencies": { - "Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24027", - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Tasks": "4.0.11-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Core.Tests/project.json.template b/templates/src/csharp/Grpc.Core.Tests/project.json.template index bc9fa3e63a9..3452d6b4b02 100644 --- a/templates/src/csharp/Grpc.Core.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Core.Tests/project.json.template @@ -8,16 +8,20 @@ }, "Newtonsoft.Json": "8.0.3", "NUnit": "3.2.0", - "NUnitLite": "3.2.0-*" + "NUnitLite": "3.2.0-*", + "NUnit.ConsoleRunner": "3.2.0", + "OpenCover": "4.6.519", + "ReportGenerator": "2.4.4.0" }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } }, diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template index cdcebc5303d..ed5d6499365 100644 --- a/templates/src/csharp/Grpc.Core/project.json.template +++ b/templates/src/csharp/Grpc.Core/project.json.template @@ -16,12 +16,12 @@ "files": { "mappings": { "build/net45/": "Grpc.Core.targets", - "build/native/bin/windows_x86/": "../nativelibs/windows_x86/grpc_csharp_ext.dll", - "build/native/bin/windows_x64/": "../nativelibs/windows_x64/grpc_csharp_ext.dll", - "build/native/bin/linux_x86/": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", - "build/native/bin/linux_x64/": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", - "build/native/bin/macosx_x86/": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", - "build/native/bin/macosx_x64/": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" + "runtimes/win/native/grpc_csharp_ext.x86.dll": "../nativelibs/windows_x86/grpc_csharp_ext.dll", + "runtimes/win/native/grpc_csharp_ext.x64.dll": "../nativelibs/windows_x64/grpc_csharp_ext.dll", + "runtimes/linux/native/libgrpc_csharp_ext.x86.so": "../nativelibs/linux_x86/libgrpc_csharp_ext.so", + "runtimes/linux/native/libgrpc_csharp_ext.x64.so": "../nativelibs/linux_x64/libgrpc_csharp_ext.so", + "runtimes/osx/native/libgrpc_csharp_ext.x86.dylib": "../nativelibs/macosx_x86/libgrpc_csharp_ext.dylib", + "runtimes/osx/native/libgrpc_csharp_ext.x64.dylib": "../nativelibs/macosx_x64/libgrpc_csharp_ext.dylib" } } }, @@ -33,17 +33,14 @@ "xmlDoc": true }, "dependencies": { - "Ix-Async": "1.2.5" + "System.Interactive.Async": "3.0.0" }, "frameworks": { "net45": { }, "netstandard1.5": { - "imports": [ - "portable-net45" - ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Threading.Thread": "4.0.0-rc2-24027" + "NETStandard.Library": "1.6.0", + "System.Threading.Thread": "4.0.0" } } } diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template index fba401c3a47..f0fc4b97da7 100644 --- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template @@ -9,12 +9,10 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { - "imports": [ - "portable-net45" - ], + "netcoreapp1.0": { "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template index fba401c3a47..f0fc4b97da7 100644 --- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template +++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template @@ -9,12 +9,10 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { - "imports": [ - "portable-net45" - ], + "netcoreapp1.0": { "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Examples.Tests/project.json.template b/templates/src/csharp/Grpc.Examples.Tests/project.json.template index 21765f0565c..af13cb58501 100644 --- a/templates/src/csharp/Grpc.Examples.Tests/project.json.template +++ b/templates/src/csharp/Grpc.Examples.Tests/project.json.template @@ -11,12 +11,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template index 715fc087256..1e79c717101 100644 --- a/templates/src/csharp/Grpc.Examples/project.json.template +++ b/templates/src/csharp/Grpc.Examples/project.json.template @@ -6,7 +6,7 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0-beta3" + "Google.Protobuf": "3.0.0" }, "frameworks": { "net45": { @@ -15,12 +15,10 @@ "System.IO": "" } }, - "netstandard1.5": { - "imports": [ - "portable-net45" - ], + "netcoreapp1.0": { "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template index 79e67226cb4..417b773a428 100644 --- a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template @@ -11,12 +11,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template index 264ed292050..46307dda002 100644 --- a/templates/src/csharp/Grpc.HealthCheck/project.json.template +++ b/templates/src/csharp/Grpc.HealthCheck/project.json.template @@ -25,7 +25,7 @@ }, "dependencies": { "Grpc.Core": "${settings.csharp_version}", - "Google.Protobuf": "3.0.0-beta3" + "Google.Protobuf": "3.0.0" }, "frameworks": { "net45": { @@ -35,11 +35,8 @@ } }, "netstandard1.5": { - "imports": [ - "portable-net45" - ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template index 10ed5493477..40300407ba2 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template @@ -9,13 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template index 10ed5493477..40300407ba2 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template @@ -9,13 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template index 10ed5493477..40300407ba2 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template @@ -9,13 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template index 10ed5493477..40300407ba2 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template @@ -9,13 +9,13 @@ }, "frameworks": { "net45": { }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0" } } } diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template index 31815114857..6a32ddb2f33 100644 --- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template +++ b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template @@ -9,29 +9,27 @@ "Grpc.Core": { "target": "project" }, - "Google.Protobuf": "3.0.0-beta3", - "CommandLineParser": "1.9.71", + "Google.Protobuf": "3.0.0", + "CommandLineParser.Unofficial": "2.0.275", + "Moq": "4.6.38-alpha", "NUnit": "3.2.0", "NUnitLite": "3.2.0-*" }, "frameworks": { "net45": { - "dependencies": { - "Moq": "4.2.1510.2205" - }, "frameworkAssemblies": { "System.Runtime": "", "System.IO": "" } }, - "netstandard1.5": { + "netcoreapp1.0": { "imports": [ - "portable-net45", - "net45" + "portable-net45" ], "dependencies": { - "NETStandard.Library": "1.5.0-rc2-24027", - "System.Linq.Expressions": "4.0.11-rc2-24027" + "Microsoft.NETCore.App": "1.0.0", + "NETStandard.Library": "1.6.0", + "System.Linq.Expressions": "4.1.0" } } } diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include index ae96b94f728..8597ae33675 100644 --- a/templates/src/csharp/build_options.include +++ b/templates/src/csharp/build_options.include @@ -20,10 +20,10 @@ "include": "data/*", % endif "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/dbg/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/dbg/libgrpc_csharp_ext.dylib" } } } @@ -42,18 +42,18 @@ "include": "data/*", % endif "mappings": { - "nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", - "nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", - "nativelibs/linux_x64/libgrpc_csharp_ext.so": "../../../libs/opt/libgrpc_csharp_ext.so", - "nativelibs/macosx_x64/libgrpc_csharp_ext.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" + "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll", + "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll", + "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so", + "libgrpc_csharp_ext.x64.dylib": "../../../libs/opt/libgrpc_csharp_ext.dylib" } } } } }, + %endif "runtimes": { "win7-x64": { }, "debian.8-x64": { }, "osx.10.11-x64": { } }, - % endif \ No newline at end of file diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template index ea2acb661ee..5cbd8e3746d 100644 --- a/templates/src/csharp/build_packages.bat.template +++ b/templates/src/csharp/build_packages.bat.template @@ -33,10 +33,7 @@ @rem Current package versions set VERSION=${settings.csharp_version} - set PROTOBUF_VERSION=3.0.0-beta3 - - @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well. - set VERSION_WITH_BETA=%VERSION%-beta + set PROTOBUF_VERSION=3.0.0 @rem Adjust the location of nuget.exe set NUGET=C:\nuget\nuget.exe @@ -60,7 +57,6 @@ @rem Fetch all dependencies %%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error - %%NUGET% restore Grpc.sln || goto :error setlocal @@ -75,7 +71,7 @@ %%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error %%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error - %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error + %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error %%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error diff --git a/templates/src/node/health_check/package.json.template b/templates/src/node/health_check/package.json.template index 1248ced1e16..c2bb232245d 100644 --- a/templates/src/node/health_check/package.json.template +++ b/templates/src/node/health_check/package.json.template @@ -17,15 +17,15 @@ } ], "dependencies": { - "grpc": "^0.15.0", + "grpc": "^${settings.node_version}", "lodash": "^3.9.3", - "google-protobuf": "^3.0.0-alpha.5" + "google-protobuf": "^3.0.0" }, - "files": { + "files": [ "LICENSE", "health.js", "v1" - }, + ], "main": "src/node/index.js", "license": "BSD-3-Clause" } diff --git a/templates/src/php/composer.json.template b/templates/src/php/composer.json.template new file mode 100644 index 00000000000..bf876f345e7 --- /dev/null +++ b/templates/src/php/composer.json.template @@ -0,0 +1,23 @@ +%YAML 1.2 +--- | + { + "name": "grpc/grpc", + "type": "library", + "description": "gRPC library for PHP", + "keywords": ["rpc"], + "homepage": "http://grpc.io", + "license": "BSD-3-Clause", + "version": "${settings.php_version.php_composer()}", + "require": { + "php": ">=5.5.0", + "stanley-cheung/protobuf-php": "v0.6" + }, + "require-dev": { + "google/auth": "v0.9" + }, + "autoload": { + "psr-4": { + "Grpc\\": "lib/Grpc/" + } + } + } diff --git a/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template b/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template deleted file mode 100644 index d83bccad1db..00000000000 --- a/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template +++ /dev/null @@ -1,41 +0,0 @@ -%YAML 1.2 ---- | - /* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - /* TODO(atash) remove cruft */ - #include - - #include "imports.generated.h" - - diff --git a/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template b/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template deleted file mode 100644 index b85bc3dbd8b..00000000000 --- a/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template +++ /dev/null @@ -1,52 +0,0 @@ -%YAML 1.2 ---- | - /* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - - /* TODO(atash) remove cruft */ - #ifndef PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ - #define PYGRPC_CYTHON_WINDOWS_IMPORTS_H_ - - #include - - #include - #include - #include - #include - #include - #include - #include - #include - #include - - #endif diff --git a/templates/src/python/grpcio_health_checking/grpc_version.py.template b/templates/src/python/grpcio_health_checking/grpc_version.py.template new file mode 100644 index 00000000000..98946e95d3d --- /dev/null +++ b/templates/src/python/grpcio_health_checking/grpc_version.py.template @@ -0,0 +1,34 @@ +%YAML 1.2 +--- | + # Copyright 2016, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!! + + VERSION='${settings.python_version.pep440()}' diff --git a/templates/tools/dockerfile/apt_get_pyenv.include b/templates/tools/dockerfile/apt_get_pyenv.include index 70e90289b70..816b27904f6 100644 --- a/templates/tools/dockerfile/apt_get_pyenv.include +++ b/templates/tools/dockerfile/apt_get_pyenv.include @@ -15,4 +15,5 @@ RUN curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/py RUN pyenv update RUN pyenv install 3.5-dev RUN pyenv install 3.6-dev -RUN pyenv local 3.5-dev 3.6-dev +RUN pyenv install pypy-5.3.1 +RUN pyenv local 3.5-dev 3.6-dev pypy-5.3.1 diff --git a/templates/tools/dockerfile/csharp_deps.include b/templates/tools/dockerfile/csharp_deps.include index 489dc44a436..7e89dec2cc2 100644 --- a/templates/tools/dockerfile/csharp_deps.include +++ b/templates/tools/dockerfile/csharp_deps.include @@ -14,3 +14,5 @@ RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y ${'\\'} ca-certificates-mono ${'\\'} nuget ${'\\'} && apt-get clean + +RUN nuget update -self diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template index 6232e081eb9..f37eadad745 100644 --- a/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php/Dockerfile.template @@ -1,6 +1,6 @@ %YAML 1.2 --- | - # Copyright 2015, Google Inc. + # Copyright 2016, Google Inc. # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -32,34 +32,8 @@ FROM debian:jessie <%include file="../../apt_get_basic.include"/> - <%include file="../../python_deps.include"/> <%include file="../../ruby_deps.include"/> <%include file="../../php_deps.include"/> <%include file="../../run_tests_addons.include"/> - # ronn: a ruby tool used to convert markdown to man pages, used during the - # install of Protobuf extensions - # - # rake: a ruby version of make used to build the PHP Protobuf extension - RUN /bin/bash -l -c "rvm all do gem install ronn rake" - - # Install composer - RUN curl -sS https://getcomposer.org/installer | php - RUN mv composer.phar /usr/local/bin/composer - - # As an attempt to work around #4212, try to prefetch Protobuf-PHP dependency - # into composer cache to prevent "composer install" from cloning on each build. - RUN git clone --mirror https://github.com/stanley-cheung/Protobuf-PHP.git ${'\\'} - /root/.composer/cache/vcs/git-github.com-stanley-cheung-Protobuf-PHP.git/ - - # Download the patched PHP protobuf so that PHP gRPC clients can be generated - # from proto3 schemas. - RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php - - RUN /bin/bash -l -c "rvm use ruby-2.1 ${'\\'} - && cd /var/local/git/protobuf-php ${'\\'} - && rvm all do rake pear:package version=1.0 ${'\\'} - && pear install Protobuf-1.0.tgz" - - # Define the default command. - CMD ["bash"] + <%include file="../../php_common_deps.include"/> diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template new file mode 100644 index 00000000000..42157ee062c --- /dev/null +++ b/templates/tools/dockerfile/interoptest/grpc_interop_php7/Dockerfile.template @@ -0,0 +1,37 @@ +%YAML 1.2 +--- | + # Copyright 2016, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + FROM debian:jessie + + <%include file="../../php7_deps.include"/> + <%include file="../../ruby_deps.include"/> + <%include file="../../run_tests_addons.include"/> + <%include file="../../php_common_deps.include"/> diff --git a/templates/tools/dockerfile/php7_deps.include b/templates/tools/dockerfile/php7_deps.include new file mode 100644 index 00000000000..a24e5064428 --- /dev/null +++ b/templates/tools/dockerfile/php7_deps.include @@ -0,0 +1,45 @@ +#================= +# PHP7 dependencies + +# Install Git and basic packages. +RUN apt-get update && apt-get install -y ${'\\'} + autoconf ${'\\'} + automake ${'\\'} + build-essential ${'\\'} + ccache ${'\\'} + curl ${'\\'} + git ${'\\'} + libcurl4-openssl-dev ${'\\'} + libgmp-dev ${'\\'} + libgmp3-dev ${'\\'} + libssl-dev ${'\\'} + libtool ${'\\'} + libxml2-dev ${'\\'} + pkg-config ${'\\'} + re2c ${'\\'} + time ${'\\'} + unzip ${'\\'} + wget ${'\\'} + zip && apt-get clean + +# Install other dependencies +RUN ln -sf /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h +RUN wget http://ftp.gnu.org/gnu/bison/bison-2.6.4.tar.gz -O /var/local/bison-2.6.4.tar.gz +RUN cd /var/local ${'\\'} + && tar -zxvf bison-2.6.4.tar.gz ${'\\'} + && cd /var/local/bison-2.6.4 ${'\\'} + && ./configure ${'\\'} + && make ${'\\'} + && make install + +# Compile PHP7 from source +RUN git clone https://github.com/php/php-src /var/local/git/php-src +RUN cd /var/local/git/php-src ${'\\'} + && git checkout PHP-7.0.9 ${'\\'} + && ./buildconf --force ${'\\'} + && ./configure ${'\\'} + --with-gmp ${'\\'} + --with-openssl ${'\\'} + --with-zlib ${'\\'} + && make ${'\\'} + && make install diff --git a/templates/tools/dockerfile/php_common_deps.include b/templates/tools/dockerfile/php_common_deps.include new file mode 100644 index 00000000000..8839bb51554 --- /dev/null +++ b/templates/tools/dockerfile/php_common_deps.include @@ -0,0 +1,21 @@ +# ronn: a ruby tool used to convert markdown to man pages, used during the +# install of Protobuf extensions +# +# rake: a ruby version of make used to build the PHP Protobuf extension +RUN /bin/bash -l -c "rvm all do gem install ronn rake" + +# Install composer +RUN curl -sS https://getcomposer.org/installer | php +RUN mv composer.phar /usr/local/bin/composer + +# Download the patched PHP protobuf so that PHP gRPC clients can be generated +# from proto3 schemas. +RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php + +RUN /bin/bash -l -c "rvm use ruby-2.1 ${'\\'} + && cd /var/local/git/protobuf-php ${'\\'} + && rvm all do rake pear:package version=1.0 ${'\\'} + && pear install Protobuf-1.0.tgz" + +# Define the default command. +CMD ["bash"] diff --git a/templates/tools/dockerfile/php_deps.include b/templates/tools/dockerfile/php_deps.include index 739049b5ea0..da071e23ba4 100644 --- a/templates/tools/dockerfile/php_deps.include +++ b/templates/tools/dockerfile/php_deps.include @@ -3,11 +3,5 @@ # Install dependencies -RUN /bin/bash -l -c "echo 'deb http://packages.dotdeb.org wheezy-php55 all' ${'\\'} - >> /etc/apt/sources.list.d/dotdeb.list" -RUN /bin/bash -l -c "echo 'deb-src http://packages.dotdeb.org wheezy-php55 all' ${'\\'} - >> /etc/apt/sources.list.d/dotdeb.list" -RUN wget http://www.dotdeb.org/dotdeb.gpg -O- | apt-key add - - RUN apt-get update && apt-get install -y ${'\\'} git php5 php5-dev phpunit unzip diff --git a/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template b/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template index f8dc0794742..13a250eb31c 100644 --- a/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template +++ b/templates/tools/dockerfile/stress_test/grpc_interop_stress_php/Dockerfile.template @@ -47,11 +47,6 @@ RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer - # As an attempt to work around #4212, try to prefetch Protobuf-PHP dependency - # into composer cache to prevent "composer install" from cloning on each build. - RUN git clone --mirror https://github.com/stanley-cheung/Protobuf-PHP.git ${'\\'} - /root/.composer/cache/vcs/git-github.com-stanley-cheung-Protobuf-PHP.git/ - # Download the patched PHP protobuf so that PHP gRPC clients can be generated # from proto3 schemas. RUN git clone https://github.com/stanley-cheung/Protobuf-PHP.git /var/local/git/protobuf-php diff --git a/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template new file mode 100644 index 00000000000..e6a213d90d3 --- /dev/null +++ b/templates/tools/dockerfile/test/php7_jessie_x64/Dockerfile.template @@ -0,0 +1,38 @@ +%YAML 1.2 +--- | + # Copyright 2016, Google Inc. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without + # modification, are permitted provided that the following conditions are + # met: + # + # * Redistributions of source code must retain the above copyright + # notice, this list of conditions and the following disclaimer. + # * Redistributions in binary form must reproduce the above + # copyright notice, this list of conditions and the following disclaimer + # in the documentation and/or other materials provided with the + # distribution. + # * Neither the name of Google Inc. nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + FROM debian:jessie + + <%include file="../../php7_deps.include"/> + <%include file="../../python_deps.include"/> + <%include file="../../run_tests_addons.include"/> + # Define the default command. + CMD ["bash"] diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c index 24ee3387a0f..be88d4a69a9 100644 --- a/test/core/bad_client/bad_client.c +++ b/test/core/bad_client/bad_client.c @@ -130,7 +130,7 @@ void grpc_run_bad_client_test( grpc_server_start(a.server); transport = grpc_create_chttp2_transport(&exec_ctx, NULL, sfd.server, 0); server_setup_transport(&a, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); /* Bind everything into the same pollset */ diff --git a/test/core/bad_client/tests/head_of_line_blocking.c b/test/core/bad_client/tests/head_of_line_blocking.c index e4051bb6685..64cb79d82f2 100644 --- a/test/core/bad_client/tests/head_of_line_blocking.c +++ b/test/core/bad_client/tests/head_of_line_blocking.c @@ -97,7 +97,7 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, &deadline, &request_metadata_recv, &payload, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(payload != NULL); diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c index ded5f17d4ab..d106ce62107 100644 --- a/test/core/bad_client/tests/large_metadata.c +++ b/test/core/bad_client/tests/large_metadata.c @@ -121,7 +121,7 @@ static void server_verifier(grpc_server *server, grpc_completion_queue *cq, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); @@ -148,7 +148,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); @@ -171,7 +171,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server, op.reserved = NULL; error = grpc_call_start_batch(s, &op, 1, tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 0); // Operation fails. + CQ_EXPECT_COMPLETION(cqv, tag(102), 0); // Operation fails. cq_verify(cqv); gpr_free((char *)meta.value); diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c index 6216553a614..e174af5931a 100644 --- a/test/core/bad_client/tests/server_registered_method.c +++ b/test/core/bad_client/tests/server_registered_method.c @@ -70,7 +70,7 @@ static void verifier_succeeds(grpc_server *server, grpc_completion_queue *cq, &deadline, &request_metadata_recv, &payload, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(payload != NULL); @@ -96,7 +96,7 @@ static void verifier_fails(grpc_server *server, grpc_completion_queue *cq, &deadline, &request_metadata_recv, &payload, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(payload == NULL); diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c index 25bbe968e4a..c08aa40a0a7 100644 --- a/test/core/bad_client/tests/simple_request.c +++ b/test/core/bad_client/tests/simple_request.c @@ -114,7 +114,7 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c index bb06ab0bb96..c9cdb169b61 100644 --- a/test/core/bad_ssl/bad_ssl_test.c +++ b/test/core/bad_ssl/bad_ssl_test.c @@ -111,7 +111,7 @@ static void run_test(const char *target, size_t nops) { error = grpc_call_start_batch(c, ops, nops, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status != GRPC_STATUS_OK); diff --git a/test/core/census/README b/test/core/census/README new file mode 100644 index 00000000000..d5363b72333 --- /dev/null +++ b/test/core/census/README @@ -0,0 +1,7 @@ +Test source and data files for Census. + +binary proto files (*.pb) in data directory are generated from the *.txt file, +via: + +BASE="filename" +cat $BASE.txt | protoc --encode=google.census.Resource census.proto > $BASE.pb diff --git a/test/core/census/data/resource_empty_name.pb b/test/core/census/data/resource_empty_name.pb new file mode 100644 index 00000000000..4d547445fae --- /dev/null +++ b/test/core/census/data/resource_empty_name.pb @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/core/census/data/resource_empty_name.txt b/test/core/census/data/resource_empty_name.txt new file mode 100644 index 00000000000..271fd3274c2 --- /dev/null +++ b/test/core/census/data/resource_empty_name.txt @@ -0,0 +1,5 @@ +# Name is present, but empty. +name : '' +unit { + numerator : SECS +} diff --git a/test/core/census/data/resource_full.pb b/test/core/census/data/resource_full.pb new file mode 100644 index 00000000000..e4c6a2aef53 --- /dev/null +++ b/test/core/census/data/resource_full.pb @@ -0,0 +1,2 @@ + + full_resource"A resource with everything defined \ No newline at end of file diff --git a/test/core/census/data/resource_full.txt b/test/core/census/data/resource_full.txt new file mode 100644 index 00000000000..1aa2fafe3a4 --- /dev/null +++ b/test/core/census/data/resource_full.txt @@ -0,0 +1,9 @@ +# A full resource definition - all fields filled out. +name : 'full_resource' +description : 'A resource with everything defined' +unit { + # Megabits per second. + prefix : 6 + numerator : BITS + denominator : SECS +} diff --git a/test/core/census/data/resource_minimal_good.pb b/test/core/census/data/resource_minimal_good.pb new file mode 100644 index 00000000000..7100c462bf1 --- /dev/null +++ b/test/core/census/data/resource_minimal_good.pb @@ -0,0 +1,2 @@ + + minimal_good \ No newline at end of file diff --git a/test/core/census/data/resource_minimal_good.txt b/test/core/census/data/resource_minimal_good.txt new file mode 100644 index 00000000000..a7a7e71dd62 --- /dev/null +++ b/test/core/census/data/resource_minimal_good.txt @@ -0,0 +1,5 @@ +# A minimal "good" Resource definition: has a name and numerator/unit. +name : 'minimal_good' +unit { + numerator : SECS +} diff --git a/test/core/census/data/resource_no_name.pb b/test/core/census/data/resource_no_name.pb new file mode 100644 index 00000000000..4d547445fae --- /dev/null +++ b/test/core/census/data/resource_no_name.pb @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/test/core/census/data/resource_no_name.txt b/test/core/census/data/resource_no_name.txt new file mode 100644 index 00000000000..8f12a91d35e --- /dev/null +++ b/test/core/census/data/resource_no_name.txt @@ -0,0 +1,4 @@ +# The minimal good Resource without a name. +unit { + numerator : SECS +} diff --git a/test/core/census/data/resource_no_numerator.pb b/test/core/census/data/resource_no_numerator.pb new file mode 100644 index 00000000000..2a5cceee70c --- /dev/null +++ b/test/core/census/data/resource_no_numerator.pb @@ -0,0 +1,2 @@ + +resource_no_numeratorýÿÿÿÿÿÿÿÿ \ No newline at end of file diff --git a/test/core/census/data/resource_no_numerator.txt b/test/core/census/data/resource_no_numerator.txt new file mode 100644 index 00000000000..fc1fec74a24 --- /dev/null +++ b/test/core/census/data/resource_no_numerator.txt @@ -0,0 +1,6 @@ +# Resource without a numerator +name : 'resource_no_numerator' +unit { + prefix : -3 + denominator : SECS +} diff --git a/test/core/census/data/resource_no_unit.pb b/test/core/census/data/resource_no_unit.pb new file mode 100644 index 00000000000..9dca2620e0a --- /dev/null +++ b/test/core/census/data/resource_no_unit.pb @@ -0,0 +1,2 @@ + +resource_no_unit \ No newline at end of file diff --git a/test/core/census/data/resource_no_unit.txt b/test/core/census/data/resource_no_unit.txt new file mode 100644 index 00000000000..c5d5115cebf --- /dev/null +++ b/test/core/census/data/resource_no_unit.txt @@ -0,0 +1,2 @@ +# The minimal good resource without a unit +name : 'resource_no_unit' diff --git a/test/core/census/resource_test.c b/test/core/census/resource_test.c new file mode 100644 index 00000000000..f0e70396156 --- /dev/null +++ b/test/core/census/resource_test.c @@ -0,0 +1,169 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/ext/census/resource.h" +#include +#include +#include +#include +#include +#include +#include +#include "src/core/ext/census/base_resources.h" +#include "test/core/util/test_config.h" + +// Test all the functionality for dealing with Resources. + +// Just startup and shutdown resources subsystem. +static void test_enable_disable() { + initialize_resources(); + shutdown_resources(); +} + +// A blank/empty initialization should not work. +static void test_empty_definition() { + initialize_resources(); + int32_t rid = census_define_resource(NULL, 0); + GPR_ASSERT(rid == -1); + uint8_t buffer[50] = {0}; + rid = census_define_resource(buffer, 50); + GPR_ASSERT(rid == -1); + shutdown_resources(); +} + +// Given a file name, read raw proto and define the resource included within. +// Returns resource id from census_define_resource(). +static int32_t define_resource_from_file(const char *file) { +#define BUF_SIZE 512 + uint8_t buffer[BUF_SIZE]; + FILE *input = fopen(file, "rb"); + GPR_ASSERT(input != NULL); + size_t nbytes = fread(buffer, 1, BUF_SIZE, input); + GPR_ASSERT(nbytes != 0 && nbytes < BUF_SIZE && feof(input) && !ferror(input)); + int32_t rid = census_define_resource(buffer, nbytes); + GPR_ASSERT(fclose(input) == 0); + return rid; +} + +// Test definition of a single resource, using a proto read from a file. The +// `succeed` parameter indicates whether we expect the definition to succeed or +// fail. `name` is used to check that the returned resource can be looked up by +// name. +static void test_define_single_resource(const char *file, const char *name, + bool succeed) { + gpr_log(GPR_INFO, "Test defining resource \"%s\"\n", name); + initialize_resources(); + int32_t rid = define_resource_from_file(file); + if (succeed) { + GPR_ASSERT(rid >= 0); + int32_t rid2 = census_resource_id(name); + GPR_ASSERT(rid == rid2); + } else { + GPR_ASSERT(rid < 0); + } + shutdown_resources(); +} + +// Try deleting various resources (both those that exist and those that don't). +static void test_delete_resource(const char *minimal_good, const char *full) { + initialize_resources(); + // Try deleting resource before any are defined. + census_delete_resource(0); + // Create and check a couple of resources. + int32_t rid1 = define_resource_from_file(minimal_good); + int32_t rid2 = define_resource_from_file(full); + GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2); + int32_t rid3 = census_resource_id("minimal_good"); + int32_t rid4 = census_resource_id("full_resource"); + GPR_ASSERT(rid1 == rid3 && rid2 == rid4); + // Try deleting non-existant resources. + census_delete_resource(-1); + census_delete_resource(rid1 + rid2 + 1); + census_delete_resource(10000000); + // Delete one of the previously defined resources and check for deletion. + census_delete_resource(rid1); + rid3 = census_resource_id("minimal_good"); + GPR_ASSERT(rid3 < 0); + // Check that re-adding works. + rid1 = define_resource_from_file(minimal_good); + GPR_ASSERT(rid1 >= 0); + rid3 = census_resource_id("minimal_good"); + GPR_ASSERT(rid1 == rid3); + shutdown_resources(); +} + +// Test define base resources. +static void test_base_resources() { + initialize_resources(); + define_base_resources(); + int32_t rid1 = census_resource_id("client_rpc_latency"); + int32_t rid2 = census_resource_id("server_rpc_latency"); + GPR_ASSERT(rid1 >= 0 && rid2 >= 0 && rid1 != rid2); + shutdown_resources(); +} + +int main(int argc, char **argv) { + const char *resource_empty_name_pb, *resource_full_pb, + *resource_minimal_good_pb, *resource_no_name_pb, + *resource_no_numerator_pb, *resource_no_unit_pb; + if (argc == 7) { + resource_empty_name_pb = argv[1]; + resource_full_pb = argv[2]; + resource_minimal_good_pb = argv[3]; + resource_no_name_pb = argv[4]; + resource_no_numerator_pb = argv[5]; + resource_no_unit_pb = argv[6]; + } else { + GPR_ASSERT(argc == 1); + resource_empty_name_pb = "test/core/census/data/resource_empty_name.pb"; + resource_full_pb = "test/core/census/data/resource_full.pb"; + resource_minimal_good_pb = "test/core/census/data/resource_minimal_good.pb"; + resource_no_name_pb = "test/core/census/data/resource_no_name.pb"; + resource_no_numerator_pb = "test/core/census/data/resource_no_numerator.pb"; + resource_no_unit_pb = "test/core/census/data/resource_no_unit.pb"; + } + grpc_test_init(argc, argv); + test_enable_disable(); + test_empty_definition(); + test_define_single_resource(resource_minimal_good_pb, "minimal_good", true); + test_define_single_resource(resource_full_pb, "full_resource", true); + test_define_single_resource(resource_no_name_pb, "resource_no_name", false); + test_define_single_resource(resource_no_numerator_pb, "resource_no_numerator", + false); + test_define_single_resource(resource_no_unit_pb, "resource_no_unit", false); + test_define_single_resource(resource_empty_name_pb, "resource_empty_name", + false); + test_delete_resource(resource_minimal_good_pb, resource_full_pb); + test_base_resources(); + return 0; +} diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index f9561bed707..569b3f7cd23 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -53,17 +53,20 @@ static void channel_init_func(grpc_exec_ctx *exec_ctx, *(int *)(elem->channel_data) = 0; } -static void call_init_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) { +static grpc_error *call_init_func(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { ++*(int *)(elem->channel_data); *(int *)(elem->call_data) = 0; + return GRPC_ERROR_NONE; } static void channel_destroy_func(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem) {} static void call_destroy_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, void *ignored) { + const grpc_call_final_info *final_info, + void *ignored) { ++*(int *)(elem->channel_data); } @@ -132,8 +135,10 @@ static void test_create_channel_stack(void) { GPR_ASSERT(*channel_data == 0); call_stack = gpr_malloc(channel_stack->call_stack_size); - grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, NULL, - NULL, call_stack); + grpc_error *error = + grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, + NULL, NULL, call_stack); + GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(call_stack->count == 1); call_elem = grpc_call_stack_element(call_stack, 0); GPR_ASSERT(call_elem->filter == channel_elem->filter); diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c index 3160312db6f..0b9648b7e1c 100644 --- a/test/core/client_config/lb_policies_test.c +++ b/test/core/client_config/lb_policies_test.c @@ -351,9 +351,9 @@ static int *perform_request(servers_fixture *f, grpc_channel *client, ops, (size_t)(op - ops), tag(102), NULL)); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); if (!completed_client) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } cq_verify(cqv); @@ -376,7 +376,7 @@ static int *perform_request(servers_fixture *f, grpc_channel *client, } else { /* no response from server */ grpc_call_cancel(c, NULL); if (!completed_client) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); } } @@ -576,7 +576,7 @@ static void test_ping() { client = create_client(f); grpc_channel_ping(client, f->cq, tag(0), NULL); - cq_expect_completion(cqv, tag(0), 0); + CQ_EXPECT_COMPLETION(cqv, tag(0), 0); /* check that we're still in idle, and start connecting */ GPR_ASSERT(grpc_channel_check_connectivity_state(client, 1) == @@ -586,7 +586,7 @@ static void test_ping() { while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f->cq, tag(99)); - cq_expect_completion(cqv, tag(99), 1); + CQ_EXPECT_COMPLETION(cqv, tag(99), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -596,7 +596,7 @@ static void test_ping() { for (i = 1; i <= 5; i++) { grpc_channel_ping(client, f->cq, tag(i), NULL); - cq_expect_completion(cqv, tag(i), 1); + CQ_EXPECT_COMPLETION(cqv, tag(i), 1); cq_verify(cqv); } gpr_free(rdata.call_details); diff --git a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c index 69c07d83f43..6a33525f629 100644 --- a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c @@ -127,26 +127,26 @@ int main(int argc, char **argv) { grpc_resolver *resolver = create_resolver("dns:test"); - grpc_client_config *config = (grpc_client_config *)1; + grpc_resolver_result *result = (grpc_resolver_result *)1; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_event ev1; gpr_event_init(&ev1); - grpc_resolver_next(&exec_ctx, resolver, &config, + grpc_resolver_next(&exec_ctx, resolver, &result, grpc_closure_create(on_done, &ev1)); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(wait_loop(5, &ev1)); - GPR_ASSERT(config == NULL); + GPR_ASSERT(result == NULL); gpr_event ev2; gpr_event_init(&ev2); - grpc_resolver_next(&exec_ctx, resolver, &config, + grpc_resolver_next(&exec_ctx, resolver, &result, grpc_closure_create(on_done, &ev2)); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(wait_loop(30, &ev2)); - GPR_ASSERT(config != NULL); + GPR_ASSERT(result != NULL); - grpc_client_config_unref(&exec_ctx, config); + grpc_resolver_result_unref(&exec_ctx, result); GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test"); grpc_exec_ctx_finish(&exec_ctx); diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c index cca75f54a5f..5ed0eb64d26 100644 --- a/test/core/end2end/bad_server_response_test.c +++ b/test/core/end2end/bad_server_response_test.c @@ -71,6 +71,8 @@ #define UNPARSEABLE_DETAIL_MSG "Failed parsing HTTP/2" +#define HTTP1_DETAIL_MSG "Trying to connect an http1.x server" + /* TODO(zyc) Check the content of incomming data instead of using this length */ #define EXPECTED_INCOMING_DATA_LENGTH (size_t)310 @@ -204,7 +206,7 @@ static void start_rpc(int target_port, grpc_status_code expected_status, GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); gpr_log(GPR_DEBUG, "Rpc status: %d, details: %s", status, details); @@ -334,7 +336,7 @@ int main(int argc, char **argv) { /* http1 response */ run_test(HTTP1_RESP, sizeof(HTTP1_RESP) - 1, GRPC_STATUS_UNAVAILABLE, - UNPARSEABLE_DETAIL_MSG); + HTTP1_DETAIL_MSG); return 0; } diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 890309c44a8..1f42d3457e8 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -61,7 +61,8 @@ typedef struct metadata { list to detail other expectations */ typedef struct expectation { struct expectation *next; - struct expectation *prev; + const char *file; + int line; grpc_completion_type type; void *tag; int success; @@ -71,17 +72,14 @@ typedef struct expectation { struct cq_verifier { /* bound completion queue */ grpc_completion_queue *cq; - /* the root/sentinal expectation */ - expectation expect; + /* start of expectation list */ + expectation *first_expectation; }; cq_verifier *cq_verifier_create(grpc_completion_queue *cq) { cq_verifier *v = gpr_malloc(sizeof(cq_verifier)); - v->expect.type = ROOT_EXPECTATION; - v->expect.tag = NULL; - v->expect.next = &v->expect; - v->expect.prev = &v->expect; v->cq = cq; + v->first_expectation = NULL; return v; } @@ -184,7 +182,8 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) { switch (e->type) { case GRPC_OP_COMPLETE: - gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d", e->success); + gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d %s:%d", e->success, + e->file, e->line); gpr_strvec_add(buf, tmp); break; case GRPC_QUEUE_TIMEOUT: @@ -198,7 +197,7 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) { static void expectations_to_strvec(gpr_strvec *buf, cq_verifier *v) { expectation *e; - for (e = v->expect.next; e != &v->expect; e = e->next) { + for (e = v->first_expectation; e != NULL; e = e->next) { expectation_to_strvec(buf, e); gpr_strvec_add(buf, gpr_strdup("\n")); } @@ -218,53 +217,48 @@ static void fail_no_event_received(cq_verifier *v) { } void cq_verify(cq_verifier *v) { - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); - grpc_event ev; - expectation *e; - char *s; - gpr_strvec have_tags; - - gpr_strvec_init(&have_tags); - - while (v->expect.next != &v->expect) { - ev = grpc_completion_queue_next(v->cq, deadline, NULL); + const gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); + while (v->first_expectation != NULL) { + grpc_event ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type == GRPC_QUEUE_TIMEOUT) { fail_no_event_received(v); break; } - - for (e = v->expect.next; e != &v->expect; e = e->next) { - gpr_asprintf(&s, " %p", e->tag); - gpr_strvec_add(&have_tags, s); + expectation *e; + expectation *prev = NULL; + for (e = v->first_expectation; e != NULL; e = e->next) { if (e->tag == ev.tag) { verify_matches(e, &ev); - e->next->prev = e->prev; - e->prev->next = e->next; + if (e == v->first_expectation) v->first_expectation = e->next; + if (prev != NULL) prev->next = e->next; gpr_free(e); break; } + prev = e; } - if (e == &v->expect) { - s = grpc_event_string(&ev); - gpr_log(GPR_ERROR, "event not found: %s", s); + if (e == NULL) { + char *s = grpc_event_string(&ev); + gpr_log(GPR_ERROR, "cq returned unexpected event: %s", s); gpr_free(s); - s = gpr_strvec_flatten(&have_tags, NULL); - gpr_log(GPR_ERROR, "have tags:%s", s); + gpr_strvec expectations; + gpr_strvec_init(&expectations); + expectations_to_strvec(&expectations, v); + s = gpr_strvec_flatten(&expectations, NULL); + gpr_strvec_destroy(&expectations); + gpr_log(GPR_ERROR, "expected tags:\n%s", s); gpr_free(s); - gpr_strvec_destroy(&have_tags); abort(); } } - - gpr_strvec_destroy(&have_tags); } -void cq_verify_empty(cq_verifier *v) { - gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(1, GPR_TIMESPAN)); +void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec) { + gpr_timespec deadline = + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(timeout_sec, GPR_TIMESPAN)); grpc_event ev; - GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty"); + GPR_ASSERT(v->first_expectation == NULL && "expectation queue must be empty"); ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type != GRPC_QUEUE_TIMEOUT) { @@ -275,16 +269,21 @@ void cq_verify_empty(cq_verifier *v) { } } -static expectation *add(cq_verifier *v, grpc_completion_type type, void *tag) { +void cq_verify_empty(cq_verifier *v) { cq_verify_empty_timeout(v, 1); } + +static void add(cq_verifier *v, const char *file, int line, + grpc_completion_type type, void *tag, bool success) { expectation *e = gpr_malloc(sizeof(expectation)); e->type = type; + e->file = file; + e->line = line; e->tag = tag; - e->next = &v->expect; - e->prev = e->next->prev; - e->next->prev = e->prev->next = e; - return e; + e->success = success; + e->next = v->first_expectation; + v->first_expectation = e; } -void cq_expect_completion(cq_verifier *v, void *tag, bool success) { - add(v, GRPC_OP_COMPLETE, tag)->success = success; +void cq_expect_completion(cq_verifier *v, const char *file, int line, void *tag, + bool success) { + add(v, file, line, GRPC_OP_COMPLETE, tag, success); } diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h index 8c9a85c2187..0a7c03c090d 100644 --- a/test/core/end2end/cq_verifier.h +++ b/test/core/end2end/cq_verifier.h @@ -55,11 +55,17 @@ void cq_verify(cq_verifier *v); /* ensure that the completion queue is empty */ void cq_verify_empty(cq_verifier *v); +/* ensure that the completion queue is empty, waiting up to \a timeout secs. */ +void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec); + /* Various expectation matchers Any functions taking ... expect a NULL terminated list of key/value pairs (each pair using two parameter slots) of metadata that MUST be present in the event. */ -void cq_expect_completion(cq_verifier *v, void *tag, bool success); +void cq_expect_completion(cq_verifier *v, const char *file, int line, void *tag, + bool success); +#define CQ_EXPECT_COMPLETION(v, tag, success) \ + cq_expect_completion(v, __FILE__, __LINE__, tag, success) int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string); int contains_metadata(grpc_metadata_array *array, const char *key, diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 348b9ed5f02..8abb81c803a 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -199,7 +199,7 @@ void test_connect(const char *server_host, const char *client_host, int port, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -221,8 +221,8 @@ void test_connect(const char *server_host, const char *client_host, int port, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); peer = grpc_call_get_peer(c); @@ -238,7 +238,7 @@ void test_connect(const char *server_host, const char *client_host, int port, grpc_call_destroy(s); } else { /* Check for a failed connection. */ - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index 03e55f11812..a6302621970 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -69,6 +69,8 @@ extern void disappearing_server(grpc_end2end_test_config config); extern void disappearing_server_pre_init(void); extern void empty_batch(grpc_end2end_test_config config); extern void empty_batch_pre_init(void); +extern void filter_call_init_fails(grpc_end2end_test_config config); +extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); @@ -83,6 +85,8 @@ extern void invoke_large_request(grpc_end2end_test_config config); extern void invoke_large_request_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); +extern void load_reporting_hook(grpc_end2end_test_config config); +extern void load_reporting_hook_pre_init(void); extern void max_concurrent_streams(grpc_end2end_test_config config); extern void max_concurrent_streams_pre_init(void); extern void max_message_length(grpc_end2end_test_config config); @@ -91,6 +95,8 @@ extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); extern void network_status_change(grpc_end2end_test_config config); extern void network_status_change_pre_init(void); +extern void no_logging(grpc_end2end_test_config config); +extern void no_logging_pre_init(void); extern void no_op(grpc_end2end_test_config config); extern void no_op_pre_init(void); extern void payload(grpc_end2end_test_config config); @@ -111,6 +117,8 @@ extern void shutdown_finishes_calls(grpc_end2end_test_config config); extern void shutdown_finishes_calls_pre_init(void); extern void shutdown_finishes_tags(grpc_end2end_test_config config); extern void shutdown_finishes_tags_pre_init(void); +extern void simple_cacheable_request(grpc_end2end_test_config config); +extern void simple_cacheable_request_pre_init(void); extern void simple_delayed_request(grpc_end2end_test_config config); extern void simple_delayed_request_pre_init(void); extern void simple_metadata(grpc_end2end_test_config config); @@ -138,6 +146,7 @@ void grpc_end2end_tests_pre_init(void) { default_host_pre_init(); disappearing_server_pre_init(); empty_batch_pre_init(); + filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); graceful_server_shutdown_pre_init(); high_initial_seqno_pre_init(); @@ -145,10 +154,12 @@ void grpc_end2end_tests_pre_init(void) { idempotent_request_pre_init(); invoke_large_request_pre_init(); large_metadata_pre_init(); + load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); network_status_change_pre_init(); + no_logging_pre_init(); no_op_pre_init(); payload_pre_init(); ping_pre_init(); @@ -159,6 +170,7 @@ void grpc_end2end_tests_pre_init(void) { server_finishes_request_pre_init(); shutdown_finishes_calls_pre_init(); shutdown_finishes_tags_pre_init(); + simple_cacheable_request_pre_init(); simple_delayed_request_pre_init(); simple_metadata_pre_init(); simple_request_pre_init(); @@ -186,6 +198,7 @@ void grpc_end2end_tests(int argc, char **argv, default_host(config); disappearing_server(config); empty_batch(config); + filter_call_init_fails(config); filter_causes_close(config); graceful_server_shutdown(config); high_initial_seqno(config); @@ -193,10 +206,12 @@ void grpc_end2end_tests(int argc, char **argv, idempotent_request(config); invoke_large_request(config); large_metadata(config); + load_reporting_hook(config); max_concurrent_streams(config); max_message_length(config); negative_deadline(config); network_status_change(config); + no_logging(config); no_op(config); payload(config); ping(config); @@ -207,6 +222,7 @@ void grpc_end2end_tests(int argc, char **argv, server_finishes_request(config); shutdown_finishes_calls(config); shutdown_finishes_tags(config); + simple_cacheable_request(config); simple_delayed_request(config); simple_metadata(config); simple_request(config); @@ -268,6 +284,10 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); continue; } + if (0 == strcmp("filter_call_init_fails", argv[i])) { + filter_call_init_fails(config); + continue; + } if (0 == strcmp("filter_causes_close", argv[i])) { filter_causes_close(config); continue; @@ -296,6 +316,10 @@ void grpc_end2end_tests(int argc, char **argv, large_metadata(config); continue; } + if (0 == strcmp("load_reporting_hook", argv[i])) { + load_reporting_hook(config); + continue; + } if (0 == strcmp("max_concurrent_streams", argv[i])) { max_concurrent_streams(config); continue; @@ -312,6 +336,10 @@ void grpc_end2end_tests(int argc, char **argv, network_status_change(config); continue; } + if (0 == strcmp("no_logging", argv[i])) { + no_logging(config); + continue; + } if (0 == strcmp("no_op", argv[i])) { no_op(config); continue; @@ -352,6 +380,10 @@ void grpc_end2end_tests(int argc, char **argv, shutdown_finishes_tags(config); continue; } + if (0 == strcmp("simple_cacheable_request", argv[i])) { + simple_cacheable_request(config); + continue; + } if (0 == strcmp("simple_delayed_request", argv[i])) { simple_delayed_request(config); continue; diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index 877b1b19893..925872a71ff 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -71,6 +71,8 @@ extern void disappearing_server(grpc_end2end_test_config config); extern void disappearing_server_pre_init(void); extern void empty_batch(grpc_end2end_test_config config); extern void empty_batch_pre_init(void); +extern void filter_call_init_fails(grpc_end2end_test_config config); +extern void filter_call_init_fails_pre_init(void); extern void filter_causes_close(grpc_end2end_test_config config); extern void filter_causes_close_pre_init(void); extern void graceful_server_shutdown(grpc_end2end_test_config config); @@ -85,6 +87,8 @@ extern void invoke_large_request(grpc_end2end_test_config config); extern void invoke_large_request_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); +extern void load_reporting_hook(grpc_end2end_test_config config); +extern void load_reporting_hook_pre_init(void); extern void max_concurrent_streams(grpc_end2end_test_config config); extern void max_concurrent_streams_pre_init(void); extern void max_message_length(grpc_end2end_test_config config); @@ -93,6 +97,8 @@ extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); extern void network_status_change(grpc_end2end_test_config config); extern void network_status_change_pre_init(void); +extern void no_logging(grpc_end2end_test_config config); +extern void no_logging_pre_init(void); extern void no_op(grpc_end2end_test_config config); extern void no_op_pre_init(void); extern void payload(grpc_end2end_test_config config); @@ -113,6 +119,8 @@ extern void shutdown_finishes_calls(grpc_end2end_test_config config); extern void shutdown_finishes_calls_pre_init(void); extern void shutdown_finishes_tags(grpc_end2end_test_config config); extern void shutdown_finishes_tags_pre_init(void); +extern void simple_cacheable_request(grpc_end2end_test_config config); +extern void simple_cacheable_request_pre_init(void); extern void simple_delayed_request(grpc_end2end_test_config config); extern void simple_delayed_request_pre_init(void); extern void simple_metadata(grpc_end2end_test_config config); @@ -141,6 +149,7 @@ void grpc_end2end_tests_pre_init(void) { default_host_pre_init(); disappearing_server_pre_init(); empty_batch_pre_init(); + filter_call_init_fails_pre_init(); filter_causes_close_pre_init(); graceful_server_shutdown_pre_init(); high_initial_seqno_pre_init(); @@ -148,10 +157,12 @@ void grpc_end2end_tests_pre_init(void) { idempotent_request_pre_init(); invoke_large_request_pre_init(); large_metadata_pre_init(); + load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); max_message_length_pre_init(); negative_deadline_pre_init(); network_status_change_pre_init(); + no_logging_pre_init(); no_op_pre_init(); payload_pre_init(); ping_pre_init(); @@ -162,6 +173,7 @@ void grpc_end2end_tests_pre_init(void) { server_finishes_request_pre_init(); shutdown_finishes_calls_pre_init(); shutdown_finishes_tags_pre_init(); + simple_cacheable_request_pre_init(); simple_delayed_request_pre_init(); simple_metadata_pre_init(); simple_request_pre_init(); @@ -190,6 +202,7 @@ void grpc_end2end_tests(int argc, char **argv, default_host(config); disappearing_server(config); empty_batch(config); + filter_call_init_fails(config); filter_causes_close(config); graceful_server_shutdown(config); high_initial_seqno(config); @@ -197,10 +210,12 @@ void grpc_end2end_tests(int argc, char **argv, idempotent_request(config); invoke_large_request(config); large_metadata(config); + load_reporting_hook(config); max_concurrent_streams(config); max_message_length(config); negative_deadline(config); network_status_change(config); + no_logging(config); no_op(config); payload(config); ping(config); @@ -211,6 +226,7 @@ void grpc_end2end_tests(int argc, char **argv, server_finishes_request(config); shutdown_finishes_calls(config); shutdown_finishes_tags(config); + simple_cacheable_request(config); simple_delayed_request(config); simple_metadata(config); simple_request(config); @@ -276,6 +292,10 @@ void grpc_end2end_tests(int argc, char **argv, empty_batch(config); continue; } + if (0 == strcmp("filter_call_init_fails", argv[i])) { + filter_call_init_fails(config); + continue; + } if (0 == strcmp("filter_causes_close", argv[i])) { filter_causes_close(config); continue; @@ -304,6 +324,10 @@ void grpc_end2end_tests(int argc, char **argv, large_metadata(config); continue; } + if (0 == strcmp("load_reporting_hook", argv[i])) { + load_reporting_hook(config); + continue; + } if (0 == strcmp("max_concurrent_streams", argv[i])) { max_concurrent_streams(config); continue; @@ -320,6 +344,10 @@ void grpc_end2end_tests(int argc, char **argv, network_status_change(config); continue; } + if (0 == strcmp("no_logging", argv[i])) { + no_logging(config); + continue; + } if (0 == strcmp("no_op", argv[i])) { no_op(config); continue; @@ -360,6 +388,10 @@ void grpc_end2end_tests(int argc, char **argv, shutdown_finishes_tags(config); continue; } + if (0 == strcmp("simple_cacheable_request", argv[i])) { + simple_cacheable_request(config); + continue; + } if (0 == strcmp("simple_delayed_request", argv[i])) { simple_delayed_request(config); continue; diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h index dfa041c0c64..34af0936cdb 100644 --- a/test/core/end2end/end2end_tests.h +++ b/test/core/end2end/end2end_tests.h @@ -42,6 +42,7 @@ typedef struct grpc_end2end_test_config grpc_end2end_test_config; #define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4 +#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 8 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check" diff --git a/test/core/end2end/fixtures/h2_loadreporting.c b/test/core/end2end/fixtures/h2_load_reporting.c similarity index 52% rename from test/core/end2end/fixtures/h2_loadreporting.c rename to test/core/end2end/fixtures/h2_load_reporting.c index 4ed02f97286..f6d3923db94 100644 --- a/test/core/end2end/fixtures/h2_loadreporting.c +++ b/test/core/end2end/fixtures/h2_load_reporting.c @@ -52,18 +52,16 @@ #include "test/core/util/port.h" #include "test/core/util/test_config.h" -static grpc_load_reporting_config *g_client_lrc; -static grpc_load_reporting_config *g_server_lrc; - -typedef struct fullstack_fixture_data { +typedef struct load_reporting_fixture_data { char *localaddr; -} fullstack_fixture_data; +} load_reporting_fixture_data; -static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( +static grpc_end2end_test_fixture chttp2_create_fixture_load_reporting( grpc_channel_args *client_args, grpc_channel_args *server_args) { grpc_end2end_test_fixture f; int port = grpc_pick_unused_port_or_die(); - fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data)); + load_reporting_fixture_data *ffd = + gpr_malloc(sizeof(load_reporting_fixture_data)); memset(&f, 0, sizeof(f)); gpr_join_host_port(&ffd->localaddr, "localhost", port); @@ -74,47 +72,20 @@ static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( return f; } -typedef struct { - int64_t total_bytes; - bool fully_processed; - uint32_t initial_token; - uint32_t final_token; -} aggregated_bw_stats; - -static void sample_fn(const grpc_load_reporting_call_data *call_data, - void *user_data) { - GPR_ASSERT(user_data != NULL); - aggregated_bw_stats *custom_stats = (aggregated_bw_stats *)user_data; - if (call_data == NULL) { - /* initial invocation */ - custom_stats->initial_token = 0xDEADBEEF; - } else { - /* final invocation */ - custom_stats->total_bytes = - (int64_t)(call_data->stats->transport_stream_stats.outgoing.data_bytes + - call_data->stats->transport_stream_stats.incoming.data_bytes); - custom_stats->final_token = 0xCAFED00D; - custom_stats->fully_processed = true; - } -} - -void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f, - grpc_channel_args *client_args) { - fullstack_fixture_data *ffd = f->fixture_data; - grpc_arg arg = grpc_load_reporting_config_create_arg(g_client_lrc); - client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1); +void chttp2_init_client_load_reporting(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args) { + load_reporting_fixture_data *ffd = f->fixture_data; f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL); - grpc_channel_args_destroy(client_args); GPR_ASSERT(f->client); } -void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f, - grpc_channel_args *server_args) { - fullstack_fixture_data *ffd = f->fixture_data; +void chttp2_init_server_load_reporting(grpc_end2end_test_fixture *f, + grpc_channel_args *server_args) { + load_reporting_fixture_data *ffd = f->fixture_data; + grpc_arg arg = grpc_load_reporting_enable_arg(); if (f->server) { grpc_server_destroy(f->server); } - grpc_arg arg = grpc_load_reporting_config_create_arg(g_server_lrc); server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1); f->server = grpc_server_create(server_args, NULL); grpc_channel_args_destroy(server_args); @@ -123,36 +94,23 @@ 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 = f->fixture_data; +void chttp2_tear_down_load_reporting(grpc_end2end_test_fixture *f) { + load_reporting_fixture_data *ffd = f->fixture_data; gpr_free(ffd->localaddr); gpr_free(ffd); } /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack+loadreporting", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, - chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, - chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, + {"chttp2/fullstack+load_reporting", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, + chttp2_create_fixture_load_reporting, chttp2_init_client_load_reporting, + chttp2_init_server_load_reporting, chttp2_tear_down_load_reporting}, }; int main(int argc, char **argv) { size_t i; - aggregated_bw_stats *aggr_stats_client = - gpr_malloc(sizeof(aggregated_bw_stats)); - aggr_stats_client->total_bytes = -1; - aggr_stats_client->fully_processed = false; - aggregated_bw_stats *aggr_stats_server = - gpr_malloc(sizeof(aggregated_bw_stats)); - aggr_stats_server->total_bytes = -1; - aggr_stats_server->fully_processed = false; - - g_client_lrc = - grpc_load_reporting_config_create(sample_fn, aggr_stats_client); - g_server_lrc = - grpc_load_reporting_config_create(sample_fn, aggr_stats_server); - grpc_test_init(argc, argv); grpc_end2end_tests_pre_init(); grpc_init(); @@ -163,22 +121,5 @@ int main(int argc, char **argv) { grpc_shutdown(); - grpc_load_reporting_config_destroy(g_client_lrc); - grpc_load_reporting_config_destroy(g_server_lrc); - - if (aggr_stats_client->fully_processed) { - GPR_ASSERT(aggr_stats_client->total_bytes >= 0); - GPR_ASSERT(aggr_stats_client->initial_token == 0xDEADBEEF); - GPR_ASSERT(aggr_stats_client->final_token == 0xCAFED00D); - } - if (aggr_stats_server->fully_processed) { - GPR_ASSERT(aggr_stats_server->total_bytes >= 0); - GPR_ASSERT(aggr_stats_server->initial_token == 0xDEADBEEF); - GPR_ASSERT(aggr_stats_server->final_token == 0xCAFED00D); - } - - gpr_free(aggr_stats_client); - gpr_free(aggr_stats_server); - return 0; } diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c index 8c50eeb5d5b..c7b99863f02 100644 --- a/test/core/end2end/fixtures/h2_proxy.c +++ b/test/core/end2end/fixtures/h2_proxy.c @@ -113,7 +113,8 @@ void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, + {"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_REQUEST_PROXYING, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c index 6b0769b6088..b8a5257ab2a 100644 --- a/test/core/end2end/fixtures/h2_sockpair+trace.c +++ b/test/core/end2end/fixtures/h2_sockpair+trace.c @@ -108,7 +108,7 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1); client_setup_transport(&exec_ctx, &cs, transport); GPR_ASSERT(f->client); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -124,7 +124,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0); server_setup_transport(f, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c index 7be88f8a68e..a57990d6e73 100644 --- a/test/core/end2end/fixtures/h2_sockpair.c +++ b/test/core/end2end/fixtures/h2_sockpair.c @@ -107,7 +107,7 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1); client_setup_transport(&exec_ctx, &cs, transport); GPR_ASSERT(f->client); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -123,7 +123,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0); server_setup_transport(f, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c index 166654bcbfd..50aac8045a9 100644 --- a/test/core/end2end/fixtures/h2_sockpair_1byte.c +++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c @@ -107,7 +107,7 @@ static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, grpc_create_chttp2_transport(&exec_ctx, client_args, sfd->client, 1); client_setup_transport(&exec_ctx, &cs, transport); GPR_ASSERT(f->client); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } @@ -123,7 +123,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, transport = grpc_create_chttp2_transport(&exec_ctx, server_args, sfd->server, 0); server_setup_transport(f, transport); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c index b476bf5516d..ae2604dfb5c 100644 --- a/test/core/end2end/fixtures/h2_ssl_cert.c +++ b/test/core/end2end/fixtures/h2_ssl_cert.c @@ -331,7 +331,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), expected_result == SUCCESS); + CQ_EXPECT_COMPLETION(cqv, tag(1), expected_result == SUCCESS); cq_verify(cqv); grpc_call_destroy(c); diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c index 238e6bca461..eeb54b8b88e 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.c +++ b/test/core/end2end/fixtures/h2_ssl_proxy.c @@ -184,6 +184,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( static grpc_end2end_test_config configs[] = { {"chttp2/simple_ssl_fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_REQUEST_PROXYING | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_secure_fullstack, diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c index 13b8bf7561a..96ea82d95ea 100644 --- a/test/core/end2end/fuzzers/api_fuzzer.c +++ b/test/core/end2end/fuzzers/api_fuzzer.c @@ -258,7 +258,7 @@ static void do_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { grpc_transport *transport = grpc_create_chttp2_transport(exec_ctx, NULL, server, 0); grpc_server_setup_transport(exec_ctx, g_server, transport, NULL, NULL); - grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(exec_ctx, transport, NULL); grpc_exec_ctx_sched(exec_ctx, fc->closure, GRPC_ERROR_NONE, NULL); } else { diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 new file mode 100644 index 00000000000..1aa57b990d7 Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 differ diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 b/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 new file mode 100644 index 00000000000..385a724f3dc Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 differ diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 new file mode 100644 index 00000000000..e21c7c6d39e Binary files /dev/null and b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 differ diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c index 79b23d78569..00e650a30b9 100644 --- a/test/core/end2end/fuzzers/client_fuzzer.c +++ b/test/core/end2end/fuzzers/client_fuzzer.c @@ -63,7 +63,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_completion_queue *cq = grpc_completion_queue_create(NULL); grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 1); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_channel *channel = grpc_channel_create( &exec_ctx, "test-target", NULL, GRPC_CLIENT_DIRECT_CHANNEL, transport); diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index 097e9a89224..e5a73d523fa 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -21,8 +21,6 @@ "\x0A:authority" "\x0Dauthorization" "\x0Dcache-control" -"\x0Acensus-bin" -"\x11census-binary-bin" "\x13content-disposition" "\x10content-encoding" "\x10content-language" @@ -42,11 +40,14 @@ "\x03GET" "\x04grpc" "\x14grpc-accept-encoding" +"\x0Fgrpc-census-bin" "\x0Dgrpc-encoding" "\x1Egrpc-internal-encoding-request" "\x0Cgrpc-message" +"\x10grpc-payload-bin" "\x0Bgrpc-status" "\x0Cgrpc-timeout" +"\x10grpc-tracing-bin" "\x04gzip" "\x0Dgzip, deflate" "\x04host" @@ -63,7 +64,8 @@ "\x13if-unmodified-since" "\x0Dlast-modified" "\x04link" -"\x0Eload-reporting" +"\x16load-reporting-initial" +"\x17load-reporting-trailing" "\x08location" "\x0Cmax-forwards" "\x07:method" @@ -137,7 +139,8 @@ "\x00\x13if-unmodified-since\x00" "\x00\x0Dlast-modified\x00" "\x00\x04link\x00" -"\x00\x0Eload-reporting\x00" +"\x00\x16load-reporting-initial\x00" +"\x00\x17load-reporting-trailing\x00" "\x00\x08location\x00" "\x00\x0Cmax-forwards\x00" "\x00\x07:method\x03GET" diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c index 80f568ac927..79eaad70c5d 100644 --- a/test/core/end2end/fuzzers/server_fuzzer.c +++ b/test/core/end2end/fuzzers/server_fuzzer.c @@ -71,7 +71,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { grpc_transport *transport = grpc_create_chttp2_transport(&exec_ctx, NULL, mock_endpoint, 0); grpc_server_setup_transport(&exec_ctx, server, transport, NULL, NULL); - grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0); + grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL); grpc_call *call1 = NULL; grpc_call_details call_details1; diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index fb7275474d3..c6368c6a5f5 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -53,13 +53,13 @@ fd_unsecure_fixture_options = default_unsecure_fixture_options._replace( END2END_FIXTURES = { 'h2_compress': default_unsecure_fixture_options, 'h2_census': default_unsecure_fixture_options, + 'h2_load_reporting': default_unsecure_fixture_options, 'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False), 'h2_fd': fd_unsecure_fixture_options, 'h2_full': default_unsecure_fixture_options, 'h2_full+pipe': default_unsecure_fixture_options._replace( platforms=['linux']), 'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True), - 'h2_loadreporting': default_unsecure_fixture_options, 'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False), 'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True, ci_mac=False), @@ -102,6 +102,7 @@ END2END_TESTS = { 'disappearing_server': connectivity_test_options, 'empty_batch': default_test_options, 'filter_causes_close': default_test_options, + 'filter_call_init_fails': default_test_options, 'graceful_server_shutdown': default_test_options._replace(cpu_cost=LOWCPU), 'hpack_size': default_test_options._replace(proxyable=False, traceable=False), @@ -113,8 +114,10 @@ END2END_TESTS = { 'max_message_length': default_test_options, 'negative_deadline': default_test_options, 'network_status_change': default_test_options, + 'no_logging': default_test_options._replace(traceable=False), 'no_op': default_test_options, 'payload': default_test_options, + 'load_reporting_hook': default_test_options, 'ping_pong_streaming': default_test_options, 'ping': connectivity_test_options._replace(proxyable=False), 'registered_call': default_test_options, @@ -124,6 +127,7 @@ END2END_TESTS = { 'server_finishes_request': default_test_options, 'shutdown_finishes_calls': default_test_options, 'shutdown_finishes_tags': default_test_options, + 'simple_cacheable_request': default_test_options, 'simple_delayed_request': connectivity_test_options, 'simple_metadata': default_test_options, 'simple_request': default_test_options, diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c index 67cc24c74c5..a8c7b2be5ac 100644 --- a/test/core/end2end/goaway_server_test.c +++ b/test/core/end2end/goaway_server_test.c @@ -175,8 +175,8 @@ int main(int argc, char **argv) { set_resolve_port(port1); /* first call should now start */ - cq_expect_completion(cqv, tag(0x101), 1); - cq_expect_completion(cqv, tag(0x301), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x301), 1); cq_verify(cqv); GPR_ASSERT(GRPC_CHANNEL_READY == @@ -200,7 +200,7 @@ int main(int argc, char **argv) { * we should see a connectivity change and then nothing */ set_resolve_port(-1); grpc_server_shutdown_and_notify(server1, cq, tag(0xdead1)); - cq_expect_completion(cqv, tag(0x9999), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x9999), 1); cq_verify(cqv); cq_verify_empty(cqv); @@ -250,8 +250,8 @@ int main(int argc, char **argv) { &request_metadata2, cq, cq, tag(0x401))); /* second call should now start */ - cq_expect_completion(cqv, tag(0x201), 1); - cq_expect_completion(cqv, tag(0x401), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x201), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x401), 1); cq_verify(cqv); /* listen for close on the server call to probe for finishing */ @@ -273,12 +273,12 @@ int main(int argc, char **argv) { grpc_call_cancel(call2, NULL); /* now everything else should finish */ - cq_expect_completion(cqv, tag(0x102), 1); - cq_expect_completion(cqv, tag(0x202), 1); - cq_expect_completion(cqv, tag(0x302), 1); - cq_expect_completion(cqv, tag(0x402), 1); - cq_expect_completion(cqv, tag(0xdead1), 1); - cq_expect_completion(cqv, tag(0xdead2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x202), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x302), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x402), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead2), 1); cq_verify(cqv); grpc_call_destroy(call1); diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c index 35456607012..2b9904a2441 100644 --- a/test/core/end2end/invalid_call_argument_test.c +++ b/test/core/end2end/invalid_call_argument_test.c @@ -116,8 +116,8 @@ static void prepare_test(int is_client) { &g_state.call_details, &g_state.server_initial_metadata_recv, g_state.cq, g_state.cq, tag(101))); - cq_expect_completion(g_state.cqv, tag(101), 1); - cq_expect_completion(g_state.cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 1); cq_verify(g_state.cqv); } } @@ -191,7 +191,7 @@ static void test_send_initial_metadata_more_than_once() { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, (size_t)(op - g_state.ops), tag(1), NULL)); - cq_expect_completion(g_state.cqv, tag(1), 0); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 0); cq_verify(g_state.cqv); op = g_state.ops; @@ -312,7 +312,7 @@ static void test_receive_initial_metadata_twice_at_client() { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, (size_t)(op - g_state.ops), tag(1), NULL)); - cq_expect_completion(g_state.cqv, tag(1), 0); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 0); cq_verify(g_state.cqv); op = g_state.ops; op->op = GRPC_OP_RECV_INITIAL_METADATA; @@ -405,7 +405,7 @@ static void test_recv_status_on_client_twice() { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, (size_t)(op - g_state.ops), tag(1), NULL)); - cq_expect_completion(g_state.cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 1); cq_verify(g_state.cqv); op = g_state.ops; diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c index 08af3821971..03ff70a1881 100644 --- a/test/core/end2end/no_server_test.c +++ b/test/core/end2end/no_server_test.c @@ -86,7 +86,7 @@ int main(int argc, char **argv) { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch( call, ops, (size_t)(op - ops), tag(1), NULL)); /* verify that all tags get completed */ - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index c9663c2155e..e0c7ac7c021 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -150,7 +148,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c index 3dd26120777..6b105def33c 100644 --- a/test/core/end2end/tests/binary_metadata.c +++ b/test/core/end2end/tests/binary_metadata.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -199,7 +197,7 @@ static void test_request_response_with_metadata_and_payload( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -218,7 +216,7 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -243,8 +241,8 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c index 694a0aa9ef4..981c0fcc8c5 100644 --- a/test/core/end2end/tests/call_creds.c +++ b/test/core/end2end/tests/call_creds.c @@ -53,8 +53,6 @@ static const char overridden_iam_selector[] = "overridden_selector"; typedef enum { NONE, OVERRIDE, DESTROY } override_mode; -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -234,7 +232,7 @@ static void request_response_with_payload_and_call_creds( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); s_auth_context = grpc_call_auth_context(s); GPR_ASSERT(s_auth_context != NULL); @@ -264,7 +262,7 @@ static void request_response_with_payload_and_call_creds( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -289,8 +287,8 @@ static void request_response_with_payload_and_call_creds( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); @@ -450,7 +448,7 @@ static void test_request_with_server_rejecting_client_creds( error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(error == GRPC_CALL_OK); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNAUTHENTICATED); diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 51c13da3b1e..b4ac3b3249b 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -172,7 +170,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -202,8 +200,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL)); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c index 2b5a409deef..5adc71e2552 100644 --- a/test/core/end2end/tests/cancel_after_client_done.c +++ b/test/core/end2end/tests/cancel_after_client_done.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -176,7 +174,7 @@ static void test_cancel_after_accept_and_writes_closed( error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -206,8 +204,8 @@ static void test_cancel_after_accept_and_writes_closed( GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL)); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index 85fbe9de7bb..85d8799f36d 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -170,7 +168,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL)); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index d99062c6082..c57091476e4 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -168,7 +166,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config, error = grpc_call_start_batch(c, ops, test_ops, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_CANCELLED); diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 0c893b5f9ef..3b03616b3bb 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c index 673c7051ad1..e65390ac4a5 100644 --- a/test/core/end2end/tests/cancel_with_status.c +++ b/test/core/end2end/tests/cancel_with_status.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -152,7 +150,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t num_ops) { grpc_call_cancel_with_status(c, GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index ec5c012238e..1724da4d0cf 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -50,8 +50,6 @@ #include "src/core/lib/surface/call_test_only.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -198,7 +196,7 @@ static void request_for_disabled_algorithm( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), true); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); cq_verify(cqv); op = ops; @@ -215,7 +213,7 @@ static void request_for_disabled_algorithm( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), false); + CQ_EXPECT_COMPLETION(cqv, tag(102), false); op = ops; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; @@ -226,8 +224,8 @@ static void request_for_disabled_algorithm( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), true); - cq_expect_completion(cqv, tag(1), true); + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); cq_verify(cqv); /* call was cancelled (closed) ... */ @@ -361,7 +359,7 @@ static void request_with_payload_template( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(100)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(100), true); + CQ_EXPECT_COMPLETION(cqv, tag(100), true); cq_verify(cqv); GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer( @@ -421,7 +419,7 @@ static void request_with_payload_template( op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW); @@ -438,8 +436,8 @@ static void request_with_payload_template( op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW); @@ -484,10 +482,10 @@ static void request_with_payload_template( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(101), 1); - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/connectivity.c b/test/core/end2end/tests/connectivity.c index 5775976b1cb..260297ebd4d 100644 --- a/test/core/end2end/tests/connectivity.c +++ b/test/core/end2end/tests/connectivity.c @@ -102,7 +102,7 @@ static void test_connectivity(grpc_end2end_test_config config) { f.cq, tag(2)); /* and now the watch should trigger */ - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || @@ -112,7 +112,7 @@ static void test_connectivity(grpc_end2end_test_config config) { grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_CONNECTING, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(3)); - cq_expect_completion(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || @@ -130,7 +130,7 @@ static void test_connectivity(grpc_end2end_test_config config) { while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(4)); - cq_expect_completion(cqv, tag(4), 1); + CQ_EXPECT_COMPLETION(cqv, tag(4), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -148,8 +148,8 @@ static void test_connectivity(grpc_end2end_test_config config) { grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); - cq_expect_completion(cqv, tag(5), 1); - cq_expect_completion(cqv, tag(0xdead), 1); + CQ_EXPECT_COMPLETION(cqv, tag(5), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index 728ee597b50..208e31697e6 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -162,7 +160,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(error == GRPC_CALL_OK); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); peer = grpc_call_get_peer(s); @@ -196,8 +194,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(error == GRPC_CALL_OK); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c index 536fbd0d8a8..a0059b9ad59 100644 --- a/test/core/end2end/tests/disappearing_server.c +++ b/test/core/end2end/tests/disappearing_server.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { @@ -139,7 +137,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, grpc_server_request_call(f->server, &s, &call_details, &request_metadata_recv, f->cq, f->cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); /* should be able to shut down the server early @@ -168,9 +166,9 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); - cq_expect_completion(cqv, tag(1000), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1000), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index c05b9199146..ac53e1839be 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -112,7 +110,7 @@ static void empty_batch_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(c, op, 0, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_call_destroy(c); diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c new file mode 100644 index 00000000000..a70f50af988 --- /dev/null +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -0,0 +1,273 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "src/core/lib/channel/channel_stack_builder.h" +#include "src/core/lib/surface/channel_init.h" +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static bool g_enable_filter = false; + +static void *tag(intptr_t t) { return (void *)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +// Simple request via a server filter that always fails to initialize +// the call. +static void test_request(grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); + grpc_byte_buffer *request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + grpc_end2end_test_fixture f = + begin_test(config, "filter_call_init_fails", NULL, NULL); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *request_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr", deadline, NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->data.send_initial_metadata.metadata = NULL; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED); + GPR_ASSERT(0 == strcmp(details, "access denied")); + + gpr_free(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(request_payload_recv); + + end_test(&f); + config.tear_down_data(&f); +} + +/******************************************************************************* + * Test filter - always fails to initialize a call + */ + +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + return grpc_error_set_int(GRPC_ERROR_CREATE("access denied"), + GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_PERMISSION_DENIED); +} + +static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, + const grpc_call_final_info *final_info, + void *and_free_memory) {} + +static void init_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem, + grpc_channel_element_args *args) {} + +static void destroy_channel_elem(grpc_exec_ctx *exec_ctx, + grpc_channel_element *elem) {} + +static const grpc_channel_filter test_filter = { + grpc_call_next_op, + grpc_channel_next_op, + 0, + init_call_elem, + grpc_call_stack_ignore_set_pollset_or_pollset_set, + destroy_call_elem, + 0, + init_channel_elem, + destroy_channel_elem, + grpc_call_next_get_peer, + "filter_call_init_fails"}; + +/******************************************************************************* + * Registration + */ + +static bool maybe_add_filter(grpc_channel_stack_builder *builder, void *arg) { + if (g_enable_filter) { + // Want to add the filter as close to the end as possible, to make + // sure that all of the filters work well together. However, we + // can't add it at the very end, because the connected channel filter + // must be the last one. So we add it right before the last one. + grpc_channel_stack_builder_iterator *it = + grpc_channel_stack_builder_create_iterator_at_last(builder); + GPR_ASSERT(grpc_channel_stack_builder_move_prev(it)); + const bool retval = grpc_channel_stack_builder_add_filter_before( + it, &test_filter, NULL, NULL); + grpc_channel_stack_builder_iterator_destroy(it); + return retval; + } else { + return true; + } +} + +static void init_plugin(void) { + grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, + maybe_add_filter, NULL); +} + +static void destroy_plugin(void) {} + +void filter_call_init_fails(grpc_end2end_test_config config) { + g_enable_filter = true; + test_request(config); + g_enable_filter = false; +} + +void filter_call_init_fails_pre_init(void) { + grpc_register_plugin(init_plugin, destroy_plugin); +} diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c index 526c05ca3e8..cdf868377ae 100644 --- a/test/core/end2end/tests/filter_causes_close.c +++ b/test/core/end2end/tests/filter_causes_close.c @@ -46,8 +46,6 @@ #include "src/core/lib/surface/channel_init.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static bool g_enable_filter = false; static void *tag(intptr_t t) { return (void *)t; } @@ -172,7 +170,7 @@ static void test_request(grpc_end2end_test_config config) { &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED); @@ -233,11 +231,14 @@ static void start_transport_stream_op(grpc_exec_ctx *exec_ctx, grpc_call_next_op(exec_ctx, elem, op); } -static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - grpc_call_element_args *args) {} +static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, + grpc_call_element *elem, + grpc_call_element_args *args) { + return GRPC_ERROR_NONE; +} static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, - const grpc_call_stats *stats, + const grpc_call_final_info *final_info, void *and_free_memory) {} static void init_channel_elem(grpc_exec_ctx *exec_ctx, diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c index f527b8617d9..29347a068ae 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.c +++ b/test/core/end2end/tests/graceful_server_shutdown.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -154,7 +152,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); /* shutdown and destroy the server */ @@ -183,9 +181,9 @@ static void test_early_server_shutdown_finishes_inflight_calls( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(0xdead), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_call_destroy(s); diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index db45f5eb5ad..dab527005cf 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -47,8 +47,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -159,7 +157,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -184,8 +182,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c index 7ff0461f5f6..fb00ae4eaaa 100644 --- a/test/core/end2end/tests/hpack_size.c +++ b/test/core/end2end/tests/hpack_size.c @@ -310,7 +310,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t index) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -335,8 +335,8 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t index) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c index dfedcfebee8..65f6dd08c5a 100644 --- a/test/core/end2end/tests/idempotent_request.c +++ b/test/core/end2end/tests/idempotent_request.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -163,7 +161,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); peer = grpc_call_get_peer(s); @@ -197,8 +195,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 9c9ca951293..1df237cb6c4 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -39,12 +39,11 @@ #include #include #include +#include #include #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -101,9 +100,25 @@ static gpr_slice large_slice(void) { return slice; } -static void test_invoke_large_request(grpc_end2end_test_config config) { +static void test_invoke_large_request(grpc_end2end_test_config config, + int max_frame_size, int lookahead_bytes) { + char *name; + gpr_asprintf(&name, + "test_invoke_large_request:max_frame_size=%d:lookahead_bytes=%d", + max_frame_size, lookahead_bytes); + + grpc_arg args[2]; + args[0].type = GRPC_ARG_INTEGER; + args[0].key = GRPC_ARG_HTTP2_MAX_FRAME_SIZE; + args[0].value.integer = max_frame_size; + args[1].type = GRPC_ARG_INTEGER; + args[1].key = GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES; + args[1].value.integer = lookahead_bytes; + grpc_channel_args channel_args = {GPR_ARRAY_SIZE(args), args}; + grpc_end2end_test_fixture f = - begin_test(config, "test_invoke_large_request", NULL, NULL); + begin_test(config, name, &channel_args, &channel_args); + gpr_free(name); gpr_slice request_payload_slice = large_slice(); gpr_slice response_payload_slice = large_slice(); @@ -179,7 +194,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -197,7 +212,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -222,8 +237,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); @@ -255,7 +270,26 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { } void invoke_large_request(grpc_end2end_test_config config) { - test_invoke_large_request(config); + test_invoke_large_request(config, 16384, 65536); + test_invoke_large_request(config, 32768, 65536); + + test_invoke_large_request(config, 1000000 - 1, 65536); + test_invoke_large_request(config, 1000000, 65536); + test_invoke_large_request(config, 1000000 + 1, 65536); + test_invoke_large_request(config, 1000000 + 2, 65536); + test_invoke_large_request(config, 1000000 + 3, 65536); + test_invoke_large_request(config, 1000000 + 4, 65536); + test_invoke_large_request(config, 1000000 + 5, 65536); + test_invoke_large_request(config, 1000000 + 6, 65536); + + test_invoke_large_request(config, 1000000 - 1, 2000000); + test_invoke_large_request(config, 1000000, 2000000); + test_invoke_large_request(config, 1000000 + 1, 2000000); + test_invoke_large_request(config, 1000000 + 2, 2000000); + test_invoke_large_request(config, 1000000 + 3, 2000000); + test_invoke_large_request(config, 1000000 + 4, 2000000); + test_invoke_large_request(config, 1000000 + 5, 2000000); + test_invoke_large_request(config, 1000000 + 6, 2000000); } void invoke_large_request_pre_init(void) {} diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c index 1f278960196..eb174a2dbb7 100644 --- a/test/core/end2end/tests/large_metadata.c +++ b/test/core/end2end/tests/large_metadata.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -181,7 +179,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -200,7 +198,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -222,8 +220,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c new file mode 100644 index 00000000000..59d054cf877 --- /dev/null +++ b/test/core/end2end/tests/load_reporting_hook.c @@ -0,0 +1,321 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include + +#include +#include +#include +#include +#include +#include +#include "test/core/end2end/cq_verifier.h" + +#include "src/core/ext/load_reporting/load_reporting.h" +#include "src/core/ext/load_reporting/load_reporting_filter.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/transport/static_metadata.h" + +enum { TIMEOUT = 200000 }; + +static void *tag(intptr_t t) { return (void *)t; } + +typedef struct { + gpr_mu mu; + intptr_t channel_id; + intptr_t call_id; + + char *initial_md_str; + char *trailing_md_str; + char *method_name; + + uint64_t incoming_bytes; + uint64_t outgoing_bytes; + + grpc_status_code call_final_status; + + bool fully_processed; +} load_reporting_data; + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +static void request_response_with_payload(grpc_end2end_test_fixture f, + const char *method_name, + const char *request_msg, + const char *response_msg, + grpc_metadata *initial_lr_metadata, + grpc_metadata *trailing_lr_metadata) { + gpr_slice request_payload_slice = gpr_slice_from_static_string(request_msg); + gpr_slice response_payload_slice = gpr_slice_from_static_string(response_msg); + grpc_call *c; + grpc_call *s; + grpc_byte_buffer *request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer *response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *request_payload_recv = NULL; + grpc_byte_buffer *response_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + int was_cancelled = 2; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + method_name, "foo.test.google.fr", deadline, + NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + GPR_ASSERT(initial_lr_metadata != NULL); + op->data.send_initial_metadata.count = 1; + op->data.send_initial_metadata.metadata = initial_lr_metadata; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + GPR_ASSERT(trailing_lr_metadata != NULL); + op->data.send_status_from_server.trailing_metadata_count = 1; + op->data.send_status_from_server.trailing_metadata = trailing_lr_metadata; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = "xyz"; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_OK); + + gpr_free(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + grpc_call_destroy(s); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); +} + +/* override the default for testing purposes */ +extern void (*g_load_reporting_fn)( + const grpc_load_reporting_call_data *call_data); + +static void test_load_reporting_hook(grpc_end2end_test_config config) { + /* TODO(dgq): this test is currently a noop until LR is fully defined. + * Leaving the rest here, as it'll likely be reusable. */ + + /* Introduce load reporting for the server through its arguments */ + grpc_arg arg = grpc_load_reporting_enable_arg(); + grpc_channel_args *lr_server_args = + grpc_channel_args_copy_and_add(NULL, &arg, 1); + + grpc_end2end_test_fixture f = + begin_test(config, "test_load_reporting_hook", NULL, lr_server_args); + + const char *method_name = "/gRPCFTW"; + const char *request_msg = "the msg from the client"; + const char *response_msg = "... and the response from the server"; + + grpc_metadata initial_lr_metadata; + grpc_metadata trailing_lr_metadata; + + initial_lr_metadata.key = GRPC_LOAD_REPORTING_INITIAL_MD_KEY; + initial_lr_metadata.value = "client-token"; + initial_lr_metadata.value_length = strlen(initial_lr_metadata.value); + memset(&initial_lr_metadata.internal_data, 0, + sizeof(initial_lr_metadata.internal_data)); + + trailing_lr_metadata.key = GRPC_LOAD_REPORTING_TRAILING_MD_KEY; + trailing_lr_metadata.value = "server-token"; + trailing_lr_metadata.value_length = strlen(trailing_lr_metadata.value); + memset(&trailing_lr_metadata.internal_data, 0, + sizeof(trailing_lr_metadata.internal_data)); + + request_response_with_payload(f, method_name, request_msg, response_msg, + &initial_lr_metadata, &trailing_lr_metadata); + end_test(&f); + grpc_channel_args_destroy(lr_server_args); + config.tear_down_data(&f); +} + +void load_reporting_hook(grpc_end2end_test_config config) { + test_load_reporting_hook(config); +} + +void load_reporting_hook_pre_init(void) {} diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 41de74ff874..65fa9468387 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -155,7 +153,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -180,8 +178,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); @@ -382,17 +380,17 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { error = grpc_call_start_batch(s1, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(live_call + 2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(live_call + 2), 1); /* first request is finished, we should be able to start the second */ live_call = (live_call == 300) ? 400 : 300; - cq_expect_completion(cqv, tag(live_call + 1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(live_call + 1), 1); cq_verify(cqv); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( f.server, &s2, &call_details, &request_metadata_recv, f.cq, f.cq, tag(201))); - cq_expect_completion(cqv, tag(201), 1); + CQ_EXPECT_COMPLETION(cqv, tag(201), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -417,8 +415,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { error = grpc_call_start_batch(s2, ops, (size_t)(op - ops), tag(202), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(live_call + 2), 1); - cq_expect_completion(cqv, tag(202), 1); + CQ_EXPECT_COMPLETION(cqv, tag(live_call + 2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(202), 1); cq_verify(cqv); cq_verifier_destroy(cqv); diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 08d326ab4d6..43f71f51d15 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -179,7 +177,7 @@ static void test_max_message_length(grpc_end2end_test_config config) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -197,8 +195,8 @@ static void test_max_message_length(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status != GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c index dff7992f63b..c999ac116aa 100644 --- a/test/core/end2end/tests/negative_deadline.c +++ b/test/core/end2end/tests/negative_deadline.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -150,7 +148,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t num_ops) { error = grpc_call_start_batch(c, ops, num_ops, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c index 39ddc137543..1d4b6dbb18f 100644 --- a/test/core/end2end/tests/network_status_change.c +++ b/test/core/end2end/tests/network_status_change.c @@ -46,8 +46,6 @@ /* this is a private API but exposed here for testing*/ extern void grpc_network_status_shutdown_all_endpoints(); -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -168,7 +166,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101))); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); op = ops; @@ -185,7 +183,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); // Simulate the network loss event @@ -207,8 +205,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); // Expected behavior of a RPC when network is lost. diff --git a/test/core/end2end/tests/no_logging.c b/test/core/end2end/tests/no_logging.c new file mode 100644 index 00000000000..3c40e5dbacd --- /dev/null +++ b/test/core/end2end/tests/no_logging.c @@ -0,0 +1,293 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/support/string.h" +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static void *tag(intptr_t t) { return (void *)t; } + +extern void gpr_default_log(gpr_log_func_args *args); + +static void test_no_log(gpr_log_func_args *args) { + char *message = NULL; + gpr_asprintf(&message, "Unwanted log: %s", args->message); + args->message = message; + gpr_default_log(args); + gpr_free(message); + abort(); +} + +static void test_no_error_log(gpr_log_func_args *args) { + if (args->severity == GPR_LOG_SEVERITY_ERROR) { + test_no_log(args); + } +} + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +static void simple_request_body(grpc_end2end_test_fixture f) { + grpc_call *c; + grpc_call *s; + gpr_timespec deadline = five_seconds_time(); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + int was_cancelled = 2; + char *peer; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr:1234", deadline, + NULL); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != NULL); + gpr_free(peer); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != NULL); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != NULL); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + op->data.send_status_from_server.status_details = "xyz"; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == strcmp(details, "xyz")); + GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + gpr_free(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + grpc_call_destroy(s); + + cq_verifier_destroy(cqv); +} + +static void test_invoke_simple_request(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + f = begin_test(config, "test_invoke_simple_request_with_no_error_logging", + NULL, NULL); + simple_request_body(f); + end_test(&f); + config.tear_down_data(&f); +} + +static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { + int i; + grpc_end2end_test_fixture f = + begin_test(config, "test_invoke_10_simple_requests_with_no_error_logging", + NULL, NULL); + for (i = 0; i < 10; i++) { + simple_request_body(f); + gpr_log(GPR_INFO, "Passed simple request %d", i); + } + simple_request_body(f); + end_test(&f); + config.tear_down_data(&f); +} + +static void test_no_error_logging_in_entire_process( + grpc_end2end_test_config config) { + int i; + gpr_set_log_function(test_no_error_log); + for (i = 0; i < 10; i++) { + test_invoke_simple_request(config); + } + test_invoke_10_simple_requests(config); + gpr_set_log_function(gpr_default_log); +} + +static void test_no_logging_in_one_request(grpc_end2end_test_config config) { + int i; + grpc_end2end_test_fixture f = + begin_test(config, "test_no_logging_in_last_request", NULL, NULL); + for (i = 0; i < 10; i++) { + simple_request_body(f); + } + gpr_set_log_function(test_no_log); + simple_request_body(f); + gpr_set_log_function(gpr_default_log); + end_test(&f); + config.tear_down_data(&f); +} + +void no_logging(grpc_end2end_test_config config) { + test_no_logging_in_one_request(config); + test_no_error_logging_in_entire_process(config); +} + +void no_logging_pre_init(void) {} diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 284be7af2ae..8b29c219dcf 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index 443d85eecc4..c71704ff61f 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -172,7 +170,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -190,7 +188,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -215,8 +213,8 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/ping.c b/test/core/end2end/tests/ping.c index d49bec983be..5e5169dedce 100644 --- a/test/core/end2end/tests/ping.c +++ b/test/core/end2end/tests/ping.c @@ -52,7 +52,7 @@ static void test_ping(grpc_end2end_test_config config) { config.init_server(&f, NULL); grpc_channel_ping(f.client, f.cq, tag(0), NULL); - cq_expect_completion(cqv, tag(0), 0); + CQ_EXPECT_COMPLETION(cqv, tag(0), 0); /* check that we're still in idle, and start connecting */ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) == @@ -62,7 +62,7 @@ static void test_ping(grpc_end2end_test_config config) { while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(99)); - cq_expect_completion(cqv, tag(99), 1); + CQ_EXPECT_COMPLETION(cqv, tag(99), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -72,12 +72,12 @@ static void test_ping(grpc_end2end_test_config config) { for (i = 1; i <= 5; i++) { grpc_channel_ping(f.client, f.cq, tag(i), NULL); - cq_expect_completion(cqv, tag(i), 1); + CQ_EXPECT_COMPLETION(cqv, tag(i), 1); cq_verify(cqv); } grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); - cq_expect_completion(cqv, tag(0xdead), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); cq_verify(cqv); /* cleanup server */ diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index 1d2f7943c1d..7e360c415b1 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -162,7 +160,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(100)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(100), 1); + CQ_EXPECT_COMPLETION(cqv, tag(100), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -208,7 +206,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -220,8 +218,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); grpc_byte_buffer_destroy(request_payload); @@ -254,10 +252,10 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(101), 1); - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); cq_verify(cqv); grpc_call_destroy(c); diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index ece6250ea13..9b2b42b5583 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -156,7 +154,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, void *rc) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -181,8 +179,8 @@ static void simple_request_body(grpc_end2end_test_fixture f, void *rc) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index b5d398bba9f..25150e6f2d6 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -44,8 +44,6 @@ #include "src/core/lib/transport/byte_stream.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -165,7 +163,7 @@ static void test_invoke_request_with_flags( GPR_ASSERT(expectation == error); if (expectation == GRPC_CALL_OK) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); } diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index d94267e09cf..67208c050c1 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -165,7 +163,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101))); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -183,7 +181,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -203,8 +201,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c index a723c6fd2ca..7fb9025aa38 100644 --- a/test/core/end2end/tests/server_finishes_request.c +++ b/test/core/end2end/tests/server_finishes_request.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -153,7 +151,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -178,8 +176,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c index abb6b26a875..dff2e6f2809 100644 --- a/test/core/end2end/tests/shutdown_finishes_calls.c +++ b/test/core/end2end/tests/shutdown_finishes_calls.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -147,7 +145,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -164,9 +162,9 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_shutdown_and_notify(f.server, f.cq, tag(1000)); grpc_server_cancel_all_calls(f.server); - cq_expect_completion(cqv, tag(1000), 1); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1000), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_server_destroy(f.server); diff --git a/test/core/end2end/tests/shutdown_finishes_tags.c b/test/core/end2end/tests/shutdown_finishes_tags.c index b1f3c94562a..1d110a74eac 100644 --- a/test/core/end2end/tests/shutdown_finishes_tags.c +++ b/test/core/end2end/tests/shutdown_finishes_tags.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -104,8 +102,8 @@ static void test_early_server_shutdown_finishes_tags( f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101))); grpc_server_shutdown_and_notify(f.server, f.cq, tag(1000)); - cq_expect_completion(cqv, tag(101), 0); - cq_expect_completion(cqv, tag(1000), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 0); + CQ_EXPECT_COMPLETION(cqv, tag(1000), 1); cq_verify(cqv); GPR_ASSERT(s == NULL); diff --git a/test/core/end2end/tests/simple_cacheable_request.c b/test/core/end2end/tests/simple_cacheable_request.c new file mode 100644 index 00000000000..b52eb19315e --- /dev/null +++ b/test/core/end2end/tests/simple_cacheable_request.c @@ -0,0 +1,276 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include +#include + +#include +#include +#include +#include +#include +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static void *tag(intptr_t t) { return (void *)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +/* Request/response with metadata and payload.*/ +static void test_cacheable_request_response_with_metadata_and_payload( + grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); + gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); + grpc_byte_buffer *request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer *response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + grpc_metadata meta_c[2] = { + {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}}, + {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}}; + grpc_metadata meta_s[2] = { + {"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}}, + {"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}}; + grpc_end2end_test_fixture f = begin_test( + config, "test_cacheable_request_response_with_metadata_and_payload", NULL, + NULL); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *request_payload_recv = NULL; + grpc_byte_buffer *response_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + int was_cancelled = 2; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr", deadline, NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 2; + op->data.send_initial_metadata.metadata = meta_c; + op->flags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 2; + op->data.send_initial_metadata.metadata = meta_s; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = "xyz"; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(0 == strcmp(details, "xyz")); + GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); + if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { + // Our simple proxy does not support cacheable requests + } else { + GPR_ASSERT(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST & call_details.flags); + } + GPR_ASSERT(was_cancelled == 0); + GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); + GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); + GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1")); + GPR_ASSERT(contains_metadata(&request_metadata_recv, "key2", "val2")); + GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key3", "val3")); + GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key4", "val4")); + + gpr_free(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + grpc_call_destroy(s); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + end_test(&f); + config.tear_down_data(&f); +} + +void simple_cacheable_request(grpc_end2end_test_config config) { + test_cacheable_request_response_with_metadata_and_payload(config); +} + +void simple_cacheable_request_pre_init(void) {} diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index e1fcc035bbd..74f1232d786 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { @@ -150,7 +148,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, grpc_server_request_call(f->server, &s, &call_details, &request_metadata_recv, f->cq, f->cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -175,8 +173,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c index c9b1a03da52..13c77c033e0 100644 --- a/test/core/end2end/tests/simple_metadata.c +++ b/test/core/end2end/tests/simple_metadata.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -183,7 +181,7 @@ static void test_request_response_with_metadata_and_payload( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -202,7 +200,7 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -227,8 +225,8 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index a8014e6894c..ed7b850808a 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -163,7 +161,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); peer = grpc_call_get_peer(s); @@ -197,8 +195,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/streaming_error_response.c b/test/core/end2end/tests/streaming_error_response.c index e15c132d633..8285468321c 100644 --- a/test/core/end2end/tests/streaming_error_response.c +++ b/test/core/end2end/tests/streaming_error_response.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -163,7 +161,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101))); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -177,7 +175,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -188,9 +186,9 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); if (!request_status_early) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } cq_verify(cqv); @@ -217,11 +215,11 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { GPR_ASSERT(GRPC_CALL_OK == error); } - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); if (request_status_early) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } else { - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); } cq_verify(cqv); @@ -237,7 +235,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); cq_verify(cqv); GPR_ASSERT(response_payload1_recv != NULL); diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c index 41e0f009113..d7093ae7239 100644 --- a/test/core/end2end/tests/trailing_metadata.c +++ b/test/core/end2end/tests/trailing_metadata.c @@ -43,8 +43,6 @@ #include #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -186,7 +184,7 @@ static void test_request_response_with_metadata_and_payload( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -205,7 +203,7 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -231,8 +229,8 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index 3152fb7a464..a959a7e07fa 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -70,7 +70,8 @@ static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, g_number_of_reads++; g_number_of_bytes_read += (int)byte_count; - grpc_pollset_kick(g_pollset, NULL); + GPR_ASSERT( + GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(g_pollset, NULL))); gpr_mu_unlock(g_mu); } @@ -179,8 +180,10 @@ static void test_receive(int number_of_clients) { while (g_number_of_reads == number_of_reads_before && gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) { grpc_pollset_worker *worker = NULL; - grpc_pollset_work(&exec_ctx, g_pollset, &worker, - gpr_now(GPR_CLOCK_MONOTONIC), deadline); + GPR_ASSERT(GRPC_LOG_IF_ERROR( + "pollset_work", + grpc_pollset_work(&exec_ctx, g_pollset, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), deadline))); gpr_mu_unlock(g_mu); grpc_exec_ctx_finish(&exec_ctx); gpr_mu_lock(g_mu); @@ -199,7 +202,8 @@ static void test_receive(int number_of_clients) { GPR_ASSERT(g_number_of_orphan_calls == 1); } -static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) { +static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, + grpc_error *error) { grpc_pollset_destroy(p); } diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index ac1abbd8f3d..7ea5caca5b1 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/core/nanopb/fuzzer_response.c b/test/core/nanopb/fuzzer_response.c index 21a5d7b9685..75a99faf3f3 100644 --- a/test/core/nanopb/fuzzer_response.c +++ b/test/core/nanopb/fuzzer_response.c @@ -43,9 +43,9 @@ bool leak_check = true; int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); - grpc_grpclb_response *response; - if ((response = grpc_grpclb_response_parse(slice))) { - grpc_grpclb_response_destroy(response); + grpc_grpclb_initial_response *response; + if ((response = grpc_grpclb_initial_response_parse(slice))) { + grpc_grpclb_initial_response_destroy(response); } gpr_slice_unref(slice); return 0; diff --git a/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 b/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 new file mode 100644 index 00000000000..a0c7605580a --- /dev/null +++ b/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 @@ -0,0 +1 @@ +:Ê%cE'yzŠ \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 b/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 new file mode 100644 index 00000000000..8b36124b3fb --- /dev/null +++ b/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 @@ -0,0 +1 @@ +x;x_%C88 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 b/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 new file mode 100644 index 00000000000..ea02afac49b --- /dev/null +++ b/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 @@ -0,0 +1,2 @@ +xxyyz%øyzŠ[zxy'z + diff --git a/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 b/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 new file mode 100644 index 00000000000..9e9b466b2f7 --- /dev/null +++ b/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 @@ -0,0 +1 @@ +xx;x_%;:Ê%C)x_%C88c8E'yzŠ8 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb b/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb new file mode 100644 index 00000000000..88c739ecaa1 --- /dev/null +++ b/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb @@ -0,0 +1 @@ +))'x;x_%C88xy(Pyz) \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 b/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 new file mode 100644 index 00000000000..5e6f546ff5c --- /dev/null +++ b/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 @@ -0,0 +1 @@ +_x;x)x;x_x;x_%88%8888: \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a b/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a new file mode 100644 index 00000000000..71d688b694e --- /dev/null +++ b/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a @@ -0,0 +1 @@ +x8 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 b/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 new file mode 100644 index 00000000000..5a89a07ba76 --- /dev/null +++ b/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 @@ -0,0 +1 @@ +x);x(_%88x;x_%88 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 b/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 new file mode 100644 index 00000000000..cfa2be994fb --- /dev/null +++ b/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 @@ -0,0 +1 @@ +)x;x_x;x_%88%88: \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 b/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 new file mode 100644 index 00000000000..c1ddf65acd2 --- /dev/null +++ b/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 @@ -0,0 +1 @@ +%cyzŠ \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 b/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 new file mode 100644 index 00000000000..dc427d1e120 --- /dev/null +++ b/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 @@ -0,0 +1 @@ +%øyzŠ \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d b/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d new file mode 100644 index 00000000000..154449d0efe --- /dev/null +++ b/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d @@ -0,0 +1 @@ +Ê:%Ec \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 b/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 new file mode 100644 index 00000000000..841ced83c3f --- /dev/null +++ b/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 @@ -0,0 +1,2 @@ +xxyyz!úyzŠ[zxy'zyz +Š diff --git a/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f b/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f new file mode 100644 index 00000000000..6790bc27984 --- /dev/null +++ b/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f @@ -0,0 +1 @@ +x;:Ê%)x_%C8cE'yzŠ8 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 b/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 new file mode 100644 index 00000000000..1625d0a1aed --- /dev/null +++ b/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 @@ -0,0 +1 @@ +x;x_%88 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 b/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 new file mode 100644 index 00000000000..125c330b3e4 --- /dev/null +++ b/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 @@ -0,0 +1 @@ +)))'x;x_%C88)'x;x_%C89xyyzxyyz) \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 b/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 new file mode 100644 index 00000000000..6e6f08cb07f --- /dev/null +++ b/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 @@ -0,0 +1 @@ +))'x;x_%C88xyyz) \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 b/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 new file mode 100644 index 00000000000..ab4a1c7657b --- /dev/null +++ b/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 @@ -0,0 +1 @@ +x%8 \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae b/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae new file mode 100644 index 00000000000..4ac1945a847 --- /dev/null +++ b/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae @@ -0,0 +1 @@ +x);x(_%88x;x_xxyyz \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 b/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 new file mode 100644 index 00000000000..5c673ae28a7 --- /dev/null +++ b/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 @@ -0,0 +1 @@ +Ê%ccyzyzŠ \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b b/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b new file mode 100644 index 00000000000..e478275ed4f --- /dev/null +++ b/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b @@ -0,0 +1,2 @@ +)'xyyz!úyzŠ[zxÊ%ccyzyzy'z*zŠ +Š diff --git a/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 b/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 new file mode 100644 index 00000000000..c73cbfe8aff --- /dev/null +++ b/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 @@ -0,0 +1,2 @@ +)'xyyz)úyzŠ[zxÊ%cCyzyzy'z*zŠ +Š diff --git a/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 b/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 new file mode 100644 index 00000000000..f9f7246e9c9 --- /dev/null +++ b/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 @@ -0,0 +1,2 @@ +xxyyz%%øyzŠ[zxy'zyz +Š diff --git a/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a b/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a new file mode 100644 index 00000000000..83ac46d8337 --- /dev/null +++ b/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a @@ -0,0 +1 @@ +Ê:%Dx;:Ê%)x_%C8cc \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a b/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a new file mode 100644 index 00000000000..e8a0f87653d --- /dev/null +++ b/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a @@ -0,0 +1 @@ +) \ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/xyz b/test/core/support/percent_decode_corpus/xyz new file mode 100644 index 00000000000..cd470e61900 --- /dev/null +++ b/test/core/support/percent_decode_corpus/xyz @@ -0,0 +1 @@ +xyz diff --git a/test/core/support/percent_decode_fuzzer.c b/test/core/support/percent_decode_fuzzer.c new file mode 100644 index 00000000000..3e02980e05e --- /dev/null +++ b/test/core/support/percent_decode_fuzzer.c @@ -0,0 +1,66 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include + +#include "src/core/lib/support/percent_encoding.h" +#include "test/core/util/memory_counters.h" + +bool squelch = true; +bool leak_check = true; + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct grpc_memory_counters counters; + grpc_memory_counters_init(); + gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size); + gpr_slice output; + if (gpr_strict_percent_decode_slice( + input, gpr_url_percent_encoding_unreserved_bytes, &output)) { + gpr_slice_unref(output); + } + if (gpr_strict_percent_decode_slice( + input, gpr_compatible_percent_encoding_unreserved_bytes, &output)) { + gpr_slice_unref(output); + } + gpr_slice_unref(gpr_permissive_percent_decode_slice(input)); + gpr_slice_unref(input); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + return 0; +} diff --git a/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f b/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f new file mode 100644 index 00000000000..d09c4a039c0 --- /dev/null +++ b/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f @@ -0,0 +1,3 @@ +_x;7y +xyz')S)xy-zý +Æ* \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 b/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 new file mode 100644 index 00000000000..4d0c38d0e27 --- /dev/null +++ b/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 @@ -0,0 +1 @@ +xyx \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf b/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf new file mode 100644 index 00000000000..fc6e93342a6 --- /dev/null +++ b/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf @@ -0,0 +1 @@ +.yx.yxxxyzxyyzxy \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 b/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 new file mode 100644 index 00000000000..6823c73f767 --- /dev/null +++ b/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 @@ -0,0 +1 @@ +xyrxyxyzxxyzxyzxyxyy \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 b/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 new file mode 100644 index 00000000000..a65cbb4d5be --- /dev/null +++ b/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 @@ -0,0 +1,3 @@ +xy +xyz +)S-Æþ \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a b/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a new file mode 100644 index 00000000000..8d031d7e2d8 --- /dev/null +++ b/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a @@ -0,0 +1,3 @@ +xy +xyz +)S)Æ* \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e b/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e new file mode 100644 index 00000000000..4d82ca3953d --- /dev/null +++ b/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e @@ -0,0 +1,4 @@ +x;7y +xyz +)S)xyz +Æ* \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 b/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 new file mode 100644 index 00000000000..bb7f4ae07e5 --- /dev/null +++ b/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 @@ -0,0 +1 @@ +xyzxy \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 b/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 new file mode 100644 index 00000000000..50879d0f375 --- /dev/null +++ b/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 @@ -0,0 +1,3 @@ +xy +xz +)Sxy-Æzx_yþ \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b b/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b new file mode 100644 index 00000000000..dc1ab9bfc2d --- /dev/null +++ b/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b @@ -0,0 +1,3 @@ +_x;7y +xyz')S)xyz +Æ* \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 b/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 new file mode 100644 index 00000000000..3476e0b70bf --- /dev/null +++ b/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 @@ -0,0 +1,2 @@ +xyz +)S \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 b/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 new file mode 100644 index 00000000000..822d50abf8d --- /dev/null +++ b/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 @@ -0,0 +1 @@ +.yx \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 b/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 new file mode 100644 index 00000000000..101639c93d6 --- /dev/null +++ b/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 @@ -0,0 +1,4 @@ +x;y +xyz +)S)xyz +Æ* \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 b/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 new file mode 100644 index 00000000000..6e07ab342fe --- /dev/null +++ b/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 @@ -0,0 +1,5 @@ +x;y +xøyz +)S)xyz +Æ.y~ +)S \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 b/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 new file mode 100644 index 00000000000..13d7fab5968 --- /dev/null +++ b/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 @@ -0,0 +1,3 @@ +xy +xyz +)S)S \ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/xyz b/test/core/support/percent_encode_corpus/xyz new file mode 100644 index 00000000000..cd470e61900 --- /dev/null +++ b/test/core/support/percent_encode_corpus/xyz @@ -0,0 +1 @@ +xyz diff --git a/test/core/support/percent_encode_fuzzer.c b/test/core/support/percent_encode_fuzzer.c new file mode 100644 index 00000000000..c9548232b5f --- /dev/null +++ b/test/core/support/percent_encode_fuzzer.c @@ -0,0 +1,73 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include + +#include "src/core/lib/support/percent_encoding.h" +#include "test/core/util/memory_counters.h" + +bool squelch = true; +bool leak_check = true; + +static void test(const uint8_t *data, size_t size, const uint8_t *dict) { + struct grpc_memory_counters counters; + grpc_memory_counters_init(); + gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size); + gpr_slice output = gpr_percent_encode_slice(input, dict); + gpr_slice decoded_output; + // encoder must always produce decodable output + GPR_ASSERT(gpr_strict_percent_decode_slice(output, dict, &decoded_output)); + gpr_slice permissive_decoded_output = + gpr_permissive_percent_decode_slice(output); + // and decoded output must always match the input + GPR_ASSERT(gpr_slice_cmp(input, decoded_output) == 0); + GPR_ASSERT(gpr_slice_cmp(input, permissive_decoded_output) == 0); + gpr_slice_unref(input); + gpr_slice_unref(output); + gpr_slice_unref(decoded_output); + gpr_slice_unref(permissive_decoded_output); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + test(data, size, gpr_url_percent_encoding_unreserved_bytes); + test(data, size, gpr_compatible_percent_encoding_unreserved_bytes); + return 0; +} diff --git a/test/core/support/percent_encoding_test.c b/test/core/support/percent_encoding_test.c new file mode 100644 index 00000000000..ab5f3f2d14d --- /dev/null +++ b/test/core/support/percent_encoding_test.c @@ -0,0 +1,157 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/lib/support/percent_encoding.h" + +#include +#include + +#include "src/core/lib/support/string.h" +#include "test/core/util/test_config.h" + +#define TEST_VECTOR(raw, encoded, dict) \ + test_vector(raw, sizeof(raw) - 1, encoded, sizeof(encoded) - 1, dict) + +#define TEST_NONCONFORMANT_VECTOR(encoded, permissive_unencoded, dict) \ + test_nonconformant_vector(encoded, sizeof(encoded) - 1, \ + permissive_unencoded, \ + sizeof(permissive_unencoded) - 1, dict) + +static void test_vector(const char *raw, size_t raw_length, const char *encoded, + size_t encoded_length, const uint8_t *dict) { + char *raw_msg = gpr_dump(raw, raw_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded_msg = + gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", raw_msg, encoded_msg); + gpr_free(raw_msg); + gpr_free(encoded_msg); + + gpr_slice raw_slice = gpr_slice_from_copied_buffer(raw, raw_length); + gpr_slice encoded_slice = + gpr_slice_from_copied_buffer(encoded, encoded_length); + gpr_slice raw2encoded_slice = gpr_percent_encode_slice(raw_slice, dict); + gpr_slice encoded2raw_slice; + GPR_ASSERT( + gpr_strict_percent_decode_slice(encoded_slice, dict, &encoded2raw_slice)); + gpr_slice encoded2raw_permissive_slice = + gpr_permissive_percent_decode_slice(encoded_slice); + + char *raw2encoded_msg = + gpr_dump_slice(raw2encoded_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded2raw_msg = + gpr_dump_slice(encoded2raw_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded2raw_permissive_msg = gpr_dump_slice( + encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, + "Result:\nraw2encoded = %s\nencoded2raw = %s\nencoded2raw_permissive " + "= %s", + raw2encoded_msg, encoded2raw_msg, encoded2raw_permissive_msg); + gpr_free(raw2encoded_msg); + gpr_free(encoded2raw_msg); + gpr_free(encoded2raw_permissive_msg); + + GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_slice)); + GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_permissive_slice)); + GPR_ASSERT(0 == gpr_slice_cmp(encoded_slice, raw2encoded_slice)); + + gpr_slice_unref(encoded2raw_slice); + gpr_slice_unref(encoded2raw_permissive_slice); + gpr_slice_unref(raw2encoded_slice); + gpr_slice_unref(raw_slice); + gpr_slice_unref(encoded_slice); +} + +static void test_nonconformant_vector(const char *encoded, + size_t encoded_length, + const char *permissive_unencoded, + size_t permissive_unencoded_length, + const uint8_t *dict) { + char *permissive_unencoded_msg = + gpr_dump(permissive_unencoded, permissive_unencoded_length, + GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded_msg = + gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", permissive_unencoded_msg, + encoded_msg); + gpr_free(permissive_unencoded_msg); + gpr_free(encoded_msg); + + gpr_slice permissive_unencoded_slice = gpr_slice_from_copied_buffer( + permissive_unencoded, permissive_unencoded_length); + gpr_slice encoded_slice = + gpr_slice_from_copied_buffer(encoded, encoded_length); + gpr_slice encoded2raw_slice; + GPR_ASSERT(!gpr_strict_percent_decode_slice(encoded_slice, dict, + &encoded2raw_slice)); + gpr_slice encoded2raw_permissive_slice = + gpr_permissive_percent_decode_slice(encoded_slice); + + char *encoded2raw_permissive_msg = gpr_dump_slice( + encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "Result:\nencoded2raw_permissive = %s", + encoded2raw_permissive_msg); + gpr_free(encoded2raw_permissive_msg); + + GPR_ASSERT(0 == gpr_slice_cmp(permissive_unencoded_slice, + encoded2raw_permissive_slice)); + + gpr_slice_unref(permissive_unencoded_slice); + gpr_slice_unref(encoded2raw_permissive_slice); + gpr_slice_unref(encoded_slice); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + TEST_VECTOR( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~", + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~", + gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\x00", "%00", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\x01", "%01", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("a b", "a%20b", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR(" b", "%20b", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("a b", "a b", gpr_compatible_percent_encoding_unreserved_bytes); + TEST_VECTOR(" b", " b", gpr_compatible_percent_encoding_unreserved_bytes); + TEST_VECTOR("\x0f", "%0F", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\xff", "%FF", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\xee", "%EE", gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("%", "%", + gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("%A", "%A", + gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("%AG", "%AG", + gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("\0", "\0", + gpr_url_percent_encoding_unreserved_bytes); + return 0; +} diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c index 0da483a3216..06c364b3680 100644 --- a/test/core/support/slice_test.c +++ b/test/core/support/slice_test.c @@ -85,6 +85,27 @@ static void test_slice_new_returns_something_sensible(void) { gpr_slice_unref(slice); } +/* destroy function that sets a mark to indicate it was called. */ +static void set_mark(void *p) { *((int *)p) = 1; } + +static void test_slice_new_with_user_data(void) { + int marker = 0; + uint8_t buf[2]; + gpr_slice slice; + + buf[0] = 0; + buf[1] = 1; + slice = gpr_slice_new_with_user_data(buf, 2, set_mark, &marker); + GPR_ASSERT(marker == 0); + GPR_ASSERT(GPR_SLICE_LENGTH(slice) == 2); + GPR_ASSERT(GPR_SLICE_START_PTR(slice)[0] == 0); + GPR_ASSERT(GPR_SLICE_START_PTR(slice)[1] == 1); + + /* unref should cause destroy function to run. */ + gpr_slice_unref(slice); + GPR_ASSERT(marker == 1); +} + static int do_nothing_with_len_1_calls = 0; static void do_nothing_with_len_1(void *ignored, size_t len) { @@ -232,6 +253,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); test_slice_malloc_returns_something_sensible(); test_slice_new_returns_something_sensible(); + test_slice_new_with_user_data(); test_slice_new_with_len_returns_something_sensible(); for (length = 0; length < 128; length++) { test_slice_sub_works(length); diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c index f36f9805752..2894b0c66f0 100644 --- a/test/core/surface/lame_client_test.c +++ b/test/core/surface/lame_client_test.c @@ -132,7 +132,7 @@ int main(int argc, char **argv) { GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ - cq_expect_completion(cqv, tag(1), 0); + CQ_EXPECT_COMPLETION(cqv, tag(1), 0); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -149,7 +149,7 @@ int main(int argc, char **argv) { GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); peer = grpc_call_get_peer(call); diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index 186bb6406fd..1c1c74879be 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -97,7 +97,7 @@ static void verify(size_t window_available, int eof, size_t expect_window_used, grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); - grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, &stats, + grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats, &output); merged = grpc_slice_merge(output.slices, output.count); gpr_slice_buffer_destroy(&output); @@ -202,7 +202,8 @@ static void verify_table_size_change_match_elem_size(const char *key, grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); - grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, &stats, &output); + grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats, + &output); gpr_slice_buffer_destroy(&output); grpc_metadata_batch_destroy(&b); diff --git a/test/core/transport/chttp2/timeout_encoding_test.c b/test/core/transport/timeout_encoding_test.c similarity index 89% rename from test/core/transport/chttp2/timeout_encoding_test.c rename to test/core/transport/timeout_encoding_test.c index 67639936a76..b6004af7b47 100644 --- a/test/core/transport/chttp2/timeout_encoding_test.c +++ b/test/core/transport/timeout_encoding_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/ext/transport/chttp2/transport/timeout_encoding.h" +#include "src/core/lib/transport/timeout_encoding.h" #include #include @@ -46,8 +46,8 @@ #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) static void assert_encodes_as(gpr_timespec ts, const char *s) { - char buffer[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; - grpc_chttp2_encode_timeout(ts, buffer); + char buffer[GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; + grpc_http2_encode_timeout(ts, buffer); gpr_log(GPR_INFO, "check '%s' == '%s'", buffer, s); GPR_ASSERT(0 == strcmp(buffer, s)); } @@ -88,7 +88,7 @@ void test_encoding(void) { static void assert_decodes_as(const char *buffer, gpr_timespec expected) { gpr_timespec got; gpr_log(GPR_INFO, "check decoding '%s'", buffer); - GPR_ASSERT(1 == grpc_chttp2_decode_timeout(buffer, &got)); + GPR_ASSERT(1 == grpc_http2_decode_timeout(buffer, &got)); GPR_ASSERT(0 == gpr_time_cmp(got, expected)); } @@ -137,15 +137,15 @@ void test_decoding(void) { void test_decoding_fails(void) { gpr_timespec x; LOG_TEST("test_decoding_fails"); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout(" ", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("x", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("1", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("1x", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("1ux", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("!", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("n1", &x)); - GPR_ASSERT(0 == grpc_chttp2_decode_timeout("-1u", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout(" ", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("x", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("1", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("1x", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("1ux", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("!", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("n1", &x)); + GPR_ASSERT(0 == grpc_http2_decode_timeout("-1u", &x)); } int main(int argc, char **argv) { diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index ef3d1aaa510..7b0fd6ce804 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -43,6 +43,7 @@ #include #include +#include #include #include #include @@ -206,6 +207,27 @@ class ServiceA GRPC_FINAL { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; + template + class WithStreamedUnaryMethod_MethodA1 : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_MethodA1() { + ::grpc::Service::MarkMethodStreamedUnary(0, + new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_MethodA1() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_MethodA1 StreamedUnaryService; }; // ServiceB leading comment 1 @@ -284,6 +306,27 @@ class ServiceB GRPC_FINAL { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; + template + class WithStreamedUnaryMethod_MethodB1 : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_MethodB1() { + ::grpc::Service::MarkMethodStreamedUnary(0, + new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_MethodB1() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedMethodB1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_MethodB1 StreamedUnaryService; }; // ServiceB trailing comment 1 diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 4a8936d2810..ac79fe82740 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -200,6 +200,10 @@ class Verifier { bool spin_; }; +bool plugin_has_sync_methods(std::unique_ptr& plugin) { + return plugin->has_sync_methods(); +} + // This class disables the server builder plugins that may add sync services to // the server. If there are sync services, UnimplementedRpc test will triger // the sync unkown rpc routine on the server side, rather than the async one @@ -210,14 +214,9 @@ class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption { void UpdatePlugins(std::vector>* plugins) GRPC_OVERRIDE { - auto plugin = plugins->begin(); - while (plugin != plugins->end()) { - if ((*plugin)->has_sync_methods()) { - plugins->erase(plugin++); - } else { - plugin++; - } - } + plugins->erase(std::remove_if(plugins->begin(), plugins->end(), + plugin_has_sync_methods), + plugins->end()); } }; diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 0f87ae3e440..46a58d3ac39 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -1414,7 +1414,7 @@ TEST_P(SecureEnd2endTest, ClientAuthContext) { std::shared_ptr auth_ctx = context.auth_context(); std::vector tst = auth_ctx->FindPropertyValues("transport_security_type"); - EXPECT_EQ(1u, tst.size()); + ASSERT_EQ(1u, tst.size()); EXPECT_EQ(GetParam().credentials_type, ToString(tst[0])); if (GetParam().credentials_type == kTlsCredentialsType) { EXPECT_EQ("x509_subject_alternative_name", diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc new file mode 100644 index 00000000000..853720fd0d0 --- /dev/null +++ b/test/cpp/end2end/filter_end2end_test.cc @@ -0,0 +1,353 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/cpp/common/channel_filter.h" +#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/util/byte_buffer_proto_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +void* tag(int i) { return (void*)(intptr_t)i; } + +void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { + bool ok; + void* got_tag; + EXPECT_TRUE(cq->Next(&got_tag, &ok)); + EXPECT_EQ(expect_ok, ok); + EXPECT_EQ(tag(i), got_tag); +} + +namespace { + +int global_num_connections = 0; +int global_num_calls = 0; +mutex global_mu; + +void IncrementConnectionCounter() { + unique_lock lock(global_mu); + ++global_num_connections; +} + +void ResetConnectionCounter() { + unique_lock lock(global_mu); + global_num_connections = 0; +} + +int GetConnectionCounterValue() { + unique_lock lock(global_mu); + return global_num_connections; +} + +void IncrementCallCounter() { + unique_lock lock(global_mu); + ++global_num_calls; +} + +void ResetCallCounter() { + unique_lock lock(global_mu); + global_num_calls = 0; +} + +int GetCallCounterValue() { + unique_lock lock(global_mu); + return global_num_calls; +} + +} // namespace + +class ChannelDataImpl : public ChannelData { + public: + ChannelDataImpl(const grpc_channel_args& args, const char* peer) + : ChannelData(args, peer) { + IncrementConnectionCounter(); + } +}; + +class CallDataImpl : public CallData { + public: + explicit CallDataImpl(const ChannelDataImpl& channel_data) + : CallData(channel_data) {} + + void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem, + TransportStreamOp* op) GRPC_OVERRIDE { + // Incrementing the counter could be done from the ctor, but we want + // to test that the individual methods are actually called correctly. + if (op->recv_initial_metadata() != nullptr) IncrementCallCounter(); + grpc_call_next_op(exec_ctx, elem, op->op()); + } +}; + +class FilterEnd2endTest : public ::testing::Test { + protected: + FilterEnd2endTest() : server_host_("localhost") {} + + void SetUp() GRPC_OVERRIDE { + int port = grpc_pick_unused_port_or_die(); + server_address_ << server_host_ << ":" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterAsyncGenericService(&generic_service_); + srv_cq_ = builder.AddCompletionQueue(); + server_ = builder.BuildAndStart(); + } + + void TearDown() GRPC_OVERRIDE { + server_->Shutdown(); + void* ignored_tag; + bool ignored_ok; + cli_cq_.Shutdown(); + srv_cq_->Shutdown(); + while (cli_cq_.Next(&ignored_tag, &ignored_ok)) + ; + while (srv_cq_->Next(&ignored_tag, &ignored_ok)) + ; + } + + void ResetStub() { + std::shared_ptr channel = + CreateChannel(server_address_.str(), InsecureChannelCredentials()); + generic_stub_.reset(new GenericStub(channel)); + ResetConnectionCounter(); + ResetCallCounter(); + } + + void server_ok(int i) { verify_ok(srv_cq_.get(), i, true); } + void client_ok(int i) { verify_ok(&cli_cq_, i, true); } + void server_fail(int i) { verify_ok(srv_cq_.get(), i, false); } + void client_fail(int i) { verify_ok(&cli_cq_, i, false); } + + void SendRpc(int num_rpcs) { + const grpc::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo"); + for (int i = 0; i < num_rpcs; i++) { + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter stream(&srv_ctx); + + // The string needs to be long enough to test heap-based slice. + send_request.set_message("Hello world. Hello world. Hello world."); + std::unique_ptr call = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + client_ok(1); + std::unique_ptr send_buffer = + SerializeToByteBuffer(&send_request); + call->Write(*send_buffer, tag(2)); + // Send ByteBuffer can be destroyed after calling Write. + send_buffer.reset(); + client_ok(2); + call->WritesDone(tag(3)); + client_ok(3); + + generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), + srv_cq_.get(), tag(4)); + + verify_ok(srv_cq_.get(), 4, true); + EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); + EXPECT_EQ(kMethodName, srv_ctx.method()); + ByteBuffer recv_buffer; + stream.Read(&recv_buffer, tag(5)); + server_ok(5); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + send_buffer = SerializeToByteBuffer(&send_response); + stream.Write(*send_buffer, tag(6)); + send_buffer.reset(); + server_ok(6); + + stream.Finish(Status::OK, tag(7)); + server_ok(7); + + recv_buffer.Clear(); + call->Read(&recv_buffer, tag(8)); + client_ok(8); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); + + call->Finish(&recv_status, tag(9)); + client_ok(9); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + } + } + + CompletionQueue cli_cq_; + std::unique_ptr srv_cq_; + std::unique_ptr stub_; + std::unique_ptr generic_stub_; + std::unique_ptr server_; + AsyncGenericService generic_service_; + const grpc::string server_host_; + std::ostringstream server_address_; +}; + +TEST_F(FilterEnd2endTest, SimpleRpc) { + ResetStub(); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); + SendRpc(1); + EXPECT_EQ(1, GetConnectionCounterValue()); + EXPECT_EQ(1, GetCallCounterValue()); +} + +TEST_F(FilterEnd2endTest, SequentialRpcs) { + ResetStub(); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); + SendRpc(10); + EXPECT_EQ(1, GetConnectionCounterValue()); + EXPECT_EQ(10, GetCallCounterValue()); +} + +// One ping, one pong. +TEST_F(FilterEnd2endTest, SimpleBidiStreaming) { + ResetStub(); + EXPECT_EQ(0, GetConnectionCounterValue()); + EXPECT_EQ(0, GetCallCounterValue()); + + const grpc::string kMethodName( + "/grpc.cpp.test.util.EchoTestService/BidiStream"); + EchoRequest send_request; + EchoRequest recv_request; + EchoResponse send_response; + EchoResponse recv_response; + Status recv_status; + ClientContext cli_ctx; + GenericServerContext srv_ctx; + GenericServerAsyncReaderWriter srv_stream(&srv_ctx); + + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + send_request.set_message("Hello"); + std::unique_ptr cli_stream = + generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1)); + client_ok(1); + + generic_service_.RequestCall(&srv_ctx, &srv_stream, srv_cq_.get(), + srv_cq_.get(), tag(2)); + + verify_ok(srv_cq_.get(), 2, true); + EXPECT_EQ(server_host_, srv_ctx.host().substr(0, server_host_.length())); + EXPECT_EQ(kMethodName, srv_ctx.method()); + + std::unique_ptr send_buffer = + SerializeToByteBuffer(&send_request); + cli_stream->Write(*send_buffer, tag(3)); + send_buffer.reset(); + client_ok(3); + + ByteBuffer recv_buffer; + srv_stream.Read(&recv_buffer, tag(4)); + server_ok(4); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_request)); + EXPECT_EQ(send_request.message(), recv_request.message()); + + send_response.set_message(recv_request.message()); + send_buffer = SerializeToByteBuffer(&send_response); + srv_stream.Write(*send_buffer, tag(5)); + send_buffer.reset(); + server_ok(5); + + cli_stream->Read(&recv_buffer, tag(6)); + client_ok(6); + EXPECT_TRUE(ParseFromByteBuffer(&recv_buffer, &recv_response)); + EXPECT_EQ(send_response.message(), recv_response.message()); + + cli_stream->WritesDone(tag(7)); + client_ok(7); + + srv_stream.Read(&recv_buffer, tag(8)); + server_fail(8); + + srv_stream.Finish(Status::OK, tag(9)); + server_ok(9); + + cli_stream->Finish(&recv_status, tag(10)); + client_ok(10); + + EXPECT_EQ(send_response.message(), recv_response.message()); + EXPECT_TRUE(recv_status.ok()); + + EXPECT_EQ(1, GetCallCounterValue()); + EXPECT_EQ(1, GetConnectionCounterValue()); +} + +void RegisterFilter() { + grpc::RegisterChannelFilter( + "test-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::RegisterFilter(); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index 7e0c0e8a7ca..a6ea13aa8bd 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -199,7 +199,8 @@ class HybridEnd2endTest : public ::testing::Test { HybridEnd2endTest() {} void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2, - AsyncGenericService* generic_service) { + AsyncGenericService* generic_service, + int max_message_size = 0) { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; @@ -217,6 +218,11 @@ class HybridEnd2endTest : public ::testing::Test { if (generic_service) { builder.RegisterAsyncGenericService(generic_service); } + + if (max_message_size != 0) { + builder.SetMaxMessageSize(max_message_size); + } + // Create a separate cq for each potential handler. for (int i = 0; i < 5; i++) { cqs_.push_back(builder.AddCompletionQueue(false)); @@ -415,6 +421,83 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) { request_stream_handler_thread.join(); } +// Add a second service with one sync streamed unary method. +class StreamedUnaryDupPkg + : public duplicate::EchoTestService::WithStreamedUnaryMethod_Echo< + TestServiceImplDupPkg> { + public: + Status StreamedEcho(ServerContext* context, + ServerUnaryStreamer* stream) + GRPC_OVERRIDE { + EchoRequest req; + EchoResponse resp; + uint32_t next_msg_sz; + stream->NextMessageSize(&next_msg_sz); + gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); + GPR_ASSERT(stream->Read(&req)); + resp.set_message(req.message() + "_dup"); + GPR_ASSERT(stream->Write(resp)); + return Status::OK; + } +}; + +TEST_F(HybridEnd2endTest, + AsyncRequestStreamResponseStream_SyncStreamedUnaryDupService) { + typedef EchoTestService::WithAsyncMethod_RequestStream< + EchoTestService::WithAsyncMethod_ResponseStream> + SType; + SType service; + StreamedUnaryDupPkg dup_service; + SetUpServer(&service, &dup_service, nullptr, 8192); + ResetStub(); + std::thread response_stream_handler_thread(HandleServerStreaming, + &service, cqs_[0].get()); + std::thread request_stream_handler_thread(HandleClientStreaming, + &service, cqs_[1].get()); + TestAllMethods(); + SendEchoToDupService(); + response_stream_handler_thread.join(); + request_stream_handler_thread.join(); +} + +// Add a second service that is fully Streamed Unary +class FullyStreamedUnaryDupPkg + : public duplicate::EchoTestService::StreamedUnaryService { + public: + Status StreamedEcho(ServerContext* context, + ServerUnaryStreamer* stream) + GRPC_OVERRIDE { + EchoRequest req; + EchoResponse resp; + uint32_t next_msg_sz; + stream->NextMessageSize(&next_msg_sz); + gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); + GPR_ASSERT(stream->Read(&req)); + resp.set_message(req.message() + "_dup"); + GPR_ASSERT(stream->Write(resp)); + return Status::OK; + } +}; + +TEST_F(HybridEnd2endTest, + AsyncRequestStreamResponseStream_SyncFullyStreamedUnaryDupService) { + typedef EchoTestService::WithAsyncMethod_RequestStream< + EchoTestService::WithAsyncMethod_ResponseStream> + SType; + SType service; + FullyStreamedUnaryDupPkg dup_service; + SetUpServer(&service, &dup_service, nullptr, 8192); + ResetStub(); + std::thread response_stream_handler_thread(HandleServerStreaming, + &service, cqs_[0].get()); + std::thread request_stream_handler_thread(HandleClientStreaming, + &service, cqs_[1].get()); + TestAllMethods(); + SendEchoToDupService(); + response_stream_handler_thread.join(); + request_stream_handler_thread.join(); +} + // Add a second service with one async method. TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { typedef EchoTestService::WithAsyncMethod_RequestStream< diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index 0ace5d94183..40526271221 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -31,6 +31,7 @@ * */ +#include #include #include @@ -63,6 +64,10 @@ class MockClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface { public: void WaitForInitialMetadata() GRPC_OVERRIDE {} + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = UINT_MAX; + return true; + } bool Read(R* msg) GRPC_OVERRIDE { return true; } bool Write(const W& msg) GRPC_OVERRIDE { return true; } bool WritesDone() GRPC_OVERRIDE { return true; } @@ -74,6 +79,10 @@ class MockClientReaderWriter GRPC_FINAL public: MockClientReaderWriter() : writes_done_(false) {} void WaitForInitialMetadata() GRPC_OVERRIDE {} + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = UINT_MAX; + return true; + } bool Read(EchoResponse* msg) GRPC_OVERRIDE { if (writes_done_) return false; msg->set_message(last_message_); diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc index f8fc39b5535..efbb0e1f8e5 100644 --- a/test/cpp/end2end/proto_server_reflection_test.cc +++ b/test/cpp/end2end/proto_server_reflection_test.cc @@ -31,7 +31,6 @@ * */ -#include #include #include #include @@ -59,7 +58,7 @@ class ProtoServerReflectionTest : public ::testing::Test { void SetUp() GRPC_OVERRIDE { port_ = grpc_pick_unused_port_or_die(); - ref_desc_pool_ = google::protobuf::DescriptorPool::generated_pool(); + ref_desc_pool_ = protobuf::DescriptorPool::generated_pool(); ServerBuilder builder; grpc::string server_address = "localhost:" + to_string(port_); @@ -73,7 +72,7 @@ class ProtoServerReflectionTest : public ::testing::Test { CreateChannel(target, InsecureChannelCredentials()); stub_ = grpc::testing::EchoTestService::NewStub(channel); desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel)); - desc_pool_.reset(new google::protobuf::DescriptorPool(desc_db_.get())); + desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); } string to_string(const int number) { @@ -83,15 +82,15 @@ class ProtoServerReflectionTest : public ::testing::Test { } void CompareService(const grpc::string& service) { - const google::protobuf::ServiceDescriptor* service_desc = + const protobuf::ServiceDescriptor* service_desc = desc_pool_->FindServiceByName(service); - const google::protobuf::ServiceDescriptor* ref_service_desc = + const protobuf::ServiceDescriptor* ref_service_desc = ref_desc_pool_->FindServiceByName(service); EXPECT_TRUE(service_desc != nullptr); EXPECT_TRUE(ref_service_desc != nullptr); EXPECT_EQ(service_desc->DebugString(), ref_service_desc->DebugString()); - const google::protobuf::FileDescriptor* file_desc = service_desc->file(); + const protobuf::FileDescriptor* file_desc = service_desc->file(); if (known_files_.find(file_desc->package() + "/" + file_desc->name()) != known_files_.end()) { EXPECT_EQ(file_desc->DebugString(), @@ -105,9 +104,9 @@ class ProtoServerReflectionTest : public ::testing::Test { } void CompareMethod(const grpc::string& method) { - const google::protobuf::MethodDescriptor* method_desc = + const protobuf::MethodDescriptor* method_desc = desc_pool_->FindMethodByName(method); - const google::protobuf::MethodDescriptor* ref_method_desc = + const protobuf::MethodDescriptor* ref_method_desc = ref_desc_pool_->FindMethodByName(method); EXPECT_TRUE(method_desc != nullptr); EXPECT_TRUE(ref_method_desc != nullptr); @@ -122,9 +121,8 @@ class ProtoServerReflectionTest : public ::testing::Test { return; } - const google::protobuf::Descriptor* desc = - desc_pool_->FindMessageTypeByName(type); - const google::protobuf::Descriptor* ref_desc = + const protobuf::Descriptor* desc = desc_pool_->FindMessageTypeByName(type); + const protobuf::Descriptor* ref_desc = ref_desc_pool_->FindMessageTypeByName(type); EXPECT_TRUE(desc != nullptr); EXPECT_TRUE(ref_desc != nullptr); @@ -135,10 +133,10 @@ class ProtoServerReflectionTest : public ::testing::Test { std::unique_ptr server_; std::unique_ptr stub_; std::unique_ptr desc_db_; - std::unique_ptr desc_pool_; + std::unique_ptr desc_pool_; std::unordered_set known_files_; std::unordered_set known_types_; - const google::protobuf::DescriptorPool* ref_desc_pool_; + const protobuf::DescriptorPool* ref_desc_pool_; int port_; reflection::ProtoServerReflectionPlugin plugin_; }; diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc index 778a2be573e..b967a5d1e99 100644 --- a/test/cpp/end2end/server_builder_plugin_test.cc +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -191,7 +191,7 @@ class ServerBuilderPluginTest : public ::testing::TestWithParam { // we run some tests without a service, and for those we need to supply a // frequently polled completion queue cq_ = builder_->AddCompletionQueue(); - cq_thread_ = grpc::thread(std::bind(&ServerBuilderPluginTest::RunCQ, this)); + cq_thread_ = new grpc::thread(&ServerBuilderPluginTest::RunCQ, this); server_ = builder_->BuildAndStart(); EXPECT_TRUE(CheckPresent()); } @@ -209,7 +209,8 @@ class ServerBuilderPluginTest : public ::testing::TestWithParam { EXPECT_TRUE(plugin->finish_is_called()); server_->Shutdown(); cq_->Shutdown(); - cq_thread_.join(); + cq_thread_->join(); + delete cq_thread_; } string to_string(const int number) { @@ -224,7 +225,7 @@ class ServerBuilderPluginTest : public ::testing::TestWithParam { std::unique_ptr stub_; std::unique_ptr cq_; std::unique_ptr server_; - grpc::thread cq_thread_; + grpc::thread* cq_thread_; TestServiceImpl service_; int port_; diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc index bf77878e0a6..33de1ee93c6 100644 --- a/test/cpp/grpclb/grpclb_api_test.cc +++ b/test/cpp/grpclb/grpclb_api_test.cc @@ -58,26 +58,24 @@ TEST_F(GrpclbTest, CreateRequest) { grpc_grpclb_request_destroy(c_req); } -TEST_F(GrpclbTest, ParseResponse) { +TEST_F(GrpclbTest, ParseInitialResponse) { LoadBalanceResponse response; auto* initial_response = response.mutable_initial_response(); auto* client_stats_report_interval = initial_response->mutable_client_stats_report_interval(); client_stats_report_interval->set_seconds(123); client_stats_report_interval->set_nanos(456); - const std::string encoded_response = response.SerializeAsString(); gpr_slice encoded_slice = gpr_slice_from_copied_string(encoded_response.c_str()); - grpc_grpclb_response* c_response = grpc_grpclb_response_parse(encoded_slice); - EXPECT_TRUE(c_response->has_initial_response); - EXPECT_FALSE(c_response->initial_response.has_load_balancer_delegate); - EXPECT_EQ(c_response->initial_response.client_stats_report_interval.seconds, - 123); - EXPECT_EQ(c_response->initial_response.client_stats_report_interval.nanos, - 456); + + grpc_grpclb_initial_response* c_initial_response = + grpc_grpclb_initial_response_parse(encoded_slice); + EXPECT_FALSE(c_initial_response->has_load_balancer_delegate); + EXPECT_EQ(c_initial_response->client_stats_report_interval.seconds, 123); + EXPECT_EQ(c_initial_response->client_stats_report_interval.nanos, 456); gpr_slice_unref(encoded_slice); - grpc_grpclb_response_destroy(c_response); + grpc_grpclb_initial_response_destroy(c_initial_response); } TEST_F(GrpclbTest, ParseResponseServerList) { diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc new file mode 100644 index 00000000000..a4aa97391bb --- /dev/null +++ b/test/cpp/grpclb/grpclb_test.cc @@ -0,0 +1,689 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include + +extern "C" { +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/core/ext/client_config/client_channel.h" +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/support/tmpfile.h" +#include "src/core/lib/surface/channel.h" +#include "src/core/lib/surface/server.h" +#include "test/core/end2end/cq_verifier.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +} + +#include "src/proto/grpc/lb/v1/load_balancer.pb.h" + +#define NUM_BACKENDS 4 + +// TODO(dgq): Other scenarios in need of testing: +// - Send an empty serverlist update and verify that the client request blocks +// until a new serverlist with actual contents is available. +// - Send identical serverlist update +// - Test reception of invalid serverlist +// - Test pinging +// - Test against a non-LB server. That server should return UNIMPLEMENTED and +// the call should fail. +// - Random LB server closing the stream unexpectedly. + +namespace grpc { +namespace { + +typedef struct client_fixture { + grpc_channel *client; + char *server_uri; + grpc_completion_queue *cq; +} client_fixture; + +typedef struct server_fixture { + grpc_server *server; + grpc_call *server_call; + grpc_completion_queue *cq; + char *servers_hostport; + int port; + gpr_thd_id tid; + int num_calls_serviced; +} server_fixture; + +typedef struct test_fixture { + server_fixture lb_server; + server_fixture lb_backends[NUM_BACKENDS]; + client_fixture client; + int lb_server_update_delay_ms; +} test_fixture; + +static void *tag(intptr_t t) { return (void *)t; } + +static gpr_slice build_response_payload_slice( + const char *host, int *ports, size_t nports, + int64_t expiration_interval_secs, int32_t expiration_interval_nanos) { + // server_list { + // servers { + // ip_address: "127.0.0.1" + // port: ... + // load_balance_token: "token..." + // } + // ... + // } + grpc::lb::v1::LoadBalanceResponse response; + auto *serverlist = response.mutable_server_list(); + + if (expiration_interval_secs > 0 || expiration_interval_nanos > 0) { + auto *expiration_interval = serverlist->mutable_expiration_interval(); + if (expiration_interval_secs > 0) { + expiration_interval->set_seconds(expiration_interval_secs); + } + if (expiration_interval_nanos > 0) { + expiration_interval->set_nanos(expiration_interval_nanos); + } + } + for (size_t i = 0; i < nports; i++) { + auto *server = serverlist->add_servers(); + server->set_ip_address(host); + server->set_port(ports[i]); + // The following long long int cast is meant to work around the + // disfunctional implementation of std::to_string in gcc 4.4, which doesn't + // have a version for int but does have one for long long int. + server->set_load_balance_token("token" + + std::to_string((long long int)ports[i])); + } + + gpr_log(GPR_INFO, "generating response: %s", + response.ShortDebugString().c_str()); + + const gpr_slice response_slice = + gpr_slice_from_copied_string(response.SerializeAsString().c_str()); + return response_slice; +} + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), + NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void sleep_ms(int delay_ms) { + gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(delay_ms, GPR_TIMESPAN))); +} + +static void start_lb_server(server_fixture *sf, int *ports, size_t nports, + int update_delay_ms) { + grpc_call *s; + cq_verifier *cqv = cq_verifier_create(sf->cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_call_error error; + int was_cancelled = 2; + grpc_byte_buffer *request_payload_recv; + grpc_byte_buffer *response_payload; + + memset(ops, 0, sizeof(ops)); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + error = grpc_server_request_call(sf->server, &s, &call_details, + &request_metadata_recv, sf->cq, sf->cq, + tag(200)); + GPR_ASSERT(GRPC_CALL_OK == error); + gpr_log(GPR_INFO, "LB Server[%s] up", sf->servers_hostport); + CQ_EXPECT_COMPLETION(cqv, tag(200), 1); + cq_verify(cqv); + gpr_log(GPR_INFO, "LB Server[%s] after tag 200", sf->servers_hostport); + + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(201), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + gpr_log(GPR_INFO, "LB Server[%s] after tag 201", sf->servers_hostport); + + // receive request for backends + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(202), 1); + cq_verify(cqv); + gpr_log(GPR_INFO, "LB Server[%s] after RECV_MSG", sf->servers_hostport); + // TODO(dgq): validate request. + grpc_byte_buffer_destroy(request_payload_recv); + gpr_slice response_payload_slice; + for (int i = 0; i < 2; i++) { + if (i == 0) { + // First half of the ports. + response_payload_slice = + build_response_payload_slice("127.0.0.1", ports, nports / 2, -1, -1); + } else { + // Second half of the ports. + sleep_ms(update_delay_ms); + response_payload_slice = + build_response_payload_slice("127.0.0.1", ports + (nports / 2), + (nports + 1) / 2 /* ceil */, -1, -1); + } + + response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(203), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(203), 1); + cq_verify(cqv); + gpr_log(GPR_INFO, "LB Server[%s] after SEND_MESSAGE, iter %d", + sf->servers_hostport, i); + + grpc_byte_buffer_destroy(response_payload); + gpr_slice_unref(response_payload_slice); + } + gpr_log(GPR_INFO, "LB Server[%s] shutting down", sf->servers_hostport); + + op = ops; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = "xyz"; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(204), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(201), 1); + CQ_EXPECT_COMPLETION(cqv, tag(204), 1); + cq_verify(cqv); + gpr_log(GPR_INFO, "LB Server[%s] after tag 204. All done. LB server out", + sf->servers_hostport); + + grpc_call_destroy(s); + + cq_verifier_destroy(cqv); + + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); +} + +static void start_backend_server(server_fixture *sf) { + grpc_call *s; + cq_verifier *cqv; + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array request_metadata_recv; + grpc_call_details call_details; + grpc_call_error error; + int was_cancelled; + grpc_byte_buffer *request_payload_recv; + grpc_byte_buffer *response_payload; + grpc_event ev; + + while (true) { + memset(ops, 0, sizeof(ops)); + cqv = cq_verifier_create(sf->cq); + was_cancelled = 2; + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + error = grpc_server_request_call(sf->server, &s, &call_details, + &request_metadata_recv, sf->cq, sf->cq, + tag(100)); + GPR_ASSERT(GRPC_CALL_OK == error); + gpr_log(GPR_INFO, "Server[%s] up", sf->servers_hostport); + ev = grpc_completion_queue_next(sf->cq, + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(60), NULL); + if (!ev.success) { + gpr_log(GPR_INFO, "Server[%s] being torn down", sf->servers_hostport); + cq_verifier_destroy(cqv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + return; + } + GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); + gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport); + + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + gpr_log(GPR_INFO, "Server[%s] after tag 101", sf->servers_hostport); + + bool exit = false; + gpr_slice response_payload_slice = + gpr_slice_from_copied_string("hello you"); + while (!exit) { + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + ev = grpc_completion_queue_next( + sf->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), NULL); + if (ev.type == GRPC_OP_COMPLETE && ev.success) { + GPR_ASSERT(ev.tag = tag(102)); + if (request_payload_recv == NULL) { + exit = true; + gpr_log(GPR_INFO, + "Server[%s] recv \"close\" from client, exiting. Call #%d", + sf->servers_hostport, sf->num_calls_serviced); + } + } else { + gpr_log(GPR_INFO, "Server[%s] forced to shutdown. Call #%d", + sf->servers_hostport, sf->num_calls_serviced); + exit = true; + } + gpr_log(GPR_INFO, "Server[%s] after tag 102. Call #%d", + sf->servers_hostport, sf->num_calls_serviced); + + if (!exit) { + response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + error = + grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + ev = grpc_completion_queue_next( + sf->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), NULL); + if (ev.type == GRPC_OP_COMPLETE && ev.success) { + GPR_ASSERT(ev.tag = tag(103)); + } else { + gpr_log(GPR_INFO, "Server[%s] forced to shutdown. Call #%d", + sf->servers_hostport, sf->num_calls_serviced); + exit = true; + } + gpr_log(GPR_INFO, "Server[%s] after tag 103. Call #%d", + sf->servers_hostport, sf->num_calls_serviced); + grpc_byte_buffer_destroy(response_payload); + } + + grpc_byte_buffer_destroy(request_payload_recv); + } + ++sf->num_calls_serviced; + + gpr_log(GPR_INFO, "Server[%s] OUT OF THE LOOP", sf->servers_hostport); + gpr_slice_unref(response_payload_slice); + + op = ops; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = "Backend server out a-ok"; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); + cq_verify(cqv); + gpr_log(GPR_INFO, "Server[%s] DONE. After servicing %d calls", + sf->servers_hostport, sf->num_calls_serviced); + + grpc_call_destroy(s); + cq_verifier_destroy(cqv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + } +} + +static void perform_request(client_fixture *cf) { + grpc_call *c; + cq_verifier *cqv = cq_verifier_create(cf->cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + grpc_byte_buffer *request_payload; + grpc_byte_buffer *response_payload_recv; + int i; + + memset(ops, 0, sizeof(ops)); + gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); + + c = grpc_channel_create_call(cf->client, NULL, GRPC_PROPAGATE_DEFAULTS, + cf->cq, "/foo", "foo.test.google.fr:1234", + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1000), NULL); + gpr_log(GPR_INFO, "Call 0x%" PRIxPTR " created", (intptr_t)c); + GPR_ASSERT(c); + char *peer; + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + for (i = 0; i < 4; i++) { + request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); + + op = ops; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + peer = grpc_call_get_peer(c); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); + cq_verify(cqv); + gpr_free(peer); + + grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(response_payload_recv); + } + + gpr_slice_unref(request_payload_slice); + + op = ops; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + cq_verify(cqv); + peer = grpc_call_get_peer(c); + gpr_log(GPR_INFO, "Client DONE WITH SERVER %s ", peer); + gpr_free(peer); + + grpc_call_destroy(c); + + cq_verify_empty_timeout(cqv, 1); + cq_verifier_destroy(cqv); + + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + gpr_free(details); +} + +static void setup_client(const char *server_hostport, client_fixture *cf) { + cf->cq = grpc_completion_queue_create(NULL); + cf->server_uri = gpr_strdup(server_hostport); + cf->client = grpc_insecure_channel_create(cf->server_uri, NULL, NULL); +} + +static void teardown_client(client_fixture *cf) { + grpc_completion_queue_shutdown(cf->cq); + drain_cq(cf->cq); + grpc_completion_queue_destroy(cf->cq); + cf->cq = NULL; + grpc_channel_destroy(cf->client); + cf->client = NULL; + gpr_free(cf->server_uri); +} + +static void setup_server(const char *host, server_fixture *sf) { + int assigned_port; + + sf->cq = grpc_completion_queue_create(NULL); + const char *colon_idx = strchr(host, ':'); + if (colon_idx) { + const char *port_str = colon_idx + 1; + sf->port = atoi(port_str); + sf->servers_hostport = gpr_strdup(host); + } else { + sf->port = grpc_pick_unused_port_or_die(); + gpr_join_host_port(&sf->servers_hostport, host, sf->port); + } + + sf->server = grpc_server_create(NULL, NULL); + grpc_server_register_completion_queue(sf->server, sf->cq, NULL); + GPR_ASSERT((assigned_port = grpc_server_add_insecure_http2_port( + sf->server, sf->servers_hostport)) > 0); + GPR_ASSERT(sf->port == assigned_port); + grpc_server_start(sf->server); +} + +static void teardown_server(server_fixture *sf) { + if (!sf->server) return; + + gpr_log(GPR_INFO, "Server[%s] shutting down", sf->servers_hostport); + grpc_server_shutdown_and_notify(sf->server, sf->cq, tag(1000)); + GPR_ASSERT(grpc_completion_queue_pluck( + sf->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(sf->server); + gpr_thd_join(sf->tid); + + sf->server = NULL; + grpc_completion_queue_shutdown(sf->cq); + drain_cq(sf->cq); + grpc_completion_queue_destroy(sf->cq); + + gpr_log(GPR_INFO, "Server[%s] bye bye", sf->servers_hostport); + gpr_free(sf->servers_hostport); +} + +static void fork_backend_server(void *arg) { + server_fixture *sf = static_cast(arg); + start_backend_server(sf); +} + +static void fork_lb_server(void *arg) { + test_fixture *tf = static_cast(arg); + int ports[NUM_BACKENDS]; + for (int i = 0; i < NUM_BACKENDS; i++) { + ports[i] = tf->lb_backends[i].port; + } + start_lb_server(&tf->lb_server, ports, NUM_BACKENDS, + tf->lb_server_update_delay_ms); +} + +static void setup_test_fixture(test_fixture *tf, + int lb_server_update_delay_ms) { + tf->lb_server_update_delay_ms = lb_server_update_delay_ms; + + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + + for (int i = 0; i < NUM_BACKENDS; ++i) { + setup_server("127.0.0.1", &tf->lb_backends[i]); + gpr_thd_new(&tf->lb_backends[i].tid, fork_backend_server, + &tf->lb_backends[i], &options); + } + + setup_server("127.0.0.1", &tf->lb_server); + gpr_thd_new(&tf->lb_server.tid, fork_lb_server, &tf->lb_server, &options); + + char *server_uri; + gpr_asprintf(&server_uri, "ipv4:%s?lb_policy=grpclb&lb_enabled=1", + tf->lb_server.servers_hostport); + setup_client(server_uri, &tf->client); + gpr_free(server_uri); +} + +static void teardown_test_fixture(test_fixture *tf) { + teardown_client(&tf->client); + for (int i = 0; i < NUM_BACKENDS; ++i) { + teardown_server(&tf->lb_backends[i]); + } + teardown_server(&tf->lb_server); +} + +// The LB server will send two updates: batch 1 and batch 2. Each batch +// contains +// two addresses, both of a valid and running backend server. Batch 1 is +// readily +// available and provided as soon as the client establishes the streaming +// call. +// Batch 2 is sent after a delay of \a lb_server_update_delay_ms +// milliseconds. +static test_fixture test_update(int lb_server_update_delay_ms) { + gpr_log(GPR_INFO, "start %s(%d)", __func__, lb_server_update_delay_ms); + test_fixture tf; + memset(&tf, 0, sizeof(tf)); + setup_test_fixture(&tf, lb_server_update_delay_ms); + perform_request( + &tf.client); // "consumes" 1st backend server of 1st serverlist + perform_request( + &tf.client); // "consumes" 2nd backend server of 1st serverlist + + perform_request( + &tf.client); // "consumes" 1st backend server of 2nd serverlist + perform_request( + &tf.client); // "consumes" 2nd backend server of 2nd serverlist + + teardown_test_fixture(&tf); + gpr_log(GPR_INFO, "end %s(%d)", __func__, lb_server_update_delay_ms); + return tf; +} + +} // namespace +} // namespace grpc + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + grpc_init(); + + grpc::test_fixture tf_result; + // Clients take a bit over one second to complete a call (the last part of the + // call sleeps for 1 second while verifying the client's completion queue is + // empty). Therefore: + // + // If the LB server waits 800ms before sending an update, it will arrive + // before the first client request is done, skipping the second server from + // batch 1 altogether: the 2nd client request will go to the 1st server of + // batch 2 (ie, the third one out of the four total servers). + tf_result = grpc::test_update(800); + GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced == 1); + GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 0); + GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced == 2); + GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 1); + + // If the LB server waits 1500ms, the update arrives after having picked the + // 2nd server from batch 1 but before the next pick for the first server of + // batch 2. All server are used. + tf_result = grpc::test_update(1500); + GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced == 1); + GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 1); + GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced == 1); + GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 1); + + // If the LB server waits > 2000ms, the update arrives after the first two + // request are done and the third pick is performed, which returns, in RR + // fashion, the 1st server of the 1st update. Therefore, the second server of + // batch 1 is hit at least one, whereas the first server of batch 2 is never + // hit. + tf_result = grpc::test_update(2500); + GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced >= 1); + GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced > 0); + GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced > 0); + GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 0); + + grpc_shutdown(); + return 0; +} diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index ebef0002a3c..e5878bb248c 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -31,7 +31,6 @@ * */ -#include #include #include @@ -78,8 +77,6 @@ using grpc::testing::StreamingOutputCallResponse; using grpc::testing::TestService; using grpc::Status; -static bool got_sigint = false; - const char kEchoInitialMetadataKey[] = "x-grpc-test-echo-initial"; const char kEchoTrailingBinMetadataKey[] = "x-grpc-test-echo-trailing-bin"; const char kEchoUserAgentKey[] = "x-grpc-test-echo-useragent"; @@ -311,7 +308,9 @@ class TestServiceImpl : public TestService::Service { } }; -void RunServer() { +void grpc::testing::interop::RunServer( + std::shared_ptr creds) { + GPR_ASSERT(FLAGS_port != 0); std::ostringstream server_address; server_address << "0.0.0.0:" << FLAGS_port; TestServiceImpl service; @@ -321,24 +320,10 @@ void RunServer() { ServerBuilder builder; builder.RegisterService(&service); - std::shared_ptr creds = - grpc::testing::CreateInteropServerCredentials(); builder.AddListeningPort(server_address.str(), creds); std::unique_ptr server(builder.BuildAndStart()); gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str()); - while (!got_sigint) { + while (!g_got_sigint) { sleep(5); } } - -static void sigint_handler(int x) { got_sigint = true; } - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - signal(SIGINT, sigint_handler); - - GPR_ASSERT(FLAGS_port != 0); - RunServer(); - - return 0; -} diff --git a/src/python/grpcio/grpc/_cython/loader.c b/test/cpp/interop/interop_server_bootstrap.cc similarity index 76% rename from src/python/grpcio/grpc/_cython/loader.c rename to test/cpp/interop/interop_server_bootstrap.cc index 34bd8975495..424f7ca7f0d 100644 --- a/src/python/grpcio/grpc/_cython/loader.c +++ b/test/cpp/interop/interop_server_bootstrap.cc @@ -31,22 +31,24 @@ * */ -#include -#include "loader.h" +#include +#include -#ifdef __cplusplus -extern "C" { -#endif /* __cpluslus */ +#include "test/cpp/interop/server_helper.h" +#include "test/cpp/util/test_config.h" -int pygrpc_load_core(char *path) { return 1; } +bool grpc::testing::interop::g_got_sigint = false; -// Cython doesn't have Py_AtExit bindings, so we call the C_API directly -int pygrpc_initialize_core(void) { - grpc_init(); - return Py_AtExit(grpc_shutdown) < 0 ? 0 : 1; +static void sigint_handler(int x) { + grpc::testing::interop::g_got_sigint = true; } -#ifdef __cplusplus -} -#endif /* __cpluslus */ +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + signal(SIGINT, sigint_handler); + + grpc::testing::interop::RunServer( + grpc::testing::CreateInteropServerCredentials()); + return 0; +} diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h index a1da14a4c8d..fc4ea8b3e81 100644 --- a/test/cpp/interop/server_helper.h +++ b/test/cpp/interop/server_helper.h @@ -60,6 +60,12 @@ class InteropServerContextInspector { const ::grpc::ServerContext& context_; }; +namespace interop { + +extern bool g_got_sigint; +void RunServer(std::shared_ptr creds); + +} // namespace interop } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 4045e13460f..fada4ba7679 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -169,6 +169,7 @@ class Client { // Must call AwaitThreadsCompletion before destructor to avoid a race // between destructor and invocation of virtual ThreadFunc void AwaitThreadsCompletion() { + gpr_atm_rel_store(&thread_pool_done_, static_cast(true)); DestroyMultithreading(); std::unique_lock g(thread_completion_mu_); while (threads_remaining_ != 0) { @@ -178,8 +179,10 @@ class Client { protected: bool closed_loop_; + gpr_atm thread_pool_done_; void StartThreads(size_t num_threads) { + gpr_atm_rel_store(&thread_pool_done_, static_cast(false)); threads_remaining_ = num_threads; for (size_t i = 0; i < num_threads; i++) { threads_.emplace_back(new Thread(this, i)); @@ -241,18 +244,9 @@ class Client { class Thread { public: Thread(Client* client, size_t idx) - : done_(false), - client_(client), - idx_(idx), - impl_(&Thread::ThreadFunc, this) {} + : client_(client), idx_(idx), impl_(&Thread::ThreadFunc, this) {} - ~Thread() { - { - std::lock_guard g(mu_); - done_ = true; - } - impl_.join(); - } + ~Thread() { impl_.join(); } void BeginSwap(Histogram* n) { std::lock_guard g(mu_); @@ -282,9 +276,9 @@ class Client { } if (!thread_still_ok) { gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); - done_ = true; } - if (done_) { + if (!thread_still_ok || + static_cast(gpr_atm_acq_load(&client_->thread_pool_done_))) { client_->CompleteThread(); return; } @@ -292,7 +286,6 @@ class Client { } std::mutex mu_; - bool done_; Histogram histogram_; Client* client_; const size_t idx_; diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 25c78235532..8062424a1fb 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -79,10 +79,29 @@ class SynchronousClient virtual ~SynchronousClient(){}; protected: - void WaitToIssue(int thread_idx) { + // WaitToIssue returns false if we realize that we need to break out + bool WaitToIssue(int thread_idx) { if (!closed_loop_) { - gpr_sleep_until(NextIssueTime(thread_idx)); + const gpr_timespec next_issue_time = NextIssueTime(thread_idx); + // Avoid sleeping for too long continuously because we might + // need to terminate before then. This is an issue since + // exponential distribution can occasionally produce bad outliers + while (true) { + const gpr_timespec one_sec_delay = + gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), + gpr_time_from_seconds(1, GPR_TIMESPAN)); + if (gpr_time_cmp(next_issue_time, one_sec_delay) <= 0) { + gpr_sleep_until(next_issue_time); + return true; + } else { + gpr_sleep_until(one_sec_delay); + if (gpr_atm_acq_load(&thread_pool_done_) != static_cast(0)) { + return false; + } + } + } } + return true; } size_t num_threads_; @@ -101,7 +120,9 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { ~SynchronousUnaryClient() {} bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE { - WaitToIssue(thread_idx); + if (!WaitToIssue(thread_idx)) { + return true; + } auto* stub = channels_[thread_idx % channels_.size()].get_stub(); double start = UsageTimer::Now(); GPR_TIMER_SCOPE("SynchronousUnaryClient::ThreadFunc", 0); @@ -144,7 +165,9 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { } bool ThreadFunc(HistogramEntry* entry, size_t thread_idx) GRPC_OVERRIDE { - WaitToIssue(thread_idx); + if (!WaitToIssue(thread_idx)) { + return true; + } GPR_TIMER_SCOPE("SynchronousStreamingClient::ThreadFunc", 0); double start = UsageTimer::Now(); if (stream_[thread_idx]->Write(request_) && diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 2aeaea51f25..f67f353c4dd 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -186,6 +186,9 @@ std::unique_ptr RunScenario( const ClientConfig& initial_client_config, size_t num_clients, const ServerConfig& initial_server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count) { + // Log everything from the driver + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + // ClientContext allocations (all are destroyed at scope exit) list contexts; @@ -310,6 +313,7 @@ std::unique_ptr RunScenario( // clients is array rather than std::vector to avoid gcc-4.4 issues // where class contained in std::vector must have a copy constructor auto* clients = new ClientData[num_clients]; + size_t channels_allocated = 0; for (size_t i = 0; i < num_clients; i++) { const auto& worker = workers[i + num_servers]; gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")", @@ -345,6 +349,16 @@ std::unique_ptr RunScenario( } } + // Reduce channel count so that total channels specified is held regardless + // of the number of clients available + size_t num_channels = + (client_config.client_channels() - channels_allocated) / + (num_clients - i); + channels_allocated += num_channels; + gpr_log(GPR_DEBUG, "Client %" PRIdPTR " gets %" PRIdPTR " channels", i, + num_channels); + per_client_config.set_client_channels(num_channels); + ClientArgs args; *args.mutable_setup() = per_client_config; clients[i].stream = diff --git a/test/cpp/qps/limit_cores.cc b/test/cpp/qps/limit_cores.cc index 59ed369067f..b5c222542be 100644 --- a/test/cpp/qps/limit_cores.cc +++ b/test/cpp/qps/limit_cores.cc @@ -68,9 +68,9 @@ int LimitCores(const int* cores, int cores_size) { cores_set++; } } - GPR_ASSERT(sched_setaffinity(0, size, cpup) == 0); + bool affinity_set = (sched_setaffinity(0, size, cpup) == 0); CPU_FREE(cpup); - return cores_set; + return affinity_set ? cores_set : num_cores; } } // namespace testing diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index dea87463312..082b4bc72fe 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -108,14 +108,14 @@ class AsyncQpsServerTest : public Server { auto request_unary = std::bind(request_unary_function, &async_service_, _1, _2, _3, srv_cqs_[j].get(), srv_cqs_[j].get(), _4); - contexts_.push_front( + contexts_.emplace_back( new ServerRpcContextUnaryImpl(request_unary, process_rpc_bound)); } if (request_streaming_function) { auto request_streaming = std::bind(request_streaming_function, &async_service_, _1, _2, srv_cqs_[j].get(), srv_cqs_[j].get(), _3); - contexts_.push_front(new ServerRpcContextStreamingImpl( + contexts_.emplace_back(new ServerRpcContextStreamingImpl( request_streaming, process_rpc_bound)); } } @@ -146,10 +146,6 @@ class AsyncQpsServerTest : public Server { while ((*cq)->Next(&got_tag, &ok)) ; } - while (!contexts_.empty()) { - delete contexts_.front(); - contexts_.pop_front(); - } } private: @@ -336,7 +332,7 @@ class AsyncQpsServerTest : public Server { std::unique_ptr server_; std::vector> srv_cqs_; ServiceType async_service_; - std::forward_list contexts_; + std::vector> contexts_; struct PerThreadShutdownState { mutable std::mutex mutex; diff --git a/src/python/grpcio/grpc/_cython/loader.h b/test/cpp/util/cli_credentials.cc similarity index 64% rename from src/python/grpcio/grpc/_cython/loader.h rename to test/cpp/util/cli_credentials.cc index 62fd2252047..8de9393e4d4 100644 --- a/src/python/grpcio/grpc/_cython/loader.h +++ b/test/cpp/util/cli_credentials.cc @@ -31,31 +31,33 @@ * */ -#ifndef PYGRPC_LOADER_H_ -#define PYGRPC_LOADER_H_ - -#include "imports.generated.h" - -/* Additional inclusions not covered by "imports.generated.h" */ -#include - -/* TODO(atash) remove cruft */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cpluslus */ - -/* Attempts to load the core if necessary, and return non-zero upon succes. */ -int pygrpc_load_core(char *path); - -/* Initializes grpc and registers grpc_shutdown() to be called right before - * interpreter exit. Returns non-zero upon success. - */ -int pygrpc_initialize_core(void); - -#ifdef __cplusplus +#include "test/cpp/util/cli_credentials.h" + +#include + +DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); +DEFINE_bool(use_auth, false, "Whether to create default google credentials."); + +namespace grpc { +namespace testing { + +std::shared_ptr CliCredentials::GetCredentials() + const { + if (!FLAGS_enable_ssl) { + return grpc::InsecureChannelCredentials(); + } else { + if (FLAGS_use_auth) { + return grpc::GoogleDefaultCredentials(); + } else { + return grpc::SslCredentials(grpc::SslCredentialsOptions()); + } + } } -#endif /* __cpluslus */ - -#endif /* GRPC_RB_BYTE_BUFFER_H_ */ +const grpc::string CliCredentials::GetCredentialUsage() const { + return " --enable_ssl ; Set whether to use tls\n" + " --use_auth ; Set whether to create default google" + " credentials\n"; +} +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/cli_credentials.h b/test/cpp/util/cli_credentials.h new file mode 100644 index 00000000000..581b77a9c63 --- /dev/null +++ b/test/cpp/util/cli_credentials.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H +#define GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H + +#include +#include + +namespace grpc { +namespace testing { + +class CliCredentials { + public: + virtual ~CliCredentials() {} + virtual std::shared_ptr GetCredentials() const; + virtual const grpc::string GetCredentialUsage() const; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H diff --git a/test/cpp/util/config_grpc_cli.h b/test/cpp/util/config_grpc_cli.h new file mode 100644 index 00000000000..ea8231aa26d --- /dev/null +++ b/test/cpp/util/config_grpc_cli.h @@ -0,0 +1,85 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H +#define GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H + +#include + +#ifndef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY +#include +#define GRPC_CUSTOM_DYNAMICMESSAGEFACTORY \ + ::google::protobuf::DynamicMessageFactory +#endif + +#ifndef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE +#include +#define GRPC_CUSTOM_DESCRIPTORPOOLDATABASE \ + ::google::protobuf::DescriptorPoolDatabase +#define GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE \ + ::google::protobuf::MergedDescriptorDatabase +#endif + +#ifndef GRPC_CUSTOM_TEXTFORMAT +#include +#define GRPC_CUSTOM_TEXTFORMAT ::google::protobuf::TextFormat +#endif + +#ifndef GRPC_CUSTOM_DISKSOURCETREE +#include +#define GRPC_CUSTOM_DISKSOURCETREE ::google::protobuf::compiler::DiskSourceTree +#define GRPC_CUSTOM_IMPORTER ::google::protobuf::compiler::Importer +#define GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR \ + ::google::protobuf::compiler::MultiFileErrorCollector +#endif + +namespace grpc { +namespace protobuf { + +typedef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory; + +typedef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE DescriptorPoolDatabase; +typedef GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase; + +typedef GRPC_CUSTOM_TEXTFORMAT TextFormat; + +namespace compiler { +typedef GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree; +typedef GRPC_CUSTOM_IMPORTER Importer; +typedef GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR MultiFileErrorCollector; +} // namespace importer + +} // namespace protobuf +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc index c52e48bae65..fe248601eeb 100644 --- a/test/cpp/util/grpc_cli.cc +++ b/test/cpp/util/grpc_cli.cc @@ -33,27 +33,34 @@ /* A command line tool to talk to a grpc server. + Run `grpc_cli help` command to see its usage information. + Example of talking to grpc interop server: - grpc_cli call localhost:50051 UnaryCall src/proto/grpc/testing/test.proto \ - "response_size:10" --enable_ssl=false + grpc_cli call localhost:50051 UnaryCall "response_size:10" \ + --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false Options: - 1. --proto_path, if your proto file is not under current working directory, + 1. --protofiles, use this flag to provide proto files if the server does + does not have the reflection service. + 2. --proto_path, if your proto file is not under current working directory, use this flag to provide a search root. It should work similar to the - counterpart in protoc. - 2. --metadata specifies metadata to be sent to the server, such as: + counterpart in protoc. This option is valid only when protofiles is + provided. + 3. --metadata specifies metadata to be sent to the server, such as: --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" - 3. --enable_ssl, whether to use tls. - 4. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call - 3. --input_binary_file, a file containing the serialized request. The file - can be generated by calling something like: + 4. --enable_ssl, whether to use tls. + 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call + 6. --infile, input filename (defaults to stdin) + 7. --outfile, output filename (defaults to stdout) + 8. --binary_input, use the serialized request as input. The serialized + request can be generated by calling something like: protoc --proto_path=src/proto/grpc/testing/ \ --encode=grpc.testing.SimpleRequest \ src/proto/grpc/testing/messages.proto \ < input.txt > input.bin If this is used and no proto file is provided in the argument list, the method string has to be exact in the form of /package.service/method. - 4. --output_binary_file, a file to write binary format response into, it can + 9. --binary_output, use binary format response as output, it can be later decoded using protoc: protoc --proto_path=src/proto/grpc/testing/ \ --decode=grpc.testing.SimpleResponse \ @@ -62,165 +69,33 @@ */ #include +#include #include -#include #include -#include -#include -#include -#include -#include - -#include "test/cpp/util/cli_call.h" -#include "test/cpp/util/proto_file_parser.h" -#include "test/cpp/util/string_ref_helper.h" +#include +#include "test/cpp/util/cli_credentials.h" +#include "test/cpp/util/grpc_tool.h" #include "test/cpp/util/test_config.h" -DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls."); -DEFINE_bool(use_auth, false, "Whether to create default google credentials."); -DEFINE_string(input_binary_file, "", - "Path to input file containing serialized request."); -DEFINE_string(output_binary_file, "", - "Path to output file to write serialized response."); -DEFINE_string(metadata, "", - "Metadata to send to server, in the form of key1:val1:key2:val2"); -DEFINE_string(proto_path, ".", "Path to look for the proto file."); - -void ParseMetadataFlag( - std::multimap* client_metadata) { - if (FLAGS_metadata.empty()) { - return; - } - std::vector fields; - const char* delim = ":"; - size_t cur, next = -1; - do { - cur = next + 1; - next = FLAGS_metadata.find_first_of(delim, cur); - fields.push_back(FLAGS_metadata.substr(cur, next - cur)); - } while (next != grpc::string::npos); - if (fields.size() % 2) { - std::cout << "Failed to parse metadata flag" << std::endl; - exit(1); - } - for (size_t i = 0; i < fields.size(); i += 2) { - client_metadata->insert( - std::pair(fields[i], fields[i + 1])); - } -} +DEFINE_string(outfile, "", "Output file (default is stdout)"); -template -void PrintMetadata(const T& m, const grpc::string& message) { - if (m.empty()) { - return; - } - std::cout << message << std::endl; - grpc::string pair; - for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) { - pair.clear(); - pair.append(iter->first.data(), iter->first.size()); - pair.append(" : "); - pair.append(iter->second.data(), iter->second.size()); - std::cout << pair << std::endl; +static bool SimplePrint(const grpc::string& outfile, + const grpc::string& output) { + if (outfile.empty()) { + std::cout << output; + } else { + std::ofstream output_file(outfile, std::ios::trunc | std::ios::binary); + output_file << output; + output_file.close(); } + return true; } int main(int argc, char** argv) { grpc::testing::InitTest(&argc, &argv, true); - if (argc < 4 || argc == 5 || grpc::string(argv[1]) != "call") { - std::cout << "Usage: grpc_cli call server_host:port method_name " - << "[proto file] [text format request] []" << std::endl; - } - - grpc::string file_name; - grpc::string request_text; - grpc::string server_address(argv[2]); - grpc::string method_name(argv[3]); - std::unique_ptr parser; - grpc::string serialized_request_proto; - - if (argc == 6) { - file_name = argv[4]; - // TODO(yangg) read from stdin as well? - request_text = argv[5]; - } - - if (request_text.empty() && FLAGS_input_binary_file.empty()) { - std::cout << "Missing input. Use text format input or " - << "--input_binary_file for serialized request" << std::endl; - return 1; - } else if (!request_text.empty()) { - parser.reset(new grpc::testing::ProtoFileParser(FLAGS_proto_path, file_name, - method_name)); - method_name = parser->GetFullMethodName(); - if (parser->HasError()) { - return 1; - } - } - - if (parser) { - serialized_request_proto = - parser->GetSerializedProto(request_text, true /* is_request */); - if (parser->HasError()) { - return 1; - } - } else if (!FLAGS_input_binary_file.empty()) { - std::ifstream input_file(FLAGS_input_binary_file, - std::ios::in | std::ios::binary); - std::stringstream input_stream; - input_stream << input_file.rdbuf(); - serialized_request_proto = input_stream.str(); - } - std::cout << "connecting to " << server_address << std::endl; - - std::shared_ptr creds; - if (!FLAGS_enable_ssl) { - creds = grpc::InsecureChannelCredentials(); - } else { - if (FLAGS_use_auth) { - creds = grpc::GoogleDefaultCredentials(); - } else { - creds = grpc::SslCredentials(grpc::SslCredentialsOptions()); - } - } - std::shared_ptr channel = - grpc::CreateChannel(server_address, creds); - - grpc::string serialized_response_proto; - std::multimap client_metadata; - std::multimap server_initial_metadata, - server_trailing_metadata; - ParseMetadataFlag(&client_metadata); - PrintMetadata(client_metadata, "Sending client initial metadata:"); - grpc::Status s = grpc::testing::CliCall::Call( - channel, method_name, serialized_request_proto, - &serialized_response_proto, client_metadata, &server_initial_metadata, - &server_trailing_metadata); - PrintMetadata(server_initial_metadata, - "Received initial metadata from server:"); - PrintMetadata(server_trailing_metadata, - "Received trailing metadata from server:"); - if (s.ok()) { - std::cout << "Rpc succeeded with OK status" << std::endl; - if (parser) { - grpc::string response_text = parser->GetTextFormat( - serialized_response_proto, false /* is_request */); - if (parser->HasError()) { - return 1; - } - std::cout << "Response: \n " << response_text << std::endl; - } - if (!FLAGS_output_binary_file.empty()) { - std::ofstream output_file(FLAGS_output_binary_file, - std::ios::trunc | std::ios::binary); - output_file << serialized_response_proto; - } - } else { - std::cout << "Rpc failed with status code " << s.error_code() - << " error message " << s.error_message() << std::endl; - } - - return 0; + return grpc::testing::GrpcToolMainLib( + argc, (const char**)argv, grpc::testing::CliCredentials(), + std::bind(SimplePrint, FLAGS_outfile, std::placeholders::_1)); } diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc new file mode 100644 index 00000000000..4af00cdc966 --- /dev/null +++ b/test/cpp/util/grpc_tool.cc @@ -0,0 +1,365 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/cpp/util/grpc_tool.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "test/cpp/util/cli_call.h" +#include "test/cpp/util/proto_file_parser.h" +#include "test/cpp/util/proto_reflection_descriptor_database.h" +#include "test/cpp/util/test_config.h" + +DEFINE_bool(remotedb, true, "Use server types to parse and format messages"); +DEFINE_string(metadata, "", + "Metadata to send to server, in the form of key1:val1:key2:val2"); +DEFINE_string(proto_path, ".", "Path to look for the proto file."); +DEFINE_string(protofiles, "", "Name of the proto file."); +DEFINE_bool(binary_input, false, "Input in binary format"); +DEFINE_bool(binary_output, false, "Output in binary format"); +DEFINE_string(infile, "", "Input file (default is stdin)"); + +namespace grpc { +namespace testing { +namespace { + +class GrpcTool { + public: + explicit GrpcTool(); + virtual ~GrpcTool() {} + + bool Help(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool CallMethod(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + // TODO(zyc): implement the following methods + // bool ListServices(int argc, const char** argv, GrpcToolOutputCallback + // callback); + // bool PrintType(int argc, const char** argv, GrpcToolOutputCallback + // callback); + // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback + // callback); + // bool ParseMessage(int argc, const char** argv, GrpcToolOutputCallback + // callback); + // bool ToText(int argc, const char** argv, GrpcToolOutputCallback callback); + // bool ToBinary(int argc, const char** argv, GrpcToolOutputCallback + // callback); + + void SetPrintCommandMode(int exit_status) { + print_command_usage_ = true; + usage_exit_status_ = exit_status; + } + + private: + void CommandUsage(const grpc::string& usage) const; + bool print_command_usage_; + int usage_exit_status_; + const grpc::string cred_usage_; +}; + +template +std::function +BindWith5Args(T&& func) { + return std::bind(std::forward(func), std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5); +} + +template +size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast(!(sizeof(a) % sizeof(*(a))))); +} + +void ParseMetadataFlag( + std::multimap* client_metadata) { + if (FLAGS_metadata.empty()) { + return; + } + std::vector fields; + const char* delim = ":"; + size_t cur, next = -1; + do { + cur = next + 1; + next = FLAGS_metadata.find_first_of(delim, cur); + fields.push_back(FLAGS_metadata.substr(cur, next - cur)); + } while (next != grpc::string::npos); + if (fields.size() % 2) { + fprintf(stderr, "Failed to parse metadata flag.\n"); + exit(1); + } + for (size_t i = 0; i < fields.size(); i += 2) { + client_metadata->insert( + std::pair(fields[i], fields[i + 1])); + } +} + +template +void PrintMetadata(const T& m, const grpc::string& message) { + if (m.empty()) { + return; + } + fprintf(stderr, "%s\n", message.c_str()); + grpc::string pair; + for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) { + pair.clear(); + pair.append(iter->first.data(), iter->first.size()); + pair.append(" : "); + pair.append(iter->second.data(), iter->second.size()); + fprintf(stderr, "%s\n", pair.c_str()); + } +} + +struct Command { + const char* command; + std::function + function; + int min_args; + int max_args; +}; + +const Command ops[] = { + {"help", BindWith5Args(&GrpcTool::Help), 0, INT_MAX}, + // {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + // {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3}, + // {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, + // {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3}, + // {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3}, + // {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3}, +}; + +void Usage(const grpc::string& msg) { + fprintf( + stderr, + "%s\n" + // " grpc_cli ls ... ; List services\n" + " grpc_cli call ... ; Call method\n" + // " grpc_cli type ... ; Print type\n" + // " grpc_cli parse ... ; Parse message\n" + // " grpc_cli totext ... ; Convert binary message to text\n" + // " grpc_cli tobinary ... ; Convert text message to binary\n" + " grpc_cli help ... ; Print this message, or per-command usage\n" + "\n", + msg.c_str()); + + exit(1); +} + +const Command* FindCommand(const grpc::string& name) { + for (int i = 0; i < (int)ArraySize(ops); i++) { + if (name == ops[i].command) { + return &ops[i]; + } + } + return NULL; +} +} // namespace + +int GrpcToolMainLib(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + if (argc < 2) { + Usage("No command specified"); + } + + grpc::string command = argv[1]; + argc -= 2; + argv += 2; + + const Command* cmd = FindCommand(command); + if (cmd != NULL) { + GrpcTool grpc_tool; + if (argc < cmd->min_args || argc > cmd->max_args) { + // Force the command to print its usage message + fprintf(stderr, "\nWrong number of arguments for %s\n", command.c_str()); + grpc_tool.SetPrintCommandMode(1); + return cmd->function(&grpc_tool, -1, NULL, cred, callback); + } + const bool ok = cmd->function(&grpc_tool, argc, argv, cred, callback); + return ok ? 0 : 1; + } else { + Usage("Invalid command '" + grpc::string(command.c_str()) + "'"); + } + return 1; +} + +GrpcTool::GrpcTool() : print_command_usage_(false), usage_exit_status_(0) {} + +void GrpcTool::CommandUsage(const grpc::string& usage) const { + if (print_command_usage_) { + fprintf(stderr, "\n%s%s\n", usage.c_str(), + (usage.empty() || usage[usage.size() - 1] != '\n') ? "\n" : ""); + exit(usage_exit_status_); + } +} + +bool GrpcTool::Help(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Print help\n" + " grpc_cli help [subcommand]\n"); + + if (argc == 0) { + Usage(""); + } else { + const Command* cmd = FindCommand(argv[0]); + if (cmd == NULL) { + Usage("Unknown command '" + grpc::string(argv[0]) + "'"); + } + SetPrintCommandMode(0); + cmd->function(this, -1, NULL, cred, callback); + } + return true; +} + +bool GrpcTool::CallMethod(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Call method\n" + " grpc_cli call
[.] \n" + "
; host:port\n" + " ; Exported service name\n" + " ; Method name\n" + " ; Text protobuffer (overrides infile)\n" + " --protofiles ; Comma separated proto files used as a" + " fallback when parsing request/response\n" + " --proto_path ; The search path of proto files, valid" + " only when --protofiles is given\n" + " --metadata ; The metadata to be sent to the server\n" + " --infile ; Input filename (defaults to stdin)\n" + " --outfile ; Output filename (defaults to stdout)\n" + " --binary_input ; Input in binary format\n" + " --binary_output ; Output in binary format\n" + + cred.GetCredentialUsage()); + + std::stringstream output_ss; + grpc::string request_text; + grpc::string server_address(argv[0]); + grpc::string method_name(argv[1]); + std::unique_ptr parser; + grpc::string serialized_request_proto; + + if (argc == 3) { + request_text = argv[2]; + if (!FLAGS_infile.empty()) { + fprintf(stderr, "warning: request given in argv, ignoring --infile\n"); + } + } else { + std::stringstream input_stream; + if (FLAGS_infile.empty()) { + if (isatty(STDIN_FILENO)) { + fprintf(stderr, "reading request message from stdin...\n"); + } + input_stream << std::cin.rdbuf(); + } else { + std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary); + input_stream << input_file.rdbuf(); + input_file.close(); + } + request_text = input_stream.str(); + } + + std::shared_ptr channel = + grpc::CreateChannel(server_address, cred.GetCredentials()); + if (!FLAGS_binary_input || !FLAGS_binary_output) { + parser.reset( + new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr, + FLAGS_proto_path, FLAGS_protofiles)); + if (parser->HasError()) { + return false; + } + } + + if (FLAGS_binary_input) { + serialized_request_proto = request_text; + } else { + serialized_request_proto = parser->GetSerializedProtoFromMethod( + method_name, request_text, true /* is_request */); + if (parser->HasError()) { + return false; + } + } + fprintf(stderr, "connecting to %s\n", server_address.c_str()); + + grpc::string serialized_response_proto; + std::multimap client_metadata; + std::multimap server_initial_metadata, + server_trailing_metadata; + ParseMetadataFlag(&client_metadata); + PrintMetadata(client_metadata, "Sending client initial metadata:"); + grpc::Status status = grpc::testing::CliCall::Call( + channel, parser->GetFormatedMethodName(method_name), + serialized_request_proto, &serialized_response_proto, client_metadata, + &server_initial_metadata, &server_trailing_metadata); + PrintMetadata(server_initial_metadata, + "Received initial metadata from server:"); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); + if (status.ok()) { + fprintf(stderr, "Rpc succeeded with OK status\n"); + if (FLAGS_binary_output) { + output_ss << serialized_response_proto; + } else { + grpc::string response_text = parser->GetTextFormatFromMethod( + method_name, serialized_response_proto, false /* is_request */); + if (parser->HasError()) { + return false; + } + output_ss << "Response: \n " << response_text << std::endl; + } + } else { + fprintf(stderr, "Rpc failed with status code %d, error message: %s\n", + status.error_code(), status.error_message().c_str()); + } + + return callback(output_ss.str()); +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h new file mode 100644 index 00000000000..df3680258b8 --- /dev/null +++ b/test/cpp/util/grpc_tool.h @@ -0,0 +1,54 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_GRPC_TOOL_H +#define GRPC_TEST_CPP_UTIL_GRPC_TOOL_H + +#include + +#include + +#include "test/cpp/util/cli_credentials.h" + +namespace grpc { +namespace testing { + +typedef std::function GrpcToolOutputCallback; + +int GrpcToolMainLib(int argc, const char **argv, const CliCredentials &cred, + GrpcToolOutputCallback callback); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_GRPC_TOOL_H diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc new file mode 100644 index 00000000000..b96afaf50cb --- /dev/null +++ b/test/cpp/util/grpc_tool_test.cc @@ -0,0 +1,227 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/cpp/util/grpc_tool.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "src/proto/grpc/testing/echo.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/cli_credentials.h" +#include "test/cpp/util/string_ref_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { +namespace { + +class TestCliCredentials GRPC_FINAL : public grpc::testing::CliCredentials { + public: + std::shared_ptr GetCredentials() const + GRPC_OVERRIDE { + return InsecureChannelCredentials(); + } + const grpc::string GetCredentialUsage() const GRPC_OVERRIDE { return ""; } +}; + +} // namespame + +class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { + public: + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) GRPC_OVERRIDE { + if (!context->client_metadata().empty()) { + for (std::multimap::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + response->set_message(request->message()); + return Status::OK; + } +}; + +class GrpcToolTest : public ::testing::Test { + protected: + GrpcToolTest() {} + + // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die() + // uses atexit() to free chosen ports, and it will spawn a new thread in + // resolve_address_posix.c:192 at exit time. + const grpc::string SetUpServer() { + std::ostringstream server_address; + int port = grpc_pick_unused_port_or_die(); + server_address << "localhost:" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address.str(), InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + return server_address.str(); + } + + void ShutdownServer() { server_->Shutdown(); } + + std::unique_ptr server_; + TestServiceImpl service_; + reflection::ProtoServerReflectionPlugin plugin_; +}; + +static bool PrintStream(std::stringstream* ss, const grpc::string& output) { + (*ss) << output << std::endl; + return true; +} + +template +static size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast(!(sizeof(a) % sizeof(*(a))))); +} + +#define USAGE_REGEX "( grpc_cli .+\n){2,10}" + +TEST_F(GrpcToolTest, NoCommand) { + // Test input "grpc_cli" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, InvalidCommand) { + // Test input "grpc_cli" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "abc"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, HelpCommand) { + // Test input "grpc_cli help" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "help"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1)), + ::testing::ExitedWithCode(1), USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, CallCommand) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello'"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(NULL != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TooFewArguments) { + // Test input "grpc_cli call localhost: Echo "message: 'Hello'" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "call", "Echo"}; + + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, TooManyArguments) { + // Test input "grpc_cli call localhost: Echo Echo "message: 'Hello'" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "call", "localhost:10000", + "Echo", "Echo", "message: 'Hello'"}; + + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc index 25aec329eb3..0c88c244486 100644 --- a/test/cpp/util/proto_file_parser.cc +++ b/test/cpp/util/proto_file_parser.cc @@ -37,7 +37,6 @@ #include #include -#include #include namespace grpc { @@ -56,8 +55,7 @@ bool MethodNameMatch(const grpc::string& full_name, const grpc::string& input) { } } // namespace -class ErrorPrinter - : public google::protobuf::compiler::MultiFileErrorCollector { +class ErrorPrinter : public protobuf::compiler::MultiFileErrorCollector { public: explicit ErrorPrinter(ProtoFileParser* parser) : parser_(parser) {} @@ -71,7 +69,7 @@ class ErrorPrinter void AddWarning(const grpc::string& filename, int line, int column, const grpc::string& message) GRPC_OVERRIDE { - std::cout << "warning " << filename << " " << line << " " << column << " " + std::cerr << "warning " << filename << " " << line << " " << column << " " << message << std::endl; } @@ -79,25 +77,71 @@ class ErrorPrinter ProtoFileParser* parser_; // not owned }; -ProtoFileParser::ProtoFileParser(const grpc::string& proto_path, - const grpc::string& file_name, - const grpc::string& method) +ProtoFileParser::ProtoFileParser(std::shared_ptr channel, + const grpc::string& proto_path, + const grpc::string& protofiles) : has_error_(false) { - source_tree_.MapPath("", proto_path); - error_printer_.reset(new ErrorPrinter(this)); - importer_.reset(new google::protobuf::compiler::Importer( - &source_tree_, error_printer_.get())); - const auto* file_desc = importer_->Import(file_name); - if (!file_desc) { - LogError(""); + std::vector service_list; + if (channel) { + reflection_db_.reset(new grpc::ProtoReflectionDescriptorDatabase(channel)); + reflection_db_->GetServices(&service_list); + } + + if (!protofiles.empty()) { + source_tree_.MapPath("", proto_path); + error_printer_.reset(new ErrorPrinter(this)); + importer_.reset( + new protobuf::compiler::Importer(&source_tree_, error_printer_.get())); + + grpc::string file_name; + std::stringstream ss(protofiles); + while (std::getline(ss, file_name, ',')) { + const auto* file_desc = importer_->Import(file_name); + if (file_desc) { + for (int i = 0; i < file_desc->service_count(); i++) { + service_desc_list_.push_back(file_desc->service(i)); + } + } else { + std::cerr << file_name << " not found" << std::endl; + } + } + + file_db_.reset(new protobuf::DescriptorPoolDatabase(*importer_->pool())); + } + + if (!reflection_db_ && !file_db_) { + LogError("No available proto database"); return; } - dynamic_factory_.reset( - new google::protobuf::DynamicMessageFactory(importer_->pool())); - const google::protobuf::MethodDescriptor* method_descriptor = nullptr; - for (int i = 0; !method_descriptor && i < file_desc->service_count(); i++) { - const auto* service_desc = file_desc->service(i); + if (!reflection_db_) { + desc_db_ = std::move(file_db_); + } else if (!file_db_) { + desc_db_ = std::move(reflection_db_); + } else { + desc_db_.reset(new protobuf::MergedDescriptorDatabase(reflection_db_.get(), + file_db_.get())); + } + + desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); + dynamic_factory_.reset(new protobuf::DynamicMessageFactory(desc_pool_.get())); + + for (auto it = service_list.begin(); it != service_list.end(); it++) { + if (const protobuf::ServiceDescriptor* service_desc = + desc_pool_->FindServiceByName(*it)) { + service_desc_list_.push_back(service_desc); + } + } +} + +ProtoFileParser::~ProtoFileParser() {} + +grpc::string ProtoFileParser::GetFullMethodName(const grpc::string& method) { + has_error_ = false; + const protobuf::MethodDescriptor* method_descriptor = nullptr; + for (auto it = service_desc_list_.begin(); it != service_desc_list_.end(); + it++) { + const auto* service_desc = *it; for (int j = 0; j < service_desc->method_count(); j++) { const auto* method_desc = service_desc->method(j); if (MethodNameMatch(method_desc->full_name(), method)) { @@ -115,35 +159,87 @@ ProtoFileParser::ProtoFileParser(const grpc::string& proto_path, LogError("Method name not found"); } if (has_error_) { - return; + return ""; } - full_method_name_ = method_descriptor->full_name(); - size_t last_dot = full_method_name_.find_last_of('.'); + + return method_descriptor->full_name(); +} + +grpc::string ProtoFileParser::GetFormatedMethodName( + const grpc::string& method) { + has_error_ = false; + grpc::string formated_method_name = GetFullMethodName(method); + if (has_error_) { + return ""; + } + size_t last_dot = formated_method_name.find_last_of('.'); if (last_dot != grpc::string::npos) { - full_method_name_[last_dot] = '/'; + formated_method_name[last_dot] = '/'; + } + formated_method_name.insert(formated_method_name.begin(), '/'); + return formated_method_name; +} + +grpc::string ProtoFileParser::GetMessageTypeFromMethod( + const grpc::string& method, bool is_request) { + has_error_ = false; + grpc::string full_method_name = GetFullMethodName(method); + if (has_error_) { + return ""; + } + const protobuf::MethodDescriptor* method_desc = + desc_pool_->FindMethodByName(full_method_name); + if (!method_desc) { + LogError("Method not found"); + return ""; } - full_method_name_.insert(full_method_name_.begin(), '/'); - request_prototype_.reset( - dynamic_factory_->GetPrototype(method_descriptor->input_type())->New()); - response_prototype_.reset( - dynamic_factory_->GetPrototype(method_descriptor->output_type())->New()); + return is_request ? method_desc->input_type()->full_name() + : method_desc->output_type()->full_name(); } -ProtoFileParser::~ProtoFileParser() {} +grpc::string ProtoFileParser::GetSerializedProtoFromMethod( + const grpc::string& method, const grpc::string& text_format_proto, + bool is_request) { + has_error_ = false; + grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request); + if (has_error_) { + return ""; + } + return GetSerializedProtoFromMessageType(message_type_name, + text_format_proto); +} -grpc::string ProtoFileParser::GetSerializedProto( - const grpc::string& text_format_proto, bool is_request) { +grpc::string ProtoFileParser::GetTextFormatFromMethod( + const grpc::string& method, const grpc::string& serialized_proto, + bool is_request) { + has_error_ = false; + grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request); + if (has_error_) { + return ""; + } + return GetTextFormatFromMessageType(message_type_name, serialized_proto); +} + +grpc::string ProtoFileParser::GetSerializedProtoFromMessageType( + const grpc::string& message_type_name, + const grpc::string& text_format_proto) { + has_error_ = false; grpc::string serialized; - grpc::protobuf::Message* msg = - is_request ? request_prototype_.get() : response_prototype_.get(); - bool ok = - google::protobuf::TextFormat::ParseFromString(text_format_proto, msg); + const protobuf::Descriptor* desc = + desc_pool_->FindMessageTypeByName(message_type_name); + if (!desc) { + LogError("Message type not found"); + return ""; + } + std::unique_ptr msg( + dynamic_factory_->GetPrototype(desc)->New()); + bool ok = protobuf::TextFormat::ParseFromString(text_format_proto, msg.get()); if (!ok) { LogError("Failed to parse text format to proto."); return ""; } - ok = request_prototype_->SerializeToString(&serialized); + ok = msg->SerializeToString(&serialized); if (!ok) { LogError("Failed to serialize proto."); return ""; @@ -151,16 +247,24 @@ grpc::string ProtoFileParser::GetSerializedProto( return serialized; } -grpc::string ProtoFileParser::GetTextFormat( - const grpc::string& serialized_proto, bool is_request) { - grpc::protobuf::Message* msg = - is_request ? request_prototype_.get() : response_prototype_.get(); +grpc::string ProtoFileParser::GetTextFormatFromMessageType( + const grpc::string& message_type_name, + const grpc::string& serialized_proto) { + has_error_ = false; + const protobuf::Descriptor* desc = + desc_pool_->FindMessageTypeByName(message_type_name); + if (!desc) { + LogError("Message type not found"); + return ""; + } + std::unique_ptr msg( + dynamic_factory_->GetPrototype(desc)->New()); if (!msg->ParseFromString(serialized_proto)) { LogError("Failed to deserialize proto."); return ""; } grpc::string text_format; - if (!google::protobuf::TextFormat::PrintToString(*msg, &text_format)) { + if (!protobuf::TextFormat::PrintToString(*msg.get(), &text_format)) { LogError("Failed to print proto message to text format"); return ""; } @@ -169,7 +273,7 @@ grpc::string ProtoFileParser::GetTextFormat( void ProtoFileParser::LogError(const grpc::string& error_msg) { if (!error_msg.empty()) { - std::cout << error_msg << std::endl; + std::cerr << error_msg << std::endl; } has_error_ = true; } diff --git a/test/cpp/util/proto_file_parser.h b/test/cpp/util/proto_file_parser.h index 46cdd665038..eda3991e727 100644 --- a/test/cpp/util/proto_file_parser.h +++ b/test/cpp/util/proto_file_parser.h @@ -36,10 +36,10 @@ #include -#include -#include +#include -#include "src/compiler/config.h" +#include "test/cpp/util/config_grpc_cli.h" +#include "test/cpp/util/proto_reflection_descriptor_database.h" namespace grpc { namespace testing { @@ -48,35 +48,63 @@ class ErrorPrinter; // Find method and associated request/response types. class ProtoFileParser { public: - // The given proto file_name will be searched in a source tree rooted from - // proto_path. The method could be a partial string such as Service.Method or - // even just Method. It will log an error if there is ambiguity. - ProtoFileParser(const grpc::string& proto_path, const grpc::string& file_name, - const grpc::string& method); + // The parser will search proto files using the server reflection service + // provided on the given channel. The given protofiles in a source tree rooted + // from proto_path will also be searched. + ProtoFileParser(std::shared_ptr channel, + const grpc::string& proto_path, + const grpc::string& protofiles); + ~ProtoFileParser(); - grpc::string GetFullMethodName() const { return full_method_name_; } + // The input method name in the following four functions could be a partial + // string such as Service.Method or even just Method. It will log an error if + // there is ambiguity. + // Full method name is in the form of Service.Method, it's good to be used in + // descriptor database queries. + grpc::string GetFullMethodName(const grpc::string& method); + + // Formated method name is in the form of /Service/Method, it's good to be + // used as the argument of Stub::Call() + grpc::string GetFormatedMethodName(const grpc::string& method); + + grpc::string GetSerializedProtoFromMethod( + const grpc::string& method, const grpc::string& text_format_proto, + bool is_request); - grpc::string GetSerializedProto(const grpc::string& text_format_proto, - bool is_request); + grpc::string GetTextFormatFromMethod(const grpc::string& method, + const grpc::string& serialized_proto, + bool is_request); - grpc::string GetTextFormat(const grpc::string& serialized_proto, - bool is_request); + grpc::string GetSerializedProtoFromMessageType( + const grpc::string& message_type_name, + const grpc::string& text_format_proto); + + grpc::string GetTextFormatFromMessageType( + const grpc::string& message_type_name, + const grpc::string& serialized_proto); bool HasError() const { return has_error_; } void LogError(const grpc::string& error_msg); private: + grpc::string GetMessageTypeFromMethod(const grpc::string& method, + bool is_request); + bool has_error_; grpc::string request_text_; - grpc::string full_method_name_; - google::protobuf::compiler::DiskSourceTree source_tree_; + protobuf::compiler::DiskSourceTree source_tree_; std::unique_ptr error_printer_; - std::unique_ptr importer_; - std::unique_ptr dynamic_factory_; + std::unique_ptr importer_; + std::unique_ptr reflection_db_; + std::unique_ptr file_db_; + std::unique_ptr desc_db_; + std::unique_ptr desc_pool_; + std::unique_ptr dynamic_factory_; std::unique_ptr request_prototype_; std::unique_ptr response_prototype_; + std::vector service_desc_list_; }; } // namespace testing diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc index 25b720aee0a..f0d14c686a3 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/test/cpp/util/proto_reflection_descriptor_database.cc @@ -53,10 +53,20 @@ ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( std::shared_ptr channel) : stub_(ServerReflection::NewStub(channel)) {} -ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() {} +ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { + if (stream_) { + stream_->WritesDone(); + Status status = stream_->Finish(); + if (!status.ok()) { + gpr_log(GPR_INFO, + "ServerReflectionInfo rpc failed. Error code: %d, details: %s", + (int)status.error_code(), status.error_message().c_str()); + } + } +} bool ProtoReflectionDescriptorDatabase::FindFileByName( - const string& filename, google::protobuf::FileDescriptorProto* output) { + const string& filename, protobuf::FileDescriptorProto* output) { if (cached_db_.FindFileByName(filename, output)) { return true; } @@ -101,7 +111,7 @@ bool ProtoReflectionDescriptorDatabase::FindFileByName( } bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( - const string& symbol_name, google::protobuf::FileDescriptorProto* output) { + const string& symbol_name, protobuf::FileDescriptorProto* output) { if (cached_db_.FindFileContainingSymbol(symbol_name, output)) { return true; } @@ -148,7 +158,7 @@ bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension( const string& containing_type, int field_number, - google::protobuf::FileDescriptorProto* output) { + protobuf::FileDescriptorProto* output) { if (cached_db_.FindFileContainingExtension(containing_type, field_number, output)) { return true; @@ -276,10 +286,10 @@ bool ProtoReflectionDescriptorDatabase::GetServices( return false; } -const google::protobuf::FileDescriptorProto +const protobuf::FileDescriptorProto ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( const std::string& byte_fd_proto) { - google::protobuf::FileDescriptorProto file_desc_proto; + protobuf::FileDescriptorProto file_desc_proto; file_desc_proto.ParseFromString(byte_fd_proto); return file_desc_proto; } @@ -287,7 +297,7 @@ ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( void ProtoReflectionDescriptorDatabase::AddFileFromResponse( const grpc::reflection::v1alpha::FileDescriptorResponse& response) { for (int i = 0; i < response.file_descriptor_proto_size(); ++i) { - const google::protobuf::FileDescriptorProto file_proto = + const protobuf::FileDescriptorProto file_proto = ParseFileDescriptorProtoResponse(response.file_descriptor_proto(i)); if (known_files_.find(file_proto.name()) == known_files_.end()) { known_files_.insert(file_proto.name()); diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index 99c00675bb3..eb7cf4907db 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -38,19 +38,19 @@ #include #include -#include -#include -#include +// GRPC_NO_GENERATED_CODE indicates generated pb files should not be used +#ifdef GRPC_NO_GENERATED_CODE +#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" +#else #include +#endif // GRPC_NO_GENERATED_CODE #include - namespace grpc { // ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and // provides the methods defined by DescriptorDatabase interfaces. It can be used // to feed a DescriptorPool instance. -class ProtoReflectionDescriptorDatabase - : public google::protobuf::DescriptorDatabase { +class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { public: explicit ProtoReflectionDescriptorDatabase( std::unique_ptr stub); @@ -65,14 +65,13 @@ class ProtoReflectionDescriptorDatabase // Find a file by file name. Fills in in *output and returns true if found. // Otherwise, returns false, leaving the contents of *output undefined. bool FindFileByName(const string& filename, - google::protobuf::FileDescriptorProto* output) - GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; // Find the file that declares the given fully-qualified symbol name. // If found, fills in *output and returns true, otherwise returns false // and leaves *output undefined. bool FindFileContainingSymbol(const string& symbol_name, - google::protobuf::FileDescriptorProto* output) + protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; // Find the file which defines an extension extending the given message type @@ -81,7 +80,7 @@ class ProtoReflectionDescriptorDatabase // must be a fully-qualified type name. bool FindFileContainingExtension( const string& containing_type, int field_number, - google::protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; + protobuf::FileDescriptorProto* output) GRPC_OVERRIDE; // Finds the tag numbers used by all known extensions of // extendee_type, and appends them to output in an undefined @@ -102,7 +101,7 @@ class ProtoReflectionDescriptorDatabase grpc::reflection::v1alpha::ServerReflectionResponse> ClientStream; - const google::protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( + const protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( const std::string& byte_fd_proto); void AddFileFromResponse( @@ -123,7 +122,7 @@ class ProtoReflectionDescriptorDatabase std::unordered_map> cached_extension_numbers_; std::mutex stream_mutex_; - google::protobuf::SimpleDescriptorDatabase cached_db_; + protobuf::SimpleDescriptorDatabase cached_db_; }; } // namespace grpc diff --git a/test/distrib/csharp/DistribTest/App.config b/test/distrib/csharp/DistribTest/App.config deleted file mode 100644 index 30d3e094721..00000000000 --- a/test/distrib/csharp/DistribTest/App.config +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj index 1acb34d1b2e..0bff9ff3e0b 100644 --- a/test/distrib/csharp/DistribTest/DistribTest.csproj +++ b/test/distrib/csharp/DistribTest/DistribTest.csproj @@ -1,5 +1,5 @@  - + Debug @@ -41,6 +41,8 @@ prompt MinimumRecommendedRules.ruleset true + 4 + false bin\x64\Release\ @@ -51,65 +53,49 @@ prompt MinimumRecommendedRules.ruleset true + 4 - - ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll - - - ..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll - - - ..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll - - - ..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll - ..\packages\Grpc.Auth.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Auth.dll ..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.dll - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll - - - ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll - - - False - ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll - - ..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll + ..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll - - ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll - - - ..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll - + + ..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll + + + ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll + + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll + + + ..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll + - @@ -119,9 +105,7 @@ This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - -