This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push: new 2bdb635be feat(services/azdls): add request context (#6122) 2bdb635be is described below commit 2bdb635be88c6de804f8fa43db192ef44f49ac38 Author: Erick Guan <297343+erickg...@users.noreply.github.com> AuthorDate: Tue Apr 29 04:00:05 2025 +0200 feat(services/azdls): add request context (#6122) * feat(services/azdls): add request context * refactor(services/azdls): extract constants and remove unnecessary params --- core/src/services/azdls/backend.rs | 44 ++--------------- core/src/services/azdls/core.rs | 98 +++++++++++++++++++++++++++++--------- core/src/services/azdls/writer.rs | 12 ++--- 3 files changed, 83 insertions(+), 71 deletions(-) diff --git a/core/src/services/azdls/backend.rs b/core/src/services/azdls/backend.rs index 67307dd7c..ed3b8ef38 100644 --- a/core/src/services/azdls/backend.rs +++ b/core/src/services/azdls/backend.rs @@ -27,6 +27,7 @@ use reqsign::AzureStorageLoader; use reqsign::AzureStorageSigner; use super::core::AzdlsCore; +use super::core::DIRECTORY; use super::delete::AzdlsDeleter; use super::error::parse_error; use super::lister::AzdlsLister; @@ -273,7 +274,7 @@ impl Access for AzdlsBackend { async fn create_dir(&self, path: &str, _: OpCreateDir) -> Result<RpCreateDir> { let resp = self .core - .azdls_create(path, "directory", &OpWrite::default(), Buffer::new()) + .azdls_create(path, DIRECTORY, &OpWrite::default()) .await?; let status = resp.status(); @@ -285,48 +286,13 @@ impl Access for AzdlsBackend { async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> { // Stat root always returns a DIR. + // TODO: include metadata for the root (#4746) if path == "/" { return Ok(RpStat::new(Metadata::new(EntryMode::DIR))); } - let resp = self.core.azdls_get_properties(path).await?; - - if resp.status() != StatusCode::OK { - return Err(parse_error(resp)); - } - - let mut meta = parse_into_metadata(path, resp.headers())?; - let resource = resp - .headers() - .get("x-ms-resource-type") - .ok_or_else(|| { - Error::new( - ErrorKind::Unexpected, - "azdls should return x-ms-resource-type header, but it's missing", - ) - })? - .to_str() - .map_err(|err| { - Error::new( - ErrorKind::Unexpected, - "azdls should return x-ms-resource-type header, but it's not a valid string", - ) - .set_source(err) - })?; - - meta = match resource { - "file" => meta.with_mode(EntryMode::FILE), - "directory" => meta.with_mode(EntryMode::DIR), - v => { - return Err(Error::new( - ErrorKind::Unexpected, - "azdls returns not supported x-ms-resource-type", - ) - .with_context("resource", v)) - } - }; - - Ok(RpStat::new(meta)) + let metadata = self.core.azdls_stat_metadata(path).await?; + Ok(RpStat::new(metadata)) } async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> { diff --git a/core/src/services/azdls/core.rs b/core/src/services/azdls/core.rs index 2e0878359..c5f1e5f6e 100644 --- a/core/src/services/azdls/core.rs +++ b/core/src/services/azdls/core.rs @@ -22,6 +22,7 @@ use http::HeaderName; use http::HeaderValue; use http::Request; use http::Response; +use http::StatusCode; use reqsign::AzureStorageCredential; use reqsign::AzureStorageLoader; use reqsign::AzureStorageSigner; @@ -33,8 +34,12 @@ use std::sync::Arc; use crate::raw::*; use crate::*; +use super::error::parse_error; + const X_MS_RENAME_SOURCE: &str = "x-ms-rename-source"; const X_MS_VERSION: &str = "x-ms-version"; +pub const DIRECTORY: &str = "directory"; +pub const FILE: &str = "file"; pub struct AzdlsCore { pub info: Arc<AccessorInfo>, @@ -112,7 +117,10 @@ impl AzdlsCore { req = req.header(http::header::RANGE, range.to_header()); } - let mut req = req.body(Buffer::new()).map_err(new_request_build_error)?; + let mut req = req + .extension(Operation::Read) + .body(Buffer::new()) + .map_err(new_request_build_error)?; self.sign(&mut req).await?; self.info.http_client().fetch(req).await @@ -126,7 +134,6 @@ impl AzdlsCore { path: &str, resource: &str, args: &OpWrite, - body: Buffer, ) -> Result<Response<Buffer>> { let p = build_abs_path(&self.root, path) .trim_end_matches('/') @@ -160,11 +167,18 @@ impl AzdlsCore { req = req.header(IF_NONE_MATCH, v) } - // Set body - let mut req = req.body(body).map_err(new_request_build_error)?; + let operation = if resource == DIRECTORY { + Operation::CreateDir + } else { + Operation::Write + }; - self.sign(&mut req).await?; + let mut req = req + .extension(operation) + .body(Buffer::new()) + .map_err(new_request_build_error)?; + self.sign(&mut req).await?; self.send(req).await } @@ -179,12 +193,12 @@ impl AzdlsCore { percent_encode_path(&target) ); + let source_path = format!("/{}/{}", self.filesystem, percent_encode_path(&source)); + let mut req = Request::put(&url) - .header( - X_MS_RENAME_SOURCE, - format!("/{}/{}", self.filesystem, percent_encode_path(&source)), - ) + .header(X_MS_RENAME_SOURCE, source_path) .header(CONTENT_LENGTH, 0) + .extension(Operation::Rename) .body(Buffer::new()) .map_err(new_request_build_error)?; @@ -218,11 +232,12 @@ impl AzdlsCore { req = req.header(CONTENT_LENGTH, size) } - // Set body - let mut req = req.body(body).map_err(new_request_build_error)?; + let mut req = req + .extension(Operation::Write) + .body(body) + .map_err(new_request_build_error)?; self.sign(&mut req).await?; - self.send(req).await } @@ -240,10 +255,50 @@ impl AzdlsCore { let req = Request::head(&url); - let mut req = req.body(Buffer::new()).map_err(new_request_build_error)?; + let mut req = req + .extension(Operation::Stat) + .body(Buffer::new()) + .map_err(new_request_build_error)?; self.sign(&mut req).await?; - self.info.http_client().send(req).await + self.send(req).await + } + + pub async fn azdls_stat_metadata(&self, path: &str) -> Result<Metadata> { + let resp = self.azdls_get_properties(path).await?; + + if resp.status() != StatusCode::OK { + return Err(parse_error(resp)); + } + + let meta = parse_into_metadata(path, resp.headers())?; + let resource = resp + .headers() + .get("x-ms-resource-type") + .ok_or_else(|| { + Error::new( + ErrorKind::Unexpected, + "azdls should return x-ms-resource-type header, but it's missing", + ) + })? + .to_str() + .map_err(|err| { + Error::new( + ErrorKind::Unexpected, + "azdls should return x-ms-resource-type header, but it's not a valid string", + ) + .set_source(err) + })?; + + match resource { + FILE => Ok(meta.with_mode(EntryMode::FILE)), + DIRECTORY => Ok(meta.with_mode(EntryMode::DIR)), + v => Err(Error::new( + ErrorKind::Unexpected, + "azdls returns an unknown x-ms-resource-type", + ) + .with_context("resource", v)), + } } pub async fn azdls_delete(&self, path: &str) -> Result<Response<Buffer>> { @@ -258,9 +313,10 @@ impl AzdlsCore { percent_encode_path(&p) ); - let req = Request::delete(&url); - - let mut req = req.body(Buffer::new()).map_err(new_request_build_error)?; + let mut req = Request::delete(&url) + .extension(Operation::Delete) + .body(Buffer::new()) + .map_err(new_request_build_error)?; self.sign(&mut req).await?; self.send(req).await @@ -290,6 +346,7 @@ impl AzdlsCore { } let mut req = Request::get(url.finish()) + .extension(Operation::List) .body(Buffer::new()) .map_err(new_request_build_error)?; @@ -312,12 +369,7 @@ impl AzdlsCore { if !parts.is_empty() { let parent_path = parts.join("/"); let resp = self - .azdls_create( - &parent_path, - "directory", - &OpWrite::default(), - Buffer::new(), - ) + .azdls_create(&parent_path, DIRECTORY, &OpWrite::default()) .await?; Ok(Some(resp)) diff --git a/core/src/services/azdls/writer.rs b/core/src/services/azdls/writer.rs index 227022eba..63f19647a 100644 --- a/core/src/services/azdls/writer.rs +++ b/core/src/services/azdls/writer.rs @@ -19,7 +19,7 @@ use std::sync::Arc; use http::StatusCode; -use super::core::AzdlsCore; +use super::core::{AzdlsCore, FILE}; use super::error::parse_error; use crate::raw::*; use crate::*; @@ -41,10 +41,7 @@ impl AzdlsWriter { impl oio::OneShotWrite for AzdlsWriter { async fn write_once(&self, bs: Buffer) -> Result<Metadata> { - let resp = self - .core - .azdls_create(&self.path, "file", &self.op, Buffer::new()) - .await?; + let resp = self.core.azdls_create(&self.path, FILE, &self.op).await?; let status = resp.status(); match status { @@ -83,10 +80,7 @@ impl oio::AppendWrite for AzdlsWriter { async fn append(&self, offset: u64, size: u64, body: Buffer) -> Result<Metadata> { if offset == 0 { - let resp = self - .core - .azdls_create(&self.path, "file", &self.op, Buffer::new()) - .await?; + let resp = self.core.azdls_create(&self.path, FILE, &self.op).await?; let status = resp.status(); match status {