public virtual Response AppendBlockFromUri()

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();
                }
            }
        }