diff options
40 files changed, 654 insertions, 722 deletions
@@ -247,8 +247,8 @@ cc_library( "src/core/lib/transport/mdstr_hash_table.h", "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", - "src/core/lib/transport/method_config.h", "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", @@ -436,8 +436,8 @@ cc_library( "src/core/lib/transport/mdstr_hash_table.c", "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", - "src/core/lib/transport/method_config.c", "src/core/lib/transport/pid_controller.c", + "src/core/lib/transport/service_config.c", "src/core/lib/transport/static_metadata.c", "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", @@ -681,8 +681,8 @@ cc_library( "src/core/lib/transport/mdstr_hash_table.h", "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", - "src/core/lib/transport/method_config.h", "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", @@ -855,8 +855,8 @@ cc_library( "src/core/lib/transport/mdstr_hash_table.c", "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", - "src/core/lib/transport/method_config.c", "src/core/lib/transport/pid_controller.c", + "src/core/lib/transport/service_config.c", "src/core/lib/transport/static_metadata.c", "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", @@ -1070,8 +1070,8 @@ cc_library( "src/core/lib/transport/mdstr_hash_table.h", "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", - "src/core/lib/transport/method_config.h", "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", @@ -1236,8 +1236,8 @@ cc_library( "src/core/lib/transport/mdstr_hash_table.c", "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", - "src/core/lib/transport/method_config.c", "src/core/lib/transport/pid_controller.c", + "src/core/lib/transport/service_config.c", "src/core/lib/transport/static_metadata.c", "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", @@ -2097,8 +2097,8 @@ objc_library( "src/core/lib/transport/mdstr_hash_table.c", "src/core/lib/transport/metadata.c", "src/core/lib/transport/metadata_batch.c", - "src/core/lib/transport/method_config.c", "src/core/lib/transport/pid_controller.c", + "src/core/lib/transport/service_config.c", "src/core/lib/transport/static_metadata.c", "src/core/lib/transport/timeout_encoding.c", "src/core/lib/transport/transport.c", @@ -2321,8 +2321,8 @@ objc_library( "src/core/lib/transport/mdstr_hash_table.h", "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", - "src/core/lib/transport/method_config.h", "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index 98d54f2198..09536d5ed8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -391,8 +391,8 @@ add_library(grpc src/core/lib/transport/mdstr_hash_table.c src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c - src/core/lib/transport/method_config.c src/core/lib/transport/pid_controller.c + src/core/lib/transport/service_config.c src/core/lib/transport/static_metadata.c src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c @@ -670,8 +670,8 @@ add_library(grpc_cronet src/core/lib/transport/mdstr_hash_table.c src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c - src/core/lib/transport/method_config.c src/core/lib/transport/pid_controller.c + src/core/lib/transport/service_config.c src/core/lib/transport/static_metadata.c src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c @@ -921,8 +921,8 @@ add_library(grpc_unsecure src/core/lib/transport/mdstr_hash_table.c src/core/lib/transport/metadata.c src/core/lib/transport/metadata_batch.c - src/core/lib/transport/method_config.c src/core/lib/transport/pid_controller.c + src/core/lib/transport/service_config.c src/core/lib/transport/static_metadata.c src/core/lib/transport/timeout_encoding.c src/core/lib/transport/transport.c @@ -2725,8 +2725,8 @@ LIBGRPC_SRC = \ src/core/lib/transport/mdstr_hash_table.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ - src/core/lib/transport/method_config.c \ src/core/lib/transport/pid_controller.c \ + src/core/lib/transport/service_config.c \ src/core/lib/transport/static_metadata.c \ src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ @@ -3022,8 +3022,8 @@ LIBGRPC_CRONET_SRC = \ src/core/lib/transport/mdstr_hash_table.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ - src/core/lib/transport/method_config.c \ src/core/lib/transport/pid_controller.c \ + src/core/lib/transport/service_config.c \ src/core/lib/transport/static_metadata.c \ src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ @@ -3310,8 +3310,8 @@ LIBGRPC_TEST_UTIL_SRC = \ src/core/lib/transport/mdstr_hash_table.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ - src/core/lib/transport/method_config.c \ src/core/lib/transport/pid_controller.c \ + src/core/lib/transport/service_config.c \ src/core/lib/transport/static_metadata.c \ src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ @@ -3527,8 +3527,8 @@ LIBGRPC_UNSECURE_SRC = \ src/core/lib/transport/mdstr_hash_table.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ - src/core/lib/transport/method_config.c \ src/core/lib/transport/pid_controller.c \ + src/core/lib/transport/service_config.c \ src/core/lib/transport/static_metadata.c \ src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ diff --git a/binding.gyp b/binding.gyp index ba90fcaa10..2f3ac0cf65 100644 --- a/binding.gyp +++ b/binding.gyp @@ -671,8 +671,8 @@ 'src/core/lib/transport/mdstr_hash_table.c', 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', - 'src/core/lib/transport/method_config.c', 'src/core/lib/transport/pid_controller.c', + 'src/core/lib/transport/service_config.c', 'src/core/lib/transport/static_metadata.c', 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', diff --git a/build.yaml b/build.yaml index 41c0f9a086..e2469d47fe 100644 --- a/build.yaml +++ b/build.yaml @@ -254,8 +254,8 @@ filegroups: - src/core/lib/transport/mdstr_hash_table.h - src/core/lib/transport/metadata.h - src/core/lib/transport/metadata_batch.h - - src/core/lib/transport/method_config.h - src/core/lib/transport/pid_controller.h + - src/core/lib/transport/service_config.h - src/core/lib/transport/static_metadata.h - src/core/lib/transport/timeout_encoding.h - src/core/lib/transport/transport.h @@ -367,8 +367,8 @@ filegroups: - src/core/lib/transport/mdstr_hash_table.c - src/core/lib/transport/metadata.c - src/core/lib/transport/metadata_batch.c - - src/core/lib/transport/method_config.c - src/core/lib/transport/pid_controller.c + - src/core/lib/transport/service_config.c - src/core/lib/transport/static_metadata.c - src/core/lib/transport/timeout_encoding.c - src/core/lib/transport/transport.c @@ -187,8 +187,8 @@ if test "$PHP_GRPC" != "no"; then src/core/lib/transport/mdstr_hash_table.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ - src/core/lib/transport/method_config.c \ src/core/lib/transport/pid_controller.c \ + src/core/lib/transport/service_config.c \ src/core/lib/transport/static_metadata.c \ src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 8869bec32e..19d5d6e85e 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -336,8 +336,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/mdstr_hash_table.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', - 'src/core/lib/transport/method_config.h', 'src/core/lib/transport/pid_controller.h', + 'src/core/lib/transport/service_config.h', 'src/core/lib/transport/static_metadata.h', 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', @@ -529,8 +529,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/mdstr_hash_table.c', 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', - 'src/core/lib/transport/method_config.c', 'src/core/lib/transport/pid_controller.c', + 'src/core/lib/transport/service_config.c', 'src/core/lib/transport/static_metadata.c', 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', @@ -739,8 +739,8 @@ Pod::Spec.new do |s| 'src/core/lib/transport/mdstr_hash_table.h', 'src/core/lib/transport/metadata.h', 'src/core/lib/transport/metadata_batch.h', - 'src/core/lib/transport/method_config.h', 'src/core/lib/transport/pid_controller.h', + 'src/core/lib/transport/service_config.h', 'src/core/lib/transport/static_metadata.h', 'src/core/lib/transport/timeout_encoding.h', 'src/core/lib/transport/transport.h', diff --git a/grpc.gemspec b/grpc.gemspec index b071fccb82..43b8caff03 100755 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -256,8 +256,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/mdstr_hash_table.h ) 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/method_config.h ) s.files += %w( src/core/lib/transport/pid_controller.h ) + s.files += %w( src/core/lib/transport/service_config.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 ) @@ -449,8 +449,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/lib/transport/mdstr_hash_table.c ) 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/method_config.c ) s.files += %w( src/core/lib/transport/pid_controller.c ) + s.files += %w( src/core/lib/transport/service_config.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 ) diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h index c8360282e7..ca269be218 100644 --- a/include/grpc++/channel.h +++ b/include/grpc++/channel.h @@ -57,6 +57,13 @@ class Channel final : public ChannelInterface, /// \a try_to_connect is set to true, try to connect. grpc_connectivity_state GetState(bool try_to_connect) override; + /// Returns the LB policy name, or the empty string if not yet available. + grpc::string GetLoadBalancingPolicyName() const; + + /// Returns the service config in JSON form, or the empty string if + /// not available. + grpc::string GetServiceConfigJSON() const; + private: template <class InputMessage, class OutputMessage> friend Status BlockingUnaryCall(ChannelInterface* channel, diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h index 49a3e9461c..37de51e813 100644 --- a/include/grpc++/support/channel_arguments.h +++ b/include/grpc++/support/channel_arguments.h @@ -90,6 +90,10 @@ class ChannelArguments { /// grpclb LB policy will be used, regardless of what is specified here. void SetLoadBalancingPolicyName(const grpc::string& lb_policy_name); + /// Set service config in JSON form. + /// Primarily meant for use in unit tests. + void SetServiceConfigJSON(const grpc::string& service_config_json); + // Generic channel argument setters. Only for advanced use cases. /// Set an integer argument \a value under \a key. void SetInt(const grpc::string& key, int value); diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 1bf78e4e69..9cb89e9841 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -473,6 +473,9 @@ typedef struct { /* If non-NULL, will be set to point to a string indicating the LB * policy name. Caller takes ownership. */ char **lb_policy_name; + /* If non-NULL, will be set to point to a string containing the + * service config used by the channel in JSON form. */ + char **service_config_json; } grpc_channel_info; typedef struct grpc_resource_quota grpc_resource_quota; diff --git a/package.xml b/package.xml index 348ad5f23c..1e737f20a9 100644 --- a/package.xml +++ b/package.xml @@ -263,8 +263,8 @@ <file baseinstalldir="/" name="src/core/lib/transport/mdstr_hash_table.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/metadata.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/metadata_batch.h" role="src" /> - <file baseinstalldir="/" name="src/core/lib/transport/method_config.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/pid_controller.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/transport/service_config.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/static_metadata.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/timeout_encoding.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/transport.h" role="src" /> @@ -456,8 +456,8 @@ <file baseinstalldir="/" name="src/core/lib/transport/mdstr_hash_table.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/metadata.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/metadata_batch.c" role="src" /> - <file baseinstalldir="/" name="src/core/lib/transport/method_config.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/pid_controller.c" role="src" /> + <file baseinstalldir="/" name="src/core/lib/transport/service_config.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/static_metadata.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/timeout_encoding.c" role="src" /> <file baseinstalldir="/" name="src/core/lib/transport/transport.c" role="src" /> diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index 1cce3bc329..a92a220c74 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -56,7 +56,7 @@ #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/metadata.h" #include "src/core/lib/transport/metadata_batch.h" -#include "src/core/lib/transport/method_config.h" +#include "src/core/lib/transport/service_config.h" #include "src/core/lib/transport/static_metadata.h" /* Client channel implementation */ @@ -82,30 +82,61 @@ static void *method_parameters_copy(void *value) { return new_value; } -static int method_parameters_cmp(void *value1, void *value2) { - const method_parameters *v1 = value1; - const method_parameters *v2 = value2; - const int retval = gpr_time_cmp(v1->timeout, v2->timeout); - if (retval != 0) return retval; - if (v1->wait_for_ready > v2->wait_for_ready) return 1; - if (v1->wait_for_ready < v2->wait_for_ready) return -1; - return 0; -} - static const grpc_mdstr_hash_table_vtable method_parameters_vtable = { - gpr_free, method_parameters_copy, method_parameters_cmp}; - -static void *method_config_convert_value( - const grpc_method_config *method_config) { + gpr_free, method_parameters_copy}; + +static void *method_parameters_create_from_json(const grpc_json *json) { + wait_for_ready_value wait_for_ready = WAIT_FOR_READY_UNSET; + gpr_timespec timeout = {0, 0, GPR_TIMESPAN}; + for (grpc_json *field = json->child; field != NULL; field = field->next) { + if (field->key == NULL) continue; + if (strcmp(field->key, "waitForReady") == 0) { + if (wait_for_ready != WAIT_FOR_READY_UNSET) return NULL; // Duplicate. + if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) { + return NULL; + } + wait_for_ready = field->type == GRPC_JSON_TRUE ? WAIT_FOR_READY_TRUE + : WAIT_FOR_READY_FALSE; + } else if (strcmp(field->key, "timeout") == 0) { + if (timeout.tv_sec > 0 || timeout.tv_nsec > 0) return NULL; // Duplicate. + if (field->type != GRPC_JSON_STRING) return NULL; + size_t len = strlen(field->value); + if (field->value[len - 1] != 's') return NULL; + char* buf = gpr_strdup(field->value); + buf[len - 1] = '\0'; // Remove trailing 's'. + char* decimal_point = strchr(buf, '.'); + if (decimal_point != NULL) { + *decimal_point = '\0'; + timeout.tv_nsec = gpr_parse_nonnegative_int(decimal_point + 1); + if (timeout.tv_nsec == -1) { + gpr_free(buf); + return NULL; + } + // There should always be exactly 3, 6, or 9 fractional digits. + int multiplier = 1; + switch (strlen(decimal_point + 1)) { + case 9: + break; + case 6: + multiplier *= 1000; + break; + case 3: + multiplier *= 1000000; + break; + default: // Unsupported number of digits. + gpr_free(buf); + return NULL; + } + timeout.tv_nsec *= multiplier; + } + timeout.tv_sec = gpr_parse_nonnegative_int(buf); + if (timeout.tv_sec == -1) return NULL; + gpr_free(buf); + } + } method_parameters *value = gpr_malloc(sizeof(method_parameters)); - const gpr_timespec *timeout = grpc_method_config_get_timeout(method_config); - value->timeout = timeout != NULL ? *timeout : gpr_time_0(GPR_TIMESPAN); - const bool *wait_for_ready = - grpc_method_config_get_wait_for_ready(method_config); - value->wait_for_ready = - wait_for_ready == NULL - ? WAIT_FOR_READY_UNSET - : (wait_for_ready ? WAIT_FOR_READY_TRUE : WAIT_FOR_READY_FALSE); + value->timeout = timeout; + value->wait_for_ready = wait_for_ready; return value; } @@ -126,6 +157,8 @@ typedef struct client_channel_channel_data { /** currently active load balancer */ char *lb_policy_name; grpc_lb_policy *lb_policy; + /** service config in JSON form */ + char *service_config_json; /** maps method names to method_parameters structs */ grpc_mdstr_hash_table *method_params_table; /** incoming resolver result - set by resolver.next() */ @@ -232,15 +265,12 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, grpc_connectivity_state state = GRPC_CHANNEL_TRANSIENT_FAILURE; bool exit_idle = false; grpc_error *state_error = GRPC_ERROR_CREATE("No load balancing policy"); + char *service_config_json = NULL; if (chand->resolver_result != NULL) { - grpc_lb_policy_args lb_policy_args; - lb_policy_args.args = chand->resolver_result; - lb_policy_args.client_channel_factory = chand->client_channel_factory; - // Find LB policy name. const grpc_arg *channel_arg = - grpc_channel_args_find(lb_policy_args.args, GRPC_ARG_LB_POLICY_NAME); + grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_POLICY_NAME); if (channel_arg != NULL) { GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING); lb_policy_name = channel_arg->value.string; @@ -249,7 +279,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, // assume that we should use the grpclb policy, regardless of what the // resolver actually specified. channel_arg = - grpc_channel_args_find(lb_policy_args.args, GRPC_ARG_LB_ADDRESSES); + grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES); if (channel_arg != NULL) { GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); grpc_lb_addresses *addresses = channel_arg->value.pointer.p; @@ -274,7 +304,10 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, // Use pick_first if nothing was specified and we didn't select grpclb // above. if (lb_policy_name == NULL) lb_policy_name = "pick_first"; - + // Instantiate LB policy. + grpc_lb_policy_args lb_policy_args; + lb_policy_args.args = chand->resolver_result; + lb_policy_args.client_channel_factory = chand->client_channel_factory; lb_policy = grpc_lb_policy_create(exec_ctx, lb_policy_name, &lb_policy_args); if (lb_policy != NULL) { @@ -283,13 +316,20 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, state = grpc_lb_policy_check_connectivity(exec_ctx, lb_policy, &state_error); } + // Find service config. channel_arg = - grpc_channel_args_find(lb_policy_args.args, GRPC_ARG_SERVICE_CONFIG); + grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG); if (channel_arg != NULL) { - GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); - method_params_table = grpc_method_config_table_convert( - (grpc_method_config_table *)channel_arg->value.pointer.p, - method_config_convert_value, &method_parameters_vtable); + GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING); + service_config_json = gpr_strdup(channel_arg->value.string); + grpc_service_config *service_config = + grpc_service_config_create(service_config_json); + if (service_config != NULL) { + method_params_table = grpc_service_config_create_method_config_table( + service_config, method_parameters_create_from_json, + &method_parameters_vtable); + grpc_service_config_destroy(service_config); + } } // Before we clean up, save a copy of lb_policy_name, since it might // be pointing to data inside chand->resolver_result. @@ -311,6 +351,10 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, } old_lb_policy = chand->lb_policy; chand->lb_policy = lb_policy; + if (service_config_json != NULL) { + gpr_free(chand->service_config_json); + chand->service_config_json = service_config_json; + } if (chand->method_params_table != NULL) { grpc_mdstr_hash_table_unref(chand->method_params_table); } @@ -446,6 +490,11 @@ static void cc_get_channel_info(grpc_exec_ctx *exec_ctx, ? NULL : gpr_strdup(chand->lb_policy_name); } + if (info->service_config_json != NULL) { + *info->service_config_json = chand->service_config_json == NULL + ? NULL + : gpr_strdup(chand->service_config_json); + } gpr_mu_unlock(&chand->mu); } @@ -489,6 +538,7 @@ static void cc_destroy_channel_elem(grpc_exec_ctx *exec_ctx, GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel"); } gpr_free(chand->lb_policy_name); + gpr_free(chand->service_config_json); if (chand->method_params_table != NULL) { grpc_mdstr_hash_table_unref(chand->method_params_table); } diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c index 1331fe1c65..28ad587c0e 100644 --- a/src/core/lib/channel/message_size_filter.c +++ b/src/core/lib/channel/message_size_filter.c @@ -39,7 +39,8 @@ #include <grpc/support/string_util.h> #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/transport/method_config.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/service_config.h" #define DEFAULT_MAX_SEND_MESSAGE_LENGTH -1 // Unlimited. // The protobuf library will (by default) start warning at 100 megs. @@ -56,30 +57,29 @@ static void* message_size_limits_copy(void* value) { return new_value; } -static int message_size_limits_cmp(void* value1, void* value2) { - const message_size_limits* v1 = value1; - const message_size_limits* v2 = value2; - if (v1->max_send_size > v2->max_send_size) return 1; - if (v1->max_send_size < v2->max_send_size) return -1; - if (v1->max_recv_size > v2->max_recv_size) return 1; - if (v1->max_recv_size < v2->max_recv_size) return -1; - return 0; -} - static const grpc_mdstr_hash_table_vtable message_size_limits_vtable = { - gpr_free, message_size_limits_copy, message_size_limits_cmp}; + gpr_free, message_size_limits_copy}; -static void* method_config_convert_value( - const grpc_method_config* method_config) { +static void* message_size_limits_create_from_json(const grpc_json* json) { + int max_request_message_bytes = -1; + int max_response_message_bytes = -1; + for (grpc_json* field = json->child; field != NULL; field = field->next) { + if (field->key == NULL) continue; + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { + if (max_request_message_bytes >= 0) return NULL; // Duplicate. + if (field->type != GRPC_JSON_STRING) return NULL; + max_request_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_request_message_bytes == -1) return NULL; + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { + if (max_response_message_bytes >= 0) return NULL; // Duplicate. + if (field->type != GRPC_JSON_STRING) return NULL; + max_response_message_bytes = gpr_parse_nonnegative_int(field->value); + if (max_response_message_bytes == -1) return NULL; + } + } message_size_limits* value = gpr_malloc(sizeof(message_size_limits)); - const int32_t* max_request_message_bytes = - grpc_method_config_get_max_request_message_bytes(method_config); - value->max_send_size = - max_request_message_bytes != NULL ? *max_request_message_bytes : -1; - const int32_t* max_response_message_bytes = - grpc_method_config_get_max_response_message_bytes(method_config); - value->max_recv_size = - max_response_message_bytes != NULL ? *max_response_message_bytes : -1; + value->max_send_size = max_request_message_bytes; + value->max_recv_size = max_response_message_bytes; return value; } @@ -223,10 +223,16 @@ static void init_channel_elem(grpc_exec_ctx* exec_ctx, const grpc_arg* channel_arg = grpc_channel_args_find(args->channel_args, GRPC_ARG_SERVICE_CONFIG); if (channel_arg != NULL) { - GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); - chand->method_limit_table = grpc_method_config_table_convert( - (grpc_method_config_table*)channel_arg->value.pointer.p, - method_config_convert_value, &message_size_limits_vtable); + GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING); + grpc_service_config* service_config = + grpc_service_config_create(channel_arg->value.string); + if (service_config != NULL) { + chand->method_limit_table = + grpc_service_config_create_method_config_table( + service_config, message_size_limits_create_from_json, + &message_size_limits_vtable); + grpc_service_config_destroy(service_config); + } } } diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c index 5b583a1f2e..48b13686d7 100644 --- a/src/core/lib/json/json.c +++ b/src/core/lib/json/json.c @@ -37,15 +37,15 @@ #include "src/core/lib/json/json.h" -grpc_json *grpc_json_create(grpc_json_type type) { - grpc_json *json = gpr_malloc(sizeof(*json)); +grpc_json* grpc_json_create(grpc_json_type type) { + grpc_json* json = gpr_malloc(sizeof(*json)); memset(json, 0, sizeof(*json)); json->type = type; return json; } -void grpc_json_destroy(grpc_json *json) { +void grpc_json_destroy(grpc_json* json) { while (json->child) { grpc_json_destroy(json->child); } diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h index 681df4bb77..7111db0b52 100644 --- a/src/core/lib/json/json.h +++ b/src/core/lib/json/json.h @@ -42,14 +42,14 @@ * are not owned by it. */ typedef struct grpc_json { - struct grpc_json *next; - struct grpc_json *prev; - struct grpc_json *child; - struct grpc_json *parent; + struct grpc_json* next; + struct grpc_json* prev; + struct grpc_json* child; + struct grpc_json* parent; grpc_json_type type; - const char *key; - const char *value; + const char* key; + const char* value; } grpc_json; /* The next two functions are going to parse the input string, and @@ -65,8 +65,8 @@ typedef struct grpc_json { * * Delete the allocated tree afterward using grpc_json_destroy(). */ -grpc_json *grpc_json_parse_string_with_len(char *input, size_t size); -grpc_json *grpc_json_parse_string(char *input); +grpc_json* grpc_json_parse_string_with_len(char* input, size_t size); +grpc_json* grpc_json_parse_string(char* input); /* This function will create a new string using gpr_realloc, and will * deserialize the grpc_json tree into it. It'll be zero-terminated, @@ -76,13 +76,13 @@ grpc_json *grpc_json_parse_string(char *input); * If indent is 0, then newlines will be suppressed as well, and the * output will be condensed at its maximum. */ -char *grpc_json_dump_to_string(grpc_json *json, int indent); +char* grpc_json_dump_to_string(grpc_json* json, int indent); /* Use these to create or delete a grpc_json object. * Deletion is recursive. We will not attempt to free any of the strings * in any of the objects of that tree. */ -grpc_json *grpc_json_create(grpc_json_type type); -void grpc_json_destroy(grpc_json *json); +grpc_json* grpc_json_create(grpc_json_type type); +void grpc_json_destroy(grpc_json* json); #endif /* GRPC_CORE_LIB_JSON_JSON_H */ diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c index dc243bf0bf..f10a30f0fd 100644 --- a/src/core/lib/support/string.c +++ b/src/core/lib/support/string.c @@ -34,7 +34,9 @@ #include "src/core/lib/support/string.h" #include <ctype.h> +#include <limits.h> #include <stddef.h> +#include <stdlib.h> #include <string.h> #include <grpc/support/alloc.h> @@ -189,6 +191,13 @@ int int64_ttoa(int64_t value, char *string) { return i; } +int gpr_parse_nonnegative_int(const char *value) { + char *end; + long result = strtol(value, &end, 0); + if (*end != '\0' || result < 0 || result > INT_MAX) return -1; + return (int)result; +} + char *gpr_leftpad(const char *str, char flag, size_t length) { const size_t str_length = strlen(str); const size_t out_length = str_length > length ? str_length : length; diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index 13891d0b9e..e933e2eb46 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -77,6 +77,9 @@ NOTE: This function ensures sufficient bit width even on Win x64, where long is 32bit is size.*/ int int64_ttoa(int64_t value, char *output); +// Parses a non-negative number from a value string. Returns -1 on error. +int gpr_parse_nonnegative_int(const char *value); + /* Reverse a run of bytes */ void gpr_reverse_bytes(char *str, int len); diff --git a/src/core/lib/transport/mdstr_hash_table.c b/src/core/lib/transport/mdstr_hash_table.c index 8e914c420b..3d01e56df7 100644 --- a/src/core/lib/transport/mdstr_hash_table.c +++ b/src/core/lib/transport/mdstr_hash_table.c @@ -41,7 +41,6 @@ struct grpc_mdstr_hash_table { gpr_refcount refs; - size_t num_entries; size_t size; grpc_mdstr_hash_table_entry* entries; }; @@ -77,7 +76,6 @@ grpc_mdstr_hash_table* grpc_mdstr_hash_table_create( grpc_mdstr_hash_table* table = gpr_malloc(sizeof(*table)); memset(table, 0, sizeof(*table)); gpr_ref_init(&table->refs, 1); - table->num_entries = num_entries; // Quadratic probing gets best performance when the table is no more // than half full. table->size = num_entries * 2; @@ -96,7 +94,7 @@ grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table) { return table; } -int grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) { +void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) { if (table != NULL && gpr_unref(&table->refs)) { for (size_t i = 0; i < table->size; ++i) { grpc_mdstr_hash_table_entry* entry = &table->entries[i]; @@ -107,13 +105,7 @@ int grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table) { } gpr_free(table->entries); gpr_free(table); - return 1; } - return 0; -} - -size_t grpc_mdstr_hash_table_num_entries(const grpc_mdstr_hash_table* table) { - return table->num_entries; } void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table, @@ -123,35 +115,3 @@ void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table, if (idx == table->size) return NULL; // Not found. return table->entries[idx].value; } - -int grpc_mdstr_hash_table_cmp(const grpc_mdstr_hash_table* table1, - const grpc_mdstr_hash_table* table2) { - // Compare by num_entries. - if (table1->num_entries < table2->num_entries) return -1; - if (table1->num_entries > table2->num_entries) return 1; - for (size_t i = 0; i < table1->num_entries; ++i) { - grpc_mdstr_hash_table_entry* e1 = &table1->entries[i]; - grpc_mdstr_hash_table_entry* e2 = &table2->entries[i]; - // Compare keys by hash value. - if (e1->key->hash < e2->key->hash) return -1; - if (e1->key->hash > e2->key->hash) return 1; - // Compare by vtable (pointer equality). - if (e1->vtable < e2->vtable) return -1; - if (e1->vtable > e2->vtable) return 1; - // Compare values via vtable. - const int value_result = e1->vtable->compare_value(e1->value, e2->value); - if (value_result != 0) return value_result; - } - return 0; -} - -void grpc_mdstr_hash_table_iterate( - const grpc_mdstr_hash_table* table, - void (*func)(const grpc_mdstr_hash_table_entry* entry, void* user_data), - void* user_data) { - for (size_t i = 0; i < table->size; ++i) { - if (table->entries[i].key != NULL) { - func(&table->entries[i], user_data); - } - } -} diff --git a/src/core/lib/transport/mdstr_hash_table.h b/src/core/lib/transport/mdstr_hash_table.h index bceb4df93d..8982ec3a8d 100644 --- a/src/core/lib/transport/mdstr_hash_table.h +++ b/src/core/lib/transport/mdstr_hash_table.h @@ -51,7 +51,6 @@ typedef struct grpc_mdstr_hash_table grpc_mdstr_hash_table; typedef struct grpc_mdstr_hash_table_vtable { void (*destroy_value)(void* value); void* (*copy_value)(void* value); - int (*compare_value)(void* value1, void* value2); } grpc_mdstr_hash_table_vtable; typedef struct grpc_mdstr_hash_table_entry { @@ -67,26 +66,11 @@ grpc_mdstr_hash_table* grpc_mdstr_hash_table_create( size_t num_entries, grpc_mdstr_hash_table_entry* entries); grpc_mdstr_hash_table* grpc_mdstr_hash_table_ref(grpc_mdstr_hash_table* table); -/** Returns 1 when \a table is destroyed. */ -int grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table); - -/** Returns the number of entries in \a table. */ -size_t grpc_mdstr_hash_table_num_entries(const grpc_mdstr_hash_table* table); +void grpc_mdstr_hash_table_unref(grpc_mdstr_hash_table* table); /** Returns the value from \a table associated with \a key. Returns NULL if \a key is not found. */ void* grpc_mdstr_hash_table_get(const grpc_mdstr_hash_table* table, const grpc_mdstr* key); -/** Compares two hash tables. - The sort order is stable but undefined. */ -int grpc_mdstr_hash_table_cmp(const grpc_mdstr_hash_table* table1, - const grpc_mdstr_hash_table* table2); - -/** Iterates over the entries in \a table, calling \a func for each entry. */ -void grpc_mdstr_hash_table_iterate( - const grpc_mdstr_hash_table* table, - void (*func)(const grpc_mdstr_hash_table_entry* entry, void* user_data), - void* user_data); - #endif /* GRPC_CORE_LIB_TRANSPORT_MDSTR_HASH_TABLE_H */ diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c deleted file mode 100644 index 57d97700bf..0000000000 --- a/src/core/lib/transport/method_config.c +++ /dev/null @@ -1,340 +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/lib/transport/method_config.h" - -#include <string.h> - -#include <grpc/impl/codegen/grpc_types.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/time.h> - -#include "src/core/lib/transport/mdstr_hash_table.h" -#include "src/core/lib/transport/metadata.h" - -// -// grpc_method_config -// - -// bool vtable - -static void* bool_copy(void* valuep) { - bool value = *(bool*)valuep; - bool* new_value = gpr_malloc(sizeof(bool)); - *new_value = value; - return new_value; -} - -static int bool_cmp(void* v1, void* v2) { - bool b1 = *(bool*)v1; - bool b2 = *(bool*)v2; - if (!b1 && b2) return -1; - if (b1 && !b2) return 1; - return 0; -} - -static grpc_mdstr_hash_table_vtable bool_vtable = {gpr_free, bool_copy, - bool_cmp}; - -// timespec vtable - -static void* timespec_copy(void* valuep) { - gpr_timespec value = *(gpr_timespec*)valuep; - gpr_timespec* new_value = gpr_malloc(sizeof(gpr_timespec)); - *new_value = value; - return new_value; -} - -static int timespec_cmp(void* v1, void* v2) { - return gpr_time_cmp(*(gpr_timespec*)v1, *(gpr_timespec*)v2); -} - -static grpc_mdstr_hash_table_vtable timespec_vtable = {gpr_free, timespec_copy, - timespec_cmp}; - -// int32 vtable - -static void* int32_copy(void* valuep) { - int32_t value = *(int32_t*)valuep; - int32_t* new_value = gpr_malloc(sizeof(int32_t)); - *new_value = value; - return new_value; -} - -static int int32_cmp(void* v1, void* v2) { - int32_t i1 = *(int32_t*)v1; - int32_t i2 = *(int32_t*)v2; - if (i1 < i2) return -1; - if (i1 > i2) return 1; - return 0; -} - -static grpc_mdstr_hash_table_vtable int32_vtable = {gpr_free, int32_copy, - int32_cmp}; - -// Hash table keys. -#define GRPC_METHOD_CONFIG_WAIT_FOR_READY "grpc.wait_for_ready" // bool -#define GRPC_METHOD_CONFIG_TIMEOUT "grpc.timeout" // gpr_timespec -#define GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES \ - "grpc.max_request_message_bytes" // int32 -#define GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES \ - "grpc.max_response_message_bytes" // int32 - -struct grpc_method_config { - grpc_mdstr_hash_table* table; - grpc_mdstr* wait_for_ready_key; - grpc_mdstr* timeout_key; - grpc_mdstr* max_request_message_bytes_key; - grpc_mdstr* max_response_message_bytes_key; -}; - -grpc_method_config* grpc_method_config_create( - bool* wait_for_ready, gpr_timespec* timeout, - int32_t* max_request_message_bytes, int32_t* max_response_message_bytes) { - grpc_method_config* method_config = gpr_malloc(sizeof(grpc_method_config)); - memset(method_config, 0, sizeof(grpc_method_config)); - method_config->wait_for_ready_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_WAIT_FOR_READY); - method_config->timeout_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_TIMEOUT); - method_config->max_request_message_bytes_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_REQUEST_MESSAGE_BYTES); - method_config->max_response_message_bytes_key = - grpc_mdstr_from_string(GRPC_METHOD_CONFIG_MAX_RESPONSE_MESSAGE_BYTES); - grpc_mdstr_hash_table_entry entries[4]; - size_t num_entries = 0; - if (wait_for_ready != NULL) { - entries[num_entries].key = method_config->wait_for_ready_key; - entries[num_entries].value = wait_for_ready; - entries[num_entries].vtable = &bool_vtable; - ++num_entries; - } - if (timeout != NULL) { - entries[num_entries].key = method_config->timeout_key; - entries[num_entries].value = timeout; - entries[num_entries].vtable = ×pec_vtable; - ++num_entries; - } - if (max_request_message_bytes != NULL) { - entries[num_entries].key = method_config->max_request_message_bytes_key; - entries[num_entries].value = max_request_message_bytes; - entries[num_entries].vtable = &int32_vtable; - ++num_entries; - } - if (max_response_message_bytes != NULL) { - entries[num_entries].key = method_config->max_response_message_bytes_key; - entries[num_entries].value = max_response_message_bytes; - entries[num_entries].vtable = &int32_vtable; - ++num_entries; - } - method_config->table = grpc_mdstr_hash_table_create(num_entries, entries); - return method_config; -} - -grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config) { - grpc_mdstr_hash_table_ref(method_config->table); - return method_config; -} - -void grpc_method_config_unref(grpc_method_config* method_config) { - if (grpc_mdstr_hash_table_unref(method_config->table)) { - GRPC_MDSTR_UNREF(method_config->wait_for_ready_key); - GRPC_MDSTR_UNREF(method_config->timeout_key); - GRPC_MDSTR_UNREF(method_config->max_request_message_bytes_key); - GRPC_MDSTR_UNREF(method_config->max_response_message_bytes_key); - gpr_free(method_config); - } -} - -int grpc_method_config_cmp(const grpc_method_config* method_config1, - const grpc_method_config* method_config2) { - return grpc_mdstr_hash_table_cmp(method_config1->table, - method_config2->table); -} - -const bool* grpc_method_config_get_wait_for_ready( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get(method_config->table, - method_config->wait_for_ready_key); -} - -const gpr_timespec* grpc_method_config_get_timeout( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get(method_config->table, - method_config->timeout_key); -} - -const int32_t* grpc_method_config_get_max_request_message_bytes( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get( - method_config->table, method_config->max_request_message_bytes_key); -} - -const int32_t* grpc_method_config_get_max_response_message_bytes( - const grpc_method_config* method_config) { - return grpc_mdstr_hash_table_get( - method_config->table, method_config->max_response_message_bytes_key); -} - -// -// grpc_method_config_table -// - -static void method_config_unref(void* valuep) { - grpc_method_config_unref(valuep); -} - -static void* method_config_ref(void* valuep) { - return grpc_method_config_ref(valuep); -} - -static int method_config_cmp(void* valuep1, void* valuep2) { - return grpc_method_config_cmp(valuep1, valuep2); -} - -static const grpc_mdstr_hash_table_vtable method_config_table_vtable = { - method_config_unref, method_config_ref, method_config_cmp}; - -grpc_method_config_table* grpc_method_config_table_create( - size_t num_entries, grpc_method_config_table_entry* entries) { - grpc_mdstr_hash_table_entry* hash_table_entries = - gpr_malloc(sizeof(grpc_mdstr_hash_table_entry) * num_entries); - for (size_t i = 0; i < num_entries; ++i) { - hash_table_entries[i].key = entries[i].method_name; - hash_table_entries[i].value = entries[i].method_config; - hash_table_entries[i].vtable = &method_config_table_vtable; - } - grpc_method_config_table* method_config_table = - grpc_mdstr_hash_table_create(num_entries, hash_table_entries); - gpr_free(hash_table_entries); - return method_config_table; -} - -grpc_method_config_table* grpc_method_config_table_ref( - grpc_method_config_table* table) { - return grpc_mdstr_hash_table_ref(table); -} - -void grpc_method_config_table_unref(grpc_method_config_table* table) { - grpc_mdstr_hash_table_unref(table); -} - -int grpc_method_config_table_cmp(const grpc_method_config_table* table1, - const grpc_method_config_table* table2) { - return grpc_mdstr_hash_table_cmp(table1, table2); -} - -void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table, - const grpc_mdstr* path) { - void* value = grpc_mdstr_hash_table_get(table, path); - // If we didn't find a match for the path, try looking for a wildcard - // entry (i.e., change "/service/method" to "/service/*"). - if (value == NULL) { - const char* path_str = grpc_mdstr_as_c_string(path); - const char* sep = strrchr(path_str, '/') + 1; - const size_t len = (size_t)(sep - path_str); - char* buf = gpr_malloc(len + 2); // '*' and NUL - memcpy(buf, path_str, len); - buf[len] = '*'; - buf[len + 1] = '\0'; - grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf); - gpr_free(buf); - value = grpc_mdstr_hash_table_get(table, wildcard_path); - GRPC_MDSTR_UNREF(wildcard_path); - } - return value; -} - -static void* copy_arg(void* p) { return grpc_method_config_table_ref(p); } - -static void destroy_arg(void* p) { grpc_method_config_table_unref(p); } - -static int cmp_arg(void* p1, void* p2) { - return grpc_method_config_table_cmp(p1, p2); -} - -static grpc_arg_pointer_vtable arg_vtable = {copy_arg, destroy_arg, cmp_arg}; - -grpc_arg grpc_method_config_table_create_channel_arg( - grpc_method_config_table* table) { - grpc_arg arg; - arg.type = GRPC_ARG_POINTER; - arg.key = GRPC_ARG_SERVICE_CONFIG; - arg.value.pointer.p = table; - arg.value.pointer.vtable = &arg_vtable; - return arg; -} - -// State used by convert_entry() below. -typedef struct conversion_state { - void* (*convert_value)(const grpc_method_config* method_config); - const grpc_mdstr_hash_table_vtable* vtable; - size_t num_entries; - grpc_mdstr_hash_table_entry* entries; -} conversion_state; - -// A function to be passed to grpc_mdstr_hash_table_iterate() to create -// a copy of the entries. -static void convert_entry(const grpc_mdstr_hash_table_entry* entry, - void* user_data) { - conversion_state* state = user_data; - state->entries[state->num_entries].key = GRPC_MDSTR_REF(entry->key); - state->entries[state->num_entries].value = state->convert_value(entry->value); - state->entries[state->num_entries].vtable = state->vtable; - ++state->num_entries; -} - -grpc_mdstr_hash_table* grpc_method_config_table_convert( - const grpc_method_config_table* table, - void* (*convert_value)(const grpc_method_config* method_config), - const grpc_mdstr_hash_table_vtable* vtable) { - // Create an array of the entries in the table with converted values. - conversion_state state; - state.convert_value = convert_value; - state.vtable = vtable; - state.num_entries = 0; - state.entries = gpr_malloc(sizeof(grpc_mdstr_hash_table_entry) * - grpc_mdstr_hash_table_num_entries(table)); - grpc_mdstr_hash_table_iterate(table, convert_entry, &state); - // Create a new table based on the array we just constructed. - grpc_mdstr_hash_table* new_table = - grpc_mdstr_hash_table_create(state.num_entries, state.entries); - // Clean up the array. - for (size_t i = 0; i < state.num_entries; ++i) { - GRPC_MDSTR_UNREF(state.entries[i].key); - vtable->destroy_value(state.entries[i].value); - } - gpr_free(state.entries); - // Return the new table. - return new_table; -} diff --git a/src/core/lib/transport/method_config.h b/src/core/lib/transport/method_config.h deleted file mode 100644 index 58fedd9436..0000000000 --- a/src/core/lib/transport/method_config.h +++ /dev/null @@ -1,136 +0,0 @@ -// -// 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_TRANSPORT_METHOD_CONFIG_H -#define GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H - -#include <stdbool.h> - -#include <grpc/impl/codegen/gpr_types.h> -#include <grpc/impl/codegen/grpc_types.h> - -#include "src/core/lib/transport/mdstr_hash_table.h" -#include "src/core/lib/transport/metadata.h" - -/// Per-method configuration. -typedef struct grpc_method_config grpc_method_config; - -/// Creates a grpc_method_config with the specified parameters. -/// Any parameter may be NULL to indicate that the value is unset. -/// -/// \a wait_for_ready indicates whether the client should wait until the -/// request deadline for the channel to become ready, even if there is a -/// temporary failure before the deadline while attempting to connect. -/// -/// \a timeout indicates the timeout for calls. -/// -/// \a max_request_message_bytes and \a max_response_message_bytes -/// indicate the maximum sizes of the request (checked when sending) and -/// response (checked when receiving) messages. -grpc_method_config* grpc_method_config_create( - bool* wait_for_ready, gpr_timespec* timeout, - int32_t* max_request_message_bytes, int32_t* max_response_message_bytes); - -grpc_method_config* grpc_method_config_ref(grpc_method_config* method_config); -void grpc_method_config_unref(grpc_method_config* method_config); - -/// Compares two grpc_method_configs. -/// The sort order is stable but undefined. -int grpc_method_config_cmp(const grpc_method_config* method_config1, - const grpc_method_config* method_config2); - -/// These methods return NULL if the requested field is unset. -/// The caller does NOT take ownership of the result. -const bool* grpc_method_config_get_wait_for_ready( - const grpc_method_config* method_config); -const gpr_timespec* grpc_method_config_get_timeout( - const grpc_method_config* method_config); -const int32_t* grpc_method_config_get_max_request_message_bytes( - const grpc_method_config* method_config); -const int32_t* grpc_method_config_get_max_response_message_bytes( - const grpc_method_config* method_config); - -/// A table of method configs. -typedef grpc_mdstr_hash_table grpc_method_config_table; - -typedef struct grpc_method_config_table_entry { - /// The name is of one of the following forms: - /// service/method -- specifies exact service and method name - /// service/* -- matches all methods for the specified service - grpc_mdstr* method_name; - grpc_method_config* method_config; -} grpc_method_config_table_entry; - -/// Takes new references to all keys and values in \a entries. -grpc_method_config_table* grpc_method_config_table_create( - size_t num_entries, grpc_method_config_table_entry* entries); - -grpc_method_config_table* grpc_method_config_table_ref( - grpc_method_config_table* table); -void grpc_method_config_table_unref(grpc_method_config_table* table); - -/// Compares two grpc_method_config_tables. -/// The sort order is stable but undefined. -int grpc_method_config_table_cmp(const grpc_method_config_table* table1, - const grpc_method_config_table* table2); - -/// Gets the method config for the specified \a path, which should be of -/// the form "/service/method". -/// Returns NULL if the method has no config. -/// Caller does NOT own a reference to the result. -/// -/// Note: This returns a void* instead of a grpc_method_config* so that -/// it can also be used for tables constructed via -/// grpc_method_config_table_convert(). -void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table, - const grpc_mdstr* path); - -/// Returns a channel arg containing \a table. -grpc_arg grpc_method_config_table_create_channel_arg( - grpc_method_config_table* table); - -/// Generates a new table from \a table whose values are converted to a -/// new form via the \a convert_value function. The new table will use -/// \a vtable for its values. -/// -/// This is generally used to convert the table's value type from -/// grpc_method_config to a simple struct containing only the parameters -/// relevant to a particular filter, thus avoiding the need for a hash -/// table lookup on the fast path. In that scenario, \a convert_value -/// will return a new instance of the struct containing the values from -/// the grpc_method_config, and \a vtable provides the methods for -/// operating on the struct type. -grpc_mdstr_hash_table* grpc_method_config_table_convert( - const grpc_method_config_table* table, - void* (*convert_value)(const grpc_method_config* method_config), - const grpc_mdstr_hash_table_vtable* vtable); - -#endif /* GRPC_CORE_LIB_TRANSPORT_METHOD_CONFIG_H */ diff --git a/src/core/lib/transport/service_config.c b/src/core/lib/transport/service_config.c new file mode 100644 index 0000000000..2e2b59e3f7 --- /dev/null +++ b/src/core/lib/transport/service_config.c @@ -0,0 +1,249 @@ +// +// 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/lib/transport/service_config.h" + +#include <string.h> + +#include <grpc/impl/codegen/grpc_types.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> + +#include "src/core/lib/json/json.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/mdstr_hash_table.h" + +// The main purpose of the code here is to parse the service config in +// JSON form, which will look like this: +// +// { +// "loadBalancingPolicy": "string", // optional +// "methodConfig": [ // array of one or more method_config objects +// { +// "name": [ // array of one or more name objects +// { +// "service": "string", // required +// "method": "string", // optional +// } +// ], +// // remaining fields are optional. +// // see https://developers.google.com/protocol-buffers/docs/proto3#json +// // for format details. +// "waitForReady": bool, +// "timeout": "duration_string", +// "maxRequestMessageBytes": "int64_string", +// "maxResponseMessageBytes": "int64_string", +// } +// ] +// } + +struct grpc_service_config { + char* json_string; // Underlying storage for json_tree. + grpc_json* json_tree; +}; + +grpc_service_config* grpc_service_config_create(const char* json_string) { + grpc_service_config* service_config = gpr_malloc(sizeof(*service_config)); + service_config->json_string = gpr_strdup(json_string); + service_config->json_tree = + grpc_json_parse_string(service_config->json_string); + if (service_config->json_tree == NULL) { + gpr_log(GPR_INFO, "failed to parse JSON for service config"); + gpr_free(service_config->json_string); + gpr_free(service_config); + return NULL; + } + return service_config; +} + +void grpc_service_config_destroy(grpc_service_config* service_config) { + grpc_json_destroy(service_config->json_tree); + gpr_free(service_config->json_string); + gpr_free(service_config); +} + +const char* grpc_service_config_get_lb_policy_name( + const grpc_service_config* service_config) { + const grpc_json* json = service_config->json_tree; + if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL; + const char* lb_policy_name = NULL; + for (grpc_json* field = json->child; field != NULL; field = field->next) { + if (field->key == NULL) return NULL; + if (strcmp(field->key, "loadBalancingPolicy") == 0) { + if (lb_policy_name != NULL) return NULL; // Duplicate. + if (field->type != GRPC_JSON_STRING) return NULL; + lb_policy_name = field->value; + } + } + return lb_policy_name; +} + +// Returns the number of names specified in the method config \a json. +static size_t count_names_in_method_config_json(grpc_json* json) { + size_t num_names = 0; + for (grpc_json* field = json->child; field != NULL; field = field->next) { + if (field->key != NULL && strcmp(field->key, "name") == 0) ++num_names; + } + return num_names; +} + +// Returns a path string for the JSON name object specified by \a json. +// Returns NULL on error. Caller takes ownership of result. +static char* parse_json_method_name(grpc_json* json) { + if (json->type != GRPC_JSON_OBJECT) return NULL; + const char* service_name = NULL; + const char* method_name = NULL; + for (grpc_json* child = json->child; child != NULL; child = child->next) { + if (child->key == NULL) return NULL; + if (child->type != GRPC_JSON_STRING) return NULL; + if (strcmp(child->key, "service") == 0) { + if (service_name != NULL) return NULL; // Duplicate. + if (child->value == NULL) return NULL; + service_name = child->value; + } else if (strcmp(child->key, "method") == 0) { + if (method_name != NULL) return NULL; // Duplicate. + if (child->value == NULL) return NULL; + method_name = child->value; + } + } + if (service_name == NULL) return NULL; // Required field. + char* path; + gpr_asprintf(&path, "/%s/%s", service_name, + method_name == NULL ? "*" : method_name); + return path; +} + +// Parses the method config from \a json. Adds an entry to \a entries for +// each name found, incrementing \a idx for each entry added. +// Returns false on error. +static bool parse_json_method_config( + grpc_json* json, void* (*create_value)(const grpc_json* method_config_json), + const grpc_mdstr_hash_table_vtable* vtable, + grpc_mdstr_hash_table_entry* entries, size_t* idx) { + // Construct value. + void* method_config = create_value(json); + if (method_config == NULL) return false; + // Construct list of paths. + bool success = false; + gpr_strvec paths; + gpr_strvec_init(&paths); + for (grpc_json* child = json->child; child != NULL; child = child->next) { + if (child->key == NULL) continue; + if (strcmp(child->key, "name") == 0) { + if (child->type != GRPC_JSON_ARRAY) goto done; + for (grpc_json* name = child->child; name != NULL; name = name->next) { + char* path = parse_json_method_name(name); + gpr_strvec_add(&paths, path); + } + } + } + if (paths.count == 0) goto done; // No names specified. + // Add entry for each path. + for (size_t i = 0; i < paths.count; ++i) { + entries[*idx].key = grpc_mdstr_from_string(paths.strs[i]); + entries[*idx].value = vtable->copy_value(method_config); + entries[*idx].vtable = vtable; + ++*idx; + } + success = true; +done: + vtable->destroy_value(method_config); + gpr_strvec_destroy(&paths); + return success; +} + +grpc_mdstr_hash_table* grpc_service_config_create_method_config_table( + const grpc_service_config* service_config, + void* (*create_value)(const grpc_json* method_config_json), + const grpc_mdstr_hash_table_vtable* vtable) { + const grpc_json* json = service_config->json_tree; + // Traverse parsed JSON tree. + if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL; + size_t num_entries = 0; + grpc_mdstr_hash_table_entry* entries = NULL; + for (grpc_json* field = json->child; field != NULL; field = field->next) { + if (field->key == NULL) return NULL; + if (strcmp(field->key, "methodConfig") == 0) { + if (entries != NULL) return NULL; // Duplicate. + if (field->type != GRPC_JSON_ARRAY) return NULL; + // Find number of entries. + for (grpc_json* method = field->child; method != NULL; + method = method->next) { + num_entries += count_names_in_method_config_json(method); + } + // Populate method config table entries. + entries = gpr_malloc(num_entries * sizeof(grpc_mdstr_hash_table_entry)); + size_t idx = 0; + for (grpc_json* method = field->child; method != NULL; + method = method->next) { + if (!parse_json_method_config(method, create_value, vtable, entries, + &idx)) { + return NULL; + } + } + GPR_ASSERT(idx == num_entries); + } + } + // Instantiate method config table. + grpc_mdstr_hash_table* method_config_table = NULL; + if (entries != NULL) { + method_config_table = grpc_mdstr_hash_table_create(num_entries, entries); + // Clean up. + for (size_t i = 0; i < num_entries; ++i) { + GRPC_MDSTR_UNREF(entries[i].key); + vtable->destroy_value(entries[i].value); + } + gpr_free(entries); + } + return method_config_table; +} + +void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table, + const grpc_mdstr* path) { + void* value = grpc_mdstr_hash_table_get(table, path); + // If we didn't find a match for the path, try looking for a wildcard + // entry (i.e., change "/service/method" to "/service/*"). + if (value == NULL) { + const char* path_str = grpc_mdstr_as_c_string(path); + const char* sep = strrchr(path_str, '/') + 1; + const size_t len = (size_t)(sep - path_str); + char* buf = gpr_malloc(len + 2); // '*' and NUL + memcpy(buf, path_str, len); + buf[len] = '*'; + buf[len + 1] = '\0'; + grpc_mdstr* wildcard_path = grpc_mdstr_from_string(buf); + gpr_free(buf); + value = grpc_mdstr_hash_table_get(table, wildcard_path); + GRPC_MDSTR_UNREF(wildcard_path); + } + return value; +} diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h new file mode 100644 index 0000000000..2ffe475193 --- /dev/null +++ b/src/core/lib/transport/service_config.h @@ -0,0 +1,70 @@ +// +// 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_TRANSPORT_SERVICE_CONFIG_H +#define GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H + +#include <grpc/impl/codegen/grpc_types.h> + +#include "src/core/lib/json/json.h" +#include "src/core/lib/transport/mdstr_hash_table.h" + +typedef struct grpc_service_config grpc_service_config; + +grpc_service_config* grpc_service_config_create(const char* json_string); +void grpc_service_config_destroy(grpc_service_config* service_config); + +/// Gets the LB policy name from \a service_config. +/// Returns NULL if no LB policy name was specified. +/// Caller does NOT take ownership. +const char* grpc_service_config_get_lb_policy_name( + const grpc_service_config* service_config); + +/// Creates a method config table based on the data in \a json. +/// The table's keys are request paths. The table's value type is +/// returned by \a create_value(), based on data parsed from the JSON tree. +/// \a vtable provides methods used to manage the values. +/// Returns NULL on error. +grpc_mdstr_hash_table* grpc_service_config_create_method_config_table( + const grpc_service_config* service_config, + void* (*create_value)(const grpc_json* method_config_json), + const grpc_mdstr_hash_table_vtable* vtable); + +/// A helper function for looking up values in the table returned by +/// \a grpc_service_config_create_method_config_table(). +/// Gets the method config for the specified \a path, which should be of +/// the form "/service/method". +/// Returns NULL if the method has no config. +/// Caller does NOT own a reference to the result. +void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table, + const grpc_mdstr* path); + +#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */ diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc index 5f1d00d2b4..357d8317ad 100644 --- a/src/cpp/client/channel_cc.cc +++ b/src/cpp/client/channel_cc.cc @@ -48,6 +48,7 @@ #include <grpc++/support/time.h> #include <grpc/grpc.h> #include <grpc/slice.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include "src/core/lib/profiling/timers.h" @@ -61,6 +62,35 @@ Channel::Channel(const grpc::string& host, grpc_channel* channel) Channel::~Channel() { grpc_channel_destroy(c_channel_); } +namespace { + +grpc::string GetChannelInfoField(grpc_channel* channel, + grpc_channel_info* channel_info, + char*** channel_info_field) { + char* value = NULL; + memset(channel_info, 0, sizeof(*channel_info)); + *channel_info_field = &value; + grpc_channel_get_info(channel, channel_info); + if (value == NULL) return ""; + grpc::string result = value; + gpr_free(value); + return result; +} + +} // namespace + +grpc::string Channel::GetLoadBalancingPolicyName() const { + grpc_channel_info channel_info; + return GetChannelInfoField(c_channel_, &channel_info, + &channel_info.lb_policy_name); +} + +grpc::string Channel::GetServiceConfigJSON() const { + grpc_channel_info channel_info; + return GetChannelInfoField(c_channel_, &channel_info, + &channel_info.service_config_json); +} + Call Channel::CreateCall(const RpcMethod& method, ClientContext* context, CompletionQueue* cq) { const bool kRegistered = method.channel_tag() && context->authority().empty(); diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc index d86ba9dd4e..305ea0f14c 100644 --- a/src/cpp/common/channel_arguments.cc +++ b/src/cpp/common/channel_arguments.cc @@ -125,6 +125,11 @@ void ChannelArguments::SetLoadBalancingPolicyName( SetString(GRPC_ARG_LB_POLICY_NAME, lb_policy_name); } +void ChannelArguments::SetServiceConfigJSON( + const grpc::string& service_config_json) { + SetString(GRPC_ARG_SERVICE_CONFIG, service_config_json); +} + void ChannelArguments::SetInt(const grpc::string& key, int value) { grpc_arg arg; arg.type = GRPC_ARG_INTEGER; diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index b0041871d4..58efc25a88 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -181,8 +181,8 @@ CORE_SOURCE_FILES = [ 'src/core/lib/transport/mdstr_hash_table.c', 'src/core/lib/transport/metadata.c', 'src/core/lib/transport/metadata_batch.c', - 'src/core/lib/transport/method_config.c', 'src/core/lib/transport/pid_controller.c', + 'src/core/lib/transport/service_config.c', 'src/core/lib/transport/static_metadata.c', 'src/core/lib/transport/timeout_encoding.c', 'src/core/lib/transport/transport.c', diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c index 198aafb91f..3aba906094 100644 --- a/test/core/client_channel/lb_policies_test.c +++ b/test/core/client_channel/lb_policies_test.c @@ -43,6 +43,7 @@ #include "src/core/ext/client_channel/client_channel.h" #include "src/core/ext/client_channel/lb_policy_registry.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/support/string.h" #include "src/core/lib/surface/channel.h" @@ -642,21 +643,43 @@ static void test_pending_calls(size_t concurrent_calls) { } static void test_get_channel_info() { - grpc_channel *channel = grpc_insecure_channel_create( - "test:127.0.0.1:1234?lb_policy=round_robin", NULL, NULL); + grpc_channel *channel = + grpc_insecure_channel_create("ipv4:127.0.0.1:1234", NULL, NULL); // Ensures that resolver returns. grpc_channel_check_connectivity_state(channel, true /* try_to_connect */); - // Use grpc_channel_get_info() to get LB policy name. - char *lb_policy_name = NULL; + // First, request no fields. This is a no-op. grpc_channel_info channel_info; + memset(&channel_info, 0, sizeof(channel_info)); + grpc_channel_get_info(channel, &channel_info); + // Request LB policy name. + char *lb_policy_name = NULL; channel_info.lb_policy_name = &lb_policy_name; grpc_channel_get_info(channel, &channel_info); GPR_ASSERT(lb_policy_name != NULL); - GPR_ASSERT(strcmp(lb_policy_name, "round_robin") == 0); + GPR_ASSERT(strcmp(lb_policy_name, "pick_first") == 0); gpr_free(lb_policy_name); - // Try again without requesting anything. This is a no-op. - channel_info.lb_policy_name = NULL; + // Request service config, which does not exist, so we'll get nothing back. + memset(&channel_info, 0, sizeof(channel_info)); + char *service_config_json = "dummy_string"; + channel_info.service_config_json = &service_config_json; + grpc_channel_get_info(channel, &channel_info); + GPR_ASSERT(service_config_json == NULL); + // Recreate the channel such that it has a service config. + grpc_channel_destroy(channel); + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = GRPC_ARG_SERVICE_CONFIG; + arg.value.string = "{\"lb_policy_name\": \"round_robin\"}"; + grpc_channel_args *args = grpc_channel_args_copy_and_add(NULL, &arg, 1); + channel = grpc_insecure_channel_create("ipv4:127.0.0.1:1234", args, NULL); + grpc_channel_args_destroy(args); + // Ensures that resolver returns. + grpc_channel_check_connectivity_state(channel, true /* try_to_connect */); + // Now request the service config again. grpc_channel_get_info(channel, &channel_info); + GPR_ASSERT(service_config_json != NULL); + GPR_ASSERT(strcmp(service_config_json, arg.value.string) == 0); + gpr_free(service_config_json); // Clean up. grpc_channel_destroy(channel); } diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c index 13414c0378..728d6dca59 100644 --- a/test/core/end2end/connection_refused_test.c +++ b/test/core/end2end/connection_refused_test.c @@ -41,7 +41,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/method_config.h" +#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/util/port.h" @@ -76,18 +76,19 @@ static void run_test(bool wait_for_ready, bool use_service_config) { grpc_channel_args *args = NULL; if (use_service_config) { GPR_ASSERT(wait_for_ready); - grpc_method_config_table_entry entry = { - grpc_mdstr_from_string("/service/method"), - grpc_method_config_create(&wait_for_ready, NULL, NULL, NULL), - }; - grpc_method_config_table *method_config_table = - grpc_method_config_table_create(1, &entry); - GRPC_MDSTR_UNREF(entry.method_name); - grpc_method_config_unref(entry.method_config); - grpc_arg arg = - grpc_method_config_table_create_channel_arg(method_config_table); + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = GRPC_ARG_SERVICE_CONFIG; + arg.value.string = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"waitForReady\": true\n" + " } ]\n" + "}"; args = grpc_channel_args_copy_and_add(args, &arg, 1); - grpc_method_config_table_unref(method_config_table); } /* create a call, channel to a port which will refuse connection */ diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 428a2d1c3c..e582c59f2d 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -44,7 +44,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/method_config.h" +#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" @@ -134,19 +134,19 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, grpc_channel_args *args = NULL; if (use_service_config) { - gpr_timespec timeout = {5, 0, GPR_TIMESPAN}; - grpc_method_config_table_entry entry = { - grpc_mdstr_from_string("/service/method"), - grpc_method_config_create(NULL, &timeout, NULL, NULL), - }; - grpc_method_config_table *method_config_table = - grpc_method_config_table_create(1, &entry); - GRPC_MDSTR_UNREF(entry.method_name); - grpc_method_config_unref(entry.method_config); - grpc_arg arg = - grpc_method_config_table_create_channel_arg(method_config_table); + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = GRPC_ARG_SERVICE_CONFIG; + arg.value.string = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"timeout\": \"5s\"\n" + " } ]\n" + "}"; args = grpc_channel_args_copy_and_add(args, &arg, 1); - grpc_method_config_table_unref(method_config_table); } grpc_end2end_test_fixture f = diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 0ddd7bed15..c222d9dfae 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -44,7 +44,7 @@ #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/transport/metadata.h" -#include "src/core/lib/transport/method_config.h" +#include "src/core/lib/transport/service_config.h" #include "test/core/end2end/cq_verifier.h" @@ -138,19 +138,19 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config, if (use_service_config) { // We don't currently support service configs on the server side. GPR_ASSERT(send_limit); - int32_t max_request_message_bytes = 5; - grpc_method_config_table_entry entry = { - grpc_mdstr_from_string("/service/method"), - grpc_method_config_create(NULL, NULL, &max_request_message_bytes, NULL), - }; - grpc_method_config_table *method_config_table = - grpc_method_config_table_create(1, &entry); - GRPC_MDSTR_UNREF(entry.method_name); - grpc_method_config_unref(entry.method_config); - grpc_arg arg = - grpc_method_config_table_create_channel_arg(method_config_table); + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = GRPC_ARG_SERVICE_CONFIG; + arg.value.string = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"maxRequestMessageBytes\": \"5\"\n" + " } ]\n" + "}"; client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1); - grpc_method_config_table_unref(method_config_table); } else { // Set limit via channel args. grpc_arg arg; @@ -312,20 +312,19 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config, if (use_service_config) { // We don't currently support service configs on the server side. GPR_ASSERT(!send_limit); - int32_t max_response_message_bytes = 5; - grpc_method_config_table_entry entry = { - grpc_mdstr_from_string("/service/method"), - grpc_method_config_create(NULL, NULL, NULL, - &max_response_message_bytes), - }; - grpc_method_config_table *method_config_table = - grpc_method_config_table_create(1, &entry); - GRPC_MDSTR_UNREF(entry.method_name); - grpc_method_config_unref(entry.method_config); - grpc_arg arg = - grpc_method_config_table_create_channel_arg(method_config_table); + grpc_arg arg; + arg.type = GRPC_ARG_STRING; + arg.key = GRPC_ARG_SERVICE_CONFIG; + arg.value.string = + "{\n" + " \"methodConfig\": [ {\n" + " \"name\": [\n" + " { \"service\": \"service\", \"method\": \"method\" }\n" + " ],\n" + " \"maxResponseMessageBytes\": \"5\"\n" + " } ]\n" + "}"; client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1); - grpc_method_config_table_unref(method_config_table); } else { // Set limit via channel args. grpc_arg arg; diff --git a/test/cpp/end2end/round_robin_end2end_test.cc b/test/cpp/end2end/round_robin_end2end_test.cc index 76211cbdd3..cc340b96b3 100644 --- a/test/cpp/end2end/round_robin_end2end_test.cc +++ b/test/cpp/end2end/round_robin_end2end_test.cc @@ -109,9 +109,9 @@ class RoundRobinEnd2endTest : public ::testing::Test { uri << "127.0.0.1:" << servers_[i]->port_ << ","; } uri << "127.0.0.1:" << servers_[servers_.size() - 1]->port_; - std::shared_ptr<Channel> channel = + channel_ = CreateCustomChannel(uri.str(), InsecureChannelCredentials(), args); - stub_ = grpc::testing::EchoTestService::NewStub(channel); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); } void SendRpc(int num_rpcs) { @@ -165,6 +165,7 @@ class RoundRobinEnd2endTest : public ::testing::Test { const grpc::string server_host_; CompletionQueue cli_cq_; + std::shared_ptr<Channel> channel_; std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; std::vector<std::unique_ptr<ServerData>> servers_; }; @@ -186,6 +187,8 @@ TEST_F(RoundRobinEnd2endTest, PickFirst) { } } EXPECT_TRUE(found); + // Check LB policy name for the channel. + EXPECT_EQ("pick_first", channel_->GetLoadBalancingPolicyName()); } TEST_F(RoundRobinEnd2endTest, RoundRobin) { @@ -198,6 +201,8 @@ TEST_F(RoundRobinEnd2endTest, RoundRobin) { for (size_t i = 0; i < servers_.size(); ++i) { EXPECT_EQ(1, servers_[i]->service_.request_count()); } + // Check LB policy name for the channel. + EXPECT_EQ("round_robin", channel_->GetLoadBalancingPolicyName()); } } // namespace diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 55b8d40aca..d71efc168e 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -879,8 +879,8 @@ src/core/lib/transport/connectivity_state.h \ src/core/lib/transport/mdstr_hash_table.h \ src/core/lib/transport/metadata.h \ src/core/lib/transport/metadata_batch.h \ -src/core/lib/transport/method_config.h \ src/core/lib/transport/pid_controller.h \ +src/core/lib/transport/service_config.h \ src/core/lib/transport/static_metadata.h \ src/core/lib/transport/timeout_encoding.h \ src/core/lib/transport/transport.h \ @@ -1072,8 +1072,8 @@ src/core/lib/transport/connectivity_state.c \ src/core/lib/transport/mdstr_hash_table.c \ src/core/lib/transport/metadata.c \ src/core/lib/transport/metadata_batch.c \ -src/core/lib/transport/method_config.c \ src/core/lib/transport/pid_controller.c \ +src/core/lib/transport/service_config.c \ src/core/lib/transport/static_metadata.c \ src/core/lib/transport/timeout_encoding.c \ src/core/lib/transport/transport.c \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 104eaa7475..6ab1fdead6 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -6739,8 +6739,8 @@ "src/core/lib/transport/mdstr_hash_table.h", "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.h", - "src/core/lib/transport/method_config.h", "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/timeout_encoding.h", "src/core/lib/transport/transport.h", @@ -6956,10 +6956,10 @@ "src/core/lib/transport/metadata.h", "src/core/lib/transport/metadata_batch.c", "src/core/lib/transport/metadata_batch.h", - "src/core/lib/transport/method_config.c", - "src/core/lib/transport/method_config.h", "src/core/lib/transport/pid_controller.c", "src/core/lib/transport/pid_controller.h", + "src/core/lib/transport/service_config.c", + "src/core/lib/transport/service_config.h", "src/core/lib/transport/static_metadata.c", "src/core/lib/transport/static_metadata.h", "src/core/lib/transport/timeout_encoding.c", diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj index c608cb8943..3beff4a8d5 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj @@ -388,8 +388,8 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" /> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\method_config.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" /> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" /> @@ -690,10 +690,10 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c"> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\method_config.c"> - </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c"> diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters index c6ca85cab6..f658aad73e 100644 --- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters +++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters @@ -322,10 +322,10 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\method_config.c"> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c"> @@ -1001,10 +1001,10 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\method_config.h"> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h"> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h"> diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj index 764f4615b6..f0f49ecfc4 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj @@ -281,8 +281,8 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" /> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\method_config.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" /> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" /> @@ -541,10 +541,10 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c"> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\method_config.c"> - </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c"> diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters index 2b72043001..8413567d8f 100644 --- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters @@ -379,10 +379,10 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\method_config.c"> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c"> @@ -797,10 +797,10 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\method_config.h"> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h"> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h"> diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj index ed68f03ad5..5d971b18bd 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj @@ -378,8 +378,8 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\mdstr_hash_table.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" /> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\method_config.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h" /> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" /> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" /> @@ -658,10 +658,10 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c"> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\method_config.c"> - </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c"> + </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c"> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c"> diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters index e8c16e531f..01e4a7a698 100644 --- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -325,10 +325,10 @@ <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\method_config.c"> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> - <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.c"> + <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\service_config.c"> <Filter>src\core\lib\transport</Filter> </ClCompile> <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c"> @@ -914,10 +914,10 @@ <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\method_config.h"> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> - <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\pid_controller.h"> + <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\service_config.h"> <Filter>src\core\lib\transport</Filter> </ClInclude> <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h"> |