/proc/self/cwd/source/common/config/datasource.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "source/common/config/datasource.h" |
2 | | |
3 | | #include "envoy/config/core/v3/base.pb.h" |
4 | | |
5 | | #include "source/common/config/utility.h" |
6 | | |
7 | | #include "fmt/format.h" |
8 | | |
9 | | namespace Envoy { |
10 | | namespace Config { |
11 | | namespace DataSource { |
12 | | |
13 | | // Default Parameters of the jittered backoff strategy. |
14 | | static constexpr uint32_t RetryInitialDelayMilliseconds = 1000; |
15 | | static constexpr uint32_t RetryMaxDelayMilliseconds = 10 * 1000; |
16 | | static constexpr uint32_t RetryCount = 1; |
17 | | |
18 | | std::string read(const envoy::config::core::v3::DataSource& source, bool allow_empty, Api::Api& api, |
19 | 14.1k | uint64_t max_size) { |
20 | 14.1k | std::string data; |
21 | 14.1k | absl::StatusOr<std::string> file_or_error; |
22 | 14.1k | switch (source.specifier_case()) { |
23 | 140 | case envoy::config::core::v3::DataSource::SpecifierCase::kFilename: |
24 | 140 | if (max_size > 0) { |
25 | 36 | if (!api.fileSystem().fileExists(source.filename())) { |
26 | 36 | throwEnvoyExceptionOrPanic(fmt::format("file {} does not exist", source.filename())); |
27 | 36 | } |
28 | 0 | const ssize_t size = api.fileSystem().fileSize(source.filename()); |
29 | 0 | if (size < 0) { |
30 | 0 | throwEnvoyExceptionOrPanic( |
31 | 0 | absl::StrCat("cannot determine size of file ", source.filename())); |
32 | 0 | } |
33 | 0 | if (static_cast<uint64_t>(size) > max_size) { |
34 | 0 | throwEnvoyExceptionOrPanic(fmt::format("file {} size is {} bytes; maximum is {}", |
35 | 0 | source.filename(), size, max_size)); |
36 | 0 | } |
37 | 0 | } |
38 | 104 | file_or_error = api.fileSystem().fileReadToEnd(source.filename()); |
39 | 104 | THROW_IF_STATUS_NOT_OK(file_or_error, throw); |
40 | 49 | data = file_or_error.value(); |
41 | 49 | break; |
42 | 2.08k | case envoy::config::core::v3::DataSource::SpecifierCase::kInlineBytes: |
43 | 2.08k | data = source.inline_bytes(); |
44 | 2.08k | break; |
45 | 1.47k | case envoy::config::core::v3::DataSource::SpecifierCase::kInlineString: |
46 | 1.47k | data = source.inline_string(); |
47 | 1.47k | break; |
48 | 126 | case envoy::config::core::v3::DataSource::SpecifierCase::kEnvironmentVariable: { |
49 | 126 | const char* environment_variable = std::getenv(source.environment_variable().c_str()); |
50 | 126 | if (environment_variable == nullptr) { |
51 | 71 | throwEnvoyExceptionOrPanic( |
52 | 71 | fmt::format("Environment variable doesn't exist: {}", source.environment_variable())); |
53 | 71 | } |
54 | 55 | data = environment_variable; |
55 | 55 | break; |
56 | 126 | } |
57 | 10.3k | default: |
58 | 10.3k | if (!allow_empty) { |
59 | 0 | throwEnvoyExceptionOrPanic( |
60 | 0 | fmt::format("Unexpected DataSource::specifier_case(): {}", source.specifier_case())); |
61 | 0 | } |
62 | 14.1k | } |
63 | 13.9k | if (!allow_empty && data.empty()) { |
64 | 0 | throwEnvoyExceptionOrPanic("DataSource cannot be empty"); |
65 | 0 | } |
66 | 13.9k | return data; |
67 | 13.9k | } |
68 | | |
69 | 43 | absl::optional<std::string> getPath(const envoy::config::core::v3::DataSource& source) { |
70 | 43 | return source.specifier_case() == envoy::config::core::v3::DataSource::SpecifierCase::kFilename |
71 | 43 | ? absl::make_optional(source.filename()) |
72 | 43 | : absl::nullopt; |
73 | 43 | } |
74 | | |
75 | | RemoteAsyncDataProvider::RemoteAsyncDataProvider( |
76 | | Upstream::ClusterManager& cm, Init::Manager& manager, |
77 | | const envoy::config::core::v3::RemoteDataSource& source, Event::Dispatcher& dispatcher, |
78 | | Random::RandomGenerator& random, bool allow_empty, AsyncDataSourceCb&& callback) |
79 | | : allow_empty_(allow_empty), callback_(std::move(callback)), |
80 | | fetcher_(std::make_unique<Config::DataFetcher::RemoteDataFetcher>(cm, source.http_uri(), |
81 | | source.sha256(), *this)), |
82 | 0 | init_target_("RemoteAsyncDataProvider", [this]() { start(); }), |
83 | | retries_remaining_( |
84 | 0 | PROTOBUF_GET_WRAPPED_OR_DEFAULT(source.retry_policy(), num_retries, RetryCount)) { |
85 | |
|
86 | 0 | backoff_strategy_ = Utility::prepareJitteredExponentialBackOffStrategy( |
87 | 0 | source, random, RetryInitialDelayMilliseconds, RetryMaxDelayMilliseconds); |
88 | |
|
89 | 0 | retry_timer_ = dispatcher.createTimer([this]() -> void { start(); }); |
90 | |
|
91 | 0 | manager.add(init_target_); |
92 | 0 | } |
93 | | |
94 | | } // namespace DataSource |
95 | | } // namespace Config |
96 | | } // namespace Envoy |