Line data Source code
1 : #include "source/extensions/key_value/file_based/config.h" 2 : 3 : #include "envoy/registry/registry.h" 4 : 5 : namespace Envoy { 6 : namespace Extensions { 7 : namespace KeyValue { 8 : 9 : FileBasedKeyValueStore::FileBasedKeyValueStore(Event::Dispatcher& dispatcher, 10 : std::chrono::milliseconds flush_interval, 11 : Filesystem::Instance& file_system, 12 : const std::string& filename, uint32_t max_entries) 13 : : KeyValueStoreBase(dispatcher, flush_interval, max_entries), file_system_(file_system), 14 0 : filename_(filename) { 15 0 : if (!file_system_.fileExists(filename_)) { 16 0 : ENVOY_LOG(info, "File for key value store does not yet exist: {}", filename); 17 0 : return; 18 0 : } 19 0 : auto file_or_error = file_system_.fileReadToEnd(filename_); 20 0 : THROW_IF_STATUS_NOT_OK(file_or_error, throw); 21 0 : const std::string contents = file_or_error.value(); 22 0 : if (!parseContents(contents)) { 23 0 : ENVOY_LOG(warn, "Failed to parse key value store file {}", filename); 24 0 : } 25 0 : } 26 : 27 0 : void FileBasedKeyValueStore::flush() { 28 0 : static constexpr Filesystem::FlagSet DefaultFlags{1 << Filesystem::File::Operation::Write | 29 0 : 1 << Filesystem::File::Operation::Create}; 30 0 : Filesystem::FilePathAndType file_info{Filesystem::DestinationType::File, filename_}; 31 0 : auto file = file_system_.createFile(file_info); 32 0 : if (!file || !file->open(DefaultFlags).return_value_) { 33 0 : ENVOY_LOG(error, "Failed to flush cache to file {}", filename_); 34 0 : return; 35 0 : } 36 0 : for (const auto& [key, value_with_ttl] : store()) { 37 0 : file->write(absl::StrCat(key.length(), "\n")); 38 0 : file->write(key); 39 0 : file->write(absl::StrCat(value_with_ttl.value_.length(), "\n")); 40 0 : file->write(value_with_ttl.value_); 41 0 : if (value_with_ttl.ttl_.has_value()) { 42 0 : std::string ttl = std::to_string(value_with_ttl.ttl_.value().count()); 43 0 : file->write(KV_STORE_TTL_KEY); 44 0 : file->write(absl::StrCat(ttl.length(), "\n")); 45 0 : file->write(ttl); 46 0 : } 47 0 : } 48 0 : file->close(); 49 0 : } 50 : 51 : KeyValueStorePtr FileBasedKeyValueStoreFactory::createStore( 52 : const Protobuf::Message& config, ProtobufMessage::ValidationVisitor& validation_visitor, 53 0 : Event::Dispatcher& dispatcher, Filesystem::Instance& file_system) { 54 0 : const auto& typed_config = MessageUtil::downcastAndValidate< 55 0 : const envoy::config::common::key_value::v3::KeyValueStoreConfig&>(config, validation_visitor); 56 0 : const auto file_config = MessageUtil::anyConvertAndValidate< 57 0 : envoy::extensions::key_value::file_based::v3::FileBasedKeyValueStoreConfig>( 58 0 : typed_config.config().typed_config(), validation_visitor); 59 0 : const auto milliseconds = 60 0 : std::chrono::milliseconds(DurationUtil::durationToMilliseconds(file_config.flush_interval())); 61 0 : const uint32_t max_entries = PROTOBUF_GET_WRAPPED_OR_DEFAULT(file_config, max_entries, 1000); 62 0 : return std::make_unique<FileBasedKeyValueStore>(dispatcher, milliseconds, file_system, 63 0 : file_config.filename(), max_entries); 64 0 : } 65 : 66 : REGISTER_FACTORY(FileBasedKeyValueStoreFactory, KeyValueStoreFactory); 67 : 68 : } // namespace KeyValue 69 : } // namespace Extensions 70 : } // namespace Envoy