xds_api.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /*
  2. *
  3. * Copyright 2018 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #ifndef GRPC_CORE_EXT_XDS_XDS_API_H
  19. #define GRPC_CORE_EXT_XDS_XDS_API_H
  20. #include <grpc/support/port_platform.h>
  21. #include <stdint.h>
  22. #include <set>
  23. #include "absl/container/inlined_vector.h"
  24. #include "absl/types/optional.h"
  25. #include "re2/re2.h"
  26. #include "upb/def.hpp"
  27. #include <grpc/slice_buffer.h>
  28. #include "envoy/admin/v3/config_dump.upb.h"
  29. #include "src/core/ext/filters/client_channel/server_address.h"
  30. #include "src/core/ext/xds/xds_bootstrap.h"
  31. #include "src/core/ext/xds/xds_client_stats.h"
  32. #include "src/core/ext/xds/xds_http_filters.h"
  33. #include "src/core/lib/matchers/matchers.h"
  34. namespace grpc_core {
  35. // TODO(yashykt): Check to see if xDS security is enabled. This will be
  36. // removed once this feature is fully integration-tested and enabled by
  37. // default.
  38. bool XdsSecurityEnabled();
  39. class XdsClient;
  40. class XdsApi {
  41. public:
  42. static const char* kLdsTypeUrl;
  43. static const char* kRdsTypeUrl;
  44. static const char* kCdsTypeUrl;
  45. static const char* kEdsTypeUrl;
  46. struct Duration {
  47. int64_t seconds = 0;
  48. int32_t nanos = 0;
  49. bool operator==(const Duration& other) const {
  50. return seconds == other.seconds && nanos == other.nanos;
  51. }
  52. std::string ToString() const {
  53. return absl::StrFormat("Duration seconds: %ld, nanos %d", seconds, nanos);
  54. }
  55. };
  56. using TypedPerFilterConfig =
  57. std::map<std::string, XdsHttpFilterImpl::FilterConfig>;
  58. // TODO(donnadionne): When we can use absl::variant<>, consider using that
  59. // for: PathMatcher, HeaderMatcher, cluster_name and weighted_clusters
  60. struct Route {
  61. // Matchers for this route.
  62. struct Matchers {
  63. StringMatcher path_matcher;
  64. std::vector<HeaderMatcher> header_matchers;
  65. absl::optional<uint32_t> fraction_per_million;
  66. bool operator==(const Matchers& other) const {
  67. return path_matcher == other.path_matcher &&
  68. header_matchers == other.header_matchers &&
  69. fraction_per_million == other.fraction_per_million;
  70. }
  71. std::string ToString() const;
  72. };
  73. struct HashPolicy {
  74. enum Type { HEADER, CHANNEL_ID };
  75. Type type;
  76. bool terminal = false;
  77. // Fields used for type HEADER.
  78. std::string header_name;
  79. std::unique_ptr<RE2> regex = nullptr;
  80. std::string regex_substitution;
  81. HashPolicy() {}
  82. // Copyable.
  83. HashPolicy(const HashPolicy& other);
  84. HashPolicy& operator=(const HashPolicy& other);
  85. // Moveable.
  86. HashPolicy(HashPolicy&& other) noexcept;
  87. HashPolicy& operator=(HashPolicy&& other) noexcept;
  88. bool operator==(const HashPolicy& other) const;
  89. std::string ToString() const;
  90. };
  91. Matchers matchers;
  92. std::vector<HashPolicy> hash_policies;
  93. // Action for this route.
  94. // TODO(roth): When we can use absl::variant<>, consider using that
  95. // here, to enforce the fact that only one of the two fields can be set.
  96. std::string cluster_name;
  97. struct ClusterWeight {
  98. std::string name;
  99. uint32_t weight;
  100. TypedPerFilterConfig typed_per_filter_config;
  101. bool operator==(const ClusterWeight& other) const {
  102. return name == other.name && weight == other.weight &&
  103. typed_per_filter_config == other.typed_per_filter_config;
  104. }
  105. std::string ToString() const;
  106. };
  107. std::vector<ClusterWeight> weighted_clusters;
  108. // Storing the timeout duration from route action:
  109. // RouteAction.max_stream_duration.grpc_timeout_header_max or
  110. // RouteAction.max_stream_duration.max_stream_duration if the former is
  111. // not set.
  112. absl::optional<Duration> max_stream_duration;
  113. TypedPerFilterConfig typed_per_filter_config;
  114. bool operator==(const Route& other) const {
  115. return matchers == other.matchers && cluster_name == other.cluster_name &&
  116. weighted_clusters == other.weighted_clusters &&
  117. max_stream_duration == other.max_stream_duration &&
  118. typed_per_filter_config == other.typed_per_filter_config;
  119. }
  120. std::string ToString() const;
  121. };
  122. struct RdsUpdate {
  123. struct VirtualHost {
  124. std::vector<std::string> domains;
  125. std::vector<Route> routes;
  126. TypedPerFilterConfig typed_per_filter_config;
  127. bool operator==(const VirtualHost& other) const {
  128. return domains == other.domains && routes == other.routes &&
  129. typed_per_filter_config == other.typed_per_filter_config;
  130. }
  131. };
  132. std::vector<VirtualHost> virtual_hosts;
  133. bool operator==(const RdsUpdate& other) const {
  134. return virtual_hosts == other.virtual_hosts;
  135. }
  136. std::string ToString() const;
  137. VirtualHost* FindVirtualHostForDomain(const std::string& domain);
  138. };
  139. struct CommonTlsContext {
  140. struct CertificateValidationContext {
  141. std::vector<StringMatcher> match_subject_alt_names;
  142. bool operator==(const CertificateValidationContext& other) const {
  143. return match_subject_alt_names == other.match_subject_alt_names;
  144. }
  145. std::string ToString() const;
  146. bool Empty() const;
  147. };
  148. struct CertificateProviderInstance {
  149. std::string instance_name;
  150. std::string certificate_name;
  151. bool operator==(const CertificateProviderInstance& other) const {
  152. return instance_name == other.instance_name &&
  153. certificate_name == other.certificate_name;
  154. }
  155. std::string ToString() const;
  156. bool Empty() const;
  157. };
  158. struct CombinedCertificateValidationContext {
  159. CertificateValidationContext default_validation_context;
  160. CertificateProviderInstance
  161. validation_context_certificate_provider_instance;
  162. bool operator==(const CombinedCertificateValidationContext& other) const {
  163. return default_validation_context == other.default_validation_context &&
  164. validation_context_certificate_provider_instance ==
  165. other.validation_context_certificate_provider_instance;
  166. }
  167. std::string ToString() const;
  168. bool Empty() const;
  169. };
  170. CertificateProviderInstance tls_certificate_certificate_provider_instance;
  171. CombinedCertificateValidationContext combined_validation_context;
  172. bool operator==(const CommonTlsContext& other) const {
  173. return tls_certificate_certificate_provider_instance ==
  174. other.tls_certificate_certificate_provider_instance &&
  175. combined_validation_context == other.combined_validation_context;
  176. }
  177. std::string ToString() const;
  178. bool Empty() const;
  179. };
  180. struct DownstreamTlsContext {
  181. CommonTlsContext common_tls_context;
  182. bool require_client_certificate = false;
  183. bool operator==(const DownstreamTlsContext& other) const {
  184. return common_tls_context == other.common_tls_context &&
  185. require_client_certificate == other.require_client_certificate;
  186. }
  187. std::string ToString() const;
  188. bool Empty() const;
  189. };
  190. // TODO(roth): When we can use absl::variant<>, consider using that
  191. // here, to enforce the fact that only one of the two fields can be set.
  192. struct LdsUpdate {
  193. enum class ListenerType {
  194. kTcpListener = 0,
  195. kHttpApiListener,
  196. } type;
  197. struct HttpConnectionManager {
  198. // The name to use in the RDS request.
  199. std::string route_config_name;
  200. // Storing the Http Connection Manager Common Http Protocol Option
  201. // max_stream_duration
  202. Duration http_max_stream_duration;
  203. // The RouteConfiguration to use for this listener.
  204. // Present only if it is inlined in the LDS response.
  205. absl::optional<RdsUpdate> rds_update;
  206. struct HttpFilter {
  207. std::string name;
  208. XdsHttpFilterImpl::FilterConfig config;
  209. bool operator==(const HttpFilter& other) const {
  210. return name == other.name && config == other.config;
  211. }
  212. std::string ToString() const;
  213. };
  214. std::vector<HttpFilter> http_filters;
  215. bool operator==(const HttpConnectionManager& other) const {
  216. return route_config_name == other.route_config_name &&
  217. http_max_stream_duration == other.http_max_stream_duration &&
  218. rds_update == other.rds_update &&
  219. http_filters == other.http_filters;
  220. }
  221. std::string ToString() const;
  222. };
  223. // Populated for type=kHttpApiListener.
  224. HttpConnectionManager http_connection_manager;
  225. // Populated for type=kTcpListener.
  226. // host:port listening_address set when type is kTcpListener
  227. std::string address;
  228. struct FilterChainData {
  229. DownstreamTlsContext downstream_tls_context;
  230. // This is in principle the filter list.
  231. // We currently require exactly one filter, which is the HCM.
  232. HttpConnectionManager http_connection_manager;
  233. bool operator==(const FilterChainData& other) const {
  234. return downstream_tls_context == other.downstream_tls_context &&
  235. http_connection_manager == other.http_connection_manager;
  236. }
  237. std::string ToString() const;
  238. } filter_chain_data;
  239. // A multi-level map used to determine which filter chain to use for a given
  240. // incoming connection. Determining the right filter chain for a given
  241. // connection checks the following properties, in order:
  242. // - destination port (never matched, so not present in map)
  243. // - destination IP address
  244. // - server name (never matched, so not present in map)
  245. // - transport protocol (allows only "raw_buffer" or unset, prefers the
  246. // former, so only one of those two types is present in map)
  247. // - application protocol (never matched, so not present in map)
  248. // - connection source type (any, local or external)
  249. // - source IP address
  250. // - source port
  251. // https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/listener/v3/listener_components.proto#config-listener-v3-filterchainmatch
  252. // for more details
  253. struct FilterChainMap {
  254. struct FilterChainDataSharedPtr {
  255. std::shared_ptr<FilterChainData> data;
  256. bool operator==(const FilterChainDataSharedPtr& other) const {
  257. return *data == *other.data;
  258. }
  259. };
  260. struct CidrRange {
  261. grpc_resolved_address address;
  262. uint32_t prefix_len;
  263. bool operator==(const CidrRange& other) const {
  264. return memcmp(&address, &other.address, sizeof(address)) == 0 &&
  265. prefix_len == other.prefix_len;
  266. }
  267. std::string ToString() const;
  268. };
  269. using SourcePortsMap = std::map<uint16_t, FilterChainDataSharedPtr>;
  270. struct SourceIp {
  271. absl::optional<CidrRange> prefix_range;
  272. SourcePortsMap ports_map;
  273. bool operator==(const SourceIp& other) const {
  274. return prefix_range == other.prefix_range &&
  275. ports_map == other.ports_map;
  276. }
  277. };
  278. using SourceIpVector = std::vector<SourceIp>;
  279. enum class ConnectionSourceType {
  280. kAny = 0,
  281. kSameIpOrLoopback,
  282. kExternal
  283. };
  284. using ConnectionSourceTypesArray = std::array<SourceIpVector, 3>;
  285. struct DestinationIp {
  286. absl::optional<CidrRange> prefix_range;
  287. // We always fail match on server name, so those filter chains are not
  288. // included here.
  289. ConnectionSourceTypesArray source_types_array;
  290. bool operator==(const DestinationIp& other) const {
  291. return prefix_range == other.prefix_range &&
  292. source_types_array == other.source_types_array;
  293. }
  294. };
  295. // We always fail match on destination ports map
  296. using DestinationIpVector = std::vector<DestinationIp>;
  297. DestinationIpVector destination_ip_vector;
  298. bool operator==(const FilterChainMap& other) const {
  299. return destination_ip_vector == other.destination_ip_vector;
  300. }
  301. std::string ToString() const;
  302. } filter_chain_map;
  303. absl::optional<FilterChainData> default_filter_chain;
  304. bool operator==(const LdsUpdate& other) const {
  305. return http_connection_manager == other.http_connection_manager &&
  306. address == other.address &&
  307. filter_chain_map == other.filter_chain_map &&
  308. default_filter_chain == other.default_filter_chain;
  309. }
  310. std::string ToString() const;
  311. };
  312. struct LdsResourceData {
  313. LdsUpdate resource;
  314. std::string serialized_proto;
  315. };
  316. using LdsUpdateMap = std::map<std::string /*server_name*/, LdsResourceData>;
  317. struct RdsResourceData {
  318. RdsUpdate resource;
  319. std::string serialized_proto;
  320. };
  321. using RdsUpdateMap =
  322. std::map<std::string /*route_config_name*/, RdsResourceData>;
  323. struct CdsUpdate {
  324. enum ClusterType { EDS, LOGICAL_DNS, AGGREGATE };
  325. ClusterType cluster_type;
  326. // For cluster type EDS.
  327. // The name to use in the EDS request.
  328. // If empty, the cluster name will be used.
  329. std::string eds_service_name;
  330. // Tls Context used by clients
  331. CommonTlsContext common_tls_context;
  332. // The LRS server to use for load reporting.
  333. // If not set, load reporting will be disabled.
  334. // If set to the empty string, will use the same server we obtained the CDS
  335. // data from.
  336. absl::optional<std::string> lrs_load_reporting_server_name;
  337. // The LB policy to use (e.g., "ROUND_ROBIN" or "RING_HASH").
  338. std::string lb_policy;
  339. // Used for RING_HASH LB policy only.
  340. uint64_t min_ring_size = 1024;
  341. uint64_t max_ring_size = 8388608;
  342. enum HashFunction { XX_HASH, MURMUR_HASH_2 };
  343. HashFunction hash_function;
  344. // Maximum number of outstanding requests can be made to the upstream
  345. // cluster.
  346. uint32_t max_concurrent_requests = 1024;
  347. // For cluster type AGGREGATE.
  348. // The prioritized list of cluster names.
  349. std::vector<std::string> prioritized_cluster_names;
  350. bool operator==(const CdsUpdate& other) const {
  351. return cluster_type == other.cluster_type &&
  352. eds_service_name == other.eds_service_name &&
  353. common_tls_context == other.common_tls_context &&
  354. lrs_load_reporting_server_name ==
  355. other.lrs_load_reporting_server_name &&
  356. prioritized_cluster_names == other.prioritized_cluster_names &&
  357. max_concurrent_requests == other.max_concurrent_requests;
  358. }
  359. std::string ToString() const;
  360. };
  361. struct CdsResourceData {
  362. CdsUpdate resource;
  363. std::string serialized_proto;
  364. };
  365. using CdsUpdateMap = std::map<std::string /*cluster_name*/, CdsResourceData>;
  366. struct EdsUpdate {
  367. struct Priority {
  368. struct Locality {
  369. RefCountedPtr<XdsLocalityName> name;
  370. uint32_t lb_weight;
  371. ServerAddressList endpoints;
  372. bool operator==(const Locality& other) const {
  373. return *name == *other.name && lb_weight == other.lb_weight &&
  374. endpoints == other.endpoints;
  375. }
  376. bool operator!=(const Locality& other) const {
  377. return !(*this == other);
  378. }
  379. std::string ToString() const;
  380. };
  381. std::map<XdsLocalityName*, Locality, XdsLocalityName::Less> localities;
  382. bool operator==(const Priority& other) const;
  383. std::string ToString() const;
  384. };
  385. using PriorityList = absl::InlinedVector<Priority, 2>;
  386. // There are two phases of accessing this class's content:
  387. // 1. to initialize in the control plane combiner;
  388. // 2. to use in the data plane combiner.
  389. // So no additional synchronization is needed.
  390. class DropConfig : public RefCounted<DropConfig> {
  391. public:
  392. struct DropCategory {
  393. bool operator==(const DropCategory& other) const {
  394. return name == other.name &&
  395. parts_per_million == other.parts_per_million;
  396. }
  397. std::string name;
  398. const uint32_t parts_per_million;
  399. };
  400. using DropCategoryList = absl::InlinedVector<DropCategory, 2>;
  401. void AddCategory(std::string name, uint32_t parts_per_million) {
  402. drop_category_list_.emplace_back(
  403. DropCategory{std::move(name), parts_per_million});
  404. if (parts_per_million == 1000000) drop_all_ = true;
  405. }
  406. // The only method invoked from outside the WorkSerializer (used in
  407. // the data plane).
  408. bool ShouldDrop(const std::string** category_name) const;
  409. const DropCategoryList& drop_category_list() const {
  410. return drop_category_list_;
  411. }
  412. bool drop_all() const { return drop_all_; }
  413. bool operator==(const DropConfig& other) const {
  414. return drop_category_list_ == other.drop_category_list_;
  415. }
  416. bool operator!=(const DropConfig& other) const {
  417. return !(*this == other);
  418. }
  419. std::string ToString() const;
  420. private:
  421. DropCategoryList drop_category_list_;
  422. bool drop_all_ = false;
  423. };
  424. PriorityList priorities;
  425. RefCountedPtr<DropConfig> drop_config;
  426. bool operator==(const EdsUpdate& other) const {
  427. return priorities == other.priorities &&
  428. *drop_config == *other.drop_config;
  429. }
  430. std::string ToString() const;
  431. };
  432. struct EdsResourceData {
  433. EdsUpdate resource;
  434. std::string serialized_proto;
  435. };
  436. using EdsUpdateMap =
  437. std::map<std::string /*eds_service_name*/, EdsResourceData>;
  438. struct ClusterLoadReport {
  439. XdsClusterDropStats::Snapshot dropped_requests;
  440. std::map<RefCountedPtr<XdsLocalityName>, XdsClusterLocalityStats::Snapshot,
  441. XdsLocalityName::Less>
  442. locality_stats;
  443. grpc_millis load_report_interval;
  444. };
  445. using ClusterLoadReportMap = std::map<
  446. std::pair<std::string /*cluster_name*/, std::string /*eds_service_name*/>,
  447. ClusterLoadReport>;
  448. // The metadata of the xDS resource; used by the xDS config dump.
  449. struct ResourceMetadata {
  450. // Resource status from the view of a xDS client, which tells the
  451. // synchronization status between the xDS client and the xDS server.
  452. enum ClientResourceStatus {
  453. // Client requested this resource but hasn't received any update from
  454. // management server. The client will not fail requests, but will queue
  455. // them
  456. // until update arrives or the client times out waiting for the resource.
  457. REQUESTED = 1,
  458. // This resource has been requested by the client but has either not been
  459. // delivered by the server or was previously delivered by the server and
  460. // then subsequently removed from resources provided by the server.
  461. DOES_NOT_EXIST,
  462. // Client received this resource and replied with ACK.
  463. ACKED,
  464. // Client received this resource and replied with NACK.
  465. NACKED
  466. };
  467. // The client status of this resource.
  468. ClientResourceStatus client_status = REQUESTED;
  469. // The serialized bytes of the last successfully updated raw xDS resource.
  470. std::string serialized_proto;
  471. // The timestamp when the resource was last successfully updated.
  472. grpc_millis update_time = 0;
  473. // The last successfully updated version of the resource.
  474. std::string version;
  475. // The rejected version string of the last failed update attempt.
  476. std::string failed_version;
  477. // Details about the last failed update attempt.
  478. std::string failed_details;
  479. // Timestamp of the last failed update attempt.
  480. grpc_millis failed_update_time = 0;
  481. };
  482. using ResourceMetadataMap =
  483. std::map<absl::string_view /*resource_name*/, const ResourceMetadata*>;
  484. struct ResourceTypeMetadata {
  485. absl::string_view version;
  486. ResourceMetadataMap resource_metadata_map;
  487. };
  488. using ResourceTypeMetadataMap =
  489. std::map<absl::string_view /*type_url*/, ResourceTypeMetadata>;
  490. static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
  491. envoy_admin_v3_REQUESTED) ==
  492. ResourceMetadata::ClientResourceStatus::REQUESTED,
  493. "");
  494. static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
  495. envoy_admin_v3_DOES_NOT_EXIST) ==
  496. ResourceMetadata::ClientResourceStatus::DOES_NOT_EXIST,
  497. "");
  498. static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
  499. envoy_admin_v3_ACKED) ==
  500. ResourceMetadata::ClientResourceStatus::ACKED,
  501. "");
  502. static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
  503. envoy_admin_v3_NACKED) ==
  504. ResourceMetadata::ClientResourceStatus::NACKED,
  505. "");
  506. // If the response can't be parsed at the top level, the resulting
  507. // type_url will be empty.
  508. // If there is any other type of validation error, the parse_error
  509. // field will be set to something other than GRPC_ERROR_NONE and the
  510. // resource_names_failed field will be populated.
  511. // Otherwise, one of the *_update_map fields will be populated, based
  512. // on the type_url field.
  513. struct AdsParseResult {
  514. grpc_error* parse_error = GRPC_ERROR_NONE;
  515. std::string version;
  516. std::string nonce;
  517. std::string type_url;
  518. LdsUpdateMap lds_update_map;
  519. RdsUpdateMap rds_update_map;
  520. CdsUpdateMap cds_update_map;
  521. EdsUpdateMap eds_update_map;
  522. std::set<std::string> resource_names_failed;
  523. };
  524. XdsApi(XdsClient* client, TraceFlag* tracer, const XdsBootstrap::Node* node);
  525. // Creates an ADS request.
  526. // Takes ownership of \a error.
  527. grpc_slice CreateAdsRequest(const XdsBootstrap::XdsServer& server,
  528. const std::string& type_url,
  529. const std::set<absl::string_view>& resource_names,
  530. const std::string& version,
  531. const std::string& nonce, grpc_error* error,
  532. bool populate_node);
  533. // Parses an ADS response.
  534. AdsParseResult ParseAdsResponse(
  535. const XdsBootstrap::XdsServer& server, const grpc_slice& encoded_response,
  536. const std::set<absl::string_view>& expected_listener_names,
  537. const std::set<absl::string_view>& expected_route_configuration_names,
  538. const std::set<absl::string_view>& expected_cluster_names,
  539. const std::set<absl::string_view>& expected_eds_service_names);
  540. // Creates an initial LRS request.
  541. grpc_slice CreateLrsInitialRequest(const XdsBootstrap::XdsServer& server);
  542. // Creates an LRS request sending a client-side load report.
  543. grpc_slice CreateLrsRequest(ClusterLoadReportMap cluster_load_report_map);
  544. // Parses the LRS response and returns \a
  545. // load_reporting_interval for client-side load reporting. If there is any
  546. // error, the output config is invalid.
  547. grpc_error* ParseLrsResponse(const grpc_slice& encoded_response,
  548. bool* send_all_clusters,
  549. std::set<std::string>* cluster_names,
  550. grpc_millis* load_reporting_interval);
  551. // Assemble the client config proto message and return the serialized result.
  552. std::string AssembleClientConfig(
  553. const ResourceTypeMetadataMap& resource_type_metadata_map);
  554. private:
  555. XdsClient* client_;
  556. TraceFlag* tracer_;
  557. const XdsBootstrap::Node* node_; // Do not own.
  558. upb::SymbolTable symtab_;
  559. const std::string build_version_;
  560. const std::string user_agent_name_;
  561. };
  562. } // namespace grpc_core
  563. #endif /* GRPC_CORE_EXT_XDS_XDS_API_H */