1use async_trait::async_trait;
4use crate::{
5 StorageResult, StorageFile, StorageConfig, StorageStats,
6 UploadOptions, DownloadOptions, PresignedUrlOptions, ByteRange,
7 types::EncryptionConfig,
8};
9use std::collections::HashMap;
10use bytes::Bytes;
11
12#[async_trait]
14pub trait StorageService: Send + Sync {
15 async fn upload_bytes(
17 &self,
18 path: &str,
19 data: Bytes,
20 options: Option<UploadOptions>,
21 ) -> StorageResult<StorageFile>;
22
23 async fn upload_reader(
25 &self,
26 path: &str,
27 reader: Box<dyn tokio::io::AsyncRead + Send + Unpin>,
28 size: Option<u64>,
29 options: Option<UploadOptions>,
30 ) -> StorageResult<StorageFile>;
31
32 async fn upload_file(
34 &self,
35 path: &str,
36 local_path: &str,
37 options: Option<UploadOptions>,
38 ) -> StorageResult<StorageFile>;
39
40 async fn download_bytes(
42 &self,
43 path: &str,
44 options: Option<DownloadOptions>,
45 ) -> StorageResult<Bytes>;
46
47 async fn download_writer(
49 &self,
50 path: &str,
51 writer: Box<dyn tokio::io::AsyncWrite + Send + Unpin>,
52 options: Option<DownloadOptions>,
53 ) -> StorageResult<()>;
54
55 async fn download_file(
57 &self,
58 path: &str,
59 local_path: &str,
60 options: Option<DownloadOptions>,
61 ) -> StorageResult<()>;
62
63 async fn stream_file(
65 &self,
66 path: &str,
67 range: Option<ByteRange>,
68 ) -> StorageResult<Box<dyn futures::stream::Stream<Item = StorageResult<Bytes>> + Send + Unpin>>;
69
70 async fn get_file(&self, path: &str) -> StorageResult<StorageFile>;
72
73 async fn file_exists(&self, path: &str) -> StorageResult<bool>;
75
76 async fn delete_file(&self, path: &str) -> StorageResult<bool>;
78
79 async fn copy_file(&self, from_path: &str, to_path: &str) -> StorageResult<StorageFile>;
81
82 async fn move_file(&self, from_path: &str, to_path: &str) -> StorageResult<StorageFile>;
84
85 async fn list_files(
87 &self,
88 prefix: &str,
89 limit: Option<u32>,
90 continuation_token: Option<String>,
91 ) -> StorageResult<FileListResult>;
92
93 async fn generate_presigned_url(
95 &self,
96 path: &str,
97 options: PresignedUrlOptions,
98 ) -> StorageResult<String>;
99
100 async fn get_file_url(
102 &self,
103 path: &str,
104 expiry_seconds: Option<u64>,
105 ) -> StorageResult<String>;
106
107 async fn update_metadata(
109 &self,
110 path: &str,
111 metadata: HashMap<String, String>,
112 ) -> StorageResult<StorageFile>;
113
114 async fn get_stats(&self) -> StorageResult<StorageStats>;
116
117 async fn test_connection(&self) -> StorageResult<bool>;
119
120 fn backend_type(&self) -> crate::StorageBackend;
122
123 fn bucket(&self) -> &str;
125
126 fn config(&self) -> &StorageConfig;
128}
129
130#[async_trait]
132pub trait StorageManager: Send + Sync {
133 async fn create_bucket(&self, bucket_name: &str, config: Option<BucketConfig>) -> StorageResult<bool>;
135
136 async fn delete_bucket(&self, bucket_name: &str, force: bool) -> StorageResult<bool>;
138
139 async fn list_buckets(&self) -> StorageResult<Vec<String>>;
141
142 async fn get_bucket_info(&self, bucket_name: &str) -> StorageResult<BucketInfo>;
144
145 async fn set_lifecycle_rules(
147 &self,
148 bucket_name: &str,
149 rules: Vec<LifecycleRule>,
150 ) -> StorageResult<bool>;
151
152 async fn enable_versioning(&self, bucket_name: &str) -> StorageResult<bool>;
154
155 async fn disable_versioning(&self, bucket_name: &str) -> StorageResult<bool>;
157
158 async fn set_access_control(
160 &self,
161 bucket_name: &str,
162 policy: AccessPolicy,
163 ) -> StorageResult<bool>;
164
165 async fn get_access_control(&self, bucket_name: &str) -> StorageResult<AccessPolicy>;
167
168 async fn restore_backup(
170 &self,
171 backup_path: &str,
172 target_bucket: &str,
173 target_prefix: Option<String>,
174 ) -> StorageResult<RestoreResult>;
175
176 async fn create_backup(
178 &self,
179 bucket_name: &str,
180 backup_path: &str,
181 prefix_filter: Option<String>,
182 ) -> StorageResult<BackupResult>;
183}
184
185#[async_trait]
187pub trait StorageMonitor: Send + Sync {
188 async fn start_monitoring(&self, bucket_name: &str) -> StorageResult<()>;
190
191 async fn stop_monitoring(&self, bucket_name: &str) -> StorageResult<()>;
193
194 async fn get_metrics(&self, bucket_name: &str) -> StorageResult<HashMap<String, f64>>;
196
197 async fn set_alert_thresholds(
199 &self,
200 bucket_name: &str,
201 thresholds: AlertThresholds,
202 ) -> StorageResult<()>;
203
204 async fn get_alerts(&self, bucket_name: &str) -> StorageResult<Vec<StorageAlert>>;
206
207 async fn get_usage_trends(
209 &self,
210 bucket_name: &str,
211 period: TrendPeriod,
212 ) -> StorageResult<UsageTrend>;
213
214 async fn generate_report(
216 &self,
217 bucket_name: &str,
218 report_type: ReportType,
219 ) -> StorageResult<StorageReport>;
220}
221
222#[derive(Debug, Clone)]
224pub struct FileListResult {
225 pub files: Vec<StorageFile>,
227
228 pub prefixes: Vec<String>,
230
231 pub truncated: bool,
233
234 pub next_continuation_token: Option<String>,
236
237 pub total_count: Option<u64>,
239}
240
241#[derive(Debug, Clone)]
243pub struct BucketConfig {
244 pub region: Option<String>,
246
247 pub access_policy: Option<AccessPolicy>,
249
250 pub storage_class: Option<String>,
252
253 pub versioning: Option<bool>,
255
256 pub lifecycle_rules: Option<Vec<LifecycleRule>>,
258
259 pub tags: Option<HashMap<String, String>>,
261
262 pub encryption: Option<EncryptionConfig>,
264}
265
266#[derive(Debug, Clone)]
268pub struct BucketInfo {
269 pub name: String,
271
272 pub created_at: chrono::DateTime<chrono::Utc>,
274
275 pub region: String,
277
278 pub storage_class: String,
280
281 pub versioning: VersioningStatus,
283
284 pub access_policy: AccessPolicy,
286
287 pub size_bytes: u64,
289
290 pub object_count: u64,
292
293 pub tags: HashMap<String, String>,
295}
296
297#[derive(Debug, Clone, Copy, PartialEq, Eq)]
299pub enum VersioningStatus {
300 Enabled,
301 Suspended,
302 Disabled,
303}
304
305#[derive(Debug, Clone)]
307pub struct LifecycleRule {
308 pub id: String,
310
311 pub status: LifecycleRuleStatus,
313
314 pub filter: LifecycleFilter,
316
317 pub action: LifecycleAction,
319}
320
321#[derive(Debug, Clone, Copy, PartialEq, Eq)]
323pub enum LifecycleRuleStatus {
324 Enabled,
325 Disabled,
326}
327
328#[derive(Debug, Clone)]
330pub struct LifecycleFilter {
331 pub prefix: Option<String>,
333
334 pub tags: Option<HashMap<String, String>>,
336
337 pub size_range: Option<(u64, u64)>,
339}
340
341#[derive(Debug, Clone)]
343pub struct LifecycleAction {
344 pub action_type: LifecycleActionType,
346
347 pub days: Option<u32>,
349
350 pub storage_class: Option<String>,
352}
353
354#[derive(Debug, Clone, Copy, PartialEq, Eq)]
356pub enum LifecycleActionType {
357 Delete,
359
360 Transition,
362
363 Expire,
365
366 Archive,
368}
369
370#[derive(Debug, Clone, Copy, PartialEq, Eq)]
372pub enum AccessPolicy {
373 Private,
374 PublicRead,
375 PublicReadWrite,
376 Custom,
377}
378
379#[derive(Debug, Clone)]
381pub struct RestoreResult {
382 pub files_restored: u64,
384
385 pub bytes_restored: u64,
387
388 pub files_failed: u64,
390
391 pub errors: Vec<String>,
393
394 pub duration_seconds: u64,
396}
397
398#[derive(Debug, Clone)]
400pub struct BackupResult {
401 pub files_backed_up: u64,
403
404 pub bytes_backed_up: u64,
406
407 pub backup_path: String,
409
410 pub backup_checksum: String,
412
413 pub files_skipped: u64,
415
416 pub errors: Vec<String>,
418
419 pub duration_seconds: u64,
421}
422
423#[derive(Debug, Clone)]
425pub struct AlertThresholds {
426 pub storage_usage_percent: Option<f64>,
428
429 pub file_count_limit: Option<u64>,
431
432 pub large_file_threshold: Option<u64>,
434
435 pub error_rate_percent: Option<f64>,
437
438 pub avg_response_time_ms: Option<f64>,
440}
441
442#[derive(Debug, Clone)]
444pub struct StorageAlert {
445 pub id: String,
447
448 pub alert_type: StorageAlertType,
450
451 pub severity: AlertSeverity,
453
454 pub message: String,
456
457 pub timestamp: chrono::DateTime<chrono::Utc>,
459
460 pub bucket: String,
462
463 pub details: HashMap<String, String>,
465}
466
467#[derive(Debug, Clone, Copy, PartialEq, Eq)]
469pub enum StorageAlertType {
470 StorageUsage,
471 FileCount,
472 LargeFile,
473 ErrorRate,
474 ResponseTime,
475 ConnectionFailure,
476 PermissionDenied,
477}
478
479#[derive(Debug, Clone, Copy, PartialEq, Eq)]
481pub enum AlertSeverity {
482 Info,
483 Warning,
484 Error,
485 Critical,
486}
487
488#[derive(Debug, Clone, Copy, PartialEq, Eq)]
490pub enum TrendPeriod {
491 LastHour,
492 Last24Hours,
493 Last7Days,
494 Last30Days,
495 Custom { hours: u32 },
496}
497
498#[derive(Debug, Clone)]
500pub struct UsageTrend {
501 pub period: TrendPeriod,
503
504 pub data_points: Vec<TrendDataPoint>,
506
507 pub growth_rate: f64,
509
510 pub predicted_usage: Option<u64>,
512}
513
514#[derive(Debug, Clone)]
516pub struct TrendDataPoint {
517 pub timestamp: chrono::DateTime<chrono::Utc>,
519
520 pub usage_bytes: u64,
522
523 pub file_count: u64,
525
526 pub operations: u64,
528}
529
530#[derive(Debug, Clone, Copy, PartialEq, Eq)]
532pub enum ReportType {
533 Usage,
534 Performance,
535 Cost,
536 Security,
537 Compliance,
538}
539
540#[derive(Debug, Clone)]
542pub struct StorageReport {
543 pub report_type: ReportType,
545
546 pub generated_at: chrono::DateTime<chrono::Utc>,
548
549 pub data: serde_json::Value,
551
552 pub summary: HashMap<String, String>,
554
555 pub recommendations: Vec<String>,
557}