#pragma once #include "envoy/config/subscription.h" #include "envoy/service/discovery/v3/discovery.pb.h" #include "common/protobuf/utility.h" #include "xds/core/v3/collection_entry.pb.h" namespace Envoy { namespace Config { namespace { std::vector repeatedPtrFieldToVector(const Protobuf::RepeatedPtrField& xs) { std::vector ys; std::copy(xs.begin(), xs.end(), std::back_inserter(ys)); return ys; } } // namespace class DecodedResourceImpl; using DecodedResourceImplPtr = std::unique_ptr; class DecodedResourceImpl : public DecodedResource { public: static DecodedResourceImplPtr fromResource(OpaqueResourceDecoder& resource_decoder, const ProtobufWkt::Any& resource, const std::string& version) { if (resource.Is()) { envoy::service::discovery::v3::Resource r; MessageUtil::unpackTo(resource, r); r.set_version(version); return std::make_unique(resource_decoder, r); } return std::unique_ptr(new DecodedResourceImpl( resource_decoder, absl::nullopt, Protobuf::RepeatedPtrField(), resource, true, version, absl::nullopt)); } DecodedResourceImpl(OpaqueResourceDecoder& resource_decoder, const envoy::service::discovery::v3::Resource& resource) : DecodedResourceImpl(resource_decoder, resource.name(), resource.aliases(), resource.resource(), resource.has_resource(), resource.version(), resource.has_ttl() ? absl::make_optional(std::chrono::milliseconds( DurationUtil::durationToMilliseconds(resource.ttl()))) : absl::nullopt) {} DecodedResourceImpl(OpaqueResourceDecoder& resource_decoder, const xds::core::v3::CollectionEntry::InlineEntry& inline_entry) : DecodedResourceImpl(resource_decoder, inline_entry.name(), Protobuf::RepeatedPtrField(), inline_entry.resource(), true, inline_entry.version(), absl::nullopt) {} DecodedResourceImpl(ProtobufTypes::MessagePtr resource, const std::string& name, const std::vector& aliases, const std::string& version) : resource_(std::move(resource)), has_resource_(true), name_(name), aliases_(aliases), version_(version), ttl_(absl::nullopt) {} // Config::DecodedResource const std::string& name() const override { return name_; } const std::vector& aliases() const override { return aliases_; } const std::string& version() const override { return version_; }; const Protobuf::Message& resource() const override { return *resource_; }; bool hasResource() const override { return has_resource_; } absl::optional ttl() const override { return ttl_; } private: DecodedResourceImpl(OpaqueResourceDecoder& resource_decoder, absl::optional name, const Protobuf::RepeatedPtrField& aliases, const ProtobufWkt::Any& resource, bool has_resource, const std::string& version, absl::optional ttl) : resource_(resource_decoder.decodeResource(resource)), has_resource_(has_resource), name_(name ? *name : resource_decoder.resourceName(*resource_)), aliases_(repeatedPtrFieldToVector(aliases)), version_(version), ttl_(ttl) {} const ProtobufTypes::MessagePtr resource_; const bool has_resource_; const std::string name_; const std::vector aliases_; const std::string version_; // Per resource TTL. const absl::optional ttl_; }; struct DecodedResourcesWrapper { DecodedResourcesWrapper() = default; DecodedResourcesWrapper(OpaqueResourceDecoder& resource_decoder, const Protobuf::RepeatedPtrField& resources, const std::string& version) { for (const auto& resource : resources) { pushBack((DecodedResourceImpl::fromResource(resource_decoder, resource, version))); } } void pushBack(Config::DecodedResourcePtr&& resource) { owned_resources_.push_back(std::move(resource)); refvec_.emplace_back(*owned_resources_.back()); } std::vector owned_resources_; std::vector refvec_; }; } // namespace Config } // namespace Envoy