in sdk/storage/Azure.Storage.Blobs/src/BlockBlobClient.cs [1912:2337]
public virtual Response<BlobContentInfo> CommitBlockList(
IEnumerable<string> base64BlockIds,
CommitBlockListOptions options,
CancellationToken cancellationToken = default) =>
CommitBlockListInternal(
base64BlockIds,
options?.HttpHeaders,
options?.Metadata,
options?.Tags,
options?.Conditions,
options?.AccessTier,
options?.ImmutabilityPolicy,
options?.LegalHold,
async: false,
cancellationToken)
.EnsureCompleted();
/// <summary>
/// The <see cref="CommitBlockList(IEnumerable{string}, BlobHttpHeaders, Metadata, BlobRequestConditions, AccessTier?, CancellationToken)"/>
/// operation writes a blob by specifying the list of block IDs that make up the blob.
/// In order to be written as part of a blob, a block must have been
/// successfully written to the server in a prior <see cref="StageBlock(string, Stream, byte[], BlobRequestConditions, IProgress{long}, CancellationToken)"/>
/// operation. You can call <see cref="CommitBlockList(IEnumerable{string}, BlobHttpHeaders, Metadata, BlobRequestConditions, AccessTier?, CancellationToken)"/>
/// to update a blob by uploading only those blocks that have changed,
/// then committing the new and existing blocks together. You can do
/// this by specifying whether to commit a block from the committed
/// block list or from the uncommitted block list, or to commit the
/// most recently uploaded version of the block, whichever list it
/// may belong to. Any blocks not specified in the block list are
/// permanently deleted.
///
/// Note: Uncommitted blocks will expire and be permanently deleted after 7 days.
/// Blocks that are committed to a blob do not expire.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/rest/api/storageservices/put-block-list">
/// Put Block List</see>.
/// </summary>
/// <param name="base64BlockIds">
/// Specify the Uncommitted Base64 encoded block IDs to indicate that
/// the blob service should search only the uncommitted block list for
/// the named blocks. If the block is not found in the uncommitted
/// block list, it will not be written as part of the blob, and a
/// <see cref="RequestFailedException"/> will be thrown.
/// </param>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// block blob.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this block blob.
/// </param>
/// <param name="conditions">
/// Optional <see cref="BlockBlobClient"/> to add
/// conditions on committing this block list.
/// </param>
/// <param name="accessTier">
/// Optional <see cref="AccessTier"/>
/// Indicates the tier to be set on the blob.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobContentInfo}"/> describing the
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual Response<BlobContentInfo> CommitBlockList(
IEnumerable<string> base64BlockIds,
BlobHttpHeaders httpHeaders = default,
Metadata metadata = default,
BlobRequestConditions conditions = default,
AccessTier? accessTier = default,
CancellationToken cancellationToken = default) =>
CommitBlockListInternal(
base64BlockIds: base64BlockIds,
blobHttpHeaders: httpHeaders,
metadata: metadata,
tags: default,
conditions: conditions,
accessTier: accessTier,
immutabilityPolicy: default,
legalHold: default,
async: false,
cancellationToken: cancellationToken)
.EnsureCompleted();
/// <summary>
/// The <see cref="CommitBlockListAsync(IEnumerable{string}, CommitBlockListOptions, CancellationToken)"/>
/// operation writes a blob by specifying the list of block IDs that make up the blob. In order
/// to be written as part of a blob, a block must have been
/// successfully written to the server in a prior <see cref="StageBlock(string, Stream, byte[], BlobRequestConditions, IProgress{long}, CancellationToken)"/>
/// operation. You can call <see cref="CommitBlockListAsync(IEnumerable{string}, CommitBlockListOptions, CancellationToken)"/>
/// to update a blob by uploading only those blocks that have changed,
/// then committing the new and existing blocks together. You can do
/// this by specifying whether to commit a block from the committed
/// block list or from the uncommitted block list, or to commit the
/// most recently uploaded version of the block, whichever list it
/// may belong to. Any blocks not specified in the block list are
/// permanently deleted.
///
/// Note: Uncommitted blocks will expire and be permanently deleted after 7 days.
/// Blocks that are committed to a blob do not expire.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/rest/api/storageservices/put-block-list">
/// Put Block List</see>.
/// </summary>
/// <param name="base64BlockIds">
/// Specify the Uncommitted Base64 encoded block IDs to indicate that
/// the blob service should search only the uncommitted block list for
/// the named blocks. If the block is not found in the uncommitted
/// block list, it will not be written as part of the blob, and a
/// <see cref="RequestFailedException"/> will be thrown.
/// </param>
/// <param name="options">
/// Optional parameters.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobContentInfo}"/> describing the
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
public virtual async Task<Response<BlobContentInfo>> CommitBlockListAsync(
IEnumerable<string> base64BlockIds,
CommitBlockListOptions options,
CancellationToken cancellationToken = default) =>
await CommitBlockListInternal(
base64BlockIds,
options?.HttpHeaders,
options?.Metadata,
options?.Tags,
options?.Conditions,
options?.AccessTier,
options?.ImmutabilityPolicy,
options?.LegalHold,
async: true,
cancellationToken)
.ConfigureAwait(false);
/// <summary>
/// The <see cref="CommitBlockListAsync(IEnumerable{string}, BlobHttpHeaders, Metadata, BlobRequestConditions, AccessTier?, CancellationToken)"/>
/// operation writes a blob bys pecifying the list of block IDs that make up the blob.
/// In order to be written as part of a blob, a block must have been
/// successfully written to the server in a prior <see cref="StageBlockAsync(string, Stream, byte[], BlobRequestConditions, IProgress{long}, CancellationToken)"/>
/// operation. You can call <see cref="CommitBlockListAsync(IEnumerable{string}, BlobHttpHeaders, Metadata, BlobRequestConditions, AccessTier?, CancellationToken)"/>
/// to update a blob by uploading only those blocks that have changed,
/// then committing the new and existing blocks together. You can do
/// this by specifying whether to commit a block from the committed
/// block list or from the uncommitted block list, or to commit the
/// most recently uploaded version of the block, whichever list it
/// may belong to. Any blocks not specified in the block list are
/// permanently deleted.
///
/// Note: Uncommitted blocks will expire and be permanently deleted after 7 days.
/// Blocks that are committed to a blob do not expire.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/rest/api/storageservices/put-block-list">
/// Put Block List</see>.
/// </summary>
/// <param name="base64BlockIds">
/// Specify the Uncommitted Base64 encoded block IDs to indicate that
/// the blob service should search only the uncommitted block list for
/// the named blocks. If the block is not found in the uncommitted
/// block list, it will not be written as part of the blob, and a
/// <see cref="RequestFailedException"/> will be thrown.
/// </param>
/// <param name="httpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// block blob.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this block blob.
/// </param>
/// <param name="conditions">
/// Optional <see cref="BlockBlobClient"/> to add
/// conditions on committing this block list.
/// </param>
/// <param name="accessTier">
/// Optional <see cref="AccessTier"/>
/// Indicates the tier to be set on the blob.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobAppendInfo}"/> describing the
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public virtual async Task<Response<BlobContentInfo>> CommitBlockListAsync(
IEnumerable<string> base64BlockIds,
BlobHttpHeaders httpHeaders = default,
Metadata metadata = default,
BlobRequestConditions conditions = default,
AccessTier? accessTier = default,
CancellationToken cancellationToken = default) =>
await CommitBlockListInternal(
base64BlockIds: base64BlockIds,
blobHttpHeaders: httpHeaders,
metadata: metadata,
tags: default,
conditions: conditions,
accessTier: accessTier,
immutabilityPolicy: default,
legalHold: default,
async: true,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
/// <summary>
/// The <see cref="CommitBlockListInternal"/> operation writes a blob by
/// specifying the list of block IDs that make up the blob. In order
/// to be written as part of a blob, a block must have been
/// successfully written to the server in a prior <see cref="StageBlockAsync(string, Stream, byte[], BlobRequestConditions, IProgress{long}, CancellationToken)"/>
/// operation. You can call <see cref="CommitBlockListInternal"/> to
/// update a blob by uploading only those blocks that have changed,
/// then committing the new and existing blocks together. You can do
/// this by specifying whether to commit a block from the committed
/// block list or from the uncommitted block list, or to commit the
/// most recently uploaded version of the block, whichever list it
/// may belong to. Any blocks not specified in the block list are
/// permanently deleted.
///
/// Note: Uncommitted blocks will expire and be permanently deleted after 7 days.
/// Blocks that are committed to a blob do not expire.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/rest/api/storageservices/put-block-list">
/// Put Block List</see>.
/// </summary>
/// <param name="base64BlockIds">
/// Specify the Uncommitted Base64 encoded block IDs to indicate that
/// the blob service should search only the uncommitted block list for
/// the named blocks. If the block is not found in the uncommitted
/// block list, it will not be written as part of the blob, and a
/// <see cref="RequestFailedException"/> will be thrown.
/// </param>
/// <param name="blobHttpHeaders">
/// Optional standard HTTP header properties that can be set for the
/// block blob.
/// </param>
/// <param name="metadata">
/// Optional custom metadata to set for this block blob.
/// </param>
/// <param name="tags">
/// Optional tags to set for this block blob.
/// </param>
/// <param name="conditions">
/// Optional <see cref="BlockBlobClient"/> to add
/// conditions on committing this block list.
/// </param>
/// <param name="accessTier">
/// Optional <see cref="AccessTier"/>
/// Indicates the tier to be set on the blob.
/// </param>
/// <param name="immutabilityPolicy">
/// Optional <see cref="BlobImmutabilityPolicy"/> to set on the blob.
/// Note that is parameter is only applicable to a blob within a container that
/// has immutable storage with versioning enabled.
/// </param>
/// <param name="legalHold">
/// Optional. Indicates if a legal hold should be placed on the blob.
/// Note that is parameter is only applicable to a blob within a container that
/// has immutable storage with versioning enabled.
/// </param>
/// <param name="async">
/// Whether to invoke the operation asynchronously.
/// </param>
/// <param name="cancellationToken">
/// Optional <see cref="CancellationToken"/> to propagate
/// notifications that the operation should be cancelled.
/// </param>
/// <returns>
/// A <see cref="Response{BlobAppendInfo}"/> describing the
/// state of the updated block blob.
/// </returns>
/// <remarks>
/// A <see cref="RequestFailedException"/> will be thrown if
/// a failure occurs.
/// If multiple failures occur, an <see cref="AggregateException"/> will be thrown,
/// containing each failure instance.
/// </remarks>
internal virtual async Task<Response<BlobContentInfo>> CommitBlockListInternal(
IEnumerable<string> base64BlockIds,
BlobHttpHeaders blobHttpHeaders,
Metadata metadata,
Tags tags,
BlobRequestConditions conditions,
AccessTier? accessTier,
BlobImmutabilityPolicy immutabilityPolicy,
bool? legalHold,
bool async,
CancellationToken cancellationToken)
{
using (ClientConfiguration.Pipeline.BeginLoggingScope(nameof(BlockBlobClient)))
{
ClientConfiguration.Pipeline.LogMethodEnter(
nameof(BlockBlobClient),
message:
$"{nameof(Uri)}: {Uri}\n" +
$"{nameof(base64BlockIds)}: {base64BlockIds}\n" +
$"{nameof(blobHttpHeaders)}: {blobHttpHeaders}\n" +
$"{nameof(conditions)}: {conditions}");
DiagnosticScope scope = ClientConfiguration.ClientDiagnostics.CreateScope($"{nameof(BlockBlobClient)}.{nameof(CommitBlockList)}");
// All BlobRequestConditions are valid.
conditions.ValidateConditionsNotPresent(
invalidConditions: BlobRequestConditionProperty.None,
operationName: nameof(BlockBlobClient.CommitBlockList),
parameterName: nameof(conditions));
try
{
scope.Start();
BlockLookupList blocks = new BlockLookupList() { Latest = base64BlockIds.ToList() };
ResponseWithHeaders<BlockBlobCommitBlockListHeaders> response;
using DisposableBucket disposableBucket = new();
if (ClientSideEncryption != default)
{
disposableBucket.Add(Shared.StorageExtensions.CreateClientSideEncryptionScope(ClientSideEncryption.EncryptionVersion));
}
if (async)
{
response = await BlockBlobRestClient.CommitBlockListAsync(
blocks: blocks,
blobCacheControl: blobHttpHeaders?.CacheControl,
blobContentType: blobHttpHeaders?.ContentType,
blobContentEncoding: blobHttpHeaders?.ContentEncoding,
blobContentLanguage: blobHttpHeaders?.ContentLanguage,
blobContentMD5: blobHttpHeaders?.ContentHash,
metadata: metadata,
leaseId: conditions?.LeaseId,
blobContentDisposition: blobHttpHeaders?.ContentDisposition,
encryptionKey: ClientConfiguration.CustomerProvidedKey?.EncryptionKey,
encryptionKeySha256: ClientConfiguration.CustomerProvidedKey?.EncryptionKeyHash,
encryptionAlgorithm: ClientConfiguration.CustomerProvidedKey?.EncryptionAlgorithm == null ? null : EncryptionAlgorithmTypeInternal.AES256,
encryptionScope: ClientConfiguration.EncryptionScope,
tier: accessTier,
ifModifiedSince: conditions?.IfModifiedSince,
ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
ifMatch: conditions?.IfMatch?.ToString(),
ifNoneMatch: conditions?.IfNoneMatch?.ToString(),
ifTags: conditions?.TagConditions,
blobTagsString: tags?.ToTagsString(),
immutabilityPolicyExpiry: immutabilityPolicy?.ExpiresOn,
immutabilityPolicyMode: immutabilityPolicy?.PolicyMode,
legalHold: legalHold,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
else
{
response = BlockBlobRestClient.CommitBlockList(
blocks: blocks,
blobCacheControl: blobHttpHeaders?.CacheControl,
blobContentType: blobHttpHeaders?.ContentType,
blobContentEncoding: blobHttpHeaders?.ContentEncoding,
blobContentLanguage: blobHttpHeaders?.ContentLanguage,
blobContentMD5: blobHttpHeaders?.ContentHash,
metadata: metadata,
leaseId: conditions?.LeaseId,
blobContentDisposition: blobHttpHeaders?.ContentDisposition,
encryptionKey: ClientConfiguration.CustomerProvidedKey?.EncryptionKey,
encryptionKeySha256: ClientConfiguration.CustomerProvidedKey?.EncryptionKeyHash,
encryptionAlgorithm: ClientConfiguration.CustomerProvidedKey?.EncryptionAlgorithm == null ? null : EncryptionAlgorithmTypeInternal.AES256,
encryptionScope: ClientConfiguration.EncryptionScope,
tier: accessTier,
ifModifiedSince: conditions?.IfModifiedSince,
ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
ifMatch: conditions?.IfMatch?.ToString(),
ifNoneMatch: conditions?.IfNoneMatch?.ToString(),
ifTags: conditions?.TagConditions,
blobTagsString: tags?.ToTagsString(),
immutabilityPolicyExpiry: immutabilityPolicy?.ExpiresOn,
immutabilityPolicyMode: immutabilityPolicy?.PolicyMode,
legalHold: legalHold,
cancellationToken: cancellationToken);
}
return Response.FromValue(
response.ToBlobContentInfo(),
response.GetRawResponse());
}
catch (Exception ex)
{
ClientConfiguration.Pipeline.LogException(ex);
scope.Failed(ex);
throw;
}
finally
{
ClientConfiguration.Pipeline.LogMethodExit(nameof(BlockBlobClient));
scope.Dispose();
}
}
}