Skip to content

Commit

Permalink
feat(azblob): Support copy (#1868)
Browse files Browse the repository at this point in the history
* feat(azblob): Support copy

Signed-off-by: suyanhanx <suyanhanx@gmail.com>

* make clippy happy

Signed-off-by: suyanhanx <suyanhanx@gmail.com>

---------

Signed-off-by: suyanhanx <suyanhanx@gmail.com>
  • Loading branch information
suyanhanx authored Apr 7, 2023
1 parent 74f565f commit 031c219
Showing 1 changed file with 44 additions and 1 deletion.
45 changes: 44 additions & 1 deletion core/src/services/azblob/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use crate::types::Metadata;
use crate::*;

const X_MS_BLOB_TYPE: &str = "x-ms-blob-type";
const X_MS_COPY_SOURCE: &str = "x-ms-copy-source";

/// Known endpoint suffix Azure Storage Blob services resource URI syntax.
/// Azure public cloud: https://accountname.blob.core.windows.net
Expand All @@ -65,6 +66,7 @@ const AZBLOB_BATCH_LIMIT: usize = 256;
///
/// - [x] read
/// - [x] write
/// - [x] copy
/// - [x] list
/// - [x] scan
/// - [ ] presign
Expand Down Expand Up @@ -489,7 +491,7 @@ impl Accessor for AzblobBackend {
.set_root(&self.root)
.set_name(&self.container)
.set_max_batch_operations(AZBLOB_BATCH_LIMIT)
.set_capabilities(Read | Write | List | Scan | Batch)
.set_capabilities(Read | Write | List | Scan | Batch | Copy)
.set_hints(ReadStreamable);

am
Expand Down Expand Up @@ -542,6 +544,20 @@ impl Accessor for AzblobBackend {
))
}

async fn copy(&self, from: &str, to: &str, _args: OpCopy) -> Result<RpCopy> {
let resp = self.azblob_copy_blob(from, to).await?;

let status = resp.status();

match status {
StatusCode::ACCEPTED => {
resp.into_body().consume().await?;
Ok(RpCopy::default())
}
_ => Err(parse_error(resp).await?),
}
}

async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> {
// Stat root always returns a DIR.
if path == "/" {
Expand Down Expand Up @@ -769,6 +785,33 @@ impl AzblobBackend {
self.client.send_async(req).await
}

async fn azblob_copy_blob(&self, from: &str, to: &str) -> Result<Response<IncomingAsyncBody>> {
let source = build_abs_path(&self.root, from);
let target = build_abs_path(&self.root, to);

let source = format!(
"{}/{}/{}",
self.endpoint,
self.container,
percent_encode_path(&source)
);
let target = format!(
"{}/{}/{}",
self.endpoint,
self.container,
percent_encode_path(&target)
);

let mut req = Request::put(&target)
.header(X_MS_COPY_SOURCE, source)
.body(AsyncBody::Empty)
.map_err(new_request_build_error)?;

self.signer.sign(&mut req).map_err(new_request_sign_error)?;

self.client.send_async(req).await
}

pub(crate) async fn azblob_list_blobs(
&self,
path: &str,
Expand Down

0 comments on commit 031c219

Please # to comment.