Skip to content
Snippets Groups Projects
Commit a3cb9863 authored by Éloïs's avatar Éloïs
Browse files

[ref] core: move fns get_module_conf in conf crate + TU get env conf

parent b2963c78
No related branches found
No related tags found
1 merge request!256load conf from env vars as a priority
...@@ -997,6 +997,7 @@ dependencies = [ ...@@ -997,6 +997,7 @@ dependencies = [
"dubp-user-docs 0.14.0", "dubp-user-docs 0.14.0",
"dup-crypto 0.7.0", "dup-crypto 0.7.0",
"durs-common-tools 0.2.0", "durs-common-tools 0.2.0",
"durs-message 0.3.0-dev",
"durs-module 0.3.0-dev", "durs-module 0.3.0-dev",
"envy 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "envy 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
......
...@@ -14,6 +14,7 @@ dirs = "2.0.2" ...@@ -14,6 +14,7 @@ dirs = "2.0.2"
dup-crypto = { path = "../../crypto" } dup-crypto = { path = "../../crypto" }
dubp-currency-params = { path = "../../dubp/currency-params" } dubp-currency-params = { path = "../../dubp/currency-params" }
dubp-user-docs= { path = "../../dubp/user-docs" } dubp-user-docs= { path = "../../dubp/user-docs" }
durs-message = { path = "../message" }
durs-module = { path = "../module" } durs-module = { path = "../module" }
durs-common-tools = { path = "../../tools/common-tools" } durs-common-tools = { path = "../../tools/common-tools" }
envy = "0.4.1" envy = "0.4.1"
......
...@@ -40,7 +40,7 @@ pub mod errors; ...@@ -40,7 +40,7 @@ pub mod errors;
pub mod file; pub mod file;
mod global_conf; mod global_conf;
pub mod keypairs; pub mod keypairs;
mod modules_conf; pub mod modules_conf;
mod resources; mod resources;
mod v1; mod v1;
......
...@@ -15,7 +15,24 @@ ...@@ -15,7 +15,24 @@
//! Dunitrust modules configuration //! Dunitrust modules configuration
use durs_module::ModuleName; use crate::constants;
use crate::keypairs::DuniterKeyPairs;
use crate::DuRsConf;
use dubp_currency_params::CurrencyName;
use durs_common_tools::traits::merge::Merge;
use durs_message::DursMsg;
use durs_module::{
DursConfTrait, DursModule, ModuleConfError, ModuleName, ModuleStaticName, RequiredKeysContent,
};
/// Module configurations and required keys
pub type ModuleConfsAndKeys<M> = (
(
<M as DursModule<DuRsConf, DursMsg>>::ModuleConf,
Option<<M as DursModule<DuRsConf, DursMsg>>::ModuleUserConf>,
),
RequiredKeysContent,
);
#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)]
/// Modules conf /// Modules conf
...@@ -29,6 +46,44 @@ impl Default for ModulesConf { ...@@ -29,6 +46,44 @@ impl Default for ModulesConf {
} }
impl ModulesConf { impl ModulesConf {
// get module conf
fn get_module_conf<M: DursModule<DuRsConf, DursMsg>>(
currency_name: Option<&CurrencyName>,
global_conf: &<DuRsConf as DursConfTrait>::GlobalConf,
module_conf_json: Option<serde_json::Value>,
) -> Result<(M::ModuleConf, Option<M::ModuleUserConf>), ModuleConfError> {
let file_module_user_conf: M::ModuleUserConf =
if let Some(module_conf_json) = module_conf_json {
let file_module_user_conf_opt: Option<M::ModuleUserConf> =
serde_json::from_str(module_conf_json.to_string().as_str())?;
file_module_user_conf_opt.unwrap_or_default()
} else {
M::ModuleUserConf::default()
};
let env_module_user_conf = Self::get_env_module_user_conf::<M::ModuleUserConf>(M::name())?;
M::generate_module_conf(
currency_name,
global_conf,
Some(file_module_user_conf.merge(env_module_user_conf)),
)
}
// get module conf from environment variables
fn get_env_module_user_conf<ModuleUserConf: serde::de::DeserializeOwned>(
module_name: ModuleStaticName,
) -> Result<ModuleUserConf, ModuleConfError> {
let prefix = format!(
"{}{}_",
constants::DURS_ENV_PREFIX,
module_name.0.to_ascii_uppercase()
);
envy::prefixed(prefix)
.from_env::<ModuleUserConf>()
.map_err(ModuleConfError::EnvyErr)
}
/// Change module conf /// Change module conf
pub fn set_module_conf(&mut self, module_name: ModuleName, new_module_conf: serde_json::Value) { pub fn set_module_conf(&mut self, module_name: ModuleName, new_module_conf: serde_json::Value) {
if self.0.is_null() { if self.0.is_null() {
...@@ -44,3 +99,97 @@ impl ModulesConf { ...@@ -44,3 +99,97 @@ impl ModulesConf {
} }
} }
} }
/// Get module conf and keys
pub fn get_module_conf_and_keys<M: DursModule<DuRsConf, DursMsg>>(
currency_name: Option<&CurrencyName>,
global_conf: &<DuRsConf as DursConfTrait>::GlobalConf,
module_conf_json: Option<serde_json::Value>,
keypairs: DuniterKeyPairs,
) -> Result<ModuleConfsAndKeys<M>, ModuleConfError> {
Ok((
ModulesConf::get_module_conf::<M>(currency_name, global_conf, module_conf_json)?,
DuniterKeyPairs::get_required_keys_content(M::ask_required_keys(), keypairs),
))
}
#[cfg(test)]
mod tests {
use super::*;
use once_cell::sync::Lazy;
use std::sync::Mutex;
// Empty mutex used to ensure that only one test runs at a time
static MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
#[derive(Debug, Default, Deserialize, PartialEq)]
struct TestModuleUserConf {
field1: Option<String>,
field2: Option<usize>,
}
#[inline]
fn prefix() -> String {
format!("{}MODULE_TEST_", constants::DURS_ENV_PREFIX)
}
fn clear_env_vars() {
if std::env::var(&format!("{}FIELD1", prefix())).is_ok() {
std::env::remove_var(&format!("{}FIELD1", prefix()));
}
if std::env::var(&format!("{}FIELD2", prefix())).is_ok() {
std::env::remove_var(&format!("{}FIELD2", prefix()));
}
}
#[test]
fn test_env_module_conf_without_env_vars() -> Result<(), ModuleConfError> {
let _lock = MUTEX.lock().expect("MUTEX poisoned");
clear_env_vars();
assert_eq!(
TestModuleUserConf::default(),
ModulesConf::get_env_module_user_conf(ModuleStaticName("module_test"))?,
);
Ok(())
}
#[test]
fn test_env_module_conf_with_some_valid_env_vars() -> Result<(), ModuleConfError> {
let _lock = MUTEX.lock().expect("MUTEX poisoned");
clear_env_vars();
std::env::set_var(&format!("{}FIELD1", prefix()), "toto");
std::env::set_var(&format!("{}FIELD2", prefix()), "4");
assert_eq!(
TestModuleUserConf {
field1: Some("toto".to_owned()),
field2: Some(4),
},
ModulesConf::get_env_module_user_conf(ModuleStaticName("module_test"))?,
);
Ok(())
}
#[test]
fn test_env_module_conf_with_invalid_env_var() -> Result<(), ModuleConfError> {
let _lock = MUTEX.lock().expect("MUTEX poisoned");
clear_env_vars();
// field2 must be a number
std::env::set_var(&format!("{}FIELD2", prefix()), "toto");
if let Err(ModuleConfError::EnvyErr(_)) = ModulesConf::get_env_module_user_conf::<
TestModuleUserConf,
>(ModuleStaticName("module_test"))
{
Ok(())
} else {
panic!("get_env_module_user_conf() must return an error ModuleConfError::EnvyErr.");
}
}
}
...@@ -44,7 +44,6 @@ use crate::errors::DursCoreError; ...@@ -44,7 +44,6 @@ use crate::errors::DursCoreError;
use dubp_currency_params::CurrencyName; use dubp_currency_params::CurrencyName;
use durs_bc::{dbex::DbExQuery, BlockchainModule}; use durs_bc::{dbex::DbExQuery, BlockchainModule};
use durs_common_tools::fatal_error; use durs_common_tools::fatal_error;
use durs_common_tools::traits::merge::Merge;
pub use durs_conf::{ pub use durs_conf::{
constants::KEYPAIRS_FILENAME, keypairs::cli::*, ChangeGlobalConf, DuRsConf, DuniterKeyPairs, constants::KEYPAIRS_FILENAME, keypairs::cli::*, ChangeGlobalConf, DuRsConf, DuniterKeyPairs,
}; };
...@@ -124,7 +123,8 @@ impl DursCore<DuRsConf> { ...@@ -124,7 +123,8 @@ impl DursCore<DuRsConf> {
.get(&M::name().to_string().as_str()) .get(&M::name().to_string().as_str())
.cloned(); .cloned();
let ((module_conf, module_user_conf), required_keys) = get_module_conf_and_keys::<M>( let ((module_conf, module_user_conf), required_keys) =
durs_conf::modules_conf::get_module_conf_and_keys::<M>(
durs_core.currency_name.as_ref(), durs_core.currency_name.as_ref(),
&durs_core.soft_meta_datas.conf.get_global_conf(), &durs_core.soft_meta_datas.conf.get_global_conf(),
module_conf_json, module_conf_json,
...@@ -411,7 +411,8 @@ impl DursCore<DuRsConf> { ...@@ -411,7 +411,8 @@ impl DursCore<DuRsConf> {
.cloned(); .cloned();
// Load module conf and keys // Load module conf and keys
let ((module_conf, _), required_keys) = get_module_conf_and_keys::<NM>( let ((module_conf, _), required_keys) =
durs_conf::modules_conf::get_module_conf_and_keys::<NM>(
self.currency_name.as_ref(), self.currency_name.as_ref(),
&soft_meta_datas.conf.get_global_conf(), &soft_meta_datas.conf.get_global_conf(),
module_conf_json, module_conf_json,
...@@ -495,7 +496,8 @@ impl DursCore<DuRsConf> { ...@@ -495,7 +496,8 @@ impl DursCore<DuRsConf> {
.get(&M::name().to_string().as_str()) .get(&M::name().to_string().as_str())
.cloned(); .cloned();
// Load module conf and keys // Load module conf and keys
let ((module_conf, _), required_keys) = get_module_conf_and_keys::<M>( let ((module_conf, _), required_keys) =
durs_conf::modules_conf::get_module_conf_and_keys::<M>(
self.currency_name.as_ref(), self.currency_name.as_ref(),
&soft_meta_datas.conf.get_global_conf(), &soft_meta_datas.conf.get_global_conf(),
module_conf_json, module_conf_json,
...@@ -553,66 +555,6 @@ impl DursCore<DuRsConf> { ...@@ -553,66 +555,6 @@ impl DursCore<DuRsConf> {
} }
} }
/// Module configurations and required keys
pub type ModuleConfsAndKeys<M> = (
(
<M as DursModule<DuRsConf, DursMsg>>::ModuleConf,
Option<<M as DursModule<DuRsConf, DursMsg>>::ModuleUserConf>,
),
RequiredKeysContent,
);
/// Get module conf and keys
pub fn get_module_conf_and_keys<M: DursModule<DuRsConf, DursMsg>>(
currency_name: Option<&CurrencyName>,
global_conf: &<DuRsConf as DursConfTrait>::GlobalConf,
module_conf_json: Option<serde_json::Value>,
keypairs: DuniterKeyPairs,
) -> Result<ModuleConfsAndKeys<M>, ModuleConfError> {
Ok((
get_module_conf::<M>(currency_name, global_conf, module_conf_json)?,
DuniterKeyPairs::get_required_keys_content(M::ask_required_keys(), keypairs),
))
}
fn get_env_module_user_conf<ModuleUserConf: serde::de::DeserializeOwned>(
module_name: ModuleStaticName,
) -> Result<ModuleUserConf, ModuleConfError> {
let prefix = format!(
"{}{}",
durs_conf::constants::DURS_ENV_PREFIX,
module_name.0.to_ascii_uppercase()
);
envy::prefixed(prefix)
.from_env::<ModuleUserConf>()
.map_err(ModuleConfError::EnvyErr)
}
/// get module conf
pub fn get_module_conf<M: DursModule<DuRsConf, DursMsg>>(
currency_name: Option<&CurrencyName>,
global_conf: &<DuRsConf as DursConfTrait>::GlobalConf,
module_conf_json: Option<serde_json::Value>,
) -> Result<(M::ModuleConf, Option<M::ModuleUserConf>), ModuleConfError> {
let file_module_user_conf: M::ModuleUserConf = if let Some(module_conf_json) = module_conf_json
{
let file_module_user_conf_opt: Option<M::ModuleUserConf> =
serde_json::from_str(module_conf_json.to_string().as_str())?;
file_module_user_conf_opt.unwrap_or_default()
} else {
M::ModuleUserConf::default()
};
let env_module_user_conf = get_env_module_user_conf::<M::ModuleUserConf>(M::name())?;
M::generate_module_conf(
currency_name,
global_conf,
Some(file_module_user_conf.merge(env_module_user_conf)),
)
}
/// Launch databases explorer /// Launch databases explorer
pub fn dbex(profile_path: PathBuf, csv: bool, query: &DbExQuery) { pub fn dbex(profile_path: PathBuf, csv: bool, query: &DbExQuery) {
// Launch databases explorer // Launch databases explorer
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment