in sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs [1385:1788]
public virtual Response<BlobAppendInfo> AppendBlockFromUri(
Uri sourceUri,
AppendBlobAppendBlockFromUriOptions options = default,
CancellationToken cancellationToken = default) =>
AppendBlockFromUriInternal(
sourceUri,
options?.SourceRange ?? default,
options?.SourceContentHash,
options?.DestinationConditions,
options?.SourceConditions,
options?.SourceAuthentication,
options?.SourceShareTokenIntent,
async: false,
cancellationToken)
.EnsureCompleted();
/// <summary>
/// The <see cref="AppendBlockFromUriAsync(Uri, AppendBlobAppendBlockFromUriOptions, CancellationToken)"/>
/// operation commits a new block of data, represented by the <paramref name="sourceUri"/>,
/// to the end of the existing append blob. The
/// <see cref="AppendBlockFromUriAsync(Uri, AppendBlobAppendBlockFromUriOptions, CancellationToken)"/>
/// operation is only permitted if the blob was created as an append blob.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/append-block-from-url">
/// Append Block From URL</see>.
/// </summary>
/// <param name="sourceUri">
/// Specifies the <see cref="Uri"/> of the source blob. The value may
/// be a <see cref="Uri"/> of up to 2 KB in length that specifies a
/// blob. The source blob must either be public or must be
/// authenticated via a shared access signature. If the source blob
/// is public, no authentication is required to perform the operation.
/// </param>
/// <param name="options">
/// Optional parameters. <see cref="AppendBlobAppendBlockFromUriOptions"/>.
/// </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 append 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<BlobAppendInfo>> AppendBlockFromUriAsync(
Uri sourceUri,
AppendBlobAppendBlockFromUriOptions options = default,
CancellationToken cancellationToken = default) =>
await AppendBlockFromUriInternal(
sourceUri,
options?.SourceRange ?? default,
options?.SourceContentHash,
options?.DestinationConditions,
options?.SourceConditions,
options?.SourceAuthentication,
options?.SourceShareTokenIntent,
async: true,
cancellationToken)
.ConfigureAwait(false);
/// <summary>
/// The <see cref="AppendBlockFromUriAsync(Uri, HttpRange, byte[], AppendBlobRequestConditions, AppendBlobRequestConditions, CancellationToken)"/>
/// operation commits a new block of data, represented by the <paramref name="sourceUri"/>,
/// to the end of the existing append blob. The
/// <see cref="AppendBlockFromUriAsync(Uri, HttpRange, byte[], AppendBlobRequestConditions, AppendBlobRequestConditions, CancellationToken)"/>
/// operation is only permitted if the blob was created as an append blob.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/append-block-from-url">
/// Append Block From URL</see>.
/// </summary>
/// <param name="sourceUri">
/// Specifies the <see cref="Uri"/> of the source blob. The value may
/// be a <see cref="Uri"/> of up to 2 KB in length that specifies a
/// blob. The source blob must either be public or must be
/// authenticated via a shared access signature. If the source blob
/// is public, no authentication is required to perform the operation.
/// </param>
/// <param name="sourceRange">
/// Optionally only upload the bytes of the blob in the
/// <paramref name="sourceUri"/> in the specified range. If this is
/// not specified, the entire source blob contents are uploaded as a
/// single append block.
/// </param>
/// <param name="sourceContentHash">
/// Optional MD5 hash of the append block content from the
/// <paramref name="sourceUri"/>. This hash is used to verify the
/// integrity of the block during transport of the data from the Uri.
/// When this hash is specified, the storage service compares the hash
/// of the content that has arrived from the <paramref name="sourceUri"/>
/// with this value. Note that this md5 hash is not stored with the
/// blob. If the two hashes do not match, the operation will fail
/// with a <see cref="RequestFailedException"/>.
/// </param>
/// <param name="conditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the copying of data to this append blob.
/// </param>
/// <param name="sourceConditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the copying of data from this source 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 append 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)]
#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
public virtual Response<BlobAppendInfo> AppendBlockFromUri(
#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
Uri sourceUri,
HttpRange sourceRange,
byte[] sourceContentHash,
AppendBlobRequestConditions conditions,
AppendBlobRequestConditions sourceConditions,
CancellationToken cancellationToken) =>
AppendBlockFromUriInternal(
sourceUri,
sourceRange,
sourceContentHash,
conditions,
sourceConditions,
sourceAuthentication: default,
sourceShareTokenIntent: default,
async: false,
cancellationToken)
.EnsureCompleted();
/// <summary>
/// The <see cref="AppendBlockFromUriAsync(Uri, HttpRange, byte[], AppendBlobRequestConditions, AppendBlobRequestConditions, CancellationToken)"/>
/// operation commits a new block of data, represented by the <paramref name="sourceUri"/>,
/// to the end of the existing append blob. The
/// <see cref="AppendBlockFromUriAsync(Uri, HttpRange, byte[], AppendBlobRequestConditions, AppendBlobRequestConditions, CancellationToken)"/>
/// operation is only permitted if the blob was created as an append blob.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/append-block-from-url">
/// Append Block From URL</see>.
/// </summary>
/// <param name="sourceUri">
/// Specifies the <see cref="Uri"/> of the source blob. The value may
/// be a <see cref="Uri"/> of up to 2 KB in length that specifies a
/// blob. The source blob must either be public or must be
/// authenticated via a shared access signature. If the source blob
/// is public, no authentication is required to perform the operation.
/// </param>
/// <param name="sourceRange">
/// Optionally only upload the bytes of the blob in the
/// <paramref name="sourceUri"/> in the specified range. If this is
/// not specified, the entire source blob contents are uploaded as a
/// single append block.
/// </param>
/// <param name="sourceContentHash">
/// Optional MD5 hash of the append block content from the
/// <paramref name="sourceUri"/>. This hash is used to verify the
/// integrity of the block during transport of the data from the Uri.
/// When this hash is specified, the storage service compares the hash
/// of the content that has arrived from the <paramref name="sourceUri"/>
/// with this value. Note that this md5 hash is not stored with the
/// blob. If the two hashes do not match, the operation will fail
/// with a <see cref="RequestFailedException"/>.
/// </param>
/// <param name="conditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the copying of data to this append blob.
/// </param>
/// <param name="sourceConditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the copying of data from this source 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 append 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)]
#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
public virtual async Task<Response<BlobAppendInfo>> AppendBlockFromUriAsync(
#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional CancellationToken parameter called cancellationToken.
Uri sourceUri,
HttpRange sourceRange,
byte[] sourceContentHash,
AppendBlobRequestConditions conditions,
AppendBlobRequestConditions sourceConditions,
CancellationToken cancellationToken) =>
await AppendBlockFromUriInternal(
sourceUri,
sourceRange,
sourceContentHash,
conditions,
sourceConditions,
sourceAuthentication: default,
sourceShareTokenIntent: default,
async: true,
cancellationToken)
.ConfigureAwait(false);
/// <summary>
/// The <see cref="AppendBlockFromUriInternal"/> operation commits a new
/// block of data, represented by the <paramref name="sourceUri"/>,
/// to the end of the existing append blob. The
/// <see cref="AppendBlockFromUriInternal"/> operation is only permitted
/// if the blob was created as an append blob.
///
/// For more information, see
/// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/append-block-from-url">
/// Append Block From URL</see>.
/// </summary>
/// <param name="sourceUri">
/// Specifies the <see cref="Uri"/> of the source blob. The value may
/// be a <see cref="Uri"/> of up to 2 KB in length that specifies a
/// blob. The source blob must either be public or must be
/// authenticated via a shared access signature. If the source blob
/// is public, no authentication is required to perform the operation.
/// </param>
/// <param name="sourceRange">
/// Optionally only upload the bytes of the blob in the
/// <paramref name="sourceUri"/> in the specified range. If this is
/// not specified, the entire source blob contents are uploaded as a
/// single append block.
/// </param>
/// <param name="sourceContentHash">
/// Optional MD5 hash of the append block content from the
/// <paramref name="sourceUri"/>. This hash is used to verify the
/// integrity of the block during transport of the data from the Uri.
/// When this hash is specified, the storage service compares the hash
/// of the content that has arrived from the <paramref name="sourceUri"/>
/// with this value. Note that this md5 hash is not stored with the
/// blob. If the two hashes do not match, the operation will fail
/// with a <see cref="RequestFailedException"/>.
/// </param>
/// <param name="conditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the copying of data to this append blob.
/// </param>
/// <param name="sourceConditions">
/// Optional <see cref="AppendBlobRequestConditions"/> to add
/// conditions on the copying of data from this source blob.
/// </param>
/// <param name="sourceAuthentication">
/// Optional. Source authentication used to access the source blob.
/// </param>
/// <param name="sourceShareTokenIntent">
/// Optional, only applicable (but required) when the source is Azure Storage Files and using token authentication.
/// Used to indicate the intent of the request.
/// </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 append 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>
private async Task<Response<BlobAppendInfo>> AppendBlockFromUriInternal(
Uri sourceUri,
HttpRange sourceRange,
byte[] sourceContentHash,
AppendBlobRequestConditions conditions,
AppendBlobRequestConditions sourceConditions,
HttpAuthorization sourceAuthentication,
FileShareTokenIntent? sourceShareTokenIntent,
bool async,
CancellationToken cancellationToken = default)
{
using (ClientConfiguration.Pipeline.BeginLoggingScope(nameof(AppendBlobClient)))
{
ClientConfiguration.Pipeline.LogMethodEnter(
nameof(AppendBlobClient),
message:
$"{nameof(Uri)}: {Uri}\n" +
$"{nameof(sourceUri)}: {sourceUri}\n" +
$"{nameof(conditions)}: {conditions}");
DiagnosticScope scope = ClientConfiguration.ClientDiagnostics.CreateScope($"{nameof(AppendBlobClient)}.{nameof(AppendBlockFromUri)}");
// All destination AppendBlobRequestConditions are valid.
conditions.ValidateConditionsNotPresent(
invalidConditions: BlobRequestConditionProperty.None,
operationName: nameof(AppendBlobClient.AppendBlockFromUri),
parameterName: nameof(conditions));
sourceConditions.ValidateConditionsNotPresent(
invalidConditions:
BlobRequestConditionProperty.LeaseId
| BlobRequestConditionProperty.TagConditions
| BlobRequestConditionProperty.IfAppendPositionEqual
| BlobRequestConditionProperty.IfMaxSizeLessThanOrEqual,
operationName: nameof(AppendBlobClient.AppendBlockFromUri),
parameterName: nameof(sourceConditions));
try
{
scope.Start();
ResponseWithHeaders<AppendBlobAppendBlockFromUrlHeaders> response;
if (async)
{
response = await AppendBlobRestClient.AppendBlockFromUrlAsync(
sourceUrl: sourceUri.AbsoluteUri,
contentLength: 0,
sourceRange: sourceRange.ToString(),
sourceContentMD5: sourceContentHash,
encryptionKey: ClientConfiguration.CustomerProvidedKey?.EncryptionKey,
encryptionKeySha256: ClientConfiguration.CustomerProvidedKey?.EncryptionKeyHash,
encryptionAlgorithm: ClientConfiguration.CustomerProvidedKey?.EncryptionAlgorithm == null ? null : EncryptionAlgorithmTypeInternal.AES256,
encryptionScope: ClientConfiguration.EncryptionScope,
leaseId: conditions?.LeaseId,
maxSize: conditions?.IfMaxSizeLessThanOrEqual,
appendPosition: conditions?.IfAppendPositionEqual,
ifModifiedSince: conditions?.IfModifiedSince,
ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
ifMatch: conditions?.IfMatch?.ToString(),
ifNoneMatch: conditions?.IfNoneMatch?.ToString(),
ifTags: conditions?.TagConditions,
sourceIfModifiedSince: sourceConditions?.IfModifiedSince,
sourceIfUnmodifiedSince: sourceConditions?.IfUnmodifiedSince,
sourceIfMatch: sourceConditions?.IfMatch?.ToString(),
sourceIfNoneMatch: sourceConditions?.IfNoneMatch?.ToString(),
copySourceAuthorization: sourceAuthentication?.ToString(),
fileRequestIntent: sourceShareTokenIntent,
cancellationToken: cancellationToken)
.ConfigureAwait(false);
}
else
{
response = AppendBlobRestClient.AppendBlockFromUrl(
sourceUrl: sourceUri.AbsoluteUri,
contentLength: 0,
sourceRange: sourceRange.ToString(),
sourceContentMD5: sourceContentHash,
encryptionKey: ClientConfiguration.CustomerProvidedKey?.EncryptionKey,
encryptionKeySha256: ClientConfiguration.CustomerProvidedKey?.EncryptionKeyHash,
encryptionAlgorithm: ClientConfiguration.CustomerProvidedKey?.EncryptionAlgorithm == null ? null : EncryptionAlgorithmTypeInternal.AES256,
encryptionScope: ClientConfiguration.EncryptionScope,
leaseId: conditions?.LeaseId,
maxSize: conditions?.IfMaxSizeLessThanOrEqual,
appendPosition: conditions?.IfAppendPositionEqual,
ifModifiedSince: conditions?.IfModifiedSince,
ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
ifMatch: conditions?.IfMatch?.ToString(),
ifNoneMatch: conditions?.IfNoneMatch?.ToString(),
ifTags: conditions?.TagConditions,
sourceIfModifiedSince: sourceConditions?.IfModifiedSince,
sourceIfUnmodifiedSince: sourceConditions?.IfUnmodifiedSince,
sourceIfMatch: sourceConditions?.IfMatch?.ToString(),
sourceIfNoneMatch: sourceConditions?.IfNoneMatch?.ToString(),
copySourceAuthorization: sourceAuthentication?.ToString(),
fileRequestIntent: sourceShareTokenIntent,
cancellationToken: cancellationToken);
}
return Response.FromValue(
response.ToBlobAppendInfo(),
response.GetRawResponse());
}
catch (Exception ex)
{
ClientConfiguration.Pipeline.LogException(ex);
scope.Failed(ex);
throw;
}
finally
{
ClientConfiguration.Pipeline.LogMethodExit(nameof(AppendBlobClient));
scope.Dispose();
}
}
}