#ifndef GRPC_SRC_CORE_EXT_XDS_XDS_ENDPOINT_H
#define GRPC_SRC_CORE_EXT_XDS_XDS_ENDPOINT_H
#include <grpc/support/port_platform.h>
#include <stdint.h>
#include <algorithm>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/random/random.h"
#include "absl/strings/string_view.h"
#include "envoy/config/endpoint/v3/endpoint.upbdefs.h"
#include "upb/reflection/def.h"
#include "src/core/ext/xds/xds_client.h"
#include "src/core/ext/xds/xds_client_stats.h"
#include "src/core/ext/xds/xds_resource_type.h"
#include "src/core/ext/xds/xds_resource_type_impl.h"
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/resolver/server_address.h"
namespace grpc_core {
struct XdsEndpointResource : public XdsResourceType::ResourceData {
struct Priority {
struct Locality {
RefCountedPtr<XdsLocalityName> name;
uint32_t lb_weight;
ServerAddressList endpoints;
bool operator==(const Locality& other) const {
return *name == *other.name && lb_weight == other.lb_weight &&
endpoints == other.endpoints;
}
bool operator!=(const Locality& other) const { return !(*this == other); }
std::string ToString() const;
};
std::map<XdsLocalityName*, Locality, XdsLocalityName::Less> localities;
bool operator==(const Priority& other) const;
std::string ToString() const;
};
using PriorityList = std::vector<Priority>;
class DropConfig : public RefCounted<DropConfig> {
public:
struct DropCategory {
bool operator==(const DropCategory& other) const {
return name == other.name &&
parts_per_million == other.parts_per_million;
}
std::string name;
const uint32_t parts_per_million;
};
using DropCategoryList = std::vector<DropCategory>;
void AddCategory(std::string name, uint32_t parts_per_million) {
drop_category_list_.emplace_back(
DropCategory{std::move(name), parts_per_million});
if (parts_per_million == 1000000) drop_all_ = true;
}
bool ShouldDrop(const std::string** category_name);
const DropCategoryList& drop_category_list() const {
return drop_category_list_;
}
bool drop_all() const { return drop_all_; }
bool operator==(const DropConfig& other) const {
return drop_category_list_ == other.drop_category_list_;
}
bool operator!=(const DropConfig& other) const { return !(*this == other); }
std::string ToString() const;
private:
DropCategoryList drop_category_list_;
bool drop_all_ = false;
Mutex mu_;
absl::BitGen bit_gen_ ABSL_GUARDED_BY(&mu_);
};
PriorityList priorities;
RefCountedPtr<DropConfig> drop_config;
bool operator==(const XdsEndpointResource& other) const {
return priorities == other.priorities && *drop_config == *other.drop_config;
}
std::string ToString() const;
};
class XdsEndpointResourceType
: public XdsResourceTypeImpl<XdsEndpointResourceType, XdsEndpointResource> {
public:
absl::string_view type_url() const override {
return "envoy.config.endpoint.v3.ClusterLoadAssignment";
}
DecodeResult Decode(const XdsResourceType::DecodeContext& context,
absl::string_view serialized_resource) const override;
void InitUpbSymtab(XdsClient*, upb_DefPool* symtab) const override {
envoy_config_endpoint_v3_ClusterLoadAssignment_getmsgdef(symtab);
}
};
}
#endif