< Summary

Class:Azure.Storage.Blobs.BlobContainerClient
Assembly:Azure.Storage.Blobs
File(s):C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Blobs\src\BlobContainerClient.cs
Covered lines:457
Uncovered lines:8
Coverable lines:465
Total lines:2761
Line coverage:98.2% (457 of 465)
Covered branches:66
Total branches:76
Branch coverage:86.8% (66 of 76)

Metrics

MethodCyclomatic complexity Line coverage Branch coverage
.cctor()-0%100%
get_Uri()-100%100%
get_Pipeline()-100%100%
get_Version()-100%100%
get_ClientDiagnostics()-100%100%
get_CustomerProvidedKey()-100%100%
get_ClientSideEncryption()-100%100%
get_EncryptionScope()-100%100%
get_AccountName()-100%100%
get_Name()-100%100%
.ctor()-100%100%
.ctor(...)-100%100%
.ctor(...)-100%100%
.ctor(...)-100%100%
.ctor(...)-100%100%
.ctor(...)-100%100%
.ctor(...)-100%75%
.ctor(...)-100%50%
CreateClient(...)-100%100%
GetBlobClient(...)-100%100%
SetNameFieldsIfNull()-100%100%
Create(...)-100%100%
Create(...)-100%100%
CreateAsync()-100%100%
CreateAsync()-100%100%
CreateIfNotExists(...)-100%100%
CreateIfNotExists(...)-100%100%
CreateIfNotExistsAsync()-100%100%
CreateIfNotExistsAsync()-100%100%
CreateIfNotExistsInternal()-100%100%
CreateInternal()-100%66.67%
Delete(...)-100%100%
DeleteAsync()-100%100%
DeleteIfExists(...)-100%100%
DeleteIfExistsAsync()-100%100%
DeleteIfExistsInternal()-100%100%
DeleteInternal()-100%100%
Exists(...)-100%100%
ExistsAsync()-100%100%
ExistsInternal()-100%100%
GetProperties(...)-100%100%
GetPropertiesAsync()-100%100%
GetPropertiesInternal()-100%50%
SetMetadata(...)-100%100%
SetMetadataAsync()-100%100%
SetMetadataInternal()-82.61%81.25%
GetAccessPolicy(...)-100%100%
GetAccessPolicyAsync()-100%100%
GetAccessPolicyInternal()-100%100%
SetAccessPolicy(...)-100%100%
SetAccessPolicyAsync()-100%100%
SetAccessPolicyInternal()-95.24%85.71%
GetBlobs(...)-100%100%
GetBlobsAsync(...)-100%100%
GetBlobsInternal()-100%100%
GetBlobsByHierarchy(...)-100%100%
GetBlobsByHierarchyAsync(...)-100%100%
GetBlobsByHierarchyInternal()-100%100%
UploadBlob(...)-100%100%
UploadBlobAsync()-100%100%
DeleteBlob(...)-100%100%
DeleteBlobAsync()-100%100%
DeleteBlobIfExists(...)-100%100%
DeleteBlobIfExistsAsync()-100%100%

File(s)

C:\Git\azure-sdk-for-net\sdk\storage\Azure.Storage.Blobs\src\BlobContainerClient.cs

#LineLine coverage
 1// Copyright (c) Microsoft Corporation. All rights reserved.
 2// Licensed under the MIT License.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.ComponentModel;
 7using System.IO;
 8using System.Threading;
 9using System.Threading.Tasks;
 10using Azure.Core;
 11using Azure.Core.Pipeline;
 12using Azure.Storage.Blobs.Models;
 13using Azure.Storage.Blobs.Specialized;
 14using Azure.Storage.Cryptography;
 15using Metadata = System.Collections.Generic.IDictionary<string, string>;
 16
 17namespace Azure.Storage.Blobs
 18{
 19    /// <summary>
 20    /// The <see cref="BlobContainerClient"/> allows you to manipulate Azure
 21    /// Storage containers and their blobs.
 22    /// </summary>
 23  public class BlobContainerClient
 24    {
 25        /// <summary>
 26        /// The Azure Storage name used to identify a storage account's root container.
 27        /// </summary>
 028        public static readonly string RootBlobContainerName = Constants.Blob.Container.RootName;
 29
 30        /// <summary>
 31        /// The Azure Storage name used to identify a storage account's logs container.
 32        /// </summary>
 033        public static readonly string LogsBlobContainerName = Constants.Blob.Container.LogsName;
 34
 35        /// <summary>
 36        /// The Azure Storage name used to identify a storage account's web content container.
 37        /// </summary>
 038        public static readonly string WebBlobContainerName = Constants.Blob.Container.WebName;
 39
 40#pragma warning disable IDE0032 // Use auto property
 41        /// <summary>
 42        /// Gets the container's primary <see cref="Uri"/> endpoint.
 43        /// </summary>
 44        private readonly Uri _uri;
 45#pragma warning restore IDE0032 // Use auto property
 46
 47        /// <summary>
 48        /// Gets the container's primary <see cref="Uri"/> endpoint.
 49        /// </summary>
 2136650        public virtual Uri Uri => _uri;
 51
 52        /// <summary>
 53        /// The <see cref="HttpPipeline"/> transport pipeline used to send
 54        /// every request.
 55        /// </summary>
 56        private readonly HttpPipeline _pipeline;
 57
 58        /// <summary>
 59        /// The <see cref="HttpPipeline"/> transport pipeline used to send
 60        /// every request.
 61        /// </summary>
 3393262        internal virtual HttpPipeline Pipeline => _pipeline;
 63
 64        /// <summary>
 65        /// The version of the service to use when sending requests.
 66        /// </summary>
 67        private readonly BlobClientOptions.ServiceVersion _version;
 68
 69        /// <summary>
 70        /// The version of the service to use when sending requests.
 71        /// </summary>
 2097472        internal virtual BlobClientOptions.ServiceVersion Version => _version;
 73
 74        /// <summary>
 75        /// The <see cref="ClientDiagnostics"/> instance used to create diagnostic scopes
 76        /// every request.
 77        /// </summary>
 78        private readonly ClientDiagnostics _clientDiagnostics;
 79
 80        /// <summary>
 81        /// The <see cref="ClientDiagnostics"/> instance used to create diagnostic scopes
 82        /// every request.
 83        /// </summary>
 2097484        internal virtual ClientDiagnostics ClientDiagnostics => _clientDiagnostics;
 85
 86        /// <summary>
 87        /// The <see cref="CustomerProvidedKey"/> to be used when sending requests.
 88        /// </summary>
 89        internal readonly CustomerProvidedKey? _customerProvidedKey;
 90
 91        /// <summary>
 92        /// The <see cref="CustomerProvidedKey"/> to be used when sending requests.
 93        /// </summary>
 600494        internal virtual CustomerProvidedKey? CustomerProvidedKey => _customerProvidedKey;
 95
 96        /// <summary>
 97        /// The <see cref="ClientSideEncryptionOptions"/> to be used when sending/receiving requests.
 98        /// </summary>
 99        private readonly ClientSideEncryptionOptions _clientSideEncryption;
 100
 101        /// <summary>
 102        /// The <see cref="ClientSideEncryptionOptions"/> to be used when sending/receiving requests.
 103        /// </summary>
 6004104        internal virtual ClientSideEncryptionOptions ClientSideEncryption => _clientSideEncryption;
 105
 106        /// <summary>
 107        /// The <see cref="EncryptionScope"/> to be used when sending requests.
 108        /// </summary>
 109        internal readonly string _encryptionScope;
 110
 111        /// <summary>
 112        /// The <see cref="EncryptionScope"/> to be used when sending requests.
 113        /// </summary>
 6004114        internal virtual string EncryptionScope => _encryptionScope;
 115
 116        /// <summary>
 117        /// The Storage account name corresponding to the container client.
 118        /// </summary>
 119        private string _accountName;
 120
 121        /// <summary>
 122        /// Gets the Storage account name corresponding to the container client.
 123        /// </summary>
 124        public virtual string AccountName
 125        {
 126            get
 127            {
 20128                SetNameFieldsIfNull();
 20129                return _accountName;
 130            }
 131        }
 132
 133        /// <summary>
 134        /// The name of the container.
 135        /// </summary>
 136        private string _name;
 137
 138        /// <summary>
 139        /// Gets the name of the container.
 140        /// </summary>
 141        public virtual string Name
 142        {
 143            get
 144            {
 280145                SetNameFieldsIfNull();
 280146                return _name;
 147            }
 148        }
 149
 150        #region ctor
 151        /// <summary>
 152        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 153        /// class for mocking.
 154        /// </summary>
 4440155        protected BlobContainerClient()
 156        {
 4440157        }
 158
 159        /// <summary>
 160        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 161        /// class.
 162        /// </summary>
 163        /// <param name="connectionString">
 164        /// A connection string includes the authentication information
 165        /// required for your application to access data in an Azure Storage
 166        /// account at runtime.
 167        ///
 168        /// For more information,
 169        /// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">
 170        /// Configure Azure Storage connection strings</see>
 171        /// </param>
 172        /// <param name="blobContainerName">
 173        /// The name of the blob container in the storage account to reference.
 174        /// </param>
 175        public BlobContainerClient(string connectionString, string blobContainerName)
 4176            : this(connectionString, blobContainerName, null)
 177        {
 4178        }
 179
 180        /// <summary>
 181        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 182        /// class.
 183        /// </summary>
 184        /// <param name="connectionString">
 185        /// A connection string includes the authentication information
 186        /// required for your application to access data in an Azure Storage
 187        /// account at runtime.
 188        ///
 189        /// For more information,
 190        /// <see href="https://docs.microsoft.com/azure/storage/common/storage-configure-connection-string">
 191        /// Configure Azure Storage connection strings</see>
 192        /// </param>
 193        /// <param name="blobContainerName">
 194        /// The name of the container in the storage account to reference.
 195        /// </param>
 196        /// <param name="options">
 197        /// Optional client options that define the transport pipeline
 198        /// policies for authentication, retries, etc., that are applied to
 199        /// every request.
 200        /// </param>
 36201        public BlobContainerClient(string connectionString, string blobContainerName, BlobClientOptions options)
 202        {
 36203            var conn = StorageConnectionString.Parse(connectionString);
 36204            var builder = new BlobUriBuilder(conn.BlobEndpoint) { BlobContainerName = blobContainerName };
 36205            _uri = builder.ToUri();
 36206            options ??= new BlobClientOptions();
 36207            _pipeline = options.Build(conn.Credentials);
 36208            _version = options.Version;
 36209            _clientDiagnostics = new ClientDiagnostics(options);
 36210            _customerProvidedKey = options.CustomerProvidedKey;
 36211            _encryptionScope = options.EncryptionScope;
 36212            BlobErrors.VerifyHttpsCustomerProvidedKey(_uri, _customerProvidedKey);
 36213            BlobErrors.VerifyCpkAndEncryptionScopeNotBothSet(_customerProvidedKey, _encryptionScope);
 36214        }
 215
 216        /// <summary>
 217        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 218        /// class.
 219        /// </summary>
 220        /// <param name="blobContainerUri">
 221        /// A <see cref="Uri"/> referencing the blob container that includes the
 222        /// name of the account and the name of the container.
 223        /// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}".
 224        /// </param>
 225        /// <param name="options">
 226        /// Optional client options that define the transport pipeline
 227        /// policies for authentication, retries, etc., that are applied to
 228        /// every request.
 229        /// </param>
 230        public BlobContainerClient(Uri blobContainerUri, BlobClientOptions options = default)
 40231            : this(blobContainerUri, (HttpPipelinePolicy)null,  options)
 232        {
 36233        }
 234
 235        /// <summary>
 236        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 237        /// class.
 238        /// </summary>
 239        /// <param name="blobContainerUri">
 240        /// A <see cref="Uri"/> referencing the blob container that includes the
 241        /// name of the account and the name of the container.
 242        /// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}".
 243        /// </param>
 244        /// <param name="credential">
 245        /// The shared key credential used to sign requests.
 246        /// </param>
 247        /// <param name="options">
 248        /// Optional client options that define the transport pipeline
 249        /// policies for authentication, retries, etc., that are applied to
 250        /// every request.
 251        /// </param>
 252        public BlobContainerClient(Uri blobContainerUri, StorageSharedKeyCredential credential, BlobClientOptions option
 24253            : this(blobContainerUri, credential.AsPolicy(), options)
 254        {
 24255        }
 256
 257        /// <summary>
 258        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 259        /// class.
 260        /// </summary>
 261        /// <param name="blobContainerUri">
 262        /// A <see cref="Uri"/> referencing the blob container that includes the
 263        /// name of the account and the name of the container.
 264        /// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}".
 265        /// </param>
 266        /// <param name="credential">
 267        /// The token credential used to sign requests.
 268        /// </param>
 269        /// <param name="options">
 270        /// Optional client options that define the transport pipeline
 271        /// policies for authentication, retries, etc., that are applied to
 272        /// every request.
 273        /// </param>
 274        public BlobContainerClient(Uri blobContainerUri, TokenCredential credential, BlobClientOptions options = default
 8275            : this(blobContainerUri, credential.AsPolicy(), options)
 276        {
 8277            Errors.VerifyHttpsTokenAuth(blobContainerUri);
 4278        }
 279
 280        /// <summary>
 281        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 282        /// class.
 283        /// </summary>
 284        /// <param name="blobContainerUri">
 285        /// A <see cref="Uri"/> referencing the blob container that includes the
 286        /// name of the account and the name of the container.
 287        /// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}".
 288        /// </param>
 289        /// <param name="authentication">
 290        /// An optional authentication policy used to sign requests.
 291        /// </param>
 292        /// <param name="options">
 293        /// Optional client options that define the transport pipeline
 294        /// policies for authentication, retries, etc., that are applied to
 295        /// every request.
 296        /// </param>
 72297        internal BlobContainerClient(Uri blobContainerUri, HttpPipelinePolicy authentication, BlobClientOptions options)
 298        {
 72299            _uri = blobContainerUri;
 72300            options ??= new BlobClientOptions();
 72301            _pipeline = options.Build(authentication);
 72302            _version = options.Version;
 72303            _clientDiagnostics = new ClientDiagnostics(options);
 72304            _customerProvidedKey = options.CustomerProvidedKey;
 72305            _clientSideEncryption = options._clientSideEncryptionOptions?.Clone();
 72306            _encryptionScope = options.EncryptionScope;
 72307            BlobErrors.VerifyHttpsCustomerProvidedKey(_uri, _customerProvidedKey);
 68308            BlobErrors.VerifyCpkAndEncryptionScopeNotBothSet(_customerProvidedKey, _encryptionScope);
 68309        }
 310
 311        /// <summary>
 312        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 313        /// class.
 314        /// </summary>
 315        /// <param name="containerUri">
 316        /// A <see cref="Uri"/> referencing the blob container that includes the
 317        /// name of the account and the name of the container.
 318        /// This is likely to be similar to "https://{account_name}.blob.core.windows.net/{container_name}".
 319        /// </param>
 320        /// <param name="pipeline">
 321        /// The transport pipeline used to send every request.
 322        /// </param>
 323        /// <param name="version">
 324        /// The version of the service to use when sending requests.
 325        /// </param>
 326        /// <param name="clientDiagnostics"></param>
 327        /// <param name="customerProvidedKey">Customer provided key.</param>
 328        /// <param name="clientSideEncryption"></param>
 329        /// <param name="encryptionScope">Encryption scope.</param>
 7074330        internal BlobContainerClient(
 7074331            Uri containerUri,
 7074332            HttpPipeline pipeline,
 7074333            BlobClientOptions.ServiceVersion version,
 7074334            ClientDiagnostics clientDiagnostics,
 7074335            CustomerProvidedKey? customerProvidedKey,
 7074336            ClientSideEncryptionOptions clientSideEncryption,
 7074337            string encryptionScope)
 338        {
 7074339            _uri = containerUri;
 7074340            _pipeline = pipeline;
 7074341            _version = version;
 7074342            _clientDiagnostics = clientDiagnostics;
 7074343            _customerProvidedKey = customerProvidedKey;
 7074344            _clientSideEncryption = clientSideEncryption?.Clone();
 7074345            _encryptionScope = encryptionScope;
 7074346            BlobErrors.VerifyHttpsCustomerProvidedKey(_uri, _customerProvidedKey);
 7074347            BlobErrors.VerifyCpkAndEncryptionScopeNotBothSet(_customerProvidedKey, _encryptionScope);
 7074348        }
 349
 350        /// <summary>
 351        /// Initializes a new instance of the <see cref="BlobContainerClient"/>
 352        /// class.
 353        /// </summary>
 354        /// <param name="containerUri">
 355        /// A <see cref="Uri"/> referencing the block blob that includes the
 356        /// name of the account, the name of the container, and the name of
 357        /// the blob.
 358        /// </param>
 359        /// <param name="options">
 360        /// Optional client options that define the transport pipeline
 361        /// policies for authentication, retries, etc., that are applied to
 362        /// every request.
 363        /// </param>
 364        /// <param name="pipeline">
 365        /// The transport pipeline used to send every request.
 366        /// </param>
 367        /// <returns>
 368        /// New instance of the <see cref="BlobContainerClient"/> class.
 369        /// </returns>
 370        protected static BlobContainerClient CreateClient(Uri containerUri, BlobClientOptions options, HttpPipeline pipe
 371        {
 2982372            return new BlobContainerClient(
 2982373                containerUri,
 2982374                pipeline,
 2982375                options.Version,
 2982376                new ClientDiagnostics(options),
 2982377                customerProvidedKey: null,
 2982378                clientSideEncryption: null,
 2982379                encryptionScope: null);
 380        }
 381        #endregion ctor
 382
 383        /// <summary>
 384        /// Create a new <see cref="BlobClient"/> object by appending
 385        /// <paramref name="blobName"/> to the end of <see cref="Uri"/>.  The
 386        /// new <see cref="BlobClient"/> uses the same request policy
 387        /// pipeline as the <see cref="BlobContainerClient"/>.
 388        /// </summary>
 389        /// <param name="blobName">The name of the blob.</param>
 390        /// <returns>A new <see cref="BlobClient"/> instance.</returns>
 391        public virtual BlobClient GetBlobClient(string blobName)
 392        {
 2072393            BlobUriBuilder blobUriBuilder = new BlobUriBuilder(Uri)
 2072394            {
 2072395                BlobName = blobName
 2072396            };
 397
 2072398            return new BlobClient(
 2072399                blobUriBuilder.ToUri(),
 2072400                _pipeline,
 2072401                Version,
 2072402                ClientDiagnostics,
 2072403                CustomerProvidedKey,
 2072404                ClientSideEncryption,
 2072405                EncryptionScope);
 406        }
 407
 408
 409        /// <summary>
 410        /// Sets the various name fields if they are currently null.
 411        /// </summary>
 412        private void SetNameFieldsIfNull()
 413        {
 300414            if (_name == null || _accountName == null)
 415            {
 164416                var builder = new BlobUriBuilder(Uri);
 164417                _name = builder.BlobContainerName;
 164418                _accountName = builder.AccountName;
 419            }
 300420        }
 421
 422        #region Create
 423        /// <summary>
 424        /// The <see cref="Create(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, CancellationToken)"/>
 425        /// operation creates a new container
 426        /// under the specified account. If the container with the same name
 427        /// already exists, the operation fails.
 428        ///
 429        /// For more information, see
 430        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 431        /// Create Container</see>.
 432        /// </summary>
 433        /// <param name="publicAccessType">
 434        /// Optionally specifies whether data in the container may be accessed
 435        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 436        /// specifies full public read access for container and blob data.
 437        /// Clients can enumerate blobs within the container via anonymous
 438        /// request, but cannot enumerate containers within the storage
 439        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 440        /// read access for blobs.  Blob data within this container can be
 441        /// read via anonymous request, but container data is not available.
 442        /// Clients cannot enumerate blobs within the container via anonymous
 443        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 444        /// container data is private to the account owner.
 445        /// </param>
 446        /// <param name="metadata">
 447        /// Optional custom metadata to set for this container.
 448        /// </param>
 449        /// <param name="encryptionScopeOptions">
 450        /// Optional encryption scope options to set for this container.
 451        /// </param>
 452        /// <param name="cancellationToken">
 453        /// Optional <see cref="CancellationToken"/> to propagate
 454        /// notifications that the operation should be cancelled.
 455        /// </param>
 456        /// <returns>
 457        /// A <see cref="Response{BlobContainerInfo}"/> describing the newly
 458        /// created blob container.
 459        /// </returns>
 460        /// <remarks>
 461        /// A <see cref="RequestFailedException"/> will be thrown if
 462        /// a failure occurs.
 463        /// </remarks>
 464        public virtual Response<BlobContainerInfo> Create(
 465            PublicAccessType publicAccessType = PublicAccessType.None,
 466            Metadata metadata = default,
 467            BlobContainerEncryptionScopeOptions encryptionScopeOptions = default,
 468            CancellationToken cancellationToken = default) =>
 1906469            CreateInternal(
 1906470                publicAccessType,
 1906471                metadata,
 1906472                encryptionScopeOptions,
 1906473                async: false,
 1906474                cancellationToken)
 1906475                .EnsureCompleted();
 476
 477        /// <summary>
 478        /// The <see cref="Create(PublicAccessType, Metadata, CancellationToken)"/> operation creates a new container
 479        /// under the specified account. If the container with the same name
 480        /// already exists, the operation fails.
 481        ///
 482        /// For more information, see
 483        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 484        /// Create Container</see>.
 485        /// </summary>
 486        /// <param name="publicAccessType">
 487        /// Optionally specifies whether data in the container may be accessed
 488        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 489        /// specifies full public read access for container and blob data.
 490        /// Clients can enumerate blobs within the container via anonymous
 491        /// request, but cannot enumerate containers within the storage
 492        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 493        /// read access for blobs.  Blob data within this container can be
 494        /// read via anonymous request, but container data is not available.
 495        /// Clients cannot enumerate blobs within the container via anonymous
 496        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 497        /// container data is private to the account owner.
 498        /// </param>
 499        /// <param name="metadata">
 500        /// Optional custom metadata to set for this container.
 501        /// </param>
 502        /// <param name="cancellationToken">
 503        /// Optional <see cref="CancellationToken"/> to propagate
 504        /// notifications that the operation should be cancelled.
 505        /// </param>
 506        /// <returns>
 507        /// A <see cref="Response{BlobContainerInfo}"/> describing the newly
 508        /// created blob container.
 509        /// </returns>
 510        /// <remarks>
 511        /// A <see cref="RequestFailedException"/> will be thrown if
 512        /// a failure occurs.
 513        /// </remarks>
 514#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 515        [EditorBrowsable(EditorBrowsableState.Never)]
 516        public virtual Response<BlobContainerInfo> Create(
 517#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 518            PublicAccessType publicAccessType,
 519            Metadata metadata,
 520            CancellationToken cancellationToken) =>
 1346521            CreateInternal(
 1346522                publicAccessType,
 1346523                metadata,
 1346524                encryptionScopeOptions: default,
 1346525                async: false,
 1346526                cancellationToken)
 1346527                .EnsureCompleted();
 528
 529        /// <summary>
 530        /// The <see cref="CreateAsync(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, CancellationToke
 531        /// operation creates a new container under the specified account. If the container with the same name
 532        /// already exists, the operation fails.
 533        ///
 534        /// For more information, see
 535        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 536        /// Create Container</see>.
 537        /// </summary>
 538        /// <param name="publicAccessType">
 539        /// Optionally specifies whether data in the container may be accessed
 540        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 541        /// specifies full public read access for container and blob data.
 542        /// Clients can enumerate blobs within the container via anonymous
 543        /// request, but cannot enumerate containers within the storage
 544        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 545        /// read access for blobs.  Blob data within this container can be
 546        /// read via anonymous request, but container data is not available.
 547        /// Clients cannot enumerate blobs within the container via anonymous
 548        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 549        /// container data is private to the account owner.
 550        /// </param>
 551        /// <param name="metadata">
 552        /// Optional custom metadata to set for this container.
 553        /// </param>
 554        /// <param name="encryptionScopeOptions">
 555        /// Optional encryption scope options to set for this container.
 556        /// </param>
 557        /// <param name="cancellationToken">
 558        /// Optional <see cref="CancellationToken"/> to propagate
 559        /// notifications that the operation should be cancelled.
 560        /// </param>
 561        /// <returns>
 562        /// A <see cref="Response{BlobContainerInfo}"/> describing the newly
 563        /// created container.
 564        /// </returns>
 565        /// <remarks>
 566        /// A <see cref="RequestFailedException"/> will be thrown if
 567        /// a failure occurs.
 568        /// </remarks>
 569        public virtual async Task<Response<BlobContainerInfo>> CreateAsync(
 570            PublicAccessType publicAccessType = PublicAccessType.None,
 571            Metadata metadata = default,
 572            BlobContainerEncryptionScopeOptions encryptionScopeOptions = default,
 573            CancellationToken cancellationToken = default) =>
 1914574            await CreateInternal(
 1914575                publicAccessType,
 1914576                metadata,
 1914577                encryptionScopeOptions,
 1914578                async: true,
 1914579                cancellationToken)
 1914580                .ConfigureAwait(false);
 581
 582        /// <summary>
 583        /// The <see cref="CreateAsync(PublicAccessType, Metadata, CancellationToken)"/> operation creates a new contain
 584        /// under the specified account. If the container with the same name
 585        /// already exists, the operation fails.
 586        ///
 587        /// For more information, see
 588        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 589        /// Create Container</see>.
 590        /// </summary>
 591        /// <param name="publicAccessType">
 592        /// Optionally specifies whether data in the container may be accessed
 593        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 594        /// specifies full public read access for container and blob data.
 595        /// Clients can enumerate blobs within the container via anonymous
 596        /// request, but cannot enumerate containers within the storage
 597        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 598        /// read access for blobs.  Blob data within this container can be
 599        /// read via anonymous request, but container data is not available.
 600        /// Clients cannot enumerate blobs within the container via anonymous
 601        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 602        /// container data is private to the account owner.
 603        /// </param>
 604        /// <param name="metadata">
 605        /// Optional custom metadata to set for this container.
 606        /// </param>
 607        /// <param name="cancellationToken">
 608        /// Optional <see cref="CancellationToken"/> to propagate
 609        /// notifications that the operation should be cancelled.
 610        /// </param>
 611        /// <returns>
 612        /// A <see cref="Response{BlobContainerInfo}"/> describing the newly
 613        /// created container.
 614        /// </returns>
 615        /// <remarks>
 616        /// A <see cref="RequestFailedException"/> will be thrown if
 617        /// a failure occurs.
 618        /// </remarks>
 619#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 620        [EditorBrowsable(EditorBrowsableState.Never)]
 621        public virtual async Task<Response<BlobContainerInfo>> CreateAsync(
 622#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 623            PublicAccessType publicAccessType,
 624            Metadata metadata,
 625            CancellationToken cancellationToken) =>
 1352626            await CreateInternal(
 1352627                publicAccessType,
 1352628                metadata,
 1352629                encryptionScopeOptions: default,
 1352630                async: true,
 1352631                cancellationToken)
 1352632                .ConfigureAwait(false);
 633
 634        /// <summary>
 635        /// The <see cref="CreateIfNotExists(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, Cancellati
 636        /// operation creates a new container under the specified account. If the container with the same name
 637        /// already exists, it is not changed.
 638        ///
 639        /// For more information, see
 640        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 641        /// Create Container</see>.
 642        /// </summary>
 643        /// <param name="publicAccessType">
 644        /// Optionally specifies whether data in the container may be accessed
 645        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 646        /// specifies full public read access for container and blob data.
 647        /// Clients can enumerate blobs within the container via anonymous
 648        /// request, but cannot enumerate containers within the storage
 649        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 650        /// read access for blobs.  Blob data within this container can be
 651        /// read via anonymous request, but container data is not available.
 652        /// Clients cannot enumerate blobs within the container via anonymous
 653        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 654        /// container data is private to the account owner.
 655        /// </param>
 656        /// <param name="metadata">
 657        /// Optional custom metadata to set for this container.
 658        /// </param>
 659        /// <param name="encryptionScopeOptions">
 660        /// Optional encryption scope options to set for this container.
 661        /// </param>
 662        /// <param name="cancellationToken">
 663        /// Optional <see cref="CancellationToken"/> to propagate
 664        /// notifications that the operation should be cancelled.
 665        /// </param>
 666        /// <returns>
 667        /// If the container does not already exist, a <see cref="Response{ContainerInfo}"/>
 668        /// describing the newly created container. If the container already exists, <c>null</c>.
 669        /// </returns>
 670        /// <remarks>
 671        /// A <see cref="RequestFailedException"/> will be thrown if
 672        /// a failure occurs.
 673        /// </remarks>
 674        public virtual Response<BlobContainerInfo> CreateIfNotExists(
 675            PublicAccessType publicAccessType = PublicAccessType.None,
 676            Metadata metadata = default,
 677            BlobContainerEncryptionScopeOptions encryptionScopeOptions = default,
 678            CancellationToken cancellationToken = default) =>
 6679            CreateIfNotExistsInternal(
 6680                publicAccessType,
 6681                metadata,
 6682                encryptionScopeOptions,
 6683                async: false,
 6684                cancellationToken)
 6685                .EnsureCompleted();
 686
 687        /// <summary>
 688        /// The <see cref="CreateIfNotExists(PublicAccessType, Metadata, CancellationToken)"/> operation creates a new c
 689        /// under the specified account. If the container with the same name
 690        /// already exists, it is not changed.
 691        ///
 692        /// For more information, see
 693        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 694        /// Create Container</see>.
 695        /// </summary>
 696        /// <param name="publicAccessType">
 697        /// Optionally specifies whether data in the container may be accessed
 698        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 699        /// specifies full public read access for container and blob data.
 700        /// Clients can enumerate blobs within the container via anonymous
 701        /// request, but cannot enumerate containers within the storage
 702        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 703        /// read access for blobs.  Blob data within this container can be
 704        /// read via anonymous request, but container data is not available.
 705        /// Clients cannot enumerate blobs within the container via anonymous
 706        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 707        /// container data is private to the account owner.
 708        /// </param>
 709        /// <param name="metadata">
 710        /// Optional custom metadata to set for this container.
 711        /// </param>
 712        /// <param name="cancellationToken">
 713        /// Optional <see cref="CancellationToken"/> to propagate
 714        /// notifications that the operation should be cancelled.
 715        /// </param>
 716        /// <returns>
 717        /// If the container does not already exist, a <see cref="Response{ContainerInfo}"/>
 718        /// describing the newly created container. If the container already exists, <c>null</c>.
 719        /// </returns>
 720        /// <remarks>
 721        /// A <see cref="RequestFailedException"/> will be thrown if
 722        /// a failure occurs.
 723        /// </remarks>
 724#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 725        [EditorBrowsable(EditorBrowsableState.Never)]
 726        public virtual Response<BlobContainerInfo> CreateIfNotExists(
 727#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 728            PublicAccessType publicAccessType,
 729            Metadata metadata,
 730            CancellationToken cancellationToken) =>
 6731            CreateIfNotExistsInternal(
 6732                publicAccessType,
 6733                metadata,
 6734                encryptionScopeOptions: default,
 6735                async: false,
 6736                cancellationToken)
 6737                .EnsureCompleted();
 738
 739        /// <summary>
 740        /// The <see cref="CreateIfNotExistsAsync(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, Cance
 741        /// operation creates a new container under the specified account. If the container with the same name
 742        /// already exists, it is not changed.
 743        ///
 744        /// For more information, see
 745        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 746        /// Create Container</see>.
 747        /// </summary>
 748        /// <param name="publicAccessType">
 749        /// Optionally specifies whether data in the container may be accessed
 750        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 751        /// specifies full public read access for container and blob data.
 752        /// Clients can enumerate blobs within the container via anonymous
 753        /// request, but cannot enumerate containers within the storage
 754        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 755        /// read access for blobs.  Blob data within this container can be
 756        /// read via anonymous request, but container data is not available.
 757        /// Clients cannot enumerate blobs within the container via anonymous
 758        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 759        /// container data is private to the account owner.
 760        /// </param>
 761        /// <param name="metadata">
 762        /// Optional custom metadata to set for this container.
 763        /// </param>
 764        /// <param name="encryptionScopeOptions">
 765        /// Optional encryption scope options to set for this container.
 766        /// </param>
 767        /// <param name="cancellationToken">
 768        /// Optional <see cref="CancellationToken"/> to propagate
 769        /// notifications that the operation should be cancelled.
 770        /// </param>
 771        /// <returns>
 772        /// A <see cref="Response{ContainerInfo}"/> describing the newly
 773        /// created container.
 774        /// </returns>
 775        /// <remarks>
 776        /// A <see cref="RequestFailedException"/> will be thrown if
 777        /// a failure occurs.
 778        /// </remarks>
 779        public virtual async Task<Response<BlobContainerInfo>> CreateIfNotExistsAsync(
 780            PublicAccessType publicAccessType = PublicAccessType.None,
 781            Metadata metadata = default,
 782            BlobContainerEncryptionScopeOptions encryptionScopeOptions = default,
 783            CancellationToken cancellationToken = default) =>
 6784            await CreateIfNotExistsInternal(
 6785                publicAccessType,
 6786                metadata,
 6787                encryptionScopeOptions,
 6788                async: true,
 6789                cancellationToken)
 6790                .ConfigureAwait(false);
 791
 792        /// <summary>
 793        /// The <see cref="CreateIfNotExists(PublicAccessType, Metadata, CancellationToken)"/> operation creates a new c
 794        /// under the specified account. If the container with the same name
 795        /// already exists, it is not changed.
 796        ///
 797        /// For more information, see
 798        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 799        /// Create Container</see>.
 800        /// </summary>
 801        /// <param name="publicAccessType">
 802        /// Optionally specifies whether data in the container may be accessed
 803        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 804        /// specifies full public read access for container and blob data.
 805        /// Clients can enumerate blobs within the container via anonymous
 806        /// request, but cannot enumerate containers within the storage
 807        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 808        /// read access for blobs.  Blob data within this container can be
 809        /// read via anonymous request, but container data is not available.
 810        /// Clients cannot enumerate blobs within the container via anonymous
 811        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 812        /// container data is private to the account owner.
 813        /// </param>
 814        /// <param name="metadata">
 815        /// Optional custom metadata to set for this container.
 816        /// </param>
 817        /// <param name="cancellationToken">
 818        /// Optional <see cref="CancellationToken"/> to propagate
 819        /// notifications that the operation should be cancelled.
 820        /// </param>
 821        /// <returns>
 822        /// A <see cref="Response{ContainerInfo}"/> describing the newly
 823        /// created container.
 824        /// </returns>
 825        /// <remarks>
 826        /// A <see cref="RequestFailedException"/> will be thrown if
 827        /// a failure occurs.
 828        /// </remarks>
 829#pragma warning disable AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 830        [EditorBrowsable(EditorBrowsableState.Never)]
 831        public virtual async Task<Response<BlobContainerInfo>> CreateIfNotExistsAsync(
 832#pragma warning restore AZC0002 // DO ensure all service methods, both asynchronous and synchronous, take an optional Ca
 833            PublicAccessType publicAccessType,
 834            Metadata metadata,
 835            CancellationToken cancellationToken) =>
 6836            await CreateIfNotExistsInternal(
 6837                publicAccessType,
 6838                metadata,
 6839                encryptionScopeOptions: default,
 6840                async: true,
 6841                cancellationToken)
 6842                .ConfigureAwait(false);
 843
 844        /// <summary>
 845        /// The <see cref="CreateIfNotExistsInternal(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, bo
 846        /// operation creates a new container under the specified account.  If the container already exists, it is
 847        /// not changed.
 848        ///
 849        /// For more information, see
 850        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 851        /// Create Container</see>.
 852        /// </summary>
 853        /// <param name="publicAccessType">
 854        /// Optionally specifies whether data in the container may be accessed
 855        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 856        /// specifies full public read access for container and blob data.
 857        /// Clients can enumerate blobs within the container via anonymous
 858        /// request, but cannot enumerate containers within the storage
 859        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 860        /// read access for blobs.  Blob data within this container can be
 861        /// read via anonymous request, but container data is not available.
 862        /// Clients cannot enumerate blobs within the container via anonymous
 863        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 864        /// container data is private to the account owner.
 865        /// </param>
 866        /// <param name="metadata">
 867        /// Optional custom metadata to set for this container.
 868        /// </param>
 869        /// <param name="encryptionScopeOptions">
 870        /// Optional encryption scope options to set for this container.
 871        /// </param>
 872        /// <param name="async">
 873        /// Whether to invoke the operation asynchronously.
 874        /// </param>
 875        /// <param name="cancellationToken">
 876        /// Optional <see cref="CancellationToken"/> to propagate
 877        /// notifications that the operation should be cancelled.
 878        /// </param>
 879        /// <returns>
 880        /// If the container does not already exist, a <see cref="Response{ContainerInfo}"/>
 881        /// describing the newly created container. If the container already exists, <c>null</c>.
 882        /// </returns>
 883        /// <remarks>
 884        /// A <see cref="RequestFailedException"/> will be thrown if
 885        /// a failure occurs.
 886        /// </remarks>
 887        private async Task<Response<BlobContainerInfo>> CreateIfNotExistsInternal(
 888            PublicAccessType publicAccessType,
 889            Metadata metadata,
 890            BlobContainerEncryptionScopeOptions encryptionScopeOptions,
 891            bool async,
 892            CancellationToken cancellationToken)
 893        {
 24894            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 895            {
 896                Pipeline.LogMethodEnter(
 897                    nameof(BlobContainerClient),
 898                    message:
 899                    $"{nameof(Uri)}: {Uri}\n" +
 900                    $"{nameof(publicAccessType)}: {publicAccessType}");
 901                Response <BlobContainerInfo> response;
 902                try
 903                {
 24904                    response = await CreateInternal(
 24905                        publicAccessType,
 24906                        metadata,
 24907                        encryptionScopeOptions,
 24908                        async,
 24909                        cancellationToken,
 24910                        $"{nameof(BlobContainerClient)}.{nameof(CreateIfNotExists)}")
 24911                        .ConfigureAwait(false);
 8912                }
 913                catch (RequestFailedException storageRequestFailedException)
 16914                when (storageRequestFailedException.ErrorCode == BlobErrorCode.ContainerAlreadyExists)
 915                {
 8916                    response = default;
 8917                }
 8918                catch (Exception ex)
 919                {
 920                    Pipeline.LogException(ex);
 8921                    throw;
 922                }
 923                finally
 924                {
 925                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 926                }
 16927                return response;
 928            }
 16929        }
 930
 931        /// <summary>
 932        /// The <see cref="CreateInternal"/> operation creates a new container
 933        /// under the specified account, if it does not already exist.
 934        /// If the container with the same name already exists, the operation fails.
 935        ///
 936        /// For more information, see
 937        /// <see href="https://docs.microsoft.com/rest/api/storageservices/create-container">
 938        /// Create Container</see>.
 939        /// </summary>
 940        /// <param name="publicAccessType">
 941        /// Optionally specifies whether data in the container may be accessed
 942        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 943        /// specifies full public read access for container and blob data.
 944        /// Clients can enumerate blobs within the container via anonymous
 945        /// request, but cannot enumerate containers within the storage
 946        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 947        /// read access for blobs.  Blob data within this container can be
 948        /// read via anonymous request, but container data is not available.
 949        /// Clients cannot enumerate blobs within the container via anonymous
 950        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 951        /// container data is private to the account owner.
 952        /// </param>
 953        /// <param name="metadata">
 954        /// Optional custom metadata to set for this container.
 955        /// </param>
 956        /// <param name="encryptionScopeOptions">
 957        /// Optional encryption scope options to set for this container.
 958        /// </param>
 959        /// <param name="async">
 960        /// Whether to invoke the operation asynchronously.
 961        /// </param>
 962        /// <param name="cancellationToken">
 963        /// Optional <see cref="CancellationToken"/> to propagate
 964        /// notifications that the operation should be cancelled.
 965        /// </param>
 966        /// <param name="operationName">
 967        /// Optional. To indicate if the name of the operation.
 968        /// </param>
 969        /// <returns>
 970        /// A <see cref="Response{ContainerInfo}"/> describing the newly
 971        /// created container.
 972        /// </returns>
 973        /// <remarks>
 974        /// A <see cref="RequestFailedException"/> will be thrown if
 975        /// a failure occurs.
 976        /// </remarks>
 977        private async Task<Response<BlobContainerInfo>> CreateInternal(
 978            PublicAccessType publicAccessType,
 979            Metadata metadata,
 980            BlobContainerEncryptionScopeOptions encryptionScopeOptions,
 981            bool async,
 982            CancellationToken cancellationToken,
 983            string operationName = null)
 984        {
 6542985            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 986            {
 987                Pipeline.LogMethodEnter(
 988                    nameof(BlobContainerClient),
 989                    message:
 990                    $"{nameof(Uri)}: {Uri}\n" +
 991                    $"{nameof(publicAccessType)}: {publicAccessType}");
 992                try
 993                {
 6542994                    return await BlobRestClient.Container.CreateAsync(
 6542995                        ClientDiagnostics,
 6542996                        Pipeline,
 6542997                        Uri,
 6542998                        access: publicAccessType,
 6542999                        defaultEncryptionScope: encryptionScopeOptions?.DefaultEncryptionScope,
 65421000                        preventEncryptionScopeOverride: encryptionScopeOptions?.PreventEncryptionScopeOverride,
 65421001                        version: Version.ToVersionString(),
 65421002                        metadata: metadata,
 65421003                        async: async,
 65421004                        operationName: operationName ?? $"{nameof(BlobContainerClient)}.{nameof(Create)}",
 65421005                        cancellationToken: cancellationToken)
 65421006                        .ConfigureAwait(false);
 1007                }
 401008                catch (Exception ex)
 1009                {
 1010                    Pipeline.LogException(ex);
 401011                    throw;
 1012                }
 1013                finally
 1014                {
 1015                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1016                }
 1017            }
 65021018        }
 1019        #endregion Create
 1020
 1021        #region Delete
 1022        /// <summary>
 1023        /// The <see cref="Delete"/> operation marks the specified
 1024        /// container for deletion. The container and any blobs contained
 1025        /// within it are later deleted during garbage collection.
 1026        ///
 1027        /// For more information, see
 1028        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-container">
 1029        /// Delete Container</see>.
 1030        /// </summary>
 1031        /// <param name="conditions">
 1032        /// Optional <see cref="BlobRequestConditions"/> to add
 1033        /// conditions on the deletion of this container.
 1034        /// </param>
 1035        /// <param name="cancellationToken">
 1036        /// Optional <see cref="CancellationToken"/> to propagate
 1037        /// notifications that the operation should be cancelled.
 1038        /// </param>
 1039        /// <returns>
 1040        /// A <see cref="Response"/> if successful.
 1041        /// </returns>
 1042        /// <remarks>
 1043        /// A <see cref="RequestFailedException"/> will be thrown if
 1044        /// a failure occurs.
 1045        /// </remarks>
 1046        public virtual Response Delete(
 1047            BlobRequestConditions conditions = default,
 1048            CancellationToken cancellationToken = default) =>
 32461049            DeleteInternal(
 32461050                conditions,
 32461051                false, // async
 32461052                cancellationToken)
 32461053                .EnsureCompleted();
 1054
 1055        /// <summary>
 1056        /// The <see cref="DeleteAsync"/> operation marks the specified
 1057        /// container for deletion. The container and any blobs contained
 1058        /// within it are later deleted during garbage collection.
 1059        ///
 1060        /// For more information, see
 1061        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-container">
 1062        /// Delete Container</see>.
 1063        /// </summary>
 1064        /// <param name="conditions">
 1065        /// Optional <see cref="BlobRequestConditions"/> to add
 1066        /// conditions on the deletion of this container.
 1067        /// </param>
 1068        /// <param name="cancellationToken">
 1069        /// Optional <see cref="CancellationToken"/> to propagate
 1070        /// notifications that the operation should be cancelled.
 1071        /// </param>
 1072        /// <returns>
 1073        /// A <see cref="Response"/> if successful.
 1074        /// </returns>
 1075        /// <remarks>
 1076        /// A <see cref="RequestFailedException"/> will be thrown if
 1077        /// a failure occurs.
 1078        /// </remarks>
 1079        public virtual async Task<Response> DeleteAsync(
 1080            BlobRequestConditions conditions = default,
 1081            CancellationToken cancellationToken = default) =>
 32621082            await DeleteInternal(
 32621083                conditions,
 32621084                true, // async
 32621085                cancellationToken)
 32621086                .ConfigureAwait(false);
 1087
 1088        /// <summary>
 1089        /// The <see cref="DeleteIfExists"/> operation marks the specified
 1090        /// container for deletion if it exists. The container and any blobs
 1091        /// contained within it are later deleted during garbage collection.
 1092        ///
 1093        /// For more information, see
 1094        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-container">
 1095        /// Delete Container</see>.
 1096        /// </summary>
 1097        /// <param name="conditions">
 1098        /// Optional <see cref="BlobRequestConditions"/> to add
 1099        /// conditions on the deletion of this container.
 1100        /// </param>
 1101        /// <param name="cancellationToken">
 1102        /// Optional <see cref="CancellationToken"/> to propagate
 1103        /// notifications that the operation should be cancelled.
 1104        /// </param>
 1105        /// <returns>
 1106        /// A <see cref="Response"/> Returns true if container exists and was
 1107        /// deleted, return false otherwise.
 1108        /// </returns>
 1109        /// <remarks>
 1110        /// A <see cref="RequestFailedException"/> will be thrown if
 1111        /// a failure occurs.
 1112        /// </remarks>
 1113        public virtual Response<bool> DeleteIfExists(
 1114            BlobRequestConditions conditions = default,
 1115            CancellationToken cancellationToken = default) =>
 141116            DeleteIfExistsInternal(
 141117                conditions,
 141118                false, // async
 141119                cancellationToken)
 141120                .EnsureCompleted();
 1121
 1122        /// <summary>
 1123        /// The <see cref="DeleteIfExistsAsync"/> operation marks the specified
 1124        /// container for deletion if it exists. The container and any blobs
 1125        /// contained within it are later deleted during garbage collection.
 1126        ///
 1127        /// For more information, see
 1128        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-container">
 1129        /// Delete Container</see>.
 1130        /// </summary>
 1131        /// <param name="conditions">
 1132        /// Optional <see cref="BlobRequestConditions"/> to add
 1133        /// conditions on the deletion of this container.
 1134        /// </param>
 1135        /// <param name="cancellationToken">
 1136        /// Optional <see cref="CancellationToken"/> to propagate
 1137        /// notifications that the operation should be cancelled.
 1138        /// </param>
 1139        /// <returns>
 1140        /// A <see cref="Response"/> Returns true if container exists and was
 1141        /// deleted, return false otherwise.
 1142        /// </returns>
 1143        /// <remarks>
 1144        /// A <see cref="RequestFailedException"/> will be thrown if
 1145        /// a failure occurs.
 1146        /// </remarks>
 1147        public virtual async Task<Response<bool>> DeleteIfExistsAsync(
 1148            BlobRequestConditions conditions = default,
 1149            CancellationToken cancellationToken = default) =>
 141150            await DeleteIfExistsInternal(
 141151                conditions,
 141152                true, // async
 141153                cancellationToken)
 141154                .ConfigureAwait(false);
 1155
 1156        /// <summary>
 1157        /// The <see cref="DeleteIfExistsInternal"/> operation marks the specified
 1158        /// container for deletion if it exists. The container and any blobs
 1159        /// contained within it are later deleted during garbage collection.
 1160        ///
 1161        /// For more information, see
 1162        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-container">
 1163        /// Delete Container</see>.
 1164        /// </summary>
 1165        /// <param name="conditions">
 1166        /// Optional <see cref="BlobRequestConditions"/> to add
 1167        /// conditions on the deletion of this container.
 1168        /// </param>
 1169        /// <param name="async">
 1170        /// Whether to invoke the operation asynchronously.
 1171        /// </param>
 1172        /// <param name="cancellationToken">
 1173        /// Optional <see cref="CancellationToken"/> to propagate
 1174        /// notifications that the operation should be cancelled.
 1175        /// </param>
 1176        /// <returns>
 1177        /// A <see cref="Response"/> Returns true if container exists and was
 1178        /// deleted, return false otherwise.
 1179        /// </returns>
 1180        /// <remarks>
 1181        /// A <see cref="RequestFailedException"/> will be thrown if
 1182        /// a failure occurs.
 1183        /// </remarks>
 1184        private async Task<Response<bool>> DeleteIfExistsInternal(
 1185            BlobRequestConditions conditions,
 1186            bool async,
 1187            CancellationToken cancellationToken)
 1188        {
 281189            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 1190            {
 1191                Pipeline.LogMethodEnter(
 1192                    nameof(BlobContainerClient),
 1193                    message:
 1194                    $"{nameof(Uri)}: {Uri}\n" +
 1195                    $"{nameof(conditions)}: {conditions}");
 1196                try
 1197                {
 281198                    Response response = await DeleteInternal(
 281199                        conditions,
 281200                        async,
 281201                        cancellationToken,
 281202                        $"{nameof(BlobContainerClient)}.{nameof(DeleteIfExists)}")
 281203                        .ConfigureAwait(false);
 161204                    return Response.FromValue(true, response);
 1205                }
 1206                catch (RequestFailedException storageRequestFailedException)
 121207                when (storageRequestFailedException.ErrorCode == BlobErrorCode.ContainerNotFound
 121208                || storageRequestFailedException.ErrorCode == BlobErrorCode.BlobNotFound)
 1209                {
 81210                    return Response.FromValue(false, default);
 1211                }
 41212                catch (Exception ex)
 1213                {
 1214                    Pipeline.LogException(ex);
 41215                    throw;
 1216                }
 1217                finally
 1218                {
 1219                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1220                }
 1221            }
 241222        }
 1223
 1224        /// <summary>
 1225        /// The <see cref="DeleteAsync"/> operation marks the specified
 1226        /// container for deletion. The container and any blobs contained
 1227        /// within it are later deleted during garbage collection.
 1228        ///
 1229        /// For more information, see
 1230        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-container">
 1231        /// Delete Container</see>.
 1232        /// </summary>
 1233        /// <param name="conditions">
 1234        /// Optional <see cref="BlobRequestConditions"/> to add
 1235        /// conditions on the deletion of this container.
 1236        /// </param>
 1237        /// <param name="async">
 1238        /// Whether to invoke the operation asynchronously.
 1239        /// </param>
 1240        /// <param name="cancellationToken">
 1241        /// Optional <see cref="CancellationToken"/> to propagate
 1242        /// notifications that the operation should be cancelled.
 1243        /// </param>
 1244        /// <param name="operationName">
 1245        /// Optional. To indicate if the name of the operation.
 1246        /// </param>
 1247        /// <returns>
 1248        /// A <see cref="Response"/> if successful.
 1249        /// </returns>
 1250        /// <remarks>
 1251        /// A <see cref="RequestFailedException"/> will be thrown if
 1252        /// a failure occurs.
 1253        /// </remarks>
 1254        private async Task<Response> DeleteInternal(
 1255            BlobRequestConditions conditions,
 1256            bool async,
 1257            CancellationToken cancellationToken,
 1258            string operationName = null)
 1259        {
 65361260            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 1261            {
 1262                Pipeline.LogMethodEnter(
 1263                    nameof(BlobContainerClient),
 1264                    message:
 1265                    $"{nameof(Uri)}: {Uri}\n" +
 1266                    $"{nameof(conditions)}: {conditions}");
 1267                try
 1268                {
 65361269                    if (conditions?.IfMatch != default ||
 65361270                        conditions?.IfNoneMatch != default)
 1271                    {
 81272                        throw BlobErrors.BlobConditionsMustBeDefault(nameof(RequestConditions.IfMatch), nameof(RequestCo
 1273                    }
 1274
 65281275                    return await BlobRestClient.Container.DeleteAsync(
 65281276                        ClientDiagnostics,
 65281277                        Pipeline,
 65281278                        Uri,
 65281279                        version: Version.ToVersionString(),
 65281280                        leaseId: conditions?.LeaseId,
 65281281                        ifModifiedSince: conditions?.IfModifiedSince,
 65281282                        ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
 65281283                        async: async,
 65281284                        operationName: operationName ?? $"{nameof(BlobContainerClient)}.{nameof(Delete)}",
 65281285                        cancellationToken: cancellationToken)
 65281286                        .ConfigureAwait(false);
 1287                }
 641288                catch (Exception ex)
 1289                {
 1290                    Pipeline.LogException(ex);
 641291                    throw;
 1292                }
 1293                finally
 1294                {
 1295                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1296                }
 1297            }
 64721298        }
 1299        #endregion Delete
 1300
 1301        #region Exists
 1302        /// <summary>
 1303        /// The <see cref="Exists"/> operation can be called on a
 1304        /// <see cref="BlobContainerClient"/> to see if the associated container
 1305        /// exists on the storage account in the storage service.
 1306        /// </summary>
 1307        /// <param name="cancellationToken">
 1308        /// Optional <see cref="CancellationToken"/> to propagate
 1309        /// notifications that the operation should be cancelled.
 1310        /// </param>
 1311        /// <returns>
 1312        /// Returns true if the container exists.
 1313        /// </returns>
 1314        /// <remarks>
 1315        /// A <see cref="RequestFailedException"/> will be thrown if
 1316        /// a failure occurs. If you want to create the container if
 1317        /// it doesn't exist, use
 1318        /// <see cref="CreateIfNotExists(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, CancellationTo
 1319        /// instead.
 1320        /// </remarks>
 1321        public virtual Response<bool> Exists(
 1322            CancellationToken cancellationToken = default) =>
 501323            ExistsInternal(
 501324                async: false,
 501325                cancellationToken).EnsureCompleted();
 1326
 1327        /// <summary>
 1328        /// The <see cref="ExistsAsync"/> operation can be called on a
 1329        /// <see cref="BlobContainerClient"/> to see if the associated container
 1330        /// exists on the storage account in the storage service.
 1331        /// </summary>
 1332        /// <param name="cancellationToken">
 1333        /// Optional <see cref="CancellationToken"/> to propagate
 1334        /// notifications that the operation should be cancelled.
 1335        /// </param>
 1336        /// <returns>
 1337        /// Returns true if the container exists.
 1338        /// </returns>
 1339        /// <remarks>
 1340        /// A <see cref="RequestFailedException"/> will be thrown if
 1341        /// a failure occurs. If you want to create the container if
 1342        /// it doesn't exist, use
 1343        /// <see cref="CreateIfNotExists(PublicAccessType, Metadata, BlobContainerEncryptionScopeOptions, CancellationTo
 1344        /// instead.
 1345        /// </remarks>
 1346        public virtual async Task<Response<bool>> ExistsAsync(
 1347            CancellationToken cancellationToken = default) =>
 501348            await ExistsInternal(
 501349                async: true,
 501350                cancellationToken).ConfigureAwait(false);
 1351
 1352        /// <summary>
 1353        /// The <see cref="ExistsInternal"/> operation can be called on a
 1354        /// <see cref="BlobContainerClient"/> to see if the associated container
 1355        /// exists on the storage account in the storage service.
 1356        /// </summary>
 1357        /// <param name="async">
 1358        /// Whether to invoke the operation asynchronously.
 1359        /// </param>
 1360        /// <param name="cancellationToken">
 1361        /// Optional <see cref="CancellationToken"/> to propagate
 1362        /// notifications that the operation should be cancelled.
 1363        /// </param>
 1364        /// <returns>
 1365        /// Returns true if the container exists.
 1366        /// </returns>
 1367        /// <remarks>
 1368        /// A <see cref="RequestFailedException"/> will be thrown if
 1369        /// a failure occurs.
 1370        /// </remarks>
 1371        private async Task<Response<bool>> ExistsInternal(
 1372            bool async,
 1373            CancellationToken cancellationToken)
 1374        {
 1001375            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 1376            {
 1377                Pipeline.LogMethodEnter(
 1378                    nameof(BlobContainerClient),
 1379                    message:
 1380                    $"{nameof(Uri)}: {Uri}");
 1381
 1382                try
 1383                {
 1001384                    Response<FlattenedContainerItem> response = await BlobRestClient.Container.GetPropertiesAsync(
 1001385                        ClientDiagnostics,
 1001386                        Pipeline,
 1001387                        Uri,
 1001388                        version: Version.ToVersionString(),
 1001389                        async: async,
 1001390                        operationName: $"{nameof(BlobContainerClient)}.{nameof(Exists)}",
 1001391                        cancellationToken: cancellationToken)
 1001392                        .ConfigureAwait(false);
 1393
 841394                    return Response.FromValue(true, response.GetRawResponse());
 1395                }
 1396                catch (RequestFailedException storageRequestFailedException)
 161397                when (storageRequestFailedException.ErrorCode == BlobErrorCode.ContainerNotFound)
 1398                {
 81399                    return Response.FromValue(false, default);
 1400                }
 81401                catch (Exception ex)
 1402                {
 1403                    Pipeline.LogException(ex);
 81404                    throw;
 1405                }
 1406                finally
 1407                {
 1408                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1409                }
 1410            }
 921411        }
 1412        #endregion Exists
 1413
 1414        #region GetProperties
 1415        /// <summary>
 1416        /// The <see cref="GetProperties"/> operation returns all
 1417        /// user-defined metadata and system properties for the specified
 1418        /// container. The data returned does not include the container's
 1419        /// list of blobs.
 1420        ///
 1421        /// For more information, see
 1422        /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-properties">
 1423        /// Get Container Properties</see>.
 1424        /// </summary>
 1425        /// <param name="conditions">
 1426        /// Optional <see cref="BlobRequestConditions"/> to add
 1427        /// conditions on getting the blob container's properties.
 1428        /// </param>
 1429        /// <param name="cancellationToken">
 1430        /// Optional <see cref="CancellationToken"/> to propagate
 1431        /// notifications that the operation should be cancelled.
 1432        /// </param>
 1433        /// <returns>
 1434        /// A <see cref="Response{BlobContainerProperties}"/> describing the
 1435        /// container and its properties.
 1436        /// </returns>
 1437        /// <remarks>
 1438        /// A <see cref="RequestFailedException"/> will be thrown if
 1439        /// a failure occurs.
 1440        /// </remarks>
 1441        public virtual Response<BlobContainerProperties> GetProperties(
 1442            BlobRequestConditions conditions = default,
 1443            CancellationToken cancellationToken = default) =>
 581444            GetPropertiesInternal(
 581445                conditions,
 581446                false, // async
 581447                cancellationToken)
 581448                .EnsureCompleted();
 1449
 1450        /// <summary>
 1451        /// The <see cref="GetPropertiesAsync"/> operation returns all
 1452        /// user-defined metadata and system properties for the specified
 1453        /// container. The data returned does not include the container's
 1454        /// list of blobs.
 1455        ///
 1456        /// For more information, see
 1457        /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-properties">
 1458        /// Get Container Properties</see>.
 1459        /// </summary>
 1460        /// <param name="conditions">
 1461        /// Optional <see cref="BlobRequestConditions"/> to add
 1462        /// conditions on getting the blob container's properties.
 1463        /// </param>
 1464        /// <param name="cancellationToken">
 1465        /// Optional <see cref="CancellationToken"/> to propagate
 1466        /// notifications that the operation should be cancelled.
 1467        /// </param>
 1468        /// <returns>
 1469        /// A <see cref="Response{BlobContainerProperties}"/> describing the
 1470        /// container and its properties.
 1471        /// </returns>
 1472        /// <remarks>
 1473        /// A <see cref="RequestFailedException"/> will be thrown if
 1474        /// a failure occurs.
 1475        /// </remarks>
 1476        public virtual async Task<Response<BlobContainerProperties>> GetPropertiesAsync(
 1477            BlobRequestConditions conditions = default,
 1478            CancellationToken cancellationToken = default) =>
 861479            await GetPropertiesInternal(
 861480                conditions,
 861481                true, // async
 861482                cancellationToken)
 861483                .ConfigureAwait(false);
 1484
 1485        /// <summary>
 1486        /// The <see cref="GetPropertiesAsync"/> operation returns all
 1487        /// user-defined metadata and system properties for the specified
 1488        /// container. The data returned does not include the container's
 1489        /// list of blobs.
 1490        ///
 1491        /// For more information, see
 1492        /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-properties">
 1493        /// Get Container Properties</see>.
 1494        /// </summary>
 1495        /// <param name="conditions">
 1496        /// Optional <see cref="BlobRequestConditions"/> to add
 1497        /// conditions on getting the blob container's properties.
 1498        /// </param>
 1499        /// <param name="async">
 1500        /// Whether to invoke the operation asynchronously.
 1501        /// </param>
 1502        /// <param name="cancellationToken">
 1503        /// Optional <see cref="CancellationToken"/> to propagate
 1504        /// notifications that the operation should be cancelled.
 1505        /// </param>
 1506        /// <returns>
 1507        /// A <see cref="Response{BlobContainerItem}"/> describing the
 1508        /// container and its properties.
 1509        /// </returns>
 1510        /// <remarks>
 1511        /// A <see cref="RequestFailedException"/> will be thrown if
 1512        /// a failure occurs.
 1513        /// </remarks>
 1514        private async Task<Response<BlobContainerProperties>> GetPropertiesInternal(
 1515            BlobRequestConditions conditions,
 1516            bool async,
 1517            CancellationToken cancellationToken)
 1518        {
 1441519            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 1520            {
 1521                Pipeline.LogMethodEnter(
 1522                    nameof(BlobContainerClient),
 1523                    message:
 1524                    $"{nameof(Uri)}: {Uri}\n" +
 1525                    $"{nameof(conditions)}: {conditions}");
 1526                try
 1527                {
 1528                    // GetProperties returns a flattened set of properties
 1441529                    Response<FlattenedContainerItem> response =
 1441530                        await BlobRestClient.Container.GetPropertiesAsync(
 1441531                            ClientDiagnostics,
 1441532                            Pipeline,
 1441533                            Uri,
 1441534                            version: Version.ToVersionString(),
 1441535                            leaseId: conditions?.LeaseId,
 1441536                            async: async,
 1441537                            operationName: $"{nameof(BlobContainerClient)}.{nameof(GetProperties)}",
 1441538                            cancellationToken: cancellationToken)
 1441539                            .ConfigureAwait(false);
 1540
 1541                    // Turn the flattened properties into a BlobContainerProperties
 1241542                    return Response.FromValue(
 1241543                        new BlobContainerProperties()
 1241544                            {
 1241545                                Metadata = response.Value.Metadata,
 1241546                                LastModified = response.Value.LastModified,
 1241547                                ETag = response.Value.ETag,
 1241548                                LeaseStatus = response.Value.LeaseStatus,
 1241549                                LeaseState = response.Value.LeaseState,
 1241550                                LeaseDuration = response.Value.LeaseDuration,
 1241551                                PublicAccess = response.Value.BlobPublicAccess,
 1241552                                HasImmutabilityPolicy = response.Value.HasImmutabilityPolicy,
 1241553                                HasLegalHold = response.Value.HasLegalHold,
 1241554                                DefaultEncryptionScope = response.Value.DefaultEncryptionScope,
 1241555                                PreventEncryptionScopeOverride = response.Value.DenyEncryptionScopeOverride
 1241556                        },
 1241557                        response.GetRawResponse());
 1558                }
 201559                catch (Exception ex)
 1560                {
 1561                    Pipeline.LogException(ex);
 201562                    throw;
 1563                }
 1564                finally
 1565                {
 1566                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1567                }
 1568            }
 1241569        }
 1570        #endregion GetProperties
 1571
 1572        #region SetMetadata
 1573        /// <summary>
 1574        /// The <see cref="SetMetadata"/> operation sets one or more
 1575        /// user-defined name-value pairs for the specified container.
 1576        ///
 1577        /// For more information, see
 1578        /// <see href="https://docs.microsoft.com/rest/api/storageservices/set-container-metadata">
 1579        /// Set Container Metadata</see>.
 1580        /// </summary>
 1581        /// <param name="metadata">
 1582        /// Custom metadata to set for this container.
 1583        /// </param>
 1584        /// <param name="conditions">
 1585        /// Optional <see cref="BlobRequestConditions"/> to add
 1586        /// conditions on the deletion of this container.
 1587        /// </param>
 1588        /// <param name="cancellationToken">
 1589        /// Optional <see cref="CancellationToken"/> to propagate
 1590        /// notifications that the operation should be cancelled.
 1591        /// </param>
 1592        /// <returns>
 1593        /// A <see cref="Response{BlobContainerInfo}"/> if successful.
 1594        /// </returns>
 1595        /// <remarks>
 1596        /// A <see cref="RequestFailedException"/> will be thrown if
 1597        /// a failure occurs.
 1598        /// </remarks>
 1599        public virtual Response<BlobContainerInfo> SetMetadata(
 1600            Metadata metadata,
 1601            BlobRequestConditions conditions = default,
 1602            CancellationToken cancellationToken = default) =>
 341603            SetMetadataInternal(
 341604                metadata,
 341605                conditions,
 341606                false, // async
 341607                cancellationToken)
 341608                .EnsureCompleted();
 1609
 1610        /// <summary>
 1611        /// The <see cref="SetMetadataAsync"/> operation sets one or more
 1612        /// user-defined name-value pairs for the specified container.
 1613        ///
 1614        /// For more information, see
 1615        /// <see href="https://docs.microsoft.com/rest/api/storageservices/set-container-metadata">
 1616        /// Set Container Metadata</see>.
 1617        /// </summary>
 1618        /// <param name="metadata">
 1619        /// Custom metadata to set for this container.
 1620        /// </param>
 1621        /// <param name="conditions">
 1622        /// Optional <see cref="BlobRequestConditions"/> to add
 1623        /// conditions on the deletion of this container.
 1624        /// </param>
 1625        /// <param name="cancellationToken">
 1626        /// Optional <see cref="CancellationToken"/> to propagate
 1627        /// notifications that the operation should be cancelled.
 1628        /// </param>
 1629        /// <returns>
 1630        /// A <see cref="Response{BlobContainerInfo}"/> if successful.
 1631        /// </returns>
 1632        /// <remarks>
 1633        /// A <see cref="RequestFailedException"/> will be thrown if
 1634        /// a failure occurs.
 1635        /// </remarks>
 1636        public virtual async Task<Response<BlobContainerInfo>> SetMetadataAsync(
 1637            Metadata metadata,
 1638            BlobRequestConditions conditions = default,
 1639            CancellationToken cancellationToken = default) =>
 341640            await SetMetadataInternal(
 341641                metadata,
 341642                conditions,
 341643                true, // async
 341644                cancellationToken)
 341645                .ConfigureAwait(false);
 1646
 1647        /// <summary>
 1648        /// The <see cref="SetMetadataInternal"/> operation sets one or more
 1649        /// user-defined name-value pairs for the specified container.
 1650        ///
 1651        /// For more information, see
 1652        /// <see href="https://docs.microsoft.com/rest/api/storageservices/set-container-metadata">
 1653        /// Set Container Metadata</see>.
 1654        /// </summary>
 1655        /// <param name="metadata">
 1656        /// Custom metadata to set for this container.
 1657        /// </param>
 1658        /// <param name="conditions">
 1659        /// Optional <see cref="BlobRequestConditions"/> to add
 1660        /// conditions on the deletion of this container.
 1661        /// </param>
 1662        /// <param name="async">
 1663        /// Whether to invoke the operation asynchronously.
 1664        /// </param>
 1665        /// <param name="cancellationToken">
 1666        /// Optional <see cref="CancellationToken"/> to propagate
 1667        /// notifications that the operation should be cancelled.
 1668        /// </param>
 1669        /// <returns>
 1670        /// A <see cref="Response{BlobContainerInfo}"/> if successful.
 1671        /// </returns>
 1672        /// <remarks>
 1673        /// A <see cref="RequestFailedException"/> will be thrown if
 1674        /// a failure occurs.
 1675        /// </remarks>
 1676        private async Task<Response<BlobContainerInfo>> SetMetadataInternal(
 1677            Metadata metadata,
 1678            BlobRequestConditions conditions,
 1679            bool async,
 1680            CancellationToken cancellationToken)
 1681        {
 681682            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 1683            {
 1684                Pipeline.LogMethodEnter(
 1685                    nameof(BlobContainerClient),
 1686                    message:
 1687                    $"{nameof(Uri)}: {Uri}\n" +
 1688                    $"{nameof(conditions)}: {conditions}");
 1689                try
 1690                {
 681691                    if (conditions?.IfUnmodifiedSince != default ||
 681692                        conditions?.IfMatch != default ||
 681693                        conditions?.IfNoneMatch != default)
 1694                    {
 01695                        throw BlobErrors.BlobConditionsMustBeDefault(
 01696                            nameof(RequestConditions.IfUnmodifiedSince),
 01697                            nameof(RequestConditions.IfMatch),
 01698                            nameof(RequestConditions.IfNoneMatch));
 1699                    }
 1700
 681701                    return await BlobRestClient.Container.SetMetadataAsync(
 681702                        ClientDiagnostics,
 681703                        Pipeline,
 681704                        Uri,
 681705                        version: Version.ToVersionString(),
 681706                        metadata: metadata,
 681707                        leaseId: conditions?.LeaseId,
 681708                        ifModifiedSince: conditions?.IfModifiedSince,
 681709                        async: async,
 681710                        operationName: $"{nameof(BlobContainerClient)}.{nameof(SetMetadata)}",
 681711                        cancellationToken: cancellationToken)
 681712                        .ConfigureAwait(false);
 1713                }
 241714                catch (Exception ex)
 1715                {
 1716                    Pipeline.LogException(ex);
 241717                    throw;
 1718                }
 1719                finally
 1720                {
 1721                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1722                }
 1723            }
 441724        }
 1725        #endregion SetMetadata
 1726
 1727        #region GetAccessPolicy
 1728        /// <summary>
 1729        /// The <see cref="GetAccessPolicy"/> operation gets the
 1730        /// permissions for this container. The permissions indicate whether
 1731        /// container data may be accessed publicly.
 1732        ///
 1733        /// For more information, see
 1734        /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-acl">
 1735        /// Get Container ACL</see>.
 1736        /// </summary>
 1737        /// <param name="conditions">
 1738        /// Optional <see cref="BlobRequestConditions"/> to add
 1739        /// conditions on getting the blob container's access policy.
 1740        /// </param>
 1741        /// <param name="cancellationToken">
 1742        /// Optional <see cref="CancellationToken"/> to propagate
 1743        /// notifications that the operation should be cancelled.
 1744        /// </param>
 1745        /// <returns>
 1746        /// A <see cref="Response{BlobContainerAccessPolicy}"/> describing
 1747        /// the container's access policy.
 1748        /// </returns>
 1749        /// <remarks>
 1750        /// A <see cref="RequestFailedException"/> will be thrown if
 1751        /// a failure occurs.
 1752        /// </remarks>
 1753        public virtual Response<BlobContainerAccessPolicy> GetAccessPolicy(
 1754            BlobRequestConditions conditions = default,
 1755            CancellationToken cancellationToken = default) =>
 321756            GetAccessPolicyInternal(
 321757                conditions,
 321758                false, // async
 321759                cancellationToken)
 321760                .EnsureCompleted();
 1761
 1762        /// <summary>
 1763        /// The <see cref="GetAccessPolicyAsync"/> operation gets the
 1764        /// permissions for this container. The permissions indicate whether
 1765        /// container data may be accessed publicly.
 1766        ///
 1767        /// For more information, see
 1768        /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-acl">
 1769        /// Get Container ACL</see>.
 1770        /// </summary>
 1771        /// <param name="conditions">
 1772        /// Optional <see cref="BlobRequestConditions"/> to add
 1773        /// conditions on getting the blob container's access policy.
 1774        /// </param>
 1775        /// <param name="cancellationToken">
 1776        /// Optional <see cref="CancellationToken"/> to propagate
 1777        /// notifications that the operation should be cancelled.
 1778        /// </param>
 1779        /// <returns>
 1780        /// A <see cref="Response{BlobContainerAccessPolicy}"/> describing
 1781        /// the container's access policy.
 1782        /// </returns>
 1783        /// <remarks>
 1784        /// A <see cref="RequestFailedException"/> will be thrown if
 1785        /// a failure occurs.
 1786        /// </remarks>
 1787        public virtual async Task<Response<BlobContainerAccessPolicy>> GetAccessPolicyAsync(
 1788            BlobRequestConditions conditions = default,
 1789            CancellationToken cancellationToken = default) =>
 321790            await GetAccessPolicyInternal(
 321791                conditions,
 321792                true, // async
 321793                cancellationToken)
 321794                .ConfigureAwait(false);
 1795
 1796        /// <summary>
 1797        /// The <see cref="GetAccessPolicyAsync"/> operation gets the
 1798        /// permissions for this container. The permissions indicate whether
 1799        /// container data may be accessed publicly.
 1800        ///
 1801        /// For more information, see
 1802        /// <see href="https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-acl">
 1803        /// Get Container ACL</see>.
 1804        /// </summary>
 1805        /// <param name="conditions">
 1806        /// Optional <see cref="BlobRequestConditions"/> to add
 1807        /// conditions on getting the blob container's access policy.
 1808        /// </param>
 1809        /// <param name="async">
 1810        /// Whether to invoke the operation asynchronously.
 1811        /// </param>
 1812        /// <param name="cancellationToken">
 1813        /// Optional <see cref="CancellationToken"/> to propagate
 1814        /// notifications that the operation should be cancelled.
 1815        /// </param>
 1816        /// <returns>
 1817        /// A <see cref="Response{BlobContainerAccessPolicy}"/> describing
 1818        /// the container's access policy.
 1819        /// </returns>
 1820        /// <remarks>
 1821        /// A <see cref="RequestFailedException"/> will be thrown if
 1822        /// a failure occurs.
 1823        /// </remarks>
 1824        private async Task<Response<BlobContainerAccessPolicy>> GetAccessPolicyInternal(
 1825            BlobRequestConditions conditions,
 1826            bool async,
 1827            CancellationToken cancellationToken)
 1828        {
 641829            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 1830            {
 1831                Pipeline.LogMethodEnter(
 1832                    nameof(BlobContainerClient),
 1833                    message:
 1834                    $"{nameof(Uri)}: {Uri}\n" +
 1835                    $"{nameof(conditions)}: {conditions}");
 1836                try
 1837                {
 641838                    return await BlobRestClient.Container.GetAccessPolicyAsync(
 641839                        ClientDiagnostics,
 641840                        Pipeline,
 641841                        Uri,
 641842                        version: Version.ToVersionString(),
 641843                        leaseId: conditions?.LeaseId,
 641844                        async: async,
 641845                        operationName: $"{nameof(BlobContainerClient)}.{nameof(GetAccessPolicy)}",
 641846                        cancellationToken: cancellationToken)
 641847                        .ConfigureAwait(false);
 1848                }
 161849                catch (Exception ex)
 1850                {
 1851                    Pipeline.LogException(ex);
 161852                    throw;
 1853                }
 1854                finally
 1855                {
 1856                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 1857                }
 1858            }
 481859        }
 1860        #endregion GetAccessPolicy
 1861
 1862        #region SetAccessPolicy
 1863        /// <summary>
 1864        /// The <see cref="SetAccessPolicy"/> operation sets the
 1865        /// permissions for the specified container. The permissions indicate
 1866        /// whether blob container data may be accessed publicly.
 1867        ///
 1868        /// For more information, see
 1869        /// <see href=" https://docs.microsoft.com/rest/api/storageservices/set-container-acl">
 1870        /// Set Container ACL</see>.
 1871        /// </summary>
 1872        /// <param name="accessType">
 1873        /// Optionally specifies whether data in the container may be accessed
 1874        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 1875        /// specifies full public read access for container and blob data.
 1876        /// Clients can enumerate blobs within the container via anonymous
 1877        /// request, but cannot enumerate containers within the storage
 1878        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 1879        /// read access for blobs.  Blob data within this container can be
 1880        /// read via anonymous request, but container data is not available.
 1881        /// Clients cannot enumerate blobs within the container via anonymous
 1882        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 1883        /// container data is private to the account owner.
 1884        /// </param>
 1885        /// <param name="permissions">
 1886        /// Stored access policies that you can use to provide fine grained
 1887        /// control over container permissions.
 1888        /// </param>
 1889        /// <param name="conditions">
 1890        /// Optional <see cref="BlobRequestConditions"/> to add
 1891        /// conditions on setting this blob container's access policy.
 1892        /// </param>
 1893        /// <param name="cancellationToken">
 1894        /// Optional <see cref="CancellationToken"/> to propagate
 1895        /// notifications that the operation should be cancelled.
 1896        /// </param>
 1897        /// <returns>
 1898        /// A <see cref="Response{BlobContainerInfo}"/> describing the
 1899        /// updated container.
 1900        /// </returns>
 1901        /// <remarks>
 1902        /// A <see cref="RequestFailedException"/> will be thrown if
 1903        /// a failure occurs.
 1904        /// </remarks>
 1905        public virtual Response<BlobContainerInfo> SetAccessPolicy(
 1906            PublicAccessType accessType = PublicAccessType.None,
 1907            IEnumerable<BlobSignedIdentifier> permissions = default,
 1908            BlobRequestConditions conditions = default,
 1909            CancellationToken cancellationToken = default) =>
 2201910            SetAccessPolicyInternal(
 2201911                accessType,
 2201912                permissions,
 2201913                conditions,
 2201914                false, // async
 2201915                cancellationToken)
 2201916                .EnsureCompleted();
 1917
 1918        /// <summary>
 1919        /// The <see cref="SetAccessPolicyAsync"/> operation sets the
 1920        /// permissions for the specified container. The permissions indicate
 1921        /// whether blob container data may be accessed publicly.
 1922        ///
 1923        /// For more information, see
 1924        /// <see href=" https://docs.microsoft.com/rest/api/storageservices/set-container-acl">
 1925        /// Set Container ACL</see>.
 1926        /// </summary>
 1927        /// <param name="accessType">
 1928        /// Optionally specifies whether data in the container may be accessed
 1929        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 1930        /// specifies full public read access for container and blob data.
 1931        /// Clients can enumerate blobs within the container via anonymous
 1932        /// request, but cannot enumerate containers within the storage
 1933        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 1934        /// read access for blobs.  Blob data within this container can be
 1935        /// read via anonymous request, but container data is not available.
 1936        /// Clients cannot enumerate blobs within the container via anonymous
 1937        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 1938        /// container data is private to the account owner.
 1939        /// </param>
 1940        /// <param name="permissions">
 1941        /// Stored access policies that you can use to provide fine grained
 1942        /// control over container permissions.
 1943        /// </param>
 1944        /// <param name="conditions">
 1945        /// Optional <see cref="BlobRequestConditions"/> to add
 1946        /// conditions on setting this blob container's access policy.
 1947        /// </param>
 1948        /// <param name="cancellationToken">
 1949        /// Optional <see cref="CancellationToken"/> to propagate
 1950        /// notifications that the operation should be cancelled.
 1951        /// </param>
 1952        /// <returns>
 1953        /// A <see cref="Response{BlobContainerInfo}"/> describing the
 1954        /// updated container.
 1955        /// </returns>
 1956        /// <remarks>
 1957        /// A <see cref="RequestFailedException"/> will be thrown if
 1958        /// a failure occurs.
 1959        /// </remarks>
 1960        public virtual async Task<Response<BlobContainerInfo>> SetAccessPolicyAsync(
 1961            PublicAccessType accessType = PublicAccessType.None,
 1962            IEnumerable<BlobSignedIdentifier> permissions = default,
 1963            BlobRequestConditions conditions = default,
 1964            CancellationToken cancellationToken = default) =>
 2201965            await SetAccessPolicyInternal(
 2201966                accessType,
 2201967                permissions,
 2201968                conditions,
 2201969                true, // async
 2201970                cancellationToken)
 2201971                .ConfigureAwait(false);
 1972
 1973        /// <summary>
 1974        /// The <see cref="SetAccessPolicyAsync"/> operation sets the
 1975        /// permissions for the specified container. The permissions indicate
 1976        /// whether blob container data may be accessed publicly.
 1977        ///
 1978        /// For more information, see
 1979        /// <see href=" https://docs.microsoft.com/rest/api/storageservices/set-container-acl">
 1980        /// Set Container ACL</see>.
 1981        /// </summary>
 1982        /// <param name="accessType">
 1983        /// Optionally specifies whether data in the container may be accessed
 1984        /// publicly and the level of access. <see cref="PublicAccessType.BlobContainer"/>
 1985        /// specifies full public read access for container and blob data.
 1986        /// Clients can enumerate blobs within the container via anonymous
 1987        /// request, but cannot enumerate containers within the storage
 1988        /// account.  <see cref="PublicAccessType.Blob"/> specifies public
 1989        /// read access for blobs.  Blob data within this container can be
 1990        /// read via anonymous request, but container data is not available.
 1991        /// Clients cannot enumerate blobs within the container via anonymous
 1992        /// request.  <see cref="PublicAccessType.None"/> specifies that the
 1993        /// container data is private to the account owner.
 1994        /// </param>
 1995        /// <param name="permissions">
 1996        /// Stored access policies that you can use to provide fine grained
 1997        /// control over container permissions.
 1998        /// </param>
 1999        /// <param name="conditions">
 2000        /// Optional <see cref="BlobRequestConditions"/> to add
 2001        /// conditions on setting this blob container's access policy.
 2002        /// </param>
 2003        /// <param name="async">
 2004        /// Whether to invoke the operation asynchronously.
 2005        /// </param>
 2006        /// <param name="cancellationToken">
 2007        /// Optional <see cref="CancellationToken"/> to propagate
 2008        /// notifications that the operation should be cancelled.
 2009        /// </param>
 2010        /// <returns>
 2011        /// A <see cref="Response{BlobContainerInfo}"/> describing the
 2012        /// updated container.
 2013        /// </returns>
 2014        /// <remarks>
 2015        /// A <see cref="RequestFailedException"/> will be thrown if
 2016        /// a failure occurs.
 2017        /// </remarks>
 2018        private async Task<Response<BlobContainerInfo>> SetAccessPolicyInternal(
 2019            PublicAccessType accessType,
 2020            IEnumerable<BlobSignedIdentifier> permissions,
 2021            BlobRequestConditions conditions,
 2022            bool async,
 2023            CancellationToken cancellationToken)
 2024        {
 4402025            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 2026            {
 2027                Pipeline.LogMethodEnter(
 2028                    nameof(BlobContainerClient),
 2029                    message:
 2030                    $"{nameof(Uri)}: {Uri}\n" +
 2031                    $"{nameof(accessType)}: {accessType}");
 2032                try
 2033                {
 4402034                    if (conditions?.IfMatch != default ||
 4402035                        conditions?.IfNoneMatch != default)
 2036                    {
 02037                        throw BlobErrors.BlobConditionsMustBeDefault(nameof(RequestConditions.IfMatch), nameof(RequestCo
 2038                    }
 2039
 4402040                    return await BlobRestClient.Container.SetAccessPolicyAsync(
 4402041                        ClientDiagnostics,
 4402042                        Pipeline,
 4402043                        Uri,
 4402044                        version: Version.ToVersionString(),
 4402045                        permissions: permissions,
 4402046                        leaseId: conditions?.LeaseId,
 4402047                        access: accessType,
 4402048                        ifModifiedSince: conditions?.IfModifiedSince,
 4402049                        ifUnmodifiedSince: conditions?.IfUnmodifiedSince,
 4402050                        async: async,
 4402051                        operationName: $"{nameof(BlobContainerClient)}.{nameof(SetAccessPolicy)}",
 4402052                        cancellationToken: cancellationToken)
 4402053                        .ConfigureAwait(false);
 2054                }
 322055                catch (Exception ex)
 2056                {
 2057                    Pipeline.LogException(ex);
 322058                    throw;
 2059                }
 2060                finally
 2061                {
 2062                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 2063                }
 2064            }
 4082065        }
 2066        #endregion SetAccessPolicy
 2067
 2068        #region GetBlobs
 2069        /// <summary>
 2070        /// The <see cref="GetBlobs"/> operation returns an async sequence
 2071        /// of blobs in this container.  Enumerating the blobs may make
 2072        /// multiple requests to the service while fetching all the values.
 2073        /// Blobs are ordered lexicographically by name.
 2074        ///
 2075        /// For more information, see
 2076        /// <see href="https://docs.microsoft.com/rest/api/storageservices/list-blobs">
 2077        /// List Blobs</see>.
 2078        /// </summary>
 2079        /// <param name="traits">
 2080        /// Specifies trait options for shaping the blobs.
 2081        /// </param>
 2082        /// <param name="states">
 2083        /// Specifies state options for filtering the blobs.
 2084        /// </param>
 2085        /// <param name="prefix">
 2086        /// Specifies a string that filters the results to return only blobs
 2087        /// whose name begins with the specified <paramref name="prefix"/>.
 2088        /// </param>
 2089        /// <param name="cancellationToken">
 2090        /// Optional <see cref="CancellationToken"/> to propagate
 2091        /// notifications that the operation should be cancelled.
 2092        /// </param>
 2093        /// <returns>
 2094        /// An <see cref="Pageable{T}"/> of <see cref="BlobItem"/>
 2095        /// describing the blobs in the container.
 2096        /// </returns>
 2097        /// <remarks>
 2098        /// A <see cref="RequestFailedException"/> will be thrown if
 2099        /// a failure occurs.
 2100        /// </remarks>
 2101        public virtual Pageable<BlobItem> GetBlobs(
 2102            BlobTraits traits = BlobTraits.None,
 2103            BlobStates states = BlobStates.None,
 2104            string prefix = default,
 2105            CancellationToken cancellationToken = default) =>
 682106            new GetBlobsAsyncCollection(this, traits, states, prefix).ToSyncCollection(cancellationToken);
 2107
 2108        /// <summary>
 2109        /// The <see cref="GetBlobsAsync"/> operation returns an async
 2110        /// sequence of blobs in this container.  Enumerating the blobs may
 2111        /// make multiple requests to the service while fetching all the
 2112        /// values.  Blobs are ordered lexicographically by name.
 2113        ///
 2114        /// For more information, see
 2115        /// <see href="https://docs.microsoft.com/rest/api/storageservices/list-blobs">
 2116        /// List Blobs</see>.
 2117        /// </summary>
 2118        /// <param name="traits">
 2119        /// Specifies trait options for shaping the blobs.
 2120        /// </param>
 2121        /// <param name="states">
 2122        /// Specifies state options for filtering the blobs.
 2123        /// </param>
 2124        /// <param name="prefix">
 2125        /// Specifies a string that filters the results to return only blobs
 2126        /// whose name begins with the specified <paramref name="prefix"/>.
 2127        /// </param>
 2128        /// <param name="cancellationToken">
 2129        /// Optional <see cref="CancellationToken"/> to propagate
 2130        /// notifications that the operation should be cancelled.
 2131        /// </param>
 2132        /// <returns>
 2133        /// An <see cref="AsyncPageable{T}"/> describing the
 2134        /// blobs in the container.
 2135        /// </returns>
 2136        /// <remarks>
 2137        /// A <see cref="RequestFailedException"/> will be thrown if
 2138        /// a failure occurs.
 2139        /// </remarks>
 2140        public virtual AsyncPageable<BlobItem> GetBlobsAsync(
 2141            BlobTraits traits = BlobTraits.None,
 2142            BlobStates states = BlobStates.None,
 2143            string prefix = default,
 2144            CancellationToken cancellationToken = default) =>
 782145            new GetBlobsAsyncCollection(this, traits, states, prefix).ToAsyncCollection(cancellationToken);
 2146
 2147        /// <summary>
 2148        /// The <see cref="GetBlobsInternal"/> operation returns a
 2149        /// single segment of blobs in this container, starting
 2150        /// from the specified <paramref name="marker"/>.  Use an empty
 2151        /// <paramref name="marker"/> to start enumeration from the beginning
 2152        /// and the <see cref="BlobsFlatSegment.NextMarker"/> if it's not
 2153        /// empty to make subsequent calls to <see cref="GetBlobsAsync"/>
 2154        /// to continue enumerating the blobs segment by segment. Blobs are
 2155        /// ordered lexicographically by name.
 2156        ///
 2157        /// For more information, see
 2158        /// <see href="https://docs.microsoft.com/rest/api/storageservices/list-blobs">
 2159        /// List Blobs</see>.
 2160        /// </summary>
 2161        /// <param name="marker">
 2162        /// An optional string value that identifies the segment of the list
 2163        /// of blobs to be returned with the next listing operation.  The
 2164        /// operation returns a non-empty <see cref="BlobsFlatSegment.NextMarker"/>
 2165        /// if the listing operation did not return all blobs remaining to be
 2166        /// listed with the current segment.  The NextMarker value can
 2167        /// be used as the value for the <paramref name="marker"/> parameter
 2168        /// in a subsequent call to request the next segment of list items.
 2169        /// </param>
 2170        /// <param name="traits">
 2171        /// Specifies trait options for shaping the blobs.
 2172        /// </param>
 2173        /// <param name="states">
 2174        /// Specifies state options for filtering the blobs.
 2175        /// </param>
 2176        /// <param name="prefix">
 2177        /// Specifies a string that filters the results to return only blobs
 2178        /// whose name begins with the specified <paramref name="prefix"/>.
 2179        /// </param>
 2180        /// <param name="pageSizeHint">
 2181        /// Gets or sets a value indicating the size of the page that should be
 2182        /// requested.
 2183        /// </param>
 2184        /// <param name="async">
 2185        /// Whether to invoke the operation asynchronously.
 2186        /// </param>
 2187        /// <param name="cancellationToken">
 2188        /// Optional <see cref="CancellationToken"/> to propagate
 2189        /// notifications that the operation should be cancelled.
 2190        /// </param>
 2191        /// <returns>
 2192        /// A <see cref="Response{BlobsFlatSegment}"/> describing a
 2193        /// segment of the blobs in the container.
 2194        /// </returns>
 2195        /// <remarks>
 2196        /// A <see cref="RequestFailedException"/> will be thrown if
 2197        /// a failure occurs.
 2198        /// </remarks>
 2199        internal async Task<Response<BlobsFlatSegment>> GetBlobsInternal(
 2200            string marker,
 2201            BlobTraits traits,
 2202            BlobStates states,
 2203            string prefix,
 2204            int? pageSizeHint,
 2205            bool async,
 2206            CancellationToken cancellationToken)
 2207        {
 1462208            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 2209            {
 2210                Pipeline.LogMethodEnter(
 2211                    nameof(BlobContainerClient),
 2212                    message:
 2213                    $"{nameof(Uri)}: {Uri}\n" +
 2214                    $"{nameof(marker)}: {marker}\n" +
 2215                    $"{nameof(traits)}: {traits}\n" +
 2216                    $"{nameof(states)}: {states}");
 2217
 2218                try
 2219                {
 1462220                    Response<BlobsFlatSegment> response = await BlobRestClient.Container.ListBlobsFlatSegmentAsync(
 1462221                          ClientDiagnostics,
 1462222                          Pipeline,
 1462223                          Uri,
 1462224                          version: Version.ToVersionString(),
 1462225                          marker: marker,
 1462226                          prefix: prefix,
 1462227                          maxresults: pageSizeHint,
 1462228                          include: BlobExtensions.AsIncludeItems(traits, states),
 1462229                          async: async,
 1462230                          cancellationToken: cancellationToken)
 1462231                          .ConfigureAwait(false);
 1422232                    if ((traits & BlobTraits.Metadata) != BlobTraits.Metadata)
 2233                    {
 1382234                        IEnumerable<BlobItem> blobItems = response.Value.BlobItems.ToBlobItems();
 6842235                        foreach (BlobItem blobItem in blobItems)
 2236                        {
 2042237                            blobItem.Metadata = null;
 2238                        }
 2239                    }
 1422240                    return response;
 2241                }
 42242                catch (Exception ex)
 2243                {
 2244                    Pipeline.LogException(ex);
 42245                    throw;
 2246                }
 2247                finally
 2248                {
 2249                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 2250                }
 2251            }
 1422252        }
 2253        #endregion GetBlobs
 2254
 2255        #region GetBlobsByHierarchy
 2256        /// <summary>
 2257        /// The <see cref="GetBlobsByHierarchy"/> operation returns
 2258        /// an async collection of blobs in this container.  Enumerating the
 2259        /// blobs may make multiple requests to the service while fetching all
 2260        /// the values.  Blobs are ordered lexicographically by name.   A
 2261        /// <paramref name="delimiter"/> can be used to traverse a virtual
 2262        /// hierarchy of blobs as though it were a file system.
 2263        ///
 2264        /// For more information, see
 2265        /// <see href="https://docs.microsoft.com/rest/api/storageservices/list-blobs">
 2266        /// List Blobs</see>.
 2267        /// </summary>
 2268        /// <param name="traits">
 2269        /// Specifies trait options for shaping the blobs.
 2270        /// </param>
 2271        /// <param name="states">
 2272        /// Specifies state options for filtering the blobs.
 2273        /// </param>
 2274        /// <param name="delimiter">
 2275        /// A <paramref name="delimiter"/> that can be used to traverse a
 2276        /// virtual hierarchy of blobs as though it were a file system.  The
 2277        /// delimiter may be a single character or a string.
 2278        /// <see cref="BlobHierarchyItem.Prefix"/> will be returned
 2279        /// in place of all blobs whose names begin with the same substring up
 2280        /// to the appearance of the delimiter character.  The value of a
 2281        /// prefix is substring+delimiter, where substring is the common
 2282        /// substring that begins one or more blob  names, and delimiter is the
 2283        /// value of <paramref name="delimiter"/>. You can use the value of
 2284        /// prefix to make a subsequent call to list the blobs that begin with
 2285        /// this prefix, by specifying the value of the prefix for the
 2286        /// <paramref name="prefix"/>.
 2287        ///
 2288        /// Note that each BlobPrefix element returned counts toward the
 2289        /// maximum result, just as each Blob element does.
 2290        /// </param>
 2291        /// <param name="prefix">
 2292        /// Specifies a string that filters the results to return only blobs
 2293        /// whose name begins with the specified <paramref name="prefix"/>.
 2294        /// </param>
 2295        /// <param name="cancellationToken">
 2296        /// Optional <see cref="CancellationToken"/> to propagate
 2297        /// notifications that the operation should be cancelled.
 2298        /// </param>
 2299        /// <returns>
 2300        /// An <see cref="Pageable{T}"/> of <see cref="BlobHierarchyItem"/>
 2301        /// describing the blobs in the container.
 2302        /// </returns>
 2303        /// <remarks>
 2304        /// A <see cref="RequestFailedException"/> will be thrown if
 2305        /// a failure occurs.
 2306        /// </remarks>
 2307        public virtual Pageable<BlobHierarchyItem> GetBlobsByHierarchy(
 2308            BlobTraits traits = BlobTraits.None,
 2309            BlobStates states = BlobStates.None,
 2310            string delimiter = default,
 2311            string prefix = default,
 2312            CancellationToken cancellationToken = default) =>
 2122313            new GetBlobsByHierarchyAsyncCollection(this, delimiter, traits, states, prefix).ToSyncCollection(cancellatio
 2314
 2315        /// <summary>
 2316        /// The <see cref="GetBlobsByHierarchyAsync"/> operation returns
 2317        /// an async collection of blobs in this container.  Enumerating the
 2318        /// blobs may make multiple requests to the service while fetching all
 2319        /// the values.  Blobs are ordered lexicographically by name.   A
 2320        /// <paramref name="delimiter"/> can be used to traverse a virtual
 2321        /// hierarchy of blobs as though it were a file system.
 2322        ///
 2323        /// For more information, see
 2324        /// <see href="https://docs.microsoft.com/rest/api/storageservices/list-blobs">
 2325        /// List Blobs</see>.
 2326        /// </summary>
 2327        /// <param name="traits">
 2328        /// Specifies trait options for shaping the blobs.
 2329        /// </param>
 2330        /// <param name="states">
 2331        /// Specifies state options for filtering the blobs.
 2332        /// </param>
 2333        /// <param name="delimiter">
 2334        /// A <paramref name="delimiter"/> that can be used to traverse a
 2335        /// virtual hierarchy of blobs as though it were a file system.  The
 2336        /// delimiter may be a single character or a string.
 2337        /// <see cref="BlobHierarchyItem.Prefix"/> will be returned
 2338        /// in place of all blobs whose names begin with the same substring up
 2339        /// to the appearance of the delimiter character.  The value of a
 2340        /// prefix is substring+delimiter, where substring is the common
 2341        /// substring that begins one or more blob  names, and delimiter is the
 2342        /// value of <paramref name="delimiter"/>. You can use the value of
 2343        /// prefix to make a subsequent call to list the blobs that begin with
 2344        /// this prefix, by specifying the value of the prefix for the
 2345        /// <paramref name="prefix"/>.
 2346        ///
 2347        /// Note that each BlobPrefix element returned counts toward the
 2348        /// maximum result, just as each Blob element does.
 2349        /// </param>
 2350        /// <param name="prefix">
 2351        /// Specifies a string that filters the results to return only blobs
 2352        /// whose name begins with the specified <paramref name="prefix"/>.
 2353        /// </param>
 2354        /// <param name="cancellationToken">
 2355        /// Optional <see cref="CancellationToken"/> to propagate
 2356        /// notifications that the operation should be cancelled.
 2357        /// </param>
 2358        /// <returns>
 2359        /// An <see cref="AsyncPageable{T}"/> describing the
 2360        /// blobs in the container.
 2361        /// </returns>
 2362        /// <remarks>
 2363        /// A <see cref="RequestFailedException"/> will be thrown if
 2364        /// a failure occurs.
 2365        /// </remarks>
 2366        public virtual AsyncPageable<BlobHierarchyItem> GetBlobsByHierarchyAsync(
 2367            BlobTraits traits = BlobTraits.None,
 2368            BlobStates states = BlobStates.None,
 2369            string delimiter = default,
 2370            string prefix = default,
 2371            CancellationToken cancellationToken = default) =>
 2142372            new GetBlobsByHierarchyAsyncCollection(this, delimiter, traits, states, prefix).ToAsyncCollection(cancellati
 2373
 2374        /// <summary>
 2375        /// The <see cref="GetBlobsByHierarchyInternal"/> operation returns
 2376        /// a single segment of blobs in this container, starting
 2377        /// from the specified <paramref name="marker"/>.  Use an empty
 2378        /// <paramref name="marker"/> to start enumeration from the beginning
 2379        /// and the <see cref="BlobsHierarchySegment.NextMarker"/> if it's not
 2380        /// empty to make subsequent calls to <see cref="GetBlobsByHierarchyAsync"/>
 2381        /// to continue enumerating the blobs segment by segment. Blobs are
 2382        /// ordered lexicographically by name.   A <paramref name="delimiter"/>
 2383        /// can be used to traverse a virtual hierarchy of blobs as though
 2384        /// it were a file system.
 2385        ///
 2386        /// For more information, see
 2387        /// <see href="https://docs.microsoft.com/rest/api/storageservices/list-blobs">
 2388        /// List Blobs</see>.
 2389        /// </summary>
 2390        /// <param name="marker">
 2391        /// An optional string value that identifies the segment of the list
 2392        /// of blobs to be returned with the next listing operation.  The
 2393        /// operation returns a non-empty <see cref="BlobsHierarchySegment.NextMarker"/>
 2394        /// if the listing operation did not return all blobs remaining to be
 2395        /// listed with the current segment.  The NextMarker value can
 2396        /// be used as the value for the <paramref name="marker"/> parameter
 2397        /// in a subsequent call to request the next segment of list items.
 2398        /// </param>
 2399        /// <param name="delimiter">
 2400        /// A <paramref name="delimiter"/> that can be used to traverse a
 2401        /// virtual hierarchy of blobs as though it were a file system.  The
 2402        /// delimiter may be a single character or a string.
 2403        /// <see cref="BlobHierarchyItem.Prefix"/> will be returned
 2404        /// in place of all blobs whose names begin with the same substring up
 2405        /// to the appearance of the delimiter character.  The value of a
 2406        /// prefix is substring+delimiter, where substring is the common
 2407        /// substring that begins one or more blob  names, and delimiter is the
 2408        /// value of <paramref name="delimiter"/>. You can use the value of
 2409        /// prefix to make a subsequent call to list the blobs that begin with
 2410        /// this prefix, by specifying the value of the prefix for the
 2411        /// <paramref name="prefix"/>.
 2412        ///
 2413        /// Note that each BlobPrefix element returned counts toward the
 2414        /// maximum result, just as each Blob element does.
 2415        /// </param>
 2416        /// <param name="traits">
 2417        /// Specifies trait options for shaping the blobs.
 2418        /// </param>
 2419        /// <param name="states">
 2420        /// Specifies state options for filtering the blobs.
 2421        /// </param>
 2422        /// <param name="prefix">
 2423        /// Specifies a string that filters the results to return only blobs
 2424        /// whose name begins with the specified <paramref name="prefix"/>.
 2425        /// </param>
 2426        /// <param name="pageSizeHint">
 2427        /// Gets or sets a value indicating the size of the page that should be
 2428        /// requested.
 2429        /// </param>
 2430        /// <param name="async">
 2431        /// Whether to invoke the operation asynchronously.
 2432        /// </param>
 2433        /// <param name="cancellationToken">
 2434        /// Optional <see cref="CancellationToken"/> to propagate
 2435        /// notifications that the operation should be cancelled.
 2436        /// </param>
 2437        /// <returns>
 2438        /// A <see cref="Response{BlobsHierarchySegment}"/> describing a
 2439        /// segment of the blobs in the container.
 2440        /// </returns>
 2441        /// <remarks>
 2442        /// A <see cref="RequestFailedException"/> will be thrown if
 2443        /// a failure occurs.
 2444        /// </remarks>
 2445        internal async Task<Response<BlobsHierarchySegment>> GetBlobsByHierarchyInternal(
 2446            string marker,
 2447            string delimiter,
 2448            BlobTraits traits,
 2449            BlobStates states,
 2450            string prefix,
 2451            int? pageSizeHint,
 2452            bool async,
 2453            CancellationToken cancellationToken)
 2454        {
 4262455            using (Pipeline.BeginLoggingScope(nameof(BlobContainerClient)))
 2456            {
 2457                Pipeline.LogMethodEnter(
 2458                    nameof(BlobContainerClient),
 2459                    message:
 2460                    $"{nameof(Uri)}: {Uri}\n" +
 2461                    $"{nameof(marker)}: {marker}\n" +
 2462                    $"{nameof(delimiter)}: {delimiter}\n" +
 2463                    $"{nameof(traits)}: {traits}\n" +
 2464                    $"{nameof(states)}: {states}");
 2465                try
 2466                {
 4262467                    return await BlobRestClient.Container.ListBlobsHierarchySegmentAsync(
 4262468                        ClientDiagnostics,
 4262469                        Pipeline,
 4262470                        Uri,
 4262471                        version: Version.ToVersionString(),
 4262472                        marker: marker,
 4262473                        prefix: prefix,
 4262474                        maxresults: pageSizeHint,
 4262475                        include: BlobExtensions.AsIncludeItems(traits, states),
 4262476                        delimiter: delimiter,
 4262477                        async: async,
 4262478                        cancellationToken: cancellationToken)
 4262479                        .ConfigureAwait(false);
 2480                }
 42481                catch (Exception ex)
 2482                {
 2483                    Pipeline.LogException(ex);
 42484                    throw;
 2485                }
 2486                finally
 2487                {
 2488                    Pipeline.LogMethodExit(nameof(BlobContainerClient));
 2489                }
 2490            }
 4222491        }
 2492        #endregion GetBlobsByHierarchy
 2493
 2494        #region UploadBlob
 2495        /// <summary>
 2496        /// The <see cref="UploadBlobAsync"/> operation creates a new block
 2497        /// blob.
 2498        ///
 2499        /// For partial block blob updates and other advanced features, please
 2500        /// see <see cref="BlockBlobClient"/>.  To create or modify page or
 2501        /// append blobs, please see <see cref="PageBlobClient"/> or
 2502        /// <see cref="AppendBlobClient"/>.
 2503        ///
 2504        /// For more information, see
 2505        /// <see href="https://docs.microsoft.com/rest/api/storageservices/put-blob">
 2506        /// Put Blob</see>.
 2507        /// </summary>
 2508        /// <param name="blobName">The name of the blob to upload.</param>
 2509        /// <param name="content">
 2510        /// A <see cref="Stream"/> containing the content to upload.
 2511        /// </param>
 2512        /// <param name="cancellationToken">
 2513        /// Optional <see cref="CancellationToken"/> to propagate
 2514        /// notifications that the operation should be cancelled.
 2515        /// </param>
 2516        /// <returns>
 2517        /// A <see cref="Response{BlobContentInfo}"/> describing the
 2518        /// state of the updated block blob.
 2519        /// </returns>
 2520        /// <remarks>
 2521        /// A <see cref="RequestFailedException"/> will be thrown
 2522        /// if the blob already exists.  To overwrite an existing block blob,
 2523        /// get a <see cref="BlobClient"/> by calling <see cref="GetBlobClient(string)"/>,
 2524        /// and then call <see cref="BlobClient.UploadAsync(Stream, bool, CancellationToken)"/>
 2525        /// with the override parameter set to true.
 2526        /// </remarks>
 2527        [ForwardsClientCalls]
 2528        public virtual Response<BlobContentInfo> UploadBlob(
 2529            string blobName,
 2530            Stream content,
 2531            CancellationToken cancellationToken = default) =>
 22532            GetBlobClient(blobName)
 22533                .Upload(
 22534                    content,
 22535                    cancellationToken);
 2536
 2537        /// <summary>
 2538        /// The <see cref="UploadBlob"/> operation creates a new block
 2539        /// blob.
 2540        ///
 2541        /// For partial block blob updates and other advanced features, please
 2542        /// see <see cref="BlockBlobClient"/>.  To create or modify page or
 2543        /// append blobs, please see <see cref="PageBlobClient"/> or
 2544        /// <see cref="AppendBlobClient"/>.
 2545        ///
 2546        /// For more information, see
 2547        /// <see href="https://docs.microsoft.com/rest/api/storageservices/put-blob">
 2548        /// Put Blob</see>.
 2549        /// </summary>
 2550        /// <param name="blobName">The name of the blob to upload.</param>
 2551        /// <param name="content">
 2552        /// A <see cref="Stream"/> containing the content to upload.
 2553        /// </param>
 2554        /// <param name="cancellationToken">
 2555        /// Optional <see cref="CancellationToken"/> to propagate
 2556        /// notifications that the operation should be cancelled.
 2557        /// </param>
 2558        /// <returns>
 2559        /// A <see cref="Response{BlobContentInfo}"/> describing the
 2560        /// state of the updated block blob.
 2561        /// </returns>
 2562        /// <remarks>
 2563        /// A <see cref="RequestFailedException"/> will be thrown
 2564        /// if the blob already exists.  To overwrite an existing block blob,
 2565        /// get a <see cref="BlobClient"/> by calling <see cref="GetBlobClient(string)"/>,
 2566        /// and then call <see cref="BlobClient.Upload(Stream, bool, CancellationToken)"/>
 2567        /// with the override parameter set to true.
 2568        /// </remarks>
 2569        [ForwardsClientCalls]
 2570        public virtual async Task<Response<BlobContentInfo>> UploadBlobAsync(
 2571            string blobName,
 2572            Stream content,
 2573            CancellationToken cancellationToken = default) =>
 22574            await GetBlobClient(blobName)
 22575                .UploadAsync(
 22576                    content,
 22577                    cancellationToken)
 22578                    .ConfigureAwait(false);
 2579        #endregion UploadBlob
 2580
 2581        #region DeleteBlob
 2582        /// <summary>
 2583        /// The <see cref="DeleteBlob"/> operation marks the specified
 2584        /// blob or snapshot for deletion. The blob is later deleted during
 2585        /// garbage collection.
 2586        ///
 2587        /// Note that in order to delete a blob, you must delete all of its
 2588        /// snapshots. You can delete both at the same time using
 2589        /// <see cref="DeleteSnapshotsOption.IncludeSnapshots"/>.
 2590        ///
 2591        /// For more information, see
 2592        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob">
 2593        /// Delete Blob</see>.
 2594        /// </summary>
 2595        /// <param name="blobName">The name of the blob to delete.</param>
 2596        /// <param name="snapshotsOption">
 2597        /// Specifies options for deleting blob snapshots.
 2598        /// </param>
 2599        /// <param name="conditions">
 2600        /// Optional <see cref="BlobRequestConditions"/> to add conditions on
 2601        /// deleting this blob.
 2602        /// </param>
 2603        /// <param name="cancellationToken">
 2604        /// Optional <see cref="CancellationToken"/> to propagate
 2605        /// notifications that the operation should be cancelled.
 2606        /// </param>
 2607        /// <returns>
 2608        /// A <see cref="Response"/> on successfully deleting.
 2609        /// </returns>
 2610        /// <remarks>
 2611        /// A <see cref="RequestFailedException"/> will be thrown if
 2612        /// a failure occurs.
 2613        /// </remarks>
 2614        [ForwardsClientCalls]
 2615        public virtual Response DeleteBlob(
 2616            string blobName,
 2617            DeleteSnapshotsOption snapshotsOption = default,
 2618            BlobRequestConditions conditions = default,
 2619            CancellationToken cancellationToken = default) =>
 42620            GetBlobClient(blobName)
 42621                .Delete(
 42622                    snapshotsOption,
 42623                    conditions,
 42624                    cancellationToken);
 2625
 2626        /// <summary>
 2627        /// The <see cref="DeleteBlobAsync"/> operation marks the specified
 2628        /// blob or snapshot for deletion. The blob is later deleted during
 2629        /// garbage collection.
 2630        ///
 2631        /// Note that in order to delete a blob, you must delete all of its
 2632        /// snapshots. You can delete both at the same time using
 2633        /// <see cref="DeleteSnapshotsOption.IncludeSnapshots"/>.
 2634        ///
 2635        /// For more information, see
 2636        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob">
 2637        /// Delete Blob</see>.
 2638        /// </summary>
 2639        /// <param name="blobName">The name of the blob to delete.</param>
 2640        /// <param name="snapshotsOption">
 2641        /// Specifies options for deleting blob snapshots.
 2642        /// </param>
 2643        /// <param name="conditions">
 2644        /// Optional <see cref="BlobRequestConditions"/> to add conditions on
 2645        /// deleting this blob.
 2646        /// </param>
 2647        /// <param name="cancellationToken">
 2648        /// Optional <see cref="CancellationToken"/> to propagate
 2649        /// notifications that the operation should be cancelled.
 2650        /// </param>
 2651        /// <returns>
 2652        /// A <see cref="Response"/> on successfully deleting.
 2653        /// </returns>
 2654        /// <remarks>
 2655        /// A <see cref="RequestFailedException"/> will be thrown if
 2656        /// a failure occurs.
 2657        /// </remarks>
 2658        [ForwardsClientCalls]
 2659        public virtual async Task<Response> DeleteBlobAsync(
 2660            string blobName,
 2661            DeleteSnapshotsOption snapshotsOption = default,
 2662            BlobRequestConditions conditions = default,
 2663            CancellationToken cancellationToken = default) =>
 42664            await GetBlobClient(blobName)
 42665                .DeleteAsync(
 42666                    snapshotsOption,
 42667                    conditions,
 42668                    cancellationToken)
 42669                    .ConfigureAwait(false);
 2670
 2671        /// <summary>
 2672        /// The <see cref="DeleteBlobIfExists"/> operation marks the specified
 2673        /// blob or snapshot for deletion, if the blob or snapshot exists. The blob
 2674        /// is later deleted during garbage collection.
 2675        ///
 2676        /// Note that in order to delete a blob, you must delete all of its
 2677        /// snapshots. You can delete both at the same time using
 2678        /// <see cref="DeleteSnapshotsOption.IncludeSnapshots"/>.
 2679        ///
 2680        /// For more information, see
 2681        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob">
 2682        /// Delete Blob</see>.
 2683        /// </summary>
 2684        /// <param name="blobName">The name of the blob to delete.</param>
 2685        /// <param name="snapshotsOption">
 2686        /// Specifies options for deleting blob snapshots.
 2687        /// </param>
 2688        /// <param name="conditions">
 2689        /// Optional <see cref="BlobRequestConditions"/> to add conditions on
 2690        /// deleting this blob.
 2691        /// </param>
 2692        /// <param name="cancellationToken">
 2693        /// Optional <see cref="CancellationToken"/> to propagate
 2694        /// notifications that the operation should be cancelled.
 2695        /// </param>
 2696        /// <returns>
 2697        /// A <see cref="Response"/> on successfully deleting.
 2698        /// </returns>
 2699        /// <remarks>
 2700        /// A <see cref="RequestFailedException"/> will be thrown if
 2701        /// a failure occurs.
 2702        /// </remarks>
 2703        [ForwardsClientCalls]
 2704        public virtual Response<bool> DeleteBlobIfExists(
 2705            string blobName,
 2706            DeleteSnapshotsOption snapshotsOption = default,
 2707            BlobRequestConditions conditions = default,
 2708            CancellationToken cancellationToken = default) =>
 82709                GetBlobClient(blobName).
 82710                DeleteIfExists(
 82711                    snapshotsOption,
 82712                    conditions ?? default,
 82713                    cancellationToken);
 2714
 2715        /// <summary>
 2716        /// The <see cref="DeleteBlobIfExistsAsync"/> operation marks the specified
 2717        /// blob or snapshot for deletion, if the blob or snapshot exists. The blob
 2718        /// is later deleted during garbage collection.
 2719        ///
 2720        /// Note that in order to delete a blob, you must delete all of its
 2721        /// snapshots. You can delete both at the same time using
 2722        /// <see cref="DeleteSnapshotsOption.IncludeSnapshots"/>.
 2723        ///
 2724        /// For more information, see
 2725        /// <see href="https://docs.microsoft.com/rest/api/storageservices/delete-blob">
 2726        /// Delete Blob</see>.
 2727        /// </summary>
 2728        /// <param name="blobName">The name of the blob to delete.</param>
 2729        /// <param name="snapshotsOption">
 2730        /// Specifies options for deleting blob snapshots.
 2731        /// </param>
 2732        /// <param name="conditions">
 2733        /// Optional <see cref="BlobRequestConditions"/> to add conditions on
 2734        /// deleting this blob.
 2735        /// </param>
 2736        /// <param name="cancellationToken">
 2737        /// Optional <see cref="CancellationToken"/> to propagate
 2738        /// notifications that the operation should be cancelled.
 2739        /// </param>
 2740        /// <returns>
 2741        /// A <see cref="Response"/> on successfully deleting.
 2742        /// </returns>
 2743        /// <remarks>
 2744        /// A <see cref="RequestFailedException"/> will be thrown if
 2745        /// a failure occurs.
 2746        /// </remarks>
 2747        [ForwardsClientCalls]
 2748        public virtual async Task<Response<bool>> DeleteBlobIfExistsAsync(
 2749            string blobName,
 2750            DeleteSnapshotsOption snapshotsOption = default,
 2751            BlobRequestConditions conditions = default,
 2752            CancellationToken cancellationToken = default) =>
 82753            await GetBlobClient(blobName).DeleteIfExistsAsync(
 82754                    snapshotsOption,
 82755                    conditions ?? default,
 82756                    cancellationToken)
 82757                    .ConfigureAwait(false);
 2758
 2759        #endregion DeleteBlob
 2760    }
 2761}