twelve_factor/
lib.rs

1#[macro_use]
2extern crate log;
3
4extern crate config;
5extern crate flexi_logger;
6extern crate getopts;
7extern crate hyper;
8extern crate hyper_router;
9
10mod configuration;
11mod logging;
12mod monitoring;
13
14use getopts::Options;
15use std::env;
16
17pub use configuration::{ConfigProvider, Configuration, ConfigurationPreferences};
18pub use logging::LoggingConfig;
19pub use monitoring::MonitoringConfig;
20
21pub struct ApplicationBuilder {
22    config_prefs: ConfigurationPreferences,
23    logging_config: LoggingConfig,
24    monitoring_config: MonitoringConfig,
25}
26
27impl ApplicationBuilder {
28    pub fn default() -> ApplicationBuilder {
29        ApplicationBuilder {
30            config_prefs: ConfigurationPreferences::default(),
31            logging_config: LoggingConfig::default(),
32            monitoring_config: MonitoringConfig::default(),
33        }
34    }
35
36    pub fn with_config_preferences(
37        mut self,
38        config_prefs: ConfigurationPreferences,
39    ) -> ApplicationBuilder {
40        self.config_prefs = config_prefs;
41        self
42    }
43
44    pub fn with_logging_config(mut self, logging_config: LoggingConfig) -> ApplicationBuilder {
45        self.logging_config = logging_config;
46        self
47    }
48
49    pub fn with_monitoring_config(
50        mut self,
51        monitoring_config: MonitoringConfig,
52    ) -> ApplicationBuilder {
53        self.monitoring_config = monitoring_config;
54        self
55    }
56
57    pub fn build(self) -> Application {
58        Application::start(&self)
59    }
60}
61
62pub trait LifeCycle {
63    fn shutdown(&self);
64}
65
66pub struct Application {
67    pub configuration: configuration::Configuration,
68}
69
70impl Application {
71    fn start(app_builder: &ApplicationBuilder) -> Application {
72        let config = Configuration::read_configuration(&app_builder.config_prefs);
73        logging::start_logging(&app_builder.logging_config);
74        monitoring::start_beacon(&app_builder.monitoring_config);
75        Application {
76            configuration: config,
77        }
78    }
79
80    pub fn start_from_cli() -> Application {
81        let args: Vec<String> = env::args().collect();
82        let mut options = Options::new();
83        options.optopt(
84            "c",
85            "config",
86            "fully qualified path to the configuration file",
87            "CONFIG",
88        );
89        options.optopt(
90            "s",
91            "secrets",
92            "fully qualified path to the file that contains secrets",
93            "SECRETS",
94        );
95        let matches = options
96            .parse(&args[1..])
97            .expect("Unable to read command line");
98
99        let config_prefs = ConfigurationPreferences {
100            config_file: matches.opt_str("config"),
101            secrets_file: matches.opt_str("secrets"),
102            prefix: None,
103            separator: None,
104        };
105
106        let config = Configuration::read_configuration(&config_prefs);
107
108        let log_config: LoggingConfig = match config.get_value("logging") {
109            Ok(v) => v,
110            Err(_) => LoggingConfig::default(),
111        };
112
113        let montior_config: MonitoringConfig = match config.get_value("monitoring") {
114            Ok(v) => v,
115            Err(_) => MonitoringConfig::default(),
116        };
117        logging::start_logging(&log_config);
118        monitoring::start_beacon(&montior_config);
119
120        Application {
121            configuration: config,
122        }
123    }
124}