From 1e847c92a9bc40b92df314aa2e529624644588f0 Mon Sep 17 00:00:00 2001 From: Jens Walter Date: Tue, 26 Oct 2021 15:54:33 +0200 Subject: [PATCH] support find blobs by tags operation (#439) --- .../requests/find_blobs_by_tags_builder.rs | 74 +++++++++++++++ sdk/storage/src/account/requests/mod.rs | 2 + .../responses/list_blobs_by_tags_response.rs | 91 +++++++++++++++++++ sdk/storage/src/account/responses/mod.rs | 2 + .../src/core/clients/storage_client.rs | 4 + 5 files changed, 173 insertions(+) create mode 100644 sdk/storage/src/account/requests/find_blobs_by_tags_builder.rs create mode 100644 sdk/storage/src/account/responses/list_blobs_by_tags_response.rs diff --git a/sdk/storage/src/account/requests/find_blobs_by_tags_builder.rs b/sdk/storage/src/account/requests/find_blobs_by_tags_builder.rs new file mode 100644 index 0000000000..ba4fa67d53 --- /dev/null +++ b/sdk/storage/src/account/requests/find_blobs_by_tags_builder.rs @@ -0,0 +1,74 @@ +use crate::account::responses::ListBlobsByTagsResponse; +use crate::core::prelude::*; +use azure_core::headers::add_optional_header; +use azure_core::prelude::*; +use std::convert::TryInto; + +#[derive(Debug, Clone)] +pub struct FindBlobsByTagsBuilder<'a> { + client: &'a StorageClient, + expression: String, + lease_id: Option<&'a str>, + next_marker: Option, + max_results: Option, + client_request_id: Option>, + timeout: Option, +} + +impl<'a> FindBlobsByTagsBuilder<'a> { + pub(crate) fn new(client: &'a StorageClient) -> Self { + Self { + client, + expression: "".to_string(), + lease_id: None, + next_marker: None, + max_results: None, + client_request_id: None, + timeout: None, + } + } + + setters! { + expression: String => expression, + next_marker: NextMarker => Some(next_marker), + max_results: MaxResults => Some(max_results), + client_request_id: ClientRequestId<'a> => Some(client_request_id), + timeout: Timeout => Some(timeout), + } + + pub async fn execute( + &self, + ) -> Result> { + let mut url = self + .client + .storage_account_client() + .blob_storage_url() + .to_owned(); + + self.timeout.append_to_url_query(&mut url); + url.query_pairs_mut().append_pair("comp", "blobs"); + url.query_pairs_mut().append_pair("where", &self.expression); + + trace!("url == {:?}", url); + + let (request, _url) = self.client.prepare_request( + url.as_str(), + &http::Method::GET, + &|mut request| { + request = add_optional_header(&self.client_request_id, request); + request + }, + None, + )?; + + let response = self + .client + .http_client() + .execute_request_check_status(request, http::StatusCode::OK) + .await?; + + debug!("response.headers() == {:#?}", response.headers()); + + Ok((&response).try_into()?) + } +} diff --git a/sdk/storage/src/account/requests/mod.rs b/sdk/storage/src/account/requests/mod.rs index 714ebfb9dd..3251385e1f 100644 --- a/sdk/storage/src/account/requests/mod.rs +++ b/sdk/storage/src/account/requests/mod.rs @@ -1,2 +1,4 @@ +mod find_blobs_by_tags_builder; mod get_account_information_builder; +pub use self::find_blobs_by_tags_builder::FindBlobsByTagsBuilder; pub use self::get_account_information_builder::GetAccountInformationBuilder; diff --git a/sdk/storage/src/account/responses/list_blobs_by_tags_response.rs b/sdk/storage/src/account/responses/list_blobs_by_tags_response.rs new file mode 100644 index 0000000000..eac488fad6 --- /dev/null +++ b/sdk/storage/src/account/responses/list_blobs_by_tags_response.rs @@ -0,0 +1,91 @@ +use crate::xml::read_xml; +use azure_core::headers::{date_from_headers, request_id_from_headers}; +use azure_core::prelude::NextMarker; +use azure_core::RequestId; +use bytes::Bytes; +use chrono::{DateTime, Utc}; +use std::convert::TryFrom; + +#[derive(Debug, Clone, PartialEq)] +pub struct ListBlobsByTagsResponse { + pub max_results: Option, + pub delimiter: Option, + pub next_marker: Option, + pub r#where: Option, + pub blobs: Blobs, + pub request_id: RequestId, + pub date: DateTime, +} + +#[derive(Debug, Clone, PartialEq, Deserialize)] +#[serde(rename_all = "PascalCase")] +struct ListBlobsByTagsResponseInternal { + pub max_results: Option, + pub delimiter: Option, + pub next_marker: Option, + pub r#where: Option, + pub blobs: Blobs, +} + +#[derive(Debug, Clone, PartialEq, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Blobs { + #[serde(rename = "Blob", default = "Vec::new")] + pub blobs: Vec, +} + +#[derive(Debug, Clone, PartialEq, Deserialize)] +#[serde(rename_all = "PascalCase")] +pub struct Blob { + pub name: String, + pub container_name: String, + pub tag_value: String, +} + +impl TryFrom<&http::Response> for ListBlobsByTagsResponse { + type Error = crate::Error; + + fn try_from(response: &http::Response) -> Result { + let body = response.body(); + + trace!("body == {:?}", body); + let list_blobs_response_internal: ListBlobsByTagsResponseInternal = read_xml(body)?; + + Ok(Self { + request_id: request_id_from_headers(response.headers())?, + date: date_from_headers(response.headers())?, + max_results: list_blobs_response_internal.max_results, + delimiter: list_blobs_response_internal.delimiter, + r#where: list_blobs_response_internal.r#where, + blobs: list_blobs_response_internal.blobs, + next_marker: NextMarker::from_possibly_empty_string( + list_blobs_response_internal.next_marker, + ), + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn deserde_azure() { + const S: &'static str = " + + tag1='value1' + + + test1 + container1 + value1 + + + + "; + + let bytes = Bytes::from(S); + let _list_blobs_response_internal: ListBlobsByTagsResponseInternal = + read_xml(&bytes).unwrap(); + } +} diff --git a/sdk/storage/src/account/responses/mod.rs b/sdk/storage/src/account/responses/mod.rs index df25743497..b757d9c3b5 100644 --- a/sdk/storage/src/account/responses/mod.rs +++ b/sdk/storage/src/account/responses/mod.rs @@ -1,2 +1,4 @@ mod get_account_information_response; +mod list_blobs_by_tags_response; pub use get_account_information_response::GetAccountInformationResponse; +pub use list_blobs_by_tags_response::ListBlobsByTagsResponse; diff --git a/sdk/storage/src/core/clients/storage_client.rs b/sdk/storage/src/core/clients/storage_client.rs index fc9329124a..cd0967e598 100644 --- a/sdk/storage/src/core/clients/storage_client.rs +++ b/sdk/storage/src/core/clients/storage_client.rs @@ -84,6 +84,10 @@ impl StorageClient { crate::account::requests::GetAccountInformationBuilder::new(self) } + pub fn find_blobs_by_tags(&self) -> crate::account::requests::FindBlobsByTagsBuilder { + crate::account::requests::FindBlobsByTagsBuilder::new(self) + } + #[cfg(feature = "blob")] pub fn list_containers(&self) -> crate::container::requests::ListContainersBuilder { crate::container::requests::ListContainersBuilder::new(self)