From c968e60e2ef60cd20353c34fb6260a63ce9db031 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 2 Nov 2016 14:07:36 -0700 Subject: Use JSON for service config channel arg. --- src/core/lib/support/string.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/core/lib/support/string.h') diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index 9a94e9471c..3a5a8ed826 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -80,6 +80,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_number(const char* value); + /* Reverse a run of bytes */ void gpr_reverse_bytes(char *str, int len); -- cgit v1.2.3 From 47f1084ce835d4288ddfa9f280e07d0a8d5719c5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 3 Nov 2016 08:45:27 -0700 Subject: clang-format --- src/core/ext/client_channel/client_channel.c | 12 ++++++------ src/core/lib/json/json.c | 6 +++--- src/core/lib/json/json.h | 22 +++++++++++----------- src/core/lib/support/string.c | 4 ++-- src/core/lib/support/string.h | 2 +- src/core/lib/transport/method_config.c | 8 +++----- test/core/end2end/connection_refused_test.c | 2 +- test/core/end2end/tests/cancel_after_accept.c | 2 +- test/core/end2end/tests/max_message_length.c | 4 ++-- 9 files changed, 30 insertions(+), 32 deletions(-) (limited to 'src/core/lib/support/string.h') diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index d53265bc9c..4ca24c4dbc 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -86,21 +86,21 @@ static const grpc_mdstr_hash_table_vtable method_parameters_vtable = { 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) { + 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, "wait_for_ready") == 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; + 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_OBJECT) return NULL; if (field->child == NULL) return NULL; - for (grpc_json* subfield = field->child; subfield != NULL; + for (grpc_json *subfield = field->child; subfield != NULL; subfield = subfield->next) { if (subfield->key == NULL) return NULL; if (strcmp(subfield->key, "seconds") == 0) { @@ -303,7 +303,7 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg, grpc_channel_args_find(lb_policy_args.args, GRPC_ARG_SERVICE_CONFIG); if (channel_arg != NULL) { GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER); - grpc_json_tree* json_tree = channel_arg->value.pointer.p; + grpc_json_tree *json_tree = channel_arg->value.pointer.p; method_params_table = grpc_method_config_table_create_from_json( json_tree->root, method_parameters_create_from_json, &method_parameters_vtable); diff --git a/src/core/lib/json/json.c b/src/core/lib/json/json.c index c1a99df6c3..9acf3b0438 100644 --- a/src/core/lib/json/json.c +++ b/src/core/lib/json/json.c @@ -39,15 +39,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 e18ace7547..1663c690e5 100644 --- a/src/core/lib/json/json.h +++ b/src/core/lib/json/json.h @@ -44,14 +44,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 @@ -67,8 +67,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, @@ -78,14 +78,14 @@ 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); /* Compares two JSON trees. */ int grpc_json_cmp(const grpc_json* json1, const grpc_json* json2); diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c index 56f29492bf..165b3189a5 100644 --- a/src/core/lib/support/string.c +++ b/src/core/lib/support/string.c @@ -196,8 +196,8 @@ int int64_ttoa(int64_t value, char *string) { return i; } -int gpr_parse_nonnegative_number(const char* value) { - char* end; +int gpr_parse_nonnegative_number(const char *value) { + char *end; long result = strtol(value, &end, 0); if (*end != '\0' || result < 0 || result > INT_MAX) return -1; return (int)result; diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index 3a5a8ed826..34fd154a83 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -81,7 +81,7 @@ 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_number(const char* value); +int gpr_parse_nonnegative_number(const char *value); /* Reverse a run of bytes */ void gpr_reverse_bytes(char *str, int len); diff --git a/src/core/lib/transport/method_config.c b/src/core/lib/transport/method_config.c index a163af91d6..1ce43ca13f 100644 --- a/src/core/lib/transport/method_config.c +++ b/src/core/lib/transport/method_config.c @@ -80,10 +80,9 @@ static char* parse_json_method_name(grpc_json* json) { // Parses the method config from \a json. Adds an entry to \a entries for // each name found, incrementing \a idx for each entry added. static bool parse_json_method_config( - grpc_json* json, - void* (*create_value)(const grpc_json* method_config_json), + 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) { + grpc_mdstr_hash_table_entry* entries, size_t* idx) { // Construct value. void* method_config = create_value(json); if (method_config == NULL) return NULL; @@ -135,8 +134,7 @@ grpc_mdstr_hash_table* grpc_method_config_table_create_from_json( 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)); + 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) { diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c index ba9fb3d30a..2857ca70e8 100644 --- a/test/core/end2end/connection_refused_test.c +++ b/test/core/end2end/connection_refused_test.c @@ -76,7 +76,7 @@ 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_json_tree* service_config_json = grpc_json_tree_create( + grpc_json_tree *service_config_json = grpc_json_tree_create( "{\n" " \"method_config\": [ {\n" " \"name\": [\n" diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 68a8256092..bef33f2a33 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -132,7 +132,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, grpc_channel_args *args = NULL; if (use_service_config) { - grpc_json_tree* service_config_json = grpc_json_tree_create( + grpc_json_tree *service_config_json = grpc_json_tree_create( "{\n" " \"method_config\": [ {\n" " \"name\": [\n" diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index f0bc7acdff..4cffff915e 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -137,7 +137,7 @@ 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); - grpc_json_tree* service_config_json = grpc_json_tree_create( + grpc_json_tree *service_config_json = grpc_json_tree_create( "{\n" " \"method_config\": [ {\n" " \"name\": [\n" @@ -308,7 +308,7 @@ 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); - grpc_json_tree* service_config_json = grpc_json_tree_create( + grpc_json_tree *service_config_json = grpc_json_tree_create( "{\n" " \"method_config\": [ {\n" " \"name\": [\n" -- cgit v1.2.3 From 84c8a027d3b9427982bc31be52e587ecd3462b9d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Nov 2016 09:39:34 -0800 Subject: Change JSON format to use the standard proto3 mapping for each type. --- src/core/ext/client_channel/client_channel.c | 49 +++++++++++++++++---------- src/core/lib/channel/message_size_filter.c | 12 +++---- src/core/lib/support/string.c | 2 +- src/core/lib/support/string.h | 2 +- src/core/lib/transport/service_config.c | 24 ++++++------- test/core/end2end/connection_refused_test.c | 4 +-- test/core/end2end/tests/cancel_after_accept.c | 4 +-- test/core/end2end/tests/max_message_length.c | 8 ++--- 8 files changed, 58 insertions(+), 47 deletions(-) (limited to 'src/core/lib/support/string.h') diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c index 139912e4ba..a92a220c74 100644 --- a/src/core/ext/client_channel/client_channel.c +++ b/src/core/ext/client_channel/client_channel.c @@ -90,7 +90,7 @@ static void *method_parameters_create_from_json(const grpc_json *json) { 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, "wait_for_ready") == 0) { + 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; @@ -99,26 +99,39 @@ static void *method_parameters_create_from_json(const grpc_json *json) { : 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_OBJECT) return NULL; - if (field->child == NULL) return NULL; - for (grpc_json *subfield = field->child; subfield != NULL; - subfield = subfield->next) { - if (subfield->key == NULL) return NULL; - if (strcmp(subfield->key, "seconds") == 0) { - if (timeout.tv_sec > 0) return NULL; // Duplicate. - if (subfield->type != GRPC_JSON_NUMBER) return NULL; - timeout.tv_sec = gpr_parse_nonnegative_number(subfield->value); - if (timeout.tv_sec == -1) return NULL; - } else if (strcmp(subfield->key, "nanos") == 0) { - if (timeout.tv_nsec > 0) return NULL; // Duplicate. - if (subfield->type != GRPC_JSON_NUMBER) return NULL; - timeout.tv_nsec = gpr_parse_nonnegative_number(subfield->value); - if (timeout.tv_nsec == -1) return NULL; - } else { - // Unknown key. + 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)); diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c index 507ea26c05..28ad587c0e 100644 --- a/src/core/lib/channel/message_size_filter.c +++ b/src/core/lib/channel/message_size_filter.c @@ -65,15 +65,15 @@ static void* message_size_limits_create_from_json(const grpc_json* json) { 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, "max_request_message_bytes") == 0) { + if (strcmp(field->key, "maxRequestMessageBytes") == 0) { if (max_request_message_bytes >= 0) return NULL; // Duplicate. - if (field->type != GRPC_JSON_NUMBER) return NULL; - max_request_message_bytes = gpr_parse_nonnegative_number(field->value); + 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, "max_response_message_bytes") == 0) { + } else if (strcmp(field->key, "maxResponseMessageBytes") == 0) { if (max_response_message_bytes >= 0) return NULL; // Duplicate. - if (field->type != GRPC_JSON_NUMBER) return NULL; - max_response_message_bytes = gpr_parse_nonnegative_number(field->value); + 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; } } diff --git a/src/core/lib/support/string.c b/src/core/lib/support/string.c index aa58dd15e3..f10a30f0fd 100644 --- a/src/core/lib/support/string.c +++ b/src/core/lib/support/string.c @@ -191,7 +191,7 @@ int int64_ttoa(int64_t value, char *string) { return i; } -int gpr_parse_nonnegative_number(const char *value) { +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; diff --git a/src/core/lib/support/string.h b/src/core/lib/support/string.h index a691ebb2a6..e933e2eb46 100644 --- a/src/core/lib/support/string.h +++ b/src/core/lib/support/string.h @@ -78,7 +78,7 @@ 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_number(const char *value); +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/service_config.c b/src/core/lib/transport/service_config.c index a8494cbe8b..2e2b59e3f7 100644 --- a/src/core/lib/transport/service_config.c +++ b/src/core/lib/transport/service_config.c @@ -46,8 +46,8 @@ // JSON form, which will look like this: // // { -// "lb_policy_name": "string", // optional -// "method_config": [ // array of one or more method_config objects +// "loadBalancingPolicy": "string", // optional +// "methodConfig": [ // array of one or more method_config objects // { // "name": [ // array of one or more name objects // { @@ -55,15 +55,13 @@ // "method": "string", // optional // } // ], -// // remaining fields are optional -// "wait_for_ready": bool, -// "timeout": { -// // one or both of these fields may be specified -// "seconds": number, -// "nanos": number, -// }, -// "max_request_message_bytes": number, -// "max_response_message_bytes": number +// // 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", // } // ] // } @@ -100,7 +98,7 @@ const char* grpc_service_config_get_lb_policy_name( 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, "lb_policy_name") == 0) { + 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; @@ -194,7 +192,7 @@ grpc_mdstr_hash_table* grpc_service_config_create_method_config_table( 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, "method_config") == 0) { + if (strcmp(field->key, "methodConfig") == 0) { if (entries != NULL) return NULL; // Duplicate. if (field->type != GRPC_JSON_ARRAY) return NULL; // Find number of entries. diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c index c14d72f49e..728d6dca59 100644 --- a/test/core/end2end/connection_refused_test.c +++ b/test/core/end2end/connection_refused_test.c @@ -81,11 +81,11 @@ static void run_test(bool wait_for_ready, bool use_service_config) { arg.key = GRPC_ARG_SERVICE_CONFIG; arg.value.string = "{\n" - " \"method_config\": [ {\n" + " \"methodConfig\": [ {\n" " \"name\": [\n" " { \"service\": \"service\", \"method\": \"method\" }\n" " ],\n" - " \"wait_for_ready\": true\n" + " \"waitForReady\": true\n" " } ]\n" "}"; args = grpc_channel_args_copy_and_add(args, &arg, 1); diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 28d24aa306..e582c59f2d 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -139,11 +139,11 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, arg.key = GRPC_ARG_SERVICE_CONFIG; arg.value.string = "{\n" - " \"method_config\": [ {\n" + " \"methodConfig\": [ {\n" " \"name\": [\n" " { \"service\": \"service\", \"method\": \"method\" }\n" " ],\n" - " \"timeout\": { \"seconds\": 5 }\n" + " \"timeout\": \"5s\"\n" " } ]\n" "}"; args = grpc_channel_args_copy_and_add(args, &arg, 1); diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 90dae50b75..c222d9dfae 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -143,11 +143,11 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config, arg.key = GRPC_ARG_SERVICE_CONFIG; arg.value.string = "{\n" - " \"method_config\": [ {\n" + " \"methodConfig\": [ {\n" " \"name\": [\n" " { \"service\": \"service\", \"method\": \"method\" }\n" " ],\n" - " \"max_request_message_bytes\": 5\n" + " \"maxRequestMessageBytes\": \"5\"\n" " } ]\n" "}"; client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1); @@ -317,11 +317,11 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config, arg.key = GRPC_ARG_SERVICE_CONFIG; arg.value.string = "{\n" - " \"method_config\": [ {\n" + " \"methodConfig\": [ {\n" " \"name\": [\n" " { \"service\": \"service\", \"method\": \"method\" }\n" " ],\n" - " \"max_response_message_bytes\": 5\n" + " \"maxResponseMessageBytes\": \"5\"\n" " } ]\n" "}"; client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1); -- cgit v1.2.3