rocketmq_controller/metadata/
config.rs

1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18use std::sync::Arc;
19
20use dashmap::DashMap;
21use serde::Deserialize;
22use serde::Serialize;
23use tracing::info;
24
25use crate::config::ControllerConfig;
26use crate::error::ControllerError;
27use crate::error::Result;
28
29/// Configuration information
30#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct ConfigInfo {
32    /// Config key
33    pub key: String,
34
35    /// Config value
36    pub value: String,
37
38    /// Config description
39    pub description: Option<String>,
40}
41
42/// Configuration manager
43pub struct ConfigManager {
44    /// Configurations: key -> ConfigInfo
45    configs: Arc<DashMap<String, ConfigInfo>>,
46
47    /// Controller configuration
48    #[allow(dead_code)]
49    config: Arc<ControllerConfig>,
50}
51
52impl ConfigManager {
53    /// Create a new config manager
54    pub fn new(config: Arc<ControllerConfig>) -> Self {
55        Self {
56            configs: Arc::new(DashMap::new()),
57            config,
58        }
59    }
60
61    /// Start the config manager
62    pub async fn start(&self) -> Result<()> {
63        info!("Starting config manager");
64        Ok(())
65    }
66
67    /// Shutdown the config manager
68    pub async fn shutdown(&self) -> Result<()> {
69        info!("Shutting down config manager");
70        self.configs.clear();
71        Ok(())
72    }
73
74    /// Set a configuration
75    pub async fn set_config(&self, info: ConfigInfo) -> Result<()> {
76        info!("Setting config: {} = {}", info.key, info.value);
77
78        if info.key.is_empty() {
79            return Err(ControllerError::InvalidRequest(
80                "Config key cannot be empty".to_string(),
81            ));
82        }
83
84        self.configs.insert(info.key.clone(), info);
85        Ok(())
86    }
87
88    /// Get a configuration
89    pub async fn get_config(&self, key: &str) -> Result<ConfigInfo> {
90        self.configs
91            .get(key)
92            .map(|entry| entry.value().clone())
93            .ok_or_else(|| ControllerError::MetadataNotFound {
94                key: key.to_string(),
95            })
96    }
97
98    /// Delete a configuration
99    pub async fn delete_config(&self, key: &str) -> Result<()> {
100        info!("Deleting config: {}", key);
101
102        self.configs
103            .remove(key)
104            .ok_or_else(|| ControllerError::MetadataNotFound {
105                key: key.to_string(),
106            })?;
107
108        Ok(())
109    }
110
111    /// List all configurations
112    pub async fn list_configs(&self) -> Vec<ConfigInfo> {
113        self.configs
114            .iter()
115            .map(|entry| entry.value().clone())
116            .collect()
117    }
118}
119
120#[cfg(test)]
121mod tests {
122    use super::*;
123
124    #[tokio::test]
125    async fn test_config_management() {
126        let config = Arc::new(ControllerConfig::test_config());
127
128        let manager = ConfigManager::new(config);
129
130        let info = ConfigInfo {
131            key: "test.key".to_string(),
132            value: "test.value".to_string(),
133            description: Some("Test configuration".to_string()),
134        };
135
136        assert!(manager.set_config(info.clone()).await.is_ok());
137        assert!(manager.get_config("test.key").await.is_ok());
138    }
139}