opendal/services/azblob/
config.rs1use std::fmt::Debug;
19
20use serde::Deserialize;
21use serde::Serialize;
22
23use super::backend::AzblobBuilder;
24
25#[derive(Default, Serialize, Deserialize, Clone, PartialEq, Eq)]
27pub struct AzblobConfig {
28 pub root: Option<String>,
32
33 #[serde(alias = "azure_container_name", alias = "container_name")]
35 pub container: String,
36
37 #[serde(alias = "azure_storage_endpoint", alias = "azure_endpoint")]
44 pub endpoint: Option<String>,
45
46 #[serde(alias = "azure_storage_account_name")]
48 pub account_name: Option<String>,
49
50 #[serde(
52 alias = "azure_storage_account_key",
53 alias = "azure_storage_access_key",
54 alias = "azure_storage_master_key",
55 alias = "access_key",
56 alias = "master_key"
57 )]
58 pub account_key: Option<String>,
59
60 pub encryption_key: Option<String>,
62
63 pub encryption_key_sha256: Option<String>,
65
66 pub encryption_algorithm: Option<String>,
68
69 #[serde(
71 alias = "azure_storage_sas_key",
72 alias = "azure_storage_sas_token",
73 alias = "sas_key"
74 )]
75 pub sas_token: Option<String>,
76
77 pub batch_max_operations: Option<usize>,
79}
80
81impl Debug for AzblobConfig {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 f.debug_struct("AzblobConfig")
84 .field("root", &self.root)
85 .field("container", &self.container)
86 .field("endpoint", &self.endpoint)
87 .finish_non_exhaustive()
88 }
89}
90
91impl crate::Configurator for AzblobConfig {
92 type Builder = AzblobBuilder;
93
94 fn from_uri(uri: &crate::types::OperatorUri) -> crate::Result<Self> {
95 let mut map = uri.options().clone();
96
97 if let Some(container) = uri.name() {
98 map.insert("container".to_string(), container.to_string());
99 }
100
101 if let Some(root) = uri.root() {
102 map.insert("root".to_string(), root.to_string());
103 }
104
105 Self::from_iter(map)
106 }
107
108 #[allow(deprecated)]
109 fn into_builder(self) -> Self::Builder {
110 AzblobBuilder {
111 config: self,
112
113 http_client: None,
114 }
115 }
116}
117
118#[cfg(test)]
119mod tests {
120 use super::*;
121 use crate::Configurator;
122 use crate::types::OperatorUri;
123
124 #[test]
125 fn test_container_name_aliases() {
126 let json = r#"{"container": "test-container"}"#;
127 let config: AzblobConfig = serde_json::from_str(json).unwrap();
128 assert_eq!(config.container, "test-container");
129
130 let json = r#"{"azure_container_name": "test-container"}"#;
131 let config: AzblobConfig = serde_json::from_str(json).unwrap();
132 assert_eq!(config.container, "test-container");
133
134 let json = r#"{"container_name": "test-container"}"#;
135 let config: AzblobConfig = serde_json::from_str(json).unwrap();
136 assert_eq!(config.container, "test-container");
137 }
138
139 #[test]
140 fn test_account_name_aliases() {
141 let json = r#"{"container": "test", "account_name": "testaccount"}"#;
142 let config: AzblobConfig = serde_json::from_str(json).unwrap();
143 assert_eq!(config.account_name, Some("testaccount".to_string()));
144
145 let json = r#"{"container": "test", "azure_storage_account_name": "testaccount-azure"}"#;
146 let config: AzblobConfig = serde_json::from_str(json).unwrap();
147 assert_eq!(config.account_name, Some("testaccount-azure".to_string()));
148 }
149
150 #[test]
151 fn test_account_key_aliases() {
152 let json = r#"{"container": "test", "account_key": "dGVzdGtleQ=="}"#;
153 let config: AzblobConfig = serde_json::from_str(json).unwrap();
154 assert_eq!(config.account_key, Some("dGVzdGtleQ==".to_string()));
155
156 let json = r#"{"container": "test", "azure_storage_account_key": "dGVzdGtleQ=="}"#;
157 let config: AzblobConfig = serde_json::from_str(json).unwrap();
158 assert_eq!(config.account_key, Some("dGVzdGtleQ==".to_string()));
159
160 let json = r#"{"container": "test", "azure_storage_access_key": "dGVzdGtleQ=="}"#;
161 let config: AzblobConfig = serde_json::from_str(json).unwrap();
162 assert_eq!(config.account_key, Some("dGVzdGtleQ==".to_string()));
163
164 let json = r#"{"container": "test", "azure_storage_master_key": "dGVzdGtleQ=="}"#;
165 let config: AzblobConfig = serde_json::from_str(json).unwrap();
166 assert_eq!(config.account_key, Some("dGVzdGtleQ==".to_string()));
167
168 let json = r#"{"container": "test", "access_key": "dGVzdGtleQ=="}"#;
169 let config: AzblobConfig = serde_json::from_str(json).unwrap();
170 assert_eq!(config.account_key, Some("dGVzdGtleQ==".to_string()));
171
172 let json = r#"{"container": "test", "master_key": "dGVzdGtleQ=="}"#;
173 let config: AzblobConfig = serde_json::from_str(json).unwrap();
174 assert_eq!(config.account_key, Some("dGVzdGtleQ==".to_string()));
175 }
176
177 #[test]
178 fn test_sas_token_aliases() {
179 let json = r#"{"container": "test", "sas_token": "test-token"}"#;
180 let config: AzblobConfig = serde_json::from_str(json).unwrap();
181 assert_eq!(config.sas_token, Some("test-token".to_string()));
182
183 let json = r#"{"container": "test", "azure_storage_sas_key": "test-token"}"#;
184 let config: AzblobConfig = serde_json::from_str(json).unwrap();
185 assert_eq!(config.sas_token, Some("test-token".to_string()));
186
187 let json = r#"{"container": "test", "azure_storage_sas_token": "test-token"}"#;
188 let config: AzblobConfig = serde_json::from_str(json).unwrap();
189 assert_eq!(config.sas_token, Some("test-token".to_string()));
190
191 let json = r#"{"container": "test", "sas_key": "test-token"}"#;
192 let config: AzblobConfig = serde_json::from_str(json).unwrap();
193 assert_eq!(config.sas_token, Some("test-token".to_string()));
194 }
195
196 #[test]
197 fn test_endpoint_aliases() {
198 let json = r#"{"container": "test", "endpoint": "https://test.blob.core.windows.net"}"#;
199 let config: AzblobConfig = serde_json::from_str(json).unwrap();
200 assert_eq!(
201 config.endpoint,
202 Some("https://test.blob.core.windows.net".to_string())
203 );
204
205 let json = r#"{"container": "test", "azure_storage_endpoint": "https://test.blob.core.windows.net"}"#;
206 let config: AzblobConfig = serde_json::from_str(json).unwrap();
207 assert_eq!(
208 config.endpoint,
209 Some("https://test.blob.core.windows.net".to_string())
210 );
211
212 let json =
213 r#"{"container": "test", "azure_endpoint": "https://test.blob.core.windows.net"}"#;
214 let config: AzblobConfig = serde_json::from_str(json).unwrap();
215 assert_eq!(
216 config.endpoint,
217 Some("https://test.blob.core.windows.net".to_string())
218 );
219 }
220
221 #[test]
222 fn from_uri_with_host_container() {
223 let uri = OperatorUri::new(
224 "azblob://my-container/path/to/root",
225 Vec::<(String, String)>::new(),
226 )
227 .unwrap();
228 let cfg = AzblobConfig::from_uri(&uri).unwrap();
229 assert_eq!(cfg.container, "my-container");
230 assert_eq!(cfg.root.as_deref(), Some("path/to/root"));
231 }
232
233 #[test]
234 fn from_uri_with_path_container() {
235 let uri = OperatorUri::new(
236 "azblob://my-container/nested/root",
237 Vec::<(String, String)>::new(),
238 )
239 .unwrap();
240 let cfg = AzblobConfig::from_uri(&uri).unwrap();
241 assert_eq!(cfg.container, "my-container");
242 assert_eq!(cfg.root.as_deref(), Some("nested/root"));
243 }
244}