aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/ext/client_channel/client_channel.c10
-rw-r--r--src/core/lib/channel/message_size_filter.c10
-rw-r--r--src/core/lib/json/json.c59
-rw-r--r--src/core/lib/json/json.h19
-rw-r--r--src/core/lib/transport/service_config.c78
-rw-r--r--src/core/lib/transport/service_config.h26
-rw-r--r--test/core/end2end/connection_refused_test.c9
-rw-r--r--test/core/end2end/tests/cancel_after_accept.c9
-rw-r--r--test/core/end2end/tests/max_message_length.c18
9 files changed, 84 insertions, 154 deletions
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index d9161f47cd..023bd24c19 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -302,11 +302,13 @@ static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
channel_arg =
grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG);
if (channel_arg != NULL) {
- GPR_ASSERT(channel_arg->type == GRPC_ARG_POINTER);
- grpc_json_tree *service_config_json = channel_arg->value.pointer.p;
- method_params_table = grpc_method_config_table_create_from_json(
- service_config_json->root, method_parameters_create_from_json,
+ GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
+ grpc_service_config* service_config =
+ grpc_service_config_create(channel_arg->value.string);
+ 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);
}
// Clean up.
grpc_channel_args_destroy(chand->resolver_result);
diff --git a/src/core/lib/channel/message_size_filter.c b/src/core/lib/channel/message_size_filter.c
index f826c74f89..b579fa367a 100644
--- a/src/core/lib/channel/message_size_filter.c
+++ b/src/core/lib/channel/message_size_filter.c
@@ -223,11 +223,13 @@ 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);
- grpc_json_tree* json_tree = channel_arg->value.pointer.p;
- chand->method_limit_table = grpc_method_config_table_create_from_json(
- json_tree->root, message_size_limits_create_from_json,
+ GPR_ASSERT(channel_arg->type == GRPC_ARG_STRING);
+ grpc_service_config* service_config =
+ grpc_service_config_create(channel_arg->value.string);
+ 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 9acf3b0438..48b13686d7 100644
--- a/src/core/lib/json/json.c
+++ b/src/core/lib/json/json.c
@@ -34,8 +34,6 @@
#include <string.h>
#include <grpc/support/alloc.h>
-#include <grpc/support/string_util.h>
-#include <grpc/support/sync.h>
#include "src/core/lib/json/json.h"
@@ -64,60 +62,3 @@ void grpc_json_destroy(grpc_json* json) {
gpr_free(json);
}
-
-int grpc_json_cmp(const grpc_json* json1, const grpc_json* json2) {
- if (json1 == NULL) {
- if (json2 != NULL) return 1;
- return 0; // Both NULL.
- } else {
- if (json2 == NULL) return -1;
- }
- // Compare type.
- if (json1->type > json2->type) return 1;
- if (json1->type < json2->type) return -1;
- // Compare key.
- if (json1->key == NULL) {
- if (json2->key != NULL) return -1;
- } else {
- if (json2->key == NULL) return 1;
- int retval = strcmp(json1->key, json2->key);
- if (retval != 0) return retval;
- }
- // Compare value.
- if (json1->value == NULL) {
- if (json2->value != NULL) return -1;
- } else {
- if (json2->value == NULL) return 1;
- int retval = strcmp(json1->value, json2->value);
- if (retval != 0) return retval;
- }
- // Recursively compare the next pointer.
- int retval = grpc_json_cmp(json1->next, json2->next);
- if (retval != 0) return retval;
- // Recursively compare the child pointer.
- retval = grpc_json_cmp(json1->child, json2->child);
- if (retval != 0) return retval;
- // Both are the same.
- return 0;
-}
-
-grpc_json_tree* grpc_json_tree_create(const char* json_string) {
- grpc_json_tree* tree = gpr_malloc(sizeof(*tree));
- tree->string = gpr_strdup(json_string);
- tree->root = grpc_json_parse_string(tree->string);
- gpr_ref_init(&tree->refs, 1);
- return tree;
-}
-
-grpc_json_tree* grpc_json_tree_ref(grpc_json_tree* tree) {
- gpr_ref(&tree->refs);
- return tree;
-}
-
-void grpc_json_tree_unref(grpc_json_tree* tree) {
- if (gpr_unref(&tree->refs)) {
- grpc_json_destroy(tree->root);
- gpr_free(tree->string);
- gpr_free(tree);
- }
-}
diff --git a/src/core/lib/json/json.h b/src/core/lib/json/json.h
index 1663c690e5..7111db0b52 100644
--- a/src/core/lib/json/json.h
+++ b/src/core/lib/json/json.h
@@ -36,8 +36,6 @@
#include <stdlib.h>
-#include <grpc/support/sync.h>
-
#include "src/core/lib/json/json_common.h"
/* A tree-like structure to hold json values. The key and value pointers
@@ -87,21 +85,4 @@ char* grpc_json_dump_to_string(grpc_json* json, int indent);
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);
-
-/* A wrapper that contains the string used for underlying allocation and
- is refcounted. */
-typedef struct {
- grpc_json* root;
- char* string;
- gpr_refcount refs;
-} grpc_json_tree;
-
-/* Creates a copy of \a json_string. */
-grpc_json_tree* grpc_json_tree_create(const char* json_string);
-
-grpc_json_tree* grpc_json_tree_ref(grpc_json_tree* tree);
-void grpc_json_tree_unref(grpc_json_tree* tree);
-
#endif /* GRPC_CORE_LIB_JSON_JSON_H */
diff --git a/src/core/lib/transport/service_config.c b/src/core/lib/transport/service_config.c
index 2a717e7b9b..a467b8c6af 100644
--- a/src/core/lib/transport/service_config.c
+++ b/src/core/lib/transport/service_config.c
@@ -42,6 +42,40 @@
#include "src/core/lib/support/string.h"
#include "src/core/lib/transport/mdstr_hash_table.h"
+struct grpc_service_config {
+ char* string;
+ grpc_json* json;
+};
+
+grpc_service_config* grpc_service_config_create(const char* json_string) {
+ grpc_service_config* service_config = gpr_malloc(sizeof(*service_config));
+ service_config->string = gpr_strdup(json_string);
+ service_config->json = grpc_json_parse_string(service_config->string);
+ return service_config;
+}
+
+void grpc_service_config_destroy(grpc_service_config* service_config) {
+ grpc_json_destroy(service_config->json);
+ gpr_free(service_config->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;
+ 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, "lb_policy_name") == 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;
@@ -115,10 +149,11 @@ done:
return retval;
}
-grpc_mdstr_hash_table* grpc_method_config_table_create_from_json(
- const grpc_json* json,
+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;
// Traverse parsed JSON tree.
if (json->type != GRPC_JSON_OBJECT || json->key != NULL) return NULL;
size_t num_entries = 0;
@@ -180,42 +215,3 @@ void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
}
return value;
}
-
-const char* grpc_service_config_get_lb_policy_name(
- grpc_json_tree* service_config) {
- grpc_json* json = service_config->root;
- 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, "lb_policy_name") == 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;
-}
-
-static void* copy_json_tree(void* t) { return grpc_json_tree_ref(t); }
-
-static void destroy_json_tree(void* t) { grpc_json_tree_unref(t); }
-
-static int cmp_json_tree(void* t1, void* t2) {
- grpc_json_tree* tree1 = t1;
- grpc_json_tree* tree2 = t2;
- return grpc_json_cmp(tree1->root, tree2->root);
-}
-
-static grpc_arg_pointer_vtable service_config_arg_vtable = {
- copy_json_tree, destroy_json_tree, cmp_json_tree};
-
-grpc_arg grpc_service_config_create_channel_arg(
- grpc_json_tree* service_config) {
- grpc_arg arg;
- arg.type = GRPC_ARG_POINTER;
- arg.key = GRPC_ARG_SERVICE_CONFIG;
- arg.value.pointer.p = service_config;
- arg.value.pointer.vtable = &service_config_arg_vtable;
- return arg;
-}
diff --git a/src/core/lib/transport/service_config.h b/src/core/lib/transport/service_config.h
index c6c8e6be7f..bf50226f96 100644
--- a/src/core/lib/transport/service_config.h
+++ b/src/core/lib/transport/service_config.h
@@ -37,16 +37,29 @@
#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_method_config_table_create_from_json(
- const grpc_json* json,
+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
+/// 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.
@@ -54,13 +67,4 @@ grpc_mdstr_hash_table* grpc_method_config_table_create_from_json(
void* grpc_method_config_table_get(const grpc_mdstr_hash_table* table,
const grpc_mdstr* path);
-/// 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(
- grpc_json_tree* service_config);
-
-/// Creates a channel arg containing \a service_config.
-grpc_arg grpc_service_config_create_channel_arg(grpc_json_tree* service_config);
-
#endif /* GRPC_CORE_LIB_TRANSPORT_SERVICE_CONFIG_H */
diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c
index 2814c94e2e..c14d72f49e 100644
--- a/test/core/end2end/connection_refused_test.c
+++ b/test/core/end2end/connection_refused_test.c
@@ -76,7 +76,10 @@ 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_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = GRPC_ARG_SERVICE_CONFIG;
+ arg.value.string =
"{\n"
" \"method_config\": [ {\n"
" \"name\": [\n"
@@ -84,10 +87,8 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
" ],\n"
" \"wait_for_ready\": true\n"
" } ]\n"
- "}");
- grpc_arg arg = grpc_service_config_create_channel_arg(service_config_json);
+ "}";
args = grpc_channel_args_copy_and_add(args, &arg, 1);
- grpc_json_tree_unref(service_config_json);
}
/* 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 a187311b79..d3155f1902 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -132,7 +132,10 @@ 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_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = GRPC_ARG_SERVICE_CONFIG;
+ arg.value.string =
"{\n"
" \"method_config\": [ {\n"
" \"name\": [\n"
@@ -140,10 +143,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config,
" ],\n"
" \"timeout\": { \"seconds\": 5 }\n"
" } ]\n"
- "}");
- grpc_arg arg = grpc_service_config_create_channel_arg(service_config_json);
+ "}";
args = grpc_channel_args_copy_and_add(args, &arg, 1);
- grpc_json_tree_unref(service_config_json);
}
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 05ac087c13..f1dbc214dd 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -137,7 +137,10 @@ 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_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = GRPC_ARG_SERVICE_CONFIG;
+ arg.value.string =
"{\n"
" \"method_config\": [ {\n"
" \"name\": [\n"
@@ -145,10 +148,8 @@ static void test_max_message_length_on_request(grpc_end2end_test_config config,
" ],\n"
" \"max_request_message_bytes\": 5\n"
" } ]\n"
- "}");
- grpc_arg arg = grpc_service_config_create_channel_arg(service_config_json);
+ "}";
client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
- grpc_json_tree_unref(service_config_json);
} else {
// Set limit via channel args.
grpc_arg arg;
@@ -308,7 +309,10 @@ 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_arg arg;
+ arg.type = GRPC_ARG_STRING;
+ arg.key = GRPC_ARG_SERVICE_CONFIG;
+ arg.value.string =
"{\n"
" \"method_config\": [ {\n"
" \"name\": [\n"
@@ -316,10 +320,8 @@ static void test_max_message_length_on_response(grpc_end2end_test_config config,
" ],\n"
" \"max_response_message_bytes\": 5\n"
" } ]\n"
- "}");
- grpc_arg arg = grpc_service_config_create_channel_arg(service_config_json);
+ "}";
client_args = grpc_channel_args_copy_and_add(NULL, &arg, 1);
- grpc_json_tree_unref(service_config_json);
} else {
// Set limit via channel args.
grpc_arg arg;