service config API: use absl::Status instead of grpc_error (#30321)

* service config API: use absl::Status instead of grpc_error

* Automated change: Fix sanity tests

* add missing build deps

* attempt to work around build breakage on older compilers

* trying the work-around in more spots

* more work-arounds

* more workarounds

* Automated change: Fix sanity tests

* work around another compiler problem

* Automated change: Fix sanity tests

* Automated change: Fix sanity tests

Co-authored-by: markdroth <markdroth@users.noreply.github.com>
pull/30346/head
Mark D. Roth 3 years ago committed by GitHub
parent dc0fd42d7b
commit f4edc883ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      BUILD
  2. 9
      src/core/ext/filters/client_channel/client_channel.cc
  3. 21
      src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
  4. 23
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
  5. 39
      src/core/ext/filters/client_channel/resolver_result_parsing.cc
  6. 12
      src/core/ext/filters/client_channel/resolver_result_parsing.h
  7. 39
      src/core/ext/filters/client_channel/retry_service_config.cc
  8. 12
      src/core/ext/filters/client_channel/retry_service_config.h
  9. 16
      src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc
  10. 23
      src/core/ext/filters/fault_injection/service_config_parser.cc
  11. 7
      src/core/ext/filters/fault_injection/service_config_parser.h
  12. 18
      src/core/ext/filters/message_size/message_size_filter.cc
  13. 7
      src/core/ext/filters/message_size/message_size_filter.h
  14. 22
      src/core/ext/filters/rbac/rbac_service_config_parser.cc
  15. 7
      src/core/ext/filters/rbac/rbac_service_config_parser.h
  16. 4
      src/core/ext/xds/xds_server_config_fetcher.cc
  17. 162
      src/core/lib/service_config/service_config_impl.cc
  18. 20
      src/core/lib/service_config/service_config_impl.h
  19. 49
      src/core/lib/service_config/service_config_parser.cc
  20. 28
      src/core/lib/service_config/service_config_parser.h
  21. 14
      src/cpp/common/validate_service_config.cc
  22. 166
      test/core/client_channel/rls_lb_config_parser_test.cc
  23. 855
      test/core/client_channel/service_config_test.cc
  24. 129
      test/core/ext/filters/rbac/rbac_service_config_parser_test.cc
  25. 7
      test/cpp/client/client_channel_stress_test.cc
  26. 7
      test/cpp/client/destroy_grpclb_channel_with_active_connect_stress_test.cc
  27. 5
      test/cpp/end2end/client_lb_end2end_test.cc
  28. 5
      test/cpp/end2end/grpclb_end2end_test.cc
  29. 10
      test/cpp/end2end/rls_end2end_test.cc
  30. 16
      test/cpp/end2end/service_config_end2end_test.cc

15
BUILD

@ -3093,6 +3093,8 @@ grpc_cc_library(
],
external_deps = [
"absl/memory",
"absl/status",
"absl/status:statusor",
"absl/strings",
],
language = "c++",
@ -3119,11 +3121,14 @@ grpc_cc_library(
hdrs = [
"src/core/lib/service_config/service_config_parser.h",
],
external_deps = ["absl/strings"],
external_deps = [
"absl/status",
"absl/status:statusor",
"absl/strings",
],
language = "c++",
deps = [
"channel_args",
"error",
"gpr_base",
"json",
],
@ -3543,6 +3548,8 @@ grpc_cc_library(
],
external_deps = [
"absl/memory",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/strings:str_format",
"absl/types:optional",
@ -6453,6 +6460,8 @@ grpc_cc_library(
hdrs = GRPCXX_HDRS,
external_deps = [
"absl/base:core_headers",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/synchronization",
"absl/memory",
@ -6497,6 +6506,8 @@ grpc_cc_library(
hdrs = GRPCXX_HDRS,
external_deps = [
"absl/base:core_headers",
"absl/status",
"absl/status:statusor",
"absl/strings",
"absl/synchronization",
"absl/memory",

@ -999,12 +999,13 @@ ClientChannel::ClientChannel(grpc_channel_element_args* args,
channel_args_.GetString(GRPC_ARG_SERVICE_CONFIG);
if (!service_config_json.has_value()) service_config_json = "{}";
*error = GRPC_ERROR_NONE;
default_service_config_ =
ServiceConfigImpl::Create(channel_args_, *service_config_json, error);
if (!GRPC_ERROR_IS_NONE(*error)) {
default_service_config_.reset();
auto service_config =
ServiceConfigImpl::Create(channel_args_, *service_config_json);
if (!service_config.ok()) {
*error = absl_status_to_grpc_error(service_config.status());
return;
}
default_service_config_ = std::move(*service_config);
// Get URI to resolve, using proxy mapper if needed.
absl::optional<std::string> server_uri =
channel_args_.GetOwnedString(GRPC_ARG_SERVER_URI);

@ -407,22 +407,21 @@ AresClientChannelDNSResolver::AresRequestWrapper::OnResolvedLocked(
grpc_error_handle service_config_error = GRPC_ERROR_NONE;
std::string service_config_string =
ChooseServiceConfig(service_config_json_, &service_config_error);
RefCountedPtr<ServiceConfig> service_config;
if (GRPC_ERROR_IS_NONE(service_config_error) &&
!service_config_string.empty()) {
GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s",
this, service_config_string.c_str());
service_config = ServiceConfigImpl::Create(resolver_->channel_args(),
service_config_string,
&service_config_error);
}
if (!GRPC_ERROR_IS_NONE(service_config_error)) {
result.service_config = absl::UnavailableError(
absl::StrCat("failed to parse service config: ",
grpc_error_std_string(service_config_error)));
GRPC_ERROR_UNREF(service_config_error);
} else {
result.service_config = std::move(service_config);
} else if (!service_config_string.empty()) {
GRPC_CARES_TRACE_LOG("resolver:%p selected service config choice: %s",
this, service_config_string.c_str());
result.service_config = ServiceConfigImpl::Create(
resolver_->channel_args(), service_config_string);
if (!result.service_config.ok()) {
result.service_config = absl::UnavailableError(
absl::StrCat("failed to parse service config: ",
result.service_config.status().message()));
}
}
}
if (balancer_addresses_ != nullptr) {

@ -616,8 +616,13 @@ grpc_error_handle XdsResolver::XdsConfigSelector::CreateMethodConfig(
absl::StrJoin(fields, ",\n"),
"\n } ]\n"
"}");
*method_config =
ServiceConfigImpl::Create(result.args, json.c_str(), &error);
auto method_config_or =
ServiceConfigImpl::Create(result.args, json.c_str());
if (!method_config_or.ok()) {
error = absl_status_to_grpc_error(method_config_or.status());
} else {
*method_config = std::move(*method_config_or);
}
}
return error;
}
@ -993,9 +998,8 @@ void XdsResolver::OnResourceDoesNotExist(std::string context) {
current_virtual_host_.routes.clear();
Result result;
result.addresses.emplace();
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = ServiceConfigImpl::Create(args_, "{}", &error);
GPR_ASSERT(*result.service_config != nullptr);
result.service_config = ServiceConfigImpl::Create(args_, "{}");
GPR_ASSERT(result.service_config.ok());
result.resolution_note = std::move(context);
result.args = args_;
result_handler_->ReportResult(std::move(result));
@ -1039,14 +1043,7 @@ XdsResolver::CreateServiceConfig() {
" ]\n"
"}");
std::string json = absl::StrJoin(config_parts, "");
grpc_error_handle error = GRPC_ERROR_NONE;
absl::StatusOr<RefCountedPtr<ServiceConfig>> result =
ServiceConfigImpl::Create(args_, json.c_str(), &error);
if (!GRPC_ERROR_IS_NONE(error)) {
result = grpc_error_to_absl_status(error);
GRPC_ERROR_UNREF(error);
}
return result;
return ServiceConfigImpl::Create(args_, json.c_str());
}
void XdsResolver::GenerateResult() {

@ -33,6 +33,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json_util.h"
// As per the retry design, we do not allow more than 5 retry attempts.
@ -80,11 +81,9 @@ absl::optional<std::string> ParseHealthCheckConfig(const Json& field,
} // namespace
std::unique_ptr<ServiceConfigParser::ParsedConfig>
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ClientChannelServiceConfigParser::ParseGlobalParams(const ChannelArgs& /*args*/,
const Json& json,
grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
const Json& json) {
std::vector<grpc_error_handle> error_list;
// Parse LB config.
RefCountedPtr<LoadBalancingPolicy::Config> parsed_lb_config;
@ -135,20 +134,23 @@ ClientChannelServiceConfigParser::ParseGlobalParams(const ChannelArgs& /*args*/,
error_list.push_back(parsing_error);
}
}
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel global parser",
&error_list);
if (GRPC_ERROR_IS_NONE(*error)) {
if (!error_list.empty()) {
grpc_error_handle error = GRPC_ERROR_CREATE_FROM_VECTOR(
"Client channel global parser", &error_list);
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing client channel global parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
return absl::make_unique<ClientChannelGlobalParsedConfig>(
std::move(parsed_lb_config), std::move(lb_policy_name),
std::move(health_check_service_name));
}
return nullptr;
}
std::unique_ptr<ServiceConfigParser::ParsedConfig>
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ClientChannelServiceConfigParser::ParsePerMethodParams(
const ChannelArgs& /*args*/, const Json& json, grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
const ChannelArgs& /*args*/, const Json& json) {
std::vector<grpc_error_handle> error_list;
// Parse waitForReady.
absl::optional<bool> wait_for_ready;
@ -168,12 +170,17 @@ ClientChannelServiceConfigParser::ParsePerMethodParams(
ParseJsonObjectFieldAsDuration(json.object_value(), "timeout", &timeout,
&error_list, false);
// Return result.
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list);
if (GRPC_ERROR_IS_NONE(*error)) {
if (!error_list.empty()) {
grpc_error_handle error =
GRPC_ERROR_CREATE_FROM_VECTOR("Client channel parser", &error_list);
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing client channel method parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
return absl::make_unique<ClientChannelMethodParsedConfig>(timeout,
wait_for_ready);
}
return nullptr;
}
} // namespace internal

@ -25,6 +25,7 @@
#include <string>
#include <utility>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
@ -33,7 +34,6 @@
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/service_config/service_config_parser.h"
@ -89,13 +89,11 @@ class ClientChannelServiceConfigParser : public ServiceConfigParser::Parser {
public:
absl::string_view name() const override { return parser_name(); }
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParseGlobalParams(
const ChannelArgs& /*args*/, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParseGlobalParams(const ChannelArgs& /*args*/, const Json& json) override;
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
const ChannelArgs& /*args*/, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParsePerMethodParams(const ChannelArgs& /*args*/, const Json& json) override;
static size_t ParserIndex();
static void Register(CoreConfiguration::Builder* builder);

@ -28,6 +28,8 @@
#include <vector>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include <grpc/impl/codegen/grpc_types.h>
@ -38,6 +40,7 @@
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json_util.h"
// As per the retry design, we do not allow more than 5 retry attempts.
@ -138,18 +141,22 @@ grpc_error_handle ParseRetryThrottling(const Json& json,
} // namespace
std::unique_ptr<ServiceConfigParser::ParsedConfig>
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
RetryServiceConfigParser::ParseGlobalParams(const ChannelArgs& /*args*/,
const Json& json,
grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
const Json& json) {
auto it = json.object_value().find("retryThrottling");
if (it == json.object_value().end()) return nullptr;
intptr_t max_milli_tokens = 0;
intptr_t milli_token_ratio = 0;
*error =
grpc_error_handle error =
ParseRetryThrottling(it->second, &max_milli_tokens, &milli_token_ratio);
if (!GRPC_ERROR_IS_NONE(*error)) return nullptr;
if (!GRPC_ERROR_IS_NONE(error)) {
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing retry global parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
return absl::make_unique<RetryGlobalConfig>(max_milli_tokens,
milli_token_ratio);
}
@ -286,11 +293,9 @@ grpc_error_handle ParseRetryPolicy(
} // namespace
std::unique_ptr<ServiceConfigParser::ParsedConfig>
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
RetryServiceConfigParser::ParsePerMethodParams(const ChannelArgs& args,
const Json& json,
grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
const Json& json) {
// Parse retry policy.
auto it = json.object_value().find("retryPolicy");
if (it == json.object_value().end()) return nullptr;
@ -300,10 +305,16 @@ RetryServiceConfigParser::ParsePerMethodParams(const ChannelArgs& args,
float backoff_multiplier = 0;
StatusCodeSet retryable_status_codes;
absl::optional<Duration> per_attempt_recv_timeout;
*error = ParseRetryPolicy(args, it->second, &max_attempts, &initial_backoff,
&max_backoff, &backoff_multiplier,
&retryable_status_codes, &per_attempt_recv_timeout);
if (!GRPC_ERROR_IS_NONE(*error)) return nullptr;
grpc_error_handle error = ParseRetryPolicy(
args, it->second, &max_attempts, &initial_backoff, &max_backoff,
&backoff_multiplier, &retryable_status_codes, &per_attempt_recv_timeout);
if (!GRPC_ERROR_IS_NONE(error)) {
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing retry method parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
return absl::make_unique<RetryMethodConfig>(
max_attempts, initial_backoff, max_backoff, backoff_multiplier,
retryable_status_codes, per_attempt_recv_timeout);

@ -24,6 +24,7 @@
#include <memory>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
@ -31,7 +32,6 @@
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/service_config/service_config_parser.h"
@ -89,13 +89,11 @@ class RetryServiceConfigParser : public ServiceConfigParser::Parser {
public:
absl::string_view name() const override { return parser_name(); }
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParseGlobalParams(
const ChannelArgs& /*args*/, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParseGlobalParams(const ChannelArgs& /*args*/, const Json& json) override;
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
const ChannelArgs& args, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParsePerMethodParams(const ChannelArgs& args, const Json& json) override;
static size_t ParserIndex();
static void Register(CoreConfiguration::Builder* builder);

@ -23,6 +23,8 @@
#include <string>
#include <utility>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/types/optional.h"
#include <grpc/impl/codegen/grpc_types.h>
@ -55,17 +57,13 @@ class ServiceConfigChannelArgChannelData {
const char* service_config_str = grpc_channel_args_find_string(
args->channel_args, GRPC_ARG_SERVICE_CONFIG);
if (service_config_str != nullptr) {
grpc_error_handle service_config_error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs::FromC(args->channel_args),
service_config_str, &service_config_error);
if (GRPC_ERROR_IS_NONE(service_config_error)) {
service_config_ = std::move(service_config);
auto service_config = ServiceConfigImpl::Create(
ChannelArgs::FromC(args->channel_args), service_config_str);
if (!service_config.ok()) {
gpr_log(GPR_ERROR, "%s", service_config.status().ToString().c_str());
} else {
gpr_log(GPR_ERROR, "%s",
grpc_error_std_string(service_config_error).c_str());
service_config_ = std::move(*service_config);
}
GRPC_ERROR_UNREF(service_config_error);
}
}

@ -22,14 +22,14 @@
#include <vector>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/types/optional.h"
#include <grpc/support/log.h>
#include "src/core/ext/filters/fault_injection/fault_injection_filter.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json_util.h"
namespace grpc_core {
@ -141,10 +141,9 @@ ParseFaultInjectionPolicy(const Json::Array& policies_json_array,
} // namespace
std::unique_ptr<ServiceConfigParser::ParsedConfig>
FaultInjectionServiceConfigParser::ParsePerMethodParams(
const ChannelArgs& args, const Json& json, grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
FaultInjectionServiceConfigParser::ParsePerMethodParams(const ChannelArgs& args,
const Json& json) {
// Only parse fault injection policy if the following channel arg is present.
if (!args.GetBool(GRPC_ARG_PARSE_FAULT_INJECTION_METHOD_CONFIG)
.value_or(false)) {
@ -160,10 +159,16 @@ FaultInjectionServiceConfigParser::ParsePerMethodParams(
fault_injection_policies =
ParseFaultInjectionPolicy(*policies_json_array, &error_list);
}
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Fault injection parser", &error_list);
if (!GRPC_ERROR_IS_NONE(*error) || fault_injection_policies.empty()) {
return nullptr;
if (!error_list.empty()) {
grpc_error_handle error =
GRPC_ERROR_CREATE_FROM_VECTOR("Fault injection parser", &error_list);
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing fault injection method parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
if (fault_injection_policies.empty()) return nullptr;
return absl::make_unique<FaultInjectionMethodParsedConfig>(
std::move(fault_injection_policies));
}

@ -28,6 +28,7 @@
#include <utility>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include <grpc/status.h>
@ -35,7 +36,6 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/service_config/service_config_parser.h"
@ -88,9 +88,8 @@ class FaultInjectionServiceConfigParser final
public:
absl::string_view name() const override { return parser_name(); }
// Parses the per-method service config for fault injection filter.
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
const ChannelArgs& args, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParsePerMethodParams(const ChannelArgs& args, const Json& json) override;
// Returns the parser index for FaultInjectionServiceConfigParser.
static size_t ParserIndex();
// Registers FaultInjectionServiceConfigParser to ServiceConfigParser.

@ -26,6 +26,8 @@
#include <vector>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/types/optional.h"
@ -41,6 +43,7 @@
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/iomgr/call_combiner.h"
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/service_config/service_config_call_data.h"
#include "src/core/lib/slice/slice_buffer.h"
#include "src/core/lib/surface/channel_init.h"
@ -72,11 +75,9 @@ const MessageSizeParsedConfig* MessageSizeParsedConfig::GetFromCallContext(
// MessageSizeParser
//
std::unique_ptr<ServiceConfigParser::ParsedConfig>
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
MessageSizeParser::ParsePerMethodParams(const ChannelArgs& /*args*/,
const Json& json,
grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
const Json& json) {
std::vector<grpc_error_handle> error_list;
// Max request size.
int max_request_message_bytes = -1;
@ -113,8 +114,13 @@ MessageSizeParser::ParsePerMethodParams(const ChannelArgs& /*args*/,
}
}
if (!error_list.empty()) {
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list);
return nullptr;
grpc_error_handle error =
GRPC_ERROR_CREATE_FROM_VECTOR("Message size parser", &error_list);
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing message size method parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
return absl::make_unique<MessageSizeParsedConfig>(max_request_message_bytes,
max_response_message_bytes);

@ -23,6 +23,7 @@
#include <memory>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "src/core/lib/channel/channel_args.h"
@ -30,7 +31,6 @@
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/context.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/service_config/service_config_parser.h"
@ -64,9 +64,8 @@ class MessageSizeParser : public ServiceConfigParser::Parser {
public:
absl::string_view name() const override { return parser_name(); }
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
const ChannelArgs& /*args*/, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParsePerMethodParams(const ChannelArgs& /*args*/, const Json& json) override;
static void Register(CoreConfiguration::Builder* builder);

@ -26,12 +26,12 @@
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/types/optional.h"
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json_util.h"
#include "src/core/lib/matchers/matchers.h"
#include "src/core/lib/transport/error_utils.h"
@ -581,11 +581,9 @@ std::vector<Rbac> ParseRbacArray(const Json::Array& policies_json_array,
} // namespace
std::unique_ptr<ServiceConfigParser::ParsedConfig>
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
RbacServiceConfigParser::ParsePerMethodParams(const ChannelArgs& args,
const Json& json,
grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr && GRPC_ERROR_IS_NONE(*error));
const Json& json) {
// Only parse rbac policy if the channel arg is present
if (!args.GetBool(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG).value_or(false)) {
return nullptr;
@ -597,10 +595,16 @@ RbacServiceConfigParser::ParsePerMethodParams(const ChannelArgs& args,
&policies_json_array, &error_list)) {
rbac_policies = ParseRbacArray(*policies_json_array, &error_list);
}
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Rbac parser", &error_list);
if (!GRPC_ERROR_IS_NONE(*error) || rbac_policies.empty()) {
return nullptr;
grpc_error_handle error =
GRPC_ERROR_CREATE_FROM_VECTOR("Rbac parser", &error_list);
if (!GRPC_ERROR_IS_NONE(error)) {
absl::Status status = absl::InvalidArgumentError(
absl::StrCat("error parsing RBAC method parameters: ",
grpc_error_std_string(error)));
GRPC_ERROR_UNREF(error);
return status;
}
if (rbac_policies.empty()) return nullptr;
return absl::make_unique<RbacMethodParsedConfig>(std::move(rbac_policies));
}

@ -26,11 +26,11 @@
#include <utility>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/authorization/grpc_authorization_engine.h"
#include "src/core/lib/security/authorization/rbac_policy.h"
@ -69,9 +69,8 @@ class RbacServiceConfigParser : public ServiceConfigParser::Parser {
public:
absl::string_view name() const override { return parser_name(); }
// Parses the per-method service config for rbac filter.
std::unique_ptr<ServiceConfigParser::ParsedConfig> ParsePerMethodParams(
const ChannelArgs& args, const Json& json,
grpc_error_handle* error) override;
absl::StatusOr<std::unique_ptr<ServiceConfigParser::ParsedConfig>>
ParsePerMethodParams(const ChannelArgs& args, const Json& json) override;
// Returns the parser index for RbacServiceConfigParser.
static size_t ParserIndex();
// Registers RbacServiceConfigParser to ServiceConfigParser.

@ -1169,10 +1169,8 @@ XdsServerConfigFetcher::ListenerWatcher::FilterChainMatchManager::
absl::StrJoin(fields, ",\n"),
"\n } ]\n"
"}");
grpc_error_handle error = GRPC_ERROR_NONE;
config_selector_route.method_config =
ServiceConfigImpl::Create(result.args, json.c_str(), &error);
GPR_ASSERT(GRPC_ERROR_IS_NONE(error));
ServiceConfigImpl::Create(result.args, json.c_str()).value();
}
}
}

@ -26,11 +26,13 @@
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include <grpc/support/log.h>
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/service_config/service_config_parser.h"
#include "src/core/lib/slice/slice_internal.h"
@ -38,37 +40,46 @@
namespace grpc_core {
RefCountedPtr<ServiceConfig> ServiceConfigImpl::Create(
const ChannelArgs& args, absl::string_view json_string,
grpc_error_handle* error) {
GPR_DEBUG_ASSERT(error != nullptr);
Json json = Json::Parse(json_string, error);
if (!GRPC_ERROR_IS_NONE(*error)) return nullptr;
return MakeRefCounted<ServiceConfigImpl>(args, std::string(json_string),
std::move(json), error);
absl::StatusOr<RefCountedPtr<ServiceConfig>> ServiceConfigImpl::Create(
const ChannelArgs& args, absl::string_view json_string) {
grpc_error_handle error = GRPC_ERROR_NONE;
Json json = Json::Parse(json_string, &error);
if (!GRPC_ERROR_IS_NONE(error)) {
absl::Status status =
absl::InvalidArgumentError(grpc_error_std_string(error));
GRPC_ERROR_UNREF(error);
return status;
}
absl::Status status;
auto service_config = MakeRefCounted<ServiceConfigImpl>(
args, std::string(json_string), std::move(json), &status);
if (!status.ok()) return status;
return service_config;
}
ServiceConfigImpl::ServiceConfigImpl(const ChannelArgs& args,
std::string json_string, Json json,
grpc_error_handle* error)
absl::Status* status)
: json_string_(std::move(json_string)), json_(std::move(json)) {
GPR_DEBUG_ASSERT(error != nullptr);
GPR_DEBUG_ASSERT(status != nullptr);
if (json_.type() != Json::Type::OBJECT) {
*error =
GRPC_ERROR_CREATE_FROM_STATIC_STRING("JSON value is not an object");
*status = absl::InvalidArgumentError("JSON value is not an object");
return;
}
std::vector<grpc_error_handle> error_list;
grpc_error_handle global_error = GRPC_ERROR_NONE;
parsed_global_configs_ =
std::vector<std::string> errors;
auto parsed_global_configs =
CoreConfiguration::Get().service_config_parser().ParseGlobalParameters(
args, json_, &global_error);
if (!GRPC_ERROR_IS_NONE(global_error)) error_list.push_back(global_error);
grpc_error_handle local_error = ParsePerMethodParams(args);
if (!GRPC_ERROR_IS_NONE(local_error)) error_list.push_back(local_error);
if (!error_list.empty()) {
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Service config parsing error",
&error_list);
args, json_);
if (!parsed_global_configs.ok()) {
errors.emplace_back(parsed_global_configs.status().message());
} else {
parsed_global_configs_ = std::move(*parsed_global_configs);
}
absl::Status local_status = ParsePerMethodParams(args);
if (!local_status.ok()) errors.emplace_back(local_status.message());
if (!errors.empty()) {
*status = absl::InvalidArgumentError(absl::StrCat(
"Service config parsing errors: [", absl::StrJoin(errors, "; "), "]"));
}
}
@ -78,52 +89,50 @@ ServiceConfigImpl::~ServiceConfigImpl() {
}
}
grpc_error_handle ServiceConfigImpl::ParseJsonMethodConfig(
const ChannelArgs& args, const Json& json) {
std::vector<grpc_error_handle> error_list;
absl::Status ServiceConfigImpl::ParseJsonMethodConfig(const ChannelArgs& args,
const Json& json,
size_t index) {
std::vector<std::string> errors;
const ServiceConfigParser::ParsedConfigVector* vector_ptr = nullptr;
// Parse method config with each registered parser.
auto parsed_configs =
absl::make_unique<ServiceConfigParser::ParsedConfigVector>();
grpc_error_handle parser_error = GRPC_ERROR_NONE;
*parsed_configs =
auto parsed_configs_or =
CoreConfiguration::Get().service_config_parser().ParsePerMethodParameters(
args, json, &parser_error);
if (!GRPC_ERROR_IS_NONE(parser_error)) {
error_list.push_back(parser_error);
}
args, json);
if (!parsed_configs_or.ok()) {
errors.emplace_back(parsed_configs_or.status().message());
} else {
auto parsed_configs =
absl::make_unique<ServiceConfigParser::ParsedConfigVector>(
std::move(*parsed_configs_or));
parsed_method_config_vectors_storage_.push_back(std::move(parsed_configs));
const auto* vector_ptr = parsed_method_config_vectors_storage_.back().get();
vector_ptr = parsed_method_config_vectors_storage_.back().get();
}
// Add an entry for each path.
bool found_name = false;
auto it = json.object_value().find("name");
if (it != json.object_value().end()) {
if (it->second.type() != Json::Type::ARRAY) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:name error:not of type Array"));
return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
}
errors.emplace_back("field:name error:not of type Array");
} else {
const Json::Array& name_array = it->second.array_value();
for (const Json& name : name_array) {
grpc_error_handle parse_error = GRPC_ERROR_NONE;
std::string path = ParseJsonMethodName(name, &parse_error);
if (!GRPC_ERROR_IS_NONE(parse_error)) {
error_list.push_back(parse_error);
absl::StatusOr<std::string> path = ParseJsonMethodName(name);
if (!path.ok()) {
errors.emplace_back(path.status().message());
} else {
found_name = true;
if (path.empty()) {
if (path->empty()) {
if (default_method_config_vector_ != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:name error:multiple default method configs"));
errors.emplace_back(
"field:name error:multiple default method configs");
}
default_method_config_vector_ = vector_ptr;
} else {
grpc_slice key = grpc_slice_from_copied_string(path.c_str());
grpc_slice key = grpc_slice_from_cpp_string(std::move(*path));
// If the key is not already present in the map, this will
// store a ref to the key in the map.
auto& value = parsed_method_configs_map_[key];
if (value != nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:name error:multiple method configs with same name"));
errors.emplace_back(
"field:name error:multiple method configs with same name");
// The map entry already existed, so we need to unref the
// key we just created.
grpc_slice_unref_internal(key);
@ -134,42 +143,41 @@ grpc_error_handle ServiceConfigImpl::ParseJsonMethodConfig(
}
}
}
if (!found_name) {
parsed_method_config_vectors_storage_.pop_back();
}
return GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
if (!errors.empty()) {
return absl::InvalidArgumentError(
absl::StrCat("index ", index, ": [", absl::StrJoin(errors, "; "), "]"));
}
return absl::OkStatus();
}
grpc_error_handle ServiceConfigImpl::ParsePerMethodParams(
const ChannelArgs& args) {
std::vector<grpc_error_handle> error_list;
absl::Status ServiceConfigImpl::ParsePerMethodParams(const ChannelArgs& args) {
auto it = json_.object_value().find("methodConfig");
if (it != json_.object_value().end()) {
if (it == json_.object_value().end()) return absl::OkStatus();
if (it->second.type() != Json::Type::ARRAY) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:methodConfig error:not of type Array"));
return absl::InvalidArgumentError("field must be of type array");
}
for (const Json& method_config : it->second.array_value()) {
std::vector<std::string> errors;
for (size_t i = 0; i < it->second.array_value().size(); ++i) {
const Json& method_config = it->second.array_value()[i];
if (method_config.type() != Json::Type::OBJECT) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:methodConfig error:not of type Object"));
continue;
}
grpc_error_handle error = ParseJsonMethodConfig(args, method_config);
if (!GRPC_ERROR_IS_NONE(error)) {
error_list.push_back(error);
errors.emplace_back(absl::StrCat("index ", i, ": not of type Object"));
} else {
absl::Status status = ParseJsonMethodConfig(args, method_config, i);
if (!status.ok()) errors.emplace_back(status.message());
}
}
if (!errors.empty()) {
return absl::InvalidArgumentError(absl::StrCat(
"errors parsing methodConfig: [", absl::StrJoin(errors, "; "), "]"));
}
return GRPC_ERROR_CREATE_FROM_VECTOR("Method Params", &error_list);
return absl::OkStatus();
}
std::string ServiceConfigImpl::ParseJsonMethodName(const Json& json,
grpc_error_handle* error) {
absl::StatusOr<std::string> ServiceConfigImpl::ParseJsonMethodName(
const Json& json) {
if (json.type() != Json::Type::OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"field:name error:type is not object");
return "";
return absl::InvalidArgumentError("field:name error:type is not object");
}
// Find service name.
const std::string* service_name = nullptr;
@ -177,9 +185,8 @@ std::string ServiceConfigImpl::ParseJsonMethodName(const Json& json,
if (it != json.object_value().end() &&
it->second.type() != Json::Type::JSON_NULL) {
if (it->second.type() != Json::Type::STRING) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
return absl::InvalidArgumentError(
"field:name error: field:service error:not of type string");
return "";
}
if (!it->second.string_value().empty()) {
service_name = &it->second.string_value();
@ -191,9 +198,8 @@ std::string ServiceConfigImpl::ParseJsonMethodName(const Json& json,
if (it != json.object_value().end() &&
it->second.type() != Json::Type::JSON_NULL) {
if (it->second.type() != Json::Type::STRING) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
return absl::InvalidArgumentError(
"field:name error: field:method error:not of type string");
return "";
}
if (!it->second.string_value().empty()) {
method_name = &it->second.string_value();
@ -203,7 +209,7 @@ std::string ServiceConfigImpl::ParseJsonMethodName(const Json& json,
// Method name may not be specified without service name.
if (service_name == nullptr) {
if (method_name != nullptr) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
return absl::InvalidArgumentError(
"field:name error:method name populated without service name");
}
return "";

@ -26,6 +26,8 @@
#include <unordered_map>
#include <vector>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include <grpc/slice.h>
@ -33,7 +35,6 @@
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/service_config/service_config.h"
#include "src/core/lib/service_config/service_config_parser.h"
@ -68,13 +69,11 @@ namespace grpc_core {
class ServiceConfigImpl final : public ServiceConfig {
public:
/// Creates a new service config from parsing \a json_string.
/// Returns null on parse error.
static RefCountedPtr<ServiceConfig> Create(const ChannelArgs& args,
absl::string_view json_string,
grpc_error_handle* error);
static absl::StatusOr<RefCountedPtr<ServiceConfig>> Create(
const ChannelArgs& args, absl::string_view json_string);
ServiceConfigImpl(const ChannelArgs& args, std::string json_string, Json json,
grpc_error_handle* error);
absl::Status* status);
~ServiceConfigImpl() override;
absl::string_view json_string() const override { return json_string_; }
@ -96,14 +95,13 @@ class ServiceConfigImpl final : public ServiceConfig {
private:
// Helper functions for parsing the method configs.
grpc_error_handle ParsePerMethodParams(const ChannelArgs& args);
grpc_error_handle ParseJsonMethodConfig(const ChannelArgs& args,
const Json& json);
absl::Status ParsePerMethodParams(const ChannelArgs& args);
absl::Status ParseJsonMethodConfig(const ChannelArgs& args, const Json& json,
size_t index);
// Returns a path string for the JSON name object specified by json.
// Sets *error on error.
static std::string ParseJsonMethodName(const Json& json,
grpc_error_handle* error);
static absl::StatusOr<std::string> ParseJsonMethodName(const Json& json);
std::string json_string_;
Json json_;

@ -22,7 +22,9 @@
#include <string>
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_join.h"
#include <grpc/support/log.h>
@ -47,46 +49,43 @@ void ServiceConfigParser::Builder::RegisterParser(
registered_parsers_.emplace_back(std::move(parser));
}
ServiceConfigParser::ParsedConfigVector
absl::StatusOr<ServiceConfigParser::ParsedConfigVector>
ServiceConfigParser::ParseGlobalParameters(const ChannelArgs& args,
const Json& json,
grpc_error_handle* error) const {
const Json& json) const {
ParsedConfigVector parsed_global_configs;
std::vector<grpc_error_handle> error_list;
std::vector<std::string> errors;
for (size_t i = 0; i < registered_parsers_.size(); i++) {
grpc_error_handle parser_error = GRPC_ERROR_NONE;
auto parsed_config =
registered_parsers_[i]->ParseGlobalParams(args, json, &parser_error);
if (!GRPC_ERROR_IS_NONE(parser_error)) {
error_list.push_back(parser_error);
auto parsed_config = registered_parsers_[i]->ParseGlobalParams(args, json);
if (!parsed_config.ok()) {
errors.emplace_back(parsed_config.status().message());
} else {
parsed_global_configs.push_back(std::move(*parsed_config));
}
parsed_global_configs.push_back(std::move(parsed_config));
}
if (!error_list.empty()) {
*error = GRPC_ERROR_CREATE_FROM_VECTOR("Global Params", &error_list);
if (!errors.empty()) {
return absl::InvalidArgumentError(absl::StrJoin(errors, "; "));
}
return parsed_global_configs;
return std::move(parsed_global_configs);
}
ServiceConfigParser::ParsedConfigVector
absl::StatusOr<ServiceConfigParser::ParsedConfigVector>
ServiceConfigParser::ParsePerMethodParameters(const ChannelArgs& args,
const Json& json,
grpc_error_handle* error) const {
const Json& json) const {
ParsedConfigVector parsed_method_configs;
std::vector<grpc_error_handle> error_list;
std::vector<std::string> errors;
for (size_t i = 0; i < registered_parsers_.size(); ++i) {
grpc_error_handle parser_error = GRPC_ERROR_NONE;
auto parsed_config =
registered_parsers_[i]->ParsePerMethodParams(args, json, &parser_error);
if (!GRPC_ERROR_IS_NONE(parser_error)) {
error_list.push_back(parser_error);
registered_parsers_[i]->ParsePerMethodParams(args, json);
if (!parsed_config.ok()) {
errors.emplace_back(parsed_config.status().message());
} else {
parsed_method_configs.push_back(std::move(*parsed_config));
}
parsed_method_configs.push_back(std::move(parsed_config));
}
if (!error_list.empty()) {
*error = GRPC_ERROR_CREATE_FROM_VECTOR("methodConfig", &error_list);
if (!errors.empty()) {
return absl::InvalidArgumentError(absl::StrJoin(errors, "; "));
}
return parsed_method_configs;
return std::move(parsed_method_configs);
}
size_t ServiceConfigParser::GetParserIndex(absl::string_view name) const {

@ -26,12 +26,10 @@
#include <utility>
#include <vector>
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
namespace grpc_core {
@ -54,19 +52,13 @@ class ServiceConfigParser {
virtual absl::string_view name() const = 0;
virtual std::unique_ptr<ParsedConfig> ParseGlobalParams(
const ChannelArgs&, const Json& /* json */, grpc_error_handle* error) {
// Avoid unused parameter warning on debug-only parameter
(void)error;
GPR_DEBUG_ASSERT(error != nullptr);
virtual absl::StatusOr<std::unique_ptr<ParsedConfig>> ParseGlobalParams(
const ChannelArgs& /*args*/, const Json& /*json*/) {
return nullptr;
}
virtual std::unique_ptr<ParsedConfig> ParsePerMethodParams(
const ChannelArgs&, const Json& /* json */, grpc_error_handle* error) {
// Avoid unused parameter warning on debug-only parameter
(void)error;
GPR_DEBUG_ASSERT(error != nullptr);
virtual absl::StatusOr<std::unique_ptr<ParsedConfig>> ParsePerMethodParams(
const ChannelArgs& /*args*/, const Json& /*json*/) {
return nullptr;
}
};
@ -88,13 +80,11 @@ class ServiceConfigParser {
ServiceConfigParserList registered_parsers_;
};
ParsedConfigVector ParseGlobalParameters(const ChannelArgs& args,
const Json& json,
grpc_error_handle* error) const;
absl::StatusOr<ParsedConfigVector> ParseGlobalParameters(
const ChannelArgs& args, const Json& json) const;
ParsedConfigVector ParsePerMethodParameters(const ChannelArgs& args,
const Json& json,
grpc_error_handle* error) const;
absl::StatusOr<ParsedConfigVector> ParsePerMethodParameters(
const ChannelArgs& args, const Json& json) const;
// Return the index for a given registered parser.
// If there is an error, return -1.

@ -18,26 +18,24 @@
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include <grpc/grpc.h>
#include <grpcpp/support/config.h>
#include <grpcpp/support/validate_service_config.h>
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/service_config/service_config_impl.h"
namespace grpc {
namespace experimental {
std::string ValidateServiceConfigJSON(const std::string& service_config_json) {
grpc_init();
grpc_error_handle error = GRPC_ERROR_NONE;
grpc_core::ServiceConfigImpl::Create(grpc_core::ChannelArgs(),
service_config_json.c_str(), &error);
auto service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), service_config_json.c_str());
std::string return_value;
if (!GRPC_ERROR_IS_NONE(error)) {
return_value = grpc_error_std_string(error);
GRPC_ERROR_UNREF(error);
}
if (!service_config.ok()) return_value = service_config.status().ToString();
grpc_shutdown();
return return_value;
}

@ -63,11 +63,10 @@ TEST_F(RlsConfigParsingTest, ValidConfig) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
EXPECT_NE(service_config, nullptr);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
EXPECT_NE(*service_config, nullptr);
}
//
@ -82,17 +81,17 @@ TEST_F(RlsConfigParsingTest, TopLevelRequiredFieldsMissing) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig error:does not exist.*"
"field:childPolicyConfigTargetFieldName error:does not exist.*"
"field:childPolicy error:does not exist"));
GRPC_ERROR_UNREF(error);
"field:childPolicy error:does not exist"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, TopLevelFieldsWrongTypes) {
@ -107,18 +106,18 @@ TEST_F(RlsConfigParsingTest, TopLevelFieldsWrongTypes) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig error:type should be OBJECT.*"
"field:routeLookupChannelServiceConfig error:type should be OBJECT.*"
"field:childPolicyConfigTargetFieldName error:type should be STRING.*"
"field:childPolicy error:type should be ARRAY"));
GRPC_ERROR_UNREF(error);
"field:childPolicy error:type should be ARRAY"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, TopLevelFieldsInvalidValues) {
@ -133,17 +132,17 @@ TEST_F(RlsConfigParsingTest, TopLevelFieldsInvalidValues) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:childPolicyConfigTargetFieldName error:must be non-empty.*"
"field:childPolicy" CHILD_ERROR_TAG
"No known policies in list: unknown"));
GRPC_ERROR_UNREF(error);
"No known policies in list: unknown"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, InvalidChildPolicyConfig) {
@ -158,16 +157,16 @@ TEST_F(RlsConfigParsingTest, InvalidChildPolicyConfig) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:childPolicy" CHILD_ERROR_TAG
"errors parsing grpclb LB policy config: \\["
"error parsing childPolicy field: type should be array\\]"));
GRPC_ERROR_UNREF(error);
"error parsing childPolicy field: type should be array\\]"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, InvalidRlsChannelServiceConfig) {
@ -185,18 +184,18 @@ TEST_F(RlsConfigParsingTest, InvalidRlsChannelServiceConfig) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupChannelServiceConfig" CHILD_ERROR_TAG
"Service config parsing error" CHILD_ERROR_TAG
"Global Params" CHILD_ERROR_TAG
"Client channel global parser" CHILD_ERROR_TAG
"field:loadBalancingPolicy error:Unknown lb policy"));
GRPC_ERROR_UNREF(error);
"Service config parsing errors: \\["
"error parsing client channel global parameters" CHILD_ERROR_TAG
"field:loadBalancingPolicy error:Unknown lb policy"))
<< service_config.status();
}
//
@ -213,16 +212,16 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigRequiredFieldsMissing) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
"field:grpcKeybuilders error:does not exist.*"
"field:lookupService error:does not exist"));
GRPC_ERROR_UNREF(error);
"field:lookupService error:does not exist"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
@ -243,10 +242,10 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
@ -255,8 +254,8 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsWrongTypes) {
"field:maxAge error:type should be STRING.*"
"field:staleAge error:type should be STRING.*"
"field:cacheSizeBytes error:failed to parse.*"
"field:defaultTarget error:type should be STRING"));
GRPC_ERROR_UNREF(error);
"field:defaultTarget error:type should be STRING"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsInvalidValues) {
@ -271,16 +270,16 @@ TEST_F(RlsConfigParsingTest, RouteLookupConfigFieldsInvalidValues) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
"field:lookupService error:must be valid gRPC target URI.*"
"field:cacheSizeBytes error:must be greater than 0"));
GRPC_ERROR_UNREF(error);
"field:cacheSizeBytes error:must be greater than 0"))
<< service_config.status();
}
//
@ -301,17 +300,16 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderRequiredFieldsMissing) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(
grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
"field:names error:does not exist"));
GRPC_ERROR_UNREF(error);
"field:grpcKeybuilders" CHILD_ERROR_TAG
"index:0" CHILD_ERROR_TAG "field:names error:does not exist"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) {
@ -332,11 +330,11 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
@ -344,8 +342,8 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderWrongFieldTypes) {
"field:names error:type should be ARRAY.*"
"field:headers error:type should be ARRAY.*"
"field:extraKeys error:type should be OBJECT.*"
"field:constantKeys error:type should be OBJECT"));
GRPC_ERROR_UNREF(error);
"field:constantKeys error:type should be OBJECT"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) {
@ -371,10 +369,10 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
EXPECT_THAT(grpc_error_std_string(error),
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
@ -385,8 +383,8 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidValues) {
"field:service error:type should be STRING.*"
"field:method error:type should be STRING.*"
"field:constantKeys" CHILD_ERROR_TAG
"field:key error:type should be STRING"));
GRPC_ERROR_UNREF(error);
"field:key error:type should be STRING"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) {
@ -423,11 +421,11 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
@ -445,8 +443,8 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderInvalidHeaders) {
"field:names index:1 error:header name must be non-empty.*"
"field:extraKeys" CHILD_ERROR_TAG
"field:host error:must be non-empty.*"
"field:constantKeys" CHILD_ERROR_TAG "error:keys must be non-empty"));
GRPC_ERROR_UNREF(error);
"field:constantKeys" CHILD_ERROR_TAG "error:keys must be non-empty"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) {
@ -470,11 +468,11 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
@ -482,8 +480,8 @@ TEST_F(RlsConfigParsingTest, GrpcKeybuilderNameWrongFieldTypes) {
"field:names index:0 error:type should be OBJECT.*"
"field:names index:1" CHILD_ERROR_TAG
"field:service error:type should be STRING.*"
"field:method error:type should be STRING"));
GRPC_ERROR_UNREF(error);
"field:method error:type should be STRING"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInSameKeyBuilder) {
@ -510,17 +508,17 @@ TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInSameKeyBuilder) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:0" CHILD_ERROR_TAG
"field:names error:duplicate entry for /foo/bar"));
GRPC_ERROR_UNREF(error);
"field:names error:duplicate entry for /foo/bar"))
<< service_config.status();
}
TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInDifferentKeyBuilders) {
@ -551,17 +549,17 @@ TEST_F(RlsConfigParsingTest, DuplicateMethodNamesInDifferentKeyBuilders) {
" }\n"
" }]\n"
"}\n";
grpc_error_handle error = GRPC_ERROR_NONE;
auto service_config =
ServiceConfigImpl::Create(ChannelArgs(), service_config_json, &error);
ServiceConfigImpl::Create(ChannelArgs(), service_config_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"errors parsing RLS LB policy config" CHILD_ERROR_TAG
"field:routeLookupConfig" CHILD_ERROR_TAG
"field:grpcKeybuilders" CHILD_ERROR_TAG "index:1" CHILD_ERROR_TAG
"field:names error:duplicate entry for /foo/bar"));
GRPC_ERROR_UNREF(error);
"field:names error:duplicate entry for /foo/bar"))
<< service_config.status();
}
} // namespace

File diff suppressed because it is too large Load Diff

@ -40,12 +40,11 @@ TEST(RbacServiceConfigParsingTest, EmptyRbacPolicy) {
" } ]"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -69,11 +68,10 @@ TEST(RbacServiceConfigParsingTest, MissingChannelArg) {
" } ]"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
auto svc_cfg = ServiceConfigImpl::Create(ChannelArgs(), test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(ChannelArgs(), test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -91,12 +89,11 @@ TEST(RbacServiceConfigParsingTest, EmptyRbacPolicyArray) {
" \"rbacPolicy\": []"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -114,12 +111,11 @@ TEST(RbacServiceConfigParsingTest, MultipleRbacPolicies) {
" \"rbacPolicy\": [ {}, {}, {} ]"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -142,14 +138,14 @@ TEST(RbacServiceConfigParsingTest, BadRbacPolicyType) {
" \"rbacPolicy\": 1234"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex("Rbac parser" CHILD_ERROR_TAG
"field:rbacPolicy error:type should be ARRAY"));
GRPC_ERROR_UNREF(error);
"field:rbacPolicy error:type should be ARRAY"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, BadRulesType) {
@ -162,15 +158,15 @@ TEST(RbacServiceConfigParsingTest, BadRulesType) {
" \"rbacPolicy\": [{\"rules\":1}]"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex("Rbac parser" CHILD_ERROR_TAG
"rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"field:rules error:type should be OBJECT"));
GRPC_ERROR_UNREF(error);
"field:rules error:type should be OBJECT"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, BadActionAndPolicyType) {
@ -188,16 +184,16 @@ TEST(RbacServiceConfigParsingTest, BadActionAndPolicyType) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex("Rbac parser" CHILD_ERROR_TAG
"rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"field:action error:type should be NUMBER.*"
"field:policies error:type should be OBJECT"));
GRPC_ERROR_UNREF(error);
"field:policies error:type should be OBJECT"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, MissingPermissionAndPrincipals) {
@ -218,17 +214,17 @@ TEST(RbacServiceConfigParsingTest, MissingPermissionAndPrincipals) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex("Rbac parser" CHILD_ERROR_TAG
"rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"policies key:'policy'" CHILD_ERROR_TAG
"field:permissions error:does not exist.*"
"field:principals error:does not exist"));
GRPC_ERROR_UNREF(error);
"field:principals error:does not exist"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, EmptyPrincipalAndPermission) {
@ -251,17 +247,17 @@ TEST(RbacServiceConfigParsingTest, EmptyPrincipalAndPermission) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"Rbac parser" CHILD_ERROR_TAG "rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"policies key:'policy'" CHILD_ERROR_TAG
"permissions\\[0\\]" CHILD_ERROR_TAG "No valid rule found.*"
"principals\\[0\\]" CHILD_ERROR_TAG "No valid id found"));
GRPC_ERROR_UNREF(error);
"principals\\[0\\]" CHILD_ERROR_TAG "No valid id found"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsTypes) {
@ -308,12 +304,11 @@ TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsTypes) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -365,11 +360,11 @@ TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsBadTypes) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"Rbac parser" CHILD_ERROR_TAG "rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"policies key:'policy'" CHILD_ERROR_TAG
@ -414,8 +409,8 @@ TEST(RbacServiceConfigParsingTest, VariousPermissionsAndPrincipalsBadTypes) {
"principals\\[9\\]" CHILD_ERROR_TAG
"field:metadata error:type should be OBJECT.*"
"principals\\[10\\]" CHILD_ERROR_TAG
"field:notId error:type should be OBJECT.*"));
GRPC_ERROR_UNREF(error);
"field:notId error:type should be OBJECT.*"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, HeaderMatcherVariousTypes) {
@ -449,12 +444,11 @@ TEST(RbacServiceConfigParsingTest, HeaderMatcherVariousTypes) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -492,11 +486,11 @@ TEST(RbacServiceConfigParsingTest, HeaderMatcherBadTypes) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex(
"Rbac parser" CHILD_ERROR_TAG "rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"policies key:'policy'" CHILD_ERROR_TAG
@ -514,8 +508,8 @@ TEST(RbacServiceConfigParsingTest, HeaderMatcherBadTypes) {
"permissions\\[5\\]" CHILD_ERROR_TAG "header" CHILD_ERROR_TAG
"field:suffixMatch error:type should be STRING.*"
"permissions\\[6\\]" CHILD_ERROR_TAG "header" CHILD_ERROR_TAG
"field:containsMatch error:type should be STRING.*"));
GRPC_ERROR_UNREF(error);
"field:containsMatch error:type should be STRING.*"))
<< service_config.status();
}
TEST(RbacServiceConfigParsingTest, StringMatcherVariousTypes) {
@ -546,12 +540,11 @@ TEST(RbacServiceConfigParsingTest, StringMatcherVariousTypes) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
ASSERT_TRUE(service_config.ok()) << service_config.status();
const auto* vector_ptr =
svc_cfg->GetMethodParsedConfigVector(grpc_empty_slice());
(*service_config)->GetMethodParsedConfigVector(grpc_empty_slice());
ASSERT_NE(vector_ptr, nullptr);
auto* parsed_rbac_config = static_cast<RbacMethodParsedConfig*>(
((*vector_ptr)[RbacServiceConfigParser::ParserIndex()]).get());
@ -587,11 +580,11 @@ TEST(RbacServiceConfigParsingTest, StringMatcherBadTypes) {
" } ]\n"
" } ]\n"
"}";
grpc_error_handle error = GRPC_ERROR_NONE;
ChannelArgs args = ChannelArgs().Set(GRPC_ARG_PARSE_RBAC_METHOD_CONFIG, 1);
auto svc_cfg = ServiceConfigImpl::Create(args, test_json, &error);
auto service_config = ServiceConfigImpl::Create(args, test_json);
EXPECT_EQ(service_config.status().code(), absl::StatusCode::kInvalidArgument);
EXPECT_THAT(
grpc_error_std_string(error),
std::string(service_config.status().message()),
::testing::ContainsRegex("Rbac parser" CHILD_ERROR_TAG
"rbacPolicy\\[0\\]" CHILD_ERROR_TAG
"policies key:'policy'" CHILD_ERROR_TAG
@ -610,8 +603,8 @@ TEST(RbacServiceConfigParsingTest, StringMatcherBadTypes) {
"field:safeRegex error:type should be OBJECT.*"
"permissions\\[4\\]" CHILD_ERROR_TAG
"requestedServerName" CHILD_ERROR_TAG
"field:contains error:type should be STRING.*"));
GRPC_ERROR_UNREF(error);
"field:contains error:type should be STRING.*"))
<< service_config.status();
}
} // namespace

@ -240,11 +240,10 @@ class ClientChannelStressTest {
static grpc_core::Resolver::Result MakeResolverResult(
const std::vector<AddressData>& balancer_address_data) {
grpc_core::Resolver::Result result;
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), "{\"loadBalancingConfig\":[{\"grpclb\":{}}]}",
&error);
GPR_ASSERT(GRPC_ERROR_IS_NONE(error));
grpc_core::ChannelArgs(),
"{\"loadBalancingConfig\":[{\"grpclb\":{}}]}");
GPR_ASSERT(result.service_config.ok());
grpc_core::ServerAddressList balancer_addresses =
CreateAddressListFromAddressDataList(balancer_address_data);
result.args = grpc_core::SetGrpcLbBalancerAddresses(

@ -69,11 +69,10 @@ void TryConnectAndDestroy() {
grpc_core::ServerAddressList addresses;
addresses.emplace_back(address.addr, address.len, grpc_core::ChannelArgs());
grpc_core::Resolver::Result lb_address_result;
grpc_error_handle error = GRPC_ERROR_NONE;
lb_address_result.service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), "{\"loadBalancingConfig\":[{\"grpclb\":{}}]}",
&error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
grpc_core::ChannelArgs(), "{\"loadBalancingConfig\":[{\"grpclb\":{}}]}");
ASSERT_TRUE(lb_address_result.service_config.ok())
<< lb_address_result.service_config.status();
lb_address_result.args = grpc_core::SetGrpcLbBalancerAddresses(
grpc_core::ChannelArgs(), addresses);
response_generator->SetResponse(lb_address_result);

@ -210,10 +210,9 @@ class FakeResolverResponseGeneratorWrapper {
result.resolution_note = "fake resolver empty address list";
}
if (service_config_json != nullptr) {
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), service_config_json, &error);
GPR_ASSERT(*result.service_config != nullptr);
grpc_core::ChannelArgs(), service_config_json);
GPR_ASSERT(result.service_config.ok());
}
return result;
}

@ -528,10 +528,9 @@ class GrpclbEnd2endTest : public ::testing::Test {
grpc_core::Resolver::Result result;
result.addresses =
CreateLbAddressesFromAddressDataList(backend_address_data);
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), service_config_json, &error);
GPR_ASSERT(GRPC_ERROR_IS_NONE(error));
grpc_core::ChannelArgs(), service_config_json);
GPR_ASSERT(result.service_config.ok());
grpc_core::ServerAddressList balancer_addresses =
CreateLbAddressesFromAddressDataList(balancer_address_data);
result.args = grpc_core::SetGrpcLbBalancerAddresses(

@ -145,13 +145,9 @@ class FakeResolverResponseGeneratorWrapper {
static grpc_core::Resolver::Result BuildFakeResults(
absl::string_view service_config_json) {
grpc_core::Resolver::Result result;
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = grpc_core::ServiceConfigImpl::Create(
result.args, service_config_json, &error);
EXPECT_EQ(error, GRPC_ERROR_NONE)
<< "JSON: " << service_config_json
<< "Error: " << grpc_error_std_string(error);
EXPECT_NE(*result.service_config, nullptr);
result.service_config =
grpc_core::ServiceConfigImpl::Create(result.args, service_config_json);
EXPECT_TRUE(result.service_config.ok()) << result.service_config.status();
return result;
}

@ -198,10 +198,9 @@ class ServiceConfigEnd2endTest : public ::testing::Test {
void SetNextResolutionValidServiceConfig(const std::vector<int>& ports) {
grpc_core::ExecCtx exec_ctx;
grpc_core::Resolver::Result result = BuildFakeResults(ports);
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), "{}", &error);
ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
result.service_config =
grpc_core::ServiceConfigImpl::Create(grpc_core::ChannelArgs(), "{}");
ASSERT_TRUE(result.service_config.ok()) << result.service_config.status();
response_generator_->SetResponse(result);
}
@ -217,13 +216,8 @@ class ServiceConfigEnd2endTest : public ::testing::Test {
const char* svc_cfg) {
grpc_core::ExecCtx exec_ctx;
grpc_core::Resolver::Result result = BuildFakeResults(ports);
grpc_error_handle error = GRPC_ERROR_NONE;
result.service_config = grpc_core::ServiceConfigImpl::Create(
grpc_core::ChannelArgs(), svc_cfg, &error);
if (!GRPC_ERROR_IS_NONE(error)) {
result.service_config = grpc_error_to_absl_status(error);
GRPC_ERROR_UNREF(error);
}
result.service_config =
grpc_core::ServiceConfigImpl::Create(grpc_core::ChannelArgs(), svc_cfg);
response_generator_->SetResponse(result);
}

Loading…
Cancel
Save