Skip to content

Commit

Permalink
support find blobs by tags operation (#439)
Browse files Browse the repository at this point in the history
  • Loading branch information
JensWalter authored Oct 26, 2021
1 parent ec9cc59 commit 1e847c9
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 0 deletions.
74 changes: 74 additions & 0 deletions sdk/storage/src/account/requests/find_blobs_by_tags_builder.rs
Original file line number Diff line number Diff line change
@@ -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<NextMarker>,
max_results: Option<MaxResults>,
client_request_id: Option<ClientRequestId<'a>>,
timeout: Option<Timeout>,
}

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<ListBlobsByTagsResponse, Box<dyn std::error::Error + Send + Sync>> {
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()?)
}
}
2 changes: 2 additions & 0 deletions sdk/storage/src/account/requests/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
91 changes: 91 additions & 0 deletions sdk/storage/src/account/responses/list_blobs_by_tags_response.rs
Original file line number Diff line number Diff line change
@@ -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<u32>,
pub delimiter: Option<String>,
pub next_marker: Option<NextMarker>,
pub r#where: Option<String>,
pub blobs: Blobs,
pub request_id: RequestId,
pub date: DateTime<Utc>,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "PascalCase")]
struct ListBlobsByTagsResponseInternal {
pub max_results: Option<u32>,
pub delimiter: Option<String>,
pub next_marker: Option<String>,
pub r#where: Option<String>,
pub blobs: Blobs,
}

#[derive(Debug, Clone, PartialEq, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct Blobs {
#[serde(rename = "Blob", default = "Vec::new")]
pub blobs: Vec<Blob>,
}

#[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<Bytes>> for ListBlobsByTagsResponse {
type Error = crate::Error;

fn try_from(response: &http::Response<Bytes>) -> Result<Self, Self::Error> {
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 = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<EnumerationResults ServiceEndpoint=\"https://hsdgeventstoredev.blob.core.windows.net/\">
<Where>tag1='value1'</Where>
<Blobs>
<Blob>
<Name>test1</Name>
<ContainerName>container1</ContainerName>
<TagValue>value1</TagValue>
</Blob>
</Blobs>
<NextMarker/>
</EnumerationResults>";

let bytes = Bytes::from(S);
let _list_blobs_response_internal: ListBlobsByTagsResponseInternal =
read_xml(&bytes).unwrap();
}
}
2 changes: 2 additions & 0 deletions sdk/storage/src/account/responses/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
4 changes: 4 additions & 0 deletions sdk/storage/src/core/clients/storage_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 1e847c9

Please sign in to comment.