Пример #1
0
        /// <summary>
        /// The SetBlobsAccessTierAsync operation sets the tier on blobs.  The
        /// operation is allowed on block blobs in a blob storage or general
        /// purpose v2 account.
        /// </summary>
        /// <param name="blobUris">
        /// URIs of the blobs to set the tiers of.
        /// </param>
        /// <param name="accessTier">
        /// Indicates the tier to be set on the blobs.
        /// </param>
        /// <param name="rehydratePriority">
        /// Optional <see cref="RehydratePriority"/>
        /// Indicates the priority with which to rehydrate an archived blob.
        /// </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>
        /// The <see cref="Response"/>s for the individual Set Tier operations.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure to submit the batch occurs.  Individual sub-operation
        /// failures will be wrapped in an <see cref="AggregateException"/>.
        /// </remarks>
        internal async Task <Response[]> SetBlobsAccessTierInteral(
            IEnumerable <Uri> blobUris,
            AccessTier accessTier,
            RehydratePriority?rehydratePriority,
            bool async,
            CancellationToken cancellationToken)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(BlobBatchClient)}.{nameof(SetBlobsAccessTier)}");

            try
            {
                scope.Start();

                blobUris = blobUris ?? throw new ArgumentNullException(nameof(blobUris));
                var responses = new List <Response>();

                // Create the batch
                BlobBatch batch = CreateBatch();
                foreach (Uri uri in blobUris)
                {
                    responses.Add(batch.SetBlobAccessTier(uri, accessTier, rehydratePriority));
                }

                // Submit the batch
                await SubmitBatchInternal(
                    batch,
                    true,
                    async,
                    cancellationToken)
                .ConfigureAwait(false);

                return(responses.ToArray());
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
Пример #2
0
        /// <summary>
        /// The DeleteBlobsAsync operation marks the specified blobs for
        /// deletion.  The blobs are later deleted during garbage collection
        /// which could take several minutes.
        /// All of the deletions are sent as a single batched request.
        /// </summary>
        /// <param name="blobUris">URIs of the blobs to delete.</param>
        /// <param name="snapshotsOption">
        /// Specifies options for deleting blob snapshots.
        /// </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>
        /// The <see cref="Response"/>s for the individual Delete operations.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure to submit the batch occurs.  Individual sub-operation
        /// failures will be wrapped in an <see cref="AggregateException"/>.
        /// </remarks>
        internal async Task <Response[]> DeleteBlobsInteral(
            IEnumerable <Uri> blobUris,
            DeleteSnapshotsOption snapshotsOption,
            bool async,
            CancellationToken cancellationToken)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(BlobBatchClient)}.{nameof(DeleteBlobs)}");

            try
            {
                scope.Start();

                blobUris = blobUris ?? throw new ArgumentNullException(nameof(blobUris));
                var responses = new List <Response>();

                // Create the batch
                BlobBatch batch = CreateBatch();
                foreach (Uri uri in blobUris)
                {
                    responses.Add(batch.DeleteBlob(uri, snapshotsOption));
                }

                // Submit the batch
                await SubmitBatchInternal(
                    batch,
                    true,
                    async,
                    cancellationToken)
                .ConfigureAwait(false);

                return(responses.ToArray());
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
Пример #3
0
        /// <summary>
        /// Submit a <see cref="BlobBatch"/> of sub-operations.
        /// </summary>
        /// <param name="batch">
        /// A <see cref="BlobBatch"/> of sub-operations.
        /// </param>
        /// <param name="throwOnAnyFailure">
        /// A value indicating whether or not to throw exceptions for
        /// sub-operation failures.
        /// </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"/> on successfully submitting.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure to submit the batch occurs.  Individual sub-operation
        /// failures will only throw if <paramref name="throwOnAnyFailure"/> is
        /// true and be wrapped in an <see cref="AggregateException"/>.
        /// </remarks>
        private async Task <Response> SubmitBatchInternal(
            BlobBatch batch,
            bool throwOnAnyFailure,
            bool async,
            CancellationToken cancellationToken)
        {
            batch = batch ?? throw new ArgumentNullException(nameof(batch));
            if (batch.Submitted)
            {
                throw BatchErrors.CannotResubmitBatch(nameof(batch));
            }
            else if (!batch.IsAssociatedClient(this))
            {
                throw BatchErrors.BatchClientDoesNotMatch(nameof(batch));
            }

            // Get the sub-operation messages to submit
            IList <HttpMessage> messages = batch.GetMessagesToSubmit();

            if (messages.Count == 0)
            {
                throw BatchErrors.CannotSubmitEmptyBatch(nameof(batch));
            }
            // TODO: Consider validating the upper limit of 256 messages

            // Merge the sub-operations into a single multipart/mixed Stream
            (Stream content, string contentType) =
                await MergeOperationRequests(
                    messages,
                    async,
                    cancellationToken)
                .ConfigureAwait(false);

            // Send the batch request
            Response <BlobBatchResult> batchResult =
                await BatchRestClient.Service.SubmitBatchAsync(
                    ClientDiagnostics,
                    Pipeline,
                    Uri,
                    body : content,
                    contentLength : content.Length,
                    multipartContentType : contentType,
                    async : async,
                    operationName : BatchConstants.BatchOperationName,
                    cancellationToken : cancellationToken)
                .ConfigureAwait(false);

            // Split the responses apart and update the sub-operation responses
            Response raw = batchResult.GetRawResponse();

            await UpdateOperationResponses(
                messages,
                raw,
                batchResult.Value.Content,
                batchResult.Value.ContentType,
                throwOnAnyFailure,
                async,
                cancellationToken)
            .ConfigureAwait(false);

            // Return the batch result
            return(raw);
        }
Пример #4
0
        /// <summary>
        /// Submit a <see cref="BlobBatch"/> of sub-operations.
        /// </summary>
        /// <param name="batch">
        /// A <see cref="BlobBatch"/> of sub-operations.
        /// </param>
        /// <param name="throwOnAnyFailure">
        /// A value indicating whether or not to throw exceptions for
        /// sub-operation failures.
        /// </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"/> on successfully submitting.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure to submit the batch occurs.  Individual sub-operation
        /// failures will only throw if <paramref name="throwOnAnyFailure"/> is
        /// true and be wrapped in an <see cref="AggregateException"/>.
        /// </remarks>
        private async Task <Response> SubmitBatchInternal(
            BlobBatch batch,
            bool throwOnAnyFailure,
            bool async,
            CancellationToken cancellationToken)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(BlobBatchClient)}.{nameof(SubmitBatch)}");

            try
            {
                scope.Start();

                batch = batch ?? throw new ArgumentNullException(nameof(batch));
                if (batch.Submitted)
                {
                    throw BatchErrors.CannotResubmitBatch(nameof(batch));
                }
                else if (!batch.IsAssociatedClient(this))
                {
                    throw BatchErrors.BatchClientDoesNotMatch(nameof(batch));
                }

                // Get the sub-operation messages to submit
                IList <HttpMessage> messages = batch.GetMessagesToSubmit();
                if (messages.Count == 0)
                {
                    throw BatchErrors.CannotSubmitEmptyBatch(nameof(batch));
                }
                // TODO: Consider validating the upper limit of 256 messages

                // Merge the sub-operations into a single multipart/mixed Stream
                (Stream content, string contentType) =
                    await MergeOperationRequests(
                        messages,
                        async,
                        cancellationToken)
                    .ConfigureAwait(false);

                if (IsContainerScoped)
                {
                    ResponseWithHeaders <Stream, ContainerSubmitBatchHeaders> response;

                    if (async)
                    {
                        response = await _containerRestClient.SubmitBatchAsync(
                            containerName : ContainerName,
                            contentLength : content.Length,
                            multipartContentType : contentType,
                            body : content,
                            cancellationToken : cancellationToken)
                                   .ConfigureAwait(false);
                    }
                    else
                    {
                        response = _containerRestClient.SubmitBatch(
                            containerName: ContainerName,
                            contentLength: content.Length,
                            multipartContentType: contentType,
                            body: content,
                            cancellationToken: cancellationToken);
                    }

                    await UpdateOperationResponses(
                        messages,
                        response.GetRawResponse(),
                        response.Value,
                        response.Headers.ContentType,
                        throwOnAnyFailure,
                        async,
                        cancellationToken)
                    .ConfigureAwait(false);

                    return(response.GetRawResponse());
                }
                else
                {
                    ResponseWithHeaders <Stream, ServiceSubmitBatchHeaders> response;

                    if (async)
                    {
                        response = await _serviceRestClient.SubmitBatchAsync(
                            contentLength : content.Length,
                            multipartContentType : contentType,
                            body : content,
                            cancellationToken : cancellationToken)
                                   .ConfigureAwait(false);
                    }
                    else
                    {
                        response = _serviceRestClient.SubmitBatch(
                            contentLength: content.Length,
                            multipartContentType: contentType,
                            body: content,
                            cancellationToken: cancellationToken);
                    }

                    await UpdateOperationResponses(
                        messages,
                        response.GetRawResponse(),
                        response.Value,
                        response.Headers.ContentType,
                        throwOnAnyFailure,
                        async,
                        cancellationToken)
                    .ConfigureAwait(false);

                    return(response.GetRawResponse());
                }
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }
Пример #5
0
        /// <summary>
        /// Submit a <see cref="BlobBatch"/> of sub-operations.
        /// </summary>
        /// <param name="batch">
        /// A <see cref="BlobBatch"/> of sub-operations.
        /// </param>
        /// <param name="throwOnAnyFailure">
        /// A value indicating whether or not to throw exceptions for
        /// sub-operation failures.
        /// </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"/> on successfully submitting.
        /// </returns>
        /// <remarks>
        /// A <see cref="RequestFailedException"/> will be thrown if
        /// a failure to submit the batch occurs.  Individual sub-operation
        /// failures will only throw if <paramref name="throwOnAnyFailure"/> is
        /// true and be wrapped in an <see cref="AggregateException"/>.
        /// </remarks>
        private async Task <Response> SubmitBatchInternal(
            BlobBatch batch,
            bool throwOnAnyFailure,
            bool async,
            CancellationToken cancellationToken)
        {
            DiagnosticScope scope = ClientDiagnostics.CreateScope($"{nameof(BlobBatchClient)}.{nameof(SubmitBatch)}");

            try
            {
                scope.Start();

                batch = batch ?? throw new ArgumentNullException(nameof(batch));
                if (batch.Submitted)
                {
                    throw BatchErrors.CannotResubmitBatch(nameof(batch));
                }
                else if (!batch.IsAssociatedClient(this))
                {
                    throw BatchErrors.BatchClientDoesNotMatch(nameof(batch));
                }

                // Get the sub-operation messages to submit
                IList <HttpMessage> messages = batch.GetMessagesToSubmit();
                if (messages.Count == 0)
                {
                    throw BatchErrors.CannotSubmitEmptyBatch(nameof(batch));
                }
                // TODO: Consider validating the upper limit of 256 messages

                // Merge the sub-operations into a single multipart/mixed Stream
                (Stream content, string contentType) =
                    await MergeOperationRequests(
                        messages,
                        async,
                        cancellationToken)
                    .ConfigureAwait(false);

                // Send the batch request
                Response <BlobBatchResult> batchResult;

                if (_isContainerScoped)
                {
                    batchResult = await BatchRestClient.Container.SubmitBatchAsync(
                        clientDiagnostics : ClientDiagnostics,
                        pipeline : Pipeline,
                        resourceUri : Uri,
                        body : content,
                        contentLength : content.Length,
                        multipartContentType : contentType,
                        version : Version.ToVersionString(),
                        async : async,
                        operationName : $"{nameof(BlobBatchClient)}.{nameof(SubmitBatch)}",
                        cancellationToken : cancellationToken)
                                  .ConfigureAwait(false);
                }
                else
                {
                    batchResult = await BatchRestClient.Service.SubmitBatchAsync(
                        clientDiagnostics : ClientDiagnostics,
                        pipeline : Pipeline,
                        resourceUri : Uri,
                        body : content,
                        contentLength : content.Length,
                        multipartContentType : contentType,
                        version : Version.ToVersionString(),
                        async : async,
                        operationName : $"{nameof(BlobBatchClient)}.{nameof(SubmitBatch)}",
                        cancellationToken : cancellationToken)
                                  .ConfigureAwait(false);
                }

                // Split the responses apart and update the sub-operation responses
                Response raw = batchResult.GetRawResponse();
                await UpdateOperationResponses(
                    messages,
                    raw,
                    batchResult.Value.Content,
                    batchResult.Value.ContentType,
                    throwOnAnyFailure,
                    async,
                    cancellationToken)
                .ConfigureAwait(false);

                // Return the batch result
                return(raw);
            }
            catch (Exception ex)
            {
                scope.Failed(ex);
                throw;
            }
            finally
            {
                scope.Dispose();
            }
        }