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/incubator-opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 4a8d464e feat(gcs): copy support for GCS (#1869)
4a8d464e is described below
commit 4a8d464eff1b945a9ddb0a2d0dc66711b8d45409
Author: ClSlaid <[email protected]>
AuthorDate: Fri Apr 7 20:50:04 2023 +0800
feat(gcs): copy support for GCS (#1869)
* feat: copy support for GCS
Signed-off-by: ClSlaid <[email protected]>
* refactor: using `copyTo` instead of `rewriteTo`
1. `rewriteTo` is not suitable for retry, use `copyTo` instead.
Signed-off-by: ClSlaid <[email protected]>
* refactor: use `post` directly
Signed-off-by: ClSlaid <[email protected]>
---------
Signed-off-by: ClSlaid <[email protected]>
Co-authored-by: Suyan <[email protected]>
---
core/src/services/gcs/backend.rs | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs
index 06fd41ec..77314abe 100644
--- a/core/src/services/gcs/backend.rs
+++ b/core/src/services/gcs/backend.rs
@@ -55,6 +55,7 @@ const DEFAULT_GCS_SCOPE: &str =
"https://www.googleapis.com/auth/devstorage.read
/// - [x] write
/// - [x] list
/// - [x] scan
+/// - [x] copy
/// - [ ] presign
/// - [ ] blocking
///
@@ -360,7 +361,7 @@ impl Accessor for GcsBackend {
am.set_scheme(Scheme::Gcs)
.set_root(&self.root)
.set_name(&self.bucket)
- .set_capabilities(Read | Write | List | Scan)
+ .set_capabilities(Read | Write | List | Scan | Copy)
.set_hints(ReadStreamable);
am
}
@@ -405,6 +406,30 @@ impl Accessor for GcsBackend {
))
}
+ async fn copy(&self, from: &str, to: &str, _: OpCopy) -> Result<RpCopy> {
+ let source = percent_encode_path(&build_abs_path(&self.root,
from.trim_end_matches('/')));
+ let dest = percent_encode_path(&build_abs_path(&self.root,
to.trim_end_matches('/')));
+ let req_uri = format!(
+ "{}/storage/v1/b/{}/o/{}/copyTo/b/{}/o/{}",
+ self.endpoint, self.bucket, source, self.bucket, dest
+ );
+
+ let mut req = Request::post(req_uri)
+ .body(AsyncBody::Empty)
+ .map_err(new_request_build_error)?;
+
+ self.signer.sign(&mut req).map_err(new_request_sign_error)?;
+
+ let resp = self.client.send_async(req).await?;
+
+ if !resp.status().is_success() {
+ return Err(parse_error(resp).await?);
+ }
+ resp.into_body().consume().await?;
+
+ Ok(RpCopy::default())
+ }
+
async fn stat(&self, path: &str, _: OpStat) -> Result<RpStat> {
// Stat root always returns a DIR.
if path == "/" {