Skip to content

Commit

Permalink
Move find_blobs_by_tag to pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
rylev committed Jun 17, 2022
1 parent ea54831 commit 9c70bec
Show file tree
Hide file tree
Showing 9 changed files with 173 additions and 21 deletions.
2 changes: 0 additions & 2 deletions sdk/storage/src/account/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
pub mod operations;
pub mod requests;
pub mod responses;

#[derive(Debug, Clone, PartialEq)]
pub struct Account {
Expand Down
161 changes: 161 additions & 0 deletions sdk/storage/src/account/operations/find_blobs_by_tags.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
use crate::core::prelude::*;
use crate::xml::read_xml;
use azure_core::headers::{date_from_headers, request_id_from_headers};
use azure_core::prelude::*;
use azure_core::{collect_pinned_stream, RequestId, Response as HttpResponse};
use chrono::{DateTime, Utc};

#[derive(Debug, Clone)]
pub struct FindBlobsByTagsBuilder {
client: StorageClient,
expression: String,
#[allow(unused)]
next_marker: Option<NextMarker>,
#[allow(unused)]
max_results: Option<MaxResults>,
timeout: Option<Timeout>,
context: Context,
}

impl FindBlobsByTagsBuilder {
pub(crate) fn new(client: StorageClient) -> Self {
Self {
client,
expression: String::new(),
next_marker: None,
max_results: None,
timeout: None,
context: Context::new(),
}
}

setters! {
expression: String => expression,
next_marker: NextMarker => Some(next_marker),
max_results: MaxResults => Some(max_results),
timeout: Timeout => Some(timeout),
}

// TODO: Make this a stream instead of a `Future`
pub fn into_future(mut self) -> FindBlobsByTags {
Box::pin(async move {
let mut request = self
.client
.storage_account_client()
.blob_storage_request(http::Method::GET);

self.timeout.append_to_url_query(request.url_mut());
request
.url_mut()
.query_pairs_mut()
.append_pair("comp", "blobs");
request
.url_mut()
.query_pairs_mut()
.append_pair("where", &self.expression);

let response = self
.client
.storage_account_client()
.pipeline()
.send(&mut self.context, &mut request)
.await?;

ListBlobsByTagsResponse::try_from(response).await
})
}
}

/// The future returned by calling `into_future` on the builder.
pub type FindBlobsByTags =
futures::future::BoxFuture<'static, azure_core::error::Result<ListBlobsByTagsResponse>>;

#[cfg(feature = "into_future")]
impl std::future::IntoFuture for FindBlobsByTagsBuilder {
type IntoFuture = FindBlobsByTags;
type Output = <FindBlobsByTags as std::future::Future>::Output;
fn into_future(self) -> Self::IntoFuture {
Self::into_future(self)
}
}

#[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 ListBlobsByTagsResponse {
async fn try_from(response: HttpResponse) -> azure_core::error::Result<Self> {
let (_status_code, headers, pinned_stream) = response.deconstruct();
let body = collect_pinned_stream(pinned_stream).await?;
let list_blobs_response_internal: ListBlobsByTagsResponseInternal = read_xml(&body)?;

Ok(Self {
request_id: request_id_from_headers(&headers)?,
date: date_from_headers(&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: &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::Bytes::from(S);
let _list_blobs_response_internal: ListBlobsByTagsResponseInternal =
read_xml(&bytes).unwrap();
}
}
12 changes: 6 additions & 6 deletions sdk/storage/src/account/operations/get_account_information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ use http::HeaderMap;

#[derive(Debug, Clone)]
pub struct GetAccountInformationBuilder {
storage_client: StorageClient,
client: StorageClient,
context: Context,
}

impl GetAccountInformationBuilder {
pub(crate) fn new(storage_client: StorageClient) -> Self {
pub(crate) fn new(client: StorageClient) -> Self {
Self {
storage_client,
client,
context: Context::new(),
}
}
Expand All @@ -29,16 +29,16 @@ impl GetAccountInformationBuilder {
pub fn into_future(mut self) -> GetAccountInformation {
Box::pin(async move {
let mut request = self
.storage_client
.client
.storage_account_client()
.blob_storage_request("", http::Method::GET);
.blob_storage_request(http::Method::GET);

for (k, v) in [("restype", "account"), ("comp", "properties")].iter() {
request.url_mut().query_pairs_mut().append_pair(k, v);
}

let response = self
.storage_client
.client
.storage_account_client()
.pipeline()
.send(&mut self.context, &mut request)
Expand Down
2 changes: 2 additions & 0 deletions sdk/storage/src/account/operations/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
mod find_blobs_by_tags;
mod get_account_information;

pub use find_blobs_by_tags::*;
pub use get_account_information::*;
2 changes: 0 additions & 2 deletions sdk/storage/src/account/requests/mod.rs

This file was deleted.

Empty file.
2 changes: 0 additions & 2 deletions sdk/storage/src/account/responses/mod.rs

This file was deleted.

9 changes: 2 additions & 7 deletions sdk/storage/src/core/clients/storage_account_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,13 +519,8 @@ impl StorageAccountClient {
}

/// Prepares' an `azure_core::Request`.
pub(crate) fn blob_storage_request(
&self,
uri_path: &str,
http_method: http::Method,
) -> CoreRequest {
let uri = format!("{}/{}", self.blob_storage_url(), uri_path);
CoreRequest::new(uri.parse().unwrap(), http_method)
pub(crate) fn blob_storage_request(&self, http_method: http::Method) -> CoreRequest {
CoreRequest::new(self.blob_storage_url().clone(), http_method)
}
}

Expand Down
4 changes: 2 additions & 2 deletions sdk/storage/src/core/clients/storage_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ impl StorageClient {
GetAccountInformationBuilder::new(self.clone())
}

pub fn find_blobs_by_tags(&self) -> crate::account::requests::FindBlobsByTagsBuilder {
crate::account::requests::FindBlobsByTagsBuilder::new(self)
pub fn find_blobs_by_tags(&self) -> FindBlobsByTagsBuilder {
FindBlobsByTagsBuilder::new(self.clone())
}

#[allow(dead_code)]
Expand Down

0 comments on commit 9c70bec

Please sign in to comment.