From 0b4a23da0d4e608ee4ace428e671f2712d421e82 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Tue, 25 Feb 2025 09:00:35 -0300 Subject: [PATCH] fix(all): Organizing APIs and docs. --- Cargo.lock | 397 ++++++------------ Cargo.toml | 1 + README.md | 19 +- gb-api/src/main.rs | 24 +- gb-calendar/Cargo.toml | 20 + .../src/facade.rs => gb-calendar/src/lib.rs | 0 gb-file/Cargo.toml | 7 +- gb-file/src/lib.rs | 144 +++++++ gb-llm/Cargo.toml | 20 + gb-llm/src/facade.rs | 113 +++++ 10 files changed, 453 insertions(+), 292 deletions(-) create mode 100644 gb-calendar/Cargo.toml rename gb-file/src/facade.rs => gb-calendar/src/lib.rs (100%) create mode 100644 gb-file/src/lib.rs create mode 100644 gb-llm/Cargo.toml create mode 100644 gb-llm/src/facade.rs diff --git a/Cargo.lock b/Cargo.lock index 1ef6c18..2dc5042 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -376,6 +376,7 @@ dependencies = [ "blocking", "futures-lite 2.5.0", "once_cell", + "tokio", ] [[package]] @@ -479,17 +480,6 @@ dependencies = [ "reactor-trait", ] -[[package]] -name = "async-recursion" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "async-recursion" version = "1.1.1" @@ -1088,7 +1078,7 @@ dependencies = [ "futures", "futures-timer", "pin-project-lite", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "thiserror", @@ -1766,17 +1756,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive-new" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_builder" version = "0.20.2" @@ -2052,17 +2031,6 @@ dependencies = [ "zune-inflate", ] -[[package]] -name = "fail" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be3c61c59fdc91f5dbc3ea31ee8623122ce80057058be560654c5d410d181a6" -dependencies = [ - "lazy_static", - "log", - "rand 0.7.3", -] - [[package]] name = "fake" version = "2.10.0" @@ -2086,7 +2054,7 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper 0.14.32", - "hyper-tls 0.5.0", + "hyper-tls", "mime", "serde", "serde_json", @@ -2352,6 +2320,7 @@ dependencies = [ "chrono", "futures-util", "gb-core", + "gb-file", "gb-messaging", "gb-monitoring", "hyper 1.5.2", @@ -2408,7 +2377,7 @@ dependencies = [ name = "gb-automation" version = "0.1.0" dependencies = [ - "async-recursion 1.1.1", + "async-recursion", "async-trait", "chromiumoxide", "fantoccini", @@ -2449,6 +2418,23 @@ dependencies = [ "uuid", ] +[[package]] +name = "gb-file" +version = "0.1.0" +dependencies = [ + "async-trait", + "gb-core", + "minio", + "rstest", + "serde", + "serde_json", + "tempfile", + "thiserror", + "tokio", + "tokio-test", + "tracing", +] + [[package]] name = "gb-image" version = "0.1.0" @@ -2457,7 +2443,7 @@ dependencies = [ "gb-core", "image", "imageproc", - "reqwest 0.11.27", + "reqwest", "rstest", "rusttype", "serde", @@ -2557,7 +2543,6 @@ dependencies = [ "serde", "serde_json", "sqlx", - "tikv-client", "tokio", "tokio-test", "tracing", @@ -2587,7 +2572,7 @@ dependencies = [ "prometheus", "rand 0.8.5", "redis 0.24.0", - "reqwest 0.11.27", + "reqwest", "rstest", "serde", "serde_json", @@ -2771,7 +2756,7 @@ dependencies = [ "num-format", "rand 0.8.5", "regex", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "simplelog", @@ -3206,24 +3191,7 @@ dependencies = [ "hyper 0.14.32", "rustls 0.21.12", "tokio", - "tokio-rustls 0.24.1", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http 1.2.0", - "hyper 1.5.2", - "hyper-util", - "rustls 0.23.20", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.26.1", - "tower-service", + "tokio-rustls", ] [[package]] @@ -3251,22 +3219,6 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.5.2", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - [[package]] name = "hyper-util" version = "0.1.10" @@ -3274,16 +3226,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", - "futures-channel", "futures-util", "http 1.2.0", "http-body 1.0.1", "hyper 1.5.2", "pin-project-lite", - "socket2 0.5.8", "tokio", "tower-service", - "tracing", ] [[package]] @@ -4034,6 +3983,12 @@ dependencies = [ "digest", ] +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + [[package]] name = "memchr" version = "2.7.4" @@ -4061,6 +4016,42 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "minio" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a322ca30e1a0b771b1158a950a71e2edcc31cd99ed593fa707493cdff8f2dd" +dependencies = [ + "async-recursion", + "async-std", + "base64 0.21.7", + "byteorder", + "bytes", + "chrono", + "crc", + "dashmap", + "derivative", + "futures-core", + "futures-util", + "hex", + "hmac", + "http 0.2.12", + "hyper 0.14.32", + "lazy_static", + "md5", + "multimap", + "os_info", + "rand 0.8.5", + "regex", + "reqwest", + "serde", + "serde_json", + "sha2", + "tokio", + "urlencoding", + "xmltree", +] + [[package]] name = "miniz_oxide" version = "0.8.2" @@ -4138,6 +4129,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "multimap" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1a5d38b9b352dbd913288736af36af41c48d61b1a8cd34bcecd727561b7d511" +dependencies = [ + "serde", +] + [[package]] name = "nalgebra" version = "0.30.1" @@ -4388,7 +4388,7 @@ dependencies = [ "getrandom 0.2.15", "http 0.2.12", "rand 0.8.5", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "serde_path_to_error", @@ -4453,7 +4453,7 @@ dependencies = [ "chrono", "lazy_static", "mime", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", "thiserror", @@ -4537,10 +4537,10 @@ dependencies = [ "http 0.2.12", "opentelemetry 0.19.0", "opentelemetry-proto", - "prost 0.11.9", + "prost", "thiserror", "tokio", - "tonic 0.8.3", + "tonic", ] [[package]] @@ -4552,8 +4552,8 @@ dependencies = [ "futures", "futures-util", "opentelemetry 0.19.0", - "prost 0.11.9", - "tonic 0.8.3", + "prost", + "tonic", ] [[package]] @@ -4668,6 +4668,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_info" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + [[package]] name = "overload" version = "0.1.1" @@ -5161,7 +5172,6 @@ dependencies = [ "parking_lot", "procfs", "protobuf", - "reqwest 0.12.9", "thiserror", ] @@ -5172,17 +5182,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive 0.11.9", -] - -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes", - "prost-derive 0.12.6", + "prost-derive", ] [[package]] @@ -5198,19 +5198,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "prost-derive" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" -dependencies = [ - "anyhow", - "itertools 0.12.1", - "proc-macro2", - "quote", - "syn 2.0.91", -] - [[package]] name = "protobuf" version = "2.28.0" @@ -5557,8 +5544,8 @@ dependencies = [ "http 0.2.12", "http-body 0.4.6", "hyper 0.14.32", - "hyper-rustls 0.24.2", - "hyper-tls 0.5.0", + "hyper-rustls", + "hyper-tls", "ipnet", "js-sys", "log", @@ -5573,10 +5560,10 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration 0.5.1", + "system-configuration", "tokio", "tokio-native-tls", - "tokio-rustls 0.24.1", + "tokio-rustls", "tokio-util", "tower-service", "url", @@ -5588,50 +5575,6 @@ dependencies = [ "winreg 0.50.0", ] -[[package]] -name = "reqwest" -version = "0.12.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" -dependencies = [ - "base64 0.22.1", - "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.4.7", - "http 1.2.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.5.2", - "hyper-rustls 0.27.5", - "hyper-tls 0.6.0", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile 2.2.0", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 1.0.2", - "system-configuration 0.6.1", - "tokio", - "tokio-native-tls", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-registry", -] - [[package]] name = "retain_mut" version = "0.1.9" @@ -6743,9 +6686,6 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] [[package]] name = "synstructure" @@ -6778,18 +6718,7 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys 0.5.0", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "system-configuration-sys 0.6.0", + "system-configuration-sys", ] [[package]] @@ -6802,16 +6731,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "system-deps" version = "6.2.2" @@ -6963,33 +6882,6 @@ dependencies = [ "weezl", ] -[[package]] -name = "tikv-client" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048968e4e3d04db472346770cc19914c6b5ae206fa44677f6a0874d54cd05940" -dependencies = [ - "async-recursion 0.3.2", - "async-trait", - "derive-new", - "either", - "fail", - "futures", - "lazy_static", - "log", - "pin-project", - "prometheus", - "prost 0.12.6", - "rand 0.8.5", - "regex", - "semver", - "serde", - "serde_derive", - "thiserror", - "tokio", - "tonic 0.10.2", -] - [[package]] name = "time" version = "0.3.37" @@ -7139,16 +7031,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" -dependencies = [ - "rustls 0.23.20", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.17" @@ -7279,8 +7161,8 @@ dependencies = [ "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.11.9", - "prost-derive 0.11.9", + "prost", + "prost-derive", "tokio", "tokio-stream", "tokio-util", @@ -7291,36 +7173,6 @@ dependencies = [ "tracing-futures", ] -[[package]] -name = "tonic" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" -dependencies = [ - "async-stream", - "async-trait", - "axum 0.6.20", - "base64 0.21.7", - "bytes", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.12.6", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "tokio", - "tokio-rustls 0.24.1", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.4.13" @@ -8262,36 +8114,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -8577,6 +8399,21 @@ dependencies = [ "time", ] +[[package]] +name = "xml-rs" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + [[package]] name = "yasna" version = "0.5.2" diff --git a/Cargo.toml b/Cargo.toml index 62b7daa..3e5f066 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "gb-core", # Core domain models and traits "gb-api", # API layer and server implementation "gb-media", # Media processing and WebRTC handling + "gb-messaging", # Message queue and real-time communication "gb-storage", # Database and storage implementations "gb-monitoring", # Metrics, logging and monitoring diff --git a/README.md b/README.md index d9be19b..3a92ffa 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,23 @@ Licensed under terms specified in workspace configuration. - Annual penetration testing - Bi-annual disaster recovery testing ---- + +### **Key Open Source Tools in Rust/Go**: +1. **Zitadel (Go)**: Identity and access management for secure authentication. +2. **Stalwart (Rust)**: Secure email server for threat detection. +3. **MinIO (Go)**: High-performance object storage for unstructured data. +4. **Ubuntu Advantage (Go/Rust tools)**: Compliance and security tools for Ubuntu. +5. **Tantivy (Rust)**: Full-text search engine for data discovery. +6. **Drone (Go)**: CI/CD platform for DevOps automation. +7. **Temporal (Go)**: Workflow orchestration engine. +8. **Caddy (Go)**: Web server for seamless customer experiences. +9. **SeaweedFS (Go)**: Distributed file system for secure file sharing. +10. **Vector (Rust)**: Observability pipeline for monitoring. +11. **Tyk (Go)**: API gateway for secure API management. +12. **Vault (Go)**: Secrets management and encryption. +13. **Hugging Face Transformers (Rust/Go bindings)**: LLM integration and fine-tuning. +14. **Kubernetes (Go)**: Container orchestration for scalable deployments. +15. **Matrix (Rust)**: Real-time communication and collaboration. + Built with ❤️ from Brazil, using Rust for maximum performance and reliability. diff --git a/gb-api/src/main.rs b/gb-api/src/main.rs index 661f234..2843857 100644 --- a/gb-api/src/main.rs +++ b/gb-api/src/main.rs @@ -3,6 +3,17 @@ use tracing::{info, error}; use std::net::SocketAddr; use gb_messaging::MessageProcessor; + +#[allow(dead_code)] +#[derive(Clone)] +struct AppState { + db: sqlx::PgPool, + redis: redis::Client, + message_processor: MessageProcessor, + customer: PostgresCustomerRepository, + +} + #[tokio::main] async fn main() -> Result<()> { // Initialize logging first @@ -20,9 +31,12 @@ async fn initialize_bot_server() -> Result { // Initialize the MessageProcessor let message_processor = MessageProcessor::new(); - + let state = AppState::new(); + state.repo = PostgresCustomerRepository::new(Arc::new(pool)); + + // Build the Axum router using our router module - let app = gb_api::create_router(message_processor) + let app = gb_api::create_router(state) .layer(tower_http::trace::TraceLayer::new_for_http()); Ok(app) @@ -61,12 +75,6 @@ async fn initialize_redis() -> Result { .map_err(|e| Error::internal(e.to_string())) } -#[allow(dead_code)] -#[derive(Clone)] -struct AppState { - db: sqlx::PgPool, - redis: redis::Client, -} async fn start_server(app: axum::Router) -> Result<()> { diff --git a/gb-calendar/Cargo.toml b/gb-calendar/Cargo.toml new file mode 100644 index 0000000..24c759b --- /dev/null +++ b/gb-calendar/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "gb-calendar" +version = { workspace = true } +edition = { workspace = true } +authors = { workspace = true } +license = { workspace = true } + +[dependencies] +gb-core = { path = "../gb-core" } +async-trait= { workspace = true } +tokio= { workspace = true } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0"thiserror= { workspace = true } +tracing= { workspace = true } +minio-rs = "0.1" + +[dev-dependencies] +rstest= { workspace = true } +tokio-test = "0.4" +tempfile = "3.8" diff --git a/gb-file/src/facade.rs b/gb-calendar/src/lib.rs similarity index 100% rename from gb-file/src/facade.rs rename to gb-calendar/src/lib.rs diff --git a/gb-file/Cargo.toml b/gb-file/Cargo.toml index b554e9c..3f0de6e 100644 --- a/gb-file/Cargo.toml +++ b/gb-file/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "gb-document" +name = "gb-file" version = { workspace = true } edition = { workspace = true } authors = { workspace = true } @@ -10,9 +10,10 @@ gb-core = { path = "../gb-core" } async-trait= { workspace = true } tokio= { workspace = true } serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0"thiserror= { workspace = true } +serde_json = "1.0" +thiserror= { workspace = true } tracing= { workspace = true } -minio-rs = "0.1" +minio = "0.1.0" [dev-dependencies] rstest= { workspace = true } diff --git a/gb-file/src/lib.rs b/gb-file/src/lib.rs new file mode 100644 index 0000000..b93a7fd --- /dev/null +++ b/gb-file/src/lib.rs @@ -0,0 +1,144 @@ +use minio::s3::client::Client; +use minio::s3::args::{BucketExistsArgs, MakeBucketArgs, RemoveObjectArgs, GetObjectArgs, PutObjectArgs, ListObjectsArgs}; +use minio::s3::creds::StaticProvider; +use minio::s3::error::Error as MinioError; +use minio::s3::types::{BaseUrl, Item}; +use std::io::Cursor; +use std::path::Path; + +pub struct FileManager { + client: Client, + bucket_name: String, +} + +impl FileManager { + pub async fn new(endpoint: &str, access_key: &str, secret_key: &str, bucket_name: &str, use_ssl: bool) -> Result { + // Create BaseUrl from endpoint + let base_url = BaseUrl::from_string(endpoint)?; + let static_provider = StaticProvider::new( + access_key, + secret_key, + None, + ); + let client = Client::new(base_url.clone(), Some(Box::new(static_provider)), None, None).unwrap(); + + + Ok(Self { + client, + bucket_name: bucket_name.to_string(), + }) + } + + pub async fn ensure_bucket_exists(&self) -> Result<(), MinioError> { + let exists = self.client + .bucket_exists(&BucketExistsArgs::new(&self.bucket_name)?) + .await?; + if !exists { + self.client + .make_bucket(&MakeBucketArgs::new(&self.bucket_name)?) + .await?; + } + Ok(()) + } + + pub async fn upload_file(&self, path: &str, file_data: Vec) -> Result<(), MinioError> { + let reader = Cursor::new(&file_data); + let file_size = file_data.len() as u64; + + let args = PutObjectArgs::new( + &self.bucket_name, + path, + reader, + Some(file_size), + None + )?; + + self.client.put_object(&args).await?; + Ok(()) + } + + pub async fn download_file(&self, path: &str) -> Result, MinioError> { + let args = GetObjectArgs::new(&self.bucket_name, path)?; + let object = self.client.get_object(&args).await?; + let data = object.bytes().await?; + Ok(data.to_vec()) + } + + pub async fn copy_file(&self, source_path: &str, destination_path: &str) -> Result<(), MinioError> { + // Download the source file + let data = self.download_file(source_path).await?; + + // Upload it to the destination + let reader = Cursor::new(&data); + let file_size = data.len() as u64; + + let args = PutObjectArgs::new( + &self.bucket_name, + destination_path, + reader, + Some(file_size), + None + )?; + + self.client.put_object(&args).await?; + Ok(()) + } + + pub async fn move_file(&self, source_path: &str, destination_path: &str) -> Result<(), MinioError> { + self.copy_file(source_path, destination_path).await?; + self.delete_file(source_path).await?; + Ok(()) + } + + pub async fn delete_file(&self, path: &str) -> Result<(), MinioError> { + let args = RemoveObjectArgs::new(&self.bucket_name, path)?; + self.client.remove_object(&args).await?; + Ok(()) + } + + pub async fn list_files(&self, prefix: &str) -> Result, MinioError> { + // Create a predicate function that always returns true + let predicate = |_: Vec| -> bool { true }; + + let args = ListObjectsArgs::new(&self.bucket_name, &predicate)?; + let objects = self.client.list_objects(&args).await?; + + // Filter objects based on prefix manually + let file_names: Vec = objects + .into_iter() + .filter(|obj| obj.name().starts_with(prefix)) + .map(|obj| obj.name().to_string()) + .collect(); + + Ok(file_names) + } + + pub async fn get_file_contents(&self, path: &str) -> Result { + let data = self.download_file(path).await?; + let contents = String::from_utf8(data) + .map_err(|_| MinioError::InvalidResponse(400, "Invalid UTF-8 sequence".to_string()))?; + Ok(contents) + } + + pub async fn create_folder(&self, path: &str) -> Result<(), MinioError> { + let folder_path = if path.ends_with('/') { + path.to_string() + } else { + format!("{}/", path) + }; + + // Create empty file with folder path + self.upload_file(&folder_path, vec![]).await + } + + pub async fn share_folder(&self, path: &str) -> Result { + // This is just a placeholder implementation + Ok(format!("Folder shared: {}", path)) + } + + pub async fn search_files(&self, prefix: &str, query: &str) -> Result, MinioError> { + let files = self.list_files(prefix).await?; + let results = files.into_iter().filter(|f| f.contains(query)).collect(); + Ok(results) + } +} \ No newline at end of file diff --git a/gb-llm/Cargo.toml b/gb-llm/Cargo.toml new file mode 100644 index 0000000..d754964 --- /dev/null +++ b/gb-llm/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "gb-llm" +version = { workspace = true } +edition = { workspace = true } +authors = { workspace = true } +license = { workspace = true } + +[dependencies] +gb-core = { path = "../gb-core" } +async-trait= { workspace = true } +tokio= { workspace = true } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0"thiserror= { workspace = true } +tracing= { workspace = true } +minio-rs = "0.1" + +[dev-dependencies] +rstest= { workspace = true } +tokio-test = "0.4" +tempfile = "3.8" diff --git a/gb-llm/src/facade.rs b/gb-llm/src/facade.rs new file mode 100644 index 0000000..648ce3a --- /dev/null +++ b/gb-llm/src/facade.rs @@ -0,0 +1,113 @@ +use minio_rs::minio::client::Client; +use minio_rs::minio::s3::args::{BucketExistsArgs, MakeBucketArgs, RemoveObjectArgs, GetObjectArgs, PutObjectArgs, ListObjectsArgs}; +use minio_rs::minio::s3::response::Object; +use minio_rs::minio::s3::error::Error as MinioError; +use std::path::Path; +use std::io::Cursor; + +/// Represents a file manager for handling MinIO file operations. +pub struct FileManager { + client: Client, + bucket_name: String, +} + +impl FileManager { + /// Creates a new `FileManager` instance. + pub async fn new(endpoint: &str, access_key: &str, secret_key: &str, bucket_name: &str, use_ssl: bool) -> Result { + let client = Client::new(endpoint, access_key, secret_key, use_ssl).await?; + Ok(Self { + client, + bucket_name: bucket_name.to_string(), + }) + } + + /// Checks if the bucket exists, and creates it if it doesn't. + pub async fn ensure_bucket_exists(&self) -> Result<(), MinioError> { + let exists = self.client + .bucket_exists(&BucketExistsArgs::new(&self.bucket_name)) + .await?; + if !exists { + self.client + .make_bucket(&MakeBucketArgs::new(&self.bucket_name)) + .await?; + } + Ok(()) + } + + /// Uploads a file to the specified path. + pub async fn upload_file(&self, path: &str, file_data: Vec) -> Result<(), MinioError> { + let args = PutObjectArgs::new(&self.bucket_name, path, Cursor::new(file_data), file_data.len() as u64); + self.client.put_object(&args).await?; + Ok(()) + } + + /// Downloads a file from the specified path. + pub async fn download_file(&self, path: &str) -> Result, MinioError> { + let args = GetObjectArgs::new(&self.bucket_name, path); + let object = self.client.get_object(&args).await?; + let data = object.bytes().await?; + Ok(data.to_vec()) + } + + /// Copies a file from the source path to the destination path. + pub async fn copy_file(&self, source_path: &str, destination_path: &str) -> Result<(), MinioError> { + let source_args = GetObjectArgs::new(&self.bucket_name, source_path); + let object = self.client.get_object(&source_args).await?; + let data = object.bytes().await?; + + let destination_args = PutObjectArgs::new(&self.bucket_name, destination_path, Cursor::new(data.clone()), data.len() as u64); + self.client.put_object(&destination_args).await?; + Ok(()) + } + + /// Moves a file from the source path to the destination path. + pub async fn move_file(&self, source_path: &str, destination_path: &str) -> Result<(), MinioError> { + self.copy_file(source_path, destination_path).await?; + self.delete_file(source_path).await?; + Ok(()) + } + + /// Deletes a file at the specified path. + pub async fn delete_file(&self, path: &str) -> Result<(), MinioError> { + let args = RemoveObjectArgs::new(&self.bucket_name, path); + self.client.remove_object(&args).await?; + Ok(()) + } + + /// Lists all files in the specified path. + pub async fn list_files(&self, prefix: &str) -> Result, MinioError> { + let args = ListObjectsArgs::new(&self.bucket_name).with_prefix(prefix); + let objects = self.client.list_objects(&args).await?; + let file_names = objects.into_iter().map(|obj| obj.name().to_string()).collect(); + Ok(file_names) + } + + /// Retrieves the contents of a file at the specified path. + pub async fn get_file_contents(&self, path: &str) -> Result { + let data = self.download_file(path).await?; + let contents = String::from_utf8(data).map_err(|_| MinioError::InvalidResponse)?; + Ok(contents) + } + + /// Creates a folder at the specified path. + pub async fn create_folder(&self, path: &str) -> Result<(), MinioError> { + let folder_path = if path.ends_with('/') { + path.to_string() + } else { + format!("{}/", path) + }; + self.upload_file(&folder_path, vec![]).await + } + + /// Shares a folder at the specified path (placeholder implementation). + pub async fn share_folder(&self, path: &str) -> Result { + Ok(format!("Folder shared: {}", path)) + } + + /// Searches for files matching the query in the specified path. + pub async fn search_files(&self, prefix: &str, query: &str) -> Result, MinioError> { + let files = self.list_files(prefix).await?; + let results = files.into_iter().filter(|f| f.contains(query)).collect(); + Ok(results) + } +} \ No newline at end of file