From 1301c9b24cbdadb7f53d4fff1226b591a324651e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cherish=20=E8=94=A1=E6=A2=A6=E7=BC=98?= <785427346@qq.com> Date: Fri, 29 Sep 2023 18:06:12 +0800 Subject: [PATCH] enhance: env_first when get props from ClientProps. (#199) * enhance: env_first when get props from ClientProps. * chore: get_server_list from get_server_addr(). --- src/api/props.rs | 180 +++++++++++++++++++++++++------------------ src/config/mod.rs | 5 +- src/config/worker.rs | 28 +++---- src/lib.rs | 29 ++++++- src/naming/mod.rs | 16 ++-- 5 files changed, 156 insertions(+), 102 deletions(-) diff --git a/src/api/props.rs b/src/api/props.rs index 9989e7c..b4fc7dd 100644 --- a/src/api/props.rs +++ b/src/api/props.rs @@ -1,36 +1,105 @@ use std::collections::HashMap; -use crate::api::constants::DEFAULT_SERVER_ADDR; -use crate::properties::{get_value, get_value_bool, get_value_u32}; +use crate::api::constants::*; +use crate::properties::{get_value, get_value_bool, get_value_option, get_value_u32}; /// Configures settings for Client. #[derive(Debug, Clone)] pub struct ClientProps { /// server_addr e.g: 127.0.0.1:8848; 192.168.0.1 - pub(crate) server_addr: String, + server_addr: String, /// grpc port - pub(crate) grpc_port: Option, - pub(crate) namespace: String, + grpc_port: Option, + /// public is "", Should define a more meaningful namespace + namespace: String, /// app_name - pub(crate) app_name: String, + app_name: String, /// naming push_empty_protection, default true - pub(crate) naming_push_empty_protection: bool, + naming_push_empty_protection: bool, + /// env_first when get props, default true + env_first: bool, /// metadata - pub(crate) labels: HashMap, + labels: HashMap, /// client_version - pub(crate) client_version: String, + client_version: String, /// auth context - pub(crate) auth_context: HashMap, + auth_context: HashMap, } impl ClientProps { + pub(crate) fn get_server_addr(&self) -> String { + if self.env_first { + get_value( + ENV_NACOS_CLIENT_COMMON_SERVER_ADDRESS, + self.server_addr.clone(), + ) + } else { + self.server_addr.clone() + } + } + + pub(crate) fn get_remote_grpc_port(&self) -> Option { + self.grpc_port + } + + pub(crate) fn get_namespace(&self) -> String { + if self.env_first { + get_value(ENV_NACOS_CLIENT_COMMON_NAMESPACE, self.namespace.clone()) + } else { + self.namespace.clone() + } + } + + pub(crate) fn get_app_name(&self) -> String { + if self.env_first { + get_value(ENV_NACOS_CLIENT_COMMON_APP_NAME, self.app_name.clone()) + } else { + self.app_name.clone() + } + } + + pub(crate) fn get_naming_push_empty_protection(&self) -> bool { + if self.env_first { + get_value_bool( + ENV_NACOS_CLIENT_NAMING_PUSH_EMPTY_PROTECTION, + self.naming_push_empty_protection, + ) + } else { + self.naming_push_empty_protection + } + } + + pub(crate) fn get_labels(&self) -> HashMap { + let mut labels = self.labels.clone(); + labels.insert(KEY_LABEL_APP_NAME.to_string(), self.get_app_name()); + labels + } + + pub(crate) fn get_client_version(&self) -> String { + self.client_version.clone() + } + + pub(crate) fn get_auth_context(&self) -> HashMap { + let mut auth_context = self.auth_context.clone(); + if self.env_first { + if let Some(u) = get_value_option(ENV_NACOS_CLIENT_AUTH_USERNAME) { + auth_context.insert(crate::api::plugin::USERNAME.into(), u); + } + if let Some(p) = get_value_option(ENV_NACOS_CLIENT_AUTH_PASSWORD) { + auth_context.insert(crate::api::plugin::PASSWORD.into(), p); + } + } + auth_context + } + pub(crate) fn get_server_list(&self) -> crate::api::error::Result> { - if self.server_addr.trim().is_empty() { + let server_addr = self.get_server_addr(); + if server_addr.trim().is_empty() { return Err(crate::api::error::Error::WrongServerAddress(String::from( "Server address is empty", ))); } - let hosts: Vec<&str> = self.server_addr.trim().split(',').collect::>(); + let hosts: Vec<&str> = server_addr.trim().split(',').collect::>(); let mut result = vec![]; for host in hosts { let host_port = host.split(':').collect::>(); @@ -38,10 +107,7 @@ impl ClientProps { result.push(format!( "{}:{}", host, - get_value_u32( - crate::api::constants::ENV_NACOS_CLIENT_COMMON_SERVER_PORT, - crate::api::constants::DEFAULT_SERVER_PORT, - ) + get_value_u32(ENV_NACOS_CLIENT_COMMON_SERVER_PORT, DEFAULT_SERVER_PORT,) )); continue; } @@ -59,35 +125,13 @@ impl ClientProps { let env_project_version = env!("CARGO_PKG_VERSION"); let client_version = format!("Nacos-Rust-Client:{}", env_project_version); - let server_addr = get_value( - crate::api::constants::ENV_NACOS_CLIENT_COMMON_SERVER_ADDRESS, - DEFAULT_SERVER_ADDR, - ); - - // public is "", Should define a more meaningful namespace - let namespace = get_value(crate::api::constants::ENV_NACOS_CLIENT_COMMON_NAMESPACE, ""); - - let app_name = get_value( - crate::api::constants::ENV_NACOS_CLIENT_COMMON_APP_NAME, - crate::api::constants::UNKNOWN, - ); - let mut labels = HashMap::default(); - labels.insert( - crate::api::constants::KEY_LABEL_APP_NAME.to_string(), - app_name.clone(), - ); - - let naming_push_empty_protection = get_value_bool( - crate::api::constants::ENV_NACOS_CLIENT_NAMING_PUSH_EMPTY_PROTECTION, - true, - ); - ClientProps { - server_addr, - namespace, - app_name, - naming_push_empty_protection, - labels, + server_addr: String::from(DEFAULT_SERVER_ADDR), + namespace: String::from(""), + app_name: UNKNOWN.to_string(), + naming_push_empty_protection: true, + env_first: true, + labels: HashMap::default(), client_version, auth_context: HashMap::default(), grpc_port: None, @@ -96,10 +140,7 @@ impl ClientProps { /// Sets the server addr. pub fn server_addr(mut self, server_addr: impl Into) -> Self { - self.server_addr = get_value( - crate::api::constants::ENV_NACOS_CLIENT_COMMON_SERVER_ADDRESS, - server_addr.into(), - ); + self.server_addr = server_addr.into(); self } @@ -111,31 +152,25 @@ impl ClientProps { /// Sets the namespace. pub fn namespace(mut self, namespace: impl Into) -> Self { - self.namespace = get_value( - crate::api::constants::ENV_NACOS_CLIENT_COMMON_NAMESPACE, - namespace.into(), - ); + self.namespace = namespace.into(); self } /// Sets the app_name. pub fn app_name(mut self, app_name: impl Into) -> Self { - 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); + self.app_name = app_name.into(); self } /// Sets the naming_push_empty_protection. pub fn naming_push_empty_protection(mut self, naming_push_empty_protection: bool) -> Self { - self.naming_push_empty_protection = get_value_bool( - crate::api::constants::ENV_NACOS_CLIENT_NAMING_PUSH_EMPTY_PROTECTION, - naming_push_empty_protection, - ); + self.naming_push_empty_protection = naming_push_empty_protection; + self + } + + /// Sets the env_first. + pub fn env_first(mut self, env_first: bool) -> Self { + self.env_first = env_first; self } @@ -148,26 +183,16 @@ impl ClientProps { /// Add auth username. #[cfg(feature = "auth-by-http")] pub fn auth_username(mut self, username: impl Into) -> Self { - self.auth_context.insert( - crate::api::plugin::USERNAME.into(), - get_value( - crate::api::constants::ENV_NACOS_CLIENT_AUTH_USERNAME, - username.into(), - ), - ); + self.auth_context + .insert(crate::api::plugin::USERNAME.into(), username.into()); self } /// Add auth password. #[cfg(feature = "auth-by-http")] pub fn auth_password(mut self, password: impl Into) -> Self { - self.auth_context.insert( - crate::api::plugin::PASSWORD.into(), - get_value( - crate::api::constants::ENV_NACOS_CLIENT_AUTH_PASSWORD, - password.into(), - ), - ); + self.auth_context + .insert(crate::api::plugin::PASSWORD.into(), password.into()); self } @@ -192,6 +217,7 @@ mod tests { namespace: "test_namespace".to_string(), app_name: "test_app".to_string(), naming_push_empty_protection: true, + env_first: true, labels: HashMap::new(), client_version: "test_version".to_string(), auth_context: HashMap::new(), diff --git a/src/config/mod.rs b/src/config/mod.rs index 7f426e6..d7ff80f 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -37,7 +37,10 @@ impl NacosConfigService { auth_plugin: std::sync::Arc, config_filters: Vec>, ) -> crate::api::error::Result { - let client_id = generate_client_id(&client_props.server_addr, &client_props.namespace); + let client_id = generate_client_id( + &client_props.get_server_addr(), + &client_props.get_namespace(), + ); let client_worker = ConfigWorker::new(client_props, auth_plugin, config_filters, client_id.clone())?; Ok(Self { diff --git a/src/config/worker.rs b/src/config/worker.rs index 787df6f..b86b144 100644 --- a/src/config/worker.rs +++ b/src/config/worker.rs @@ -40,15 +40,15 @@ impl ConfigWorker { let auth_layer = Arc::new(AuthLayer::new( auth_plugin.clone(), client_props.get_server_list()?.to_vec(), - client_props.auth_context.clone(), + client_props.get_auth_context(), client_id.clone(), )); let remote_client = NacosGrpcClientBuilder::new(client_props.get_server_list()?) - .port(client_props.grpc_port) - .namespace(client_props.namespace.clone()) - .app_name(client_props.app_name.clone()) - .client_version(client_props.client_version.clone()) + .port(client_props.get_remote_grpc_port()) + .namespace(client_props.get_namespace()) + .app_name(client_props.get_app_name()) + .client_version(client_props.get_client_version()) .support_remote_connection(true) .support_config_remote_metrics(true) .support_naming_delta_push(false) @@ -61,7 +61,7 @@ impl ConfigWorker { crate::api::constants::common_remote::LABEL_MODULE.to_owned(), crate::api::constants::common_remote::LABEL_MODULE_CONFIG.to_owned(), ) - .add_labels(client_props.labels.clone()) + .add_labels(client_props.get_labels()) .register_server_request_handler::(Arc::new( ConfigChangeNotifyHandler { notify_change_tx }, )) @@ -99,7 +99,7 @@ impl ConfigWorker { data_id: String, group: String, ) -> crate::api::error::Result { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let config_resp = Self::get_config_inner_async( self.remote_client.clone(), data_id.clone(), @@ -138,7 +138,7 @@ impl ConfigWorker { content: String, content_type: Option, ) -> crate::api::error::Result { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let mut conf_req = ConfigReq::new(data_id, group, namespace, content, "".to_string()); for config_filter in self.config_filters.iter() { @@ -169,7 +169,7 @@ impl ConfigWorker { content_type: Option, cas_md5: String, ) -> crate::api::error::Result { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let mut conf_req = ConfigReq::new(data_id, group, namespace, content, "".to_string()); for config_filter in self.config_filters.iter() { @@ -200,7 +200,7 @@ impl ConfigWorker { content_type: Option, beta_ips: String, ) -> crate::api::error::Result { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let mut conf_req = ConfigReq::new(data_id, group, namespace, content, "".to_string()); for config_filter in self.config_filters.iter() { @@ -232,7 +232,7 @@ impl ConfigWorker { cas_md5: Option, params: HashMap, ) -> crate::api::error::Result { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let mut conf_req = ConfigReq::new(data_id, group, namespace, content, "".to_string()); for config_filter in self.config_filters.iter() { @@ -260,7 +260,7 @@ impl ConfigWorker { data_id: String, group: String, ) -> crate::api::error::Result { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); Self::remove_config_inner_async(self.remote_client.clone(), data_id, group, namespace).await } @@ -272,7 +272,7 @@ impl ConfigWorker { group: String, listener: Arc, ) { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let group_key = util::group_key(&data_id, &group, &namespace); let mut mutex = self.cache_data_map.lock().await; @@ -332,7 +332,7 @@ impl ConfigWorker { group: String, listener: Arc, ) { - let namespace = self.client_props.namespace.clone(); + let namespace = self.client_props.get_namespace(); let group_key = util::group_key(&data_id, &group, &namespace); let mut mutex = self.cache_data_map.lock().await; diff --git a/src/lib.rs b/src/lib.rs index 5f0e4a7..d61c6e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,11 +66,11 @@ use lazy_static::lazy_static; use std::collections::HashMap; use std::path::Path; -const ENV_CONFIG_FILE_PATH: &str = "CONFIG_FILE_PATH"; +const ENV_NACOS_CLIENT_PROPS_FILE_PATH: &str = "NACOS_CLIENT_PROPS_FILE_PATH"; lazy_static! { static ref PROPERTIES: HashMap = { - let env_file_path = std::env::var(ENV_CONFIG_FILE_PATH).ok(); + let env_file_path = std::env::var(ENV_NACOS_CLIENT_PROPS_FILE_PATH).ok(); let _ = env_file_path.as_ref().map(|file_path| { dotenvy::from_path(Path::new(file_path)).map_err(|e| { let _ = dotenvy::dotenv(); @@ -86,6 +86,13 @@ lazy_static! { pub(crate) mod properties { use crate::PROPERTIES; + pub(crate) fn get_value_option(key: Key) -> Option + where + Key: AsRef, + { + PROPERTIES.get(key.as_ref()).cloned() + } + pub(crate) fn get_value(key: Key, default: Default) -> String where Key: AsRef, @@ -172,6 +179,24 @@ mod tests { } } +#[cfg(test)] +mod test_props { + use crate::api::constants::ENV_NACOS_CLIENT_NAMING_PUSH_EMPTY_PROTECTION; + use crate::properties::{get_value, get_value_bool}; + + #[test] + fn test_get_value() { + let v = get_value("ENV_TEST", "TEST"); + assert_eq!(v, "TEST"); + } + + #[test] + fn test_get_value_bool() { + let v = get_value_bool(ENV_NACOS_CLIENT_NAMING_PUSH_EMPTY_PROTECTION, true); + assert_eq!(v, true); + } +} + #[cfg(test)] mod test_config { use std::sync::Once; diff --git a/src/naming/mod.rs b/src/naming/mod.rs index 6f03673..e448882 100644 --- a/src/naming/mod.rs +++ b/src/naming/mod.rs @@ -60,13 +60,13 @@ impl NacosNamingService { pub(crate) fn new(client_props: ClientProps, auth_plugin: Arc) -> Result { let server_list = Arc::new(client_props.get_server_list()?); - let mut namespace = client_props.namespace; + let mut namespace = client_props.get_namespace(); if namespace.is_empty() { namespace = crate::api::constants::DEFAULT_NAMESPACE.to_owned(); } // create client id - let client_id = generate_client_id(&client_props.server_addr, &namespace); + let client_id = generate_client_id(&client_props.get_server_addr(), &namespace); // create redo task executor let redo_task_executor = Arc::new(RedoTaskExecutor::new(client_id.clone())); @@ -83,7 +83,7 @@ impl NacosNamingService { let (observer, emitter) = observable::service_info_observable::create( client_id.clone(), naming_cache.clone(), - client_props.naming_push_empty_protection, + client_props.get_naming_push_empty_protection(), ); let server_request_handler = NamingPushRequestHandler::new(emitter.clone()); @@ -91,19 +91,19 @@ impl NacosNamingService { let auth_layer = Arc::new(AuthLayer::new( auth_plugin, server_list.to_vec(), - client_props.auth_context, + client_props.get_auth_context(), client_id.clone(), )); let nacos_grpc_client = NacosGrpcClientBuilder::new(server_list.to_vec()) - .port(client_props.grpc_port) + .port(client_props.get_remote_grpc_port()) .namespace(namespace.clone()) - .client_version(client_props.client_version) + .client_version(client_props.get_client_version()) .support_remote_connection(true) .support_config_remote_metrics(true) .support_naming_delta_push(false) .support_naming_remote_metric(false) - .add_labels(client_props.labels) + .add_labels(client_props.get_labels()) .add_label( crate::api::constants::common_remote::LABEL_SOURCE.to_owned(), crate::api::constants::common_remote::LABEL_SOURCE_SDK.to_owned(), @@ -112,7 +112,7 @@ impl NacosNamingService { crate::api::constants::common_remote::LABEL_MODULE.to_owned(), crate::api::constants::common_remote::LABEL_MODULE_NAMING.to_owned(), ) - .app_name(client_props.app_name) + .app_name(client_props.get_app_name()) .register_server_request_handler::(Arc::new( server_request_handler, ))