Skip to main content

mocra_core/common/model/
model_config.rs

1use crate::cacheable::CacheAble;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5/// Module-level configuration snapshot.
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct ModuleConfig {
8    pub account_config: serde_json::Value, // Configuration loaded from account table.
9    pub platform_config: serde_json::Value, // Configuration loaded from platform table.
10    pub module_config: serde_json::Value,  // Configuration defined on the module itself.
11    pub data_middleware_config: HashMap<String, serde_json::Value>, // Data middleware configs.
12    pub download_middleware_config: HashMap<String, serde_json::Value>, // Download middleware configs.
13    pub rel_account_platform_config: serde_json::Value,
14    pub rel_module_account_config: serde_json::Value, // Module-account relation config.
15    pub rel_module_platform_config: serde_json::Value, // Module-platform relation config.
16    pub rel_module_data_middleware_config: HashMap<String, serde_json::Value>, // Module-data-middleware relation config.
17    pub rel_module_download_middleware_config: HashMap<String, serde_json::Value>, // Module-download-middleware relation config.
18}
19impl Default for ModuleConfig {
20    fn default() -> Self {
21        ModuleConfig {
22            account_config: serde_json::Value::Object(serde_json::Map::new()),
23            platform_config: serde_json::Value::Object(serde_json::Map::new()),
24            module_config: serde_json::Value::Object(serde_json::Map::new()),
25            data_middleware_config: HashMap::new(),
26            download_middleware_config: HashMap::new(),
27            rel_account_platform_config: serde_json::Value::Object(serde_json::Map::new()),
28            rel_module_account_config: serde_json::Value::Object(serde_json::Map::new()),
29            rel_module_platform_config: serde_json::Value::Object(serde_json::Map::new()),
30            rel_module_data_middleware_config: HashMap::new(),
31            rel_module_download_middleware_config: HashMap::new(),
32        }
33    }
34}
35impl ModuleConfig {
36    /// Returns merged configuration with priority: `module_config > rel_platform_config >`
37    /// rel_account_config > rel_data_middleware_config > rel_download_middleware_config >
38    /// platform_config > account_config
39    pub fn get_merged_config(&self) -> serde_json::Value {
40        let mut merged = serde_json::Map::new();
41
42        // Merge from lower priority to higher priority.
43
44        // 1. Lowest priority: account base config.
45        if let serde_json::Value::Object(account_config) = &self.account_config {
46            for (key, value) in account_config {
47                merged.insert(key.clone(), value.clone());
48            }
49        }
50
51        // 2. Platform base config.
52        if let serde_json::Value::Object(platform_config) = &self.platform_config {
53            for (key, value) in platform_config {
54                merged.insert(key.clone(), value.clone());
55            }
56        }
57
58        // 3. Download middleware base config.
59        for config in self.download_middleware_config.values() {
60            if let serde_json::Value::Object(download_config) = config {
61                for (key, value) in download_config {
62                    merged.insert(key.clone(), value.clone());
63                }
64            }
65        }
66
67        // 4. Data middleware base config.
68        for config in self.data_middleware_config.values() {
69            if let serde_json::Value::Object(data_config) = config {
70                for (key, value) in data_config {
71                    merged.insert(key.clone(), value.clone());
72                }
73            }
74        }
75
76        if let serde_json::Value::Object(module_config) = &self.rel_account_platform_config {
77            for (key, value) in module_config {
78                merged.insert(key.clone(), value.clone());
79            }
80        }
81
82        // 5. Module-download-middleware relation config.
83        for config in self.rel_module_download_middleware_config.values() {
84            if let serde_json::Value::Object(rel_download_config) = config {
85                for (key, value) in rel_download_config {
86                    merged.insert(key.clone(), value.clone());
87                }
88            }
89        }
90
91        // 6. Module-data-middleware relation config.
92        for config in self.rel_module_data_middleware_config.values() {
93            if let serde_json::Value::Object(rel_data_config) = config {
94                for (key, value) in rel_data_config {
95                    merged.insert(key.clone(), value.clone());
96                }
97            }
98        }
99
100        // 7. Module-account relation config.
101        if let serde_json::Value::Object(rel_account_config) = &self.rel_module_account_config {
102            for (key, value) in rel_account_config {
103                merged.insert(key.clone(), value.clone());
104            }
105        }
106
107        // 8. Module-platform relation config.
108        if let serde_json::Value::Object(rel_platform_config) = &self.rel_module_platform_config {
109            for (key, value) in rel_platform_config {
110                merged.insert(key.clone(), value.clone());
111            }
112        }
113
114        // 9. Highest priority: module self config.
115        if let serde_json::Value::Object(module_config) = &self.module_config {
116            for (key, value) in module_config {
117                merged.insert(key.clone(), value.clone());
118            }
119        }
120
121        serde_json::Value::Object(merged)
122    }
123
124    /// Returns the configuration value for a key using priority-based lookup.
125    pub fn get_config_value(&self, key: &str) -> Option<&serde_json::Value> {
126        // 1. Highest priority: module self config.
127        if let serde_json::Value::Object(module_config) = &self.module_config
128            && let Some(value) = module_config.get(key)
129        {
130            return Some(value);
131        }
132
133        // 2. Module-platform relation config.
134        if let serde_json::Value::Object(rel_platform_config) = &self.rel_module_platform_config
135            && let Some(value) = rel_platform_config.get(key)
136        {
137            return Some(value);
138        }
139
140        // 3. Module-account relation config.
141        if let serde_json::Value::Object(rel_account_config) = &self.rel_module_account_config
142            && let Some(value) = rel_account_config.get(key)
143        {
144            return Some(value);
145        }
146
147        // 4. Module-data-middleware relation config.
148        for config in self.rel_module_data_middleware_config.values() {
149            if let serde_json::Value::Object(rel_data_config) = config
150                && let Some(value) = rel_data_config.get(key)
151            {
152                return Some(value);
153            }
154        }
155
156        // 5. Module-download-middleware relation config.
157        for config in self.rel_module_download_middleware_config.values() {
158            if let serde_json::Value::Object(rel_download_config) = config
159                && let Some(value) = rel_download_config.get(key)
160            {
161                return Some(value);
162            }
163        }
164
165        if let serde_json::Value::Object(rel_account_platform_config) =
166            &self.rel_account_platform_config
167            && let Some(value) = rel_account_platform_config.get(key)
168        {
169            return Some(value);
170        }
171        // 6. Platform base config.
172        if let serde_json::Value::Object(platform_config) = &self.platform_config
173            && let Some(value) = platform_config.get(key)
174        {
175            return Some(value);
176        }
177        // Account base config.
178        if let serde_json::Value::Object(account_config) = &self.account_config
179            && let Some(value) = account_config.get(key)
180        {
181            return Some(value);
182        }
183        // 7. Data middleware base config.
184        for config in self.download_middleware_config.values() {
185            if let serde_json::Value::Object(data_config) = config
186                && let Some(value) = data_config.get(key)
187            {
188                return Some(value);
189            }
190        }
191
192        // 8. Download middleware base config.
193        for config in self.data_middleware_config.values() {
194            if let serde_json::Value::Object(download_config) = config
195                && let Some(value) = download_config.get(key)
196            {
197                return Some(value);
198            }
199        }
200        None
201    }
202    pub fn get_middleware_weight(&self, middleware_name: &str) -> Option<u32> {
203        if let Some(serde_json::Value::Object(obj)) =
204            self.download_middleware_config.get(middleware_name)
205            && let Some(weight) = obj.get("weight")
206        {
207            return weight.as_u64().map(|v| v as u32);
208        }
209        if let Some(serde_json::Value::Object(obj)) = self
210            .rel_module_download_middleware_config
211            .get(middleware_name)
212            && let Some(weight) = obj.get("weight")
213        {
214            return weight.as_u64().map(|v| v as u32);
215        }
216        None
217    }
218    pub fn get_task_config(&self, key: &str) -> Option<&serde_json::Value> {
219        if let serde_json::Value::Object(account_config) = &self.account_config
220            && let Some(value) = account_config.get(key)
221        {
222            return Some(value);
223        }
224        if let serde_json::Value::Object(platform_config) = &self.platform_config
225            && let Some(value) = platform_config.get(key)
226        {
227            return Some(value);
228        }
229        if let serde_json::Value::Object(rel_account_platform_config) =
230            &self.rel_account_platform_config
231            && let Some(value) = rel_account_platform_config.get(key)
232        {
233            return Some(value);
234        }
235        None
236    }
237
238    pub fn get_config<T: serde::de::DeserializeOwned>(&self, key: &str) -> Option<T> {
239        if let Some(value) = self.get_config_value(key)
240            && let Ok(config) = serde_json::from_value::<T>(value.clone())
241        {
242            return Some(config);
243        }
244        None
245    }
246}
247
248impl CacheAble for ModuleConfig {
249    fn field() -> impl AsRef<str> {
250        "module_config"
251    }
252}