Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add support for extending file storage to other schemes and provide a runtime flag for the same #3348

Merged
merged 30 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c1c304e
refactor: rename s3 feature flag to aws_s3
Chethan-rao Jan 12, 2024
57748ba
Merge branch 'main' into rename-s3-feature
Chethan-rao Jan 14, 2024
defabfd
refactor: add support for extending file storage to other schemes and…
Chethan-rao Jan 14, 2024
b7c4403
chore: run formatter
hyperswitch-bot[bot] Jan 14, 2024
87b4c15
refactor: add support for extending file storage to other schemes and…
Chethan-rao Jan 14, 2024
ca5e108
Merge branch 'runtime-flag-for-s3' of github.com:juspay/hyperswitch i…
Chethan-rao Jan 14, 2024
0bb730f
Merge branch 'main' of github.com:juspay/hyperswitch into rename-s3-f…
Chethan-rao Jan 17, 2024
a1cf167
Merge branch 'rename-s3-feature' of github.com:juspay/hyperswitch int…
Chethan-rao Jan 17, 2024
3593e46
Merge branch 'main' of github.com:juspay/hyperswitch into rename-s3-f…
Chethan-rao Jan 17, 2024
300f4cd
Merge branch 'rename-s3-feature' of github.com:juspay/hyperswitch int…
Chethan-rao Jan 17, 2024
e5d5905
address requested changes
Chethan-rao Jan 18, 2024
dacf4be
fix file system error of directory not being created
Chethan-rao Jan 18, 2024
014bfeb
Merge branch 'main' of github.com:juspay/hyperswitch into runtime-fla…
Chethan-rao Jan 19, 2024
ef74406
update objects visibility
Chethan-rao Jan 19, 2024
1ddf76d
chore: run formatter
hyperswitch-bot[bot] Jan 19, 2024
4284dd5
update objects visibility
Chethan-rao Jan 19, 2024
2154cdc
Merge branch 'runtime-flag-for-s3' of github.com:juspay/hyperswitch i…
Chethan-rao Jan 19, 2024
f1a0a79
update docker compose volume mounting
Chethan-rao Jan 19, 2024
e928f71
Merge branch 'main' of github.com:juspay/hyperswitch into runtime-fla…
Chethan-rao Jan 24, 2024
05c09f4
perform dynamic dispatch instead of enum approach
Chethan-rao Jan 24, 2024
5abb78d
chore: run formatter
hyperswitch-bot[bot] Jan 24, 2024
5617098
update file visibility
Chethan-rao Jan 24, 2024
9559a29
Merge branch 'runtime-flag-for-s3' of github.com:juspay/hyperswitch i…
Chethan-rao Jan 24, 2024
cce7d23
Merge branch 'main' of github.com:juspay/hyperswitch into runtime-fla…
Chethan-rao Jan 25, 2024
85ecfba
Merge branch 'main' of github.com:juspay/hyperswitch into runtime-fla…
Chethan-rao Jan 25, 2024
214577f
update function param type
Chethan-rao Jan 25, 2024
2dac244
Merge branch 'main' of github.com:juspay/hyperswitch into runtime-fla…
Chethan-rao Jan 29, 2024
b0a632d
update error handling
Chethan-rao Jan 29, 2024
c0cd7d0
Merge branch 'main' of github.com:juspay/hyperswitch into runtime-fla…
Chethan-rao Jan 29, 2024
6715b64
remove as_ref call on file storage client
Chethan-rao Jan 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 15 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions config/config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -509,14 +509,6 @@ client_secret = "paypal_secret_key" # Secret key for PayPal onboarding
partner_id = "paypal_partner_id" # Partner ID for PayPal onboarding
enabled = true # Switch to enable or disable PayPal onboarding

[frm]
enabled = true

[paypal_onboarding]
client_id = "paypal_client_id" # Client ID for PayPal onboarding
client_secret = "paypal_secret_key" # Secret key for PayPal onboarding
partner_id = "paypal_partner_id" # Partner ID for PayPal onboarding
enabled = true # Switch to enable or disable PayPal onboarding

[events]
source = "logs" # The event sink to push events supports kafka or logs (stdout)
Expand All @@ -529,3 +521,11 @@ refund_analytics_topic = "topic" # Kafka topic to be used for Refund ev
api_logs_topic = "topic" # Kafka topic to be used for incoming api events
connector_logs_topic = "topic" # Kafka topic to be used for connector api events
outgoing_webhook_logs_topic = "topic" # Kafka topic to be used for outgoing webhook events

# File storage configuration
[file_storage]
file_storage_backend = "aws_s3" # File storage backend to be used

[file_storage.aws_s3]
region = "us-east-1" # The AWS region used by the AWS S3 for file storage
bucket_name = "bucket1" # The AWS S3 bucket name for file storage
3 changes: 3 additions & 0 deletions config/development.toml
Original file line number Diff line number Diff line change
Expand Up @@ -542,3 +542,6 @@ client_id = ""
client_secret = ""
partner_id = ""
enabled = true

[file_storage]
file_storage_backend = "file_system"
3 changes: 3 additions & 0 deletions config/docker_compose.toml
Original file line number Diff line number Diff line change
Expand Up @@ -398,3 +398,6 @@ enabled = true

[events]
source = "logs"

[file_storage]
file_storage_backend = "file_system"
16 changes: 16 additions & 0 deletions crates/common_utils/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,19 @@ where
T::switch_from(self)
}
}

/// Represents errors that can occur during file storage operations.
#[derive(Debug, thiserror::Error, PartialEq)]
pub enum FileStorageError {
/// Indicates that the file upload operation failed.
#[error("Failed to upload file")]
UploadFailed,

/// Indicates that the file retrieval operation failed.
#[error("Failed to retrieve file")]
RetrieveFailed,

/// Indicates that the file deletion operation failed.
#[error("Failed to delete file")]
DeleteFailed,
}
115 changes: 115 additions & 0 deletions crates/common_utils/src/fs_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
//!
//! Module for local file system storage operations
//!

use std::{
fs::{remove_file, File},
io::{Read, Write},
path::PathBuf,
};

use error_stack::{IntoReport, ResultExt};

use crate::errors::CustomResult;

/// Constructs the file path for a given file key within the file system.
/// The file path is generated based on the workspace path and the provided file key.
fn get_file_path(file_key: impl AsRef<str>) -> PathBuf {
let mut file_path = PathBuf::new();
#[cfg(feature = "logs")]
file_path.push(router_env::env::workspace_path());
Chethan-rao marked this conversation as resolved.
Show resolved Hide resolved
#[cfg(not(feature = "logs"))]
file_path.push(std::env::current_dir().unwrap_or(".".into()));

file_path.push("files");
Chethan-rao marked this conversation as resolved.
Show resolved Hide resolved
file_path.push(file_key.as_ref());
file_path
}

/// Represents a file system for storing and managing files locally.
#[derive(Debug, Clone)]
pub struct FileSystem;

impl FileSystem {
/// Saves the provided file data to the file system under the specified file key.
pub fn save_file_to_fs(
&self,
file_key: impl AsRef<str>,
file_data: Vec<u8>,
) -> CustomResult<(), FileSystemStorageError> {
let file_path = get_file_path(&file_key);

// Ignore the file name and create directories in the `file_path` if not exists
std::fs::create_dir_all(
file_path
.parent()
.ok_or(FileSystemStorageError::CreateDirFailed)?,
Chethan-rao marked this conversation as resolved.
Show resolved Hide resolved
)
.into_report()
.change_context(FileSystemStorageError::CreateDirFailed)?;

let mut file = File::create(file_path)
.into_report()
.change_context(FileSystemStorageError::CreateFailure)?;
file.write_all(&file_data)
.into_report()
.change_context(FileSystemStorageError::WriteFailure)?;
Ok(())
}

/// Deletes the file associated with the specified file key from the file system.
pub fn delete_file_from_fs(
&self,
file_key: impl AsRef<str>,
) -> CustomResult<(), FileSystemStorageError> {
let file_path = get_file_path(file_key);
remove_file(file_path)
.into_report()
.change_context(FileSystemStorageError::DeleteFailure)?;
Ok(())
}

/// Retrieves the file content associated with the specified file key from the file system.
pub fn retrieve_file_from_fs(
&self,
file_key: impl AsRef<str>,
) -> CustomResult<Vec<u8>, FileSystemStorageError> {
let mut received_data: Vec<u8> = Vec::new();
let file_path = get_file_path(file_key);
let mut file = File::open(file_path)
.into_report()
.change_context(FileSystemStorageError::FileOpenFailure)?;
file.read_to_end(&mut received_data)
.into_report()
.change_context(FileSystemStorageError::ReadFailure)?;
Ok(received_data)
}
}

/// Represents an error that can occur during local file system storage operations.
#[derive(Debug, thiserror::Error)]
pub enum FileSystemStorageError {
/// Error indicating opening a file failed
#[error("Failed while opening the file")]
FileOpenFailure,

/// Error indicating file creation failed.
#[error("Failed to create file")]
CreateFailure,

/// Error indicating reading a file failed.
#[error("Failed while reading the file")]
ReadFailure,

/// Error indicating writing to a file failed.
#[error("Failed while writing into file")]
WriteFailure,

/// Error indicating file deletion failed.
#[error("Failed while deleting the file")]
DeleteFailure,

/// Error indicating directory creation failed
#[error("Failed while creating a directory")]
CreateDirFailed,
}
1 change: 1 addition & 0 deletions crates/common_utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod errors;
pub mod events;
pub mod ext_traits;
pub mod fp_utils;
pub mod fs_utils;
pub mod macros;
pub mod pii;
#[allow(missing_docs)] // Todo: add docs
Expand Down
2 changes: 2 additions & 0 deletions crates/external_services/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ license.workspace = true
[features]
kms = ["dep:aws-config", "dep:aws-sdk-kms"]
email = ["dep:aws-config"]
aws_s3 = ["dep:aws-config", "dep:aws-sdk-s3"]

[dependencies]
async-trait = "0.1.68"
aws-config = { version = "0.55.3", optional = true }
aws-sdk-kms = { version = "0.28.0", optional = true }
aws-sdk-sesv2 = "0.28.0"
aws-sdk-sts = "0.28.0"
aws-sdk-s3 = { version = "0.28.0", optional = true }
aws-smithy-client = "0.55.3"
base64 = "0.21.2"
dyn-clone = "1.0.11"
Expand Down
Loading
Loading