Skip to content

[Storage] get_account_info for all clients, set/get_tags for BlobClient #2661

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions sdk/storage/azure_storage_blob/src/clients/blob_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

use crate::serialize::serialize_blob_tags;
use crate::{
generated::clients::BlobClient as GeneratedBlobClient,
models::{
Expand All @@ -24,6 +25,7 @@ use azure_core::{
},
Bytes, Result,
};
use std::collections::HashMap;
use std::sync::Arc;

/// A client to interact with a specific Azure storage blob, although that blob may not yet exist.
Expand Down Expand Up @@ -215,13 +217,21 @@ impl BlobClient {
///
/// # Arguments
///
/// * `tags` - Name-value pairs associated with the blob as tag. Tags are case-sensitive.
/// The tag set may contain at most 10 tags. Tag keys must be between 1 and 128 characters,
/// and tag values must be between 0 and 256 characters.
/// Valid tag key and value characters include: lowercase and uppercase letters, digits (0-9),
/// space (' '), plus (+), minus (-), period (.), solidus (/), colon (:), equals (=), underscore (_)
/// * `options` - Optional configuration for the request.
pub async fn set_tags(
&self,
tags: RequestContent<BlobTags>,
tags: HashMap<String, String>,
options: Option<BlobClientSetTagsOptions<'_>>,
) -> Result<Response<()>> {
self.client.set_tags(tags, options).await
let blob_tags = serialize_blob_tags(tags);
self.client
.set_tags(RequestContent::try_from(blob_tags)?, options)
.await
}

/// Gets the tags on a blob.
Expand Down
2 changes: 2 additions & 0 deletions sdk/storage/azure_storage_blob/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
pub mod clients;
mod generated;
mod pipeline;
pub mod serialize;

pub use clients::*;

Expand Down Expand Up @@ -37,4 +38,5 @@ pub mod models {
ListBlobsFlatSegmentResponse, PublicAccessType, RehydratePriority,
StorageServiceProperties,
};
pub use crate::serialize::*;
}
26 changes: 26 additions & 0 deletions sdk/storage/azure_storage_blob/src/serialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

use crate::generated::models::{BlobTag, BlobTags};
use azure_core::http::RequestContent;
use std::collections::HashMap;

/// Takes in an offset and a length and returns the HTTP range in string format.
///
/// # Arguments
///
/// * `tags` - A hash map containing the name-value pairs associated with the blob as tags.
pub fn serialize_blob_tags(tags: HashMap<String, String>) -> BlobTags {
let mut blob_tags: Vec<BlobTag> = vec![];

for (k, v) in tags.into_iter() {
let blob_tag = BlobTag {
key: Some(k),
value: Some(v),
};
blob_tags.push(blob_tag);
}
BlobTags {
blob_tag_set: Some(blob_tags),
}
}
72 changes: 46 additions & 26 deletions sdk/storage/azure_storage_blob/tests/blob_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use azure_core_test::{recorded, TestContext};
use azure_storage_blob::models::{
AccessTier, AccountKind, BlobClientDownloadResultHeaders,
BlobClientGetAccountInfoResultHeaders, BlobClientGetPropertiesResultHeaders,
BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlobTag, BlobTags,
BlockBlobClientUploadOptions, LeaseState,
BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions, BlockBlobClientUploadOptions,
LeaseState,
};
use azure_storage_blob::serialize::serialize_blob_tags;
use azure_storage_blob_test::{
create_test_blob, get_blob_name, get_container_client, test_blob_tag_equality,
};
use std::{collections::HashMap, error::Error};

#[recorded::test]
async fn test_get_blob_properties(ctx: TestContext) -> Result<(), Box<dyn Error>> {
// Recording Setup
Expand Down Expand Up @@ -289,34 +289,54 @@ async fn test_blob_tags(ctx: TestContext) -> Result<(), Box<dyn Error>> {
create_test_blob(&blob_client).await?;

// Set Tags with Tags Specified
let blob_tag_1 = BlobTag {
key: Some("hello".to_string()),
value: Some("world".to_string()),
};
let blob_tag_2 = BlobTag {
key: Some("ferris".to_string()),
value: Some("crab".to_string()),
};
let blob_tags = BlobTags {
blob_tag_set: Some(vec![blob_tag_1, blob_tag_2]),
};
blob_client
.set_tags(RequestContent::try_from(blob_tags.clone())?, None)
.await?;
let blob_tags = HashMap::from([
("hello".to_string(), "world".to_string()),
("ferris".to_string(), "crab".to_string()),
]);
blob_client.set_tags(blob_tags.clone(), None).await?;

// Assert
let response_tags = blob_client.get_tags(None).await?.into_body().await?;
assert!(test_blob_tag_equality(blob_tags, response_tags));
assert!(test_blob_tag_equality(
serialize_blob_tags(blob_tags),
response_tags
));

// Set Tags with No Tags (Clear Tags)
blob_client
.set_tags(
RequestContent::try_from(BlobTags {
blob_tag_set: Some(vec![]),
})?,
None,
)
.await?;
blob_client.set_tags(HashMap::new(), None).await?;

// Assert
let response_tags = blob_client.get_tags(None).await?.into_body().await?;
assert!(response_tags.blob_tag_set.is_none());

container_client.delete_container(None).await?;
Ok(())
}

#[recorded::test]
async fn test_blob_tags2(ctx: TestContext) -> Result<(), Box<dyn Error>> {
// 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 Tags with Tags Specified
let blob_tags = HashMap::from([
("hello".to_string(), "world".to_string()),
("ferris".to_string(), "crab".to_string()),
]);
blob_client.set_tags(blob_tags.clone(), None).await?;

// Assert
let response_tags = blob_client.get_tags(None).await?.into_body().await?;
assert!(test_blob_tag_equality(
serialize_blob_tags(blob_tags),
response_tags
));

// Set Tags with No Tags (Clear Tags)
blob_client.set_tags(HashMap::new(), None).await?;

// Assert
let response_tags = blob_client.get_tags(None).await?.into_body().await?;
Expand Down