reactive_graph_config_impl/
config_manager_impl.rs1use std::path::PathBuf;
2use std::sync::RwLock;
3
4use async_trait::async_trait;
5use log::debug;
6use log::error;
7use log::info;
8use springtime_di::Component;
9use springtime_di::component_alias;
10
11use reactive_graph_config_api::ConfigManager;
12use reactive_graph_config_model::GraphQLServerConfig;
13use reactive_graph_config_model::InstanceConfig;
14use reactive_graph_config_model::PluginsConfig;
15use reactive_graph_config_model::RemotesConfig;
16use reactive_graph_lifecycle::Lifecycle;
17
18const DEFAULT_CONFIG_LOCATION: &str = "./config";
19
20const DEFAULT_INSTANCE_CONFIG_FILENAME: &str = "instance.toml";
21
22const DEFAULT_GRAPHQL_CONFIG_FILENAME: &str = "graphql.toml";
23
24const DEFAULT_PLUGINS_CONFIG_FILENAME: &str = "plugins.toml";
25
26const DEFAULT_REMOTES_CONFIG_FILENAME: &str = "remotes.toml";
27
28fn create_instance_config_location() -> RwLock<PathBuf> {
29 let mut p = PathBuf::from(DEFAULT_CONFIG_LOCATION);
31 p.push(DEFAULT_INSTANCE_CONFIG_FILENAME);
32 RwLock::new(p)
33}
34
35fn create_graphql_server_config_location() -> RwLock<PathBuf> {
36 let mut p = PathBuf::from(DEFAULT_CONFIG_LOCATION);
37 p.push(DEFAULT_GRAPHQL_CONFIG_FILENAME);
38 RwLock::new(p)
39}
40
41fn create_plugins_config_location() -> RwLock<PathBuf> {
42 let mut p = PathBuf::from(DEFAULT_CONFIG_LOCATION);
43 p.push(DEFAULT_PLUGINS_CONFIG_FILENAME);
44 RwLock::new(p)
45}
46
47fn create_remotes_config_location() -> RwLock<PathBuf> {
48 let mut p = PathBuf::from(DEFAULT_CONFIG_LOCATION);
49 p.push(DEFAULT_REMOTES_CONFIG_FILENAME);
50 RwLock::new(p)
51}
52
53fn create_instance_config() -> RwLock<InstanceConfig> {
54 RwLock::new(InstanceConfig::default())
55}
56
57fn create_graphql_server_config() -> RwLock<GraphQLServerConfig> {
58 RwLock::new(GraphQLServerConfig::default())
59}
60
61fn create_plugins_config() -> RwLock<PluginsConfig> {
62 RwLock::new(PluginsConfig::default())
63}
64
65fn create_remotes_config() -> RwLock<RemotesConfig> {
66 RwLock::new(RemotesConfig::default())
67}
68
69#[derive(Component)]
70pub struct ConfigManagerImpl {
71 #[component(default = "create_instance_config_location")]
72 instance_config_location: RwLock<PathBuf>,
73 #[component(default = "create_graphql_server_config_location")]
74 graphql_server_config_location: RwLock<PathBuf>,
75 #[component(default = "create_plugins_config_location")]
76 plugins_config_location: RwLock<PathBuf>,
77 #[component(default = "create_remotes_config_location")]
78 remotes_config_location: RwLock<PathBuf>,
79 #[component(default = "create_instance_config")]
80 instance_config: RwLock<InstanceConfig>,
81 #[component(default = "create_graphql_server_config")]
82 graphql_server_config: RwLock<GraphQLServerConfig>,
83 #[component(default = "create_plugins_config")]
84 plugins_config: RwLock<PluginsConfig>,
85 #[component(default = "create_remotes_config")]
86 remotes_config: RwLock<RemotesConfig>,
87}
88
89#[component_alias]
91impl ConfigManager for ConfigManagerImpl {
92 fn get_instance_config_location(&self) -> PathBuf {
93 let reader = self.instance_config_location.read().unwrap();
94 reader.clone()
95 }
96
97 fn set_instance_config_location(&self, instance_config_location: PathBuf) {
98 let mut writer = self.instance_config_location.write().unwrap();
99 *writer = instance_config_location;
100 }
101
102 fn get_graphql_server_config_location(&self) -> PathBuf {
103 let reader = self.graphql_server_config_location.read().unwrap();
104 reader.clone()
105 }
106
107 fn set_graphql_server_config_location(&self, graphql_server_config_location: PathBuf) {
108 let mut writer = self.graphql_server_config_location.write().unwrap();
109 *writer = graphql_server_config_location;
110 }
111
112 fn get_plugins_config_location(&self) -> PathBuf {
113 let reader = self.plugins_config_location.read().unwrap();
114 reader.clone()
115 }
116
117 fn set_plugins_config_location(&self, plugins_config_location: PathBuf) {
118 let mut writer = self.plugins_config_location.write().unwrap();
119 *writer = plugins_config_location;
120 }
121
122 fn get_remotes_config_location(&self) -> PathBuf {
123 let reader = self.remotes_config_location.read().unwrap();
124 reader.clone()
125 }
126
127 fn set_remotes_config_location(&self, remotes_config_location: PathBuf) {
128 let mut writer = self.remotes_config_location.write().unwrap();
129 *writer = remotes_config_location;
130 }
131
132 fn get_instance_config(&self) -> InstanceConfig {
133 let reader = self.instance_config.read().unwrap();
134 reader.clone()
135 }
136
137 fn set_instance_config(&self, instance_config: InstanceConfig) {
138 let mut writer = self.instance_config.write().unwrap();
139 *writer = instance_config;
140 }
141
142 fn read_instance_config(&self) {
143 let location = self.get_instance_config_location();
144 match std::fs::read_to_string(&location) {
145 Ok(toml_string) => match toml::from_str(&toml_string) {
146 Ok(instance_config) => {
147 self.set_instance_config(instance_config);
148 }
149 Err(_) => {
150 error!("Failed to load the instance configuration from {}: Invalid TOML", location.to_str().unwrap_or(""));
151 }
152 },
153 Err(_) => {
154 error!("Failed to load the instance configuration from {}: File does not exist", location.to_str().unwrap_or(""));
155 }
156 }
157 }
158
159 fn set_instance_name(&self, instance_name: &str) {
160 let mut writer = self.instance_config.write().unwrap();
161 writer.name = instance_name.to_string();
162 }
163
164 fn set_instance_description(&self, instance_description: &str) {
165 let mut writer = self.instance_config.write().unwrap();
166 writer.description = instance_description.to_string();
167 }
168
169 fn get_graphql_server_config(&self) -> GraphQLServerConfig {
170 let reader = self.graphql_server_config.read().unwrap();
171 reader.clone()
172 }
173
174 fn set_graphql_server_config(&self, graphql_server_config: GraphQLServerConfig) {
175 let mut writer = self.graphql_server_config.write().unwrap();
176 *writer = graphql_server_config;
177 }
178
179 fn read_graphql_server_config(&self) {
180 let location = self.get_graphql_server_config_location();
181 match std::fs::read_to_string(&location) {
182 Ok(toml_string) => match toml::from_str(&toml_string) {
183 Ok(graphql_server_config) => {
184 debug!("Loaded graphql configuration from {}", location.to_str().unwrap_or(""));
185 self.set_graphql_server_config(graphql_server_config);
186 }
187 Err(_) => {
188 error!("Failed to load the graphql configuration from {}: Invalid TOML", location.to_str().unwrap_or(""));
189 }
190 },
191 Err(_) => {
192 error!("Failed to load the graphql configuration from {}: File does not exist", location.to_str().unwrap_or(""));
193 }
194 }
195 }
196
197 fn set_graphql_hostname(&self, hostname: &str) {
198 let mut writer = self.graphql_server_config.write().unwrap();
199 writer.hostname = Some(String::from(hostname));
200 }
201
202 fn set_graphql_port(&self, port: u16) {
203 let mut writer = self.graphql_server_config.write().unwrap();
204 writer.port = Some(port);
205 }
206
207 fn set_graphql_secure(&self, secure: bool) {
208 let mut writer = self.graphql_server_config.write().unwrap();
209 writer.secure = Some(secure);
210 }
211
212 fn set_graphql_ssl_certificate_path(&self, ssl_certificate_path: &str) {
213 let mut writer = self.graphql_server_config.write().unwrap();
214 writer.ssl_certificate_path = Some(String::from(ssl_certificate_path));
215 }
216
217 fn set_graphql_ssl_private_key_path(&self, ssl_private_key_path: &str) {
218 let mut writer = self.graphql_server_config.write().unwrap();
219 writer.ssl_private_key_path = Some(String::from(ssl_private_key_path));
220 }
221
222 fn set_graphql_shutdown_timeout(&self, shutdown_timeout: u64) {
223 let mut writer = self.graphql_server_config.write().unwrap();
224 writer.shutdown_timeout = Some(shutdown_timeout);
225 }
226
227 fn set_graphql_workers(&self, workers: usize) {
228 let mut writer = self.graphql_server_config.write().unwrap();
229 writer.workers = Some(workers);
230 }
231
232 fn get_graphql_default_context_path(&self) -> Option<String> {
233 self.graphql_server_config.read().unwrap().default_context_path()
234 }
235
236 fn set_graphql_default_context_path(&self, default_context_path: String) {
237 let mut writer = self.graphql_server_config.write().unwrap();
238 writer.default_context_path = Some(default_context_path);
239 }
240
241 fn get_plugins_config(&self) -> PluginsConfig {
242 let reader = self.plugins_config.read().unwrap();
243 reader.clone()
244 }
245
246 fn set_plugins_config(&self, plugins_config: PluginsConfig) {
247 let mut writer = self.plugins_config.write().unwrap();
248 *writer = plugins_config;
249 }
250
251 fn read_plugins_config(&self) {
252 let location = self.get_plugins_config_location();
253 match std::fs::read_to_string(&location) {
254 Ok(toml_string) => match toml::from_str(&toml_string) {
255 Ok(plugins_config) => {
256 self.set_plugins_config(plugins_config);
257 }
258 Err(_) => {
259 error!("Failed to load the plugins configuration from {}: Invalid TOML", location.to_str().unwrap_or(""));
260 }
261 },
262 Err(_) => {
263 error!("Failed to load the plugins configuration from {}: File does not exist", location.to_str().unwrap_or(""));
264 }
265 }
266 }
267
268 fn set_disable_all_plugins(&self, disabled: bool) {
269 let mut writer = self.plugins_config.write().unwrap();
270 writer.disabled = Some(disabled);
271 }
272
273 fn set_disabled_plugins(&self, disabled_plugins: Vec<String>) {
274 let mut writer = self.plugins_config.write().unwrap();
275 writer.disabled_plugins = Some(disabled_plugins);
276 }
277
278 fn set_enabled_plugins(&self, enabled_plugins: Vec<String>) {
279 let mut writer = self.plugins_config.write().unwrap();
280 writer.enabled_plugins = Some(enabled_plugins);
281 }
282
283 fn set_disable_hot_deploy(&self, disable_hot_deploy: bool) {
284 let mut writer = self.plugins_config.write().unwrap();
285 writer.hot_deploy = Some(!disable_hot_deploy);
286 }
287
288 fn set_hot_deploy_location(&self, hot_deploy_location: Option<String>) {
289 let mut writer = self.plugins_config.write().unwrap();
290 writer.hot_deploy_location = hot_deploy_location;
291 }
292
293 fn set_install_location(&self, install_location: Option<String>) {
294 let mut writer = self.plugins_config.write().unwrap();
295 writer.install_location = install_location;
296 }
297
298 fn get_remotes_config(&self) -> RemotesConfig {
299 let reader = self.remotes_config.read().unwrap();
300 reader.clone()
301 }
302
303 fn set_remotes_config(&self, remotes_config: RemotesConfig) {
304 let mut writer = self.remotes_config.write().unwrap();
305 *writer = remotes_config;
306 }
307
308 fn read_remotes_config(&self) {
309 let location = self.get_remotes_config_location();
310 match std::fs::read_to_string(&location) {
311 Ok(toml_string) => match toml::from_str(&toml_string) {
312 Ok(remotes_config) => {
313 self.set_remotes_config(remotes_config);
314 }
315 Err(e) => {
316 error!("Failed to load the remotes configuration from {}: Invalid TOML: {}", location.to_str().unwrap_or(""), e);
317 }
318 },
319 Err(e) => {
320 error!("Failed to load the remotes configuration from {}: {}", location.to_str().unwrap_or(""), e);
321 }
322 }
323 }
324
325 fn write_remotes_config(&self) {
326 let location = self.get_remotes_config_location();
327 let remotes_config = self.get_remotes_config();
328 match toml::to_string(&remotes_config) {
329 Ok(toml_string) => match std::fs::write(location.clone(), toml_string) {
330 Ok(_) => info!("Saved remote configuration to {}", location.to_str().unwrap_or("")),
331 Err(e) => error!("Failed to save remote configuration to {}: {}", location.to_str().unwrap_or(""), e),
332 },
333 Err(e) => error!("Failed to save remote configuration to {}: {}", location.to_str().unwrap_or(""), e),
334 }
335 }
336}
337
338#[async_trait]
339impl Lifecycle for ConfigManagerImpl {
340 async fn init(&self) {
341 self.read_graphql_server_config();
342 self.read_instance_config();
343 self.read_plugins_config();
344 self.read_remotes_config();
345 }
346}