Skip to main content

dispnet_storage/
storage_manager.rs

1use std::collections::HashMap;
2
3use crate::{StorageProvider, GetData, SaveData};
4
5/// Manage all storage providers.
6/// 
7/// # Example
8/// ```
9/// use dispnet_storage::storage_manager::StorageManager;
10/// 
11/// let mut manager = StorageManager::new();
12/// ```
13pub struct StorageManager {
14    storage_providers:  HashMap<String, Box<dyn StorageProvider>>,
15}
16
17impl StorageManager {
18    pub fn new() -> Self {
19        Self {
20            storage_providers: HashMap::new(),
21        }
22    }
23
24    /// Add a storage provider instance to the manager
25    pub fn add_storage_provider(self: &mut Self, layer_key: String, provider: Box<dyn StorageProvider>) {
26        self.storage_providers.insert(layer_key, provider);
27    }
28
29    /// Remove a loaded storage provider instance
30    pub fn remove_storage_provider(self: &mut Self, layer_key: &str) {
31        if self.storage_providers.contains_key(layer_key) {
32            self.storage_providers.remove(layer_key);
33        }
34    }
35
36    /// Get all layers.
37    /// 
38    /// Layers are the names of storage provider instances.
39    pub fn get_storage_provider_layers(self: &Self) -> Vec<&String> {
40        let mut keys = vec![];
41        for key in self.storage_providers.keys() {
42            keys.push(key);
43        }
44        keys
45    }
46
47    /// Get data from a storage layer with a key.
48    pub fn get(self: &Self, layer_key: &str, key: &str) -> Result<GetData, String> {
49        if self.storage_providers.contains_key(layer_key) {
50            return self.storage_providers.get(layer_key).unwrap().get(key);
51        }
52        Err("Storage provider layer not found for `get` action".to_owned())
53    }
54
55    /// Find the first data entry for the key in any storage provider.
56    pub fn find(self: &Self, key: &str) -> Result<GetData, String> {
57        for layer in self.storage_providers.iter() {
58            if let Ok(result) = layer.1.get(key) {
59                return Ok(result);
60            }
61        }
62        Err(format!("Requested key: `{}` not found in any storage provider.", key))
63    }
64
65    /// Save data to the storage layer.
66    pub fn save(self: &Self, layer_key: &str, key: &str, raw: Vec<u8>) -> Result<SaveData, String> {
67        if self.storage_providers.contains_key(layer_key) {
68            return self.storage_providers.get(layer_key).unwrap().save(key, raw);
69        }
70        Err("Storage provider layer not found for `save` action".to_owned())
71    }
72
73    /// Queue an entry for deletion in a specific layer.
74    pub fn delete(self: &Self, layer_key: &str, key: &str) {
75        if self.storage_providers.contains_key(layer_key) {
76            return self.storage_providers.get(layer_key).unwrap().delete(key);
77        }
78    }
79
80    /// Queue for deletion all entires which match the key on any layer.
81    pub fn delete_all(self: &Self, key: &str) {
82        for layer in self.storage_providers.iter() {
83            layer.1.delete(key)
84        }
85    }
86
87    /// Execute free on all layers.
88    pub fn free(self: &Self) {
89        for layer in self.storage_providers.iter() {
90            layer.1.free();
91        }
92    }
93
94    /// Executes force free on all layers.
95    pub fn force_free(self: &Self, all: bool) {
96        for layer in self.storage_providers.iter() {
97            layer.1.force_free(all);
98        }
99    }
100}
101
102#[cfg(test)]
103mod tests {
104    use crate::{filestorage::FileStorageProvider, StorageProvider};
105
106    use super::StorageManager;
107
108    const FILE_STORAGE: &str = "test_fstore";
109    const DELETE_STORAGE: &str = "test_fdelete";
110    const FILE_KEY: &str = "1234";
111
112    fn clean_up(test_key: &str) {
113        let f_path = format!("{}_{}", FILE_STORAGE, test_key);
114        let d_path = format!("{}_{}", DELETE_STORAGE, test_key);
115        let attr = std::fs::metadata(&f_path).unwrap();
116        if attr.is_dir() {
117            std::fs::remove_dir_all(&f_path).unwrap();
118        }
119        let attr = std::fs::metadata(&d_path).unwrap();
120        if attr.is_dir() {
121            std::fs::remove_dir_all(&d_path).unwrap();
122        }
123    }
124
125    fn storage_provider_instance(test_key: &str) -> Box<dyn StorageProvider> {
126        let f_path = format!("{}_{}", FILE_STORAGE, test_key);
127        let d_path = format!("{}_{}", DELETE_STORAGE, test_key);
128
129        Box::new(FileStorageProvider::new(f_path.to_owned(), d_path.to_owned()))
130    }
131
132    #[test]
133    fn add_provider() {
134        let f_key = "add_provider";
135        let mut manager = StorageManager::new();
136        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
137        assert_eq!(manager.get_storage_provider_layers().len(), 1);
138        clean_up(f_key);
139    }
140
141
142    #[test]
143    fn remove_provider() {
144        let f_key = "remove_provider";
145        let mut manager = StorageManager::new();
146        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
147        manager.remove_storage_provider("layer1");
148        assert_eq!(manager.get_storage_provider_layers().len(), 0);
149        clean_up(f_key);
150    }
151
152
153    #[test]
154    fn save() {
155        let f_key = "save_provider";
156        let mut manager = StorageManager::new();
157        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
158        let save_result = manager.save("layer1", FILE_KEY, "test".to_owned().into_bytes()).unwrap();
159        assert_eq!(save_result.key, FILE_KEY);
160        clean_up(f_key);
161    }
162
163    #[test]
164    fn get() {
165        let f_key = "get_provider";
166        let mut manager = StorageManager::new();
167        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
168        let _save_result = manager.save("layer1", FILE_KEY, "test".to_owned().into_bytes());
169        let result = manager.get("layer1", FILE_KEY).unwrap();
170        assert_eq!(result.size, 4);
171        assert_eq!(result.key, FILE_KEY);
172        clean_up(f_key);
173    }
174
175    #[test]
176    fn find() {
177        let f_key = "find_provider";
178        let mut manager = StorageManager::new();
179        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
180        let _save_result = manager.save("layer1", FILE_KEY, "test".to_owned().into_bytes());
181        let result = manager.find(FILE_KEY).unwrap();
182        assert_eq!(result.size, 4);
183        assert_eq!(result.key, FILE_KEY);
184        clean_up(f_key);
185    }
186
187    #[test]
188    fn delete() {
189        let f_key = "delete_provider";
190        let mut manager = StorageManager::new();
191        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
192        let _save_result = manager.save("layer1", FILE_KEY, "test".to_owned().into_bytes());
193        manager.delete("layer1", FILE_KEY);
194        let attr = std::fs::metadata(format!("{}_{}/{}", DELETE_STORAGE, f_key, FILE_KEY)).unwrap();
195        assert!(attr.is_file());
196        clean_up(f_key);
197    }
198
199    #[test]
200    fn free() {
201        let f_key = "free_provider";
202        let mut manager = StorageManager::new();
203        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
204        let _save_result = manager.save("layer1", FILE_KEY, "test".to_owned().into_bytes());
205        manager.delete("layer1", FILE_KEY);
206        manager.free();
207        let exists = std::path::Path::new(&format!("{}_{}/{}", DELETE_STORAGE, f_key, FILE_KEY)).exists();
208        assert!(exists);
209        clean_up(f_key);
210    }
211
212    #[test]
213    fn free_force() {
214        let f_key = "free_force_provider";
215        let mut manager = StorageManager::new();
216        manager.add_storage_provider("layer1".to_owned(), storage_provider_instance(f_key));
217        let _save_result = manager.save("layer1", FILE_KEY, "test".to_owned().into_bytes());
218        manager.delete("layer1", FILE_KEY);
219        manager.force_free(true);
220        let exists = std::path::Path::new(&format!("{}_{}/{}", DELETE_STORAGE, f_key, FILE_KEY)).exists();
221        assert!(!exists);
222        clean_up(f_key);
223    }
224}