diff --git a/sdk/storage/azure_storage_blob/src/clients/blob_client.rs b/sdk/storage/azure_storage_blob/src/clients/blob_client.rs index d8546facb5..c7997c294a 100644 --- a/sdk/storage/azure_storage_blob/src/clients/blob_client.rs +++ b/sdk/storage/azure_storage_blob/src/clients/blob_client.rs @@ -24,7 +24,7 @@ use azure_core::{ credentials::TokenCredential, http::{ policies::{BearerTokenCredentialPolicy, Policy}, - NoFormat, RequestContent, Response, Url, XmlFormat, + NoFormat, Pipeline, RequestContent, Response, Url, XmlFormat, }, Bytes, Result, }; @@ -32,10 +32,91 @@ use std::sync::Arc; /// A client to interact with a specific Azure storage blob, although that blob may not yet exist. pub struct BlobClient { - pub(super) endpoint: Url, pub(super) client: GeneratedBlobClient, } +impl GeneratedBlobClient { + fn from_url_with_credential( + blob_url: &str, + credential: Arc, + options: Option, + ) -> Result { + let options = options.unwrap_or_default(); + let blob_url = Url::parse(blob_url)?; + if !blob_url.scheme().starts_with("http") { + return Err(azure_core::Error::message( + azure_core::error::ErrorKind::Other, + format!("{blob_url} must use http(s)"), + )); + } + + let mut segments = blob_url + .path_segments() + .expect("Failed to get path segments"); + let container_name = segments + .next() + .expect("Failed to parse container_name") + .to_string(); + let blob_name = segments.collect::>().join("/"); + + let auth_policy: Arc = Arc::new(BearerTokenCredentialPolicy::new( + credential, + vec!["https://storage.azure.com/.default"], + )); + + Ok(Self { + blob_name, + container_name, + blob_url, + version: options.version, + pipeline: Pipeline::new( + option_env!("CARGO_PKG_NAME"), + option_env!("CARGO_PKG_VERSION"), + options.client_options, + Vec::default(), + vec![auth_policy], + ), + }) + } + + fn from_url_with_no_credential( + blob_url: &str, + options: Option, + ) -> Result { + let options = options.unwrap_or_default(); + let blob_url = Url::parse(blob_url)?; + if !blob_url.scheme().starts_with("http") { + return Err(azure_core::Error::message( + azure_core::error::ErrorKind::Other, + format!("{blob_url} must use http(s)"), + )); + } + + let mut segments = blob_url + .path_segments() + .expect("Failed to get path segments"); + let container_name = segments + .next() + .expect("Failed to parse container_name") + .to_string(); + let blob_name = segments.collect::>().join("/"); + + Ok(Self { + blob_name, + container_name, + blob_url, + version: options.version, + pipeline: Pipeline::new( + option_env!("CARGO_PKG_NAME"), + option_env!("CARGO_PKG_VERSION"), + options.client_options, + Vec::default(), + Vec::default(), + ), + }) + } +} + impl BlobClient { /// Creates a new BlobClient, using Entra ID authentication. /// @@ -61,55 +142,75 @@ impl BlobClient { .per_call_policies .push(storage_headers_policy); - let client = GeneratedBlobClient::new( - endpoint, - credential.clone(), - container_name.clone(), - blob_name.clone(), - Some(options), - )?; - Ok(Self { - endpoint: endpoint.parse()?, - client, - }) - } - - /// Returns a new instance of AppendBlobClient. - /// - /// # Arguments - /// - pub fn append_blob_client(&self) -> AppendBlobClient { - AppendBlobClient { - endpoint: self.client.endpoint.clone(), - client: self.client.get_append_blob_client(), + let mut url = Url::parse(endpoint)?; + if !url.scheme().starts_with("http") { + return Err(azure_core::Error::message( + azure_core::error::ErrorKind::Other, + format!("{url} must use http(s)"), + )); } - } - /// Returns a new instance of BlockBlobClient. - /// - /// # Arguments - /// - pub fn block_blob_client(&self) -> BlockBlobClient { - BlockBlobClient { - endpoint: self.client.endpoint.clone(), - client: self.client.get_block_blob_client(), - } + // In regular ctor, since struct now holds blob_url, we have to build the blob_url given endpoint + container_name + blob_name + url.path_segments_mut() + .expect("Cannot be base") + .extend([&container_name, &blob_name]); + + let client = + GeneratedBlobClient::from_url_with_credential(url.as_str(), credential, Some(options))?; + Ok(Self { client }) } - /// Returns a new instance of PageBlobClient. - /// - /// # Arguments - /// - pub fn page_blob_client(&self) -> PageBlobClient { - PageBlobClient { - endpoint: self.client.endpoint.clone(), - client: self.client.get_page_blob_client(), - } + pub fn from_blob_url(blob_url: &str, options: Option) -> Result { + let mut options = options.unwrap_or_default(); + + let storage_headers_policy = Arc::new(StorageHeadersPolicy); + options + .client_options + .per_call_policies + .push(storage_headers_policy); + + let url = Url::parse(blob_url)?; + let client = GeneratedBlobClient::from_url_with_no_credential(url.as_str(), Some(options))?; + + Ok(Self { client }) } + // /// Returns a new instance of AppendBlobClient. + // /// + // /// # Arguments + // /// + // pub fn append_blob_client(&self) -> AppendBlobClient { + // AppendBlobClient { + // endpoint: self.client.endpoint.clone(), + // client: self.client.get_append_blob_client(), + // } + // } + + // /// Returns a new instance of BlockBlobClient. + // /// + // /// # Arguments + // /// + // pub fn block_blob_client(&self) -> BlockBlobClient { + // BlockBlobClient { + // endpoint: self.client.endpoint.clone(), + // client: self.client.get_block_blob_client(), + // } + // } + + // /// Returns a new instance of PageBlobClient. + // /// + // /// # Arguments + // /// + // pub fn page_blob_client(&self) -> PageBlobClient { + // PageBlobClient { + // endpoint: self.client.endpoint.clone(), + // client: self.client.get_page_blob_client(), + // } + // } + /// Gets the endpoint of the Storage account this client is connected to. - pub fn endpoint(&self) -> &Url { - &self.endpoint + pub fn blob_url(&self) -> &Url { + &self.client.blob_url } /// Gets the container name of the Storage account this client is connected to. @@ -135,173 +236,173 @@ impl BlobClient { self.client.get_properties(options).await } - /// Sets system properties on the blob. - /// - /// # Arguments - /// - /// * `options` - Optional configuration for the request. - pub async fn set_properties( - &self, - options: Option>, - ) -> Result> { - self.client.set_properties(options).await - } + // /// Sets system properties on the blob. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional configuration for the request. + // pub async fn set_properties( + // &self, + // options: Option>, + // ) -> Result> { + // self.client.set_properties(options).await + // } - /// Downloads a blob from the service, including its metadata and properties. - /// - /// * `options` - Optional configuration for the request. - pub async fn download( - &self, - options: Option>, - ) -> Result> { - self.client.download(options).await - } + // /// Downloads a blob from the service, including its metadata and properties. + // /// + // /// * `options` - Optional configuration for the request. + // pub async fn download( + // &self, + // options: Option>, + // ) -> Result> { + // self.client.download(options).await + // } - /// Creates a new blob from a data source. - /// - /// # Arguments - /// - /// * `data` - The blob data to upload. - /// * `overwrite` - Whether the blob to be uploaded should overwrite the current data. If True, `upload_blob` will overwrite the existing data. - /// If False, the operation will fail with ResourceExistsError. - /// * `content_length` - Total length of the blob data to be uploaded. - /// * `options` - Optional configuration for the request. - pub async fn upload( - &self, - data: RequestContent, - overwrite: bool, - content_length: u64, - options: Option>, - ) -> Result> { - let mut options = options.unwrap_or_default(); + // /// Creates a new blob from a data source. + // /// + // /// # Arguments + // /// + // /// * `data` - The blob data to upload. + // /// * `overwrite` - Whether the blob to be uploaded should overwrite the current data. If True, `upload_blob` will overwrite the existing data. + // /// If False, the operation will fail with ResourceExistsError. + // /// * `content_length` - Total length of the blob data to be uploaded. + // /// * `options` - Optional configuration for the request. + // pub async fn upload( + // &self, + // data: RequestContent, + // overwrite: bool, + // content_length: u64, + // options: Option>, + // ) -> Result> { + // let mut options = options.unwrap_or_default(); - if !overwrite { - options.if_none_match = Some(String::from("*")); - } + // if !overwrite { + // options.if_none_match = Some(String::from("*")); + // } - let block_blob_client = self.client.get_block_blob_client(); + // let block_blob_client = self.client.get_block_blob_client(); - block_blob_client - .upload(data, content_length, Some(options)) - .await - } + // block_blob_client + // .upload(data, content_length, Some(options)) + // .await + // } - /// Sets user-defined metadata for the specified blob as one or more name-value pairs. Each call to this operation - /// replaces all existing metadata attached to the blob. To remove all metadata from the blob, call this operation with - /// no metadata headers. - /// - /// # Arguments - /// - /// * `options` - Optional configuration for the request. - pub async fn set_metadata( - &self, - options: Option>, - ) -> Result> { - self.client.set_metadata(options).await - } + // /// Sets user-defined metadata for the specified blob as one or more name-value pairs. Each call to this operation + // /// replaces all existing metadata attached to the blob. To remove all metadata from the blob, call this operation with + // /// no metadata headers. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional configuration for the request. + // pub async fn set_metadata( + // &self, + // options: Option>, + // ) -> Result> { + // self.client.set_metadata(options).await + // } - /// Deletes the blob. - /// - /// # Arguments - /// - /// * `options` - Optional configuration for the request. - pub async fn delete( - &self, - options: Option>, - ) -> Result> { - self.client.delete(options).await - } + // /// Deletes the blob. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional configuration for the request. + // pub async fn delete( + // &self, + // options: Option>, + // ) -> Result> { + // self.client.delete(options).await + // } - /// Sets the tier on a blob. Standard tiers are only applicable for Block blobs, while Premium tiers are only applicable - /// for Page blobs. - /// - /// # Arguments - /// - /// * `tier` - The tier to be set on the blob. - /// * `options` - Optional configuration for the request. - pub async fn set_tier( - &self, - tier: AccessTier, - options: Option>, - ) -> Result> { - self.client.set_tier(tier, options).await - } + // /// Sets the tier on a blob. Standard tiers are only applicable for Block blobs, while Premium tiers are only applicable + // /// for Page blobs. + // /// + // /// # Arguments + // /// + // /// * `tier` - The tier to be set on the blob. + // /// * `options` - Optional configuration for the request. + // pub async fn set_tier( + // &self, + // tier: AccessTier, + // options: Option>, + // ) -> Result> { + // self.client.set_tier(tier, options).await + // } - /// Requests a new lease on a blob. The lease lock duration can be 15 to 60 seconds, or can be infinite. - /// - /// # Arguments - /// - /// * `duration` - Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A - /// non-infinite lease can be between 15 and 60 seconds. - /// * `options` - Optional configuration for the request. - pub async fn acquire_lease( - &self, - duration: i32, - options: Option>, - ) -> Result> { - self.client.acquire_lease(duration, options).await - } + // /// Requests a new lease on a blob. The lease lock duration can be 15 to 60 seconds, or can be infinite. + // /// + // /// # Arguments + // /// + // /// * `duration` - Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A + // /// non-infinite lease can be between 15 and 60 seconds. + // /// * `options` - Optional configuration for the request. + // pub async fn acquire_lease( + // &self, + // duration: i32, + // options: Option>, + // ) -> Result> { + // self.client.acquire_lease(duration, options).await + // } - /// Ends a lease and ensures that another client can't acquire a new lease until the current lease - /// period has expired. - /// - /// # Arguments - /// - /// * `options` - Optional configuration for the request. - pub async fn break_lease( - &self, - options: Option>, - ) -> Result> { - self.client.break_lease(options).await - } + // /// Ends a lease and ensures that another client can't acquire a new lease until the current lease + // /// period has expired. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional configuration for the request. + // pub async fn break_lease( + // &self, + // options: Option>, + // ) -> Result> { + // self.client.break_lease(options).await + // } - /// Changes the ID of an existing lease to the proposed lease ID. - /// - /// # Arguments - /// - /// * `lease_id` - A lease ID for the source path. The source path must have an active lease and the - /// lease ID must match. - /// * `proposed_lease_id` - The proposed lease ID for the blob. - /// * `options` - Optional configuration for the request. - pub async fn change_lease( - &self, - lease_id: String, - proposed_lease_id: String, - options: Option>, - ) -> Result> { - self.client - .change_lease(lease_id, proposed_lease_id, options) - .await - } + // /// Changes the ID of an existing lease to the proposed lease ID. + // /// + // /// # Arguments + // /// + // /// * `lease_id` - A lease ID for the source path. The source path must have an active lease and the + // /// lease ID must match. + // /// * `proposed_lease_id` - The proposed lease ID for the blob. + // /// * `options` - Optional configuration for the request. + // pub async fn change_lease( + // &self, + // lease_id: String, + // proposed_lease_id: String, + // options: Option>, + // ) -> Result> { + // self.client + // .change_lease(lease_id, proposed_lease_id, options) + // .await + // } - /// Frees the lease so that another client can immediately acquire a lease - /// against the blob as soon as the release is complete. - /// - /// # Arguments - /// - /// * `lease_id` - A lease ID for the source path. The source path must have an active lease and the - /// lease ID must match. - /// * `options` - Optional configuration for the request. - pub async fn release_lease( - &self, - lease_id: String, - options: Option>, - ) -> Result> { - self.client.release_lease(lease_id, options).await - } + // /// Frees the lease so that another client can immediately acquire a lease + // /// against the blob as soon as the release is complete. + // /// + // /// # Arguments + // /// + // /// * `lease_id` - A lease ID for the source path. The source path must have an active lease and the + // /// lease ID must match. + // /// * `options` - Optional configuration for the request. + // pub async fn release_lease( + // &self, + // lease_id: String, + // options: Option>, + // ) -> Result> { + // self.client.release_lease(lease_id, options).await + // } - /// Renews the lease on a blob. - /// - /// # Arguments - /// - /// * `lease_id` - A lease ID for the source path. The source path must have an active lease and the - /// lease ID must match. - /// * `options` - Optional configuration for the request. - pub async fn renew_lease( - &self, - lease_id: String, - options: Option>, - ) -> Result> { - self.client.renew_lease(lease_id, options).await - } + // /// Renews the lease on a blob. + // /// + // /// # Arguments + // /// + // /// * `lease_id` - A lease ID for the source path. The source path must have an active lease and the + // /// lease ID must match. + // /// * `options` - Optional configuration for the request. + // pub async fn renew_lease( + // &self, + // lease_id: String, + // options: Option>, + // ) -> Result> { + // self.client.renew_lease(lease_id, options).await + // } } diff --git a/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs b/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs index 312a85c08a..f4efd825a9 100644 --- a/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs +++ b/sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs @@ -76,12 +76,12 @@ impl BlobContainerClient { /// # Arguments /// /// * `blob_name` - The name of the blob. - pub fn blob_client(&self, blob_name: String) -> BlobClient { - BlobClient { - endpoint: self.client.endpoint.clone(), - client: self.client.get_blob_client(blob_name), - } - } + // pub fn blob_client(&self, blob_name: String) -> BlobClient { + // BlobClient { + // endpoint: self.client.endpoint.clone(), + // client: self.client.get_blob_client(blob_name), + // } + // } /// Gets the endpoint of the Storage account this client is connected to. pub fn endpoint(&self) -> &Url { diff --git a/sdk/storage/azure_storage_blob/src/generated/clients/blob_client.rs b/sdk/storage/azure_storage_blob/src/generated/clients/blob_client.rs index bdddfd95fc..d2155b546f 100644 --- a/sdk/storage/azure_storage_blob/src/generated/clients/blob_client.rs +++ b/sdk/storage/azure_storage_blob/src/generated/clients/blob_client.rs @@ -40,11 +40,10 @@ use azure_core::{ }; use std::sync::Arc; -#[tracing::client] pub struct BlobClient { pub(crate) blob_name: String, pub(crate) container_name: String, - pub(crate) endpoint: Url, + pub(crate) blob_url: Url, pub(crate) pipeline: Pipeline, pub(crate) version: String, } @@ -59,17 +58,7 @@ pub struct BlobClientOptions { } impl BlobClient { - /// Creates a new BlobClient, using Entra ID authentication. - /// - /// # Arguments - /// - /// * `endpoint` - Service host - /// * `credential` - An implementation of [`TokenCredential`](azure_core::credentials::TokenCredential) that can provide an - /// Entra ID token to use when authenticating. - /// * `container_name` - The name of the container. - /// * `blob_name` - The name of the blob. - /// * `options` - Optional configuration for the client. - #[tracing::new("azure_storage_blob")] + // UNUSED UNUSED UNUSED UNUSED UNUSED UNUSED UNUSED UNUSED pub fn new( endpoint: &str, credential: Arc, @@ -93,7 +82,7 @@ impl BlobClient { Ok(Self { blob_name, container_name, - endpoint, + blob_url: endpoint, // This is straight up wrong (does not fold in blob/container to url, but need to fix compiler) version: options.version, pipeline: Pipeline::new( option_env!("CARGO_PKG_NAME"), @@ -106,292 +95,798 @@ impl BlobClient { } /// Returns the Url associated with this client. - pub fn endpoint(&self) -> &Url { - &self.endpoint + pub fn blob_url(&self) -> &Url { + &self.blob_url } - /// The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a destination blob with zero length - /// and full metadata. - /// - /// # Arguments - /// - /// * `copy_id` - The copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.abortCopyFromUrl")] - pub async fn abort_copy_from_url( - &self, - copy_id: &str, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_pair("comp", "copy") - .append_key_only("copyid"); - url.query_pairs_mut().append_pair("copyid", copy_id); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-copy-action", "abort"); - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Abort Copy From URL operation aborts a pending Copy From URL operation, and leaves a destination blob with zero length + // /// and full metadata. + // /// + // /// # Arguments + // /// + // /// * `copy_id` - The copy identifier provided in the x-ms-copy-id header of the original Copy Blob operation. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.abortCopyFromUrl")] + // pub async fn abort_copy_from_url( + // &self, + // copy_id: &str, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_pair("comp", "copy") + // .append_key_only("copyid"); + // url.query_pairs_mut().append_pair("copyid", copy_id); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-copy-action", "abort"); + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Acquire Lease operation requests a new lease on a blob. The lease lock duration can be 15 to 60 seconds, or can be - /// infinite. - /// - /// # Arguments - /// - /// * `duration` - Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A - /// non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.acquireLease")] - pub async fn acquire_lease( - &self, - duration: i32, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_key_only("acquire") - .append_pair("comp", "lease"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - request.insert_header("x-ms-lease-action", "acquire"); - request.insert_header("x-ms-lease-duration", duration.to_string()); - if let Some(proposed_lease_id) = options.proposed_lease_id { - request.insert_header("x-ms-proposed-lease-id", proposed_lease_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Acquire Lease operation requests a new lease on a blob. The lease lock duration can be 15 to 60 seconds, or can be + // /// infinite. + // /// + // /// # Arguments + // /// + // /// * `duration` - Specifies the duration of the lease, in seconds, or negative one (-1) for a lease that never expires. A + // /// non-infinite lease can be between 15 and 60 seconds. A lease duration cannot be changed using renew or change. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.acquireLease")] + // pub async fn acquire_lease( + // &self, + // duration: i32, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_key_only("acquire") + // .append_pair("comp", "lease"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // request.insert_header("x-ms-lease-action", "acquire"); + // request.insert_header("x-ms-lease-duration", duration.to_string()); + // if let Some(proposed_lease_id) = options.proposed_lease_id { + // request.insert_header("x-ms-proposed-lease-id", proposed_lease_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Break Lease operation ends a lease and ensures that another client can't acquire a new lease until the current lease - /// period has expired. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.breakLease")] - pub async fn break_lease( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_key_only("break") - .append_pair("comp", "lease"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - request.insert_header("x-ms-lease-action", "break"); - if let Some(break_period) = options.break_period { - request.insert_header("x-ms-lease-break-period", break_period.to_string()); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Break Lease operation ends a lease and ensures that another client can't acquire a new lease until the current lease + // /// period has expired. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.breakLease")] + // pub async fn break_lease( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_key_only("break") + // .append_pair("comp", "lease"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // request.insert_header("x-ms-lease-action", "break"); + // if let Some(break_period) = options.break_period { + // request.insert_header("x-ms-lease-break-period", break_period.to_string()); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Change Lease operation is used to change the ID of an existing lease. - /// - /// # Arguments - /// - /// * `lease_id` - Required. A lease ID for the source path. If specified, the source path must have an active lease and the - /// lease ID must match. - /// * `proposed_lease_id` - Required. The proposed lease ID for the container. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.changeLease")] - pub async fn change_lease( - &self, - lease_id: String, - proposed_lease_id: String, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_key_only("change") - .append_pair("comp", "lease"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - request.insert_header("x-ms-lease-action", "change"); - request.insert_header("x-ms-lease-id", lease_id); - request.insert_header("x-ms-proposed-lease-id", proposed_lease_id); - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Change Lease operation is used to change the ID of an existing lease. + // /// + // /// # Arguments + // /// + // /// * `lease_id` - Required. A lease ID for the source path. If specified, the source path must have an active lease and the + // /// lease ID must match. + // /// * `proposed_lease_id` - Required. The proposed lease ID for the container. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.changeLease")] + // pub async fn change_lease( + // &self, + // lease_id: String, + // proposed_lease_id: String, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_key_only("change") + // .append_pair("comp", "lease"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // request.insert_header("x-ms-lease-action", "change"); + // request.insert_header("x-ms-lease-id", lease_id); + // request.insert_header("x-ms-proposed-lease-id", proposed_lease_id); + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } + + // /// The Copy From URL operation copies a blob or an internet resource to a new blob. It will not return a response until the + // /// copy is complete. + // /// + // /// # Arguments + // /// + // /// * `copy_source` - Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that + // /// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must + // /// either be public or must be authenticated via a shared access signature. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.copyFromUrl")] + // pub async fn copy_from_url( + // &self, + // copy_source: String, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_pair("comp", "copy") + // .append_key_only("sync"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(tier) = options.tier { + // request.insert_header("x-ms-access-tier", tier.to_string()); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-copy-source", copy_source); + // if let Some(copy_source_authorization) = options.copy_source_authorization { + // request.insert_header("x-ms-copy-source-authorization", copy_source_authorization); + // } + // if let Some(copy_source_tags) = options.copy_source_tags { + // request.insert_header("x-ms-copy-source-tag-option", copy_source_tags.to_string()); + // } + // if let Some(encryption_scope) = options.encryption_scope { + // request.insert_header("x-ms-encryption-scope", encryption_scope); + // } + // if let Some(file_request_intent) = options.file_request_intent { + // request.insert_header("x-ms-file-request-intent", file_request_intent.to_string()); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(immutability_policy_mode) = options.immutability_policy_mode { + // request.insert_header( + // "x-ms-immutability-policy-mode", + // immutability_policy_mode.to_string(), + // ); + // } + // if let Some(immutability_policy_expiry) = options.immutability_policy_expiry { + // request.insert_header( + // "x-ms-immutability-policy-until-date", + // to_rfc7231(&immutability_policy_expiry), + // ); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // if let Some(legal_hold) = options.legal_hold { + // request.insert_header("x-ms-legal-hold", legal_hold.to_string()); + // } + // if let Some(metadata) = options.metadata { + // for (k, v) in &metadata { + // request.insert_header(format!("x-ms-meta-{k}"), v); + // } + // } + // request.insert_header("x-ms-requires-sync", "true"); + // if let Some(source_content_md5) = options.source_content_md5 { + // request.insert_header("x-ms-source-content-md5", encode(source_content_md5)); + // } + // if let Some(source_if_match) = options.source_if_match { + // request.insert_header("x-ms-source-if-match", source_if_match); + // } + // if let Some(source_if_modified_since) = options.source_if_modified_since { + // request.insert_header( + // "x-ms-source-if-modified-since", + // to_rfc7231(&source_if_modified_since), + // ); + // } + // if let Some(source_if_none_match) = options.source_if_none_match { + // request.insert_header("x-ms-source-if-none-match", source_if_none_match); + // } + // if let Some(source_if_unmodified_since) = options.source_if_unmodified_since { + // request.insert_header( + // "x-ms-source-if-unmodified-since", + // to_rfc7231(&source_if_unmodified_since), + // ); + // } + // if let Some(blob_tags_string) = options.blob_tags_string { + // request.insert_header("x-ms-tags", blob_tags_string); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } + + // /// The Create Snapshot operation creates a read-only snapshot of a blob + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.createSnapshot")] + // pub async fn create_snapshot( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "snapshot"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(encryption_algorithm) = options.encryption_algorithm { + // request.insert_header( + // "x-ms-encryption-algorithm", + // encryption_algorithm.to_string(), + // ); + // } + // if let Some(encryption_key) = options.encryption_key { + // request.insert_header("x-ms-encryption-key", encryption_key); + // } + // if let Some(encryption_key_sha256) = options.encryption_key_sha256 { + // request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); + // } + // if let Some(encryption_scope) = options.encryption_scope { + // request.insert_header("x-ms-encryption-scope", encryption_scope); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // if let Some(metadata) = options.metadata { + // for (k, v) in &metadata { + // request.insert_header(format!("x-ms-meta-{k}"), v); + // } + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } + + // /// If the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently removed from + // /// the storage account. If the storage account's soft delete feature is enabled, then, when a blob is deleted, it is marked + // /// for deletion and becomes inaccessible immediately. However, the blob service retains the blob or snapshot for the number + // /// of days specified by the DeleteRetentionPolicy section of [Storage service properties] (Set-Blob-Service-Properties.md). + // /// After the specified number of days has passed, the blob's data is permanently removed from the storage account. Note that + // /// you continue to be charged for the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API + // /// and specify the \"include=deleted\" query parameter to discover which blobs and snapshots have been soft deleted. You + // /// can then use the Undelete Blob API to restore a soft-deleted blob. All other operations on a soft-deleted blob or snapshot + // /// causes the service to return an HTTP status code of 404 (ResourceNotFound). + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.delete")] + // pub async fn delete( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // if let Some(blob_delete_type) = options.blob_delete_type { + // url.query_pairs_mut() + // .append_pair("deletetype", blob_delete_type.as_ref()); + // } + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Delete); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(delete_snapshots) = options.delete_snapshots { + // request.insert_header("x-ms-delete-snapshots", delete_snapshots.to_string()); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Copy From URL operation copies a blob or an internet resource to a new blob. It will not return a response until the - /// copy is complete. + // /// The Delete Immutability Policy operation deletes the immutability policy on the blob. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.deleteImmutabilityPolicy")] + // pub async fn delete_immutability_policy( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_pair("comp", "immutabilityPolicies"); + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Delete); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } + + // /// The Download operation reads or downloads a blob from the system, including its metadata and properties. You can also + // /// call Download to read a snapshot. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.download")] + // pub async fn download( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Get); + // request.insert_header("accept", "application/octet-stream"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(range) = options.range { + // request.insert_header("range", range); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(encryption_algorithm) = options.encryption_algorithm { + // request.insert_header( + // "x-ms-encryption-algorithm", + // encryption_algorithm.to_string(), + // ); + // } + // if let Some(encryption_key) = options.encryption_key { + // request.insert_header("x-ms-encryption-key", encryption_key); + // } + // if let Some(encryption_key_sha256) = options.encryption_key_sha256 { + // request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // if let Some(range_get_content_crc64) = options.range_get_content_crc64 { + // request.insert_header( + // "x-ms-range-get-content-crc64", + // range_get_content_crc64.to_string(), + // ); + // } + // if let Some(range_get_content_md5) = options.range_get_content_md5 { + // request.insert_header( + // "x-ms-range-get-content-md5", + // range_get_content_md5.to_string(), + // ); + // } + // if let Some(structured_body_type) = options.structured_body_type { + // request.insert_header("x-ms-structured-body", structured_body_type); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } + + // /// Returns the sku name and account kind + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.getAccountInfo")] + // pub async fn get_account_info( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_key_only("blob") + // .append_pair("comp", "properties") + // .append_pair("restype", "account"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Get); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } + + /// Returns a new instance of AppendBlobClient. + // #[tracing::subclient] + // pub fn get_append_blob_client(&self) -> AppendBlobClient { + // AppendBlobClient { + // blob_name: self.blob_name.clone(), + // container_name: self.container_name.clone(), + // endpoint: self.endpoint.clone(), + // pipeline: self.pipeline.clone(), + // version: self.version.clone(), + // } + // } + + // /// Returns a new instance of BlockBlobClient. + // #[tracing::subclient] + // pub fn get_block_blob_client(&self) -> BlockBlobClient { + // BlockBlobClient { + // blob_name: self.blob_name.clone(), + // container_name: self.container_name.clone(), + // endpoint: self.endpoint.clone(), + // pipeline: self.pipeline.clone(), + // version: self.version.clone(), + // } + // } + + // /// Returns a new instance of PageBlobClient. + // #[tracing::subclient] + // pub fn get_page_blob_client(&self) -> PageBlobClient { + // PageBlobClient { + // blob_name: self.blob_name.clone(), + // container_name: self.container_name.clone(), + // endpoint: self.endpoint.clone(), + // pipeline: self.pipeline.clone(), + // version: self.version.clone(), + // } + // } + + /// The Get Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the + /// blob. It does not return the content of the blob. /// /// # Arguments /// - /// * `copy_source` - Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that - /// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must - /// either be public or must be authenticated via a shared access signature. /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.copyFromUrl")] - pub async fn copy_from_url( + pub async fn get_properties( &self, - copy_source: String, - options: Option>, - ) -> Result> { + options: Option>, + ) -> Result> { let options = options.unwrap_or_default(); let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_pair("comp", "copy") - .append_key_only("sync"); + let mut url = self.blob_url.clone(); + if let Some(snapshot) = options.snapshot { + url.query_pairs_mut().append_pair("snapshot", &snapshot); + } if let Some(timeout) = options.timeout { url.query_pairs_mut() .append_pair("timeout", &timeout.to_string()); } - let mut request = Request::new(url, Method::Put); + if let Some(version_id) = options.version_id { + url.query_pairs_mut().append_pair("versionid", &version_id); + } + let mut request = Request::new(url, Method::Head); request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); if let Some(if_match) = options.if_match { request.insert_header("if-match", if_match); } @@ -404,76 +899,27 @@ impl BlobClient { if let Some(if_unmodified_since) = options.if_unmodified_since { request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); } - if let Some(tier) = options.tier { - request.insert_header("x-ms-access-tier", tier.to_string()); - } if let Some(client_request_id) = options.client_request_id { request.insert_header("x-ms-client-request-id", client_request_id); } - request.insert_header("x-ms-copy-source", copy_source); - if let Some(copy_source_authorization) = options.copy_source_authorization { - request.insert_header("x-ms-copy-source-authorization", copy_source_authorization); - } - if let Some(copy_source_tags) = options.copy_source_tags { - request.insert_header("x-ms-copy-source-tag-option", copy_source_tags.to_string()); + if let Some(encryption_algorithm) = options.encryption_algorithm { + request.insert_header( + "x-ms-encryption-algorithm", + encryption_algorithm.to_string(), + ); } - if let Some(encryption_scope) = options.encryption_scope { - request.insert_header("x-ms-encryption-scope", encryption_scope); + if let Some(encryption_key) = options.encryption_key { + request.insert_header("x-ms-encryption-key", encryption_key); } - if let Some(file_request_intent) = options.file_request_intent { - request.insert_header("x-ms-file-request-intent", file_request_intent.to_string()); + if let Some(encryption_key_sha256) = options.encryption_key_sha256 { + request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); } if let Some(if_tags) = options.if_tags { request.insert_header("x-ms-if-tags", if_tags); } - if let Some(immutability_policy_mode) = options.immutability_policy_mode { - request.insert_header( - "x-ms-immutability-policy-mode", - immutability_policy_mode.to_string(), - ); - } - if let Some(immutability_policy_expiry) = options.immutability_policy_expiry { - request.insert_header( - "x-ms-immutability-policy-until-date", - to_rfc7231(&immutability_policy_expiry), - ); - } if let Some(lease_id) = options.lease_id { request.insert_header("x-ms-lease-id", lease_id); } - if let Some(legal_hold) = options.legal_hold { - request.insert_header("x-ms-legal-hold", legal_hold.to_string()); - } - if let Some(metadata) = options.metadata { - for (k, v) in &metadata { - request.insert_header(format!("x-ms-meta-{k}"), v); - } - } - request.insert_header("x-ms-requires-sync", "true"); - if let Some(source_content_md5) = options.source_content_md5 { - request.insert_header("x-ms-source-content-md5", encode(source_content_md5)); - } - if let Some(source_if_match) = options.source_if_match { - request.insert_header("x-ms-source-if-match", source_if_match); - } - if let Some(source_if_modified_since) = options.source_if_modified_since { - request.insert_header( - "x-ms-source-if-modified-since", - to_rfc7231(&source_if_modified_since), - ); - } - if let Some(source_if_none_match) = options.source_if_none_match { - request.insert_header("x-ms-source-if-none-match", source_if_none_match); - } - if let Some(source_if_unmodified_since) = options.source_if_unmodified_since { - request.insert_header( - "x-ms-source-if-unmodified-since", - to_rfc7231(&source_if_unmodified_since), - ); - } - if let Some(blob_tags_string) = options.blob_tags_string { - request.insert_header("x-ms-tags", blob_tags_string); - } request.insert_header("x-ms-version", &self.version); let rsp = self.pipeline.send(&ctx, &mut request).await?; if !rsp.status().is_success() { @@ -488,1255 +934,793 @@ impl BlobClient { Ok(rsp.into()) } - /// The Create Snapshot operation creates a read-only snapshot of a blob - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.createSnapshot")] - pub async fn create_snapshot( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "snapshot"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(encryption_algorithm) = options.encryption_algorithm { - request.insert_header( - "x-ms-encryption-algorithm", - encryption_algorithm.to_string(), - ); - } - if let Some(encryption_key) = options.encryption_key { - request.insert_header("x-ms-encryption-key", encryption_key); - } - if let Some(encryption_key_sha256) = options.encryption_key_sha256 { - request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); - } - if let Some(encryption_scope) = options.encryption_scope { - request.insert_header("x-ms-encryption-scope", encryption_scope); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - if let Some(metadata) = options.metadata { - for (k, v) in &metadata { - request.insert_header(format!("x-ms-meta-{k}"), v); - } - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Get Blob Tags operation enables users to get tags on a blob. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.getTags")] + // pub async fn get_tags( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "tags"); + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Get); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// If the storage account's soft delete feature is disabled then, when a blob is deleted, it is permanently removed from - /// the storage account. If the storage account's soft delete feature is enabled, then, when a blob is deleted, it is marked - /// for deletion and becomes inaccessible immediately. However, the blob service retains the blob or snapshot for the number - /// of days specified by the DeleteRetentionPolicy section of [Storage service properties] (Set-Blob-Service-Properties.md). - /// After the specified number of days has passed, the blob's data is permanently removed from the storage account. Note that - /// you continue to be charged for the soft-deleted blob's storage until it is permanently removed. Use the List Blobs API - /// and specify the \"include=deleted\" query parameter to discover which blobs and snapshots have been soft deleted. You - /// can then use the Undelete Blob API to restore a soft-deleted blob. All other operations on a soft-deleted blob or snapshot - /// causes the service to return an HTTP status code of 404 (ResourceNotFound). - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.delete")] - pub async fn delete( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - if let Some(blob_delete_type) = options.blob_delete_type { - url.query_pairs_mut() - .append_pair("deletetype", blob_delete_type.as_ref()); - } - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Delete); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(delete_snapshots) = options.delete_snapshots { - request.insert_header("x-ms-delete-snapshots", delete_snapshots.to_string()); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Release Lease operation frees the lease if it's no longer needed, so that another client can immediately acquire a + // /// lease against the blob. + // /// + // /// # Arguments + // /// + // /// * `lease_id` - Required. A lease ID for the source path. If specified, the source path must have an active lease and the + // /// lease ID must match. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.releaseLease")] + // pub async fn release_lease( + // &self, + // lease_id: String, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_pair("comp", "lease") + // .append_key_only("release"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // request.insert_header("x-ms-lease-action", "release"); + // request.insert_header("x-ms-lease-id", lease_id); + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Delete Immutability Policy operation deletes the immutability policy on the blob. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.deleteImmutabilityPolicy")] - pub async fn delete_immutability_policy( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_pair("comp", "immutabilityPolicies"); - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Delete); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Renew Lease operation renews an existing lease. + // /// + // /// # Arguments + // /// + // /// * `lease_id` - Required. A lease ID for the source path. If specified, the source path must have an active lease and the + // /// lease ID must match. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.renewLease")] + // pub async fn renew_lease( + // &self, + // lease_id: String, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_pair("comp", "lease") + // .append_key_only("renew"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // request.insert_header("x-ms-lease-action", "renew"); + // request.insert_header("x-ms-lease-id", lease_id); + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Download operation reads or downloads a blob from the system, including its metadata and properties. You can also - /// call Download to read a snapshot. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.download")] - pub async fn download( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Get); - request.insert_header("accept", "application/octet-stream"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(range) = options.range { - request.insert_header("range", range); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(encryption_algorithm) = options.encryption_algorithm { - request.insert_header( - "x-ms-encryption-algorithm", - encryption_algorithm.to_string(), - ); - } - if let Some(encryption_key) = options.encryption_key { - request.insert_header("x-ms-encryption-key", encryption_key); - } - if let Some(encryption_key_sha256) = options.encryption_key_sha256 { - request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - if let Some(range_get_content_crc64) = options.range_get_content_crc64 { - request.insert_header( - "x-ms-range-get-content-crc64", - range_get_content_crc64.to_string(), - ); - } - if let Some(range_get_content_md5) = options.range_get_content_md5 { - request.insert_header( - "x-ms-range-get-content-md5", - range_get_content_md5.to_string(), - ); - } - if let Some(structured_body_type) = options.structured_body_type { - request.insert_header("x-ms-structured-body", structured_body_type); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// Set the expiration time of a blob + // /// + // /// # Arguments + // /// + // /// * `expiry_options` - Required. Indicates mode of the expiry time + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setExpiry")] + // pub async fn set_expiry( + // &self, + // expiry_options: BlobExpiryOptions, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "expiry"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-expiry-option", expiry_options.to_string()); + // if let Some(expires_on) = options.expires_on { + // request.insert_header("x-ms-expiry-time", to_rfc7231(&expires_on)); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// Returns the sku name and account kind - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.getAccountInfo")] - pub async fn get_account_info( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_key_only("blob") - .append_pair("comp", "properties") - .append_pair("restype", "account"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Get); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// Set the immutability policy of a blob + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setImmutabilityPolicy")] + // pub async fn set_immutability_policy( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_pair("comp", "immutabilityPolicies"); + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(immutability_policy_mode) = options.immutability_policy_mode { + // request.insert_header( + // "x-ms-immutability-policy-mode", + // immutability_policy_mode.to_string(), + // ); + // } + // if let Some(immutability_policy_expiry) = options.immutability_policy_expiry { + // request.insert_header( + // "x-ms-immutability-policy-until-date", + // to_rfc7231(&immutability_policy_expiry), + // ); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// Returns a new instance of AppendBlobClient. - #[tracing::subclient] - pub fn get_append_blob_client(&self) -> AppendBlobClient { - AppendBlobClient { - blob_name: self.blob_name.clone(), - container_name: self.container_name.clone(), - endpoint: self.endpoint.clone(), - pipeline: self.pipeline.clone(), - version: self.version.clone(), - } - } + // /// The Set Legal Hold operation sets a legal hold on the blob. + // /// + // /// # Arguments + // /// + // /// * `legal_hold` - Required. Specifies the legal hold status to set on the blob. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setLegalHold")] + // pub async fn set_legal_hold( + // &self, + // legal_hold: bool, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "legalhold"); + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-legal-hold", legal_hold.to_string()); + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// Returns a new instance of BlockBlobClient. - #[tracing::subclient] - pub fn get_block_blob_client(&self) -> BlockBlobClient { - BlockBlobClient { - blob_name: self.blob_name.clone(), - container_name: self.container_name.clone(), - endpoint: self.endpoint.clone(), - pipeline: self.pipeline.clone(), - version: self.version.clone(), - } - } + // /// The Set Metadata operation sets user-defined metadata for the specified blob as one or more name-value pairs. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setMetadata")] + // pub async fn set_metadata( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "metadata"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(encryption_algorithm) = options.encryption_algorithm { + // request.insert_header( + // "x-ms-encryption-algorithm", + // encryption_algorithm.to_string(), + // ); + // } + // if let Some(encryption_key) = options.encryption_key { + // request.insert_header("x-ms-encryption-key", encryption_key); + // } + // if let Some(encryption_key_sha256) = options.encryption_key_sha256 { + // request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); + // } + // if let Some(encryption_scope) = options.encryption_scope { + // request.insert_header("x-ms-encryption-scope", encryption_scope); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // if let Some(metadata) = options.metadata { + // for (k, v) in &metadata { + // request.insert_header(format!("x-ms-meta-{k}"), v); + // } + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// Returns a new instance of PageBlobClient. - #[tracing::subclient] - pub fn get_page_blob_client(&self) -> PageBlobClient { - PageBlobClient { - blob_name: self.blob_name.clone(), - container_name: self.container_name.clone(), - endpoint: self.endpoint.clone(), - pipeline: self.pipeline.clone(), - version: self.version.clone(), - } - } + // /// The Set HTTP Headers operation sets system properties on the blob. + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setProperties")] + // pub async fn set_properties( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut() + // .append_key_only("SetHTTPHeaders") + // .append_pair("comp", "properties"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(blob_cache_control) = options.blob_cache_control { + // request.insert_header("x-ms-blob-cache-control", blob_cache_control); + // } + // if let Some(blob_content_disposition) = options.blob_content_disposition { + // request.insert_header("x-ms-blob-content-disposition", blob_content_disposition); + // } + // if let Some(blob_content_encoding) = options.blob_content_encoding { + // request.insert_header("x-ms-blob-content-encoding", blob_content_encoding); + // } + // if let Some(blob_content_language) = options.blob_content_language { + // request.insert_header("x-ms-blob-content-language", blob_content_language); + // } + // if let Some(blob_content_md5) = options.blob_content_md5 { + // request.insert_header("x-ms-blob-content-md5", encode(blob_content_md5)); + // } + // if let Some(blob_content_type) = options.blob_content_type { + // request.insert_header("x-ms-blob-content-type", blob_content_type); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Get Properties operation returns all user-defined metadata, standard HTTP properties, and system properties for the - /// blob. It does not return the content of the blob. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.getProperties")] - pub async fn get_properties( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Head); - request.insert_header("accept", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(encryption_algorithm) = options.encryption_algorithm { - request.insert_header( - "x-ms-encryption-algorithm", - encryption_algorithm.to_string(), - ); - } - if let Some(encryption_key) = options.encryption_key { - request.insert_header("x-ms-encryption-key", encryption_key); - } - if let Some(encryption_key_sha256) = options.encryption_key_sha256 { - request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Get Blob Tags operation enables users to get tags on a blob. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.getTags")] - pub async fn get_tags( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "tags"); - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Get); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Release Lease operation frees the lease if it's no longer needed, so that another client can immediately acquire a - /// lease against the blob. - /// - /// # Arguments - /// - /// * `lease_id` - Required. A lease ID for the source path. If specified, the source path must have an active lease and the - /// lease ID must match. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.releaseLease")] - pub async fn release_lease( - &self, - lease_id: String, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_pair("comp", "lease") - .append_key_only("release"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - request.insert_header("x-ms-lease-action", "release"); - request.insert_header("x-ms-lease-id", lease_id); - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Renew Lease operation renews an existing lease. - /// - /// # Arguments - /// - /// * `lease_id` - Required. A lease ID for the source path. If specified, the source path must have an active lease and the - /// lease ID must match. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.renewLease")] - pub async fn renew_lease( - &self, - lease_id: String, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_pair("comp", "lease") - .append_key_only("renew"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - request.insert_header("x-ms-lease-action", "renew"); - request.insert_header("x-ms-lease-id", lease_id); - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// Set the expiration time of a blob - /// - /// # Arguments - /// - /// * `expiry_options` - Required. Indicates mode of the expiry time - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setExpiry")] - pub async fn set_expiry( - &self, - expiry_options: BlobExpiryOptions, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "expiry"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-expiry-option", expiry_options.to_string()); - if let Some(expires_on) = options.expires_on { - request.insert_header("x-ms-expiry-time", to_rfc7231(&expires_on)); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// Set the immutability policy of a blob - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setImmutabilityPolicy")] - pub async fn set_immutability_policy( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_pair("comp", "immutabilityPolicies"); - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(immutability_policy_mode) = options.immutability_policy_mode { - request.insert_header( - "x-ms-immutability-policy-mode", - immutability_policy_mode.to_string(), - ); - } - if let Some(immutability_policy_expiry) = options.immutability_policy_expiry { - request.insert_header( - "x-ms-immutability-policy-until-date", - to_rfc7231(&immutability_policy_expiry), - ); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Set Legal Hold operation sets a legal hold on the blob. - /// - /// # Arguments - /// - /// * `legal_hold` - Required. Specifies the legal hold status to set on the blob. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setLegalHold")] - pub async fn set_legal_hold( - &self, - legal_hold: bool, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "legalhold"); - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-legal-hold", legal_hold.to_string()); - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Set Metadata operation sets user-defined metadata for the specified blob as one or more name-value pairs. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setMetadata")] - pub async fn set_metadata( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "metadata"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(encryption_algorithm) = options.encryption_algorithm { - request.insert_header( - "x-ms-encryption-algorithm", - encryption_algorithm.to_string(), - ); - } - if let Some(encryption_key) = options.encryption_key { - request.insert_header("x-ms-encryption-key", encryption_key); - } - if let Some(encryption_key_sha256) = options.encryption_key_sha256 { - request.insert_header("x-ms-encryption-key-sha256", encryption_key_sha256); - } - if let Some(encryption_scope) = options.encryption_scope { - request.insert_header("x-ms-encryption-scope", encryption_scope); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - if let Some(metadata) = options.metadata { - for (k, v) in &metadata { - request.insert_header(format!("x-ms-meta-{k}"), v); - } - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Set HTTP Headers operation sets system properties on the blob. - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setProperties")] - pub async fn set_properties( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut() - .append_key_only("SetHTTPHeaders") - .append_pair("comp", "properties"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(blob_cache_control) = options.blob_cache_control { - request.insert_header("x-ms-blob-cache-control", blob_cache_control); - } - if let Some(blob_content_disposition) = options.blob_content_disposition { - request.insert_header("x-ms-blob-content-disposition", blob_content_disposition); - } - if let Some(blob_content_encoding) = options.blob_content_encoding { - request.insert_header("x-ms-blob-content-encoding", blob_content_encoding); - } - if let Some(blob_content_language) = options.blob_content_language { - request.insert_header("x-ms-blob-content-language", blob_content_language); - } - if let Some(blob_content_md5) = options.blob_content_md5 { - request.insert_header("x-ms-blob-content-md5", encode(blob_content_md5)); - } - if let Some(blob_content_type) = options.blob_content_type { - request.insert_header("x-ms-blob-content-type", blob_content_type); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } - - /// The Set Tags operation enables users to set tags on a blob. - /// - /// # Arguments - /// - /// * `tags` - The blob tags. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setTags")] - pub async fn set_tags( - &self, - tags: RequestContent, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "tags"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - if let Some(transactional_content_md5) = options.transactional_content_md5 { - request.insert_header("content-md5", encode(transactional_content_md5)); - } - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(transactional_content_crc64) = options.transactional_content_crc64 { - request.insert_header("x-ms-content-crc64", encode(transactional_content_crc64)); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - request.insert_header("x-ms-version", &self.version); - request.set_body(tags); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Set Tags operation enables users to set tags on a blob. + // /// + // /// # Arguments + // /// + // /// * `tags` - The blob tags. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setTags")] + // pub async fn set_tags( + // &self, + // tags: RequestContent, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "tags"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // if let Some(transactional_content_md5) = options.transactional_content_md5 { + // request.insert_header("content-md5", encode(transactional_content_md5)); + // } + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(transactional_content_crc64) = options.transactional_content_crc64 { + // request.insert_header("x-ms-content-crc64", encode(transactional_content_crc64)); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // request.insert_header("x-ms-version", &self.version); + // request.set_body(tags); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Set Tier operation sets the tier on a block blob. The operation is allowed on a page blob or block blob, but not on - /// an append blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not update the blob's - /// ETag. - /// - /// # Arguments - /// - /// * `tier` - Indicates the tier to be set on the blob. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.setTier")] - pub async fn set_tier( - &self, - tier: AccessTier, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "tier"); - if let Some(snapshot) = options.snapshot { - url.query_pairs_mut().append_pair("snapshot", &snapshot); - } - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - if let Some(version_id) = options.version_id { - url.query_pairs_mut().append_pair("versionid", &version_id); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - request.insert_header("x-ms-access-tier", tier.to_string()); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - if let Some(rehydrate_priority) = options.rehydrate_priority { - request.insert_header("x-ms-rehydrate-priority", rehydrate_priority.to_string()); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Set Tier operation sets the tier on a block blob. The operation is allowed on a page blob or block blob, but not on + // /// an append blob. A block blob's tier determines Hot/Cool/Archive storage type. This operation does not update the blob's + // /// ETag. + // /// + // /// # Arguments + // /// + // /// * `tier` - Indicates the tier to be set on the blob. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.setTier")] + // pub async fn set_tier( + // &self, + // tier: AccessTier, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "tier"); + // if let Some(snapshot) = options.snapshot { + // url.query_pairs_mut().append_pair("snapshot", &snapshot); + // } + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // if let Some(version_id) = options.version_id { + // url.query_pairs_mut().append_pair("versionid", &version_id); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // request.insert_header("x-ms-access-tier", tier.to_string()); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // if let Some(rehydrate_priority) = options.rehydrate_priority { + // request.insert_header("x-ms-rehydrate-priority", rehydrate_priority.to_string()); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// The Start Copy From URL operation copies a blob or an internet resource to a new blob. - /// - /// # Arguments - /// - /// * `copy_source` - Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that - /// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must - /// either be public or must be authenticated via a shared access signature. - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.startCopyFromUrl")] - pub async fn start_copy_from_url( - &self, - copy_source: String, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(if_match) = options.if_match { - request.insert_header("if-match", if_match); - } - if let Some(if_modified_since) = options.if_modified_since { - request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); - } - if let Some(if_none_match) = options.if_none_match { - request.insert_header("if-none-match", if_none_match); - } - if let Some(if_unmodified_since) = options.if_unmodified_since { - request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); - } - if let Some(tier) = options.tier { - request.insert_header("x-ms-access-tier", tier.to_string()); - } - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-copy-source", copy_source); - if let Some(if_tags) = options.if_tags { - request.insert_header("x-ms-if-tags", if_tags); - } - if let Some(immutability_policy_mode) = options.immutability_policy_mode { - request.insert_header( - "x-ms-immutability-policy-mode", - immutability_policy_mode.to_string(), - ); - } - if let Some(immutability_policy_expiry) = options.immutability_policy_expiry { - request.insert_header( - "x-ms-immutability-policy-until-date", - to_rfc7231(&immutability_policy_expiry), - ); - } - if let Some(lease_id) = options.lease_id { - request.insert_header("x-ms-lease-id", lease_id); - } - if let Some(legal_hold) = options.legal_hold { - request.insert_header("x-ms-legal-hold", legal_hold.to_string()); - } - if let Some(metadata) = options.metadata { - for (k, v) in &metadata { - request.insert_header(format!("x-ms-meta-{k}"), v); - } - } - if let Some(rehydrate_priority) = options.rehydrate_priority { - request.insert_header("x-ms-rehydrate-priority", rehydrate_priority.to_string()); - } - request.insert_header("x-ms-requires-sync", "true"); - if let Some(seal_blob) = options.seal_blob { - request.insert_header("x-ms-seal-blob", seal_blob.to_string()); - } - if let Some(source_if_match) = options.source_if_match { - request.insert_header("x-ms-source-if-match", source_if_match); - } - if let Some(source_if_modified_since) = options.source_if_modified_since { - request.insert_header( - "x-ms-source-if-modified-since", - to_rfc7231(&source_if_modified_since), - ); - } - if let Some(source_if_none_match) = options.source_if_none_match { - request.insert_header("x-ms-source-if-none-match", source_if_none_match); - } - if let Some(source_if_tags) = options.source_if_tags { - request.insert_header("x-ms-source-if-tags", source_if_tags); - } - if let Some(source_if_unmodified_since) = options.source_if_unmodified_since { - request.insert_header( - "x-ms-source-if-unmodified-since", - to_rfc7231(&source_if_unmodified_since), - ); - } - if let Some(blob_tags_string) = options.blob_tags_string { - request.insert_header("x-ms-tags", blob_tags_string); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// The Start Copy From URL operation copies a blob or an internet resource to a new blob. + // /// + // /// # Arguments + // /// + // /// * `copy_source` - Specifies the name of the source page blob snapshot. This value is a URL of up to 2 KB in length that + // /// specifies a page blob snapshot. The value should be URL-encoded as it would appear in a request URI. The source blob must + // /// either be public or must be authenticated via a shared access signature. + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.startCopyFromUrl")] + // pub async fn start_copy_from_url( + // &self, + // copy_source: String, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(if_match) = options.if_match { + // request.insert_header("if-match", if_match); + // } + // if let Some(if_modified_since) = options.if_modified_since { + // request.insert_header("if-modified-since", to_rfc7231(&if_modified_since)); + // } + // if let Some(if_none_match) = options.if_none_match { + // request.insert_header("if-none-match", if_none_match); + // } + // if let Some(if_unmodified_since) = options.if_unmodified_since { + // request.insert_header("if-unmodified-since", to_rfc7231(&if_unmodified_since)); + // } + // if let Some(tier) = options.tier { + // request.insert_header("x-ms-access-tier", tier.to_string()); + // } + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-copy-source", copy_source); + // if let Some(if_tags) = options.if_tags { + // request.insert_header("x-ms-if-tags", if_tags); + // } + // if let Some(immutability_policy_mode) = options.immutability_policy_mode { + // request.insert_header( + // "x-ms-immutability-policy-mode", + // immutability_policy_mode.to_string(), + // ); + // } + // if let Some(immutability_policy_expiry) = options.immutability_policy_expiry { + // request.insert_header( + // "x-ms-immutability-policy-until-date", + // to_rfc7231(&immutability_policy_expiry), + // ); + // } + // if let Some(lease_id) = options.lease_id { + // request.insert_header("x-ms-lease-id", lease_id); + // } + // if let Some(legal_hold) = options.legal_hold { + // request.insert_header("x-ms-legal-hold", legal_hold.to_string()); + // } + // if let Some(metadata) = options.metadata { + // for (k, v) in &metadata { + // request.insert_header(format!("x-ms-meta-{k}"), v); + // } + // } + // if let Some(rehydrate_priority) = options.rehydrate_priority { + // request.insert_header("x-ms-rehydrate-priority", rehydrate_priority.to_string()); + // } + // request.insert_header("x-ms-requires-sync", "true"); + // if let Some(seal_blob) = options.seal_blob { + // request.insert_header("x-ms-seal-blob", seal_blob.to_string()); + // } + // if let Some(source_if_match) = options.source_if_match { + // request.insert_header("x-ms-source-if-match", source_if_match); + // } + // if let Some(source_if_modified_since) = options.source_if_modified_since { + // request.insert_header( + // "x-ms-source-if-modified-since", + // to_rfc7231(&source_if_modified_since), + // ); + // } + // if let Some(source_if_none_match) = options.source_if_none_match { + // request.insert_header("x-ms-source-if-none-match", source_if_none_match); + // } + // if let Some(source_if_tags) = options.source_if_tags { + // request.insert_header("x-ms-source-if-tags", source_if_tags); + // } + // if let Some(source_if_unmodified_since) = options.source_if_unmodified_since { + // request.insert_header( + // "x-ms-source-if-unmodified-since", + // to_rfc7231(&source_if_unmodified_since), + // ); + // } + // if let Some(blob_tags_string) = options.blob_tags_string { + // request.insert_header("x-ms-tags", blob_tags_string); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } - /// Undelete a blob that was previously soft deleted - /// - /// # Arguments - /// - /// * `options` - Optional parameters for the request. - #[tracing::function("Storage.Blob.Container.Blob.undelete")] - pub async fn undelete( - &self, - options: Option>, - ) -> Result> { - let options = options.unwrap_or_default(); - let ctx = Context::with_context(&options.method_options.context); - let mut url = self.endpoint.clone(); - let mut path = String::from("{containerName}/{blobName}"); - path = path.replace("{blobName}", &self.blob_name); - path = path.replace("{containerName}", &self.container_name); - url = url.join(&path)?; - url.query_pairs_mut().append_pair("comp", "undelete"); - if let Some(timeout) = options.timeout { - url.query_pairs_mut() - .append_pair("timeout", &timeout.to_string()); - } - let mut request = Request::new(url, Method::Put); - request.insert_header("accept", "application/xml"); - request.insert_header("content-type", "application/xml"); - if let Some(client_request_id) = options.client_request_id { - request.insert_header("x-ms-client-request-id", client_request_id); - } - request.insert_header("x-ms-version", &self.version); - let rsp = self.pipeline.send(&ctx, &mut request).await?; - if !rsp.status().is_success() { - let status = rsp.status(); - let http_error = HttpError::new(rsp).await; - let error_kind = ErrorKind::http_response( - status, - http_error.error_code().map(std::borrow::ToOwned::to_owned), - ); - return Err(Error::new(error_kind, http_error)); - } - Ok(rsp.into()) - } + // /// Undelete a blob that was previously soft deleted + // /// + // /// # Arguments + // /// + // /// * `options` - Optional parameters for the request. + // #[tracing::function("Storage.Blob.Container.Blob.undelete")] + // pub async fn undelete( + // &self, + // options: Option>, + // ) -> Result> { + // let options = options.unwrap_or_default(); + // let ctx = Context::with_context(&options.method_options.context); + // let mut url = self.endpoint.clone(); + // let mut path = String::from("{containerName}/{blobName}"); + // path = path.replace("{blobName}", &self.blob_name); + // path = path.replace("{containerName}", &self.container_name); + // url = url.join(&path)?; + // url.query_pairs_mut().append_pair("comp", "undelete"); + // if let Some(timeout) = options.timeout { + // url.query_pairs_mut() + // .append_pair("timeout", &timeout.to_string()); + // } + // let mut request = Request::new(url, Method::Put); + // request.insert_header("accept", "application/xml"); + // request.insert_header("content-type", "application/xml"); + // if let Some(client_request_id) = options.client_request_id { + // request.insert_header("x-ms-client-request-id", client_request_id); + // } + // request.insert_header("x-ms-version", &self.version); + // let rsp = self.pipeline.send(&ctx, &mut request).await?; + // if !rsp.status().is_success() { + // let status = rsp.status(); + // let http_error = HttpError::new(rsp).await; + // let error_kind = ErrorKind::http_response( + // status, + // http_error.error_code().map(std::borrow::ToOwned::to_owned), + // ); + // return Err(Error::new(error_kind, http_error)); + // } + // Ok(rsp.into()) + // } } impl Default for BlobClientOptions { diff --git a/sdk/storage/azure_storage_blob/src/generated/clients/blob_container_client.rs b/sdk/storage/azure_storage_blob/src/generated/clients/blob_container_client.rs index 0871c272cd..c1883a1b24 100644 --- a/sdk/storage/azure_storage_blob/src/generated/clients/blob_container_client.rs +++ b/sdk/storage/azure_storage_blob/src/generated/clients/blob_container_client.rs @@ -527,16 +527,16 @@ impl BlobContainerClient { /// # Arguments /// /// * `blob_name` - The name of the blob. - #[tracing::subclient] - pub fn get_blob_client(&self, blob_name: String) -> BlobClient { - BlobClient { - blob_name, - container_name: self.container_name.clone(), - endpoint: self.endpoint.clone(), - pipeline: self.pipeline.clone(), - version: self.version.clone(), - } - } + // #[tracing::subclient] + // pub fn get_blob_client(&self, blob_name: String) -> BlobClient { + // BlobClient { + // blob_name, + // container_name: self.container_name.clone(), + // endpoint: self.endpoint.clone(), + // pipeline: self.pipeline.clone(), + // version: self.version.clone(), + // } + // } /// returns all user-defined metadata and system properties for the specified container. The data returned does not include /// the container's list of blobs diff --git a/sdk/storage/azure_storage_blob/src/lib.rs b/sdk/storage/azure_storage_blob/src/lib.rs index f223b2af46..df52630559 100644 --- a/sdk/storage/azure_storage_blob/src/lib.rs +++ b/sdk/storage/azure_storage_blob/src/lib.rs @@ -2,7 +2,6 @@ // // Licensed under the MIT License. See License.txt in the project root for license information. // Code generated by Microsoft (R) Rust Code Generator. DO NOT EDIT. - #![doc = include_str!("../README.md")] #![allow(dead_code)] #![allow(unused_imports)] diff --git a/sdk/storage/azure_storage_blob/tests/blob_client.rs b/sdk/storage/azure_storage_blob/tests/blob_client.rs index 5d5818b2f9..7792a67e02 100644 --- a/sdk/storage/azure_storage_blob/tests/blob_client.rs +++ b/sdk/storage/azure_storage_blob/tests/blob_client.rs @@ -6,420 +6,459 @@ use azure_core::{ Bytes, }; use azure_core_test::{recorded, TestContext}; -use azure_storage_blob::models::{ - AccessTier, BlobClientAcquireLeaseResultHeaders, BlobClientChangeLeaseResultHeaders, - BlobClientDownloadOptions, BlobClientDownloadResultHeaders, BlobClientGetPropertiesOptions, - BlobClientGetPropertiesResultHeaders, BlobClientSetMetadataOptions, - BlobClientSetPropertiesOptions, BlobClientSetTierOptions, BlockBlobClientUploadOptions, - LeaseState, +use azure_storage_blob::{ + models::{ + AccessTier, BlobClientAcquireLeaseResultHeaders, BlobClientChangeLeaseResultHeaders, + BlobClientDownloadOptions, BlobClientDownloadResultHeaders, BlobClientGetPropertiesOptions, + BlobClientGetPropertiesResultHeaders, BlobClientSetMetadataOptions, + BlobClientSetPropertiesOptions, BlobClientSetTierOptions, BlockBlobClientUploadOptions, + LeaseState, + }, + BlobClient, }; -use azure_storage_blob_test::{create_test_blob, get_blob_name, get_container_client}; +// use azure_storage_blob_test::{create_test_blob, get_blob_name, get_container_client}; use std::{collections::HashMap, error::Error, time::Duration}; use tokio::time; -#[recorded::test] -async fn test_get_blob_properties(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, false).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - - // Invalid Container Scenario - let response = blob_client.get_properties(None).await; - - // Assert - let error = response.unwrap_err().http_status(); - assert_eq!(StatusCode::NotFound, error.unwrap()); - - container_client.create_container(None).await?; - create_test_blob(&blob_client).await?; - - // No Option Scenario - let response = blob_client.get_properties(None).await?; - - // Assert - let lease_state = response.lease_state()?; - let content_length = response.content_length()?; - let etag = response.etag()?; - let creation_time = response.creation_time()?; - - assert_eq!(LeaseState::Available, lease_state.unwrap()); - assert_eq!(17, content_length.unwrap()); - assert!(etag.is_some()); - assert!(creation_time.is_some()); - - container_client.delete_container(None).await?; - Ok(()) -} +// #[recorded::test] +// async fn test_get_blob_properties(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, false).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); + +// // Invalid Container Scenario +// let response = blob_client.get_properties(None).await; + +// // Assert +// let error = response.unwrap_err().http_status(); +// assert_eq!(StatusCode::NotFound, error.unwrap()); + +// container_client.create_container(None).await?; +// create_test_blob(&blob_client).await?; + +// // No Option Scenario +// let response = blob_client.get_properties(None).await?; + +// // Assert +// let lease_state = response.lease_state()?; +// let content_length = response.content_length()?; +// let etag = response.etag()?; +// let creation_time = response.creation_time()?; + +// assert_eq!(LeaseState::Available, lease_state.unwrap()); +// assert_eq!(17, content_length.unwrap()); +// assert!(etag.is_some()); +// assert!(creation_time.is_some()); + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_set_blob_properties(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); +// create_test_blob(&blob_client).await?; + +// // Set Content Settings +// let set_properties_options = BlobClientSetPropertiesOptions { +// blob_content_language: Some("spanish".to_string()), +// blob_content_disposition: Some("inline".to_string()), +// ..Default::default() +// }; +// blob_client +// .set_properties(Some(set_properties_options)) +// .await?; + +// // Assert +// let response = blob_client.get_properties(None).await?; +// let content_language = response.content_language()?; +// let content_disposition = response.content_disposition()?; + +// assert_eq!("spanish".to_string(), content_language.unwrap()); +// assert_eq!("inline".to_string(), content_disposition.unwrap()); + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_upload_blob(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); + +// let data = b"hello rusty world"; + +// // No Overwrite Scenario +// blob_client +// .upload( +// RequestContent::from(data.to_vec()), +// false, +// u64::try_from(data.len())?, +// None, +// ) +// .await?; + +// // Assert +// let response = blob_client.download(None).await?; +// let content_length = response.content_length()?; +// let (status_code, _, response_body) = response.deconstruct(); +// assert!(status_code.is_success()); +// assert_eq!(17, content_length.unwrap()); +// assert_eq!(Bytes::from_static(data), response_body.collect().await?); + +// // Overwrite Scenarios +// let new_data = b"hello overwritten rusty world"; + +// // Error Case (overwrite=false/none) +// let response = blob_client +// .upload( +// RequestContent::from(new_data.to_vec()), +// false, +// u64::try_from(new_data.len())?, +// None, +// ) +// .await; + +// // Assert +// assert!(response.is_err()); +// let error = response.unwrap_err().http_status(); +// assert_eq!(StatusCode::Conflict, error.unwrap()); + +// // Working Case (overwrite=true) +// let overwrite_response = blob_client +// .upload( +// RequestContent::from(new_data.to_vec()), +// true, +// u64::try_from(new_data.len())?, +// None, +// ) +// .await?; +// let response = blob_client.download(None).await?; +// let content_length = response.content_length()?; + +// // Assert +// assert_eq!(overwrite_response.status(), StatusCode::Created); +// let (status_code, _, response_body) = response.deconstruct(); +// assert!(status_code.is_success()); +// assert_eq!(29, content_length.unwrap()); +// assert_eq!(Bytes::from_static(new_data), response_body.collect().await?); + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_delete_blob(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); +// create_test_blob(&blob_client).await?; + +// // Existence Check +// blob_client.get_properties(None).await?; + +// blob_client.delete(None).await?; + +// let response = blob_client.download(None).await; + +// // Assert +// let error = response.unwrap_err().http_status(); +// assert_eq!(StatusCode::NotFound, error.unwrap()); + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_download_blob(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); +// let data = b"hello rusty world"; + +// blob_client +// .upload( +// RequestContent::from(data.to_vec()), +// false, +// u64::try_from(data.len())?, +// None, +// ) +// .await?; +// let response = blob_client.download(None).await?; + +// // Assert +// let content_length = response.content_length()?; +// let (status_code, _, response_body) = response.deconstruct(); +// assert!(status_code.is_success()); +// assert_eq!(17, content_length.unwrap()); +// assert_eq!( +// b"hello rusty world".to_vec(), +// response_body.collect().await? +// ); + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_set_blob_metadata(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup + +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); +// let data = b"hello rusty world"; + +// // Upload Blob With Metadata +// let initial_metadata = HashMap::from([("initial".to_string(), "metadata".to_string())]); + +// let options_with_metadata = BlockBlobClientUploadOptions { +// metadata: Some(initial_metadata.clone()), +// ..Default::default() +// }; +// blob_client +// .upload( +// RequestContent::from(data.to_vec()), +// false, +// u64::try_from(data.len())?, +// Some(options_with_metadata), +// ) +// .await?; +// // Assert +// let response = blob_client.get_properties(None).await?; +// let response_metadata = response.metadata()?; +// assert_eq!(initial_metadata, response_metadata); + +// // Set Metadata With Values +// let update_metadata = HashMap::from([("updated".to_string(), "values".to_string())]); +// let set_metadata_options = BlobClientSetMetadataOptions { +// metadata: Some(update_metadata.clone()), +// ..Default::default() +// }; +// blob_client.set_metadata(Some(set_metadata_options)).await?; +// // Assert +// let response = blob_client.get_properties(None).await?; +// let response_metadata = response.metadata()?; +// assert_eq!(update_metadata, response_metadata); + +// // Set Metadata No Values (Clear Metadata) +// blob_client.set_metadata(None).await?; +// // Assert +// let response = blob_client.get_properties(None).await?; +// let response_metadata = response.metadata()?; +// assert_eq!(HashMap::new(), response_metadata); + +// Ok(()) +// } + +// #[recorded::test] +// async fn test_set_access_tier(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_client = container_client.blob_client(get_blob_name(recording)); +// create_test_blob(&blob_client).await?; + +// let original_response = blob_client.get_properties(None).await?; +// let og_access_tier = original_response.access_tier()?; +// assert_eq!(AccessTier::Hot.to_string(), og_access_tier.unwrap()); + +// // Set Standard Blob Tier (Cold) +// blob_client.set_tier(AccessTier::Cold, None).await?; +// let response = blob_client.get_properties(None).await?; + +// // Assert +// let access_tier = response.access_tier()?; +// assert_eq!(AccessTier::Cold.to_string(), access_tier.unwrap()); + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_blob_lease_operations(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_name = get_blob_name(recording); +// let blob_client = container_client.blob_client(blob_name.clone()); +// let other_blob_client = container_client.blob_client(blob_name); +// create_test_blob(&blob_client).await?; + +// // Acquire Lease +// let acquire_response = blob_client.acquire_lease(15, None).await?; +// let lease_id = acquire_response.lease_id()?.unwrap(); +// let other_acquire_response = other_blob_client.acquire_lease(15, None).await; +// // Assert +// let error = other_acquire_response.unwrap_err().http_status(); +// assert_eq!(StatusCode::Conflict, error.unwrap()); + +// // Change Lease +// let proposed_lease_id = "00000000-1111-2222-3333-444444444444".to_string(); +// let change_lease_response = blob_client +// .change_lease(lease_id, proposed_lease_id.clone(), None) +// .await?; +// // Assert +// let lease_id = change_lease_response.lease_id()?.unwrap(); +// assert_eq!(proposed_lease_id.clone().to_string(), lease_id); + +// // Sleep until lease expires +// time::sleep(Duration::from_secs(15)).await; + +// // Renew Lease +// blob_client +// .renew_lease(proposed_lease_id.clone(), None) +// .await?; +// let other_acquire_response = other_blob_client.acquire_lease(15, None).await; +// // Assert +// let error = other_acquire_response.unwrap_err().http_status(); +// assert_eq!(StatusCode::Conflict, error.unwrap()); + +// // Break Lease +// blob_client.break_lease(None).await?; +// let other_acquire_response = other_blob_client.acquire_lease(15, None).await; +// // Assert +// let error = other_acquire_response.unwrap_err().http_status(); +// assert_eq!(StatusCode::Conflict, error.unwrap()); + +// // Release Lease +// blob_client +// .release_lease(proposed_lease_id.clone(), None) +// .await?; +// other_blob_client.acquire_lease(15, None).await?; + +// container_client.delete_container(None).await?; +// Ok(()) +// } + +// #[recorded::test] +// async fn test_leased_blob_operations(ctx: TestContext) -> Result<(), Box> { +// // Recording Setup +// let recording = ctx.recording(); +// let container_client = get_container_client(recording, true).await?; +// let blob_name = get_blob_name(recording); +// let blob_client = container_client.blob_client(blob_name.clone()); +// create_test_blob(&blob_client).await?; +// let acquire_response = blob_client.acquire_lease(-1, None).await?; +// let lease_id = acquire_response.lease_id()?.unwrap(); + +// // Set Properties, Set Metadata, Set Access Tier +// let set_properties_options = BlobClientSetPropertiesOptions { +// blob_content_language: Some("spanish".to_string()), +// blob_content_disposition: Some("inline".to_string()), +// lease_id: Some(lease_id.clone()), +// ..Default::default() +// }; +// blob_client +// .set_properties(Some(set_properties_options)) +// .await?; + +// let update_metadata = HashMap::from([("updated".to_string(), "values".to_string())]); +// let set_metadata_options = BlobClientSetMetadataOptions { +// metadata: Some(update_metadata.clone()), +// lease_id: Some(lease_id.clone()), +// ..Default::default() +// }; +// blob_client.set_metadata(Some(set_metadata_options)).await?; + +// let set_tier_options = BlobClientSetTierOptions { +// lease_id: Some(lease_id.clone()), +// ..Default::default() +// }; +// blob_client +// .set_tier(AccessTier::Cold, Some(set_tier_options)) +// .await?; + +// // Assert +// let get_properties_options = BlobClientGetPropertiesOptions { +// lease_id: Some(lease_id.clone()), +// ..Default::default() +// }; +// let response = blob_client +// .get_properties(Some(get_properties_options)) +// .await?; +// let content_language = response.content_language()?; +// let content_disposition = response.content_disposition()?; +// let response_metadata = response.metadata()?; +// let access_tier = response.access_tier()?; + +// assert_eq!("spanish".to_string(), content_language.unwrap()); +// assert_eq!("inline".to_string(), content_disposition.unwrap()); +// assert_eq!(update_metadata, response_metadata); +// assert_eq!(AccessTier::Cold.to_string(), access_tier.unwrap()); + +// // Overwrite Upload +// let data = b"overruled!"; +// let upload_options = BlockBlobClientUploadOptions { +// lease_id: Some(lease_id.clone()), +// ..Default::default() +// }; +// blob_client +// .upload( +// RequestContent::from(data.to_vec()), +// true, +// u64::try_from(data.len())?, +// Some(upload_options), +// ) +// .await?; + +// // Assert +// let download_options = BlobClientDownloadOptions { +// lease_id: Some(lease_id.clone()), +// ..Default::default() +// }; +// let response = blob_client.download(Some(download_options)).await?; +// let content_length = response.content_length()?; +// let (status_code, _, response_body) = response.deconstruct(); +// assert!(status_code.is_success()); +// assert_eq!(10, content_length.unwrap()); +// assert_eq!(data.to_vec(), response_body.collect().await?); + +// blob_client.break_lease(None).await?; +// container_client.delete_container(None).await?; +// Ok(()) +// } #[recorded::test] -async fn test_set_blob_properties(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - create_test_blob(&blob_client).await?; - - // Set Content Settings - let set_properties_options = BlobClientSetPropertiesOptions { - blob_content_language: Some("spanish".to_string()), - blob_content_disposition: Some("inline".to_string()), - ..Default::default() - }; - blob_client - .set_properties(Some(set_properties_options)) - .await?; - - // Assert - let response = blob_client.get_properties(None).await?; - let content_language = response.content_language()?; - let content_disposition = response.content_disposition()?; - - assert_eq!("spanish".to_string(), content_language.unwrap()); - assert_eq!("inline".to_string(), content_disposition.unwrap()); - - container_client.delete_container(None).await?; - Ok(()) -} - -#[recorded::test] -async fn test_upload_blob(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - - let data = b"hello rusty world"; - - // No Overwrite Scenario - blob_client - .upload( - RequestContent::from(data.to_vec()), - false, - u64::try_from(data.len())?, - None, - ) - .await?; - - // Assert - let response = blob_client.download(None).await?; - let content_length = response.content_length()?; - let (status_code, _, response_body) = response.deconstruct(); - assert!(status_code.is_success()); - assert_eq!(17, content_length.unwrap()); - assert_eq!(Bytes::from_static(data), response_body.collect().await?); - - // Overwrite Scenarios - let new_data = b"hello overwritten rusty world"; - - // Error Case (overwrite=false/none) - let response = blob_client - .upload( - RequestContent::from(new_data.to_vec()), - false, - u64::try_from(new_data.len())?, - None, - ) - .await; - - // Assert - assert!(response.is_err()); - let error = response.unwrap_err().http_status(); - assert_eq!(StatusCode::Conflict, error.unwrap()); - - // Working Case (overwrite=true) - let overwrite_response = blob_client - .upload( - RequestContent::from(new_data.to_vec()), - true, - u64::try_from(new_data.len())?, - None, - ) - .await?; - let response = blob_client.download(None).await?; - let content_length = response.content_length()?; - - // Assert - assert_eq!(overwrite_response.status(), StatusCode::Created); - let (status_code, _, response_body) = response.deconstruct(); - assert!(status_code.is_success()); - assert_eq!(29, content_length.unwrap()); - assert_eq!(Bytes::from_static(new_data), response_body.collect().await?); - - container_client.delete_container(None).await?; - Ok(()) -} - -#[recorded::test] -async fn test_delete_blob(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - create_test_blob(&blob_client).await?; - - // Existence Check - blob_client.get_properties(None).await?; - - blob_client.delete(None).await?; - - let response = blob_client.download(None).await; +async fn test_sas(ctx: TestContext) -> Result<(), Box> { + // SAS + let blob_url = "SAS URL HERE"; - // Assert - let error = response.unwrap_err().http_status(); - assert_eq!(StatusCode::NotFound, error.unwrap()); + let sas_blob_client = BlobClient::from_blob_url(blob_url, None)?; - container_client.delete_container(None).await?; - Ok(()) -} - -#[recorded::test] -async fn test_download_blob(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - let data = b"hello rusty world"; - - blob_client - .upload( - RequestContent::from(data.to_vec()), - false, - u64::try_from(data.len())?, - None, - ) - .await?; - let response = blob_client.download(None).await?; - - // Assert - let content_length = response.content_length()?; - let (status_code, _, response_body) = response.deconstruct(); - assert!(status_code.is_success()); + let blob_properties = sas_blob_client.get_properties(None).await?; + let content_length = blob_properties.content_length()?; assert_eq!(17, content_length.unwrap()); - assert_eq!( - b"hello rusty world".to_vec(), - response_body.collect().await? - ); - - container_client.delete_container(None).await?; - Ok(()) -} - -#[recorded::test] -async fn test_set_blob_metadata(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - let data = b"hello rusty world"; - - // Upload Blob With Metadata - let initial_metadata = HashMap::from([("initial".to_string(), "metadata".to_string())]); - - let options_with_metadata = BlockBlobClientUploadOptions { - metadata: Some(initial_metadata.clone()), - ..Default::default() - }; - blob_client - .upload( - RequestContent::from(data.to_vec()), - false, - u64::try_from(data.len())?, - Some(options_with_metadata), - ) - .await?; - // Assert - let response = blob_client.get_properties(None).await?; - let response_metadata = response.metadata()?; - assert_eq!(initial_metadata, response_metadata); - - // Set Metadata With Values - let update_metadata = HashMap::from([("updated".to_string(), "values".to_string())]); - let set_metadata_options = BlobClientSetMetadataOptions { - metadata: Some(update_metadata.clone()), - ..Default::default() - }; - blob_client.set_metadata(Some(set_metadata_options)).await?; - // Assert - let response = blob_client.get_properties(None).await?; - let response_metadata = response.metadata()?; - assert_eq!(update_metadata, response_metadata); - - // Set Metadata No Values (Clear Metadata) - blob_client.set_metadata(None).await?; - // Assert - let response = blob_client.get_properties(None).await?; - let response_metadata = response.metadata()?; - assert_eq!(HashMap::new(), response_metadata); - - Ok(()) -} - -#[recorded::test] -async fn test_set_access_tier(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_client = container_client.blob_client(get_blob_name(recording)); - create_test_blob(&blob_client).await?; - - let original_response = blob_client.get_properties(None).await?; - let og_access_tier = original_response.access_tier()?; - assert_eq!(AccessTier::Hot.to_string(), og_access_tier.unwrap()); - - // Set Standard Blob Tier (Cold) - blob_client.set_tier(AccessTier::Cold, None).await?; - let response = blob_client.get_properties(None).await?; - // Assert - let access_tier = response.access_tier()?; - assert_eq!(AccessTier::Cold.to_string(), access_tier.unwrap()); - - container_client.delete_container(None).await?; Ok(()) } #[recorded::test] -async fn test_blob_lease_operations(ctx: TestContext) -> Result<(), Box> { - // Recording Setup +async fn test_regular(ctx: TestContext) -> Result<(), Box> { let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_name = get_blob_name(recording); - let blob_client = container_client.blob_client(blob_name.clone()); - let other_blob_client = container_client.blob_client(blob_name); - create_test_blob(&blob_client).await?; - - // Acquire Lease - let acquire_response = blob_client.acquire_lease(15, None).await?; - let lease_id = acquire_response.lease_id()?.unwrap(); - let other_acquire_response = other_blob_client.acquire_lease(15, None).await; - // Assert - let error = other_acquire_response.unwrap_err().http_status(); - assert_eq!(StatusCode::Conflict, error.unwrap()); - - // Change Lease - let proposed_lease_id = "00000000-1111-2222-3333-444444444444".to_string(); - let change_lease_response = blob_client - .change_lease(lease_id, proposed_lease_id.clone(), None) - .await?; - // Assert - let lease_id = change_lease_response.lease_id()?.unwrap(); - assert_eq!(proposed_lease_id.clone().to_string(), lease_id); - - // Sleep until lease expires - time::sleep(Duration::from_secs(15)).await; - - // Renew Lease - blob_client - .renew_lease(proposed_lease_id.clone(), None) - .await?; - let other_acquire_response = other_blob_client.acquire_lease(15, None).await; - // Assert - let error = other_acquire_response.unwrap_err().http_status(); - assert_eq!(StatusCode::Conflict, error.unwrap()); - - // Break Lease - blob_client.break_lease(None).await?; - let other_acquire_response = other_blob_client.acquire_lease(15, None).await; - // Assert - let error = other_acquire_response.unwrap_err().http_status(); - assert_eq!(StatusCode::Conflict, error.unwrap()); - - // Release Lease - blob_client - .release_lease(proposed_lease_id.clone(), None) - .await?; - other_blob_client.acquire_lease(15, None).await?; - - container_client.delete_container(None).await?; - Ok(()) -} + let endpoint = "https://ruststoragedev.blob.core.windows.net/"; + let container_name = "container0vgpjc2p"; + let blob_name = "blob1ear0rva"; + let credential = recording.credential(); + let blob_client = BlobClient::new( + endpoint, + container_name.into(), + blob_name.into(), + credential, + None, + )?; + + let blob_properties = blob_client.get_properties(None).await?; + let content_length = blob_properties.content_length()?; + assert_eq!(17, content_length.unwrap()); -#[recorded::test] -async fn test_leased_blob_operations(ctx: TestContext) -> Result<(), Box> { - // Recording Setup - let recording = ctx.recording(); - let container_client = get_container_client(recording, true).await?; - let blob_name = get_blob_name(recording); - let blob_client = container_client.blob_client(blob_name.clone()); - create_test_blob(&blob_client).await?; - let acquire_response = blob_client.acquire_lease(-1, None).await?; - let lease_id = acquire_response.lease_id()?.unwrap(); - - // Set Properties, Set Metadata, Set Access Tier - let set_properties_options = BlobClientSetPropertiesOptions { - blob_content_language: Some("spanish".to_string()), - blob_content_disposition: Some("inline".to_string()), - lease_id: Some(lease_id.clone()), - ..Default::default() - }; - blob_client - .set_properties(Some(set_properties_options)) - .await?; - - let update_metadata = HashMap::from([("updated".to_string(), "values".to_string())]); - let set_metadata_options = BlobClientSetMetadataOptions { - metadata: Some(update_metadata.clone()), - lease_id: Some(lease_id.clone()), - ..Default::default() - }; - blob_client.set_metadata(Some(set_metadata_options)).await?; - - let set_tier_options = BlobClientSetTierOptions { - lease_id: Some(lease_id.clone()), - ..Default::default() - }; - blob_client - .set_tier(AccessTier::Cold, Some(set_tier_options)) - .await?; - - // Assert - let get_properties_options = BlobClientGetPropertiesOptions { - lease_id: Some(lease_id.clone()), - ..Default::default() - }; - let response = blob_client - .get_properties(Some(get_properties_options)) - .await?; - let content_language = response.content_language()?; - let content_disposition = response.content_disposition()?; - let response_metadata = response.metadata()?; - let access_tier = response.access_tier()?; - - assert_eq!("spanish".to_string(), content_language.unwrap()); - assert_eq!("inline".to_string(), content_disposition.unwrap()); - assert_eq!(update_metadata, response_metadata); - assert_eq!(AccessTier::Cold.to_string(), access_tier.unwrap()); - - // Overwrite Upload - let data = b"overruled!"; - let upload_options = BlockBlobClientUploadOptions { - lease_id: Some(lease_id.clone()), - ..Default::default() - }; - blob_client - .upload( - RequestContent::from(data.to_vec()), - true, - u64::try_from(data.len())?, - Some(upload_options), - ) - .await?; - - // Assert - let download_options = BlobClientDownloadOptions { - lease_id: Some(lease_id.clone()), - ..Default::default() - }; - let response = blob_client.download(Some(download_options)).await?; - let content_length = response.content_length()?; - let (status_code, _, response_body) = response.deconstruct(); - assert!(status_code.is_success()); - assert_eq!(10, content_length.unwrap()); - assert_eq!(data.to_vec(), response_body.collect().await?); - - blob_client.break_lease(None).await?; - container_client.delete_container(None).await?; Ok(()) } diff --git a/sdk/storage/azure_storage_blob_test/src/lib.rs b/sdk/storage/azure_storage_blob_test/src/lib.rs index cb6b164896..edde841714 100644 --- a/sdk/storage/azure_storage_blob_test/src/lib.rs +++ b/sdk/storage/azure_storage_blob_test/src/lib.rs @@ -95,20 +95,20 @@ pub async fn get_container_client( Ok(container_client) } -/// Creates a test blob with no options, containing the data "b'hello rusty world'" with content length 17. -/// -/// # Arguments -/// -/// * `blob_client` - A reference to a BlobClient instance. -pub async fn create_test_blob( - blob_client: &BlobClient, -) -> Result> { - blob_client - .upload( - RequestContent::from(b"hello rusty world".to_vec()), - true, - 17, - None, - ) - .await -} +// / Creates a test blob with no options, containing the data "b'hello rusty world'" with content length 17. +// / +// / # Arguments +// / +// / * `blob_client` - A reference to a BlobClient instance. +// pub async fn create_test_blob( +// blob_client: &BlobClient, +// ) -> Result> { +// blob_client +// .upload( +// RequestContent::from(b"hello rusty world".to_vec()), +// true, +// 17, +// None, +// ) +// .await +// }