file_manager_strategy.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #pragma once
17 
18 #include <iostream>
19 #include <fstream>
20 #include <list>
21 #include <unordered_map>
22 #include <set>
23 #include <memory>
24 #include <random>
25 #include <mutex>
26 #include <experimental/filesystem>
29 #include <aws/core/utils/json/JsonSerializer.h>
30 
31 namespace Aws {
32 namespace FileManagement {
33 
37 };
38 
39 using DataToken = uint64_t;
40 
41 static constexpr const char* kPositionKey = "position";
42 static constexpr const char* kEofKey = "eof";
43 static constexpr const char* kFilePathKey = "file_path";
44 
51 void sanitizePath(std::string & path);
52 
57 public:
58 
59  FileTokenInfo() = default;
60 
61  // NOLINTNEXTLINE(google-runtime-int)
62  explicit FileTokenInfo(const std::string &file_path, const long position, const bool eof) :
63  file_path_{file_path},
64  position_(position),
65  eof_(eof)
66  {
67 
68  };
69 
70  // NOLINTNEXTLINE(google-runtime-int)
71  explicit FileTokenInfo(std::string &&file_path, const long position, const bool eof) :
72  file_path_{std::move(file_path)},
73  position_(position),
74  eof_(eof)
75  {
76 
77  };
78 
79  FileTokenInfo(const FileTokenInfo &info) = default;
80 
81  FileTokenInfo & operator=(const FileTokenInfo & other) = default;
82 
83  ~FileTokenInfo() = default;
84 
89  std::string serialize() const {
90  Aws::Utils::Json::JsonValue json_value;
91  const Aws::String file_path(file_path_.c_str());
92  json_value
93  .WithInt64(kPositionKey, position_)
94  .WithBool(kEofKey, eof_)
95  .WithString(kFilePathKey, file_path);
96  return std::string(json_value.View().WriteCompact().c_str());
97  }
98 
103  void deserialize(const std::string& token_info_json) {
104  const Aws::String aws_str(token_info_json.c_str());
105  const Aws::Utils::Json::JsonValue json_value(aws_str);
106  if (!json_value.WasParseSuccessful()) {
107  throw std::runtime_error("Unable to parse JSON");
108  }
109  auto view = json_value.View();
110  position_ = view.GetInt64(kPositionKey);
111  eof_ = view.GetBool(kEofKey);
112  file_path_ = view.GetString(kFilePathKey).c_str();
113  }
114 
118  std::string file_path_;
119 
123  int64_t position_ = 0;
124 
128  bool eof_{};
129 };
130 
131 inline bool operator==(const FileTokenInfo& lhs, const FileTokenInfo& rhs){
132  return lhs.eof_ == rhs.eof_ && lhs.position_ == rhs.position_ && lhs.file_path_ == rhs.file_path_;
133 }
134 
135 inline bool operator!=(const FileTokenInfo& lhs, const FileTokenInfo& rhs){ return !(lhs == rhs); }
136 
137 class DataManagerStrategy : public Service {
138 public:
139  DataManagerStrategy() = default;
140  ~DataManagerStrategy() override = default;
141 
142  virtual bool isDataAvailable() = 0;
143 
144  virtual bool isDeleteStaleData() = 0;
145 
146  virtual DataToken read(std::string &data) = 0;
147 
148  virtual void write(const std::string &data) = 0;
149 
156  virtual void resolve(const DataToken &token, bool is_success) = 0;
157 };
158 
162 class TokenStore {
163 public:
164 
165  TokenStore() = default;
166 
167  explicit TokenStore(const TokenStoreOptions &options);
168 
174  bool isTokenAvailable(const std::string &file_name) const;
175 
180  FileTokenInfo popAvailableToken(const std::string &file_name);
181 
190  // NOLINTNEXTLINE(google-runtime-int)
191  DataToken createToken(const std::string &file_name, const long streampos, bool is_eof);
192 
201  FileTokenInfo fail(const DataToken &token);
202 
210  FileTokenInfo resolve(const DataToken &token);
211 
216  std::vector<FileTokenInfo> backup();
217 
221  void backupToDisk();
222 
227  void restore(const std::vector<FileTokenInfo> &file_tokens);
228 
232  void restoreFromDisk();
233 
234 
235 
236 private:
241  void validateOptions();
242 
247  void initializeBackupDirectory();
248 
252  std::unordered_map<DataToken, FileTokenInfo> token_store_;
253 
259  std::unordered_map<std::string, std::list<DataToken>> file_tokens_;
260 
269  std::unordered_map<std::string, FileTokenInfo> staged_tokens_;
270 
275 
279  std::random_device rand_device;
280 };
281 
286 public:
287  explicit FileManagerStrategy(const FileManagerStrategyOptions &options);
288 
289  ~FileManagerStrategy() override = default;
290 
298  bool start() override;
299 
304  bool isDataAvailable() override;
305 
311  bool isDeleteStaleData() override;
312 
320  DataToken read(std::string &data) override;
321 
326  void write(const std::string &data) override;
327 
336  void resolve(const DataToken &token, bool is_success) override;
337 
344  bool shutdown() override;
345 
346 protected: // functions exposed for testing
353  std::string getFileToRead();
354 
359  std::string getActiveWriteFile() {
360  return active_write_file_;
361  }
362 
363 private:
368  void validateOptions();
369 
374  void initializeStorage();
375 
379  void initializeTokenStore();
380 
384  void discoverStoredFiles();
385 
391  void deleteFile(const std::string &file_path);
392 
398  void checkIfWriteFileShouldRotate(const uintmax_t &new_data_size);
399 
404  void rotateWriteFile();
405 
412  void checkIfStorageLimitHasBeenReached(const uintmax_t &new_data_size);
413 
417  void deleteOldestFile();
418 
423  void addFilePathToStorage(const std::experimental::filesystem::path &file_path);
424 
428  std::list<std::string> stored_files_;
429 
433  std::atomic<size_t> stored_files_size_{};
434 
438  std::string active_write_file_;
439 
443  std::atomic<size_t> active_write_file_size_{};
444 
450 
455  std::string active_read_file_;
456 
461  std::unique_ptr<std::ifstream> active_read_file_stream_;
462 
468 
473 
477  std::unique_ptr<TokenStore> token_store_;
478 };
479 
480 } // namespace FileManagement
481 } // namespace Aws
std::unique_ptr< TokenStore > token_store_
std::unordered_map< std::string, std::list< DataToken > > file_tokens_
static constexpr const char * kEofKey
FileTokenInfo(const std::string &file_path, const long position, const bool eof)
std::unordered_map< std::string, FileTokenInfo > staged_tokens_
bool operator==(const FileTokenInfo &lhs, const FileTokenInfo &rhs)
std::unordered_map< DataToken, FileTokenInfo > token_store_
FileTokenInfo(std::string &&file_path, const long position, const bool eof)
static constexpr const char * kFilePathKey
void sanitizePath(std::string &path)
static constexpr const char * kPositionKey
void deserialize(const std::string &token_info_json)
std::unique_ptr< std::ifstream > active_read_file_stream_
FileTokenInfo & operator=(const FileTokenInfo &other)=default
bool operator!=(const FileTokenInfo &lhs, const FileTokenInfo &rhs)


file_management
Author(s): AWS RoboMaker
autogenerated on Fri May 7 2021 02:18:23