Skip to main content

raps_oss/
lib.rs

1// SPDX-License-Identifier: Apache-2.0
2#![allow(clippy::uninlined_format_args)]
3// Copyright 2024-2025 Dmytro Yemelianov
4
5//! Object Storage Service (OSS) API module
6//!
7//! Handles bucket and object operations for storing files in APS.
8//! Supports multipart chunked uploads for large files with resume capability.
9
10// API response structs may contain fields we don't use - this is expected for external API contracts
11#![allow(dead_code)]
12
13mod batch;
14mod buckets;
15mod multipart;
16mod objects;
17pub mod types;
18
19pub use types::*;
20
21use raps_kernel::auth::AuthClient;
22use raps_kernel::config::Config;
23use raps_kernel::http::HttpClientConfig;
24
25/// OSS API client
26#[derive(Clone)]
27pub struct OssClient {
28    pub(crate) config: Config,
29    pub(crate) auth: AuthClient,
30    pub(crate) http_client: reqwest::Client,
31}
32
33impl OssClient {
34    /// Create a new OSS client
35    pub fn new(config: Config, auth: AuthClient) -> Self {
36        Self::new_with_http_config(config, auth, HttpClientConfig::default())
37    }
38
39    /// Create a new OSS client with custom HTTP config
40    pub fn new_with_http_config(
41        config: Config,
42        auth: AuthClient,
43        http_config: HttpClientConfig,
44    ) -> Self {
45        // Create HTTP client with configured timeouts
46        let http_client = http_config
47            .create_client()
48            .unwrap_or_else(|_| reqwest::Client::new()); // Fallback to default if config fails
49
50        Self {
51            config,
52            auth,
53            http_client,
54        }
55    }
56
57    /// Generate a base64-encoded URN for an object
58    pub fn get_urn(&self, bucket_key: &str, object_key: &str) -> String {
59        use base64::Engine;
60        let object_id = format!("urn:adsk.objects:os.object:{}/{}", bucket_key, object_key);
61        base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(object_id)
62    }
63}
64
65/// Integration tests using raps-mock
66#[cfg(test)]
67mod integration_tests {
68    use super::*;
69    use raps_kernel::auth::AuthClient;
70    use raps_kernel::config::Config;
71
72    fn create_mock_client(mock_url: &str) -> OssClient {
73        let config = Config {
74            client_id: "test-client-id".to_string(),
75            client_secret: "test-client-secret".to_string(),
76            base_url: mock_url.to_string(),
77            callback_url: "http://localhost:8080/callback".to_string(),
78            da_nickname: None,
79            http_config: HttpClientConfig::default(),
80        };
81        let auth = AuthClient::new(config.clone());
82        OssClient::new(config, auth)
83    }
84
85    #[tokio::test]
86    async fn test_client_creation() {
87        let server = raps_mock::TestServer::start_default().await.unwrap();
88        let client = create_mock_client(&server.url);
89        assert!(client.auth.config().base_url.starts_with("http://"));
90    }
91}