54 Commits

Author SHA1 Message Date
d2a8aef843 refactor app config
Some checks failed
BlockStorage/repertory/pipeline/head There was a failure building this commit
2024-12-20 15:23:03 -06:00
f14b1c7168 refactor app config 2024-12-20 15:13:13 -06:00
0a08914a01 refactor app config 2024-12-20 15:10:38 -06:00
031e8e3495 refactor 2024-12-20 14:49:47 -06:00
62489245cb cleanup 2024-12-20 14:13:55 -06:00
00844cb89c refactor 2024-12-20 14:12:22 -06:00
c943c1ecd7 refactor 2024-12-20 14:03:30 -06:00
74f9364196 fixes 2024-12-20 14:00:08 -06:00
4fd1e7507a fixes 2024-12-20 13:54:36 -06:00
edb57903bc refactor 2024-12-20 13:47:17 -06:00
c8f4af7455 fixes 2024-12-20 13:42:50 -06:00
7a6a7421cd refactor app config 2024-12-20 13:21:35 -06:00
cfa96f2476 refactor app config 2024-12-20 13:14:42 -06:00
1c2759f2d7 refactor app config 2024-12-20 13:12:18 -06:00
2e858bdd5a refactor app config 2024-12-20 08:29:57 -06:00
2c8950d5b4 refactor app config 2024-12-20 08:27:58 -06:00
895464f50d unit tests and fixes 2024-12-20 07:28:56 -06:00
7a69989275 fix 2024-12-19 15:17:05 -06:00
a6bfd2306c fix 2024-12-19 14:22:13 -06:00
447f9a886d refactor 2024-12-19 14:10:00 -06:00
fc2af3f935 refactor 2024-12-19 13:37:32 -06:00
12db0a3753 fix 2024-12-19 13:34:57 -06:00
a3991e7c76 fix 2024-12-19 13:31:57 -06:00
ce0e1358fc refactor 2024-12-19 13:16:13 -06:00
ce2bf344f9 refactor 2024-12-19 13:15:30 -06:00
ebb9f59196 refactor 2024-12-19 13:12:00 -06:00
b03060a00f refactor 2024-12-19 13:11:13 -06:00
39996b2dc8 refactor 2024-12-19 13:10:43 -06:00
3fcb846eca refactor 2024-12-19 13:10:27 -06:00
d66c818c1e refactor 2024-12-19 13:07:57 -06:00
0348492f6c refactor 2024-12-19 13:04:55 -06:00
ead3bcde1a refactor 2024-12-19 13:03:12 -06:00
2ca277ddf7 removed legacy option 2024-12-19 12:58:06 -06:00
274471a066 fix 2024-12-19 12:37:13 -06:00
001f586a24 fix 2024-12-19 12:36:57 -06:00
e2efb78385 fix 2024-12-19 12:36:16 -06:00
5018a192d7 fix 2024-12-19 12:35:35 -06:00
bd821d0a63 refactor 2024-12-19 11:16:25 -06:00
c5e463c366 fix 2024-12-19 11:15:25 -06:00
c46334b046 refactor 2024-12-19 11:13:15 -06:00
146d301002 refactor 2024-12-19 11:11:47 -06:00
e6ad15889e fix 2024-12-19 11:10:12 -06:00
7fb2889c74 refactor 2024-12-19 11:09:48 -06:00
f750a52f75 refactor 2024-12-19 10:36:25 -06:00
cf0ff8cf62 refactor 2024-12-19 10:33:39 -06:00
b7f79c4192 refactor remote mount 2024-12-19 10:31:18 -06:00
ad4e950005 refactor remote mount 2024-12-19 10:29:24 -06:00
18929038fb refactor remote mount 2024-12-19 10:15:47 -06:00
890b3e12dc refactor remote mount 2024-12-19 09:56:12 -06:00
0a45b51760 refactor remote mount 2024-12-19 09:54:29 -06:00
c0a6bde9e5 refactor 2024-12-19 08:36:34 -06:00
e4289295e8 refactor 2024-12-19 08:33:51 -06:00
60b06790a3 refactor 2024-12-19 08:19:09 -06:00
c421e84854 refactor app config 2024-12-19 07:54:00 -06:00
36 changed files with 2614 additions and 2157 deletions

View File

@ -2,6 +2,10 @@
## v2.0.2-rc
### BREAKING CHANGES
* Refactored `config.json` - will need to verify configuration settings prior to mounting
### Issues
* \#12 \[Unit Test\] Complete all providers unit tests

View File

@ -24,90 +24,33 @@
#include "events/event_system.hpp"
#include "events/events.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
#include "utils/error_utils.hpp"
namespace repertory {
template <typename data_t> class atomic final {
public:
atomic() : mtx_(std::make_shared<std::mutex>()) {}
atomic(const atomic &) = default;
atomic(data_t data)
: data_(std::move(data)), mtx_(std::make_shared<std::mutex>()) {}
atomic(data_t data, std::unique_ptr<std::mutex> mtx)
: data_(std::move(data)), mtx_(std::move(mtx)) {}
atomic(atomic &&) = default;
~atomic() = default;
private:
data_t data_;
std::shared_ptr<std::mutex> mtx_;
public:
auto operator=(const atomic &) -> atomic & = default;
auto operator=(atomic &&) -> atomic & = default;
auto operator==(const atomic &at_data) const -> bool {
mutex_lock lock(*mtx_);
return static_cast<data_t>(at_data) == data_;
}
auto operator==(const data_t &data) const -> bool {
mutex_lock lock(*mtx_);
return data == data_;
}
auto operator!=(const atomic &at_data) const -> bool {
mutex_lock lock(*mtx_);
return static_cast<data_t>(at_data) != data_;
}
auto operator!=(const data_t &data) const -> bool {
mutex_lock lock(*mtx_);
return data != data_;
}
auto operator=(const data_t &data) -> atomic & {
mutex_lock lock(*mtx_);
if (&data != &data_) {
data_ = data;
}
return *this;
}
operator data_t() const {
mutex_lock lock(*mtx_);
return data_;
}
};
using atomic_string = atomic<std::string>;
class app_config final {
public:
[[nodiscard]] static auto
default_agent_name(const provider_type &prov) -> std::string;
[[nodiscard]] static auto default_agent_name(const provider_type &prov)
-> std::string;
[[nodiscard]] static auto
default_api_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto default_api_port(const provider_type &prov)
-> std::uint16_t;
[[nodiscard]] static auto
default_data_directory(const provider_type &prov) -> std::string;
[[nodiscard]] static auto default_data_directory(const provider_type &prov)
-> std::string;
[[nodiscard]] static auto
default_remote_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto default_remote_api_port(const provider_type &prov)
-> std::uint16_t;
[[nodiscard]] static auto
default_rpc_port(const provider_type &prov) -> std::uint16_t;
[[nodiscard]] static auto default_rpc_port(const provider_type &prov)
-> std::uint16_t;
[[nodiscard]] static auto
get_provider_display_name(const provider_type &prov) -> std::string;
[[nodiscard]] static auto get_provider_display_name(const provider_type &prov)
-> std::string;
[[nodiscard]] static auto
get_provider_name(const provider_type &prov) -> std::string;
[[nodiscard]] static auto get_provider_name(const provider_type &prov)
-> std::string;
public:
app_config(const provider_type &prov, std::string_view data_directory = "");
@ -116,476 +59,216 @@ public:
private:
provider_type prov_;
atomic_string api_auth_;
atomic<std::string> api_auth_;
std::atomic<std::uint16_t> api_port_;
atomic_string api_user_;
atomic<std::string> api_user_;
std::atomic<bool> config_changed_;
database_type db_type_{database_type::rocksdb};
std::atomic<database_type> db_type_{database_type::rocksdb};
std::atomic<std::uint8_t> download_timeout_secs_;
std::atomic<bool> enable_chunk_downloader_timeout_;
std::atomic<bool> enable_comm_duration_events_;
std::atomic<bool> enable_drive_events_;
std::atomic<bool> enable_max_cache_size_;
#if defined(_WIN32)
std::atomic<bool> enable_mount_manager_;
#endif // defined(_WIN32)
std::atomic<bool> enable_remote_mount_;
std::atomic<event_level> event_level_;
std::uint32_t eviction_delay_mins_;
std::atomic<std::uint32_t> eviction_delay_mins_;
std::atomic<bool> eviction_uses_accessed_time_;
std::uint16_t high_freq_interval_secs_;
std::atomic<bool> is_remote_mount_;
std::uint16_t low_freq_interval_secs_;
std::uint64_t max_cache_size_bytes_;
std::atomic<std::uint16_t> high_freq_interval_secs_;
std::atomic<std::uint16_t> low_freq_interval_secs_;
std::atomic<std::uint64_t> max_cache_size_bytes_;
std::atomic<std::uint8_t> max_upload_count_;
std::uint16_t med_freq_interval_secs_;
std::atomic<std::uint16_t> med_freq_interval_secs_;
std::atomic<std::uint8_t> min_download_timeout_secs_;
std::uint16_t online_check_retry_secs_;
std::uint16_t orphaned_file_retention_days_;
atomic_string preferred_download_type_;
std::atomic<std::uint8_t> read_ahead_count_;
std::atomic<std::uint8_t> remote_client_pool_size_;
atomic_string remote_host_name_or_ip_;
std::atomic<std::uint8_t> remote_max_connections_;
std::uint16_t remote_port_;
std::uint16_t remote_receive_timeout_secs_;
std::uint16_t remote_send_timeout_secs_;
atomic_string remote_token_;
std::uint16_t retry_read_count_;
std::uint16_t ring_buffer_file_size_;
std::uint16_t task_wait_ms_;
std::atomic<std::uint16_t> online_check_retry_secs_;
std::atomic<std::uint16_t> orphaned_file_retention_days_;
atomic<download_type> preferred_download_type_;
std::atomic<std::uint16_t> retry_read_count_;
std::atomic<std::uint16_t> ring_buffer_file_size_;
std::atomic<std::uint16_t> task_wait_ms_;
private:
std::string cache_directory_;
std::string data_directory_;
encrypt_config encrypt_config_;
host_config hc_{};
atomic<encrypt_config> encrypt_config_;
atomic<host_config> host_config_;
std::string log_directory_;
mutable std::recursive_mutex read_write_mutex_;
s3_config s3_config_{};
sia_config sia_config_{};
atomic<remote::remote_config> remote_config_;
atomic<remote::remote_mount> remote_mount_;
atomic<s3_config> s3_config_;
atomic<sia_config> sia_config_;
std::unordered_map<std::string, std::function<std::string()>>
value_get_lookup_;
std::unordered_map<std::string,
std::function<std::string(const std::string &)>>
value_set_lookup_;
std::uint64_t version_{REPERTORY_CONFIG_VERSION};
mutable std::recursive_mutex remote_mount_mutex_;
private:
auto get_database_value(const json &json_document, const std::string &name,
database_type &dst, bool &success_flag) -> bool;
template <typename dest>
auto get_value(const json &json_document, const std::string &name, dest &dst,
bool &success_flag) -> bool {
REPERTORY_USES_FUNCTION_NAME();
auto ret{false};
try {
if (json_document.find(name) != json_document.end()) {
json_document.at(name).get_to(dst);
ret = true;
} else {
success_flag = false;
}
} catch (const json::exception &ex) {
utils::error::raise_error(function_name, ex, "exception occurred");
success_flag = false;
ret = false;
}
return ret;
}
[[nodiscard]] auto load() -> bool;
template <typename dest, typename source>
auto set_value(dest &dst, const source &src) -> bool {
auto ret{false};
recur_mutex_lock lock(read_write_mutex_);
if (dst != src) {
if (dst.load() == src) {
return false;
}
dst = src;
config_changed_ = true;
save();
ret = true;
}
return ret;
return true;
}
public:
[[nodiscard]] auto get_api_auth() const -> std::string { return api_auth_; }
[[nodiscard]] auto get_api_auth() const -> std::string;
[[nodiscard]] auto get_api_port() const -> std::uint16_t { return api_port_; }
[[nodiscard]] auto get_api_port() const -> std::uint16_t;
[[nodiscard]] auto get_api_user() const -> std::string { return api_user_; }
[[nodiscard]] auto get_api_user() const -> std::string;
[[nodiscard]] auto get_cache_directory() const -> std::string {
return cache_directory_;
}
[[nodiscard]] auto get_cache_directory() const -> std::string;
[[nodiscard]] auto get_chunk_downloader_timeout_secs() const -> std::uint8_t {
return std::max(min_download_timeout_secs_, download_timeout_secs_);
}
[[nodiscard]] auto get_chunk_downloader_timeout_secs() const -> std::uint8_t;
[[nodiscard]] auto get_config_file_path() const -> std::string;
[[nodiscard]] auto get_database_type() const -> database_type {
return db_type_;
}
[[nodiscard]] auto get_database_type() const -> database_type;
[[nodiscard]] auto get_data_directory() const -> std::string {
return data_directory_;
}
[[nodiscard]] auto get_data_directory() const -> std::string;
[[nodiscard]] auto get_enable_chunk_download_timeout() const -> bool {
return enable_chunk_downloader_timeout_;
}
[[nodiscard]] auto get_enable_chunk_download_timeout() const -> bool;
[[nodiscard]] auto get_enable_comm_duration_events() const -> bool {
return enable_comm_duration_events_;
}
[[nodiscard]] auto get_enable_comm_duration_events() const -> bool;
[[nodiscard]] auto get_enable_drive_events() const -> bool {
return enable_drive_events_;
}
[[nodiscard]] auto get_enable_drive_events() const -> bool;
[[nodiscard]] auto get_encrypt_config() const -> encrypt_config {
return encrypt_config_;
}
[[nodiscard]] auto get_encrypt_config() const -> encrypt_config;
#if defined(_WIN32)
[[nodiscard]] auto get_enable_mount_manager() const -> bool {
return enable_mount_manager_;
}
[[nodiscard]] auto get_enable_mount_manager() const -> bool;
#endif // defined(_WIN32)
[[nodiscard]] auto get_enable_max_cache_size() const -> bool {
return enable_max_cache_size_;
}
[[nodiscard]] auto get_event_level() const -> event_level;
[[nodiscard]] auto get_enable_remote_mount() const -> bool {
return enable_remote_mount_;
}
[[nodiscard]] auto get_eviction_delay_mins() const -> std::uint32_t;
[[nodiscard]] auto get_event_level() const -> event_level {
return event_level_;
}
[[nodiscard]] auto get_eviction_uses_accessed_time() const -> bool;
[[nodiscard]] auto get_eviction_delay_mins() const -> std::uint32_t {
return eviction_delay_mins_;
}
[[nodiscard]] auto get_high_frequency_interval_secs() const -> std::uint16_t;
[[nodiscard]] auto get_eviction_uses_accessed_time() const -> bool {
return eviction_uses_accessed_time_;
}
[[nodiscard]] auto get_high_frequency_interval_secs() const -> std::uint16_t {
return std::max(static_cast<std::uint16_t>(1U), high_freq_interval_secs_);
}
[[nodiscard]] auto get_host_config() const -> host_config { return hc_; }
[[nodiscard]] auto get_is_remote_mount() const -> bool {
return is_remote_mount_;
}
[[nodiscard]] auto get_host_config() const -> host_config;
[[nodiscard]] auto get_json() const -> json;
[[nodiscard]] auto get_log_directory() const -> std::string {
return log_directory_;
}
[[nodiscard]] auto get_log_directory() const -> std::string;
[[nodiscard]] auto get_low_frequency_interval_secs() const -> std::uint16_t {
return std::max(static_cast<std::uint16_t>(1U), low_freq_interval_secs_);
}
[[nodiscard]] auto get_low_frequency_interval_secs() const -> std::uint16_t;
[[nodiscard]] auto get_max_cache_size_bytes() const -> std::uint64_t;
[[nodiscard]] auto get_max_upload_count() const -> std::uint8_t {
return std::max(std::uint8_t(1U), max_upload_count_.load());
}
[[nodiscard]] auto get_max_upload_count() const -> std::uint8_t;
[[nodiscard]] auto get_med_frequency_interval_secs() const -> std::uint16_t {
return std::max(static_cast<std::uint16_t>(1U), med_freq_interval_secs_);
}
[[nodiscard]] auto get_med_frequency_interval_secs() const -> std::uint16_t;
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t {
return std::max(std::uint16_t(15U), online_check_retry_secs_);
}
[[nodiscard]] auto get_online_check_retry_secs() const -> std::uint16_t;
[[nodiscard]] auto get_orphaned_file_retention_days() const -> std::uint16_t {
return std::min(static_cast<std::uint16_t>(31U),
std::max(static_cast<std::uint16_t>(1U),
orphaned_file_retention_days_));
}
[[nodiscard]] auto get_orphaned_file_retention_days() const -> std::uint16_t;
[[nodiscard]] auto get_preferred_download_type() const -> download_type {
return download_type_from_string(preferred_download_type_,
download_type::fallback);
}
[[nodiscard]] auto get_preferred_download_type() const -> download_type;
[[nodiscard]] auto get_provider_type() const -> provider_type {
return prov_;
}
[[nodiscard]] auto get_provider_type() const -> provider_type;
[[nodiscard]] auto get_read_ahead_count() const -> std::uint8_t {
return std::max(static_cast<std::uint8_t>(1U), read_ahead_count_.load());
}
[[nodiscard]] auto get_remote_config() const -> remote::remote_config;
[[nodiscard]] auto get_remote_client_pool_size() const -> std::uint8_t {
return std::max(static_cast<std::uint8_t>(5U),
remote_client_pool_size_.load());
}
[[nodiscard]] auto get_remote_mount() const -> remote::remote_mount;
[[nodiscard]] auto get_remote_host_name_or_ip() const -> std::string {
return remote_host_name_or_ip_;
}
[[nodiscard]] auto get_retry_read_count() const -> std::uint16_t;
[[nodiscard]] auto get_remote_max_connections() const -> std::uint8_t {
return std::max(static_cast<std::uint8_t>(1U),
remote_max_connections_.load());
}
[[nodiscard]] auto get_ring_buffer_file_size() const -> std::uint16_t;
[[nodiscard]] auto get_remote_port() const -> std::uint16_t {
return remote_port_;
}
[[nodiscard]] auto get_s3_config() const -> s3_config;
[[nodiscard]] auto get_remote_receive_timeout_secs() const -> std::uint16_t {
return remote_receive_timeout_secs_;
}
[[nodiscard]] auto get_sia_config() const -> sia_config;
[[nodiscard]] auto get_remote_send_timeout_secs() const -> std::uint16_t {
return remote_send_timeout_secs_;
}
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t;
[[nodiscard]] auto get_remote_token() const -> std::string {
return remote_token_;
}
[[nodiscard]] auto get_value_by_name(const std::string &name) const
-> std::string;
[[nodiscard]] auto get_retry_read_count() const -> std::uint16_t {
return std::max(std::uint16_t(2), retry_read_count_);
}
[[nodiscard]] auto get_ring_buffer_file_size() const -> std::uint16_t {
return std::max(
static_cast<std::uint16_t>(64U),
std::min(static_cast<std::uint16_t>(1024U), ring_buffer_file_size_));
}
[[nodiscard]] auto get_s3_config() const -> s3_config { return s3_config_; }
[[nodiscard]] auto get_sia_config() const -> sia_config {
return sia_config_;
}
[[nodiscard]] auto get_task_wait_ms() const -> std::uint16_t {
return std::max(static_cast<std::uint16_t>(50U), task_wait_ms_);
}
[[nodiscard]] auto get_value_by_name(const std::string &name) -> std::string;
[[nodiscard]] auto get_version() const -> std::uint64_t { return version_; }
[[nodiscard]] auto get_version() const -> std::uint64_t;
void save();
void set_api_auth(const std::string &api_auth) {
set_value(api_auth_, api_auth);
}
void set_api_auth(const std::string &api_auth);
void set_api_port(std::uint16_t api_port) { set_value(api_port_, api_port); }
void set_api_port(std::uint16_t api_port);
void set_api_user(const std::string &api_user) {
set_value(api_user_, api_user);
}
void set_chunk_downloader_timeout_secs(
std::uint8_t chunk_downloader_timeout_secs) {
set_value(download_timeout_secs_, chunk_downloader_timeout_secs);
}
void set_database_type(const database_type &type) {
set_value(db_type_, type);
}
void set_api_user(const std::string &api_user);
void
set_enable_chunk_downloader_timeout(bool enable_chunk_downloader_timeout) {
set_value(enable_chunk_downloader_timeout_,
enable_chunk_downloader_timeout);
}
set_chunk_downloader_timeout_secs(std::uint8_t chunk_downloader_timeout_secs);
void set_enable_comm_duration_events(bool enable_comm_duration_events) {
set_value(enable_comm_duration_events_, enable_comm_duration_events);
}
void set_database_type(const database_type &type);
void set_enable_drive_events(bool enable_drive_events) {
set_value(enable_drive_events_, enable_drive_events);
}
void
set_enable_chunk_downloader_timeout(bool enable_chunk_downloader_timeout);
void set_enable_max_cache_size(bool enable_max_cache_size) {
set_value(enable_max_cache_size_, enable_max_cache_size);
}
void set_enable_comm_duration_events(bool enable_comm_duration_events);
void set_enable_drive_events(bool enable_drive_events);
#if defined(_WIN32)
void set_enable_mount_manager(bool enable_mount_manager) {
set_value(enable_mount_manager_, enable_mount_manager);
}
void set_enable_mount_manager(bool enable_mount_manager);
#endif // defined(_WIN32)
void set_enable_remote_mount(bool enable_remote_mount);
void set_event_level(const event_level &level);
void set_event_level(const event_level &level) {
if (set_value(event_level_, level)) {
event_system::instance().raise<event_level_changed>(
event_level_to_string(level));
}
}
void set_encrypt_config(encrypt_config cfg);
void set_eviction_delay_mins(std::uint32_t eviction_delay_mins) {
set_value(eviction_delay_mins_, eviction_delay_mins);
}
void set_eviction_delay_mins(std::uint32_t eviction_delay_mins);
void set_eviction_uses_accessed_time(bool eviction_uses_accessed_time) {
set_value(eviction_uses_accessed_time_, eviction_uses_accessed_time);
}
void set_eviction_uses_accessed_time(bool eviction_uses_accessed_time);
void
set_high_frequency_interval_secs(std::uint16_t high_frequency_interval_secs) {
set_value(high_freq_interval_secs_, high_frequency_interval_secs);
}
set_high_frequency_interval_secs(std::uint16_t high_frequency_interval_secs);
#if defined(PROJECT_TESTING)
void set_host_config(host_config hc) {
config_changed_ = true;
hc_ = std::move(hc);
save();
}
void set_s3_config(s3_config s3) {
config_changed_ = true;
s3_config_ = std::move(s3);
save();
}
void set_sia_config(sia_config sia) {
config_changed_ = true;
sia_config_ = std::move(sia);
save();
}
#endif // defined(PROJECT_TESTING)
void set_is_remote_mount(bool is_remote_mount);
void set_host_config(host_config cfg);
void
set_low_frequency_interval_secs(std::uint16_t low_frequency_interval_secs) {
set_value(low_freq_interval_secs_, low_frequency_interval_secs);
}
set_low_frequency_interval_secs(std::uint16_t low_frequency_interval_secs);
void set_max_cache_size_bytes(std::uint64_t max_cache_size_bytes) {
set_value(max_cache_size_bytes_, max_cache_size_bytes);
}
void set_max_cache_size_bytes(std::uint64_t max_cache_size_bytes);
void set_max_upload_count(std::uint8_t max_upload_count) {
set_value(max_upload_count_, max_upload_count);
}
void set_max_upload_count(std::uint8_t max_upload_count);
void
set_med_frequency_interval_secs(std::uint16_t med_frequency_interval_secs) {
set_value(med_freq_interval_secs_, med_frequency_interval_secs);
}
set_med_frequency_interval_secs(std::uint16_t med_frequency_interval_secs);
void set_online_check_retry_secs(std::uint16_t online_check_retry_secs) {
set_value(online_check_retry_secs_, online_check_retry_secs);
}
void set_online_check_retry_secs(std::uint16_t online_check_retry_secs);
void
set_orphaned_file_retention_days(std::uint16_t orphaned_file_retention_days) {
set_value(orphaned_file_retention_days_, orphaned_file_retention_days);
}
set_orphaned_file_retention_days(std::uint16_t orphaned_file_retention_days);
void set_preferred_download_type(const download_type &dt) {
set_value(preferred_download_type_, download_type_to_string(dt));
}
void set_preferred_download_type(const download_type &type);
void set_read_ahead_count(std::uint8_t read_ahead_count) {
set_value(read_ahead_count_, read_ahead_count);
}
void set_remote_config(remote::remote_config cfg);
void set_remote_client_pool_size(std::uint8_t remote_client_pool_size) {
set_value(remote_client_pool_size_, remote_client_pool_size);
}
void set_remote_mount(remote::remote_mount cfg);
void set_ring_buffer_file_size(std::uint16_t ring_buffer_file_size) {
set_value(ring_buffer_file_size_, ring_buffer_file_size);
}
void set_retry_read_count(std::uint16_t retry_read_count);
void set_remote_host_name_or_ip(const std::string &remote_host_name_or_ip) {
set_value(remote_host_name_or_ip_, remote_host_name_or_ip);
}
void set_ring_buffer_file_size(std::uint16_t ring_buffer_file_size);
void set_remote_max_connections(std::uint8_t remote_max_connections) {
set_value(remote_max_connections_, remote_max_connections);
}
void set_s3_config(s3_config cfg);
void set_remote_port(std::uint16_t remote_port) {
set_value(remote_port_, remote_port);
}
void set_sia_config(sia_config cfg);
void
set_remote_receive_timeout_secs(std::uint16_t remote_receive_timeout_secs) {
set_value(remote_receive_timeout_secs_, remote_receive_timeout_secs);
}
void set_remote_send_timeout_secs(std::uint16_t remote_send_timeout_secs) {
set_value(remote_send_timeout_secs_, remote_send_timeout_secs);
}
void set_remote_token(const std::string &remote_token) {
set_value(remote_token_, remote_token);
}
void set_retry_read_count(std::uint16_t retry_read_count) {
set_value(retry_read_count_, retry_read_count);
}
void set_task_wait_ms(std::uint16_t task_wait_ms) {
set_value(task_wait_ms_, task_wait_ms);
}
void set_task_wait_ms(std::uint16_t task_wait_ms);
[[nodiscard]] auto set_value_by_name(const std::string &name,
const std::string &value) -> std::string;
};
} // namespace repertory
NLOHMANN_JSON_NAMESPACE_BEGIN
template <> struct adl_serializer<repertory::atomic_string> {
static void to_json(json &data, const repertory::atomic_string &value) {
data = static_cast<std::string>(value);
}
static void from_json(const json &data, repertory::atomic_string &value) {
value = data.get<std::string>();
}
};
template <typename primitive_t>
struct adl_serializer<std::atomic<primitive_t>> {
static void to_json(json &data, const std::atomic<primitive_t> &value) {
data = value.load();
}
static void from_json(const json &data, std::atomic<primitive_t> &value) {
value.store(data.get<primitive_t>());
}
};
template <> struct adl_serializer<std::atomic<repertory::event_level>> {
static void to_json(json &data,
const std::atomic<repertory::event_level> &value) {
data = repertory::event_level_to_string(value.load());
}
static void from_json(const json &data,
std::atomic<repertory::event_level> &value) {
value.store(repertory::event_level_from_string(data.get<std::string>()));
}
};
NLOHMANN_JSON_NAMESPACE_END
#endif // REPERTORY_INCLUDE_APP_CONFIG_HPP_

View File

@ -23,6 +23,7 @@
#define REPERTORY_INCLUDE_COMM_PACKET_PACKET_CLIENT_HPP_
#include "comm/packet/packet.hpp"
#include "types/remote.hpp"
using boost::asio::ip::tcp;
@ -36,9 +37,7 @@ private:
};
public:
packet_client(std::string host_name_or_ip, std::uint8_t max_connections,
std::uint16_t port, std::uint16_t receive_timeout,
std::uint16_t send_timeout, std::string encryption_token);
packet_client(remote::remote_config cfg);
~packet_client();
@ -49,12 +48,7 @@ public:
private:
boost::asio::io_context io_context_;
std::string host_name_or_ip_;
std::uint8_t max_connections_;
std::uint16_t port_;
std::uint16_t receive_timeout_;
std::uint16_t send_timeout_;
std::string encryption_token_;
remote::remote_config cfg_;
std::string unique_id_;
private:
@ -75,21 +69,21 @@ private:
void put_client(std::shared_ptr<client> &cli);
[[nodiscard]] auto read_packet(client &cli,
packet &response) -> packet::error_type;
[[nodiscard]] auto read_packet(client &cli, packet &response)
-> packet::error_type;
void resolve();
public:
[[nodiscard]] auto send(std::string_view method,
std::uint32_t &service_flags) -> packet::error_type;
[[nodiscard]] auto send(std::string_view method, std::uint32_t &service_flags)
-> packet::error_type;
[[nodiscard]] auto send(std::string_view method, packet &request,
std::uint32_t &service_flags) -> packet::error_type;
[[nodiscard]] auto send(std::string_view method, packet &request,
packet &response,
std::uint32_t &service_flags) -> packet::error_type;
packet &response, std::uint32_t &service_flags)
-> packet::error_type;
};
} // namespace repertory

View File

@ -31,22 +31,23 @@ class i_provider;
class eviction final : public single_thread_service_base {
public:
eviction(i_provider &provider, const app_config &config, i_file_manager &fm)
eviction(i_provider &provider, const app_config &config,
i_file_manager &file_mgr)
: single_thread_service_base("eviction"),
provider_(provider),
config_(config),
fm_(fm) {}
file_mgr_(file_mgr),
provider_(provider) {}
~eviction() override = default;
private:
i_provider &provider_;
const app_config &config_;
i_file_manager &fm_;
i_file_manager &file_mgr_;
i_provider &provider_;
private:
[[nodiscard]] auto
check_minimum_requirements(const std::string &file_path) -> bool;
[[nodiscard]] auto check_minimum_requirements(const std::string &file_path)
-> bool;
[[nodiscard]] auto get_filtered_cached_files() -> std::deque<std::string>;

View File

@ -52,7 +52,7 @@ public:
: config_(config),
drive_(drv),
mount_location_(std::move(mount_location)),
client_pool_(config.get_remote_client_pool_size()) {
client_pool_(config.get_remote_mount().client_pool_size) {
event_system::instance().raise<service_started>("remote_server_base");
handler_lookup_.insert(
{"::winfsp_can_delete",
@ -1357,7 +1357,8 @@ public:
}});
packet_server_ = std::make_unique<packet_server>(
config_.get_remote_port(), config_.get_remote_token(), 10,
config_.get_remote_mount().api_port,
config_.get_remote_mount().encryption_token, 10,
[this](const std::string &client_id) {
return this->closed_handler(client_id);
},

View File

@ -32,9 +32,12 @@ enum class event_level {
trace,
};
auto event_level_from_string(std::string level) -> event_level;
[[nodiscard]] auto
event_level_from_string(std::string level,
event_level default_level = event_level::info)
-> event_level;
auto event_level_to_string(event_level level) -> std::string;
[[nodiscard]] auto event_level_to_string(event_level level) -> std::string;
class event {
protected:
@ -72,4 +75,18 @@ public:
};
} // namespace repertory
NLOHMANN_JSON_NAMESPACE_BEGIN
template <> struct adl_serializer<std::atomic<repertory::event_level>> {
static void to_json(json &data,
const std::atomic<repertory::event_level> &value) {
data = repertory::event_level_to_string(value.load());
}
static void from_json(const json &data,
std::atomic<repertory::event_level> &value) {
value.store(repertory::event_level_from_string(data.get<std::string>()));
}
};
NLOHMANN_JSON_NAMESPACE_END
#endif // REPERTORY_INCLUDE_EVENTS_EVENT_HPP_

View File

@ -96,7 +96,9 @@ protected:
return api_item_added_;
}
[[nodiscard]] auto get_comm() const -> i_http_comm & { return comm_; }
[[nodiscard]] auto get_comm() -> i_http_comm & { return comm_; }
[[nodiscard]] auto get_comm() const -> const i_http_comm & { return comm_; }
[[nodiscard]] auto get_config() -> app_config & { return config_; }

View File

@ -54,6 +54,7 @@ private:
private:
app_config &config_;
encrypt_config encrypt_config_;
private:
std::unique_ptr<i_file_db> db_{nullptr};
@ -73,6 +74,10 @@ private:
const std::string &source_path)>
callback) const -> api_error;
[[nodiscard]] auto get_encrypt_config() const -> const encrypt_config & {
return encrypt_config_;
}
auto process_directory_entry(const utils::file::i_fs_item &dir_entry,
const encrypt_config &cfg,
std::string &api_path) const -> bool;

View File

@ -46,6 +46,9 @@ public:
auto operator=(const s3_provider &) -> s3_provider & = delete;
auto operator=(s3_provider &&) -> s3_provider & = delete;
private:
s3_config s3_config_;
private:
[[nodiscard]] auto add_if_not_found(api_file &file,
const std::string &object_name) const
@ -78,6 +81,10 @@ private:
std::optional<std::string> token = std::nullopt) const
-> bool;
[[nodiscard]] auto get_s3_config() const -> const s3_config & {
return s3_config_;
}
protected:
[[nodiscard]] auto create_directory_impl(const std::string &api_path,
api_meta_map &meta)

View File

@ -45,6 +45,9 @@ public:
auto operator=(const sia_provider &) -> sia_provider & = delete;
auto operator=(sia_provider &&) -> sia_provider & = delete;
private:
sia_config sia_config_;
private:
[[nodiscard]] auto get_object_info(const std::string &api_path,
json &object_info) const -> api_error;
@ -52,6 +55,10 @@ private:
[[nodiscard]] auto get_object_list(const std::string &api_path,
nlohmann::json &object_list) const -> bool;
[[nodiscard]] auto get_sia_config() const -> const auto & {
return sia_config_;
}
protected:
[[nodiscard]] auto create_directory_impl(const std::string &api_path,
api_meta_map &meta)

View File

@ -22,6 +22,8 @@
#ifndef REPERTORY_INCLUDE_TYPES_REMOTE_HPP_
#define REPERTORY_INCLUDE_TYPES_REMOTE_HPP_
#include "types/repertory.hpp"
inline constexpr const auto PACKET_SERVICE_FUSE{1U};
inline constexpr const auto PACKET_SERVICE_WINFSP{2U};
@ -32,6 +34,61 @@ inline constexpr const auto PACKET_SERVICE_FLAGS{PACKET_SERVICE_FUSE};
#endif // defined(_WIN32)
namespace repertory::remote {
struct remote_config final {
std::uint16_t api_port{};
std::string encryption_token;
std::string host_name_or_ip;
std::uint8_t max_connections{20U};
std::uint32_t recv_timeout_ms{120U * 1000U};
std::uint32_t send_timeout_ms{30U * 1000U};
auto operator==(const remote_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return api_port == cfg.api_port &&
encryption_token == cfg.encryption_token &&
host_name_or_ip == cfg.host_name_or_ip &&
max_connections == cfg.max_connections &&
recv_timeout_ms == cfg.recv_timeout_ms &&
send_timeout_ms == cfg.send_timeout_ms;
}
return true;
}
auto operator!=(const remote_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return not(cfg == *this);
}
return false;
}
};
struct remote_mount final {
std::uint16_t api_port{};
std::uint8_t client_pool_size{20U};
bool enable{false};
std::string encryption_token;
auto operator==(const remote_mount &cfg) const noexcept -> bool {
if (&cfg == this) {
return true;
}
return api_port == cfg.api_port &&
client_pool_size == cfg.client_pool_size && enable == cfg.enable &&
encryption_token == cfg.encryption_token;
}
auto operator!=(const remote_mount &cfg) const noexcept -> bool {
if (&cfg == this) {
return false;
}
return not(cfg == *this);
}
};
using block_count = std::uint64_t;
using block_size = std::uint32_t;
using file_handle = std::uint64_t;
@ -155,9 +212,51 @@ struct statfs_x final : public statfs {
#if !defined(_WIN32)
[[nodiscard]] auto create_open_flags(std::uint32_t flags) -> open_flags;
[[nodiscard]] auto
create_os_open_flags(const open_flags &flags) -> std::uint32_t;
[[nodiscard]] auto create_os_open_flags(const open_flags &flags)
-> std::uint32_t;
#endif // !defined(_WIN32)
} // namespace repertory::remote
NLOHMANN_JSON_NAMESPACE_BEGIN
template <> struct adl_serializer<repertory::remote::remote_config> {
static void to_json(json &data,
const repertory::remote::remote_config &value) {
data[repertory::JSON_API_PORT] = value.api_port;
data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token;
data[repertory::JSON_HOST_NAME_OR_IP] = value.host_name_or_ip;
data[repertory::JSON_MAX_CONNECTIONS] = value.max_connections;
data[repertory::JSON_RECV_TIMEOUT_MS] = value.recv_timeout_ms;
data[repertory::JSON_SEND_TIMEOUT_MS] = value.send_timeout_ms;
}
static void from_json(const json &data,
repertory::remote::remote_config &value) {
data.at(repertory::JSON_API_PORT).get_to(value.api_port);
data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token);
data.at(repertory::JSON_HOST_NAME_OR_IP).get_to(value.host_name_or_ip);
data.at(repertory::JSON_MAX_CONNECTIONS).get_to(value.max_connections);
data.at(repertory::JSON_RECV_TIMEOUT_MS).get_to(value.recv_timeout_ms);
data.at(repertory::JSON_SEND_TIMEOUT_MS).get_to(value.send_timeout_ms);
}
};
template <> struct adl_serializer<repertory::remote::remote_mount> {
static void to_json(json &data,
const repertory::remote::remote_mount &value) {
data[repertory::JSON_API_PORT] = value.api_port;
data[repertory::JSON_CLIENT_POOL_SIZE] = value.client_pool_size;
data[repertory::JSON_ENABLE_REMOTE_MOUNT] = value.enable;
data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token;
}
static void from_json(const json &data,
repertory::remote::remote_mount &value) {
data.at(repertory::JSON_API_PORT).get_to(value.api_port);
data.at(repertory::JSON_CLIENT_POOL_SIZE).get_to(value.client_pool_size);
data.at(repertory::JSON_ENABLE_REMOTE_MOUNT).get_to(value.enable);
data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token);
}
};
NLOHMANN_JSON_NAMESPACE_END
#endif // REPERTORY_INCLUDE_TYPES_REMOTE_HPP_

View File

@ -23,6 +23,95 @@
#define REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_
namespace repertory {
template <typename data_t> class atomic final {
public:
atomic() : mtx_(std::make_shared<std::mutex>()) {}
atomic(const atomic &at_data)
: data_(at_data.load()), mtx_(std::make_shared<std::mutex>()) {}
atomic(data_t data)
: data_(std::move(data)), mtx_(std::make_shared<std::mutex>()) {}
atomic(atomic &&) = default;
~atomic() = default;
private:
data_t data_;
std::shared_ptr<std::mutex> mtx_;
public:
[[nodiscard]] auto load() const -> data_t {
mutex_lock lock(*mtx_);
return data_;
}
auto store(data_t data) -> data_t {
mutex_lock lock(*mtx_);
data_ = std::move(data);
return data_;
}
auto operator=(const atomic &at_data) -> atomic & {
if (&at_data == this) {
return *this;
}
store(at_data.load());
return *this;
}
auto operator=(atomic &&) -> atomic & = default;
auto operator=(data_t data) -> atomic & {
if (&data == &data_) {
return *this;
}
store(std::move(data));
return *this;
}
[[nodiscard]] auto operator==(const atomic &at_data) const -> bool {
if (&at_data == this) {
return true;
}
mutex_lock lock(*mtx_);
return at_data.load() == data_;
}
[[nodiscard]] auto operator==(const data_t &data) const -> bool {
if (&data == &data_) {
return true;
}
mutex_lock lock(*mtx_);
return data == data_;
}
[[nodiscard]] auto operator!=(const atomic &at_data) const -> bool {
if (&at_data == this) {
return false;
}
mutex_lock lock(*mtx_);
return at_data.load() != data_;
}
[[nodiscard]] auto operator!=(const data_t &data) const -> bool {
if (&data == &data_) {
return false;
}
mutex_lock lock(*mtx_);
return data != data_;
}
[[nodiscard]] operator data_t() const { return load(); }
};
inline constexpr const auto max_time{
std::numeric_limits<std::uint64_t>::max(),
};
@ -105,8 +194,9 @@ enum class database_type {
rocksdb,
sqlite,
};
[[nodiscard]] auto database_type_from_string(std::string type,
const database_type &default_type)
[[nodiscard]] auto
database_type_from_string(std::string type,
database_type default_type = database_type::rocksdb)
-> database_type;
[[nodiscard]] auto database_type_to_string(const database_type &type)
@ -117,15 +207,16 @@ enum class download_type {
fallback,
ring_buffer,
};
[[nodiscard]] auto download_type_from_string(std::string type,
const download_type &default_type)
[[nodiscard]] auto
download_type_from_string(std::string type,
download_type default_type = download_type::fallback)
-> download_type;
[[nodiscard]] auto download_type_to_string(const download_type &type)
-> std::string;
enum class exit_code : std::int32_t {
success,
success = 0,
communication_error = -1,
file_creation_failed = -2,
incompatible_version = -3,
@ -193,28 +284,27 @@ struct directory_item final {
std::uint64_t size{};
api_meta_map meta;
bool resolved{false};
[[nodiscard]] static auto from_json(const json &item) -> directory_item {
directory_item ret{};
ret.api_path = item["path"].get<std::string>();
ret.api_parent = item["parent"].get<std::string>();
ret.directory = item["directory"].get<bool>();
ret.size = item["size"].get<std::uint64_t>();
ret.meta = item["meta"].get<api_meta_map>();
return ret;
}
[[nodiscard]] auto to_json() const -> json {
return {
{"path", api_path}, {"parent", api_parent}, {"size", size},
{"directory", directory}, {"meta", meta},
};
}
};
struct encrypt_config final {
std::string encryption_token;
std::string path;
auto operator==(const encrypt_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return encryption_token == cfg.encryption_token && path == cfg.path;
}
return true;
}
auto operator!=(const encrypt_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return not(cfg == *this);
}
return false;
}
};
struct filesystem_item final {
@ -243,6 +333,7 @@ struct host_config final {
host_name_or_ip == cfg.host_name_or_ip && path == cfg.path &&
protocol == cfg.protocol && timeout_ms == cfg.timeout_ms;
}
return true;
}
@ -250,42 +341,11 @@ struct host_config final {
if (&cfg != this) {
return not(cfg == *this);
}
return false;
}
};
#if defined(__GNUG__)
__attribute__((unused))
#endif
static void
to_json(json &data, const host_config &cfg) {
data = json{
{"AgentString", cfg.agent_string},
{"ApiPassword", cfg.api_password},
{"ApiPort", cfg.api_port},
{"ApiUser", cfg.api_user},
{"HostNameOrIp", cfg.host_name_or_ip},
{"Path", cfg.path},
{"Protocol", cfg.protocol},
{"TimeoutMs", cfg.timeout_ms},
};
}
#if defined(__GNUG__)
__attribute__((unused))
#endif
static void
from_json(const json &data, host_config &cfg) {
data.at("AgentString").get_to(cfg.agent_string);
data.at("ApiPassword").get_to(cfg.api_password);
data.at("ApiPort").get_to(cfg.api_port);
data.at("AuthUser").get_to(cfg.api_user);
data.at("HostNameOrIp").get_to(cfg.host_name_or_ip);
data.at("Path").get_to(cfg.path);
data.at("Protocol").get_to(cfg.protocol);
data.at("TimeoutMs").get_to(cfg.timeout_ms);
}
struct s3_config final {
std::string access_key;
std::string bucket;
@ -296,10 +356,46 @@ struct s3_config final {
std::string url;
bool use_path_style{false};
bool use_region_in_url{false};
auto operator==(const s3_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return access_key == cfg.access_key && bucket == cfg.bucket &&
encryption_token == cfg.encryption_token && region == cfg.region &&
secret_key == cfg.secret_key && timeout_ms == cfg.timeout_ms &&
url == cfg.url && use_path_style == cfg.use_path_style &&
use_region_in_url == cfg.use_region_in_url;
}
return true;
}
auto operator!=(const s3_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return not(cfg == *this);
}
return false;
}
};
struct sia_config final {
std::string bucket;
auto operator==(const sia_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return bucket == cfg.bucket;
}
return true;
}
auto operator!=(const sia_config &cfg) const noexcept -> bool {
if (&cfg != this) {
return not(cfg == *this);
}
return false;
}
};
using api_file_list = std::vector<api_file>;
@ -307,6 +403,196 @@ using api_file_provider_callback = std::function<void(api_file &)>;
using api_item_added_callback = std::function<api_error(bool, api_file &)>;
using directory_item_list = std::vector<directory_item>;
using meta_provider_callback = std::function<void(directory_item &)>;
inline constexpr const auto JSON_ACCESS_KEY{"AccessKey"};
inline constexpr const auto JSON_AGENT_STRING{"AgentString"};
inline constexpr const auto JSON_API_AUTH{"ApiAuth"};
inline constexpr const auto JSON_API_PARENT{"ApiParent"};
inline constexpr const auto JSON_API_PASSWORD{"ApiPassword"};
inline constexpr const auto JSON_API_PATH{"ApiPath"};
inline constexpr const auto JSON_API_PORT{"ApiPort"};
inline constexpr const auto JSON_API_USER{"ApiUser"};
inline constexpr const auto JSON_BACKGROUND_DOWNLOAD_TIMEOUT_SECS{
"ChunkDownloaderTimeoutSeconds"};
inline constexpr const auto JSON_BUCKET{"Bucket"};
inline constexpr const auto JSON_CLIENT_POOL_SIZE{"ClientPoolSize"};
inline constexpr const auto JSON_DATABASE_TYPE{"DatabaseType"};
inline constexpr const auto JSON_DIRECTORY{"Directory"};
inline constexpr const auto JSON_ENABLE_CHUNK_DOWNLOADER_TIMEOUT{
"EnableChunkDownloaderTimeout"};
inline constexpr const auto JSON_ENABLE_COMM_DURATION_EVENTS{
"EnableCommDurationEvents"};
inline constexpr const auto JSON_ENABLE_DRIVE_EVENTS{"EnableDriveEvents"};
inline constexpr const auto JSON_ENABLE_MOUNT_MANAGER{"EnableMountManager"};
inline constexpr const auto JSON_ENABLE_REMOTE_MOUNT{"Enable"};
inline constexpr const auto JSON_ENCRYPTION_TOKEN{"EncryptionToken"};
inline constexpr const auto JSON_ENCRYPT_CONFIG{"EncryptConfig"};
inline constexpr const auto JSON_EVENT_LEVEL{"EventLevel"};
inline constexpr const auto JSON_EVICTION_DELAY_MINS{"EvictionDelayMinutes"};
inline constexpr const auto JSON_EVICTION_USE_ACCESS_TIME{
"EvictionUseAccessedTime"};
inline constexpr const auto JSON_HIGH_FREQ_INTERVAL_SECS{
"HighFreqIntervalSeconds"};
inline constexpr const auto JSON_HOST_CONFIG{"HostConfig"};
inline constexpr const auto JSON_HOST_NAME_OR_IP{"HostNameOrIp"};
inline constexpr const auto JSON_LOW_FREQ_INTERVAL_SECS{
"LowFreqIntervalSeconds"};
inline constexpr const auto JSON_MAX_CACHE_SIZE_BYTES{"MaxCacheSizeBytes"};
inline constexpr const auto JSON_MAX_CONNECTIONS{"MaxConnections"};
inline constexpr const auto JSON_MAX_UPLOAD_COUNT{"MaxUploadCount"};
inline constexpr const auto JSON_MED_FREQ_INTERVAL_SECS{
"MedFreqIntervalSeconds"};
inline constexpr const auto JSON_META{"Meta"};
inline constexpr const auto JSON_ONLINE_CHECK_RETRY_SECS{
"OnlineCheckRetrySeconds"};
inline constexpr const auto JSON_ORPHANED_FILE_RETENTION_DAYS{
"OrphanedFileRetentionDays"};
inline constexpr const auto JSON_PATH{"Path"};
inline constexpr const auto JSON_PREFERRED_DOWNLOAD_TYPE{
"PreferredDownloadType"};
inline constexpr const auto JSON_PROTOCOL{"Protocol"};
inline constexpr const auto JSON_RECV_TIMEOUT_MS{"ReceiveTimeoutMs"};
inline constexpr const auto JSON_REGION{"Region"};
inline constexpr const auto JSON_REMOTE_CONFIG{"RemoteConfig"};
inline constexpr const auto JSON_REMOTE_MOUNT{"RemoteMount"};
inline constexpr const auto JSON_RETRY_READ_COUNT{"RetryReadCount"};
inline constexpr const auto JSON_RING_BUFFER_FILE_SIZE{"RingBufferFileSize"};
inline constexpr const auto JSON_S3_CONFIG{"S3Config"};
inline constexpr const auto JSON_SECRET_KEY{"SecretKey"};
inline constexpr const auto JSON_SEND_TIMEOUT_MS{"SendTimeoutMs"};
inline constexpr const auto JSON_SIA_CONFIG{"SiaConfig"};
inline constexpr const auto JSON_SIZE{"Size"};
inline constexpr const auto JSON_TASK_WAIT_MS{"TaskWaitMs"};
inline constexpr const auto JSON_TIMEOUT_MS{"TimeoutMs"};
inline constexpr const auto JSON_URL{"URL"};
inline constexpr const auto JSON_USE_PATH_STYLE{"UsePathStyle"};
inline constexpr const auto JSON_USE_REGION_IN_URL{"UseRegionInURL"};
inline constexpr const auto JSON_VERSION{"Version"};
} // namespace repertory
NLOHMANN_JSON_NAMESPACE_BEGIN
template <> struct adl_serializer<repertory::directory_item> {
static void to_json(json &data, const repertory::directory_item &value) {
data[repertory::JSON_API_PARENT] = value.api_parent;
data[repertory::JSON_API_PATH] = value.api_path;
data[repertory::JSON_DIRECTORY] = value.directory;
data[repertory::JSON_META] = value.meta;
data[repertory::JSON_SIZE] = value.size;
}
static void from_json(const json &data, repertory::directory_item &value) {
data.at(repertory::JSON_API_PARENT).get_to<std::string>(value.api_parent);
data.at(repertory::JSON_API_PATH).get_to<std::string>(value.api_path);
data.at(repertory::JSON_DIRECTORY).get_to<bool>(value.directory);
data.at(repertory::JSON_META).get_to<repertory::api_meta_map>(value.meta);
data.at(repertory::JSON_SIZE).get_to<std::uint64_t>(value.size);
}
};
template <> struct adl_serializer<repertory::encrypt_config> {
static void to_json(json &data, const repertory::encrypt_config &value) {
data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token;
data[repertory::JSON_PATH] = value.path;
}
static void from_json(const json &data, repertory::encrypt_config &value) {
data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token);
data.at(repertory::JSON_PATH).get_to(value.path);
}
};
template <> struct adl_serializer<repertory::host_config> {
static void to_json(json &data, const repertory::host_config &value) {
data[repertory::JSON_AGENT_STRING] = value.agent_string;
data[repertory::JSON_API_PASSWORD] = value.api_password;
data[repertory::JSON_API_PORT] = value.api_port;
data[repertory::JSON_API_USER] = value.api_user;
data[repertory::JSON_HOST_NAME_OR_IP] = value.host_name_or_ip;
data[repertory::JSON_PATH] = value.path;
data[repertory::JSON_PROTOCOL] = value.protocol;
data[repertory::JSON_TIMEOUT_MS] = value.timeout_ms;
}
static void from_json(const json &data, repertory::host_config &value) {
data.at(repertory::JSON_AGENT_STRING).get_to(value.agent_string);
data.at(repertory::JSON_API_PASSWORD).get_to(value.api_password);
data.at(repertory::JSON_API_PORT).get_to(value.api_port);
data.at(repertory::JSON_API_USER).get_to(value.api_user);
data.at(repertory::JSON_HOST_NAME_OR_IP).get_to(value.host_name_or_ip);
data.at(repertory::JSON_PATH).get_to(value.path);
data.at(repertory::JSON_PROTOCOL).get_to(value.protocol);
data.at(repertory::JSON_TIMEOUT_MS).get_to(value.timeout_ms);
}
};
template <> struct adl_serializer<repertory::s3_config> {
static void to_json(json &data, const repertory::s3_config &value) {
data[repertory::JSON_ACCESS_KEY] = value.access_key;
data[repertory::JSON_BUCKET] = value.bucket;
data[repertory::JSON_ENCRYPTION_TOKEN] = value.encryption_token;
data[repertory::JSON_REGION] = value.region;
data[repertory::JSON_SECRET_KEY] = value.secret_key;
data[repertory::JSON_TIMEOUT_MS] = value.timeout_ms;
data[repertory::JSON_URL] = value.url;
data[repertory::JSON_USE_PATH_STYLE] = value.use_path_style;
data[repertory::JSON_USE_REGION_IN_URL] = value.use_region_in_url;
}
static void from_json(const json &data, repertory::s3_config &value) {
data.at(repertory::JSON_ACCESS_KEY).get_to(value.access_key);
data.at(repertory::JSON_BUCKET).get_to(value.bucket);
data.at(repertory::JSON_ENCRYPTION_TOKEN).get_to(value.encryption_token);
data.at(repertory::JSON_REGION).get_to(value.region);
data.at(repertory::JSON_SECRET_KEY).get_to(value.secret_key);
data.at(repertory::JSON_TIMEOUT_MS).get_to(value.timeout_ms);
data.at(repertory::JSON_URL).get_to(value.url);
data.at(repertory::JSON_USE_PATH_STYLE).get_to(value.use_path_style);
data.at(repertory::JSON_USE_REGION_IN_URL).get_to(value.use_region_in_url);
}
};
template <> struct adl_serializer<repertory::sia_config> {
static void to_json(json &data, const repertory::sia_config &value) {
data[repertory::JSON_BUCKET] = value.bucket;
}
static void from_json(const json &data, repertory::sia_config &value) {
data.at(repertory::JSON_BUCKET).get_to(value.bucket);
}
};
template <typename data_t> struct adl_serializer<repertory::atomic<data_t>> {
static void to_json(json &data, const repertory::atomic<data_t> &value) {
data = value.load();
}
static void from_json(const json &data, repertory::atomic<data_t> &value) {
value.store(data.get<data_t>());
}
};
template <typename primitive_t>
struct adl_serializer<std::atomic<primitive_t>> {
static void to_json(json &data, const std::atomic<primitive_t> &value) {
data = value.load();
}
static void from_json(const json &data, std::atomic<primitive_t> &value) {
value.store(data.get<primitive_t>());
}
};
template <> struct adl_serializer<std::atomic<repertory::database_type>> {
static void to_json(json &data,
const std::atomic<repertory::database_type> &value) {
data = repertory::database_type_to_string(value.load());
}
static void from_json(const json &data,
std::atomic<repertory::database_type> &value) {
value.store(repertory::database_type_from_string(data.get<std::string>()));
}
};
NLOHMANN_JSON_NAMESPACE_END
#endif // REPERTORY_INCLUDE_TYPES_REPERTORY_HPP_

File diff suppressed because it is too large Load Diff

View File

@ -38,18 +38,8 @@ E_SIMPLE2(packet_client_timeout, error, true,
);
// clang-format on
packet_client::packet_client(std::string host_name_or_ip,
std::uint8_t max_connections, std::uint16_t port,
std::uint16_t receive_timeout,
std::uint16_t send_timeout,
std::string encryption_token)
: host_name_or_ip_(std::move(host_name_or_ip)),
max_connections_(max_connections == 0U ? 20U : max_connections),
port_(port),
receive_timeout_(receive_timeout),
send_timeout_(send_timeout),
encryption_token_(std::move(encryption_token)),
unique_id_(utils::create_uuid_string()) {}
packet_client::packet_client(remote::remote_config cfg)
: cfg_(std::move(cfg)), unique_id_(utils::create_uuid_string()) {}
packet_client::~packet_client() {
allow_connections_ = false;
@ -115,7 +105,7 @@ auto packet_client::get_client() -> std::shared_ptr<packet_client::client> {
void packet_client::put_client(std::shared_ptr<client> &cli) {
mutex_lock clientsLock(clients_mutex_);
if (clients_.size() < max_connections_) {
if (clients_.size() < cfg_.max_connections) {
clients_.emplace_back(cli);
}
}
@ -144,7 +134,7 @@ auto packet_client::read_packet(client &cli, packet &response)
read_buffer();
response = std::move(buffer);
auto ret = response.decrypt(encryption_token_);
auto ret = response.decrypt(cfg_.encryption_token);
if (ret == 0) {
ret = response.decode(cli.nonce);
}
@ -157,8 +147,9 @@ void packet_client::resolve() {
return;
}
resolve_results_ = tcp::resolver(io_context_)
.resolve(host_name_or_ip_, std::to_string(port_));
resolve_results_ =
tcp::resolver(io_context_)
.resolve(cfg_.host_name_or_ip, std::to_string(cfg_.api_port));
}
auto packet_client::send(std::string_view method, std::uint32_t &service_flags)
@ -193,7 +184,7 @@ auto packet_client::send(std::string_view method, packet &request,
if (current_client) {
try {
request.encode_top(current_client->nonce);
request.encrypt(encryption_token_);
request.encrypt(cfg_.encryption_token);
timeout request_timeout(
[method, current_client]() {
@ -201,7 +192,7 @@ auto packet_client::send(std::string_view method, packet &request,
"request", std::string{method});
packet_client::close(*current_client);
},
std::chrono::seconds(send_timeout_));
std::chrono::milliseconds(cfg_.send_timeout_ms));
std::uint32_t offset{};
while (offset < request.get_size()) {
@ -223,7 +214,7 @@ auto packet_client::send(std::string_view method, packet &request,
"response", std::string{method});
packet_client::close(*current_client);
},
std::chrono::seconds(receive_timeout_));
std::chrono::milliseconds(cfg_.recv_timeout_ms));
ret = read_packet(*current_client, response);
response_timeout.disable();

View File

@ -115,7 +115,7 @@ auto directory_iterator::get_directory_item(const std::string &api_path,
auto directory_iterator::get_json(std::size_t offset, json &item) -> int {
if (offset < items_.size()) {
item = items_[offset].to_json();
item = json(items_.at(offset));
return 0;
}

View File

@ -36,10 +36,8 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
-> bool {
REPERTORY_USES_FUNCTION_NAME();
auto check_file = utils::file::file{file_path};
auto reference_time =
check_file.get_time(config_.get_eviction_uses_accessed_time()
auto file = utils::file::file{file_path};
auto reference_time = file.get_time(config_.get_eviction_uses_accessed_time()
? utils::file::time_type::accessed
: utils::file::time_type::modified);
@ -49,18 +47,17 @@ auto eviction::check_minimum_requirements(const std::string &file_path)
return false;
}
auto delay = (config_.get_eviction_delay_mins() * 60UL) *
auto delay =
static_cast<std::uint64_t>(config_.get_eviction_delay_mins() * 60U) *
utils::time::NANOS_PER_SECOND;
return ((reference_time.value() + static_cast<std::uint64_t>(delay)) <=
utils::time::get_time_now());
return (reference_time.value() + delay) <= utils::time::get_time_now();
}
auto eviction::get_filtered_cached_files() -> std::deque<std::string> {
auto list =
utils::file::get_directory_files(config_.get_cache_directory(), true);
list.erase(std::remove_if(list.begin(), list.end(),
[this](const std::string &path) -> bool {
[this](auto &&path) -> bool {
return not this->check_minimum_requirements(path);
}),
list.end());
@ -70,65 +67,38 @@ auto eviction::get_filtered_cached_files() -> std::deque<std::string> {
void eviction::service_function() {
REPERTORY_USES_FUNCTION_NAME();
auto should_evict = true;
// Handle maximum cache size eviction
auto used_bytes =
utils::file::directory{config_.get_cache_directory()}.size();
if (config_.get_enable_max_cache_size()) {
should_evict = (used_bytes > config_.get_max_cache_size_bytes());
}
if (should_evict) {
// Remove cached source files that don't meet minimum requirements
auto cached_files_list = get_filtered_cached_files();
while (not get_stop_requested() && should_evict &&
not cached_files_list.empty()) {
auto was_file_evicted{false};
while (not get_stop_requested() && not cached_files_list.empty()) {
auto file_path = cached_files_list.front();
cached_files_list.pop_front();
try {
std::string api_path;
if (provider_.get_api_path_from_source(
cached_files_list.front(), api_path) == api_error::success) {
api_file file{};
filesystem_item fsi{};
if (provider_.get_filesystem_item_and_file(api_path, file, fsi) ==
if (provider_.get_api_path_from_source(file_path, api_path) !=
api_error::success) {
// Only evict files that match expected size
auto opt_size = utils::file::file{cached_files_list.front()}.size();
if (opt_size.has_value()) {
auto file_size{opt_size.value()};
if (file_size == fsi.size) {
// Try to evict file
if (fm_.evict_file(fsi.api_path) &&
config_.get_enable_max_cache_size()) {
// Restrict number of items evicted if maximum cache size is
// enabled
used_bytes -= file_size;
should_evict =
(used_bytes > config_.get_max_cache_size_bytes());
}
}
} else {
utils::error::raise_api_path_error(
function_name, file.api_path, file.source_path,
utils::get_last_error_code(), "failed to get file size");
}
continue;
}
if (file_mgr_.evict_file(api_path)) {
was_file_evicted = true;
}
} catch (const std::exception &ex) {
utils::error::raise_error(function_name, ex,
"failed to process cached file|sp|" +
cached_files_list.front());
}
cached_files_list.pop_front();
utils::error::raise_error(
function_name, ex,
fmt::format("failed to process cached file|sp|{}", file_path));
}
}
if (not get_stop_requested()) {
if (get_stop_requested() || was_file_evicted) {
return;
}
unique_mutex_lock lock(get_mutex());
if (not get_stop_requested()) {
if (get_stop_requested()) {
return;
}
get_notify().wait_for(lock, 30s);
}
}
}
} // namespace repertory

View File

@ -81,8 +81,8 @@ auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid,
struct fuse_file_info * /*file_info*/)
-> api_error {
#else
auto fuse_drive::chown_impl(std::string api_path, uid_t uid,
gid_t gid) -> api_error {
auto fuse_drive::chown_impl(std::string api_path, uid_t uid, gid_t gid)
-> api_error {
#endif
return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
@ -481,8 +481,8 @@ auto fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st,
struct fuse_file_info * /*file_info*/)
-> api_error {
#else
auto fuse_drive::getattr_impl(std::string api_path,
struct stat *unix_st) -> api_error {
auto fuse_drive::getattr_impl(std::string api_path, struct stat *unix_st)
-> api_error {
#endif
auto parent = utils::path::get_parent_api_path(api_path);
@ -565,8 +565,8 @@ auto fuse_drive::getxtimes_impl(std::string api_path, struct timespec *bkuptime,
#endif // __APPLE__
#if FUSE_USE_VERSION >= 30
auto fuse_drive::init_impl(struct fuse_conn_info *conn,
struct fuse_config *cfg) -> void * {
auto fuse_drive::init_impl(struct fuse_conn_info *conn, struct fuse_config *cfg)
-> void * {
#else
void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
#endif
@ -612,7 +612,7 @@ void *fuse_drive::init_impl(struct fuse_conn_info *conn) {
eviction_->start();
}
if (config_.get_enable_remote_mount()) {
if (config_.get_remote_mount().enable) {
remote_server_ = std::make_unique<remote_fuse::remote_server>(
config_, *this, get_mount_location());
}
@ -800,8 +800,9 @@ auto fuse_drive::release_impl(std::string /*api_path*/,
return api_error::success;
}
auto fuse_drive::releasedir_impl(
std::string /*api_path*/, struct fuse_file_info *file_info) -> api_error {
auto fuse_drive::releasedir_impl(std::string /*api_path*/,
struct fuse_file_info *file_info)
-> api_error {
auto iter = directory_cache_->get_directory(file_info->fh);
if (iter == nullptr) {
return api_error::invalid_handle;
@ -819,8 +820,8 @@ auto fuse_drive::rename_directory(const std::string &from_api_path,
}
auto fuse_drive::rename_file(const std::string &from_api_path,
const std::string &to_api_path,
bool overwrite) -> int {
const std::string &to_api_path, bool overwrite)
-> int {
auto res = fm_->rename_file(from_api_path, to_api_path, overwrite);
errno = std::abs(utils::from_api_error(res));
return (res == api_error::success) ? 0 : -1;
@ -830,8 +831,8 @@ auto fuse_drive::rename_file(const std::string &from_api_path,
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path,
unsigned int /*flags*/) -> api_error {
#else
auto fuse_drive::rename_impl(std::string from_api_path,
std::string to_api_path) -> api_error {
auto fuse_drive::rename_impl(std::string from_api_path, std::string to_api_path)
-> api_error {
#endif
auto res = check_parent_access(to_api_path, W_OK | X_OK);
if (res != api_error::success) {
@ -945,15 +946,15 @@ auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
}
#else // __APPLE__
auto fuse_drive::getxattr_impl(std::string api_path, const char *name,
char *value, size_t size,
int &attribute_size) -> api_error {
char *value, size_t size, int &attribute_size)
-> api_error {
return getxattr_common(api_path, name, value, size, attribute_size, nullptr);
}
#endif // __APPLE__
auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
int &required_size,
bool &return_size) -> api_error {
int &required_size, bool &return_size)
-> api_error {
auto check_size = (size == 0);
auto res = check_parent_access(api_path, X_OK);
@ -993,8 +994,8 @@ auto fuse_drive::listxattr_impl(std::string api_path, char *buffer, size_t size,
return res;
}
auto fuse_drive::removexattr_impl(std::string api_path,
const char *name) -> api_error {
auto fuse_drive::removexattr_impl(std::string api_path, const char *name)
-> api_error {
std::string attribute_name;
#if defined(__APPLE__)
auto res = parse_xattr_parameters(name, 0, attribute_name, api_path);
@ -1022,8 +1023,8 @@ auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
uint32_t position) -> api_error {
#else // __APPLE__
auto fuse_drive::setxattr_impl(std::string api_path, const char *name,
const char *value, size_t size,
int flags) -> api_error {
const char *value, size_t size, int flags)
-> api_error {
#endif
std::string attribute_name;
#if defined(__APPLE__)
@ -1101,8 +1102,8 @@ void fuse_drive::set_item_meta(const std::string &api_path,
}
#if defined(__APPLE__)
auto fuse_drive::setattr_x_impl(std::string api_path,
struct setattr_x *attr) -> api_error {
auto fuse_drive::setattr_x_impl(std::string api_path, struct setattr_x *attr)
-> api_error {
bool exists{};
auto res = provider_.is_file(api_path, exists);
if (res != api_error::success) {
@ -1156,7 +1157,7 @@ auto fuse_drive::setattr_x_impl(std::string api_path,
ts[0].tv_sec = attr->acctime.tv_sec;
ts[0].tv_nsec = attr->acctime.tv_nsec;
} else {
struct timeval tv {};
struct timeval tv{};
gettimeofday(&tv, NULL);
ts[0].tv_sec = tv.tv_sec;
ts[0].tv_nsec = tv.tv_usec * 1000;
@ -1201,8 +1202,9 @@ auto fuse_drive::setattr_x_impl(std::string api_path,
return api_error::success;
}
auto fuse_drive::setbkuptime_impl(
std::string api_path, const struct timespec *bkuptime) -> api_error {
auto fuse_drive::setbkuptime_impl(std::string api_path,
const struct timespec *bkuptime)
-> api_error {
return check_and_perform(
api_path, X_OK, [&](api_meta_map &meta) -> api_error {
auto nanos = bkuptime->tv_nsec +
@ -1238,8 +1240,8 @@ auto fuse_drive::setvolname_impl(const char * /*volname*/) -> api_error {
return api_error::success;
}
auto fuse_drive::statfs_x_impl(std::string /*api_path*/,
struct statfs *stbuf) -> api_error {
auto fuse_drive::statfs_x_impl(std::string /*api_path*/, struct statfs *stbuf)
-> api_error {
if (statfs(&config_.get_cache_directory()[0], stbuf) != 0) {
return api_error::os_error;
}
@ -1264,8 +1266,8 @@ auto fuse_drive::statfs_x_impl(std::string /*api_path*/,
return api_error::success;
}
#else // __APPLE__
auto fuse_drive::statfs_impl(std::string /*api_path*/,
struct statvfs *stbuf) -> api_error {
auto fuse_drive::statfs_impl(std::string /*api_path*/, struct statvfs *stbuf)
-> api_error {
if (statvfs(config_.get_cache_directory().data(), stbuf) != 0) {
return api_error::os_error;
}
@ -1345,8 +1347,8 @@ auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2],
struct fuse_file_info * /*file_info*/)
-> api_error {
#else
auto fuse_drive::utimens_impl(std::string api_path,
const struct timespec tv[2]) -> api_error {
auto fuse_drive::utimens_impl(std::string api_path, const struct timespec tv[2])
-> api_error {
#endif
api_meta_map meta;
auto res = provider_.get_item_meta(api_path, meta);

View File

@ -27,12 +27,7 @@
namespace repertory::remote_fuse {
remote_client::remote_client(const app_config &config)
: config_(config),
packet_client_(
config.get_remote_host_name_or_ip(),
config.get_remote_max_connections(), config.get_remote_port(),
config.get_remote_receive_timeout_secs(),
config.get_remote_send_timeout_secs(), config.get_remote_token()) {}
: config_(config), packet_client_(config.get_remote_config()) {}
auto remote_client::fuse_access(const char *path, const std::int32_t &mask)
-> packet::error_type {

View File

@ -47,12 +47,7 @@ E_SIMPLE3(remote_winfsp_client_event, debug, true,
// clang-format on
remote_client::remote_client(const app_config &config)
: config_(config),
packet_client_(
config.get_remote_host_name_or_ip(),
config.get_remote_max_connections(), config.get_remote_port(),
config.get_remote_receive_timeout_secs(),
config.get_remote_send_timeout_secs(), config.get_remote_token()) {}
: config_(config), packet_client_(config.get_remote_config()) {}
auto remote_client::winfsp_can_delete(PVOID file_desc, PWSTR file_name)
-> packet::error_type {

View File

@ -302,27 +302,27 @@ auto remote_winfsp_drive::Overwrite(PVOID /*file_node*/, PVOID file_desc,
BOOLEAN replace_attributes,
UINT64 allocation_size, FileInfo *file_info)
-> NTSTATUS {
remote::file_info fi{};
remote::file_info info{};
auto ret = remote_instance_->winfsp_overwrite(
file_desc, attributes, replace_attributes, allocation_size, &fi);
set_file_info(*file_info, fi);
file_desc, attributes, replace_attributes, allocation_size, &info);
set_file_info(*file_info, info);
return ret;
}
void remote_winfsp_drive::populate_file_info(const json &item,
FSP_FSCTL_FILE_INFO &file_info) {
auto di = directory_item::from_json(item);
file_info.FileSize = di.directory ? 0 : di.size;
auto dir_item = item.get<directory_item>();
file_info.FileSize = dir_item.directory ? 0 : dir_item.size;
file_info.AllocationSize =
utils::divide_with_ceiling(file_info.FileSize, WINFSP_ALLOCATION_UNIT) *
WINFSP_ALLOCATION_UNIT;
file_info.ChangeTime = utils::get_changed_time_from_meta(di.meta);
file_info.CreationTime = utils::get_creation_time_from_meta(di.meta);
file_info.FileAttributes = utils::get_attributes_from_meta(di.meta);
file_info.ChangeTime = utils::get_changed_time_from_meta(dir_item.meta);
file_info.CreationTime = utils::get_creation_time_from_meta(dir_item.meta);
file_info.FileAttributes = utils::get_attributes_from_meta(dir_item.meta);
file_info.HardLinks = 0;
file_info.IndexNumber = 0;
file_info.LastAccessTime = utils::get_accessed_time_from_meta(di.meta);
file_info.LastWriteTime = utils::get_written_time_from_meta(di.meta);
file_info.LastAccessTime = utils::get_accessed_time_from_meta(dir_item.meta);
file_info.LastWriteTime = utils::get_written_time_from_meta(dir_item.meta);
file_info.ReparseTag = 0;
file_info.EaSize = 0;
}

View File

@ -89,8 +89,8 @@ auto winfsp_drive::handle_error(std::string_view function_name,
return ret;
}
auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/,
PWSTR * /*Argv*/) -> NTSTATUS {
auto winfsp_drive::winfsp_service::OnStart(ULONG /*Argc*/, PWSTR * /*Argv*/)
-> NTSTATUS {
REPERTORY_USES_FUNCTION_NAME();
auto mount_location = utils::string::to_lower(
@ -457,9 +457,10 @@ auto winfsp_drive::get_item_meta(const std::string &api_path,
return ret;
}
auto winfsp_drive::get_security_by_name(
PWSTR file_name, PUINT32 attributes, PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size) -> NTSTATUS {
auto winfsp_drive::get_security_by_name(PWSTR file_name, PUINT32 attributes,
PSECURITY_DESCRIPTOR descriptor,
std::uint64_t *descriptor_size)
-> NTSTATUS {
auto api_path =
utils::path::create_api_path(utils::string::to_utf8(file_name));
@ -640,7 +641,7 @@ auto winfsp_drive::Mounted(PVOID host) -> NTSTATUS {
}
auto mount_location = parse_mount_location(file_system_host->MountPoint());
if (config_.get_enable_remote_mount()) {
if (config_.get_remote_mount().enable) {
remote_server_ = std::make_unique<remote_winfsp::remote_server>(
config_, *this, mount_location);
}
@ -720,8 +721,8 @@ auto winfsp_drive::Open(PWSTR file_name, UINT32 create_options,
auto winfsp_drive::Overwrite(PVOID /*file_node*/, PVOID file_desc,
UINT32 attributes, BOOLEAN replace_attributes,
UINT64 /*allocation_size*/,
FileInfo *file_info) -> NTSTATUS {
UINT64 /*allocation_size*/, FileInfo *file_info)
-> NTSTATUS {
REPERTORY_USES_FUNCTION_NAME();
std::string api_path;
@ -827,8 +828,8 @@ void winfsp_drive::populate_file_info(std::uint64_t file_size,
}
auto winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer,
UINT64 offset, ULONG length,
PULONG bytes_transferred) -> NTSTATUS {
UINT64 offset, ULONG length, PULONG bytes_transferred)
-> NTSTATUS {
REPERTORY_USES_FUNCTION_NAME();
*bytes_transferred = 0U;
@ -883,8 +884,8 @@ auto winfsp_drive::Read(PVOID /*file_node*/, PVOID file_desc, PVOID buffer,
auto winfsp_drive::ReadDirectory(PVOID /*file_node*/, PVOID file_desc,
PWSTR /*pattern*/, PWSTR marker, PVOID buffer,
ULONG buffer_length,
PULONG bytes_transferred) -> NTSTATUS {
ULONG buffer_length, PULONG bytes_transferred)
-> NTSTATUS {
REPERTORY_USES_FUNCTION_NAME();
std::string api_path;
@ -1046,8 +1047,8 @@ auto winfsp_drive::Rename(PVOID /*file_node*/, PVOID /*file_desc*/,
auto winfsp_drive::SetBasicInfo(PVOID /*file_node*/, PVOID file_desc,
UINT32 attributes, UINT64 creation_time,
UINT64 last_access_time, UINT64 last_write_time,
UINT64 change_time,
FileInfo *file_info) -> NTSTATUS {
UINT64 change_time, FileInfo *file_info)
-> NTSTATUS {
REPERTORY_USES_FUNCTION_NAME();
std::string api_path;

View File

@ -24,7 +24,8 @@
#include "utils/string.hpp"
namespace repertory {
auto event_level_from_string(std::string level) -> event_level {
auto event_level_from_string(std::string level, event_level default_level)
-> event_level {
level = utils::string::to_lower(level);
if (level == "critical" || level == "event_level::critical") {
return event_level::critical;
@ -50,7 +51,7 @@ auto event_level_from_string(std::string level) -> event_level {
return event_level::trace;
}
return event_level::info;
return default_level;
}
auto event_level_to_string(event_level level) -> std::string {

View File

@ -93,6 +93,7 @@ auto cache_size_mgr::shrink(std::uint64_t size) -> api_error {
if (cache_size_ >= size) {
cache_size_ -= size;
} else {
// TODO raise warning
cache_size_ = 0U;
}

View File

@ -456,7 +456,7 @@ void base_provider::process_removed_files(std::deque<removed_item> removed_list,
REPERTORY_USES_FUNCTION_NAME();
auto orphaned_directory =
utils::path::combine(config_.get_data_directory(), {"orphaned"});
utils::path::combine(get_config().get_data_directory(), {"orphaned"});
for (const auto &item : removed_list) {
if (stop_requested) {
return;
@ -670,8 +670,10 @@ void base_provider::remove_unmatched_source_files(
return;
}
const auto &cfg = get_config();
auto source_list =
utils::file::directory{config_.get_cache_directory()}.get_files();
utils::file::directory{cfg.get_cache_directory()}.get_files();
for (const auto &source_file : source_list) {
if (stop_requested) {
return;
@ -684,15 +686,15 @@ void base_provider::remove_unmatched_source_files(
}
auto reference_time =
source_file->get_time(config_.get_eviction_uses_accessed_time()
source_file->get_time(cfg.get_eviction_uses_accessed_time()
? utils::file::time_type::accessed
: utils::file::time_type::modified);
if (not reference_time.has_value()) {
continue;
}
auto delay = (config_.get_eviction_delay_mins() * 60UL) *
utils::time::NANOS_PER_SECOND;
auto delay =
(cfg.get_eviction_delay_mins() * 60UL) * utils::time::NANOS_PER_SECOND;
if ((reference_time.value() + static_cast<std::uint64_t>(delay)) >=
utils::time::get_time_now()) {
continue;
@ -736,17 +738,19 @@ auto base_provider::start(api_item_added_callback api_item_added,
auto online{false};
auto unmount_requested{false};
{
const auto &cfg = get_config();
repertory::event_consumer consumer(
"unmount_requested",
[&unmount_requested](const event &) { unmount_requested = true; });
for (std::uint16_t idx = 0U; not online && not unmount_requested &&
(idx < config_.get_online_check_retry_secs());
(idx < cfg.get_online_check_retry_secs());
++idx) {
online = is_online();
if (not online) {
event_system::instance().raise<provider_offline>(
config_.get_host_config().host_name_or_ip,
config_.get_host_config().api_port);
cfg.get_host_config().host_name_or_ip,
cfg.get_host_config().api_port);
std::this_thread::sleep_for(1s);
}
}

View File

@ -38,7 +38,8 @@ const std::string file_table = "file";
} // namespace
namespace repertory {
encrypt_provider::encrypt_provider(app_config &config) : config_(config) {}
encrypt_provider::encrypt_provider(app_config &config)
: config_(config), encrypt_config_(config.get_encrypt_config()) {}
auto encrypt_provider::create_api_file(const std::string &api_path,
bool directory,
@ -115,7 +116,8 @@ auto encrypt_provider::do_fs_operation(
std::function<api_error(const encrypt_config &cfg,
const std::string &source_path)>
callback) const -> api_error {
auto cfg = config_.get_encrypt_config();
const auto &cfg = get_encrypt_config();
std::string source_path{api_path};
if (api_path != "/" && not utils::encryption::decrypt_file_path(
cfg.encryption_token, source_path)) {
@ -327,7 +329,7 @@ auto encrypt_provider::get_file_list(api_file_list &list,
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto cfg = config_.get_encrypt_config();
const auto &cfg = get_encrypt_config();
try {
for (const auto &dir_entry : utils::file::directory{cfg.path}.get_items()) {
@ -501,9 +503,8 @@ auto encrypt_provider::get_item_meta(const std::string &api_path,
}
auto encrypt_provider::get_total_drive_space() const -> std::uint64_t {
auto total_space =
utils::file::get_total_drive_space(config_.get_encrypt_config().path);
return total_space.value_or(0U);
return utils::file::get_total_drive_space(get_encrypt_config().path)
.value_or(0U);
}
auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
@ -521,7 +522,7 @@ auto encrypt_provider::get_total_item_count() const -> std::uint64_t {
auto encrypt_provider::get_used_drive_space() const -> std::uint64_t {
auto free_space =
utils::file::get_free_drive_space(config_.get_encrypt_config().path);
utils::file::get_free_drive_space(get_encrypt_config().path);
return free_space.has_value() ? get_total_drive_space() - free_space.value()
: 0U;
}
@ -585,10 +586,7 @@ auto encrypt_provider::is_file_writeable(const std::string & /*api_path*/) const
}
auto encrypt_provider::is_online() const -> bool {
return utils::file::directory{
config_.get_encrypt_config().path,
}
.exists();
return utils::file::directory{get_encrypt_config().path}.exists();
}
auto encrypt_provider::process_directory_entry(
@ -744,7 +742,7 @@ auto encrypt_provider::read_file_bytes(const std::string &api_path,
auto file_size{opt_size.value()};
auto cfg = config_.get_encrypt_config();
const auto &cfg = get_encrypt_config();
unique_recur_mutex_lock reader_lookup_lock(reader_lookup_mtx_);
@ -848,7 +846,7 @@ auto encrypt_provider::start(api_item_added_callback /*api_item_added*/,
fmt::format("failed to get root|{}", api_error_to_string(result)));
}
auto cfg_path = utils::path::absolute(config_.get_encrypt_config().path);
auto cfg_path = utils::path::absolute(get_encrypt_config().path);
if (result == api_error::success) {
auto cur_path = utils::path::absolute(source_path);
#if defined(_WIN32)

View File

@ -39,12 +39,11 @@
namespace repertory {
s3_provider::s3_provider(app_config &config, i_http_comm &comm)
: base_provider(config, comm) {
get_comm().enable_s3_path_style(config.get_s3_config().use_path_style);
}
: base_provider(config, comm) {}
auto s3_provider::add_if_not_found(
api_file &file, const std::string &object_name) const -> api_error {
auto s3_provider::add_if_not_found(api_file &file,
const std::string &object_name) const
-> api_error {
api_meta_map meta{};
if (get_item_meta(file.api_path, meta) == api_error::item_not_found) {
auto err = create_path_directories(
@ -70,7 +69,7 @@ auto s3_provider::convert_api_date(std::string_view date) -> std::uint64_t {
utils::string::split(date_parts.at(1U), 'Z', true).at(0U)) *
1000000UL;
struct tm tm1 {};
struct tm tm1{};
#if defined(_WIN32)
utils::time::strptime(date_time.c_str(), "%Y-%m-%dT%T", &tm1);
return nanos + utils::time::windows_time_t_to_unix_time(_mkgmtime(&tm1));
@ -85,7 +84,7 @@ auto s3_provider::create_directory_impl(const std::string &api_path,
api_meta_map &meta) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
stop_type stop_requested{false};
@ -138,7 +137,8 @@ auto s3_provider::create_file_extra(const std::string &api_path,
api_meta_map &meta) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
if (not get_config().get_s3_config().encryption_token.empty()) {
const auto &cfg = get_s3_config();
if (not cfg.encryption_token.empty()) {
std::string encrypted_file_path;
auto res = get_item_meta(utils::path::get_parent_api_path(api_path),
META_KEY, encrypted_file_path);
@ -150,7 +150,7 @@ auto s3_provider::create_file_extra(const std::string &api_path,
data_buffer result;
utils::encryption::encrypt_data(
get_config().get_s3_config().encryption_token,
cfg.encryption_token,
*(utils::string::split(api_path, '/', false).end() - 1U), result);
meta[META_KEY] = utils::path::create_api_path(
@ -161,15 +161,17 @@ auto s3_provider::create_file_extra(const std::string &api_path,
return api_error::success;
}
auto s3_provider::create_path_directories(
const std::string &api_path, const std::string &key) const -> api_error {
auto s3_provider::create_path_directories(const std::string &api_path,
const std::string &key) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
if (api_path == "/") {
return api_error::success;
}
auto encryption_token = get_config().get_s3_config().encryption_token;
const auto &cfg = get_s3_config();
auto encryption_token = cfg.encryption_token;
auto is_encrypted = not encryption_token.empty();
auto path_parts = utils::string::split(api_path, '/', false);
@ -179,8 +181,6 @@ auto s3_provider::create_path_directories(
return api_error::error;
}
auto cfg = get_config().get_s3_config();
std::string cur_key{'/'};
std::string cur_path{'/'};
for (std::size_t idx = 0U; idx < path_parts.size(); ++idx) {
@ -242,9 +242,9 @@ auto s3_provider::create_path_directories(
auto s3_provider::decrypt_object_name(std::string &object_name) const
-> api_error {
auto parts = utils::string::split(object_name, '/', false);
for (auto &&part : parts) {
for (auto &part : parts) {
if (not utils::encryption::decrypt_file_name(
get_config().get_s3_config().encryption_token, part)) {
get_s3_config().encryption_token, part)) {
return api_error::decryption_error;
}
}
@ -258,7 +258,7 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const
REPERTORY_USES_FUNCTION_NAME();
try {
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
std::string key;
if (is_encrypted) {
@ -330,11 +330,12 @@ auto s3_provider::get_directory_item_count(const std::string &api_path) const
return 0U;
}
auto s3_provider::get_directory_items_impl(
const std::string &api_path, directory_item_list &list) const -> api_error {
auto s3_provider::get_directory_items_impl(const std::string &api_path,
directory_item_list &list) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
auto ret = api_error::success;
@ -439,14 +440,14 @@ auto s3_provider::get_directory_items_impl(
auto node_list =
doc.select_nodes("/ListBucketResult/CommonPrefixes/Prefix");
for (auto &&node : node_list) {
for (const auto &node : node_list) {
add_directory_item(
true, node.node().text().as_string(), 0U,
[](const directory_item &) -> std::uint64_t { return 0U; });
}
node_list = doc.select_nodes("/ListBucketResult/Contents");
for (auto &&node : node_list) {
for (const auto &node : node_list) {
auto child_object_name = utils::path::create_api_path(
node.node().select_node("Key").node().text().as_string());
if (child_object_name == utils::path::create_api_path(prefix)) {
@ -476,8 +477,8 @@ auto s3_provider::get_directory_items_impl(
return ret;
}
auto s3_provider::get_file(const std::string &api_path,
api_file &file) const -> api_error {
auto s3_provider::get_file(const std::string &api_path, api_file &file) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
try {
@ -516,8 +517,8 @@ auto s3_provider::get_file(const std::string &api_path,
return api_error::error;
}
auto s3_provider::get_file_list(api_file_list &list,
std::string &marker) const -> api_error {
auto s3_provider::get_file_list(api_file_list &list, std::string &marker) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
std::string response_data;
@ -551,7 +552,7 @@ auto s3_provider::get_file_list(api_file_list &list,
}
auto node_list = doc.select_nodes("/ListBucketResult/Contents");
for (auto &&node : node_list) {
for (const auto &node : node_list) {
auto object_name =
std::string{node.node().select_node("Key").node().text().as_string()};
auto api_path{object_name};
@ -559,8 +560,7 @@ auto s3_provider::get_file_list(api_file_list &list,
continue;
}
auto is_encrypted =
not get_config().get_s3_config().encryption_token.empty();
auto is_encrypted = not get_s3_config().encryption_token.empty();
if (is_encrypted) {
auto err = decrypt_object_name(api_path);
if (err != api_error::success) {
@ -593,8 +593,9 @@ auto s3_provider::get_file_list(api_file_list &list,
return grab_more ? api_error::more_data : api_error::success;
}
auto s3_provider::get_last_modified(
bool directory, const std::string &api_path) const -> std::uint64_t {
auto s3_provider::get_last_modified(bool directory,
const std::string &api_path) const
-> std::uint64_t {
bool is_encrypted{};
std::string object_name;
head_object_result result{};
@ -604,13 +605,14 @@ auto s3_provider::get_last_modified(
: utils::time::get_time_now();
}
auto s3_provider::get_object_info(
bool directory, const std::string &api_path, bool &is_encrypted,
std::string &object_name, head_object_result &result) const -> api_error {
auto s3_provider::get_object_info(bool directory, const std::string &api_path,
bool &is_encrypted, std::string &object_name,
head_object_result &result) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
try {
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
is_encrypted = not cfg.encryption_token.empty();
std::string key;
@ -655,13 +657,15 @@ auto s3_provider::get_object_info(
return api_error::error;
}
auto s3_provider::get_object_list(
std::string &response_data, long &response_code,
std::optional<std::string> delimiter, std::optional<std::string> prefix,
std::optional<std::string> token) const -> bool {
auto s3_provider::get_object_list(std::string &response_data,
long &response_code,
std::optional<std::string> delimiter,
std::optional<std::string> prefix,
std::optional<std::string> token) const
-> bool {
curl::requests::http_get get{};
get.allow_timeout = true;
get.aws_service = "aws:amz:" + get_config().get_s3_config().region + ":s3";
get.aws_service = "aws:amz:" + get_s3_config().region + ":s3";
get.path = '/';
get.query["list-type"] = "2";
if (delimiter.has_value() && not delimiter.value().empty()) {
@ -687,8 +691,8 @@ auto s3_provider::get_total_drive_space() const -> std::uint64_t {
return std::numeric_limits<std::int64_t>::max() / std::int64_t(2);
}
auto s3_provider::is_directory(const std::string &api_path,
bool &exists) const -> api_error {
auto s3_provider::is_directory(const std::string &api_path, bool &exists) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
exists = false;
@ -715,8 +719,8 @@ auto s3_provider::is_directory(const std::string &api_path,
return api_error::error;
}
auto s3_provider::is_file(const std::string &api_path,
bool &exists) const -> api_error {
auto s3_provider::is_file(const std::string &api_path, bool &exists) const
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
exists = false;
@ -753,7 +757,7 @@ auto s3_provider::read_file_bytes(const std::string &api_path, std::size_t size,
REPERTORY_USES_FUNCTION_NAME();
try {
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
std::string key;
if (is_encrypted) {
@ -859,7 +863,7 @@ auto s3_provider::remove_directory_impl(const std::string &api_path)
-> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
std::string key;
@ -901,7 +905,7 @@ auto s3_provider::remove_directory_impl(const std::string &api_path)
auto s3_provider::remove_file_impl(const std::string &api_path) -> api_error {
REPERTORY_USES_FUNCTION_NAME();
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
std::string key;
@ -949,6 +953,8 @@ auto s3_provider::rename_file(const std::string & /* from_api_path */,
auto s3_provider::start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool {
event_system::instance().raise<service_started>("s3_provider");
s3_config_ = get_config().get_s3_config();
get_comm().enable_s3_path_style(s3_config_.use_path_style);
return base_provider::start(api_item_added, mgr);
}
@ -972,7 +978,7 @@ auto s3_provider::upload_file_impl(const std::string &api_path,
file_size = opt_size.value();
}
auto cfg = get_config().get_s3_config();
const auto &cfg = get_s3_config();
auto is_encrypted = not cfg.encryption_token.empty();
std::string key;

View File

@ -37,8 +37,7 @@
#include "utils/utils.hpp"
namespace {
[[nodiscard]] auto get_bucket(repertory::sia_config cfg) -> std::string {
repertory::utils::string::trim(cfg.bucket);
[[nodiscard]] auto get_bucket(const repertory::sia_config &cfg) -> std::string {
if (cfg.bucket.empty()) {
return "default";
}
@ -68,7 +67,7 @@ auto sia_provider::create_directory_impl(const std::string &api_path,
curl::requests::http_put_file put_file{};
put_file.allow_timeout = true;
put_file.path = "/api/worker/objects" + api_path + "/";
put_file.query["bucket"] = get_bucket(get_config().get_sia_config());
put_file.query["bucket"] = get_bucket(get_sia_config());
long response_code{};
stop_type stop_requested{};
@ -100,7 +99,7 @@ auto sia_provider::get_directory_item_count(const std::string &api_path) const
std::uint64_t item_count{};
if (object_list.contains("entries")) {
for (auto &&entry : object_list.at("entries")) {
for (const auto &entry : object_list.at("entries")) {
try {
auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name);
@ -137,7 +136,7 @@ auto sia_provider::get_directory_items_impl(const std::string &api_path,
}
if (object_list.contains("entries")) {
for (auto &&entry : object_list.at("entries")) {
for (const auto &entry : object_list.at("entries")) {
try {
auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name);
@ -228,7 +227,7 @@ auto sia_provider::get_file_list(api_file_list &list,
}
if (object_list.contains("entries")) {
for (auto &&entry : object_list.at("entries")) {
for (const auto &entry : object_list.at("entries")) {
auto name = entry.at("name").get<std::string>();
auto entry_api_path = utils::path::create_api_path(name);
@ -289,7 +288,7 @@ auto sia_provider::get_object_info(const std::string &api_path,
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/bus/objects" + api_path;
get.query["bucket"] = get_bucket(get_config().get_sia_config());
get.query["bucket"] = get_bucket(get_sia_config());
get.response_handler = [&object_info](const data_buffer &data,
long response_code) {
@ -330,7 +329,7 @@ auto sia_provider::get_object_list(const std::string &api_path,
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/bus/objects" + api_path + "/";
get.query["bucket"] = get_bucket(get_config().get_sia_config());
get.query["bucket"] = get_bucket(get_sia_config());
get.response_handler = [&object_list](const data_buffer &data,
long response_code) {
@ -364,7 +363,7 @@ auto sia_provider::get_total_drive_space() const -> std::uint64_t {
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/autopilot/config";
get.query["bucket"] = get_bucket(get_config().get_sia_config());
get.query["bucket"] = get_bucket(get_sia_config());
json config_data{};
get.response_handler = [&config_data](const data_buffer &data,
@ -465,7 +464,7 @@ auto sia_provider::is_online() const -> bool {
curl::requests::http_get get{};
get.allow_timeout = true;
get.path = "/api/bus/consensus/state";
get.query["bucket"] = get_bucket(get_config().get_sia_config());
get.query["bucket"] = get_bucket(get_sia_config());
json state_data{};
get.response_handler = [&state_data](const data_buffer &data,
@ -506,7 +505,7 @@ auto sia_provider::read_file_bytes(const std::string &api_path,
curl::requests::http_get get{};
get.path = "/api/worker/objects" + api_path;
get.query["bucket"] = get_bucket(get_config().get_sia_config());
get.query["bucket"] = get_bucket(get_sia_config());
get.range = {{
offset,
offset + size - 1U,
@ -561,7 +560,7 @@ auto sia_provider::remove_directory_impl(const std::string &api_path)
curl::requests::http_delete del{};
del.allow_timeout = true;
del.path = "/api/bus/objects" + api_path + "/";
del.query["bucket"] = get_bucket(get_config().get_sia_config());
del.query["bucket"] = get_bucket(get_sia_config());
long response_code{};
stop_type stop_requested{};
@ -587,7 +586,7 @@ auto sia_provider::remove_file_impl(const std::string &api_path) -> api_error {
curl::requests::http_delete del{};
del.allow_timeout = true;
del.path = "/api/bus/objects" + api_path;
del.query["bucket"] = get_bucket(get_config().get_sia_config());
del.query["bucket"] = get_bucket(get_sia_config());
long response_code{};
stop_type stop_requested{};
@ -619,7 +618,7 @@ auto sia_provider::rename_file(const std::string &from_api_path,
{"mode", "single"},
});
post.path = "/api/bus/objects/rename";
post.query["bucket"] = get_bucket(get_config().get_sia_config());
post.query["bucket"] = get_bucket(get_sia_config());
long response_code{};
stop_type stop_requested{};
@ -644,6 +643,7 @@ auto sia_provider::rename_file(const std::string &from_api_path,
auto sia_provider::start(api_item_added_callback api_item_added,
i_file_manager *mgr) -> bool {
event_system::instance().raise<service_started>("sia_provider");
sia_config_ = get_config().get_sia_config();
return base_provider::start(api_item_added, mgr);
}
@ -660,7 +660,7 @@ auto sia_provider::upload_file_impl(const std::string &api_path,
curl::requests::http_put_file put_file{};
put_file.path = "/api/worker/objects" + api_path;
put_file.query["bucket"] = get_bucket(get_config().get_sia_config());
put_file.query["bucket"] = get_bucket(get_sia_config());
put_file.source_path = source_path;
long response_code{};

View File

@ -36,15 +36,12 @@ full_server::full_server(app_config &config, i_provider &provider,
void full_server::handle_get_directory_items(const httplib::Request &req,
httplib::Response &res) {
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
const auto list = fm_.get_directory_items(api_path);
json items = {{"items", std::vector<json>()}};
for (const auto &item : list) {
items["items"].emplace_back(item.to_json());
}
res.set_content(items.dump(), "application/json");
auto api_path = utils::path::create_api_path(req.get_param_value("api_path"));
res.set_content(json({
{"items", fm_.get_directory_items(api_path)},
})
.dump(),
"application/json");
res.status = 200;
}
@ -66,9 +63,9 @@ void full_server::handle_get_drive_information(const httplib::Request & /*req*/,
void full_server::handle_get_open_files(const httplib::Request & /*req*/,
httplib::Response &res) {
const auto list = fm_.get_open_files();
auto list = fm_.get_open_files();
json open_files = {{"items", std::vector<json>()}};
json open_files;
for (const auto &kv : list) {
open_files["items"].emplace_back(json({
{"path", kv.first},
@ -81,7 +78,10 @@ void full_server::handle_get_open_files(const httplib::Request & /*req*/,
void full_server::handle_get_pinned_files(const httplib::Request & /*req*/,
httplib::Response &res) {
res.set_content(json({{"items", provider_.get_pinned_files()}}).dump(),
res.set_content(json({
{"items", provider_.get_pinned_files()},
})
.dump(),
"application/json");
res.status = 200;
}
@ -90,11 +90,10 @@ void full_server::handle_get_pinned_status(const httplib::Request &req,
httplib::Response &res) {
REPERTORY_USES_FUNCTION_NAME();
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
auto api_path = utils::path::create_api_path(req.get_param_value("api_path"));
std::string pinned;
const auto result = provider_.get_item_meta(api_path, META_PINNED, pinned);
auto result = provider_.get_item_meta(api_path, META_PINNED, pinned);
if (result != api_error::success) {
utils::error::raise_api_path_error(function_name, api_path, result,
"failed to get pinned status");
@ -103,8 +102,10 @@ void full_server::handle_get_pinned_status(const httplib::Request &req,
}
res.set_content(
json(
{{"pinned", pinned.empty() ? false : utils::string::to_bool(pinned)}})
json({
{"pinned",
pinned.empty() ? false : utils::string::to_bool(pinned)},
})
.dump(),
"application/json");
res.status = 200;
@ -114,8 +115,7 @@ void full_server::handle_pin_file(const httplib::Request &req,
httplib::Response &res) {
REPERTORY_USES_FUNCTION_NAME();
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
auto api_path = utils::path::create_api_path(req.get_param_value("api_path"));
bool exists{};
auto result = provider_.is_file(api_path, exists);
@ -143,8 +143,7 @@ void full_server::handle_unpin_file(const httplib::Request &req,
httplib::Response &res) {
REPERTORY_USES_FUNCTION_NAME();
const auto api_path =
utils::path::create_api_path(req.get_param_value("api_path"));
auto api_path = utils::path::create_api_path(req.get_param_value("api_path"));
bool exists{};
auto result = provider_.is_file(api_path, exists);

View File

@ -25,8 +25,7 @@
#include "utils/string.hpp"
namespace repertory {
auto database_type_from_string(std::string type,
const database_type &default_type)
auto database_type_from_string(std::string type, database_type default_type)
-> database_type {
type = utils::string::to_lower(utils::string::trim(type));
if (type == "rocksdb") {
@ -51,8 +50,7 @@ auto database_type_to_string(const database_type &type) -> std::string {
}
}
auto download_type_from_string(std::string type,
const download_type &default_type)
auto download_type_from_string(std::string type, download_type default_type)
-> download_type {
type = utils::string::to_lower(utils::string::trim(type));
if (type == "direct") {

View File

@ -45,15 +45,15 @@ void get_api_authentication_data(std::string &user, std::string &password,
if (success) {
if (user.empty() && password.empty()) {
password = data["ApiAuth"].get<std::string>();
user = data["ApiUser"].get<std::string>();
password = data[JSON_API_AUTH].get<std::string>();
user = data[JSON_API_USER].get<std::string>();
}
port = data["ApiPort"].get<std::uint16_t>();
port = data[JSON_API_PORT].get<std::uint16_t>();
}
}
[[nodiscard]] auto
get_provider_type_from_args(std::vector<const char *> args) -> provider_type {
[[nodiscard]] auto get_provider_type_from_args(std::vector<const char *> args)
-> provider_type {
if (has_option(args, options::s3_option)) {
return provider_type::s3;
}
@ -67,8 +67,8 @@ get_provider_type_from_args(std::vector<const char *> args) -> provider_type {
return provider_type::sia;
}
auto has_option(std::vector<const char *> args,
const std::string &option_name) -> bool {
auto has_option(std::vector<const char *> args, const std::string &option_name)
-> bool {
return std::find_if(args.begin(), args.end(),
[&option_name](const auto &value) -> bool {
return option_name == value;
@ -80,8 +80,8 @@ auto has_option(std::vector<const char *> args, const option &opt) -> bool {
}
auto parse_option(std::vector<const char *> args,
const std::string &option_name,
std::uint8_t count) -> std::vector<std::string> {
const std::string &option_name, std::uint8_t count)
-> std::vector<std::string> {
std::vector<std::string> ret;
auto found{false};
for (std::size_t i = 0U; not found && (i < args.size()); i++) {
@ -119,9 +119,10 @@ auto parse_string_option(std::vector<const char *> args, const option &opt,
return ret;
}
auto parse_drive_options(
std::vector<const char *> args, [[maybe_unused]] provider_type &prov,
[[maybe_unused]] std::string &data_directory) -> std::vector<std::string> {
auto parse_drive_options(std::vector<const char *> args,
[[maybe_unused]] provider_type &prov,
[[maybe_unused]] std::string &data_directory)
-> std::vector<std::string> {
// Strip out options from command line
const auto &option_list = options::option_list;
std::vector<std::string> drive_args;

View File

@ -71,11 +71,10 @@ mount(std::vector<const char *> args, std::string data_directory,
if (generate_config) {
app_config config(prov, data_directory);
if (prov == provider_type::remote) {
config.set_enable_remote_mount(false);
config.set_is_remote_mount(true);
config.set_remote_host_name_or_ip(remote_host);
config.set_remote_port(remote_port);
config.save();
auto cfg = config.get_remote_config();
cfg.host_name_or_ip = remote_host;
cfg.api_port = remote_port;
config.set_remote_config(cfg);
} else if (prov == provider_type::sia &&
config.get_sia_config().bucket.empty()) {
config.set_value_by_name("SiaConfig.Bucket", unique_id);
@ -128,12 +127,12 @@ mount(std::vector<const char *> args, std::string data_directory,
if (prov == provider_type::remote) {
std::uint16_t port{0U};
if (utils::get_next_available_port(config.get_api_port(), port)) {
config.set_remote_host_name_or_ip(remote_host);
config.set_remote_port(remote_port);
auto cfg = config.get_remote_config();
cfg.host_name_or_ip = remote_host;
cfg.api_port = remote_port;
config.set_remote_config(cfg);
config.set_api_port(port);
config.set_is_remote_mount(true);
config.set_enable_remote_mount(false);
config.save();
try {
remote_drive drive(
config,
@ -161,8 +160,6 @@ mount(std::vector<const char *> args, std::string data_directory,
config.set_value_by_name("SiaConfig.Bucket", unique_id);
}
config.set_is_remote_mount(false);
try {
auto provider = create_provider(prov, config);
repertory_drive drive(config, lock, *provider);

View File

@ -109,8 +109,11 @@ protected:
config->set_enable_drive_events(true);
config->set_event_level(event_level::trace);
config->set_s3_config(src_cfg.get_s3_config());
config->set_enable_remote_mount(true);
config->set_remote_port(30000U);
auto r_cfg = config->get_remote_mount();
r_cfg.enable = true;
r_cfg.api_port = 30000U;
config->set_remote_mount(r_cfg);
}
drive_args = std::vector<std::string>({
@ -152,8 +155,11 @@ protected:
config->set_event_level(event_level::trace);
config->set_host_config(src_cfg.get_host_config());
config->set_sia_config(src_cfg.get_sia_config());
config->set_enable_remote_mount(true);
config->set_remote_port(30000U);
auto r_cfg = config->get_remote_mount();
r_cfg.enable = true;
r_cfg.api_port = 30000U;
config->set_remote_mount(r_cfg);
}
drive_args = std::vector<std::string>({

View File

@ -99,8 +99,11 @@ protected:
config->set_enable_drive_events(true);
config->set_event_level(event_level::trace);
config->set_s3_config(src_cfg.get_s3_config());
config->set_enable_remote_mount(true);
config->set_remote_port(30000U);
auto r_cfg = config->get_remote_mount();
r_cfg.enable = true;
r_cfg.api_port = 30000U;
config->set_remote_mount(r_cfg);
}
drive_args = std::vector<std::string>({
@ -138,8 +141,11 @@ protected:
config->set_event_level(event_level::trace);
config->set_host_config(src_cfg.get_host_config());
config->set_sia_config(src_cfg.get_sia_config());
config->set_enable_remote_mount(true);
config->set_remote_port(30000U);
auto r_cfg = config->get_remote_mount();
r_cfg.enable = true;
r_cfg.api_port = 30000U;
config->set_remote_mount(r_cfg);
}
drive_args = std::vector<std::string>({

View File

@ -0,0 +1,63 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "test_common.hpp"
#include "types/repertory.hpp"
namespace repertory {
TEST(atomic, atomic_primitive) {
atomic<std::uint16_t> value;
value = 5U;
EXPECT_EQ(5U, static_cast<std::uint16_t>(value));
}
TEST(atomic, atomic_primitive_equality) {
atomic<std::uint16_t> value1{5U};
atomic<std::uint16_t> value2{5U};
EXPECT_EQ(value1, value1);
EXPECT_EQ(value2, value2);
EXPECT_EQ(value1, value2);
EXPECT_EQ(static_cast<std::uint16_t>(value1), 5U);
EXPECT_EQ(static_cast<std::uint16_t>(value2), 5U);
}
TEST(atomic, atomic_primitive_inequality) {
atomic<std::uint16_t> value1{5U};
atomic<std::uint16_t> value2{6U};
EXPECT_NE(value1, value2);
EXPECT_NE(static_cast<std::uint16_t>(value1), 6U);
EXPECT_NE(static_cast<std::uint16_t>(value2), 5U);
}
TEST(atomic, atomic_struct) {
atomic<encrypt_config> value{
encrypt_config{
.encryption_token = "token",
.path = "path",
},
};
auto data = static_cast<encrypt_config>(value);
EXPECT_STREQ("token", data.encryption_token.c_str());
EXPECT_STREQ("path", data.path.c_str());
}
} // namespace repertory

View File

@ -31,177 +31,33 @@ namespace repertory {
class config_test : public ::testing::Test {
public:
static console_consumer cs;
static std::atomic<std::uint64_t> idx;
std::string s3_directory{
utils::path::combine(test::get_test_output_dir(), {"config_test", "s3"})};
std::string sia_directory{utils::path::combine(test::get_test_output_dir(),
{"config_test", "sia"})};
std::string s3_directory;
std::string sia_directory;
void SetUp() override {
s3_directory = utils::path::combine(test::get_test_output_dir(),
{
"config_test",
"s3",
std::to_string(++idx),
});
sia_directory = utils::path::combine(test::get_test_output_dir(),
{
"config_test",
"sia",
std::to_string(++idx),
});
event_system::instance().start();
ASSERT_TRUE(
utils::file::directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}))
.remove_recursively());
}
void TearDown() override {
ASSERT_TRUE(
utils::file::directory(
utils::path::combine(test::get_test_output_dir(), {"config_test"}))
.remove_recursively());
event_system::instance().stop();
}
void TearDown() override { event_system::instance().stop(); }
};
const auto DEFAULT_SIA_CONFIG = "{\n"
" \"ApiAuth\": \"\",\n"
" \"ApiPort\": 10000,\n"
" \"ApiUser\": \"repertory\",\n"
" \"ChunkDownloaderTimeoutSeconds\": 30,\n"
" \"DatabaseType\": \"rocksdb\",\n"
" \"EnableChunkDownloaderTimeout\": true,\n"
" \"EnableCommDurationEvents\": false,\n"
" \"EnableDriveEvents\": false,\n"
" \"EnableMaxCacheSize\": false,\n"
#if defined(_WIN32)
" \"EnableMountManager\": false,\n"
#endif
" \"EventLevel\": \"info\",\n"
" \"EvictionDelayMinutes\": 10,\n"
" \"EvictionUsesAccessedTime\": false,\n"
" \"HighFreqIntervalSeconds\": 30,\n"
" \"HostConfig\": {\n"
" \"AgentString\": \"Sia-Agent\",\n"
" \"ApiPassword\": \"\",\n"
" \"ApiPort\": 9980,\n"
" \"HostNameOrIp\": \"localhost\",\n"
" \"TimeoutMs\": 60000\n"
" },\n"
" \"LowFreqIntervalSeconds\": 3600,\n"
" \"MaxCacheSizeBytes\": 21474836480,\n"
" \"MaxUploadCount\": 5,\n"
" \"MedFreqIntervalSeconds\": 120,\n"
" \"OnlineCheckRetrySeconds\": 60,\n"
" \"OrphanedFileRetentionDays\": 15,\n"
" \"PreferredDownloadType\": \"fallback\",\n"
" \"ReadAheadCount\": 4,\n"
" \"RemoteMount\": {\n"
" \"EnableRemoteMount\": false,\n"
" \"IsRemoteMount\": false,\n"
" \"RemoteClientPoolSize\": 10,\n"
" \"RemoteHostNameOrIp\": \"\",\n"
" \"RemoteMaxConnections\": 20,\n"
" \"RemotePort\": 20000,\n"
" \"RemoteReceiveTimeoutSeconds\": 120,\n"
" \"RemoteSendTimeoutSeconds\": 30,\n"
" \"RemoteToken\": \"\"\n"
" },\n"
" \"RetryReadCount\": 6,\n"
" \"RingBufferFileSize\": 512,\n"
" \"SiaConfig\": {\n"
" \"Bucket\": \"\"\n"
" },\n"
" \"TaskWaitMillis\": 100,\n"
" \"Version\": " +
std::to_string(REPERTORY_CONFIG_VERSION) +
"\n"
"}";
const auto DEFAULT_S3_CONFIG = "{\n"
" \"ApiAuth\": \"\",\n"
" \"ApiPort\": 10100,\n"
" \"ApiUser\": \"repertory\",\n"
" \"ChunkDownloaderTimeoutSeconds\": 30,\n"
" \"DatabaseType\": \"rocksdb\",\n"
" \"EnableChunkDownloaderTimeout\": true,\n"
" \"EnableCommDurationEvents\": false,\n"
" \"EnableDriveEvents\": false,\n"
" \"EnableMaxCacheSize\": false,\n"
#if defined(_WIN32)
" \"EnableMountManager\": false,\n"
#endif
" \"EventLevel\": \"info\",\n"
" \"EvictionDelayMinutes\": 10,\n"
" \"EvictionUsesAccessedTime\": false,\n"
" \"HighFreqIntervalSeconds\": 30,\n"
" \"LowFreqIntervalSeconds\": 3600,\n"
" \"MaxCacheSizeBytes\": 21474836480,\n"
" \"MaxUploadCount\": 5,\n"
" \"MedFreqIntervalSeconds\": 120,\n"
" \"OnlineCheckRetrySeconds\": 60,\n"
" \"OrphanedFileRetentionDays\": 15,\n"
" \"PreferredDownloadType\": \"fallback\",\n"
" \"ReadAheadCount\": 4,\n"
" \"RemoteMount\": {\n"
" \"EnableRemoteMount\": false,\n"
" \"IsRemoteMount\": false,\n"
" \"RemoteClientPoolSize\": 10,\n"
" \"RemoteHostNameOrIp\": \"\",\n"
" \"RemoteMaxConnections\": 20,\n"
" \"RemotePort\": 20100,\n"
" \"RemoteReceiveTimeoutSeconds\": 120,\n"
" \"RemoteSendTimeoutSeconds\": 30,\n"
" \"RemoteToken\": \"\"\n"
" },\n"
" \"RetryReadCount\": 6,\n"
" \"RingBufferFileSize\": 512,\n"
" \"S3Config\": {\n"
" \"AccessKey\": \"\",\n"
" \"Bucket\": \"\",\n"
" \"EncryptionToken\": \"\",\n"
" \"Region\": \"any\",\n"
" \"SecretKey\": \"\",\n"
" \"TimeoutMs\": 60000,\n"
" \"URL\": \"\",\n"
" \"UsePathStyle\": false,\n"
" \"UseRegionInURL\": false\n"
" },\n"
" \"TaskWaitMillis\": 100,\n"
" \"Version\": " +
std::to_string(REPERTORY_CONFIG_VERSION) +
"\n"
"}";
TEST_F(config_test, sia_default_settings) {
const auto config_file = utils::path::combine(sia_directory, {"config.json"});
for (int i = 0; i < 2; i++) {
app_config config(provider_type::sia, sia_directory);
config.set_remote_token("");
config.set_api_auth("");
EXPECT_TRUE(config.set_value_by_name("HostConfig.ApiPassword", "").empty());
json data;
EXPECT_TRUE(utils::file::read_json_file(config_file, data));
EXPECT_STREQ(DEFAULT_SIA_CONFIG.c_str(), data.dump(2).c_str());
EXPECT_TRUE(
utils::file::directory(utils::path::combine(sia_directory, {"cache"}))
.exists());
EXPECT_TRUE(
utils::file::directory(utils::path::combine(sia_directory, {"logs"}))
.exists());
}
}
TEST_F(config_test, s3_default_settings) {
const auto config_file = utils::path::combine(s3_directory, {"config.json"});
for (int i = 0; i < 2; i++) {
app_config config(provider_type::s3, s3_directory);
config.set_remote_token("");
config.set_api_auth("");
json data;
EXPECT_TRUE(utils::file::read_json_file(config_file, data));
EXPECT_STREQ(DEFAULT_S3_CONFIG.c_str(), data.dump(2).c_str());
EXPECT_TRUE(
utils::file::directory(utils::path::combine(s3_directory, {"cache"}))
.exists());
EXPECT_TRUE(
utils::file::directory(utils::path::combine(s3_directory, {"logs"}))
.exists());
}
}
console_consumer config_test::cs;
std::atomic<std::uint64_t> config_test::idx{0U};
TEST_F(config_test, api_path) {
std::string original_value;
@ -310,19 +166,6 @@ TEST_F(config_test, enable_drive_events) {
}
}
TEST_F(config_test, enable_max_cache_size) {
bool original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_enable_max_cache_size();
config.set_enable_max_cache_size(not original_value);
EXPECT_EQ(not original_value, config.get_enable_max_cache_size());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_enable_max_cache_size());
}
}
#if defined(_WIN32)
TEST_F(config_test, enable_mount_manager) {
bool original_value;
@ -504,20 +347,6 @@ TEST_F(config_test, orphaned_file_retention_days_maximum_value) {
}
}
TEST_F(config_test, read_ahead_count) {
std::uint8_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_read_ahead_count();
config.set_read_ahead_count(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_read_ahead_count());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_read_ahead_count());
}
}
TEST_F(config_test, get_cache_directory) {
{
app_config config(provider_type::sia, sia_directory);
@ -654,167 +483,170 @@ TEST_F(config_test, get_version) {
}
}
TEST_F(config_test, enable_remote_mount) {
bool original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_enable_remote_mount();
config.set_enable_remote_mount(not original_value);
EXPECT_EQ(not original_value, config.get_enable_remote_mount());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_enable_remote_mount());
}
}
// TEST_F(config_test, enable_remote_mount) {
// bool original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_enable_remote_mount();
// config.set_enable_remote_mount(not original_value);
// EXPECT_EQ(not original_value, config.get_enable_remote_mount());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(not original_value, config.get_enable_remote_mount());
// }
// }
TEST_F(config_test, is_remote_mount) {
bool original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_is_remote_mount();
config.set_is_remote_mount(not original_value);
EXPECT_EQ(not original_value, config.get_is_remote_mount());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(not original_value, config.get_is_remote_mount());
}
}
// TEST_F(config_test, is_remote_mount) {
// bool original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_is_remote_mount();
// config.set_is_remote_mount(not original_value);
// EXPECT_EQ(not original_value, config.get_is_remote_mount());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(not original_value, config.get_is_remote_mount());
// }
// }
TEST_F(config_test, enable_remote_mount_fails_if_remote_mount_is_true) {
app_config config(provider_type::sia, sia_directory);
config.set_is_remote_mount(true);
config.set_enable_remote_mount(true);
EXPECT_FALSE(config.get_enable_remote_mount());
EXPECT_TRUE(config.get_is_remote_mount());
}
// TEST_F(config_test, enable_remote_mount_fails_if_remote_mount_is_true) {
// app_config config(provider_type::sia, sia_directory);
// config.set_is_remote_mount(true);
// config.set_enable_remote_mount(true);
// EXPECT_FALSE(config.get_enable_remote_mount());
// EXPECT_TRUE(config.get_is_remote_mount());
// }
TEST_F(config_test, set_is_remote_mount_fails_if_enable_remote_mount_is_true) {
app_config config(provider_type::sia, sia_directory);
config.set_enable_remote_mount(true);
config.set_is_remote_mount(true);
EXPECT_FALSE(config.get_is_remote_mount());
EXPECT_TRUE(config.get_enable_remote_mount());
}
// TEST_F(config_test, set_is_remote_mount_fails_if_enable_remote_mount_is_true)
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_enable_remote_mount(true);
// config.set_is_remote_mount(true);
// EXPECT_FALSE(config.get_is_remote_mount());
// EXPECT_TRUE(config.get_enable_remote_mount());
// }
TEST_F(config_test, remote_host_name_or_ip) {
{
app_config config(provider_type::sia, sia_directory);
config.set_remote_host_name_or_ip("my.host.name");
EXPECT_STREQ("my.host.name", config.get_remote_host_name_or_ip().c_str());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_STREQ("my.host.name", config.get_remote_host_name_or_ip().c_str());
}
}
// TEST_F(config_test, remote_host_name_or_ip) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_host_name_or_ip("my.host.name");
// EXPECT_STREQ("my.host.name",
// config.get_remote_host_name_or_ip().c_str());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_STREQ("my.host.name",
// config.get_remote_host_name_or_ip().c_str());
// }
// }
TEST_F(config_test, remote_port) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_remote_port();
config.set_remote_port(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_remote_port());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_remote_port());
}
}
// TEST_F(config_test, remote_api_port) {
// std::uint16_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_api_port();
// config.set_remote_api_port(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_api_port());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_api_port());
// }
// }
TEST_F(config_test, remote_receive_timeout_secs) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_remote_receive_timeout_secs();
config.set_remote_receive_timeout_secs(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_remote_receive_timeout_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_remote_receive_timeout_secs());
}
}
// TEST_F(config_test, remote_receive_timeout_secs) {
// std::uint16_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_receive_timeout_secs();
// config.set_remote_receive_timeout_secs(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_receive_timeout_secs());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_receive_timeout_secs());
// }
// }
TEST_F(config_test, remote_send_timeout_secs) {
std::uint16_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_remote_send_timeout_secs();
config.set_remote_send_timeout_secs(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_remote_send_timeout_secs());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_remote_send_timeout_secs());
}
}
// TEST_F(config_test, remote_send_timeout_secs) {
// std::uint16_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_send_timeout_secs();
// config.set_remote_send_timeout_secs(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_send_timeout_secs());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_send_timeout_secs());
// }
// }
TEST_F(config_test, remote_token) {
{
app_config config(provider_type::sia, sia_directory);
config.set_remote_token("myToken");
EXPECT_STREQ("myToken", config.get_remote_token().c_str());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_STREQ("myToken", config.get_remote_token().c_str());
}
}
// TEST_F(config_test, remote_encryption_token) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_encryption_token("myToken");
// EXPECT_STREQ("myToken", config.get_remote_encryption_token().c_str());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_STREQ("myToken", config.get_remote_encryption_token().c_str());
// }
// }
//
// TEST_F(config_test, remote_client_pool_size) {
// std::uint8_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_client_pool_size();
// config.set_remote_client_pool_size(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_client_pool_size());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_client_pool_size());
// }
// }
//
// TEST_F(config_test, remote_client_pool_size_minimum_value) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_client_pool_size(0);
// EXPECT_EQ(5, config.get_remote_client_pool_size());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(5, config.get_remote_client_pool_size());
// }
// }
TEST_F(config_test, remote_client_pool_size) {
std::uint8_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_remote_client_pool_size();
config.set_remote_client_pool_size(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_remote_client_pool_size());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_remote_client_pool_size());
}
}
// TEST_F(config_test, remote_max_connections) {
// std::uint8_t original_value{};
// {
// app_config config(provider_type::sia, sia_directory);
// original_value = config.get_remote_max_connections();
// config.set_remote_max_connections(original_value + 5);
// EXPECT_EQ(original_value + 5, config.get_remote_max_connections());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(original_value + 5, config.get_remote_max_connections());
// }
// }
TEST_F(config_test, remote_client_pool_size_minimum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_remote_client_pool_size(0);
EXPECT_EQ(5, config.get_remote_client_pool_size());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(5, config.get_remote_client_pool_size());
}
}
TEST_F(config_test, remote_max_connections) {
std::uint8_t original_value{};
{
app_config config(provider_type::sia, sia_directory);
original_value = config.get_remote_max_connections();
config.set_remote_max_connections(original_value + 5);
EXPECT_EQ(original_value + 5, config.get_remote_max_connections());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(original_value + 5, config.get_remote_max_connections());
}
}
TEST_F(config_test, remote_max_connections_minimum_value) {
{
app_config config(provider_type::sia, sia_directory);
config.set_remote_max_connections(0);
EXPECT_EQ(1, config.get_remote_max_connections());
}
{
app_config config(provider_type::sia, sia_directory);
EXPECT_EQ(1, config.get_remote_max_connections());
}
}
// TEST_F(config_test, remote_max_connections_minimum_value) {
// {
// app_config config(provider_type::sia, sia_directory);
// config.set_remote_max_connections(0);
// EXPECT_EQ(1, config.get_remote_max_connections());
// }
// {
// app_config config(provider_type::sia, sia_directory);
// EXPECT_EQ(1, config.get_remote_max_connections());
// }
// }
TEST_F(config_test, retry_read_count) {
std::uint16_t original_value{};

View File

@ -0,0 +1,186 @@
/*
Copyright <2018-2024> <scott.e.graves@protonmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include "test_common.hpp"
#include "types/remote.hpp"
#include "types/repertory.hpp"
namespace repertory {
TEST(json_serialize, can_handle_directory_item) {
directory_item cfg{
"api", "parent", true, 2U, {{META_DIRECTORY, "true"}},
};
json data(cfg);
EXPECT_STREQ("api", data.at(JSON_API_PATH).get<std::string>().c_str());
EXPECT_STREQ("parent", data.at(JSON_API_PARENT).get<std::string>().c_str());
EXPECT_TRUE(data.at(JSON_DIRECTORY).get<bool>());
EXPECT_STREQ(
"true", data.at(JSON_META).at(META_DIRECTORY).get<std::string>().c_str());
{
auto cfg2 = data.get<directory_item>();
EXPECT_STREQ(cfg2.api_path.c_str(), cfg.api_path.c_str());
EXPECT_STREQ(cfg2.api_parent.c_str(), cfg.api_parent.c_str());
EXPECT_EQ(cfg2.directory, cfg.directory);
EXPECT_STREQ(cfg2.meta.at(META_DIRECTORY).c_str(),
cfg.meta.at(META_DIRECTORY).c_str());
}
}
TEST(json_serialize, can_handle_encrypt_config) {
encrypt_config cfg{
"token",
"path",
};
json data(cfg);
EXPECT_STREQ("token",
data.at(JSON_ENCRYPTION_TOKEN).get<std::string>().c_str());
EXPECT_STREQ("path", data.at(JSON_PATH).get<std::string>().c_str());
{
auto cfg2 = data.get<encrypt_config>();
EXPECT_STREQ(cfg2.encryption_token.c_str(), cfg.encryption_token.c_str());
EXPECT_STREQ(cfg2.path.c_str(), cfg.path.c_str());
}
}
TEST(json_serialize, can_handle_host_config) {
host_config cfg{
"agent", "pwd", "user", 1024U, "host", "path", "http", 11U,
};
json data(cfg);
EXPECT_STREQ("agent", data.at(JSON_AGENT_STRING).get<std::string>().c_str());
EXPECT_STREQ("pwd", data.at(JSON_API_PASSWORD).get<std::string>().c_str());
EXPECT_STREQ("user", data.at(JSON_API_USER).get<std::string>().c_str());
EXPECT_EQ(1024U, data.at(JSON_API_PORT).get<std::uint16_t>());
EXPECT_STREQ("host",
data.at(JSON_HOST_NAME_OR_IP).get<std::string>().c_str());
EXPECT_STREQ("path", data.at(JSON_PATH).get<std::string>().c_str());
EXPECT_STREQ("http", data.at(JSON_PROTOCOL).get<std::string>().c_str());
EXPECT_EQ(11U, data.at(JSON_TIMEOUT_MS).get<std::uint16_t>());
{
auto cfg2 = data.get<host_config>();
EXPECT_STREQ(cfg2.agent_string.c_str(), cfg.agent_string.c_str());
EXPECT_STREQ(cfg2.api_password.c_str(), cfg.api_password.c_str());
EXPECT_STREQ(cfg2.api_user.c_str(), cfg.api_user.c_str());
EXPECT_EQ(cfg2.api_port, cfg.api_port);
EXPECT_STREQ(cfg2.host_name_or_ip.c_str(), cfg.host_name_or_ip.c_str());
EXPECT_STREQ(cfg2.path.c_str(), cfg.path.c_str());
EXPECT_STREQ(cfg2.protocol.c_str(), cfg.protocol.c_str());
EXPECT_EQ(cfg2.timeout_ms, cfg.timeout_ms);
}
}
TEST(json_serialize, can_handle_remote_config) {
remote::remote_config cfg{
1024U, "token", "host", 11U, 20U, 21U,
};
json data(cfg);
EXPECT_EQ(1024U, data.at(JSON_API_PORT).get<std::uint16_t>());
EXPECT_STREQ("token",
data.at(JSON_ENCRYPTION_TOKEN).get<std::string>().c_str());
EXPECT_STREQ("host",
data.at(JSON_HOST_NAME_OR_IP).get<std::string>().c_str());
EXPECT_EQ(11U, data.at(JSON_MAX_CONNECTIONS).get<std::uint16_t>());
EXPECT_EQ(20U, data.at(JSON_RECV_TIMEOUT_MS).get<std::uint32_t>());
EXPECT_EQ(21U, data.at(JSON_SEND_TIMEOUT_MS).get<std::uint32_t>());
{
auto cfg2 = data.get<remote::remote_config>();
EXPECT_EQ(cfg2.api_port, cfg.api_port);
EXPECT_STREQ(cfg2.encryption_token.c_str(), cfg.encryption_token.c_str());
EXPECT_STREQ(cfg2.host_name_or_ip.c_str(), cfg.host_name_or_ip.c_str());
EXPECT_EQ(cfg2.max_connections, cfg.max_connections);
EXPECT_EQ(cfg2.recv_timeout_ms, cfg.recv_timeout_ms);
EXPECT_EQ(cfg2.send_timeout_ms, cfg.send_timeout_ms);
}
}
TEST(json_serialize, can_handle_remote_mount) {
remote::remote_mount cfg{1024U, 21U, true, "token"};
json data(cfg);
EXPECT_EQ(1024U, data.at(JSON_API_PORT).get<std::uint16_t>());
EXPECT_EQ(21U, data.at(JSON_CLIENT_POOL_SIZE).get<std::uint16_t>());
EXPECT_TRUE(data.at(JSON_ENABLE_REMOTE_MOUNT).get<bool>());
EXPECT_STREQ("token",
data.at(JSON_ENCRYPTION_TOKEN).get<std::string>().c_str());
{
auto cfg2 = data.get<remote::remote_mount>();
EXPECT_EQ(cfg2.api_port, cfg.api_port);
EXPECT_EQ(cfg2.client_pool_size, cfg.client_pool_size);
EXPECT_EQ(cfg2.enable, cfg.enable);
EXPECT_STREQ(cfg2.encryption_token.c_str(), cfg.encryption_token.c_str());
}
}
TEST(json_serialize, can_handle_s3_config) {
s3_config cfg{
"access", "bucket", "token", "region", "secret", 31U, "url", true, false,
};
json data(cfg);
EXPECT_STREQ("access", data.at(JSON_ACCESS_KEY).get<std::string>().c_str());
EXPECT_STREQ("bucket", data.at(JSON_BUCKET).get<std::string>().c_str());
EXPECT_STREQ("token",
data.at(JSON_ENCRYPTION_TOKEN).get<std::string>().c_str());
EXPECT_STREQ("region", data.at(JSON_REGION).get<std::string>().c_str());
EXPECT_STREQ("secret", data.at(JSON_SECRET_KEY).get<std::string>().c_str());
EXPECT_EQ(31U, data.at(JSON_TIMEOUT_MS).get<std::uint32_t>());
EXPECT_STREQ("url", data.at(JSON_URL).get<std::string>().c_str());
EXPECT_TRUE(data.at(JSON_USE_PATH_STYLE).get<bool>());
EXPECT_FALSE(data.at(JSON_USE_REGION_IN_URL).get<bool>());
{
auto cfg2 = data.get<s3_config>();
EXPECT_STREQ(cfg2.access_key.c_str(), cfg.access_key.c_str());
EXPECT_STREQ(cfg2.bucket.c_str(), cfg.bucket.c_str());
EXPECT_STREQ(cfg2.encryption_token.c_str(), cfg.encryption_token.c_str());
EXPECT_STREQ(cfg2.region.c_str(), cfg.region.c_str());
EXPECT_STREQ(cfg2.secret_key.c_str(), cfg.secret_key.c_str());
EXPECT_EQ(cfg2.timeout_ms, cfg.timeout_ms);
EXPECT_STREQ(cfg2.url.c_str(), cfg.url.c_str());
EXPECT_EQ(cfg2.use_path_style, cfg.use_path_style);
EXPECT_EQ(cfg2.use_region_in_url, cfg.use_region_in_url);
}
}
TEST(json_serialize, can_handle_sia_config) {
sia_config cfg{
"bucket",
};
json data(cfg);
EXPECT_STREQ("bucket", data.at(JSON_BUCKET).get<std::string>().c_str());
{
auto cfg2 = data.get<sia_config>();
EXPECT_STREQ(cfg2.bucket.c_str(), cfg.bucket.c_str());
}
}
} // namespace repertory