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_ENDPOINT_H 18 #define GRPC_SRC_CORE_EXT_XDS_XDS_ENDPOINT_H 19 20 #include <grpc/support/port_platform.h> 21 22 #include <stdint.h> 23 24 #include <algorithm> 25 #include <map> 26 #include <memory> 27 #include <string> 28 #include <utility> 29 #include <vector> 30 31 #include "absl/base/thread_annotations.h" 32 #include "absl/random/random.h" 33 #include "absl/strings/string_view.h" 34 #include "envoy/config/endpoint/v3/endpoint.upbdefs.h" 35 #include "upb/reflection/def.h" 36 37 #include "src/core/ext/xds/xds_client.h" 38 #include "src/core/ext/xds/xds_client_stats.h" 39 #include "src/core/ext/xds/xds_resource_type.h" 40 #include "src/core/ext/xds/xds_resource_type_impl.h" 41 #include "src/core/lib/gprpp/ref_counted.h" 42 #include "src/core/lib/gprpp/ref_counted_ptr.h" 43 #include "src/core/lib/gprpp/sync.h" 44 #include "src/core/lib/resolver/server_address.h" 45 46 namespace grpc_core { 47 48 struct XdsEndpointResource : public XdsResourceType::ResourceData { 49 struct Priority { 50 struct Locality { 51 RefCountedPtr<XdsLocalityName> name; 52 uint32_t lb_weight; 53 ServerAddressList endpoints; 54 55 bool operator==(const Locality& other) const { 56 return *name == *other.name && lb_weight == other.lb_weight && 57 endpoints == other.endpoints; 58 } 59 bool operator!=(const Locality& other) const { return !(*this == other); } 60 std::string ToString() const; 61 }; 62 63 std::map<XdsLocalityName*, Locality, XdsLocalityName::Less> localities; 64 65 bool operator==(const Priority& other) const; 66 std::string ToString() const; 67 }; 68 using PriorityList = std::vector<Priority>; 69 70 // There are two phases of accessing this class's content: 71 // 1. to initialize in the control plane combiner; 72 // 2. to use in the data plane combiner. 73 // So no additional synchronization is needed. 74 class DropConfig : public RefCounted<DropConfig> { 75 public: 76 struct DropCategory { 77 bool operator==(const DropCategory& other) const { 78 return name == other.name && 79 parts_per_million == other.parts_per_million; 80 } 81 82 std::string name; 83 const uint32_t parts_per_million; 84 }; 85 86 using DropCategoryList = std::vector<DropCategory>; 87 AddCategoryXdsEndpointResource88 void AddCategory(std::string name, uint32_t parts_per_million) { 89 drop_category_list_.emplace_back( 90 DropCategory{std::move(name), parts_per_million}); 91 if (parts_per_million == 1000000) drop_all_ = true; 92 } 93 94 // The only method invoked from outside the WorkSerializer (used in 95 // the data plane). 96 bool ShouldDrop(const std::string** category_name); 97 drop_category_listXdsEndpointResource98 const DropCategoryList& drop_category_list() const { 99 return drop_category_list_; 100 } 101 drop_allXdsEndpointResource102 bool drop_all() const { return drop_all_; } 103 104 bool operator==(const DropConfig& other) const { 105 return drop_category_list_ == other.drop_category_list_; 106 } 107 bool operator!=(const DropConfig& other) const { return !(*this == other); } 108 109 std::string ToString() const; 110 111 private: 112 DropCategoryList drop_category_list_; 113 bool drop_all_ = false; 114 115 // TODO(roth): Consider using a separate thread-local BitGen for each CPU 116 // to avoid the need for this mutex. 117 Mutex mu_; 118 absl::BitGen bit_gen_ ABSL_GUARDED_BY(&mu_); 119 }; 120 121 PriorityList priorities; 122 RefCountedPtr<DropConfig> drop_config; 123 124 bool operator==(const XdsEndpointResource& other) const { 125 return priorities == other.priorities && *drop_config == *other.drop_config; 126 } 127 std::string ToString() const; 128 }; 129 130 class XdsEndpointResourceType 131 : public XdsResourceTypeImpl<XdsEndpointResourceType, XdsEndpointResource> { 132 public: type_url()133 absl::string_view type_url() const override { 134 return "envoy.config.endpoint.v3.ClusterLoadAssignment"; 135 } 136 137 DecodeResult Decode(const XdsResourceType::DecodeContext& context, 138 absl::string_view serialized_resource) const override; 139 InitUpbSymtab(XdsClient *,upb_DefPool * symtab)140 void InitUpbSymtab(XdsClient*, upb_DefPool* symtab) const override { 141 envoy_config_endpoint_v3_ClusterLoadAssignment_getmsgdef(symtab); 142 } 143 }; 144 145 } // namespace grpc_core 146 147 #endif // GRPC_SRC_CORE_EXT_XDS_XDS_ENDPOINT_H 148