cronback_lib/
config.rs

1//! Configuration Model
2
3use std::collections::{HashMap, HashSet};
4
5use config::builder::DefaultState;
6use config::{
7    Config as ConfigRaw,
8    ConfigBuilder,
9    ConfigError,
10    Environment,
11    File,
12    FileFormat,
13};
14use serde::Deserialize;
15
16#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
17#[serde(rename_all = "snake_case")]
18#[allow(unused)]
19pub enum Role {
20    Api,
21    Dispatcher,
22    Scheduler,
23}
24
25#[derive(Debug, Clone, Deserialize)]
26pub struct MainConfig {
27    pub roles: HashSet<Role>,
28    pub prometheus_address: String,
29    pub prometheus_port: u16,
30    pub dispatcher_cell_map: HashMap<u64, String>,
31    pub scheduler_cell_map: HashMap<u64, String>,
32}
33
34#[derive(Debug, Clone, Deserialize)]
35pub struct DispatcherConfig {
36    pub cell_id: u32,
37    pub address: String,
38    pub port: u16,
39    pub request_processing_timeout_s: u64,
40    pub database_uri: String,
41}
42
43#[derive(Debug, Clone, Deserialize)]
44pub struct SchedulerConfig {
45    // Cell Id of the current scheduler
46    pub cell_id: u32,
47    pub address: String,
48    pub port: u16,
49    pub request_processing_timeout_s: u64,
50    pub spinner_yield_max_ms: u64,
51    pub max_triggers_per_tick: u64,
52    pub database_uri: String,
53    pub db_flush_s: u64,
54    pub dangerous_fast_forward: bool,
55}
56
57#[derive(Debug, Clone, Deserialize)]
58pub struct ApiConfig {
59    pub address: String,
60    pub port: u16,
61    pub database_uri: String,
62    pub admin_api_keys: HashSet<String>,
63    pub log_request_body: bool,
64    pub log_response_body: bool,
65}
66
67#[derive(Debug, Clone, Deserialize)]
68#[allow(unused)]
69///
70///
71/// * `roles`: Which roles the binary will start with
72/// * `api`: Configuration of the API server
73/// * `dispatcher`:  Configuration of the dispatcher
74/// * `scheduler`:  Configuration of the scheduler
75pub struct Config {
76    pub main: MainConfig,
77    pub api: ApiConfig,
78    pub dispatcher: DispatcherConfig,
79    pub scheduler: SchedulerConfig,
80}
81
82#[derive(Debug)]
83pub struct ConfigLoader {
84    builder: ConfigBuilder<DefaultState>,
85}
86
87impl ConfigLoader {
88    /// Loads a fresh copy of the configuration from source.
89    pub fn load(&self) -> Result<Config, ConfigError> {
90        Self::deserialize(self.builder.build_cloned()?)
91    }
92
93    /// creates a new loader configured to load the default and overlays
94    /// the user supplied config (if supplied).
95    ///
96    /// * `config_file`: The path of the configuration file to load.
97    pub fn from_path(path: &Option<String>) -> ConfigLoader {
98        let raw = include_str!("default.toml");
99        let mut builder = ConfigRaw::builder()
100            .add_source(File::from_str(raw, FileFormat::Toml))
101            .add_source(
102                Environment::with_prefix("CRONBACK")
103                    .try_parsing(true)
104                    .separator("__")
105                    .list_separator(",")
106                    .with_list_parse_key("api.admin_api_keys"),
107            );
108        if let Some(path) = path {
109            builder = builder.add_source(File::with_name(path));
110        }
111        ConfigLoader { builder }
112    }
113
114    fn deserialize(config: ConfigRaw) -> Result<Config, ConfigError> {
115        config.try_deserialize()
116    }
117}