Skip to content

Commit 897a894

Browse files
[Storage] Handwritten BlockBlobClient (#2539)
1 parent 5a9423a commit 897a894

File tree

9 files changed

+262
-207
lines changed

9 files changed

+262
-207
lines changed

sdk/storage/assets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"AssetsRepo": "Azure/azure-sdk-assets",
33
"AssetsRepoPrefixPath": "rust",
4-
"Tag": "rust/azure_storage_blob_c54b1e37ce",
4+
"Tag": "rust/azure_storage_blob_be0a70462b",
55
"TagPrefix": "rust/azure_storage_blob"
66
}

sdk/storage/azure_storage_blob/src/clients/blob_client.rs

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::{
1212
pipeline::StorageHeadersPolicy,
1313
BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientGetPropertiesOptions,
1414
BlobClientOptions, BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions,
15-
BlobClientSetTierOptions, BlockBlobClientCommitBlockListOptions,
15+
BlobClientSetTierOptions, BlockBlobClient, BlockBlobClientCommitBlockListOptions,
1616
BlockBlobClientGetBlockListOptions, BlockBlobClientStageBlockOptions,
1717
BlockBlobClientUploadOptions,
1818
};
@@ -79,6 +79,17 @@ impl BlobClient {
7979
})
8080
}
8181

82+
/// Returns a new instance of BlockBlobClient.
83+
///
84+
/// # Arguments
85+
///
86+
pub fn block_blob_client(&self) -> BlockBlobClient {
87+
BlockBlobClient {
88+
endpoint: self.client.endpoint.clone(),
89+
client: self.client.get_block_blob_client(),
90+
}
91+
}
92+
8293
/// Gets the endpoint of the Storage account this client is connected to.
8394
pub fn endpoint(&self) -> &Url {
8495
&self.endpoint
@@ -184,58 +195,6 @@ impl BlobClient {
184195
self.client.delete(options).await
185196
}
186197

187-
/// Writes to a blob based on blocks specified by the list of IDs and content that make up the blob.
188-
///
189-
/// # Arguments
190-
///
191-
/// * `blocks` - The list of Blob blocks to commit.
192-
/// * `options` - Optional configuration for the request.
193-
pub async fn commit_block_list(
194-
&self,
195-
blocks: RequestContent<BlockLookupList>,
196-
options: Option<BlockBlobClientCommitBlockListOptions<'_>>,
197-
) -> Result<Response<BlockBlobClientCommitBlockListResult>> {
198-
let block_blob_client = self.client.get_block_blob_client();
199-
block_blob_client.commit_block_list(blocks, options).await
200-
}
201-
202-
/// Creates a new block to be later committed as part of a blob.
203-
///
204-
/// # Arguments
205-
///
206-
/// * `block_id` - The unique identifier for the block. The identifier should be less than or equal to 64 bytes in size.
207-
/// For a given blob, the `block_id` must be the same size for each block.
208-
/// * `content_length` - Total length of the blob data to be staged.
209-
/// * `data` - The content of the block.
210-
/// * `options` - Optional configuration for the request.
211-
pub async fn stage_block(
212-
&self,
213-
block_id: Vec<u8>,
214-
content_length: u64,
215-
body: RequestContent<Bytes>,
216-
options: Option<BlockBlobClientStageBlockOptions<'_>>,
217-
) -> Result<Response<BlockBlobClientStageBlockResult>> {
218-
let block_blob_client = self.client.get_block_blob_client();
219-
block_blob_client
220-
.stage_block(block_id, content_length, body, options)
221-
.await
222-
}
223-
224-
/// Retrieves the list of blocks that have been uploaded as part of a block blob.
225-
///
226-
/// # Arguments
227-
///
228-
/// * `list_type` - Specifies whether to return the list of committed blocks, uncommitted blocks, or both lists together.
229-
/// * `options` - Optional configuration for the request.
230-
pub async fn get_block_list(
231-
&self,
232-
list_type: BlockListType,
233-
options: Option<BlockBlobClientGetBlockListOptions<'_>>,
234-
) -> Result<Response<BlockList>> {
235-
let block_blob_client = self.client.get_block_blob_client();
236-
block_blob_client.get_block_list(list_type, options).await
237-
}
238-
239198
/// Sets the tier on a blob. Standard tiers are only applicable for Block blobs, while Premium tiers are only applicable
240199
/// for Page blobs.
241200
///

sdk/storage/azure_storage_blob/src/clients/blob_container_client.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ impl BlobContainerClient {
7474
/// # Arguments
7575
///
7676
/// * `blob_name` - The name of the blob.
77-
/// * `options` - Optional configuration for the client.
7877
pub fn blob_client(&self, blob_name: String) -> BlobClient {
7978
BlobClient {
8079
endpoint: self.client.endpoint.clone(),

sdk/storage/azure_storage_blob/src/clients/blob_service_client.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ impl BlobServiceClient {
6565
/// # Arguments
6666
///
6767
/// * `container_name` - The name of the container.
68-
/// * `options` - Optional configuration for the client.
6968
pub fn blob_container_client(&self, container_name: String) -> BlobContainerClient {
7069
BlobContainerClient {
7170
endpoint: self.client.endpoint.clone(),
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
use crate::{
5+
generated::clients::BlockBlobClient as GeneratedBlockBlobClient,
6+
generated::models::{
7+
BlobClientDownloadResult, BlobClientGetPropertiesResult,
8+
BlockBlobClientCommitBlockListResult, BlockBlobClientStageBlockResult,
9+
BlockBlobClientUploadResult,
10+
},
11+
models::{BlockList, BlockListType, BlockLookupList, StorageServiceProperties},
12+
pipeline::StorageHeadersPolicy,
13+
BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientGetPropertiesOptions,
14+
BlobClientOptions, BlobClientSetMetadataOptions, BlobClientSetPropertiesOptions,
15+
BlobClientSetTierOptions, BlockBlobClientCommitBlockListOptions,
16+
BlockBlobClientGetBlockListOptions, BlockBlobClientOptions, BlockBlobClientStageBlockOptions,
17+
BlockBlobClientUploadOptions,
18+
};
19+
use azure_core::{
20+
credentials::TokenCredential,
21+
http::{
22+
policies::{BearerTokenCredentialPolicy, Policy},
23+
RequestContent, Response, Url,
24+
},
25+
Bytes, Result,
26+
};
27+
use std::sync::Arc;
28+
29+
/// A client to interact with a specific Azure storage Block blob, although that blob may not yet exist.
30+
pub struct BlockBlobClient {
31+
pub(crate) endpoint: Url,
32+
pub(crate) client: GeneratedBlockBlobClient,
33+
}
34+
35+
impl BlockBlobClient {
36+
/// Creates a new BlockBlobClient, using Entra ID authentication.
37+
///
38+
/// # Arguments
39+
///
40+
/// * `endpoint` - The full URL of the Azure storage account, for example `https://myaccount.blob.core.windows.net/`
41+
/// * `container_name` - The name of the container containing this Block blob.
42+
/// * `blob_name` - The name of the Block blob to interact with.
43+
/// * `credential` - An implementation of [`TokenCredential`] that can provide an Entra ID token to use when authenticating.
44+
/// * `options` - Optional configuration for the client.
45+
pub fn new(
46+
endpoint: &str,
47+
container_name: String,
48+
blob_name: String,
49+
credential: Arc<dyn TokenCredential>,
50+
options: Option<BlockBlobClientOptions>,
51+
) -> Result<Self> {
52+
let mut options = options.unwrap_or_default();
53+
54+
let storage_headers_policy = Arc::new(StorageHeadersPolicy);
55+
options
56+
.client_options
57+
.per_call_policies
58+
.push(storage_headers_policy);
59+
60+
let oauth_token_policy = BearerTokenCredentialPolicy::new(
61+
credential.clone(),
62+
["https://storage.azure.com/.default"],
63+
);
64+
options
65+
.client_options
66+
.per_try_policies
67+
.push(Arc::new(oauth_token_policy) as Arc<dyn Policy>);
68+
69+
let client = GeneratedBlockBlobClient::new(
70+
endpoint,
71+
credential.clone(),
72+
container_name.clone(),
73+
blob_name.clone(),
74+
Some(options),
75+
)?;
76+
Ok(Self {
77+
endpoint: endpoint.parse()?,
78+
client,
79+
})
80+
}
81+
82+
/// Gets the endpoint of the Storage account this client is connected to.
83+
pub fn endpoint(&self) -> &Url {
84+
&self.endpoint
85+
}
86+
87+
/// Gets the container name of the Storage account this client is connected to.
88+
pub fn container_name(&self) -> &str {
89+
&self.client.container_name
90+
}
91+
92+
/// Gets the blob name of the Storage account this client is connected to.
93+
pub fn blob_name(&self) -> &str {
94+
&self.client.blob_name
95+
}
96+
97+
/// Writes to a blob based on blocks specified by the list of IDs and content that make up the blob.
98+
///
99+
/// # Arguments
100+
///
101+
/// * `blocks` - The list of Blob blocks to commit.
102+
/// * `options` - Optional configuration for the request.
103+
pub async fn commit_block_list(
104+
&self,
105+
blocks: RequestContent<BlockLookupList>,
106+
options: Option<BlockBlobClientCommitBlockListOptions<'_>>,
107+
) -> Result<Response<BlockBlobClientCommitBlockListResult>> {
108+
self.client.commit_block_list(blocks, options).await
109+
}
110+
111+
/// Creates a new block to be later committed as part of a blob.
112+
///
113+
/// # Arguments
114+
///
115+
/// * `block_id` - The unique identifier for the block. The identifier should be less than or equal to 64 bytes in size.
116+
/// For a given blob, the `block_id` must be the same size for each block.
117+
/// * `content_length` - Total length of the blob data to be staged.
118+
/// * `data` - The content of the block.
119+
/// * `options` - Optional configuration for the request.
120+
pub async fn stage_block(
121+
&self,
122+
block_id: Vec<u8>,
123+
content_length: u64,
124+
body: RequestContent<Bytes>,
125+
options: Option<BlockBlobClientStageBlockOptions<'_>>,
126+
) -> Result<Response<BlockBlobClientStageBlockResult>> {
127+
self.client
128+
.stage_block(block_id, content_length, body, options)
129+
.await
130+
}
131+
132+
/// Retrieves the list of blocks that have been uploaded as part of a block blob.
133+
///
134+
/// # Arguments
135+
///
136+
/// * `list_type` - Specifies whether to return the list of committed blocks, uncommitted blocks, or both lists together.
137+
/// * `options` - Optional configuration for the request.
138+
pub async fn get_block_list(
139+
&self,
140+
list_type: BlockListType,
141+
options: Option<BlockBlobClientGetBlockListOptions<'_>>,
142+
) -> Result<Response<BlockList>> {
143+
self.client.get_block_list(list_type, options).await
144+
}
145+
}

sdk/storage/azure_storage_blob/src/clients/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
mod blob_client;
77
mod blob_container_client;
88
mod blob_service_client;
9+
mod block_blob_client;
910

1011
pub use blob_client::BlobClient;
1112
pub use blob_container_client::BlobContainerClient;
1213
pub use blob_service_client::BlobServiceClient;
14+
pub use block_blob_client::BlockBlobClient;

sdk/storage/azure_storage_blob/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ pub mod clients;
1111
mod generated;
1212
mod pipeline;
1313

14-
pub use crate::clients::{BlobClient, BlobContainerClient, BlobServiceClient};
14+
pub use crate::clients::{BlobClient, BlobContainerClient, BlobServiceClient, BlockBlobClient};
1515
pub use crate::generated::clients::{
16-
BlobClientOptions, BlobContainerClientOptions, BlobServiceClientOptions,
16+
BlobClientOptions, BlobContainerClientOptions, BlobServiceClientOptions, BlockBlobClientOptions,
1717
};
1818
pub use crate::generated::models::{
1919
BlobClientDeleteOptions, BlobClientDownloadOptions, BlobClientGetPropertiesOptions,

0 commit comments

Comments
 (0)