LCOV - code coverage report
Current view: top level - source/common/config - metadata.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 9 26 34.6 %
Date: 2024-01-05 06:35:25 Functions: 9 16 56.2 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <memory>
       4             : #include <string>
       5             : 
       6             : #include "envoy/config/core/v3/base.pb.h"
       7             : #include "envoy/config/typed_metadata.h"
       8             : #include "envoy/event/dispatcher.h"
       9             : #include "envoy/registry/registry.h"
      10             : #include "envoy/singleton/manager.h"
      11             : #include "envoy/type/metadata/v3/metadata.pb.h"
      12             : 
      13             : #include "source/common/protobuf/protobuf.h"
      14             : #include "source/common/shared_pool/shared_pool.h"
      15             : 
      16             : #include "absl/container/node_hash_map.h"
      17             : 
      18             : namespace Envoy {
      19             : namespace Config {
      20             : 
      21             : using ConstMetadataSharedPoolSharedPtr =
      22             :     std::shared_ptr<SharedPool::ObjectSharedPool<const envoy::config::core::v3::Metadata,
      23             :                                                  MessageUtil, MessageUtil>>;
      24             : 
      25             : /**
      26             :  * MetadataKey presents the key name and path to retrieve value from metadata.
      27             :  */
      28             : struct MetadataKey {
      29             :   std::string key_;
      30             :   std::vector<std::string> path_;
      31             : 
      32             :   MetadataKey(const envoy::type::metadata::v3::MetadataKey& metadata_key);
      33             : };
      34             : 
      35             : /**
      36             :  * Config metadata helpers.
      37             :  */
      38             : class Metadata {
      39             : public:
      40             :   /**
      41             :    * Lookup value of a key for a given filter in Metadata.
      42             :    * @param metadata reference.
      43             :    * @param filter name.
      44             :    * @param key for filter metadata.
      45             :    * @return const ProtobufWkt::Value& value if found, empty if not found.
      46             :    */
      47             :   static const ProtobufWkt::Value& metadataValue(const envoy::config::core::v3::Metadata* metadata,
      48             :                                                  const std::string& filter, const std::string& key);
      49             :   /**
      50             :    * Lookup value by a multi-key path for a given filter in Metadata. If path is empty
      51             :    * will return the empty struct.
      52             :    * @param metadata reference.
      53             :    * @param filter name.
      54             :    * @param path multi-key path.
      55             :    * @return const ProtobufWkt::Value& value if found, empty if not found.
      56             :    */
      57             :   static const ProtobufWkt::Value& metadataValue(const envoy::config::core::v3::Metadata* metadata,
      58             :                                                  const std::string& filter,
      59             :                                                  const std::vector<std::string>& path);
      60             :   /**
      61             :    * Lookup the value by a metadata key from a Metadata.
      62             :    * @param metadata reference.
      63             :    * @param metadata_key with key name and path to retrieve the value.
      64             :    * @return const ProtobufWkt::Value& value if found, empty if not found.
      65             :    */
      66             :   static const ProtobufWkt::Value& metadataValue(const envoy::config::core::v3::Metadata* metadata,
      67             :                                                  const MetadataKey& metadata_key);
      68             : 
      69             :   /**
      70             :    * Obtain mutable reference to metadata value for a given filter and key.
      71             :    * @param metadata reference.
      72             :    * @param filter name.
      73             :    * @param key for filter metadata.
      74             :    * @return ProtobufWkt::Value&. A Value message is created if not found.
      75             :    */
      76             :   static ProtobufWkt::Value& mutableMetadataValue(envoy::config::core::v3::Metadata& metadata,
      77             :                                                   const std::string& filter,
      78             :                                                   const std::string& key);
      79             : 
      80             :   using LabelSet = std::vector<std::pair<std::string, ProtobufWkt::Value>>;
      81             : 
      82             :   /**
      83             :    * Returns whether a set of the labels match a particular host's metadata.
      84             :    * @param label_set the target label key/value pair set.
      85             :    * @param host_metadata a given host's metadata.
      86             :    * @param filter_key identifies the entry in the metadata entry for the match.
      87             :    * @param list_as_any if the metadata value entry is a list, and any one of
      88             :    * the element equals to the input label_set, it's considered as match.
      89             :    */
      90             :   static bool metadataLabelMatch(const LabelSet& label_set,
      91             :                                  const envoy::config::core::v3::Metadata* host_metadata,
      92             :                                  const std::string& filter_key, bool list_as_any);
      93             :   /**
      94             :    * Returns an ObjectSharedPool to store const Metadata
      95             :    * @param manager used to create singleton
      96             :    * @param dispatcher the dispatcher object reference to the thread that created the
      97             :    * ObjectSharedPool
      98             :    */
      99             :   static ConstMetadataSharedPoolSharedPtr getConstMetadataSharedPool(Singleton::Manager& manager,
     100             :                                                                      Event::Dispatcher& dispatcher);
     101             : };
     102             : 
     103             : template <typename factoryClass> class TypedMetadataImpl : public TypedMetadata {
     104             : public:
     105             :   static_assert(std::is_base_of<Config::TypedMetadataFactory, factoryClass>::value,
     106             :                 "Factory type must be inherited from Envoy::Config::TypedMetadataFactory.");
     107         494 :   TypedMetadataImpl(const envoy::config::core::v3::Metadata& metadata) { populateFrom(metadata); }
     108             : 
     109           0 :   const TypedMetadata::Object* getData(const std::string& key) const override {
     110           0 :     const auto& it = data_.find(key);
     111           0 :     return it == data_.end() ? nullptr : it->second.get();
     112           0 :   }
     113             : 
     114             : protected:
     115             :   /* Attempt to run each of the registered factories for TypedMetadata, to
     116             :    * populate the data_ map.
     117             :    */
     118         494 :   void populateFrom(const envoy::config::core::v3::Metadata& metadata) {
     119         494 :     auto& data_by_key = metadata.filter_metadata();
     120         494 :     auto& typed_data_by_key = metadata.typed_filter_metadata();
     121         494 :     for (const auto& [factory_name, factory] :
     122         494 :          Registry::FactoryRegistry<factoryClass>::factories()) {
     123           0 :       const auto& typed_meta_iter = typed_data_by_key.find(factory_name);
     124             :       // If the key exists in Any metadata, and parse() does not return nullptr,
     125             :       // populate data_.
     126           0 :       if (typed_meta_iter != typed_data_by_key.end()) {
     127           0 :         auto result = factory->parse(typed_meta_iter->second);
     128           0 :         if (result != nullptr) {
     129           0 :           data_[factory->name()] = std::move(result);
     130           0 :           continue;
     131           0 :         }
     132           0 :       }
     133             :       // Fall back cases to parsing Struct metadata and populate data_.
     134           0 :       const auto& meta_iter = data_by_key.find(factory_name);
     135           0 :       if (meta_iter != data_by_key.end()) {
     136           0 :         data_[factory->name()] = factory->parse(meta_iter->second);
     137           0 :       }
     138           0 :     }
     139         494 :   }
     140             : 
     141             :   absl::node_hash_map<std::string, std::unique_ptr<const TypedMetadata::Object>> data_;
     142             : };
     143             : 
     144             : // MetadataPack is struct that contains both the proto and typed metadata.
     145             : template <class FactoryClass> struct MetadataPack {
     146             :   MetadataPack(const envoy::config::core::v3::Metadata& metadata)
     147         192 :       : proto_metadata_(metadata), typed_metadata_(proto_metadata_) {}
     148         246 :   MetadataPack() : proto_metadata_(), typed_metadata_(proto_metadata_) {}
     149             : 
     150             :   const envoy::config::core::v3::Metadata proto_metadata_;
     151             :   const TypedMetadataImpl<FactoryClass> typed_metadata_;
     152             : };
     153             : 
     154             : template <class FactoryClass> using MetadataPackPtr = std::unique_ptr<MetadataPack<FactoryClass>>;
     155             : template <class FactoryClass>
     156             : using MetadataPackSharedPtr = std::shared_ptr<MetadataPack<FactoryClass>>;
     157             : 
     158             : } // namespace Config
     159             : } // namespace Envoy

Generated by: LCOV version 1.15