xref: /aosp_15_r20/external/grpc-grpc/src/core/ext/xds/xds_api.h (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 // Copyright 2018 gRPC authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #ifndef GRPC_SRC_CORE_EXT_XDS_XDS_API_H
18 #define GRPC_SRC_CORE_EXT_XDS_XDS_API_H
19 
20 #include <grpc/support/port_platform.h>
21 
22 #include <stddef.h>
23 
24 #include <map>
25 #include <set>
26 #include <string>
27 #include <utility>
28 #include <vector>
29 
30 #include "absl/status/status.h"
31 #include "absl/strings/string_view.h"
32 #include "envoy/admin/v3/config_dump_shared.upb.h"
33 #include "envoy/service/status/v3/csds.upb.h"
34 #include "upb/mem/arena.h"
35 #include "upb/reflection/def.hpp"
36 
37 #include "src/core/ext/xds/xds_bootstrap.h"
38 #include "src/core/ext/xds/xds_client_stats.h"
39 #include "src/core/lib/debug/trace.h"
40 #include "src/core/lib/gprpp/ref_counted_ptr.h"
41 #include "src/core/lib/gprpp/time.h"
42 
43 namespace grpc_core {
44 
45 class XdsClient;
46 
47 // TODO(roth): When we have time, split this into multiple pieces:
48 // - ADS request/response handling
49 // - LRS request/response handling
50 // - CSDS response generation
51 class XdsApi final {
52  public:
53   // Interface defined by caller and passed to ParseAdsResponse().
54   class AdsResponseParserInterface {
55    public:
56     struct AdsResponseFields {
57       std::string type_url;
58       std::string version;
59       std::string nonce;
60       size_t num_resources;
61     };
62 
63     virtual ~AdsResponseParserInterface() = default;
64 
65     // Called when the top-level ADS fields are parsed.
66     // If this returns non-OK, parsing will stop, and the individual
67     // resources will not be processed.
68     virtual absl::Status ProcessAdsResponseFields(AdsResponseFields fields) = 0;
69 
70     // Called to parse each individual resource in the ADS response.
71     // Note that resource_name is non-empty only when the resource was
72     // wrapped in a Resource wrapper proto.
73     virtual void ParseResource(upb_Arena* arena, size_t idx,
74                                absl::string_view type_url,
75                                absl::string_view resource_name,
76                                absl::string_view serialized_resource) = 0;
77 
78     // Called when a resource is wrapped in a Resource wrapper proto but
79     // we fail to parse the Resource wrapper.
80     virtual void ResourceWrapperParsingFailed(size_t idx,
81                                               absl::string_view message) = 0;
82   };
83 
84   struct ClusterLoadReport {
85     XdsClusterDropStats::Snapshot dropped_requests;
86     std::map<RefCountedPtr<XdsLocalityName>, XdsClusterLocalityStats::Snapshot,
87              XdsLocalityName::Less>
88         locality_stats;
89     Duration load_report_interval;
90   };
91   using ClusterLoadReportMap = std::map<
92       std::pair<std::string /*cluster_name*/, std::string /*eds_service_name*/>,
93       ClusterLoadReport>;
94 
95   // The metadata of the xDS resource; used by the xDS config dump.
96   struct ResourceMetadata {
97     // Resource status from the view of a xDS client, which tells the
98     // synchronization status between the xDS client and the xDS server.
99     enum ClientResourceStatus {
100       // Client requested this resource but hasn't received any update from
101       // management server. The client will not fail requests, but will queue
102       // them
103       // until update arrives or the client times out waiting for the resource.
104       REQUESTED = 1,
105       // This resource has been requested by the client but has either not been
106       // delivered by the server or was previously delivered by the server and
107       // then subsequently removed from resources provided by the server.
108       DOES_NOT_EXIST,
109       // Client received this resource and replied with ACK.
110       ACKED,
111       // Client received this resource and replied with NACK.
112       NACKED
113     };
114 
115     // The client status of this resource.
116     ClientResourceStatus client_status = REQUESTED;
117     // The serialized bytes of the last successfully updated raw xDS resource.
118     std::string serialized_proto;
119     // The timestamp when the resource was last successfully updated.
120     Timestamp update_time;
121     // The last successfully updated version of the resource.
122     std::string version;
123     // The rejected version string of the last failed update attempt.
124     std::string failed_version;
125     // Details about the last failed update attempt.
126     std::string failed_details;
127     // Timestamp of the last failed update attempt.
128     Timestamp failed_update_time;
129   };
130   static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
131                     envoy_admin_v3_REQUESTED) ==
132                     ResourceMetadata::ClientResourceStatus::REQUESTED,
133                 "");
134   static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
135                     envoy_admin_v3_DOES_NOT_EXIST) ==
136                     ResourceMetadata::ClientResourceStatus::DOES_NOT_EXIST,
137                 "");
138   static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
139                     envoy_admin_v3_ACKED) ==
140                     ResourceMetadata::ClientResourceStatus::ACKED,
141                 "");
142   static_assert(static_cast<ResourceMetadata::ClientResourceStatus>(
143                     envoy_admin_v3_NACKED) ==
144                     ResourceMetadata::ClientResourceStatus::NACKED,
145                 "");
146 
147   XdsApi(XdsClient* client, TraceFlag* tracer, const XdsBootstrap::Node* node,
148          upb::DefPool* def_pool, std::string user_agent_name,
149          std::string user_agent_version);
150 
151   // Creates an ADS request.
152   std::string CreateAdsRequest(absl::string_view type_url,
153                                absl::string_view version,
154                                absl::string_view nonce,
155                                const std::vector<std::string>& resource_names,
156                                absl::Status status, bool populate_node);
157 
158   // Returns non-OK when failing to deserialize response message.
159   // Otherwise, all events are reported to the parser.
160   absl::Status ParseAdsResponse(absl::string_view encoded_response,
161                                 AdsResponseParserInterface* parser);
162 
163   // Creates an initial LRS request.
164   std::string CreateLrsInitialRequest();
165 
166   // Creates an LRS request sending a client-side load report.
167   std::string CreateLrsRequest(ClusterLoadReportMap cluster_load_report_map);
168 
169   // Parses the LRS response and populates send_all_clusters,
170   // cluster_names, and load_reporting_interval.
171   absl::Status ParseLrsResponse(absl::string_view encoded_response,
172                                 bool* send_all_clusters,
173                                 std::set<std::string>* cluster_names,
174                                 Duration* load_reporting_interval);
175 
176   void PopulateNode(envoy_config_core_v3_Node* node_msg, upb_Arena* arena);
177 
178  private:
179   XdsClient* client_;
180   TraceFlag* tracer_;
181   const XdsBootstrap::Node* node_;  // Do not own.
182   upb::DefPool* def_pool_;          // Do not own.
183   const std::string user_agent_name_;
184   const std::string user_agent_version_;
185 };
186 
187 }  // namespace grpc_core
188 
189 #endif  // GRPC_SRC_CORE_EXT_XDS_XDS_API_H
190