Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/api/api.h" 4 : #include "envoy/common/random_generator.h" 5 : #include "envoy/config/core/v3/base.pb.h" 6 : #include "envoy/event/deferred_deletable.h" 7 : #include "envoy/init/manager.h" 8 : #include "envoy/upstream/cluster_manager.h" 9 : 10 : #include "source/common/common/backoff_strategy.h" 11 : #include "source/common/common/empty_string.h" 12 : #include "source/common/common/enum_to_int.h" 13 : #include "source/common/config/remote_data_fetcher.h" 14 : #include "source/common/init/target_impl.h" 15 : 16 : #include "absl/types/optional.h" 17 : 18 : namespace Envoy { 19 : namespace Config { 20 : namespace DataSource { 21 : 22 : /** 23 : * Read contents of the DataSource. 24 : * @param source data source. 25 : * @param allow_empty return an empty string if no DataSource case is specified. 26 : * @param api reference to the Api object 27 : * @param max_size max size limit of file to read, default 0 means no limit, and if the file data 28 : * would exceed the limit, it will throw a EnvoyException. 29 : * @return std::string with DataSource contents. 30 : * @throw EnvoyException if no DataSource case is specified and !allow_empty. 31 : */ 32 : std::string read(const envoy::config::core::v3::DataSource& source, bool allow_empty, Api::Api& api, 33 : uint64_t max_size = 0); 34 : 35 : /** 36 : * @param source data source. 37 : * @return absl::optional<std::string> path to DataSource if a filename, otherwise absl::nullopt. 38 : */ 39 : absl::optional<std::string> getPath(const envoy::config::core::v3::DataSource& source); 40 : 41 : /** 42 : * Callback for async data source. 43 : */ 44 : using AsyncDataSourceCb = std::function<void(const std::string&)>; 45 : 46 : class LocalAsyncDataProvider { 47 : public: 48 : LocalAsyncDataProvider(Init::Manager& manager, const envoy::config::core::v3::DataSource& source, 49 : bool allow_empty, Api::Api& api, AsyncDataSourceCb&& callback) 50 : : init_target_("LocalAsyncDataProvider", [this, &source, allow_empty, &api, callback]() { 51 : callback(DataSource::read(source, allow_empty, api)); 52 : init_target_.ready(); 53 0 : }) { 54 0 : manager.add(init_target_); 55 0 : } 56 : 57 0 : ~LocalAsyncDataProvider() { init_target_.ready(); } 58 : 59 : private: 60 : Init::TargetImpl init_target_; 61 : }; 62 : 63 : using LocalAsyncDataProviderPtr = std::unique_ptr<LocalAsyncDataProvider>; 64 : 65 : class RemoteAsyncDataProvider : public Event::DeferredDeletable, 66 : public Config::DataFetcher::RemoteDataFetcherCallback, 67 : public Logger::Loggable<Logger::Id::config> { 68 : public: 69 : RemoteAsyncDataProvider(Upstream::ClusterManager& cm, Init::Manager& manager, 70 : const envoy::config::core::v3::RemoteDataSource& source, 71 : Event::Dispatcher& dispatcher, Random::RandomGenerator& random, 72 : bool allow_empty, AsyncDataSourceCb&& callback); 73 : 74 0 : ~RemoteAsyncDataProvider() override { 75 0 : init_target_.ready(); 76 0 : if (retry_timer_) { 77 0 : retry_timer_->disableTimer(); 78 0 : } 79 0 : } 80 : 81 : // Config::DataFetcher::RemoteDataFetcherCallback 82 0 : void onSuccess(const std::string& data) override { 83 0 : callback_(data); 84 0 : init_target_.ready(); 85 0 : } 86 : 87 : // Config::DataFetcher::RemoteDataFetcherCallback 88 0 : void onFailure(Config::DataFetcher::FailureReason failure) override { 89 0 : ENVOY_LOG(debug, "Failed to fetch remote data, failure reason: {}", enumToInt(failure)); 90 0 : if (retries_remaining_-- == 0) { 91 0 : ENVOY_LOG(warn, "Retry limit exceeded for fetching data from remote data source."); 92 0 : if (allow_empty_) { 93 0 : callback_(EMPTY_STRING); 94 0 : } 95 : // We need to allow server startup to continue. 96 0 : init_target_.ready(); 97 0 : return; 98 0 : } 99 : 100 0 : const auto retry_ms = std::chrono::milliseconds(backoff_strategy_->nextBackOffMs()); 101 0 : ENVOY_LOG(debug, "Remote data provider will retry in {} ms.", retry_ms.count()); 102 0 : retry_timer_->enableTimer(retry_ms); 103 0 : } 104 : 105 : private: 106 0 : void start() { fetcher_->fetch(); } 107 : 108 : bool allow_empty_; 109 : AsyncDataSourceCb callback_; 110 : const Config::DataFetcher::RemoteDataFetcherPtr fetcher_; 111 : Init::TargetImpl init_target_; 112 : 113 : Event::TimerPtr retry_timer_; 114 : BackOffStrategyPtr backoff_strategy_; 115 : uint32_t retries_remaining_; 116 : }; 117 : 118 : using RemoteAsyncDataProviderPtr = std::unique_ptr<RemoteAsyncDataProvider>; 119 : 120 : } // namespace DataSource 121 : } // namespace Config 122 : } // namespace Envoy