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