nirv_engine/utils/
config.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use crate::utils::types::ConnectorType;
4
5/// Main engine configuration
6#[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/// Protocol adapter configuration
15#[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>, // seconds
23}
24
25/// Supported protocol types
26#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
27pub enum ProtocolType {
28    PostgreSQL,
29    MySQL,
30    SQLite,
31}
32
33/// TLS configuration for protocols
34#[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/// Connector configuration
43#[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/// Connection pool configuration
53#[derive(Debug, Clone, Deserialize, Serialize)]
54pub struct PoolConfig {
55    pub min_connections: u32,
56    pub max_connections: u32,
57    pub connection_timeout: u64,    // seconds
58    pub idle_timeout: u64,          // seconds
59    pub max_lifetime: Option<u64>,  // seconds
60}
61
62/// Timeout configuration for connectors
63#[derive(Debug, Clone, Deserialize, Serialize)]
64pub struct TimeoutConfig {
65    pub connect_timeout: u64,       // seconds
66    pub query_timeout: u64,         // seconds
67    pub transaction_timeout: u64,   // seconds
68}
69
70/// Dispatcher configuration
71#[derive(Debug, Clone, Deserialize, Serialize)]
72pub struct DispatcherConfig {
73    pub max_concurrent_queries: u32,
74    pub query_cache_size: Option<u64>,  // MB
75    pub enable_cross_connector_joins: bool,
76    pub default_timeout: u64,           // seconds
77}
78
79/// Security configuration
80#[derive(Debug, Clone, Deserialize, Serialize)]
81pub struct SecurityConfig {
82    pub authentication: AuthenticationConfig,
83    pub authorization: AuthorizationConfig,
84    pub audit_logging: AuditConfig,
85}
86
87/// Authentication configuration
88#[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/// Authentication methods
97#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
98pub enum AuthMethod {
99    None,
100    Password,
101    Certificate,
102    LDAP,
103    OAuth2,
104}
105
106/// LDAP configuration
107#[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/// Authorization configuration
117#[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/// Permission types
125#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
126pub enum Permission {
127    Read,
128    Write,
129    Admin,
130    Connect,
131}
132
133/// Audit logging configuration
134#[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), // 256 MB
168            enable_cross_connector_joins: false,
169            default_timeout: 300, // 5 minutes
170        }
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}