3 * Copyright 2018 gRPC authors.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_API_H
20 #define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_API_H
22 #include <grpc/support/port_platform.h>
28 #include <grpc/slice_buffer.h>
30 #include "src/core/ext/filters/client_channel/server_address.h"
31 #include "src/core/ext/filters/client_channel/xds/xds_bootstrap.h"
32 #include "src/core/ext/filters/client_channel/xds/xds_client_stats.h"
33 #include "src/core/lib/gprpp/optional.h"
37 constexpr char kCdsTypeUrl[] = "type.googleapis.com/envoy.api.v2.Cluster";
38 constexpr char kEdsTypeUrl[] =
39 "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment";
41 // The version state for each specific ADS resource type.
43 // The version of the latest response that is accepted and used.
44 std::string version_info;
45 // The nonce of the latest response.
47 // The error message to be included in a NACK with the nonce. Consumed when a
48 // nonce is NACK'ed for the first time.
49 grpc_error* error = GRPC_ERROR_NONE;
51 ~VersionState() { GRPC_ERROR_UNREF(error); }
55 // The name to use in the EDS request.
56 // If empty, the cluster name will be used.
57 std::string eds_service_name;
58 // The LRS server to use for load reporting.
59 // If not set, load reporting will be disabled.
60 // If set to the empty string, will use the same server we obtained the CDS
62 Optional<std::string> lrs_load_reporting_server_name;
65 using CdsUpdateMap = std::map<std::string /*cluster_name*/, CdsUpdate>;
67 class XdsPriorityListUpdate {
71 bool operator==(const Locality& other) const {
72 return *name == *other.name && serverlist == other.serverlist &&
73 lb_weight == other.lb_weight && priority == other.priority;
76 // This comparator only compares the locality names.
78 bool operator()(const Locality& lhs, const Locality& rhs) const {
79 return XdsLocalityName::Less()(lhs.name, rhs.name);
83 RefCountedPtr<XdsLocalityName> name;
84 ServerAddressList serverlist;
89 bool Contains(const RefCountedPtr<XdsLocalityName>& name) const {
90 return localities.find(name) != localities.end();
93 size_t size() const { return localities.size(); }
95 std::map<RefCountedPtr<XdsLocalityName>, Locality, XdsLocalityName::Less>
99 bool operator==(const XdsPriorityListUpdate& other) const;
100 bool operator!=(const XdsPriorityListUpdate& other) const {
101 return !(*this == other);
104 void Add(LocalityMap::Locality locality);
106 const LocalityMap* Find(uint32_t priority) const;
108 bool Contains(uint32_t priority) const {
109 return priority < priorities_.size();
111 bool Contains(const RefCountedPtr<XdsLocalityName>& name);
113 bool empty() const { return priorities_.empty(); }
114 size_t size() const { return priorities_.size(); }
116 // Callers should make sure the priority list is non-empty.
117 uint32_t LowestPriority() const {
118 return static_cast<uint32_t>(priorities_.size()) - 1;
122 InlinedVector<LocalityMap, 2> priorities_;
125 // There are two phases of accessing this class's content:
126 // 1. to initialize in the control plane combiner;
127 // 2. to use in the data plane combiner.
128 // So no additional synchronization is needed.
129 class XdsDropConfig : public RefCounted<XdsDropConfig> {
131 struct DropCategory {
132 bool operator==(const DropCategory& other) const {
133 return name == other.name && parts_per_million == other.parts_per_million;
137 const uint32_t parts_per_million;
140 using DropCategoryList = InlinedVector<DropCategory, 2>;
142 void AddCategory(std::string name, uint32_t parts_per_million) {
143 drop_category_list_.emplace_back(
144 DropCategory{std::move(name), parts_per_million});
147 // The only method invoked from the data plane combiner.
148 bool ShouldDrop(const std::string** category_name) const;
150 const DropCategoryList& drop_category_list() const {
151 return drop_category_list_;
154 bool operator==(const XdsDropConfig& other) const {
155 return drop_category_list_ == other.drop_category_list_;
157 bool operator!=(const XdsDropConfig& other) const {
158 return !(*this == other);
162 DropCategoryList drop_category_list_;
166 XdsPriorityListUpdate priority_list_update;
167 RefCountedPtr<XdsDropConfig> drop_config;
168 bool drop_all = false;
171 using EdsUpdateMap = std::map<std::string /*eds_service_name*/, EdsUpdate>;
173 // Creates a request to nack an unsupported resource type.
174 // Takes ownership of \a error.
175 grpc_slice XdsUnsupportedTypeNackRequestCreateAndEncode(
176 const std::string& type_url, const std::string& nonce, grpc_error* error);
178 // Creates a CDS request querying \a cluster_names.
179 // Takes ownership of \a error.
180 grpc_slice XdsCdsRequestCreateAndEncode(
181 const std::set<StringView>& cluster_names, const XdsBootstrap::Node* node,
182 const char* build_version, const std::string& version,
183 const std::string& nonce, grpc_error* error);
185 // Creates an EDS request querying \a eds_service_names.
186 // Takes ownership of \a error.
187 grpc_slice XdsEdsRequestCreateAndEncode(
188 const std::set<StringView>& eds_service_names,
189 const XdsBootstrap::Node* node, const char* build_version,
190 const std::string& version, const std::string& nonce, grpc_error* error);
192 // Parses the ADS response and outputs the validated update for either CDS or
193 // EDS. If the response can't be parsed at the top level, \a type_url will point
194 // to an empty string; otherwise, it will point to the received data.
195 grpc_error* XdsAdsResponseDecodeAndParse(
196 const grpc_slice& encoded_response,
197 const std::set<StringView>& expected_eds_service_names,
198 CdsUpdateMap* cds_update_map, EdsUpdateMap* eds_update_map,
199 std::string* version, std::string* nonce, std::string* type_url);
201 // Creates an LRS request querying \a server_name.
202 grpc_slice XdsLrsRequestCreateAndEncode(const std::string& server_name,
203 const XdsBootstrap::Node* node,
204 const char* build_version);
206 // Creates an LRS request sending client-side load reports. If all the counters
207 // are zero, returns empty slice.
208 grpc_slice XdsLrsRequestCreateAndEncode(
209 std::map<StringView /*cluster_name*/, std::set<XdsClientStats*>>
212 // Parses the LRS response and returns \a
213 // load_reporting_interval for client-side load reporting. If there is any
214 // error, the output config is invalid.
215 grpc_error* XdsLrsResponseDecodeAndParse(const grpc_slice& encoded_response,
216 std::set<std::string>* cluster_names,
217 grpc_millis* load_reporting_interval);
219 } // namespace grpc_core
221 #endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_XDS_XDS_API_H */