summaryrefslogtreecommitdiff
path: root/grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc
diff options
context:
space:
mode:
Diffstat (limited to 'grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc')
-rw-r--r--grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc271
1 files changed, 32 insertions, 239 deletions
diff --git a/grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc
index 500c7408..b0c8eebe 100644
--- a/grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc
+++ b/grpc/src/core/ext/filters/client_channel/resolver_result_parsing.cc
@@ -1,20 +1,18 @@
-/*
- *
- * Copyright 2018 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
+//
+// Copyright 2018 gRPC authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
#include <grpc/support/port_platform.h>
@@ -63,200 +61,15 @@ void ClientChannelServiceConfigParser::Register() {
namespace {
-std::unique_ptr<ClientChannelMethodParsedConfig::RetryPolicy> ParseRetryPolicy(
- const Json& json, grpc_error** error) {
- GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
- auto retry_policy =
- absl::make_unique<ClientChannelMethodParsedConfig::RetryPolicy>();
- if (json.type() != Json::Type::OBJECT) {
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryPolicy error:should be of type object");
- return nullptr;
- }
- std::vector<grpc_error*> error_list;
- // Parse maxAttempts.
- auto it = json.object_value().find("maxAttempts");
- if (it != json.object_value().end()) {
- if (it->second.type() != Json::Type::NUMBER) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:maxAttempts error:should be of type number"));
- } else {
- retry_policy->max_attempts =
- gpr_parse_nonnegative_int(it->second.string_value().c_str());
- if (retry_policy->max_attempts <= 1) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:maxAttempts error:should be at least 2"));
- } else if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
- gpr_log(GPR_ERROR,
- "service config: clamped retryPolicy.maxAttempts at %d",
- MAX_MAX_RETRY_ATTEMPTS);
- retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
- }
- }
- }
- // Parse initialBackoff.
- if (ParseJsonObjectFieldAsDuration(json.object_value(), "initialBackoff",
- &retry_policy->initial_backoff,
- &error_list) &&
- retry_policy->initial_backoff == 0) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:initialBackoff error:must be greater than 0"));
- }
- // Parse maxBackoff.
- if (ParseJsonObjectFieldAsDuration(json.object_value(), "maxBackoff",
- &retry_policy->max_backoff, &error_list) &&
- retry_policy->max_backoff == 0) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:maxBackoff error:should be greater than 0"));
- }
- // Parse backoffMultiplier.
- it = json.object_value().find("backoffMultiplier");
- if (it != json.object_value().end()) {
- if (it->second.type() != Json::Type::NUMBER) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:backoffMultiplier error:should be of type number"));
- } else {
- if (sscanf(it->second.string_value().c_str(), "%f",
- &retry_policy->backoff_multiplier) != 1) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:backoffMultiplier error:failed to parse"));
- } else if (retry_policy->backoff_multiplier <= 0) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:backoffMultiplier error:should be greater than 0"));
- }
- }
- }
- // Parse retryableStatusCodes.
- it = json.object_value().find("retryableStatusCodes");
- if (it != json.object_value().end()) {
- if (it->second.type() != Json::Type::ARRAY) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryableStatusCodes error:should be of type array"));
- } else {
- for (const Json& element : it->second.array_value()) {
- if (element.type() != Json::Type::STRING) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryableStatusCodes error:status codes should be of type "
- "string"));
- continue;
- }
- grpc_status_code status;
- if (!grpc_status_code_from_string(element.string_value().c_str(),
- &status)) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryableStatusCodes error:failed to parse status code"));
- continue;
- }
- retry_policy->retryable_status_codes.Add(status);
- }
- if (retry_policy->retryable_status_codes.Empty()) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryableStatusCodes error:should be non-empty"));
- };
- }
- }
- // Make sure required fields are set.
- if (error_list.empty()) {
- if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
- retry_policy->max_backoff == 0 ||
- retry_policy->backoff_multiplier == 0 ||
- retry_policy->retryable_status_codes.Empty()) {
- *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryPolicy error:Missing required field(s)");
- return nullptr;
- }
- }
- *error = GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
- return *error == GRPC_ERROR_NONE ? std::move(retry_policy) : nullptr;
-}
-
-grpc_error* ParseRetryThrottling(
- const Json& json,
- ClientChannelGlobalParsedConfig::RetryThrottling* retry_throttling) {
- if (json.type() != Json::Type::OBJECT) {
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling error:Type should be object");
- }
- std::vector<grpc_error*> error_list;
- // Parse maxTokens.
- auto it = json.object_value().find("maxTokens");
- if (it == json.object_value().end()) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:maxTokens error:Not found"));
- } else if (it->second.type() != Json::Type::NUMBER) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:maxTokens error:Type should be "
- "number"));
- } else {
- retry_throttling->max_milli_tokens =
- gpr_parse_nonnegative_int(it->second.string_value().c_str()) * 1000;
- if (retry_throttling->max_milli_tokens <= 0) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:maxTokens error:should be "
- "greater than zero"));
- }
- }
- // Parse tokenRatio.
- it = json.object_value().find("tokenRatio");
- if (it == json.object_value().end()) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:tokenRatio error:Not found"));
- } else if (it->second.type() != Json::Type::NUMBER) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:tokenRatio error:type should be "
- "number"));
- } else {
- // We support up to 3 decimal digits.
- size_t whole_len = it->second.string_value().size();
- const char* value = it->second.string_value().c_str();
- uint32_t multiplier = 1;
- uint32_t decimal_value = 0;
- const char* decimal_point = strchr(value, '.');
- if (decimal_point != nullptr) {
- whole_len = static_cast<size_t>(decimal_point - value);
- multiplier = 1000;
- size_t decimal_len = strlen(decimal_point + 1);
- if (decimal_len > 3) decimal_len = 3;
- if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
- &decimal_value)) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:tokenRatio error:Failed "
- "parsing"));
- return GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
- }
- uint32_t decimal_multiplier = 1;
- for (size_t i = 0; i < (3 - decimal_len); ++i) {
- decimal_multiplier *= 10;
- }
- decimal_value *= decimal_multiplier;
- }
- uint32_t whole_value;
- if (!gpr_parse_bytes_to_uint32(value, whole_len, &whole_value)) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:tokenRatio error:Failed "
- "parsing"));
- return GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
- }
- retry_throttling->milli_token_ratio =
- static_cast<int>((whole_value * multiplier) + decimal_value);
- if (retry_throttling->milli_token_ratio <= 0) {
- error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "field:retryThrottling field:tokenRatio error:value should "
- "be greater than 0"));
- }
- }
- return GRPC_ERROR_CREATE_FROM_VECTOR("retryPolicy", &error_list);
-}
-
absl::optional<std::string> ParseHealthCheckConfig(const Json& field,
- grpc_error** error) {
+ grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
if (field.type() != Json::Type::OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:healthCheckConfig error:should be of type object");
return absl::nullopt;
}
- std::vector<grpc_error*> error_list;
+ std::vector<grpc_error_handle> error_list;
absl::optional<std::string> service_name;
auto it = field.object_value().find("serviceName");
if (it != field.object_value().end()) {
@@ -276,18 +89,19 @@ absl::optional<std::string> ParseHealthCheckConfig(const Json& field,
std::unique_ptr<ServiceConfigParser::ParsedConfig>
ClientChannelServiceConfigParser::ParseGlobalParams(
- const grpc_channel_args* /*args*/, const Json& json, grpc_error** error) {
+ const grpc_channel_args* /*args*/, const Json& json,
+ grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
- std::vector<grpc_error*> error_list;
+ std::vector<grpc_error_handle> error_list;
// Parse LB config.
RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
auto it = json.object_value().find("loadBalancingConfig");
if (it != json.object_value().end()) {
- grpc_error* parse_error = GRPC_ERROR_NONE;
+ grpc_error_handle parse_error = GRPC_ERROR_NONE;
parsed_lb_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
it->second, &parse_error);
if (parsed_lb_config == nullptr) {
- std::vector<grpc_error*> lb_errors;
+ std::vector<grpc_error_handle> lb_errors;
lb_errors.push_back(parse_error);
error_list.push_back(GRPC_ERROR_CREATE_FROM_VECTOR(
"field:loadBalancingConfig", &lb_errors));
@@ -319,24 +133,11 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
}
}
}
- // Parse retry throttling.
- absl::optional<ClientChannelGlobalParsedConfig::RetryThrottling>
- retry_throttling;
- it = json.object_value().find("retryThrottling");
- if (it != json.object_value().end()) {
- ClientChannelGlobalParsedConfig::RetryThrottling data;
- grpc_error* parsing_error = ParseRetryThrottling(it->second, &data);
- if (parsing_error != GRPC_ERROR_NONE) {
- error_list.push_back(parsing_error);
- } else {
- retry_throttling.emplace(data);
- }
- }
// Parse health check config.
absl::optional<std::string> health_check_service_name;
it = json.object_value().find("healthCheckConfig");
if (it != json.object_value().end()) {
- grpc_error* parsing_error = GRPC_ERROR_NONE;
+ grpc_error_handle parsing_error = GRPC_ERROR_NONE;
health_check_service_name =
ParseHealthCheckConfig(it->second, &parsing_error);
if (parsing_error != GRPC_ERROR_NONE) {
@@ -348,20 +149,19 @@ ClientChannelServiceConfigParser::ParseGlobalParams(
if (*error == GRPC_ERROR_NONE) {
return absl::make_unique<ClientChannelGlobalParsedConfig>(
std::move(parsed_lb_config), std::move(lb_policy_name),
- retry_throttling, std::move(health_check_service_name));
+ std::move(health_check_service_name));
}
return nullptr;
}
std::unique_ptr<ServiceConfigParser::ParsedConfig>
ClientChannelServiceConfigParser::ParsePerMethodParams(
- const grpc_channel_args* /*args*/, const Json& json, grpc_error** error) {
+ const grpc_channel_args* /*args*/, const Json& json,
+ grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
- std::vector<grpc_error*> error_list;
- absl::optional<bool> wait_for_ready;
- grpc_millis timeout = 0;
- std::unique_ptr<ClientChannelMethodParsedConfig::RetryPolicy> retry_policy;
+ std::vector<grpc_error_handle> error_list;
// Parse waitForReady.
+ absl::optional<bool> wait_for_ready;
auto it = json.object_value().find("waitForReady");
if (it != json.object_value().end()) {
if (it->second.type() == Json::Type::JSON_TRUE) {
@@ -374,21 +174,14 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(
}
}
// Parse timeout.
+ grpc_millis timeout = 0;
ParseJsonObjectFieldAsDuration(json.object_value(), "timeout", &timeout,
&error_list, false);
- // Parse retry policy.
- it = json.object_value().find("retryPolicy");
- if (it != json.object_value().end()) {
- grpc_error* error = GRPC_ERROR_NONE;
- retry_policy = ParseRetryPolicy(it->second, &error);
- if (retry_policy == nullptr) {
- error_list.push_back(error);
- }
- }
+ // Return result.
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list);
if (*error == GRPC_ERROR_NONE) {
- return absl::make_unique<ClientChannelMethodParsedConfig>(
- timeout, wait_for_ready, std::move(retry_policy));
+ return absl::make_unique<ClientChannelMethodParsedConfig>(timeout,
+ wait_for_ready);
}
return nullptr;
}