Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #47]Read configuration from environment variables #196

Merged
merged 2 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ want = "0.3.0"
dashmap = "5.4.0"
home = "0.5.4"

dotenvy = "0.15"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dotenvy 建议仅用作测试用例,放于 dev-dependencies 下。


[dev-dependencies]
tracing-subscriber = { version = "0.3", features = ["default"] }
Expand Down
12 changes: 12 additions & 0 deletions src/api/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,15 @@ pub(crate) mod common_remote {

/// env `NACOS_CLIENT_COMMON_THREAD_CORES` to set num when multi-cpus, default is num_cpus
pub const ENV_NACOS_CLIENT_COMMON_THREAD_CORES: &str = "NACOS_CLIENT_COMMON_THREAD_CORES";

pub const ENV_NACOS_CLIENT_COMMON_SERVER_ADDRESS: &str = "nacos.client.server.address";

pub const ENV_NACOS_CLIENT_COMMON_SERVER_PORT: &str = "nacos.client.server.port";

pub const ENV_NACOS_CLIENT_COMMON_NAMESPACE: &str = "nacos.client.namespace";

pub const ENV_NACOS_CLIENT_COMMON_APP_NAME: &str = "nacos.client.app.name";

pub const ENV_NACOS_CLIENT_AUTH_USER_NAME: &str = "nacos.client.username";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用大写下横线分割的如何? '.' 对于 shell 脚本也不友好。另外USERNAME 应该是可以连起来的英文字符 🫡

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

用大写下横线分割的如何? '.' 对于 shell 脚本也不友好。另外USERNAME 应该是可以连起来的英文字符 🫡

@CherishCai
可以,值我都改成大写用下划线连接,其他的设计是否有啥问题?
设计思路:

  1. 环境变量的设置有两种方式:直接设置和放入文件中
  2. 通过指定环境变量文件位置和默认位置进行加载
  3. 加载后转换成HashMap给后续进行使用
  4. 设置变量的时候首先从环境变量中获取,环境变量不存在,在从静态变量HashMap中获取进行设置填充

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mxsm 会不会太多方式造成理解成本大呢?不如先支持环境变量获取,后续真有需求再添加配置文件方式


pub const ENV_NACOS_CLIENT_AUTH_PASSWORD: &str = "nacos.client.password";
46 changes: 36 additions & 10 deletions src/api/props.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use std::collections::HashMap;

use crate::api::constants::DEFAULT_SERVER_ADDR;
use crate::properties::{get_value, get_value_u32};

/// Configures settings for Client.
#[derive(Debug, Clone)]
pub struct ClientProps {
Expand Down Expand Up @@ -33,7 +36,10 @@ impl ClientProps {
result.push(format!(
"{}:{}",
host,
crate::api::constants::DEFAULT_SERVER_PORT
get_value_u32(
crate::api::constants::ENV_NACOS_CLIENT_COMMON_SERVER_PORT,
crate::api::constants::DEFAULT_SERVER_PORT,
)
));
continue;
}
Expand All @@ -52,9 +58,12 @@ impl ClientProps {
let client_version = format!("Nacos-Rust-Client:{}", env_project_version);

ClientProps {
server_addr: String::from(crate::api::constants::DEFAULT_SERVER_ADDR),
server_addr: get_value(
crate::api::constants::ENV_NACOS_CLIENT_COMMON_SERVER_ADDRESS,
DEFAULT_SERVER_ADDR,
),
/// public is "", Should define a more meaningful namespace
namespace: String::from(""),
namespace: get_value(crate::api::constants::ENV_NACOS_CLIENT_COMMON_NAMESPACE, ""),
app_name: crate::api::constants::UNKNOWN.to_string(),
labels: HashMap::default(),
client_version,
Expand All @@ -65,7 +74,10 @@ impl ClientProps {

/// Sets the server addr.
pub fn server_addr(mut self, server_addr: impl Into<String>) -> Self {
self.server_addr = server_addr.into();
self.server_addr = get_value(
crate::api::constants::ENV_NACOS_CLIENT_COMMON_SERVER_ADDRESS,
server_addr.into(),
);
self
}

Expand All @@ -83,7 +95,10 @@ impl ClientProps {

/// Sets the app_name.
pub fn app_name(mut self, app_name: impl Into<String>) -> Self {
let name = app_name.into();
let name = get_value(
crate::api::constants::ENV_NACOS_CLIENT_COMMON_APP_NAME,
app_name.into(),
);
self.app_name = name.clone();
self.labels
.insert(crate::api::constants::KEY_LABEL_APP_NAME.to_string(), name);
Expand All @@ -99,16 +114,26 @@ impl ClientProps {
/// Add auth username.
#[cfg(feature = "auth-by-http")]
pub fn auth_username(mut self, username: impl Into<String>) -> Self {
self.auth_context
.insert(crate::api::plugin::USERNAME.into(), username.into());
self.auth_context.insert(
crate::api::plugin::USERNAME.into(),
get_value(
crate::api::constants::ENV_NACOS_CLIENT_AUTH_USER_NAME,
username.into(),
),
);
self
}

/// Add auth password.
#[cfg(feature = "auth-by-http")]
pub fn auth_password(mut self, password: impl Into<String>) -> Self {
self.auth_context
.insert(crate::api::plugin::PASSWORD.into(), password.into());
self.auth_context.insert(
crate::api::plugin::PASSWORD.into(),
get_value(
crate::api::constants::ENV_NACOS_CLIENT_AUTH_USER_NAME,
password.into(),
),
);
self
}

Expand All @@ -121,9 +146,10 @@ impl ClientProps {

#[cfg(test)]
mod tests {
use super::*;
use crate::api::error::Error;

use super::*;

#[test]
fn test_get_server_list() {
let client_props = ClientProps {
Expand Down
52 changes: 52 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,57 @@
//! ```
//!

use lazy_static::lazy_static;
use std::collections::HashMap;
use std::path::Path;

const ENV_CONFIG_FILE_PATH: &str = "CONFIG_FILE_PATH";

lazy_static! {
static ref PROPERTIES: HashMap<String, String> = {
let env_file_path = std::env::var(ENV_CONFIG_FILE_PATH).ok();
let _ = env_file_path.as_ref().map(|file_path| {
dotenvy::from_path(Path::new(file_path)).or_else(|e| {
let _ = dotenvy::dotenv();
Err(e)
})
});
dotenvy::dotenv().ok();

let prop = dotenvy::vars()
.into_iter()
.collect::<HashMap<String, String>>();

prop
};
}

pub(crate) mod properties {
use crate::PROPERTIES;

pub(crate) fn get_value<Key, Default>(key: Key, default: Default) -> String
where
Key: AsRef<str>,
Default: AsRef<str>,
{
PROPERTIES
.get(key.as_ref())
.map_or(default.as_ref().to_string(), |value| value.to_string())
}

pub(crate) fn get_value_u32<Key>(key: Key, default: u32) -> u32
where
Key: AsRef<str>,
{
PROPERTIES.get(key.as_ref()).map_or(default, |value| {
value
.to_string()
.parse::<u32>()
.map_or_else(|_e| default, |v| v)
})
}
}

/// Nacos API
pub mod api;

Expand Down Expand Up @@ -120,6 +171,7 @@ mod test_config {
use tracing::metadata::LevelFilter;

static LOGGER_INIT: Once = Once::new();

pub(crate) fn setup_log() {
LOGGER_INIT.call_once(|| {
tracing_subscriber::fmt()
Expand Down
Loading