XdsClient: access certificate provider data via dependency injection (#30506)

* don't pass context through AdsResponseParser::ParseResource()

* don't pass certificate provider info through XdsApi

* use dependency injection for cert provider map

* move XdsEncodingContext into XdsResourceType

* remove unnecessary field

* clang-format

* Automated change: Fix sanity tests

* fix xds_bootstrap_test

* fix build

* Automated change: Fix sanity tests

* fix test and clang-format

* remove unnecessary field

* fix test

* Automated change: Fix sanity tests

Co-authored-by: markdroth <markdroth@users.noreply.github.com>
pull/30511/head^2
Mark D. Roth 3 years ago committed by GitHub
parent cc96858f0b
commit dc4414aa0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/core/ext/filters/client_channel/lb_policy/xds/cds.cc
  2. 22
      src/core/ext/xds/upb_utils.h
  3. 94
      src/core/ext/xds/xds_api.cc
  4. 11
      src/core/ext/xds/xds_api.h
  5. 78
      src/core/ext/xds/xds_bootstrap.cc
  6. 36
      src/core/ext/xds/xds_bootstrap.h
  7. 15
      src/core/ext/xds/xds_client.cc
  8. 6
      src/core/ext/xds/xds_client.h
  9. 75
      src/core/ext/xds/xds_client_grpc.cc
  10. 32
      src/core/ext/xds/xds_client_grpc.h
  11. 11
      src/core/ext/xds/xds_cluster.cc
  12. 8
      src/core/ext/xds/xds_cluster.h
  13. 26
      src/core/ext/xds/xds_common_types.cc
  14. 7
      src/core/ext/xds/xds_common_types.h
  15. 8
      src/core/ext/xds/xds_endpoint.cc
  16. 8
      src/core/ext/xds/xds_endpoint.h
  17. 17
      src/core/ext/xds/xds_lb_policy_registry.cc
  18. 8
      src/core/ext/xds/xds_lb_policy_registry.h
  19. 21
      src/core/ext/xds/xds_listener.cc
  20. 8
      src/core/ext/xds/xds_listener.h
  21. 15
      src/core/ext/xds/xds_resource_type.h
  22. 25
      src/core/ext/xds/xds_route_config.cc
  23. 10
      src/core/ext/xds/xds_route_config.h
  24. 95
      test/core/xds/xds_bootstrap_test.cc
  25. 6
      test/core/xds/xds_lb_policy_registry_test.cc
  26. 1
      test/cpp/end2end/xds/xds_end2end_test.cc

@ -93,7 +93,7 @@ class CdsLbConfig : public LoadBalancingPolicy::Config {
// CDS LB policy.
class CdsLb : public LoadBalancingPolicy {
public:
CdsLb(RefCountedPtr<XdsClient> xds_client, Args args);
CdsLb(RefCountedPtr<GrpcXdsClient> xds_client, Args args);
absl::string_view name() const override { return kCds; }
@ -195,7 +195,7 @@ class CdsLb : public LoadBalancingPolicy {
ChannelArgs args_;
// The xds client.
RefCountedPtr<XdsClient> xds_client_;
RefCountedPtr<GrpcXdsClient> xds_client_;
// Maps from cluster name to the state for that cluster.
// The root of the tree is config_->cluster().
@ -258,7 +258,7 @@ void CdsLb::Helper::AddTraceEvent(TraceSeverity severity,
// CdsLb
//
CdsLb::CdsLb(RefCountedPtr<XdsClient> xds_client, Args args)
CdsLb::CdsLb(RefCountedPtr<GrpcXdsClient> xds_client, Args args)
: LoadBalancingPolicy(std::move(args)), xds_client_(std::move(xds_client)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_cds_lb_trace)) {
gpr_log(GPR_INFO, "[cdslb %p] created -- using xds client %p", this,

@ -22,32 +22,10 @@
#include <string>
#include "absl/strings/string_view.h"
#include "upb/arena.h"
#include "upb/def.h"
#include "upb/upb.h"
#include "src/core/ext/xds/certificate_provider_store.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/lib/debug/trace.h"
namespace grpc_core {
class XdsClient;
// TODO(roth): Rethink this. All fields except symtab and arena should come
// from XdsClient, injected into XdsResourceType::Decode() somehow without
// passing through XdsApi code, maybe via the AdsResponseParser.
struct XdsEncodingContext {
XdsClient* client; // Used only for logging. Unsafe for dereferencing.
const XdsBootstrap::XdsServer& server;
TraceFlag* tracer;
upb_DefPool* symtab;
upb_Arena* arena;
bool use_v3;
const CertificateProviderStore::PluginDefinitionMap*
certificate_provider_definition_map;
};
// Works for both std::string and absl::string_view.
template <typename T>
inline upb_StringView StdStringToUpbString(const T& str) {

@ -77,14 +77,10 @@ namespace grpc_core {
#endif
XdsApi::XdsApi(XdsClient* client, TraceFlag* tracer,
const XdsBootstrap::Node* node,
const CertificateProviderStore::PluginDefinitionMap*
certificate_provider_definition_map,
upb::SymbolTable* symtab)
const XdsBootstrap::Node* node, upb::SymbolTable* symtab)
: client_(client),
tracer_(tracer),
node_(node),
certificate_provider_definition_map_(certificate_provider_definition_map),
symtab_(symtab),
build_version_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING, " ",
grpc_version_string(),
@ -99,10 +95,18 @@ XdsApi::XdsApi(XdsClient* client, TraceFlag* tracer,
namespace {
void PopulateMetadataValue(const XdsEncodingContext& context,
struct XdsApiContext {
XdsClient* client;
TraceFlag* tracer;
upb_DefPool* symtab;
upb_Arena* arena;
bool use_v3;
};
void PopulateMetadataValue(const XdsApiContext& context,
google_protobuf_Value* value_pb, const Json& value);
void PopulateListValue(const XdsEncodingContext& context,
void PopulateListValue(const XdsApiContext& context,
google_protobuf_ListValue* list_value,
const Json::Array& values) {
for (const auto& value : values) {
@ -112,7 +116,7 @@ void PopulateListValue(const XdsEncodingContext& context,
}
}
void PopulateMetadata(const XdsEncodingContext& context,
void PopulateMetadata(const XdsApiContext& context,
google_protobuf_Struct* metadata_pb,
const Json::Object& metadata) {
for (const auto& p : metadata) {
@ -123,7 +127,7 @@ void PopulateMetadata(const XdsEncodingContext& context,
}
}
void PopulateMetadataValue(const XdsEncodingContext& context,
void PopulateMetadataValue(const XdsApiContext& context,
google_protobuf_Value* value_pb, const Json& value) {
switch (value.type()) {
case Json::Type::JSON_NULL:
@ -179,7 +183,7 @@ std::string EncodeStringField(uint32_t field_number, const std::string& str) {
EncodeVarint(str.size()) + str;
}
void PopulateBuildVersion(const XdsEncodingContext& context,
void PopulateBuildVersion(const XdsApiContext& context,
envoy_config_core_v3_Node* node_msg,
const std::string& build_version) {
std::string encoded_build_version = EncodeStringField(5, build_version);
@ -191,8 +195,7 @@ void PopulateBuildVersion(const XdsEncodingContext& context,
encoded_build_version.size(), context.arena);
}
void PopulateNode(const XdsEncodingContext& context,
const XdsBootstrap::Node* node,
void PopulateNode(const XdsApiContext& context, const XdsBootstrap::Node* node,
const std::string& build_version,
const std::string& user_agent_name,
const std::string& user_agent_version,
@ -243,7 +246,7 @@ void PopulateNode(const XdsEncodingContext& context,
}
void MaybeLogDiscoveryRequest(
const XdsEncodingContext& context,
const XdsApiContext& context,
const envoy_service_discovery_v3_DiscoveryRequest* request) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -257,7 +260,7 @@ void MaybeLogDiscoveryRequest(
}
std::string SerializeDiscoveryRequest(
const XdsEncodingContext& context,
const XdsApiContext& context,
envoy_service_discovery_v3_DiscoveryRequest* request) {
size_t output_length;
char* output = envoy_service_discovery_v3_DiscoveryRequest_serialize(
@ -273,13 +276,8 @@ std::string XdsApi::CreateAdsRequest(
const std::vector<std::string>& resource_names, absl::Status status,
bool populate_node) {
upb::Arena arena;
const XdsEncodingContext context = {client_,
server,
tracer_,
symtab_->ptr(),
arena.ptr(),
server.ShouldUseV3(),
certificate_provider_definition_map_};
const XdsApiContext context = {client_, tracer_, symtab_->ptr(), arena.ptr(),
server.ShouldUseV3()};
// Create a request.
envoy_service_discovery_v3_DiscoveryRequest* request =
envoy_service_discovery_v3_DiscoveryRequest_new(arena.ptr());
@ -337,7 +335,7 @@ std::string XdsApi::CreateAdsRequest(
namespace {
void MaybeLogDiscoveryResponse(
const XdsEncodingContext& context,
const XdsApiContext& context,
const envoy_service_discovery_v3_DiscoveryResponse* response) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -356,13 +354,8 @@ absl::Status XdsApi::ParseAdsResponse(const XdsBootstrap::XdsServer& server,
absl::string_view encoded_response,
AdsResponseParserInterface* parser) {
upb::Arena arena;
const XdsEncodingContext context = {client_,
server,
tracer_,
symtab_->ptr(),
arena.ptr(),
server.ShouldUseV3(),
certificate_provider_definition_map_};
const XdsApiContext context = {client_, tracer_, symtab_->ptr(), arena.ptr(),
server.ShouldUseV3()};
// Decode the response.
const envoy_service_discovery_v3_DiscoveryResponse* response =
envoy_service_discovery_v3_DiscoveryResponse_parse(
@ -413,7 +406,7 @@ absl::Status XdsApi::ParseAdsResponse(const XdsBootstrap::XdsServer& server,
serialized_resource =
UpbStringToAbsl(google_protobuf_Any_value(resource));
}
parser->ParseResource(context, i, type_url, serialized_resource);
parser->ParseResource(context.arena, i, type_url, serialized_resource);
}
return absl::OkStatus();
}
@ -421,7 +414,7 @@ absl::Status XdsApi::ParseAdsResponse(const XdsBootstrap::XdsServer& server,
namespace {
void MaybeLogLrsRequest(
const XdsEncodingContext& context,
const XdsApiContext& context,
const envoy_service_load_stats_v3_LoadStatsRequest* request) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -435,7 +428,7 @@ void MaybeLogLrsRequest(
}
std::string SerializeLrsRequest(
const XdsEncodingContext& context,
const XdsApiContext& context,
const envoy_service_load_stats_v3_LoadStatsRequest* request) {
size_t output_length;
char* output = envoy_service_load_stats_v3_LoadStatsRequest_serialize(
@ -448,13 +441,8 @@ std::string SerializeLrsRequest(
std::string XdsApi::CreateLrsInitialRequest(
const XdsBootstrap::XdsServer& server) {
upb::Arena arena;
const XdsEncodingContext context = {client_,
server,
tracer_,
symtab_->ptr(),
arena.ptr(),
server.ShouldUseV3(),
certificate_provider_definition_map_};
const XdsApiContext context = {client_, tracer_, symtab_->ptr(), arena.ptr(),
server.ShouldUseV3()};
// Create a request.
envoy_service_load_stats_v3_LoadStatsRequest* request =
envoy_service_load_stats_v3_LoadStatsRequest_new(arena.ptr());
@ -475,7 +463,7 @@ std::string XdsApi::CreateLrsInitialRequest(
namespace {
void LocalityStatsPopulate(
const XdsEncodingContext& context,
const XdsApiContext& context,
envoy_config_endpoint_v3_UpstreamLocalityStats* output,
const XdsLocalityName& locality_name,
const XdsClusterLocalityStats::Snapshot& snapshot) {
@ -525,16 +513,8 @@ void LocalityStatsPopulate(
std::string XdsApi::CreateLrsRequest(
ClusterLoadReportMap cluster_load_report_map) {
upb::Arena arena;
// The xDS server info is not actually needed here, so we seed it with an
// empty value.
XdsBootstrap::XdsServer empty_server;
const XdsEncodingContext context = {client_,
empty_server,
tracer_,
symtab_->ptr(),
arena.ptr(),
false,
certificate_provider_definition_map_};
const XdsApiContext context = {client_, tracer_, symtab_->ptr(), arena.ptr(),
/*use_v3=*/false};
// Create a request.
envoy_service_load_stats_v3_LoadStatsRequest* request =
envoy_service_load_stats_v3_LoadStatsRequest_new(arena.ptr());
@ -632,7 +612,7 @@ absl::Status XdsApi::ParseLrsResponse(absl::string_view encoded_response,
namespace {
google_protobuf_Timestamp* EncodeTimestamp(const XdsEncodingContext& context,
google_protobuf_Timestamp* EncodeTimestamp(const XdsApiContext& context,
Timestamp value) {
google_protobuf_Timestamp* timestamp =
google_protobuf_Timestamp_new(context.arena);
@ -652,16 +632,8 @@ std::string XdsApi::AssembleClientConfig(
// Fill-in the node information
auto* node = envoy_service_status_v3_ClientConfig_mutable_node(client_config,
arena.ptr());
// The xDS server info is not actually needed here, so we seed it with an
// empty value.
XdsBootstrap::XdsServer empty_server;
const XdsEncodingContext context = {client_,
empty_server,
tracer_,
symtab_->ptr(),
arena.ptr(),
true,
certificate_provider_definition_map_};
const XdsApiContext context = {client_, tracer_, symtab_->ptr(), arena.ptr(),
/*use_v3=*/true};
PopulateNode(context, node_, build_version_, user_agent_name_,
user_agent_version_, node);
// Dump each resource.

@ -30,10 +30,9 @@
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "envoy/admin/v3/config_dump_shared.upb.h"
#include "upb/arena.h"
#include "upb/def.hpp"
#include "src/core/ext/xds/certificate_provider_store.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/lib/debug/trace.h"
@ -45,7 +44,6 @@ namespace grpc_core {
class XdsClient;
// TODO(roth): When we have time, split this into multiple pieces:
// - a common upb-based parsing framework (combine with XdsEncodingContext)
// - ADS request/response handling
// - LRS request/response handling
// - CSDS response generation
@ -69,7 +67,7 @@ class XdsApi {
virtual absl::Status ProcessAdsResponseFields(AdsResponseFields fields) = 0;
// Called to parse each individual resource in the ADS response.
virtual void ParseResource(const XdsEncodingContext& context, size_t idx,
virtual void ParseResource(upb_Arena* arena, size_t idx,
absl::string_view type_url,
absl::string_view serialized_resource) = 0;
};
@ -142,7 +140,6 @@ class XdsApi {
"");
XdsApi(XdsClient* client, TraceFlag* tracer, const XdsBootstrap::Node* node,
const CertificateProviderStore::PluginDefinitionMap* map,
upb::SymbolTable* symtab);
// Creates an ADS request.
@ -181,9 +178,7 @@ class XdsApi {
XdsClient* client_;
TraceFlag* tracer_;
const XdsBootstrap::Node* node_; // Do not own.
const CertificateProviderStore::PluginDefinitionMap*
certificate_provider_definition_map_; // Do not own.
upb::SymbolTable* symtab_; // Do not own.
upb::SymbolTable* symtab_; // Do not own.
const std::string build_version_;
const std::string user_agent_name_;
const std::string user_agent_version_;

@ -34,14 +34,12 @@
#include <grpc/support/alloc.h>
#include "src/core/ext/xds/certificate_provider_factory.h"
#include "src/core/ext/xds/certificate_provider_registry.h"
#include "src/core/lib/config/core_configuration.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/json/json_util.h"
#include "src/core/lib/security/credentials/channel_creds_registry.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
@ -180,17 +178,27 @@ bool XdsBootstrap::XdsServer::IgnoreResourceDeletion() const {
//
std::unique_ptr<XdsBootstrap> XdsBootstrap::Create(
absl::string_view json_string, grpc_error_handle* error) {
absl::string_view json_string,
std::unique_ptr<XdsCertificateProviderPluginMapInterface>
certificate_provider_plugin_map,
grpc_error_handle* error) {
auto json = Json::Parse(json_string);
if (!json.ok()) {
*error = GRPC_ERROR_CREATE_FROM_CPP_STRING(absl::StrCat(
"Failed to parse bootstrap JSON string: ", json.status().ToString()));
return nullptr;
}
return absl::make_unique<XdsBootstrap>(std::move(*json), error);
return absl::make_unique<XdsBootstrap>(
std::move(*json), std::move(certificate_provider_plugin_map), error);
}
XdsBootstrap::XdsBootstrap(Json json, grpc_error_handle* error) {
XdsBootstrap::XdsBootstrap(
Json json,
std::unique_ptr<XdsCertificateProviderPluginMapInterface>
certificate_provider_plugin_map,
grpc_error_handle* error)
: certificate_provider_plugin_map_(
std::move(certificate_provider_plugin_map)) {
if (json.type() != Json::Type::OBJECT) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"malformed JSON in bootstrap file");
@ -469,36 +477,25 @@ grpc_error_handle XdsBootstrap::ParseCertificateProvider(
"\"plugin_name\" field is not a string"));
} else {
std::string plugin_name = std::move(*(it->second.mutable_string_value()));
CertificateProviderFactory* factory =
CertificateProviderRegistry::LookupCertificateProviderFactory(
plugin_name);
if (factory == nullptr) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_CPP_STRING(
absl::StrCat("Unrecognized plugin name: ", plugin_name)));
} else {
RefCountedPtr<CertificateProviderFactory::Config> config;
it = certificate_provider_json->mutable_object()->find("config");
if (it != certificate_provider_json->mutable_object()->end()) {
if (it->second.type() != Json::Type::OBJECT) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"\"config\" field is not an object"));
} else {
grpc_error_handle parse_error = GRPC_ERROR_NONE;
config = factory->CreateCertificateProviderConfig(it->second,
&parse_error);
if (!GRPC_ERROR_IS_NONE(parse_error)) {
error_list.push_back(parse_error);
}
}
it = certificate_provider_json->mutable_object()->find("config");
if (it != certificate_provider_json->mutable_object()->end()) {
if (it->second.type() != Json::Type::OBJECT) {
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"\"config\" field is not an object"));
} else {
// "config" is an optional field, so create an empty JSON object.
grpc_error_handle parse_error = GRPC_ERROR_NONE;
config = factory->CreateCertificateProviderConfig(Json::Object(),
&parse_error);
if (!GRPC_ERROR_IS_NONE(parse_error)) error_list.push_back(parse_error);
absl::Status status = certificate_provider_plugin_map_->AddPlugin(
instance_name, plugin_name, it->second);
if (!status.ok()) {
error_list.push_back(absl_status_to_grpc_error(status));
}
}
} else {
// "config" is an optional field, so create an empty JSON object.
absl::Status status = certificate_provider_plugin_map_->AddPlugin(
instance_name, plugin_name, Json::Object());
if (!status.ok()) {
error_list.push_back(absl_status_to_grpc_error(status));
}
certificate_providers_.insert(
{instance_name, {std::move(plugin_name), std::move(config)}});
}
}
return GRPC_ERROR_CREATE_FROM_VECTOR_AND_CPP_STRING(
@ -565,17 +562,8 @@ std::string XdsBootstrap::ToString() const {
parts.push_back(" },\n");
}
parts.push_back("}");
parts.push_back("certificate_providers={\n");
for (const auto& entry : certificate_providers_) {
parts.push_back(
absl::StrFormat(" %s={\n"
" plugin_name=%s\n"
" config=%s\n"
" },\n",
entry.first, entry.second.plugin_name,
entry.second.config->ToString()));
}
parts.push_back("}");
parts.push_back("certificate_providers=");
parts.push_back(certificate_provider_plugin_map_->ToString());
return absl::StrJoin(parts, "");
}

@ -26,9 +26,9 @@
#include <string>
#include <vector>
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "src/core/ext/xds/certificate_provider_store.h"
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/json/json.h"
@ -38,6 +38,19 @@ bool XdsFederationEnabled();
class XdsClient;
class XdsCertificateProviderPluginMapInterface {
public:
virtual ~XdsCertificateProviderPluginMapInterface() = default;
virtual absl::Status AddPlugin(const std::string& instance_name,
const std::string& plugin_name,
const Json& config) = 0;
virtual bool HasPlugin(const std::string& instance_name) const = 0;
virtual std::string ToString() const = 0;
};
class XdsBootstrap {
public:
struct Node {
@ -88,11 +101,17 @@ class XdsBootstrap {
// Creates bootstrap object from json_string.
// If *error is not GRPC_ERROR_NONE after returning, then there was an
// error parsing the contents.
static std::unique_ptr<XdsBootstrap> Create(absl::string_view json_string,
grpc_error_handle* error);
static std::unique_ptr<XdsBootstrap> Create(
absl::string_view json_string,
std::unique_ptr<XdsCertificateProviderPluginMapInterface>
certificate_provider_plugin_map,
grpc_error_handle* error);
// Do not instantiate directly -- use Create() above instead.
XdsBootstrap(Json json, grpc_error_handle* error);
XdsBootstrap(Json json,
std::unique_ptr<XdsCertificateProviderPluginMapInterface>
certificate_provider_plugin_map,
grpc_error_handle* error);
std::string ToString() const;
@ -110,9 +129,9 @@ class XdsBootstrap {
return authorities_;
}
const Authority* LookupAuthority(const std::string& name) const;
const CertificateProviderStore::PluginDefinitionMap& certificate_providers()
const {
return certificate_providers_;
const XdsCertificateProviderPluginMapInterface*
certificate_provider_plugin_map() const {
return certificate_provider_plugin_map_.get();
}
// A util method to check that an xds server exists in this bootstrap file.
bool XdsServerExists(const XdsServer& server) const;
@ -133,7 +152,8 @@ class XdsBootstrap {
std::string client_default_listener_resource_name_template_;
std::string server_listener_resource_name_template_;
std::map<std::string, Authority> authorities_;
CertificateProviderStore::PluginDefinitionMap certificate_providers_;
std::unique_ptr<XdsCertificateProviderPluginMapInterface>
certificate_provider_plugin_map_;
};
} // namespace grpc_core

@ -32,11 +32,11 @@
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
#include "absl/types/optional.h"
#include "upb/arena.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/support/log.h>
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_api.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_client_stats.h"
@ -149,8 +149,7 @@ class XdsClient::ChannelState::AdsCallState
absl::Status ProcessAdsResponseFields(AdsResponseFields fields) override
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
void ParseResource(const XdsEncodingContext& context, size_t idx,
absl::string_view type_url,
void ParseResource(upb_Arena* arena, size_t idx, absl::string_view type_url,
absl::string_view serialized_resource) override
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsClient::mu_);
@ -689,7 +688,7 @@ void UpdateResourceMetadataNacked(const std::string& version,
} // namespace
void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
const XdsEncodingContext& context, size_t idx, absl::string_view type_url,
upb_Arena* arena, size_t idx, absl::string_view type_url,
absl::string_view serialized_resource) {
// Check the type_url of the resource.
bool is_v2 = false;
@ -700,6 +699,9 @@ void XdsClient::ChannelState::AdsCallState::AdsResponseParser::ParseResource(
return;
}
// Parse the resource.
XdsResourceType::DecodeContext context = {
xds_client(), ads_call_state_->chand()->server_, &grpc_xds_client_trace,
xds_client()->symtab_.ptr(), arena};
absl::StatusOr<XdsResourceType::DecodeResult> result =
result_.type->Decode(context, serialized_resource, is_v2);
if (!result.ok()) {
@ -1383,10 +1385,7 @@ XdsClient::XdsClient(std::unique_ptr<XdsBootstrap> bootstrap,
transport_factory_(std::move(transport_factory)),
request_timeout_(resource_request_timeout),
xds_federation_enabled_(XdsFederationEnabled()),
certificate_provider_store_(MakeOrphanable<CertificateProviderStore>(
bootstrap_->certificate_providers())),
api_(this, &grpc_xds_client_trace, bootstrap_->node(),
&bootstrap_->certificate_providers(), &symtab_) {
api_(this, &grpc_xds_client_trace, bootstrap_->node(), &symtab_) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_client_trace)) {
gpr_log(GPR_INFO, "[xds_client %p] creating xds client", this);
}

@ -32,7 +32,6 @@
#include "absl/strings/string_view.h"
#include "upb/def.hpp"
#include "src/core/ext/xds/certificate_provider_store.h"
#include "src/core/ext/xds/xds_api.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_client_stats.h"
@ -86,10 +85,6 @@ class XdsClient : public DualRefCounted<XdsClient> {
return transport_factory_.get();
}
CertificateProviderStore& certificate_provider_store() {
return *certificate_provider_store_;
}
void Orphan() override;
// Start and cancel watch for a resource.
@ -304,7 +299,6 @@ class XdsClient : public DualRefCounted<XdsClient> {
OrphanablePtr<XdsTransportFactory> transport_factory_;
const Duration request_timeout_;
const bool xds_federation_enabled_;
OrphanablePtr<CertificateProviderStore> certificate_provider_store_;
XdsApi api_;
WorkSerializer work_serializer_;

@ -19,12 +19,18 @@
#include "src/core/ext/xds/xds_client_grpc.h"
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
@ -34,6 +40,8 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include "src/core/ext/xds/certificate_provider_factory.h"
#include "src/core/ext/xds/certificate_provider_registry.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_channel_args.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
@ -52,12 +60,17 @@
#include "src/core/lib/iomgr/error.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/load_file.h"
#include "src/core/lib/json/json.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_refcount.h"
#include "src/core/lib/transport/error_utils.h"
namespace grpc_core {
//
// GrpcXdsClient
//
namespace {
Mutex* g_mu = nullptr;
@ -131,14 +144,17 @@ absl::StatusOr<std::string> GetBootstrapContents(const char* fallback_config) {
absl::StatusOr<RefCountedPtr<GrpcXdsClient>> GrpcXdsClient::GetOrCreate(
const ChannelArgs& args, const char* reason) {
// Construct certificate provider plugin map.
auto certificate_provider_plugin_map =
absl::make_unique<GrpcXdsCertificateProviderPluginMap>();
// If getting bootstrap from channel args, create a local XdsClient
// instance for the channel or server instead of using the global instance.
absl::optional<absl::string_view> bootstrap_config = args.GetString(
GRPC_ARG_TEST_ONLY_DO_NOT_USE_IN_PROD_XDS_BOOTSTRAP_CONFIG);
if (bootstrap_config.has_value()) {
grpc_error_handle error = GRPC_ERROR_NONE;
std::unique_ptr<XdsBootstrap> bootstrap =
XdsBootstrap::Create(*bootstrap_config, &error);
std::unique_ptr<XdsBootstrap> bootstrap = XdsBootstrap::Create(
*bootstrap_config, std::move(certificate_provider_plugin_map), &error);
if (!GRPC_ERROR_IS_NONE(error)) return grpc_error_to_absl_status(error);
grpc_channel_args* xds_channel_args = args.GetPointer<grpc_channel_args>(
GRPC_ARG_TEST_ONLY_DO_NOT_USE_IN_PROD_XDS_CLIENT_CHANNEL_ARGS);
@ -160,8 +176,8 @@ absl::StatusOr<RefCountedPtr<GrpcXdsClient>> GrpcXdsClient::GetOrCreate(
}
// Parse bootstrap.
grpc_error_handle error = GRPC_ERROR_NONE;
std::unique_ptr<XdsBootstrap> bootstrap =
XdsBootstrap::Create(*bootstrap_contents, &error);
std::unique_ptr<XdsBootstrap> bootstrap = XdsBootstrap::Create(
*bootstrap_contents, std::move(certificate_provider_plugin_map), &error);
if (!GRPC_ERROR_IS_NONE(error)) return grpc_error_to_absl_status(error);
// Instantiate XdsClient.
auto xds_client = MakeRefCounted<GrpcXdsClient>(
@ -177,7 +193,11 @@ GrpcXdsClient::GrpcXdsClient(std::unique_ptr<XdsBootstrap> bootstrap,
std::max(Duration::Zero(),
args.GetDurationFromIntMillis(
GRPC_ARG_XDS_RESOURCE_DOES_NOT_EXIST_TIMEOUT_MS)
.value_or(Duration::Seconds(15)))) {}
.value_or(Duration::Seconds(15)))),
certificate_provider_store_(MakeOrphanable<CertificateProviderStore>(
static_cast<const GrpcXdsCertificateProviderPluginMap*>(
this->bootstrap().certificate_provider_plugin_map())
->plugin_map())) {}
GrpcXdsClient::~GrpcXdsClient() {
MutexLock lock(g_mu);
@ -209,6 +229,51 @@ void SetXdsFallbackBootstrapConfig(const char* config) {
} // namespace internal
//
// GrpcXdsCertificateProviderPluginMap
//
absl::Status GrpcXdsCertificateProviderPluginMap::AddPlugin(
const std::string& instance_name, const std::string& plugin_name,
const Json& config) {
CertificateProviderFactory* factory =
CertificateProviderRegistry::LookupCertificateProviderFactory(
plugin_name);
if (factory == nullptr) {
return absl::InvalidArgumentError(
absl::StrCat("Unrecognized plugin name: ", plugin_name));
}
grpc_error_handle error = GRPC_ERROR_NONE;
auto parsed_config = factory->CreateCertificateProviderConfig(config, &error);
if (!GRPC_ERROR_IS_NONE(error)) {
absl::Status status = grpc_error_to_absl_status(error);
GRPC_ERROR_UNREF(error);
return status;
}
plugin_map_.insert({instance_name, {plugin_name, std::move(parsed_config)}});
return absl::OkStatus();
}
bool GrpcXdsCertificateProviderPluginMap::HasPlugin(
const std::string& instance_name) const {
return plugin_map_.find(instance_name) != plugin_map_.end();
}
std::string GrpcXdsCertificateProviderPluginMap::ToString() const {
std::vector<std::string> parts = {"{\n"};
for (const auto& entry : plugin_map_) {
parts.push_back(
absl::StrFormat(" %s={\n"
" plugin_name=%s\n"
" config=%s\n"
" },\n",
entry.first, entry.second.plugin_name,
entry.second.config->ToString()));
}
parts.push_back("}");
return absl::StrJoin(parts, "");
}
} // namespace grpc_core
// The returned bytes may contain NULL(0), so we can't use c-string.

@ -20,18 +20,23 @@
#include <grpc/support/port_platform.h>
#include <memory>
#include <string>
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include <grpc/impl/codegen/grpc_types.h>
#include "src/core/ext/xds/certificate_provider_store.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/iomgr/iomgr_fwd.h"
#include "src/core/lib/json/json.h"
namespace grpc_core {
@ -55,6 +60,13 @@ class GrpcXdsClient : public XdsClient {
}
grpc_pollset_set* interested_parties() const;
CertificateProviderStore& certificate_provider_store() const {
return *certificate_provider_store_;
}
private:
OrphanablePtr<CertificateProviderStore> certificate_provider_store_;
};
namespace internal {
@ -65,6 +77,26 @@ void UnsetGlobalXdsClientForTest();
void SetXdsFallbackBootstrapConfig(const char* config);
} // namespace internal
// Exposed for testing purposes only.
class GrpcXdsCertificateProviderPluginMap
: public XdsCertificateProviderPluginMapInterface {
public:
const CertificateProviderStore::PluginDefinitionMap& plugin_map() const {
return plugin_map_;
}
absl::Status AddPlugin(const std::string& instance_name,
const std::string& plugin_name,
const Json& config) override;
bool HasPlugin(const std::string& instance_name) const override;
std::string ToString() const override;
private:
CertificateProviderStore::PluginDefinitionMap plugin_map_;
};
} // namespace grpc_core
#endif // GRPC_CORE_EXT_XDS_XDS_CLIENT_GRPC_H

@ -46,6 +46,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/lib/debug/trace.h"
@ -103,7 +104,7 @@ std::string XdsClusterResource::ToString() const {
namespace {
absl::StatusOr<CommonTlsContext> UpstreamTlsContextParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_core_v3_TransportSocket* transport_socket) {
CommonTlsContext common_tls_context;
// Record Upstream tls context
@ -210,7 +211,7 @@ absl::Status CdsLogicalDnsParse(const envoy_config_cluster_v3_Cluster* cluster,
}
absl::StatusOr<XdsClusterResource> CdsResourceParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_cluster_v3_Cluster* cluster, bool /*is_v2*/) {
XdsClusterResource cds_update;
std::vector<std::string> errors;
@ -491,7 +492,7 @@ absl::StatusOr<XdsClusterResource> CdsResourceParse(
return cds_update;
}
void MaybeLogCluster(const XdsEncodingContext& context,
void MaybeLogCluster(const XdsResourceType::DecodeContext& context,
const envoy_config_cluster_v3_Cluster* cluster) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -506,8 +507,8 @@ void MaybeLogCluster(const XdsEncodingContext& context,
} // namespace
absl::StatusOr<XdsResourceType::DecodeResult> XdsClusterResourceType::Decode(
const XdsEncodingContext& context, absl::string_view serialized_resource,
bool is_v2) const {
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool is_v2) const {
// Parse serialized proto.
auto* resource = envoy_config_cluster_v3_Cluster_parse(
serialized_resource.data(), serialized_resource.size(), context.arena);

@ -35,9 +35,9 @@
#include "upb/def.h"
#include "src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
namespace grpc_core {
@ -101,9 +101,9 @@ class XdsClusterResourceType
return "envoy.api.v2.Cluster";
}
absl::StatusOr<DecodeResult> Decode(const XdsEncodingContext& context,
absl::string_view serialized_resource,
bool is_v2) const override;
absl::StatusOr<DecodeResult> Decode(
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool is_v2) const override;
bool AllResourcesRequiredInSotW() const override { return true; }

@ -21,7 +21,6 @@
#include <stddef.h>
#include <algorithm>
#include <map>
#include <utility>
#include "absl/status/status.h"
@ -38,7 +37,9 @@
#include "upb/upb.h"
#include "xds/type/v3/typed_struct.upb.h"
#include "src/core/ext/xds/certificate_provider_store.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_client.h"
namespace grpc_core {
@ -113,7 +114,7 @@ namespace {
// certificate provider instances.
absl::StatusOr<CommonTlsContext::CertificateProviderPluginInstance>
CertificateProviderInstanceParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance*
certificate_provider_instance_proto) {
CommonTlsContext::CertificateProviderPluginInstance
@ -124,9 +125,8 @@ CertificateProviderInstanceParse(
UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CommonTlsContext_CertificateProviderInstance_certificate_name(
certificate_provider_instance_proto))};
if (context.certificate_provider_definition_map->find(
certificate_provider_plugin_instance.instance_name) ==
context.certificate_provider_definition_map->end()) {
if (!context.client->bootstrap().certificate_provider_plugin_map()->HasPlugin(
certificate_provider_plugin_instance.instance_name)) {
return absl::InvalidArgumentError(
absl::StrCat("Unrecognized certificate provider instance name: ",
certificate_provider_plugin_instance.instance_name));
@ -136,7 +136,7 @@ CertificateProviderInstanceParse(
absl::StatusOr<CommonTlsContext::CertificateProviderPluginInstance>
CertificateProviderPluginInstanceParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance*
certificate_provider_plugin_instance_proto) {
CommonTlsContext::CertificateProviderPluginInstance
@ -147,9 +147,8 @@ CertificateProviderPluginInstanceParse(
UpbStringToStdString(
envoy_extensions_transport_sockets_tls_v3_CertificateProviderPluginInstance_certificate_name(
certificate_provider_plugin_instance_proto))};
if (context.certificate_provider_definition_map->find(
certificate_provider_plugin_instance.instance_name) ==
context.certificate_provider_definition_map->end()) {
if (!context.client->bootstrap().certificate_provider_plugin_map()->HasPlugin(
certificate_provider_plugin_instance.instance_name)) {
return absl::InvalidArgumentError(
absl::StrCat("Unrecognized certificate provider instance name: ",
certificate_provider_plugin_instance.instance_name));
@ -159,7 +158,7 @@ CertificateProviderPluginInstanceParse(
absl::StatusOr<CommonTlsContext::CertificateValidationContext>
CertificateValidationContextParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_extensions_transport_sockets_tls_v3_CertificateValidationContext*
certificate_validation_context_proto) {
std::vector<std::string> errors;
@ -273,7 +272,7 @@ CertificateValidationContextParse(
} // namespace
absl::StatusOr<CommonTlsContext> CommonTlsContext::Parse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*
common_tls_context_proto) {
std::vector<std::string> errors;
@ -399,7 +398,8 @@ absl::StatusOr<CommonTlsContext> CommonTlsContext::Parse(
}
absl::StatusOr<ExtractExtensionTypeNameResult> ExtractExtensionTypeName(
const XdsEncodingContext& context, const google_protobuf_Any* any) {
const XdsResourceType::DecodeContext& context,
const google_protobuf_Any* any) {
ExtractExtensionTypeNameResult result;
result.type = UpbStringToAbsl(google_protobuf_Any_type_url(any));
if (result.type == "type.googleapis.com/xds.type.v3.TypedStruct" ||

@ -29,7 +29,7 @@
#include "google/protobuf/duration.upb.h"
#include "xds/type/v3/typed_struct.upb.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/matchers/matchers.h"
@ -83,7 +83,7 @@ struct CommonTlsContext {
bool Empty() const;
static absl::StatusOr<CommonTlsContext> Parse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_extensions_transport_sockets_tls_v3_CommonTlsContext*
common_tls_context_proto);
};
@ -94,7 +94,8 @@ struct ExtractExtensionTypeNameResult {
};
absl::StatusOr<ExtractExtensionTypeNameResult> ExtractExtensionTypeName(
const XdsEncodingContext& context, const google_protobuf_Any* any);
const XdsResourceType::DecodeContext& context,
const google_protobuf_Any* any);
} // namespace grpc_core

@ -125,7 +125,7 @@ std::string XdsEndpointResource::ToString() const {
namespace {
void MaybeLogClusterLoadAssignment(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_endpoint_v3_ClusterLoadAssignment* cla) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -273,7 +273,7 @@ absl::Status DropParseAndAppend(
}
absl::StatusOr<XdsEndpointResource> EdsResourceParse(
const XdsEncodingContext& /*context*/,
const XdsResourceType::DecodeContext& /*context*/,
const envoy_config_endpoint_v3_ClusterLoadAssignment*
cluster_load_assignment,
bool /*is_v2*/) {
@ -343,8 +343,8 @@ absl::StatusOr<XdsEndpointResource> EdsResourceParse(
} // namespace
absl::StatusOr<XdsResourceType::DecodeResult> XdsEndpointResourceType::Decode(
const XdsEncodingContext& context, absl::string_view serialized_resource,
bool is_v2) const {
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool is_v2) const {
// Parse serialized proto.
auto* resource = envoy_config_endpoint_v3_ClusterLoadAssignment_parse(
serialized_resource.data(), serialized_resource.size(), context.arena);

@ -33,8 +33,8 @@
#include "envoy/config/endpoint/v3/endpoint.upbdefs.h"
#include "upb/def.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
@ -129,9 +129,9 @@ class XdsEndpointResourceType
return "envoy.api.v2.ClusterLoadAssignment";
}
absl::StatusOr<DecodeResult> Decode(const XdsEncodingContext& context,
absl::string_view serialized_resource,
bool is_v2) const override;
absl::StatusOr<DecodeResult> Decode(
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool is_v2) const override;
void InitUpbSymtab(upb_DefPool* symtab) const override {
envoy_config_endpoint_v3_ClusterLoadAssignment_getmsgdef(symtab);

@ -53,8 +53,8 @@ class RingHashLbPolicyConfigFactory
: public XdsLbPolicyRegistry::ConfigFactory {
public:
absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context, absl::string_view configuration,
int /* recursion_depth */) override {
const XdsResourceType::DecodeContext& context,
absl::string_view configuration, int /* recursion_depth */) override {
const auto* resource =
envoy_extensions_load_balancing_policies_ring_hash_v3_RingHash_parse(
configuration.data(), configuration.size(), context.arena);
@ -98,7 +98,7 @@ class RoundRobinLbPolicyConfigFactory
: public XdsLbPolicyRegistry::ConfigFactory {
public:
absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& /* context */,
const XdsResourceType::DecodeContext& /* context */,
absl::string_view /* configuration */,
int /* recursion_depth */) override {
return Json::Object{{"round_robin", Json::Object()}};
@ -115,8 +115,8 @@ class WrrLocalityLbPolicyConfigFactory
: public XdsLbPolicyRegistry::ConfigFactory {
public:
absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context, absl::string_view configuration,
int recursion_depth) override {
const XdsResourceType::DecodeContext& context,
absl::string_view configuration, int recursion_depth) override {
const auto* resource =
envoy_extensions_load_balancing_policies_wrr_locality_v3_WrrLocality_parse(
configuration.data(), configuration.size(), context.arena);
@ -151,8 +151,9 @@ class WrrLocalityLbPolicyConfigFactory
}
};
absl::StatusOr<Json> ParseStructToJson(const XdsEncodingContext& context,
const google_protobuf_Struct* resource) {
absl::StatusOr<Json> ParseStructToJson(
const XdsResourceType::DecodeContext& context,
const google_protobuf_Struct* resource) {
upb::Status status;
const auto* msg_def = google_protobuf_Struct_getmsgdef(context.symtab);
size_t json_size = upb_JsonEncode(resource, msg_def, context.symtab, 0,
@ -183,7 +184,7 @@ absl::StatusOr<Json> ParseStructToJson(const XdsEncodingContext& context,
//
absl::StatusOr<Json::Array> XdsLbPolicyRegistry::ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_cluster_v3_LoadBalancingPolicy* lb_policy,
int recursion_depth) {
constexpr int kMaxRecursionDepth = 16;

@ -26,7 +26,7 @@
#include "absl/strings/string_view.h"
#include "envoy/config/cluster/v3/cluster.upb.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/lib/json/json.h"
namespace grpc_core {
@ -39,8 +39,8 @@ class XdsLbPolicyRegistry {
public:
virtual ~ConfigFactory() {}
virtual absl::StatusOr<Json::Object> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context, absl::string_view configuration,
int recursion_depth) = 0;
const XdsResourceType::DecodeContext& context,
absl::string_view configuration, int recursion_depth) = 0;
virtual absl::string_view type() = 0;
};
@ -51,7 +51,7 @@ class XdsLbPolicyRegistry {
// recursion_depth indicates the current depth of the tree if lb_policy
// configuration recursively holds other lb policies.
static absl::StatusOr<Json::Array> ConvertXdsLbPolicyConfig(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_cluster_v3_LoadBalancingPolicy* lb_policy,
int recursion_depth = 0);

@ -48,6 +48,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/lib/address_utils/parse_address.h"
@ -268,7 +269,7 @@ std::string XdsListenerResource::ToString() const {
namespace {
void MaybeLogHttpConnectionManager(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager*
http_connection_manager_config) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
@ -286,7 +287,7 @@ void MaybeLogHttpConnectionManager(
absl::StatusOr<XdsListenerResource::HttpConnectionManager>
HttpConnectionManagerParse(
bool is_client, const XdsEncodingContext& context,
bool is_client, const XdsResourceType::DecodeContext& context,
const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager*
http_connection_manager_proto,
bool is_v2) {
@ -480,7 +481,7 @@ HttpConnectionManagerParse(
}
absl::StatusOr<XdsListenerResource> LdsResourceParseClient(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_listener_v3_ApiListener* api_listener, bool is_v2) {
const upb_StringView encoded_api_listener = google_protobuf_Any_value(
envoy_config_listener_v3_ApiListener_api_listener(api_listener));
@ -502,7 +503,7 @@ absl::StatusOr<XdsListenerResource> LdsResourceParseClient(
absl::StatusOr<XdsListenerResource::DownstreamTlsContext>
DownstreamTlsContextParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_core_v3_TransportSocket* transport_socket) {
absl::string_view name = UpbStringToAbsl(
envoy_config_core_v3_TransportSocket_name(transport_socket));
@ -679,7 +680,7 @@ absl::StatusOr<FilterChain::FilterChainMatch> FilterChainMatchParse(
}
absl::StatusOr<FilterChain> FilterChainParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_listener_v3_FilterChain* filter_chain_proto,
bool is_v2) {
FilterChain filter_chain;
@ -973,7 +974,7 @@ absl::StatusOr<XdsListenerResource::FilterChainMap> BuildFilterChainMap(
}
absl::StatusOr<XdsListenerResource> LdsResourceParseServer(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_listener_v3_Listener* listener, bool is_v2) {
XdsListenerResource lds_update;
lds_update.type = XdsListenerResource::ListenerType::kTcpListener;
@ -1019,7 +1020,7 @@ absl::StatusOr<XdsListenerResource> LdsResourceParseServer(
}
absl::StatusOr<XdsListenerResource> LdsResourceParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_listener_v3_Listener* listener, bool is_v2) {
// Check whether it's a client or server listener.
const envoy_config_listener_v3_ApiListener* api_listener =
@ -1044,7 +1045,7 @@ absl::StatusOr<XdsListenerResource> LdsResourceParse(
return LdsResourceParseServer(context, listener, is_v2);
}
void MaybeLogListener(const XdsEncodingContext& context,
void MaybeLogListener(const XdsResourceType::DecodeContext& context,
const envoy_config_listener_v3_Listener* listener) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -1059,8 +1060,8 @@ void MaybeLogListener(const XdsEncodingContext& context,
} // namespace
absl::StatusOr<XdsResourceType::DecodeResult> XdsListenerResourceType::Decode(
const XdsEncodingContext& context, absl::string_view serialized_resource,
bool is_v2) const {
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool is_v2) const {
// Parse serialized proto.
auto* resource = envoy_config_listener_v3_Listener_parse(
serialized_resource.data(), serialized_resource.size(), context.arena);

@ -37,9 +37,9 @@
#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h"
#include "upb/def.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_http_filters.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
#include "src/core/ext/xds/xds_route_config.h"
#include "src/core/lib/gprpp/time.h"
@ -210,9 +210,9 @@ class XdsListenerResourceType
return "envoy.api.v2.Listener";
}
absl::StatusOr<DecodeResult> Decode(const XdsEncodingContext& context,
absl::string_view serialized_resource,
bool is_v2) const override;
absl::StatusOr<DecodeResult> Decode(
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool is_v2) const override;
bool AllResourcesRequiredInSotW() const override { return true; }

@ -23,9 +23,11 @@
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "upb/arena.h"
#include "upb/def.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/lib/debug/trace.h"
namespace grpc_core {
@ -33,6 +35,15 @@ namespace grpc_core {
// Used to inject type-specific logic into XdsClient.
class XdsResourceType {
public:
// Context passed into Decode().
struct DecodeContext {
XdsClient* client;
const XdsBootstrap::XdsServer& server;
TraceFlag* tracer;
upb_DefPool* symtab;
upb_Arena* arena;
};
// A base type for resource data.
// Subclasses will extend this, and their DecodeResults will be
// downcastable to their extended type.
@ -60,7 +71,7 @@ class XdsResourceType {
// whose resource field is set to a non-OK status.
// Otherwise, returns a DecodeResult with a valid resource.
virtual absl::StatusOr<DecodeResult> Decode(
const XdsEncodingContext& context, absl::string_view serialized_resource,
const DecodeContext& context, absl::string_view serialized_resource,
bool is_v2) const = 0;
// Returns true if r1 and r2 are equal.

@ -59,6 +59,7 @@
#include <grpc/support/log.h>
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_bootstrap.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
#include "src/core/ext/xds/xds_common_types.h"
#include "src/core/ext/xds/xds_http_filters.h"
@ -341,7 +342,7 @@ namespace {
absl::StatusOr<XdsRouteConfigResource::ClusterSpecifierPluginMap>
ClusterSpecifierPluginParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config) {
XdsRouteConfigResource::ClusterSpecifierPluginMap
cluster_specifier_plugin_map;
@ -587,7 +588,7 @@ absl::Status RouteRuntimeFractionParse(
template <typename ParentType, typename EntryType>
absl::StatusOr<XdsRouteConfigResource::TypedPerFilterConfig>
ParseTypedPerFilterConfig(
const XdsEncodingContext& context, const ParentType* parent,
const XdsResourceType::DecodeContext& context, const ParentType* parent,
const EntryType* (*entry_func)(const ParentType*, size_t*),
upb_StringView (*key_func)(const EntryType*),
const google_protobuf_Any* (*value_func)(const EntryType*)) {
@ -650,7 +651,7 @@ ParseTypedPerFilterConfig(
}
absl::Status RetryPolicyParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_route_v3_RetryPolicy* retry_policy,
absl::optional<XdsRouteConfigResource::RetryPolicy>* retry) {
std::vector<std::string> errors;
@ -725,7 +726,7 @@ absl::Status RetryPolicyParse(
}
absl::StatusOr<XdsRouteConfigResource::Route::RouteAction> RouteActionParse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_route_v3_Route* route_msg,
const std::map<std::string /*cluster_specifier_plugin_name*/,
std::string /*LB policy config*/>&
@ -783,7 +784,7 @@ absl::StatusOr<XdsRouteConfigResource::Route::RouteAction> RouteActionParse(
cluster.weight = google_protobuf_UInt32Value_value(weight);
if (cluster.weight == 0) continue;
sum_of_weights += cluster.weight;
if (context.use_v3) {
if (context.server.ShouldUseV3()) {
auto typed_per_filter_config = ParseTypedPerFilterConfig<
envoy_config_route_v3_WeightedCluster_ClusterWeight,
envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry>(
@ -942,7 +943,7 @@ absl::StatusOr<XdsRouteConfigResource::Route::RouteAction> RouteActionParse(
} // namespace
absl::StatusOr<XdsRouteConfigResource> XdsRouteConfigResource::Parse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config) {
XdsRouteConfigResource rds_update;
// Get the cluster spcifier plugins
@ -980,7 +981,7 @@ absl::StatusOr<XdsRouteConfigResource> XdsRouteConfigResource::Parse(
return absl::InvalidArgumentError("VirtualHost has no domains");
}
// Parse typed_per_filter_config.
if (context.use_v3) {
if (context.server.ShouldUseV3()) {
auto typed_per_filter_config = ParseTypedPerFilterConfig<
envoy_config_route_v3_VirtualHost,
envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry>(
@ -1063,7 +1064,7 @@ absl::StatusOr<XdsRouteConfigResource> XdsRouteConfigResource::Parse(
route.action
.emplace<XdsRouteConfigResource::Route::NonForwardingAction>();
}
if (context.use_v3) {
if (context.server.ShouldUseV3()) {
auto typed_per_filter_config = ParseTypedPerFilterConfig<
envoy_config_route_v3_Route,
envoy_config_route_v3_Route_TypedPerFilterConfigEntry>(
@ -1097,7 +1098,7 @@ absl::StatusOr<XdsRouteConfigResource> XdsRouteConfigResource::Parse(
namespace {
void MaybeLogRouteConfiguration(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config) {
if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) &&
gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) {
@ -1113,9 +1114,9 @@ void MaybeLogRouteConfiguration(
} // namespace
absl::StatusOr<XdsResourceType::DecodeResult>
XdsRouteConfigResourceType::Decode(const XdsEncodingContext& context,
absl::string_view serialized_resource,
bool /*is_v2*/) const {
XdsRouteConfigResourceType::Decode(
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool /*is_v2*/) const {
// Parse serialized proto.
auto* resource = envoy_config_route_v3_RouteConfiguration_parse(
serialized_resource.data(), serialized_resource.size(), context.arena);

@ -36,9 +36,9 @@
#include "re2/re2.h"
#include "upb/def.h"
#include "src/core/ext/xds/upb_utils.h"
#include "src/core/ext/xds/xds_cluster_specifier_plugin.h"
#include "src/core/ext/xds/xds_http_filters.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
#include "src/core/lib/channel/status_util.h"
#include "src/core/lib/gprpp/time.h"
@ -211,7 +211,7 @@ struct XdsRouteConfigResource {
std::string ToString() const;
static absl::StatusOr<XdsRouteConfigResource> Parse(
const XdsEncodingContext& context,
const XdsResourceType::DecodeContext& context,
const envoy_config_route_v3_RouteConfiguration* route_config);
};
@ -226,9 +226,9 @@ class XdsRouteConfigResourceType
return "envoy.api.v2.RouteConfiguration";
}
absl::StatusOr<DecodeResult> Decode(const XdsEncodingContext& context,
absl::string_view serialized_resource,
bool /*is_v2*/) const override;
absl::StatusOr<DecodeResult> Decode(
const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource, bool /*is_v2*/) const override;
void InitUpbSymtab(upb_DefPool* symtab) const override {
envoy_config_route_v3_RouteConfiguration_getmsgdef(symtab);

@ -28,6 +28,7 @@
#include <grpc/slice.h>
#include "src/core/ext/xds/certificate_provider_registry.h"
#include "src/core/ext/xds/xds_client_grpc.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/tmpfile.h"
#include "test/core/util/test_config.h"
@ -120,7 +121,9 @@ TEST(XdsBootstrapTest, Basic) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
EXPECT_EQ(bootstrap.server().server_uri, "fake:///lb");
EXPECT_EQ(bootstrap.server().channel_creds_type, "fake");
@ -186,7 +189,9 @@ TEST(XdsBootstrapTest, ValidWithoutNode) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
EXPECT_EQ(bootstrap.server().server_uri, "fake:///lb");
EXPECT_EQ(bootstrap.server().channel_creds_type, "fake");
@ -206,7 +211,9 @@ TEST(XdsBootstrapTest, InsecureCreds) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
EXPECT_EQ(bootstrap.server().server_uri, "fake:///lb");
EXPECT_EQ(bootstrap.server().channel_creds_type, "insecure");
@ -242,7 +249,9 @@ TEST(XdsBootstrapTest, GoogleDefaultCreds) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_EQ(error, GRPC_ERROR_NONE) << grpc_error_std_string(error);
EXPECT_EQ(bootstrap.server().server_uri, "fake:///lb");
EXPECT_EQ(bootstrap.server().channel_creds_type, "google_default");
@ -261,7 +270,9 @@ TEST(XdsBootstrapTest, MissingChannelCreds) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(
grpc_error_std_string(error),
::testing::ContainsRegex("field:channel_creds error:does not exist."));
@ -281,7 +292,9 @@ TEST(XdsBootstrapTest, NoKnownChannelCreds) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"no known creds type found in \"channel_creds\""));
@ -292,7 +305,9 @@ TEST(XdsBootstrapTest, MissingXdsServers) {
auto json = Json::Parse("{}");
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex("\"xds_servers\" field not present"));
GRPC_ERROR_UNREF(error);
@ -309,7 +324,9 @@ TEST(XdsBootstrapTest, TopFieldsWrongTypes) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex("\"xds_servers\" field is not an array.*"
"\"node\" field is not an object.*"
@ -329,7 +346,9 @@ TEST(XdsBootstrapTest, XdsServerMissingServerUri) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(
grpc_error_std_string(error),
::testing::ContainsRegex("errors parsing \"xds_servers\" array.*"
@ -352,7 +371,9 @@ TEST(XdsBootstrapTest, XdsServerUriAndCredsWrongTypes) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"errors parsing \"xds_servers\" array.*"
@ -381,7 +402,9 @@ TEST(XdsBootstrapTest, ChannelCredsFieldsWrongTypes) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(
grpc_error_std_string(error),
::testing::ContainsRegex("errors parsing \"xds_servers\" array.*"
@ -407,7 +430,9 @@ TEST(XdsBootstrapTest, NodeFieldsWrongTypes) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex("errors parsing \"node\" object.*"
"\"id\" field is not a string.*"
@ -431,7 +456,9 @@ TEST(XdsBootstrapTest, LocalityFieldsWrongType) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex("errors parsing \"node\" object.*"
"errors parsing \"locality\" object.*"
@ -457,7 +484,9 @@ TEST(XdsBootstrapTest, CertificateProvidersElementWrongType) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"errors parsing \"certificate_providers\" object.*"
@ -483,7 +512,9 @@ TEST(XdsBootstrapTest, CertificateProvidersPluginNameWrongType) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"errors parsing \"certificate_providers\" object.*"
@ -510,7 +541,9 @@ TEST(XdsBootstrapTest, CertificateProvidersUnrecognizedPluginName) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"errors parsing \"certificate_providers\" object.*"
@ -551,7 +584,9 @@ TEST(XdsBootstrapTest, AuthorityXdsServerInvalidResourceTemplate) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"errors parsing \"authorities\".*"
@ -583,7 +618,9 @@ TEST(XdsBootstrapTest, AuthorityXdsServerMissingServerUri) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(
grpc_error_std_string(error),
::testing::ContainsRegex("errors parsing \"authorities\".*"
@ -666,7 +703,9 @@ TEST(XdsBootstrapTest, CertificateProvidersFakePluginParsingError) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
EXPECT_THAT(grpc_error_std_string(error),
::testing::ContainsRegex(
"errors parsing \"certificate_providers\" object.*"
@ -696,10 +735,15 @@ TEST(XdsBootstrapTest, CertificateProvidersFakePluginParsingSuccess) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
ASSERT_TRUE(GRPC_ERROR_IS_NONE(error)) << grpc_error_std_string(error);
const CertificateProviderStore::PluginDefinition& fake_plugin =
bootstrap.certificate_providers().at("fake_plugin");
static_cast<const GrpcXdsCertificateProviderPluginMap*>(
bootstrap.certificate_provider_plugin_map())
->plugin_map()
.at("fake_plugin");
ASSERT_EQ(fake_plugin.plugin_name, "fake");
ASSERT_STREQ(fake_plugin.config->name(), "fake");
ASSERT_EQ(static_cast<RefCountedPtr<FakeCertificateProviderFactory::Config>>(
@ -726,10 +770,15 @@ TEST(XdsBootstrapTest, CertificateProvidersFakePluginEmptyConfig) {
auto json = Json::Parse(json_str);
ASSERT_TRUE(json.ok()) << json.status();
grpc_error_handle error = GRPC_ERROR_NONE;
XdsBootstrap bootstrap(std::move(*json), &error);
XdsBootstrap bootstrap(
std::move(*json),
absl::make_unique<GrpcXdsCertificateProviderPluginMap>(), &error);
ASSERT_TRUE(GRPC_ERROR_IS_NONE(error)) << grpc_error_std_string(error);
const CertificateProviderStore::PluginDefinition& fake_plugin =
bootstrap.certificate_providers().at("fake_plugin");
static_cast<const GrpcXdsCertificateProviderPluginMap*>(
bootstrap.certificate_provider_plugin_map())
->plugin_map()
.at("fake_plugin");
ASSERT_EQ(fake_plugin.plugin_name, "fake");
ASSERT_STREQ(fake_plugin.config->name(), "fake");
ASSERT_EQ(static_cast<RefCountedPtr<FakeCertificateProviderFactory::Config>>(

@ -57,10 +57,8 @@ absl::StatusOr<Json::Array> ConvertXdsPolicy(LoadBalancingPolicyProto policy) {
std::string serialized_policy = policy.SerializeAsString();
upb::Arena arena;
upb::SymbolTable symtab;
XdsEncodingContext context = {nullptr, XdsBootstrap::XdsServer(),
nullptr, symtab.ptr(),
arena.ptr(), true,
nullptr};
XdsResourceType::DecodeContext context = {nullptr, XdsBootstrap::XdsServer(),
nullptr, symtab.ptr(), arena.ptr()};
auto* upb_policy = envoy_config_cluster_v3_LoadBalancingPolicy_parse(
serialized_policy.data(), serialized_policy.size(), arena.ptr());
return XdsLbPolicyRegistry::ConvertXdsLbPolicyConfig(context, upb_policy);

@ -81,6 +81,7 @@
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/resolver/server_address.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h"
#include "src/cpp/client/secure_credentials.h"
#include "src/cpp/server/secure_server_credentials.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"

Loading…
Cancel
Save