1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use crate::utils::types::ConnectorType;
4
5#[derive(Debug, Clone, Deserialize, Serialize)]
7pub struct EngineConfig {
8 pub protocol_adapters: Vec<ProtocolConfig>,
9 pub connectors: HashMap<String, ConnectorConfig>,
10 pub dispatcher: DispatcherConfig,
11 pub security: SecurityConfig,
12}
13
14#[derive(Debug, Clone, Deserialize, Serialize)]
16pub struct ProtocolConfig {
17 pub protocol_type: ProtocolType,
18 pub bind_address: String,
19 pub port: u16,
20 pub tls_config: Option<TlsConfig>,
21 pub max_connections: Option<u32>,
22 pub connection_timeout: Option<u64>, }
24
25#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
27pub enum ProtocolType {
28 PostgreSQL,
29 MySQL,
30 SQLite,
31}
32
33#[derive(Debug, Clone, Deserialize, Serialize)]
35pub struct TlsConfig {
36 pub cert_file: String,
37 pub key_file: String,
38 pub ca_file: Option<String>,
39 pub require_client_cert: bool,
40}
41
42#[derive(Debug, Clone, Deserialize, Serialize)]
44pub struct ConnectorConfig {
45 pub connector_type: ConnectorType,
46 pub connection_string: Option<String>,
47 pub parameters: HashMap<String, String>,
48 pub pool_config: Option<PoolConfig>,
49 pub timeout_config: Option<TimeoutConfig>,
50}
51
52#[derive(Debug, Clone, Deserialize, Serialize)]
54pub struct PoolConfig {
55 pub min_connections: u32,
56 pub max_connections: u32,
57 pub connection_timeout: u64, pub idle_timeout: u64, pub max_lifetime: Option<u64>, }
61
62#[derive(Debug, Clone, Deserialize, Serialize)]
64pub struct TimeoutConfig {
65 pub connect_timeout: u64, pub query_timeout: u64, pub transaction_timeout: u64, }
69
70#[derive(Debug, Clone, Deserialize, Serialize)]
72pub struct DispatcherConfig {
73 pub max_concurrent_queries: u32,
74 pub query_cache_size: Option<u64>, pub enable_cross_connector_joins: bool,
76 pub default_timeout: u64, }
78
79#[derive(Debug, Clone, Deserialize, Serialize)]
81pub struct SecurityConfig {
82 pub authentication: AuthenticationConfig,
83 pub authorization: AuthorizationConfig,
84 pub audit_logging: AuditConfig,
85}
86
87#[derive(Debug, Clone, Deserialize, Serialize)]
89pub struct AuthenticationConfig {
90 pub enabled: bool,
91 pub auth_method: AuthMethod,
92 pub user_database: Option<String>,
93 pub ldap_config: Option<LdapConfig>,
94}
95
96#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
98pub enum AuthMethod {
99 None,
100 Password,
101 Certificate,
102 LDAP,
103 OAuth2,
104}
105
106#[derive(Debug, Clone, Deserialize, Serialize)]
108pub struct LdapConfig {
109 pub server_url: String,
110 pub bind_dn: String,
111 pub bind_password: String,
112 pub user_search_base: String,
113 pub user_search_filter: String,
114}
115
116#[derive(Debug, Clone, Deserialize, Serialize)]
118pub struct AuthorizationConfig {
119 pub enabled: bool,
120 pub default_permissions: Vec<Permission>,
121 pub role_mappings: HashMap<String, Vec<Permission>>,
122}
123
124#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
126pub enum Permission {
127 Read,
128 Write,
129 Admin,
130 Connect,
131}
132
133#[derive(Debug, Clone, Deserialize, Serialize)]
135pub struct AuditConfig {
136 pub enabled: bool,
137 pub log_file: Option<String>,
138 pub log_queries: bool,
139 pub log_connections: bool,
140 pub log_errors: bool,
141}
142
143impl Default for EngineConfig {
144 fn default() -> Self {
145 Self {
146 protocol_adapters: vec![
147 ProtocolConfig {
148 protocol_type: ProtocolType::PostgreSQL,
149 bind_address: "127.0.0.1".to_string(),
150 port: 5432,
151 tls_config: None,
152 max_connections: Some(100),
153 connection_timeout: Some(30),
154 }
155 ],
156 connectors: HashMap::new(),
157 dispatcher: DispatcherConfig::default(),
158 security: SecurityConfig::default(),
159 }
160 }
161}
162
163impl Default for DispatcherConfig {
164 fn default() -> Self {
165 Self {
166 max_concurrent_queries: 100,
167 query_cache_size: Some(256), enable_cross_connector_joins: false,
169 default_timeout: 300, }
171 }
172}
173
174impl Default for SecurityConfig {
175 fn default() -> Self {
176 Self {
177 authentication: AuthenticationConfig {
178 enabled: false,
179 auth_method: AuthMethod::None,
180 user_database: None,
181 ldap_config: None,
182 },
183 authorization: AuthorizationConfig {
184 enabled: false,
185 default_permissions: vec![Permission::Read],
186 role_mappings: HashMap::new(),
187 },
188 audit_logging: AuditConfig {
189 enabled: true,
190 log_file: None,
191 log_queries: true,
192 log_connections: true,
193 log_errors: true,
194 },
195 }
196 }
197}
198
199impl Default for PoolConfig {
200 fn default() -> Self {
201 Self {
202 min_connections: 1,
203 max_connections: 10,
204 connection_timeout: 30,
205 idle_timeout: 600,
206 max_lifetime: Some(3600),
207 }
208 }
209}
210
211impl Default for TimeoutConfig {
212 fn default() -> Self {
213 Self {
214 connect_timeout: 30,
215 query_timeout: 300,
216 transaction_timeout: 600,
217 }
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use super::*;
224
225 #[test]
226 fn test_engine_config_default() {
227 let config = EngineConfig::default();
228
229 assert_eq!(config.protocol_adapters.len(), 1);
230 assert_eq!(config.protocol_adapters[0].protocol_type, ProtocolType::PostgreSQL);
231 assert_eq!(config.protocol_adapters[0].bind_address, "127.0.0.1");
232 assert_eq!(config.protocol_adapters[0].port, 5432);
233 assert!(config.connectors.is_empty());
234 }
235
236 #[test]
237 fn test_protocol_config_creation() {
238 let config = ProtocolConfig {
239 protocol_type: ProtocolType::MySQL,
240 bind_address: "0.0.0.0".to_string(),
241 port: 3306,
242 tls_config: None,
243 max_connections: Some(50),
244 connection_timeout: Some(60),
245 };
246
247 assert_eq!(config.protocol_type, ProtocolType::MySQL);
248 assert_eq!(config.bind_address, "0.0.0.0");
249 assert_eq!(config.port, 3306);
250 assert_eq!(config.max_connections, Some(50));
251 }
252
253 #[test]
254 fn test_connector_config_creation() {
255 let mut parameters = HashMap::new();
256 parameters.insert("host".to_string(), "localhost".to_string());
257 parameters.insert("database".to_string(), "test_db".to_string());
258
259 let config = ConnectorConfig {
260 connector_type: ConnectorType::PostgreSQL,
261 connection_string: Some("postgresql://localhost/test".to_string()),
262 parameters,
263 pool_config: Some(PoolConfig::default()),
264 timeout_config: Some(TimeoutConfig::default()),
265 };
266
267 assert_eq!(config.connector_type, ConnectorType::PostgreSQL);
268 assert!(config.connection_string.is_some());
269 assert_eq!(config.parameters.get("host"), Some(&"localhost".to_string()));
270 assert!(config.pool_config.is_some());
271 assert!(config.timeout_config.is_some());
272 }
273
274 #[test]
275 fn test_dispatcher_config_default() {
276 let config = DispatcherConfig::default();
277
278 assert_eq!(config.max_concurrent_queries, 100);
279 assert_eq!(config.query_cache_size, Some(256));
280 assert!(!config.enable_cross_connector_joins);
281 assert_eq!(config.default_timeout, 300);
282 }
283
284 #[test]
285 fn test_security_config_default() {
286 let config = SecurityConfig::default();
287
288 assert!(!config.authentication.enabled);
289 assert_eq!(config.authentication.auth_method, AuthMethod::None);
290 assert!(!config.authorization.enabled);
291 assert_eq!(config.authorization.default_permissions, vec![Permission::Read]);
292 assert!(config.audit_logging.enabled);
293 assert!(config.audit_logging.log_queries);
294 }
295
296 #[test]
297 fn test_pool_config_default() {
298 let config = PoolConfig::default();
299
300 assert_eq!(config.min_connections, 1);
301 assert_eq!(config.max_connections, 10);
302 assert_eq!(config.connection_timeout, 30);
303 assert_eq!(config.idle_timeout, 600);
304 assert_eq!(config.max_lifetime, Some(3600));
305 }
306
307 #[test]
308 fn test_timeout_config_default() {
309 let config = TimeoutConfig::default();
310
311 assert_eq!(config.connect_timeout, 30);
312 assert_eq!(config.query_timeout, 300);
313 assert_eq!(config.transaction_timeout, 600);
314 }
315
316 #[test]
317 fn test_auth_method_variants() {
318 let methods = vec![
319 AuthMethod::None,
320 AuthMethod::Password,
321 AuthMethod::Certificate,
322 AuthMethod::LDAP,
323 AuthMethod::OAuth2,
324 ];
325
326 assert_eq!(methods.len(), 5);
327 assert_eq!(methods[0], AuthMethod::None);
328 assert_eq!(methods[1], AuthMethod::Password);
329 }
330
331 #[test]
332 fn test_permission_variants() {
333 let permissions = vec![
334 Permission::Read,
335 Permission::Write,
336 Permission::Admin,
337 Permission::Connect,
338 ];
339
340 assert_eq!(permissions.len(), 4);
341 assert_eq!(permissions[0], Permission::Read);
342 assert_eq!(permissions[1], Permission::Write);
343 }
344}