LCOV - code coverage report
Current view: top level - source/common/runtime - runtime_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 15 16 93.8 %
Date: 2024-01-05 06:35:25 Functions: 4 5 80.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <cstdint>
       4             : #include <memory>
       5             : #include <string>
       6             : 
       7             : #include "envoy/api/api.h"
       8             : #include "envoy/common/exception.h"
       9             : #include "envoy/common/random_generator.h"
      10             : #include "envoy/config/bootstrap/v3/bootstrap.pb.h"
      11             : #include "envoy/config/core/v3/config_source.pb.h"
      12             : #include "envoy/config/subscription.h"
      13             : #include "envoy/init/manager.h"
      14             : #include "envoy/runtime/runtime.h"
      15             : #include "envoy/service/discovery/v3/discovery.pb.h"
      16             : #include "envoy/service/runtime/v3/rtds.pb.h"
      17             : #include "envoy/service/runtime/v3/rtds.pb.validate.h"
      18             : #include "envoy/stats/stats_macros.h"
      19             : #include "envoy/stats/store.h"
      20             : #include "envoy/thread_local/thread_local.h"
      21             : #include "envoy/type/v3/percent.pb.h"
      22             : #include "envoy/upstream/cluster_manager.h"
      23             : 
      24             : #include "source/common/common/assert.h"
      25             : #include "source/common/common/logger.h"
      26             : #include "source/common/common/thread.h"
      27             : #include "source/common/config/subscription_base.h"
      28             : #include "source/common/init/manager_impl.h"
      29             : #include "source/common/init/target_impl.h"
      30             : #include "source/common/singleton/threadsafe_singleton.h"
      31             : 
      32             : #include "absl/container/node_hash_map.h"
      33             : #include "spdlog/spdlog.h"
      34             : 
      35             : namespace Envoy {
      36             : namespace Runtime {
      37             : 
      38             : using RuntimeSingleton = ThreadSafeSingleton<Loader>;
      39             : 
      40             : /**
      41             :  * All runtime stats. @see stats_macros.h
      42             :  */
      43             : #define ALL_RUNTIME_STATS(COUNTER, GAUGE)                                                          \
      44        1145 :   COUNTER(deprecated_feature_use)                                                                  \
      45        1145 :   COUNTER(load_error)                                                                              \
      46        1145 :   COUNTER(load_success)                                                                            \
      47        1145 :   COUNTER(override_dir_exists)                                                                     \
      48        1145 :   COUNTER(override_dir_not_exists)                                                                 \
      49        1145 :   GAUGE(admin_overrides_active, NeverImport)                                                       \
      50        1145 :   GAUGE(deprecated_feature_seen_since_process_start, NeverImport)                                  \
      51        1145 :   GAUGE(num_keys, NeverImport)                                                                     \
      52        1145 :   GAUGE(num_layers, NeverImport)
      53             : 
      54             : /**
      55             :  * Struct definition for all runtime stats. @see stats_macros.h
      56             :  */
      57             : struct RuntimeStats {
      58             :   ALL_RUNTIME_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT)
      59             : };
      60             : 
      61             : /**
      62             :  * Implementation of Snapshot whose source is the vector of layers passed to the constructor.
      63             :  */
      64             : class SnapshotImpl : public Snapshot, Logger::Loggable<Logger::Id::runtime> {
      65             : public:
      66             :   SnapshotImpl(Random::RandomGenerator& generator, RuntimeStats& stats,
      67             :                std::vector<OverrideLayerConstPtr>&& layers);
      68             : 
      69             :   // Runtime::Snapshot
      70             :   bool deprecatedFeatureEnabled(absl::string_view key, bool default_value) const override;
      71             :   bool runtimeFeatureEnabled(absl::string_view key) const override;
      72             :   bool featureEnabled(absl::string_view key, uint64_t default_value, uint64_t random_value,
      73             :                       uint64_t num_buckets) const override;
      74             :   bool featureEnabled(absl::string_view key, uint64_t default_value) const override;
      75             :   bool featureEnabled(absl::string_view key, uint64_t default_value,
      76             :                       uint64_t random_value) const override;
      77             :   bool featureEnabled(absl::string_view key,
      78             :                       const envoy::type::v3::FractionalPercent& default_value) const override;
      79             :   bool featureEnabled(absl::string_view key,
      80             :                       const envoy::type::v3::FractionalPercent& default_value,
      81             :                       uint64_t random_value) const override;
      82             :   ConstStringOptRef get(absl::string_view key) const override;
      83             :   uint64_t getInteger(absl::string_view key, uint64_t default_value) const override;
      84             :   double getDouble(absl::string_view key, double default_value) const override;
      85             :   bool getBoolean(absl::string_view key, bool value) const override;
      86             :   const std::vector<OverrideLayerConstPtr>& getLayers() const override;
      87             : 
      88             :   const EntryMap& values() const;
      89             : 
      90             :   static Entry createEntry(const ProtobufWkt::Value& value, absl::string_view raw_string,
      91             :                            const char*& error_message);
      92             :   static void addEntry(Snapshot::EntryMap& values, const std::string& key,
      93             :                        const ProtobufWkt::Value& value, absl::string_view raw_string = "");
      94             : 
      95             : private:
      96             :   const std::vector<OverrideLayerConstPtr> layers_;
      97             :   EntryMap values_;
      98             :   Random::RandomGenerator& generator_;
      99             :   RuntimeStats& stats_;
     100             : };
     101             : 
     102             : using SnapshotImplPtr = std::unique_ptr<SnapshotImpl>;
     103             : 
     104             : /**
     105             :  * Base implementation of OverrideLayer that by itself provides an empty values map.
     106             :  */
     107             : class OverrideLayerImpl : public Snapshot::OverrideLayer {
     108             : public:
     109        2879 :   explicit OverrideLayerImpl(absl::string_view name) : name_{name} {}
     110        3435 :   const Snapshot::EntryMap& values() const override { return values_; }
     111           0 :   const std::string& name() const override { return name_; }
     112             : 
     113             : protected:
     114             :   Snapshot::EntryMap values_;
     115             :   const std::string name_;
     116             : };
     117             : 
     118             : /**
     119             :  * Extension of OverrideLayerImpl that maintains an in-memory set of values. These values can be
     120             :  * modified programmatically via mergeValues(). AdminLayer is so named because it can be accessed
     121             :  * and manipulated by Envoy's admin interface.
     122             :  */
     123             : class AdminLayer : public OverrideLayerImpl {
     124             : public:
     125             :   explicit AdminLayer(absl::string_view name, RuntimeStats& stats)
     126        2780 :       : OverrideLayerImpl{name}, stats_{stats} {}
     127             :   /**
     128             :    * Copy-constructible so that it can snapshotted.
     129             :    */
     130        1668 :   AdminLayer(const AdminLayer& admin_layer) : AdminLayer{admin_layer.name_, admin_layer.stats_} {
     131        1668 :     values_ = admin_layer.values();
     132        1668 :   }
     133             : 
     134             :   /**
     135             :    * Merge the provided values into our entry map. An empty value indicates that a key should be
     136             :    * removed from our map.
     137             :    */
     138             :   void mergeValues(const absl::node_hash_map<std::string, std::string>& values);
     139             : 
     140             : private:
     141             :   RuntimeStats& stats_;
     142             : };
     143             : 
     144             : using AdminLayerPtr = std::unique_ptr<AdminLayer>;
     145             : 
     146             : /**
     147             :  * Extension of OverrideLayerImpl that loads values from the file system upon construction.
     148             :  */
     149             : class DiskLayer : public OverrideLayerImpl, Logger::Loggable<Logger::Id::runtime> {
     150             : public:
     151             :   DiskLayer(absl::string_view name, const std::string& path, Api::Api& api);
     152             : 
     153             : private:
     154             :   void walkDirectory(const std::string& path, const std::string& prefix, uint32_t depth,
     155             :                      Api::Api& api);
     156             : 
     157             :   const std::string path_;
     158             :   const Filesystem::WatcherPtr watcher_;
     159             : };
     160             : 
     161             : /**
     162             :  * Extension of OverrideLayerImpl that loads values from a proto Struct representation.
     163             :  */
     164             : class ProtoLayer : public OverrideLayerImpl, Logger::Loggable<Logger::Id::runtime> {
     165             : public:
     166             :   ProtoLayer(absl::string_view name, const ProtobufWkt::Struct& proto);
     167             : 
     168             : private:
     169             :   void walkProtoValue(const ProtobufWkt::Value& v, const std::string& prefix);
     170             : };
     171             : 
     172             : class LoaderImpl;
     173             : 
     174             : struct RtdsSubscription : Envoy::Config::SubscriptionBase<envoy::service::runtime::v3::Runtime>,
     175             :                           Logger::Loggable<Logger::Id::runtime> {
     176             :   RtdsSubscription(LoaderImpl& parent,
     177             :                    const envoy::config::bootstrap::v3::RuntimeLayer::RtdsLayer& rtds_layer,
     178             :                    Stats::Store& store, ProtobufMessage::ValidationVisitor& validation_visitor);
     179             : 
     180             :   // Config::SubscriptionCallbacks
     181             :   absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& resources,
     182             :                               const std::string& version_info) override;
     183             :   absl::Status onConfigUpdate(const std::vector<Config::DecodedResourceRef>& added_resources,
     184             :                               const Protobuf::RepeatedPtrField<std::string>& removed_resources,
     185             :                               const std::string&) override;
     186             : 
     187             :   void onConfigUpdateFailed(Envoy::Config::ConfigUpdateFailureReason reason,
     188             :                             const EnvoyException* e) override;
     189             : 
     190             :   void start();
     191             :   absl::Status validateUpdateSize(uint32_t added_resources_num, uint32_t removed_resources_num);
     192             :   absl::Status onConfigRemoved(const Protobuf::RepeatedPtrField<std::string>& removed_resources);
     193             :   void createSubscription();
     194             : 
     195             :   LoaderImpl& parent_;
     196             :   const envoy::config::core::v3::ConfigSource config_source_;
     197             :   Stats::Store& store_;
     198             :   Stats::ScopeSharedPtr stats_scope_;
     199             :   Config::SubscriptionPtr subscription_;
     200             :   std::string resource_name_;
     201             :   Init::TargetImpl init_target_;
     202             :   ProtobufWkt::Struct proto_;
     203             : };
     204             : 
     205             : using RtdsSubscriptionPtr = std::unique_ptr<RtdsSubscription>;
     206             : 
     207             : /**
     208             :  * Implementation of Loader that provides Snapshots of values added via mergeValues().
     209             :  * A single snapshot is shared among all threads and referenced by shared_ptr such that
     210             :  * a new runtime can be swapped in by the main thread while workers are still using the previous
     211             :  * version.
     212             :  */
     213             : class LoaderImpl : public Loader, Logger::Loggable<Logger::Id::runtime> {
     214             : public:
     215             :   LoaderImpl(Event::Dispatcher& dispatcher, ThreadLocal::SlotAllocator& tls,
     216             :              const envoy::config::bootstrap::v3::LayeredRuntime& config,
     217             :              const LocalInfo::LocalInfo& local_info, Stats::Store& store,
     218             :              Random::RandomGenerator& generator,
     219             :              ProtobufMessage::ValidationVisitor& validation_visitor, Api::Api& api);
     220             : 
     221             :   // Runtime::Loader
     222             :   void initialize(Upstream::ClusterManager& cm) override;
     223             :   const Snapshot& snapshot() override;
     224             :   SnapshotConstSharedPtr threadsafeSnapshot() override;
     225             :   void mergeValues(const absl::node_hash_map<std::string, std::string>& values) override;
     226             :   void startRtdsSubscriptions(ReadyCallback on_done) override;
     227             :   Stats::Scope& getRootScope() override;
     228             :   void countDeprecatedFeatureUse() const override;
     229             : 
     230             : private:
     231             :   friend RtdsSubscription;
     232             : 
     233             :   // Create a new Snapshot
     234             :   SnapshotImplPtr createNewSnapshot();
     235             :   // Load a new Snapshot into TLS
     236             :   void loadNewSnapshot();
     237             :   RuntimeStats generateStats(Stats::Store& store);
     238             :   void onRtdsReady();
     239             : 
     240             :   Random::RandomGenerator& generator_;
     241             :   RuntimeStats stats_;
     242             :   AdminLayerPtr admin_layer_;
     243             :   ThreadLocal::SlotPtr tls_;
     244             :   const envoy::config::bootstrap::v3::LayeredRuntime config_;
     245             :   const std::string service_cluster_;
     246             :   Filesystem::WatcherPtr watcher_;
     247             :   Api::Api& api_;
     248             :   ReadyCallback on_rtds_initialized_;
     249             :   Init::WatcherImpl init_watcher_;
     250             :   Init::ManagerImpl init_manager_{"RTDS"};
     251             :   std::vector<RtdsSubscriptionPtr> subscriptions_;
     252             :   Upstream::ClusterManager* cm_{};
     253             :   Stats::Store& store_;
     254             : 
     255             :   absl::Mutex snapshot_mutex_;
     256             :   SnapshotConstSharedPtr thread_safe_snapshot_ ABSL_GUARDED_BY(snapshot_mutex_);
     257             : };
     258             : 
     259             : } // namespace Runtime
     260             : } // namespace Envoy

Generated by: LCOV version 1.15