From db17e43e676c043861db7683bd89d7f5967e73bb Mon Sep 17 00:00:00 2001 From: jmjoy Date: Fri, 21 Jun 2024 17:49:37 +0800 Subject: [PATCH 1/7] Fix handle_url --- src/meta.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meta.rs b/src/meta.rs index 548fdcd..8e90b92 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -173,7 +173,7 @@ pub(crate) fn handle_url(request: &impl PerformRequest, base_url: Url) -> Apollo url.path_segments_mut() .map_err(|_| crate::errors::ApolloClientError::UrlCannotBeABase)? - .extend(path.split('/')); + .push(path.trim_start_matches('/')); if !query.is_empty() { url.query_pairs_mut().extend_pairs(query); } From 1ee7a063ef45e9449b03ce41201636e56d6aa28e Mon Sep 17 00:00:00 2001 From: jmjoy Date: Fri, 21 Jun 2024 17:52:33 +0800 Subject: [PATCH 2/7] Revert path() --- src/conf/requests.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/conf/requests.rs b/src/conf/requests.rs index 0c61627..5ffc59c 100644 --- a/src/conf/requests.rs +++ b/src/conf/requests.rs @@ -47,7 +47,7 @@ impl PerformRequest for CachedFetchRequest { fn path(&self) -> String { format!( - "configfiles/{app_id}/{cluster_name}/{namespace_name}", + "/configfiles/{app_id}/{cluster_name}/{namespace_name}", app_id = self.app_id, cluster_name = self.cluster_name, namespace_name = self.namespace_name @@ -134,7 +134,7 @@ impl PerformRequest for FetchRequest { fn path(&self) -> String { format!( - "configs/{app_id}/{cluster_name}/{namespace_name}", + "/configs/{app_id}/{cluster_name}/{namespace_name}", app_id = self.app_id, cluster_name = self.cluster_name, namespace_name = self.namespace_name @@ -217,7 +217,7 @@ impl PerformRequest for NotifyRequest { type Response = Vec; fn path(&self) -> String { - "notifications/v2".to_string() + "/notifications/v2".to_string() } fn queries(&self) -> ApolloClientResult, Cow<'_, str>)>> { From 8424a28af70b717c6c8e667da6ded6c4c5c64c45 Mon Sep 17 00:00:00 2001 From: jmjoy Date: Sat, 22 Jun 2024 17:47:57 +0800 Subject: [PATCH 3/7] Fix CI --- src/meta.rs | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/meta.rs b/src/meta.rs index 8e90b92..d3f2d6e 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -1,11 +1,8 @@ //! Common api metadata. use crate::errors::{ApolloClientResult, ApolloResponseError}; -use async_trait::async_trait; -use http::Method; -use reqwest::{RequestBuilder, Response}; -use std::{borrow::Cow, fmt, fmt::Display, time::Duration}; -use url::Url; +use reqwest::Response; +use std::{fmt, fmt::Display, time::Duration}; #[allow(dead_code)] pub(crate) const DEFAULT_CLUSTER_NAME: &str = "default"; @@ -57,6 +54,7 @@ impl Display for NamespaceKind { } /// Common api request trait. +#[cfg(feature = "conf")] pub(crate) trait PerformRequest { /// The returned response after request is success. type Response: PerformResponse; @@ -66,17 +64,22 @@ pub(crate) trait PerformRequest { /// Request method. fn method(&self) -> http::Method { - Method::GET + http::Method::GET } /// Url queries. - fn queries(&self) -> ApolloClientResult, Cow<'_, str>)>> { + fn queries( + &self, + ) -> ApolloClientResult, std::borrow::Cow<'_, str>)>> { Ok(vec![]) } /// Handle extras operator, such as set request body. #[allow(unused_mut)] - fn request_builder(&self, mut request_builder: RequestBuilder) -> RequestBuilder { + fn request_builder( + &self, + mut request_builder: reqwest::RequestBuilder, + ) -> reqwest::RequestBuilder { //FIXME //see issue #15701 #[cfg(all(feature = "auth", feature = "conf"))] @@ -87,6 +90,7 @@ pub(crate) trait PerformRequest { } /// AppId + #[allow(dead_code)] fn app_id(&self) -> Option<&str> { None } @@ -103,7 +107,7 @@ pub(crate) trait PerformRequest { /// /// https://www.apolloconfig.com/#/zh/usage/other-language-client-user-guide?id=_15-%e9%85%8d%e7%bd%ae%e8%ae%bf%e9%97%ae%e5%af%86%e9%92%a5 #[cfg(all(feature = "auth", feature = "conf"))] - fn signature(&self, mut request_builder: RequestBuilder) -> RequestBuilder { + fn signature(&self, mut request_builder: reqwest::RequestBuilder) -> reqwest::RequestBuilder { use hmac::{Mac, SimpleHmac}; use sha1::Sha1; type HmacWithSha1 = SimpleHmac; @@ -139,13 +143,15 @@ pub(crate) trait PerformRequest { } /// Common api response trait. -#[async_trait] +#[cfg(feature = "conf")] +#[async_trait::async_trait] pub(crate) trait PerformResponse: Sized { /// Create Self from response. async fn from_response(response: Response) -> ApolloClientResult; } -#[async_trait] +#[cfg(feature = "conf")] +#[async_trait::async_trait] impl PerformResponse for () { async fn from_response(_response: Response) -> ApolloClientResult { Ok(()) @@ -153,7 +159,7 @@ impl PerformResponse for () { } #[cfg(feature = "conf")] -#[async_trait] +#[async_trait::async_trait] impl PerformResponse for ini::Properties { async fn from_response(response: Response) -> ApolloClientResult { let content = response.text().await?; @@ -165,8 +171,11 @@ impl PerformResponse for ini::Properties { } /// Create request url from base url, mainly path and queries. -#[allow(dead_code)] -pub(crate) fn handle_url(request: &impl PerformRequest, base_url: Url) -> ApolloClientResult { +#[cfg(feature = "conf")] +pub(crate) fn handle_url( + request: &impl PerformRequest, + base_url: url::Url, +) -> ApolloClientResult { let mut url = base_url; let path = &request.path(); let query = &request.queries()?; From 150fbd854e6fe01803a5161234dd3e7484258901 Mon Sep 17 00:00:00 2001 From: jmjoy Date: Sat, 22 Jun 2024 18:23:51 +0800 Subject: [PATCH 4/7] Fix CI and handle_url --- src/conf/meta.rs | 2 +- src/conf/mod.rs | 6 +++--- src/conf/requests.rs | 6 +++--- src/meta.rs | 2 +- src/open/requests.rs | 10 ++-------- src/utils.rs | 3 +-- 6 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/conf/meta.rs b/src/conf/meta.rs index 511a232..0f49f7d 100644 --- a/src/conf/meta.rs +++ b/src/conf/meta.rs @@ -132,7 +132,7 @@ impl Display for IpValue { #[cfg(feature = "host-ip")] IpValue::HostIp => { Self::get_all_addrs() - .get(0) + .first() .map(|s| Cow::Owned(s.to_string())) .unwrap_or(Cow::Borrowed("127.0.0.1")) } diff --git a/src/conf/mod.rs b/src/conf/mod.rs index 0277743..34bab72 100644 --- a/src/conf/mod.rs +++ b/src/conf/mod.rs @@ -263,10 +263,10 @@ impl ApolloConfClient { /// Ok(()) /// } /// ``` - pub fn watch<'a>( - &'a self, + pub fn watch( + &self, request: WatchRequest, - ) -> impl Stream>>> + 'a + ) -> impl Stream>>> + '_ { let mut watch_notifications = request.create_notifications(); let mut fetch_notifications = watch_notifications.clone(); diff --git a/src/conf/requests.rs b/src/conf/requests.rs index 5ffc59c..9484d72 100644 --- a/src/conf/requests.rs +++ b/src/conf/requests.rs @@ -75,7 +75,7 @@ impl PerformRequest for CachedFetchRequest { #[cfg(feature = "auth")] fn access_key(&self) -> Option<&str> { - self.access_key.as_ref().map(|key| key.as_str()) + self.access_key.as_deref() } } @@ -165,7 +165,7 @@ impl PerformRequest for FetchRequest { #[cfg(feature = "auth")] fn access_key(&self) -> Option<&str> { - self.access_key.as_ref().map(|key| key.as_str()) + self.access_key.as_deref() } } @@ -249,7 +249,7 @@ impl PerformRequest for NotifyRequest { #[cfg(feature = "auth")] fn access_key(&self) -> Option<&str> { - self.access_key.as_ref().map(|key| key.as_str()) + self.access_key.as_deref() } } diff --git a/src/meta.rs b/src/meta.rs index d3f2d6e..08a3002 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -182,7 +182,7 @@ pub(crate) fn handle_url( url.path_segments_mut() .map_err(|_| crate::errors::ApolloClientError::UrlCannotBeABase)? - .push(path.trim_start_matches('/')); + .extend(path.split('/').skip_while(|s| s.is_empty())); if !query.is_empty() { url.query_pairs_mut().extend_pairs(query); } diff --git a/src/open/requests.rs b/src/open/requests.rs index 7a3aa5b..49f2d96 100644 --- a/src/open/requests.rs +++ b/src/open/requests.rs @@ -15,7 +15,7 @@ use http::Method; use reqwest::RequestBuilder; use std::borrow::Cow; -const OPEN_API_PREFIX: &'static str = "openapi/v1"; +const OPEN_API_PREFIX: &str = "openapi/v1"; /// Request executed by [crate::open::OpenApiClient::execute]; pub(crate) trait PerformOpenRequest: PerformRequest {} @@ -49,17 +49,11 @@ impl PerformRequest for OpenEnvClusterRequest { impl PerformOpenRequest for OpenEnvClusterRequest {} /// Fetch app infos. -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct OpenAppRequest { pub app_ids: Option>, } -impl Default for OpenAppRequest { - fn default() -> Self { - OpenAppRequest { app_ids: None } - } -} - impl PerformRequest for OpenAppRequest { type Response = Vec; diff --git a/src/utils.rs b/src/utils.rs index b25b906..e711066 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -28,7 +28,7 @@ pub(crate) fn get_all_addrs() -> &'static [std::net::IpAddr] { .map(|networks| { networks .values() - .map(|network| { + .flat_map(|network| { network .addrs .iter() @@ -50,7 +50,6 @@ pub(crate) fn get_all_addrs() -> &'static [std::net::IpAddr] { _ => None, }) }) - .flatten() .collect() }) .unwrap_or_default() From 0844182201e15771e2d2e14dee24cb1c60305e78 Mon Sep 17 00:00:00 2001 From: jmjoy Date: Sat, 22 Jun 2024 23:40:29 +0800 Subject: [PATCH 5/7] Update --- Cargo.toml | 48 ++++++++++++++++++++++++------------------------ src/conf/meta.rs | 2 +- src/meta.rs | 3 ++- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d7fe2bc..5ad6c46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,34 +30,34 @@ full = ["open"] auth = ["chrono","hmac","sha1","base64","urlencoding"] [dependencies] -async-stream = { version = "0.3.2", optional = true } -async-trait = "0.1.50" +async-stream = { version = "0.3.5", optional = true } +async-trait = "0.1.80" cfg-if = "1.0.0" -chrono = { version = "0.4.19", optional = true } -cidr-utils = { version = "0.5.4", optional = true } -form_urlencoded = "1.0.1" -futures-core = "0.3.15" -futures-util = "0.3.15" -hostname = { version = "0.3.1", optional = true } -http = "0.2.4" -log = "0.4.14" -once_cell = "1.8.0" -reqwest = { version = "0.11.4", features = ["cookies", "json"], default-features = false } -rust-ini = { version = "0.17.0", optional = true } -serde = { version = "1.0.126", features = ["derive"] } -serde_json = { version = "1.0.64", features = ["preserve_order"] } -systemstat = { version = "0.1.8", optional = true } -thiserror = "1.0.25" -url = "2.2.2" +chrono = { version = "0.4.26", optional = true } +cidr-utils = { version = "0.6.1", optional = true } +form_urlencoded = "1.2.1" +futures-core = "0.3.30" +futures-util = "0.3.30" +hostname = { version = "0.4.0", optional = true } +http = "1.1.0" +log = "0.4.18" +once_cell = "1.17.2" +reqwest = { version = "0.12.5", features = ["cookies", "json"], default-features = false } +rust-ini = { version = "0.21.0", optional = true } +serde = { version = "1.0.203", features = ["derive"] } +serde_json = { version = "1.0.117", features = ["preserve_order"] } +systemstat = { version = "0.2.3", optional = true } +thiserror = "1.0.61" +url = "2.5.2" hmac = { version = "0.12.1", optional = true } -sha1 = { version = "0.10.1", optional = true } -base64 = { version = "0.13.0", optional = true } -urlencoding = { version = "2.1.0", optional = true } +sha1 = { version = "0.10.6", optional = true } +base64 = { version = "0.22.1", optional = true } +urlencoding = { version = "2.1.3", optional = true } [dev-dependencies] -env_logger = "0.8.4" -futures = { version = "0.3.15", features = ["alloc"] } -tokio = { version = "1.7.1", features = ["full"] } +env_logger = "0.11.3" +futures = { version = "0.3.30", features = ["alloc"] } +tokio = { version = "1.29.1", features = ["full"] } [[test]] name = "conf" diff --git a/src/conf/meta.rs b/src/conf/meta.rs index 0f49f7d..9b14f78 100644 --- a/src/conf/meta.rs +++ b/src/conf/meta.rs @@ -141,7 +141,7 @@ impl Display for IpValue { IpValue::HostCidr(cidr) => { Self::get_all_addrs() .iter() - .find(|addr| cidr.contains(**addr)) + .find(|addr| cidr.contains(*addr)) .map(|s| Cow::Owned(s.to_string())) .unwrap_or(Cow::Borrowed("127.0.0.1")) } diff --git a/src/meta.rs b/src/meta.rs index 08a3002..a73619d 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -108,6 +108,7 @@ pub(crate) trait PerformRequest { /// https://www.apolloconfig.com/#/zh/usage/other-language-client-user-guide?id=_15-%e9%85%8d%e7%bd%ae%e8%ae%bf%e9%97%ae%e5%af%86%e9%92%a5 #[cfg(all(feature = "auth", feature = "conf"))] fn signature(&self, mut request_builder: reqwest::RequestBuilder) -> reqwest::RequestBuilder { + use base64::{engine::general_purpose::STANDARD, Engine}; use hmac::{Mac, SimpleHmac}; use sha1::Sha1; type HmacWithSha1 = SimpleHmac; @@ -129,7 +130,7 @@ pub(crate) trait PerformRequest { } if let Ok(mut hmac) = HmacWithSha1::new_from_slice(access_key.as_bytes()) { hmac.update(format!("{}\n{}", ts, url).as_bytes()); - let sign = base64::encode(hmac.finalize().into_bytes()); + let sign = STANDARD.encode(hmac.finalize().into_bytes()); request_builder = request_builder .header( reqwest::header::AUTHORIZATION, From 18fd8e888e6508ea56d75fe30afafa6c7506a41a Mon Sep 17 00:00:00 2001 From: jmjoy Date: Sat, 22 Jun 2024 23:58:47 +0800 Subject: [PATCH 6/7] Fix --- examples/watch.rs | 2 +- src/conf/meta.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/watch.rs b/examples/watch.rs index 57e7eab..3b2f496 100644 --- a/examples/watch.rs +++ b/examples/watch.rs @@ -1,7 +1,7 @@ use apollo_client::conf::{meta::IpValue, requests::WatchRequest, ApolloConfClientBuilder}; use cidr_utils::cidr::IpCidr; use futures_util::{pin_mut, stream::StreamExt}; -use std::error::Error; +use std::{error::Error, str::FromStr}; use url::Url; #[tokio::main] diff --git a/src/conf/meta.rs b/src/conf/meta.rs index 9b14f78..49eed53 100644 --- a/src/conf/meta.rs +++ b/src/conf/meta.rs @@ -155,6 +155,7 @@ impl Display for IpValue { #[cfg(test)] mod tests { use super::*; + use std::str::FromStr; #[test] fn test_notification_new() { From 07e5222e21773a8dcfb7ebc3894d431a24829a21 Mon Sep 17 00:00:00 2001 From: jmjoy Date: Sun, 23 Jun 2024 14:25:07 +0800 Subject: [PATCH 7/7] Fix empty ini properties --- src/conf/mod.rs | 4 ++-- src/errors.rs | 3 --- src/meta.rs | 4 +--- tests/conf.rs | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/conf/mod.rs b/src/conf/mod.rs index 34bab72..0206ee6 100644 --- a/src/conf/mod.rs +++ b/src/conf/mod.rs @@ -48,7 +48,7 @@ //! use apollo_client::conf::{meta::IpValue, requests::WatchRequest, ApolloConfClientBuilder}; //! use cidr_utils::cidr::IpCidr; //! use futures_util::{pin_mut, stream::StreamExt}; -//! use std::error::Error; +//! use std::{error::Error, str::FromStr}; //! use url::Url; //! //! #[tokio::main] @@ -236,7 +236,7 @@ impl ApolloConfClient { /// use apollo_client::conf::{meta::IpValue, requests::WatchRequest, ApolloConfClient}; /// use cidr_utils::cidr::IpCidr; /// use futures_util::{pin_mut, stream::StreamExt}; - /// use std::error::Error; + /// use std::{error::Error, str::FromStr}; /// /// #[tokio::main] /// async fn main() -> Result<(), Box> { diff --git a/src/errors.rs b/src/errors.rs index 416a183..43a4885 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -32,9 +32,6 @@ pub enum ApolloClientError { #[error("this URL is cannot-be-a-base")] UrlCannotBeABase, - - #[error("configuration is empty")] - EmptyConfiguration, } /// Apollo api response error, when http status is not success. diff --git a/src/meta.rs b/src/meta.rs index a73619d..240d17d 100644 --- a/src/meta.rs +++ b/src/meta.rs @@ -165,9 +165,7 @@ impl PerformResponse for ini::Properties { async fn from_response(response: Response) -> ApolloClientResult { let content = response.text().await?; let i = ini::Ini::load_from_str(&content)?; - Ok(i.section(None::<&'static str>) - .ok_or(crate::errors::ApolloClientError::EmptyConfiguration)? - .clone()) + Ok(i.section(None::<&'static str>).cloned().unwrap_or_default()) } } diff --git a/tests/conf.rs b/tests/conf.rs index fc89a9b..e59257d 100644 --- a/tests/conf.rs +++ b/tests/conf.rs @@ -95,7 +95,7 @@ async fn test_cached_fetch_request() { ..Default::default() }) .await; - assert!(matches!(result, Err(ApolloClientError::EmptyConfiguration))); + assert_eq!(result.unwrap(), Properties::new()); } }