From cc31deb3141b2add93d926d263c4c8d02ee57404 Mon Sep 17 00:00:00 2001 From: tg-msft Date: Sun, 20 Oct 2019 22:06:49 -0700 Subject: [PATCH] Remove WithCPK and thread options down the hierarchy Fixes #7830 --- .../src/EncryptedBlockBlobClient.cs | 15 ++-- .../src/AppendBlobClient.cs | 54 +++------------ .../Azure.Storage.Blobs/src/BlobBaseClient.cs | 69 +++++-------------- .../Azure.Storage.Blobs/src/BlobClient.cs | 8 ++- .../src/BlobClientOptions.cs | 34 ++++----- .../src/BlobContainerClient.cs | 19 ++++- .../src/BlobServiceClient.cs | 19 ++++- .../src/BlockBlobClient.cs | 54 +++------------ .../Azure.Storage.Blobs/src/PageBlobClient.cs | 55 ++++----------- .../tests/AppendBlobClientTests.cs | 9 ++- .../tests/BlobBaseClientTests.cs | 17 ++--- .../tests/BlockBlobClientTests.cs | 12 ++-- .../tests/PageBlobClientTests.cs | 20 +++--- .../tests/TestExtensions.cs | 55 +++++++++++++++ .../tests/Shared/TestExtensions.cs | 2 +- 15 files changed, 204 insertions(+), 238 deletions(-) create mode 100644 sdk/storage/Azure.Storage.Blobs/tests/TestExtensions.cs diff --git a/sdk/storage/Azure.Storage.Blobs.Cryptography/src/EncryptedBlockBlobClient.cs b/sdk/storage/Azure.Storage.Blobs.Cryptography/src/EncryptedBlockBlobClient.cs index 1a5d325b7298..38ea4211efc6 100644 --- a/sdk/storage/Azure.Storage.Blobs.Cryptography/src/EncryptedBlockBlobClient.cs +++ b/sdk/storage/Azure.Storage.Blobs.Cryptography/src/EncryptedBlockBlobClient.cs @@ -4,6 +4,7 @@ using System; using Azure.Core; using Azure.Core.Pipeline; +using Azure.Storage.Blobs.Models; #pragma warning disable SA1402 // File may only contain a single type @@ -148,8 +149,10 @@ public EncryptedBlockBlobClient(Uri blobUri, TokenCredential credential, BlobCli /// /// The transport pipeline used to send every request. /// - internal EncryptedBlockBlobClient(Uri blobUri, HttpPipeline pipeline) - : base(blobUri, pipeline) + /// Client diagnostics. + /// Customer provided key. + internal EncryptedBlockBlobClient(Uri blobUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) + : base(blobUri, pipeline, clientDiagnostics, customerProvidedKey) { } #endregion ctors @@ -175,7 +178,11 @@ public static partial class SpecializedBlobExtensions /// A new instance. public static EncryptedBlockBlobClient GetEncryptedBlockBlobClient( this BlobContainerClient client, - string blobName) - => new EncryptedBlockBlobClient(client.Uri.AppendToPath(blobName), client.Pipeline); + string blobName) => + new EncryptedBlockBlobClient( + client.Uri.AppendToPath(blobName), + client.Pipeline, + client.ClientDiagnostics, + client.CustomerProvidedKey); } } diff --git a/sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs b/sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs index fc493fe2398d..304874fa225b 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/AppendBlobClient.cs @@ -175,13 +175,10 @@ public AppendBlobClient(Uri blobUri, TokenCredential credential, BlobClientOptio /// /// The transport pipeline used to send every request. /// - /// - /// Optional client options that define the transport pipeline - /// policies for authentication, retries, etc., that are applied to - /// every request. - /// - internal AppendBlobClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions options = default) - : base(blobUri, pipeline, options) + /// Client diagnostics. + /// Customer provided key. + internal AppendBlobClient(Uri blobUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) + : base(blobUri, pipeline, clientDiagnostics, customerProvidedKey) { } #endregion ctors @@ -202,40 +199,7 @@ internal AppendBlobClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions public new AppendBlobClient WithSnapshot(string snapshot) { var builder = new BlobUriBuilder(Uri) { Snapshot = snapshot }; - return new AppendBlobClient(builder.ToUri(), Pipeline); - } - - /// - /// Initializes a new instance of the - /// class with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new instance. - public new AppendBlobClient WithCustomerProvidedKey(CustomerProvidedKey customerProvidedKey) => (AppendBlobClient)WithCustomerProvidedKeyCore(customerProvidedKey); - - /// - /// Creates a new instance of the class - /// with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new instance. - protected sealed override BlobBaseClient WithCustomerProvidedKeyCore(CustomerProvidedKey customerProvidedKey) - { - var uriBuilder = new UriBuilder(Uri) - { - Scheme = Constants.Blob.Https, - Port = Constants.Blob.HttpsPort - }; - return new AppendBlobClient( - uriBuilder.Uri, - Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey)); + return new AppendBlobClient(builder.ToUri(), Pipeline, ClientDiagnostics, CustomerProvidedKey); } #region Create @@ -1059,7 +1023,11 @@ public static partial class SpecializedBlobExtensions /// A new instance. public static AppendBlobClient GetAppendBlobClient( this BlobContainerClient client, - string blobName) - => new AppendBlobClient(client.Uri.AppendToPath(blobName), client.Pipeline); + string blobName) => + new AppendBlobClient( + client.Uri.AppendToPath(blobName), + client.Pipeline, + client.ClientDiagnostics, + client.CustomerProvidedKey); } } diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs b/sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs index 3c8dacab12c2..baa836e7b15c 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlobBaseClient.cs @@ -58,12 +58,12 @@ public class BlobBaseClient /// /// The to be used when sending requests. /// - private readonly CustomerProvidedKey? _customerProvidedKey; + internal readonly CustomerProvidedKey? _customerProvidedKey; /// /// The to be used when sending requests. /// - public virtual CustomerProvidedKey? CustomerProvidedKey => _customerProvidedKey; + internal virtual CustomerProvidedKey? CustomerProvidedKey => _customerProvidedKey; /// /// The Storage account name corresponding to the blob client. @@ -183,6 +183,7 @@ public BlobBaseClient(string connectionString, string blobContainerName, string _pipeline = options.Build(conn.Credentials); _clientDiagnostics = new ClientDiagnostics(options); _customerProvidedKey = options?.CustomerProvidedKey; + BlobErrors.VerifyHttpsCustomerProvidedKey(_uri, _customerProvidedKey); } /// @@ -272,6 +273,7 @@ internal BlobBaseClient(Uri blobUri, HttpPipelinePolicy authentication, BlobClie _pipeline = options.Build(authentication); _clientDiagnostics = new ClientDiagnostics(options); _customerProvidedKey = options?.CustomerProvidedKey; + BlobErrors.VerifyHttpsCustomerProvidedKey(_uri, _customerProvidedKey); } /// @@ -286,18 +288,14 @@ internal BlobBaseClient(Uri blobUri, HttpPipelinePolicy authentication, BlobClie /// /// The transport pipeline used to send every request. /// - /// - /// Optional client options that define the transport pipeline - /// policies for authentication, retries, etc., that are applied to - /// - internal BlobBaseClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions options = default) + /// Client diagnostics. + /// Customer provided key. + internal BlobBaseClient(Uri blobUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) { - options ??= new BlobClientOptions(); - _uri = blobUri; _pipeline = pipeline; - _clientDiagnostics = new ClientDiagnostics(options); - _customerProvidedKey = options?.CustomerProvidedKey; + _clientDiagnostics = clientDiagnostics; + _customerProvidedKey = customerProvidedKey; } #endregion ctors @@ -326,42 +324,7 @@ internal BlobBaseClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions op protected virtual BlobBaseClient WithSnapshotCore(string snapshot) { var builder = new BlobUriBuilder(Uri) { Snapshot = snapshot }; - return new BlobBaseClient(builder.ToUri(), Pipeline); - } - - /// - /// Initializes a new instance of the class - /// with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new - public virtual BlobBaseClient WithCustomerProvidedKey(CustomerProvidedKey customerProvidedKey) => - WithCustomerProvidedKeyCore(customerProvidedKey); - - /// - /// Creates a new instance of the class - /// with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new - protected virtual BlobBaseClient WithCustomerProvidedKeyCore(CustomerProvidedKey customerProvidedKey) - { - var uriBuilder = new UriBuilder(Uri) - { - Scheme = Constants.Blob.Https, - Port = Constants.Blob.HttpsPort - }; - return new BlobBaseClient( - uriBuilder.Uri, - Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey)); - + return new BlobBaseClient(builder.ToUri(), Pipeline, ClientDiagnostics, CustomerProvidedKey); } /// @@ -1213,7 +1176,7 @@ internal Task> StagedDownloadAsync( { Debug.Assert(singleBlockThreshold <= Constants.Blob.Block.MaxDownloadBytes); - var client = new BlobBaseClient(Uri, Pipeline); + var client = new BlobBaseClient(Uri, Pipeline, ClientDiagnostics, CustomerProvidedKey); Task> downloadTask = PartitionedDownloader.DownloadAsync( destination, @@ -2977,9 +2940,13 @@ public static partial class SpecializedBlobExtensions /// The . /// The name of the blob. /// A new instance. - public static BlobBaseClient GetBlobClient( + public static BlobBaseClient GetBlobBaseClient( this BlobContainerClient client, - string blobName) - => new BlobBaseClient(client.Uri.AppendToPath(blobName), client.Pipeline); + string blobName) => + new BlobBaseClient( + client.Uri.AppendToPath(blobName), + client.Pipeline, + client.ClientDiagnostics, + client.CustomerProvidedKey); } } diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlobClient.cs b/sdk/storage/Azure.Storage.Blobs/src/BlobClient.cs index e0f3267e351c..ca8df9f2fed4 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlobClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlobClient.cs @@ -157,8 +157,10 @@ public BlobClient(Uri blobUri, TokenCredential credential, BlobClientOptions opt /// /// The transport pipeline used to send every request. /// - internal BlobClient(Uri blobUri, HttpPipeline pipeline) - : base(blobUri, pipeline) + /// Client diagnostics. + /// Customer provided key. + internal BlobClient(Uri blobUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) + : base(blobUri, pipeline, clientDiagnostics, customerProvidedKey) { } #endregion ctors @@ -826,7 +828,7 @@ internal async Task> StagedUploadAsync( CancellationToken cancellationToken = default) { - var client = new BlockBlobClient(Uri, Pipeline); + var client = new BlockBlobClient(Uri, Pipeline, ClientDiagnostics, CustomerProvidedKey); singleBlockThreshold ??= client.BlockBlobMaxUploadBlobBytes; Debug.Assert(singleBlockThreshold <= client.BlockBlobMaxUploadBlobBytes); diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlobClientOptions.cs b/sdk/storage/Azure.Storage.Blobs/src/BlobClientOptions.cs index f30d99360cf8..5d2c5bcf023d 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlobClientOptions.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlobClientOptions.cs @@ -47,26 +47,6 @@ public enum ServiceVersion /// public CustomerProvidedKey? CustomerProvidedKey { get; set; } - /// - /// Initializes a new instance of the - /// class. - /// - /// - /// The of the service API used when - /// making requests - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - public BlobClientOptions( - ServiceVersion version = LatestVersion, - CustomerProvidedKey? customerProvidedKey = default) - { - Version = version == ServiceVersion.V2019_02_02 ? version: throw Errors.VersionNotSupported(nameof(version)); - CustomerProvidedKey = customerProvidedKey; - this.Initialize(); - } - /// /// Gets or sets the secondary storage that can be read from for the storage account if the /// account is enabled for RA-GRS. @@ -79,6 +59,20 @@ public BlobClientOptions( /// public Uri GeoRedundantSecondaryUri { get; set; } + /// + /// Initializes a new instance of the + /// class. + /// + /// + /// The of the service API used when + /// making requests. + /// + public BlobClientOptions(ServiceVersion version = LatestVersion) + { + Version = version == ServiceVersion.V2019_02_02 ? version: throw Errors.VersionNotSupported(nameof(version)); + this.Initialize(); + } + /// /// Create an HttpPipeline from BlobClientOptions. /// diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlobContainerClient.cs b/sdk/storage/Azure.Storage.Blobs/src/BlobContainerClient.cs index 33d0fb40d487..ffdcb3802089 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlobContainerClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlobContainerClient.cs @@ -72,6 +72,16 @@ public class BlobContainerClient /// internal virtual ClientDiagnostics ClientDiagnostics => _clientDiagnostics; + /// + /// The to be used when sending requests. + /// + internal readonly CustomerProvidedKey? _customerProvidedKey; + + /// + /// The to be used when sending requests. + /// + internal virtual CustomerProvidedKey? CustomerProvidedKey => _customerProvidedKey; + /// /// The Storage account name corresponding to the container client. /// @@ -161,6 +171,7 @@ public BlobContainerClient(string connectionString, string blobContainerName, Bl options ??= new BlobClientOptions(); _pipeline = options.Build(conn.Credentials); _clientDiagnostics = new ClientDiagnostics(options); + _customerProvidedKey = options.CustomerProvidedKey; } /// @@ -245,6 +256,7 @@ internal BlobContainerClient(Uri blobContainerUri, HttpPipelinePolicy authentica options ??= new BlobClientOptions(); _pipeline = options.Build(authentication); _clientDiagnostics = new ClientDiagnostics(options); + _customerProvidedKey = options.CustomerProvidedKey; } /// @@ -259,11 +271,13 @@ internal BlobContainerClient(Uri blobContainerUri, HttpPipelinePolicy authentica /// The transport pipeline used to send every request. /// /// - internal BlobContainerClient(Uri containerUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics) + /// /// Customer provided key. + internal BlobContainerClient(Uri containerUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) { _uri = containerUri; _pipeline = pipeline; _clientDiagnostics = clientDiagnostics; + _customerProvidedKey = customerProvidedKey; } #endregion ctor @@ -275,7 +289,8 @@ internal BlobContainerClient(Uri containerUri, HttpPipeline pipeline, ClientDiag /// /// The name of the blob. /// A new instance. - public virtual BlobClient GetBlobClient(string blobName) => new BlobClient(Uri.AppendToPath(blobName), _pipeline); + public virtual BlobClient GetBlobClient(string blobName) => + new BlobClient(Uri.AppendToPath(blobName), _pipeline, ClientDiagnostics, CustomerProvidedKey); /// /// Sets the various name fields if they are currently null. diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlobServiceClient.cs b/sdk/storage/Azure.Storage.Blobs/src/BlobServiceClient.cs index 3c19bdfae26f..56f3231c2082 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlobServiceClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlobServiceClient.cs @@ -68,6 +68,16 @@ public class BlobServiceClient /// internal virtual ClientDiagnostics ClientDiagnostics => _clientDiagnostics; + /// + /// The to be used when sending requests. + /// + internal readonly CustomerProvidedKey? _customerProvidedKey; + + /// + /// The to be used when sending requests. + /// + internal virtual CustomerProvidedKey? CustomerProvidedKey => _customerProvidedKey; + /// /// The Storage account name corresponding to the service client. /// @@ -137,6 +147,7 @@ public BlobServiceClient(string connectionString, BlobClientOptions options) _authenticationPolicy = StorageClientOptions.GetAuthenticationPolicy(conn.Credentials); _pipeline = options.Build(_authenticationPolicy); _clientDiagnostics = new ClientDiagnostics(options); + _customerProvidedKey = options.CustomerProvidedKey; } /// @@ -212,7 +223,7 @@ public BlobServiceClient(Uri serviceUri, TokenCredential credential, BlobClientO /// every request. /// internal BlobServiceClient(Uri serviceUri, HttpPipelinePolicy authentication, BlobClientOptions options) - : this(serviceUri, authentication, options.Build(authentication), new ClientDiagnostics(options)) + : this(serviceUri, authentication, options.Build(authentication), new ClientDiagnostics(options), options?.CustomerProvidedKey) { } @@ -229,12 +240,14 @@ internal BlobServiceClient(Uri serviceUri, HttpPipelinePolicy authentication, Bl /// The transport pipeline used to send every request. /// /// - internal BlobServiceClient(Uri serviceUri, HttpPipelinePolicy authentication, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics) + /// Customer provided key. + internal BlobServiceClient(Uri serviceUri, HttpPipelinePolicy authentication, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) { _uri = serviceUri; _authenticationPolicy = authentication; _pipeline = pipeline; _clientDiagnostics = clientDiagnostics; + _customerProvidedKey = customerProvidedKey; } #endregion ctors @@ -251,7 +264,7 @@ internal BlobServiceClient(Uri serviceUri, HttpPipelinePolicy authentication, Ht /// A for the desired container. /// public virtual BlobContainerClient GetBlobContainerClient(string blobContainerName) => - new BlobContainerClient(Uri.AppendToPath(blobContainerName), Pipeline, ClientDiagnostics); + new BlobContainerClient(Uri.AppendToPath(blobContainerName), Pipeline, ClientDiagnostics, CustomerProvidedKey); #region GetBlobContainers /// diff --git a/sdk/storage/Azure.Storage.Blobs/src/BlockBlobClient.cs b/sdk/storage/Azure.Storage.Blobs/src/BlockBlobClient.cs index b5011846c08a..261d81c3517e 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/BlockBlobClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/BlockBlobClient.cs @@ -229,13 +229,10 @@ public BlockBlobClient(Uri blobUri, TokenCredential credential, BlobClientOption /// /// The transport pipeline used to send every request. /// - /// - /// Optional client options that define the transport pipeline - /// policies for authentication, retries, etc., that are applied to - /// every request. - /// - internal BlockBlobClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions options = default) - : base(blobUri, pipeline, options) + /// Client diagnostics. + /// Customer provided key. + internal BlockBlobClient(Uri blobUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) + : base(blobUri, pipeline, clientDiagnostics, customerProvidedKey) { } #endregion ctors @@ -265,40 +262,7 @@ internal BlockBlobClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions o protected sealed override BlobBaseClient WithSnapshotCore(string snapshot) { var builder = new BlobUriBuilder(Uri) { Snapshot = snapshot }; - return new BlockBlobClient(builder.ToUri(), Pipeline); - } - - /// - /// Initializes a new instance of the - /// class with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new instance. - public new BlockBlobClient WithCustomerProvidedKey(CustomerProvidedKey customerProvidedKey) => (BlockBlobClient)WithCustomerProvidedKeyCore(customerProvidedKey); - - /// - /// Creates a new instance of the class - /// with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new instance. - protected sealed override BlobBaseClient WithCustomerProvidedKeyCore(CustomerProvidedKey customerProvidedKey) - { - var uriBuilder = new UriBuilder(Uri) - { - Scheme = Constants.Blob.Https, - Port = Constants.Blob.HttpsPort - }; - return new BlockBlobClient( - uriBuilder.Uri, - Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey)); + return new BlockBlobClient(builder.ToUri(), Pipeline, ClientDiagnostics, CustomerProvidedKey); } ///// @@ -1548,7 +1512,11 @@ public static partial class SpecializedBlobExtensions /// A new instance. public static BlockBlobClient GetBlockBlobClient( this BlobContainerClient client, - string blobName) - => new BlockBlobClient(client.Uri.AppendToPath(blobName), client.Pipeline); + string blobName) => + new BlockBlobClient( + client.Uri.AppendToPath(blobName), + client.Pipeline, + client.ClientDiagnostics, + client.CustomerProvidedKey); } } diff --git a/sdk/storage/Azure.Storage.Blobs/src/PageBlobClient.cs b/sdk/storage/Azure.Storage.Blobs/src/PageBlobClient.cs index ccf53b8a24af..083e4ee0d8c4 100644 --- a/sdk/storage/Azure.Storage.Blobs/src/PageBlobClient.cs +++ b/sdk/storage/Azure.Storage.Blobs/src/PageBlobClient.cs @@ -174,12 +174,10 @@ public PageBlobClient(Uri blobUri, TokenCredential credential, BlobClientOptions /// /// The transport pipeline used to send every request. /// - /// - /// Optional client options that define the transport pipeline - /// policies for authentication, retries, etc., that are applied to - /// - internal PageBlobClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions options = default) - : base(blobUri, pipeline, options) + /// Client diagnostics. + /// Customer provided key. + internal PageBlobClient(Uri blobUri, HttpPipeline pipeline, ClientDiagnostics clientDiagnostics, CustomerProvidedKey? customerProvidedKey) + : base(blobUri, pipeline, clientDiagnostics, customerProvidedKey) { } #endregion ctors @@ -209,40 +207,7 @@ internal PageBlobClient(Uri blobUri, HttpPipeline pipeline, BlobClientOptions op protected sealed override BlobBaseClient WithSnapshotCore(string snapshot) { var builder = new BlobUriBuilder(Uri) { Snapshot = snapshot }; - return new PageBlobClient(builder.ToUri(), Pipeline); - } - - /// - /// Initializes a new instance of the - /// class with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new instance. - public new PageBlobClient WithCustomerProvidedKey(CustomerProvidedKey customerProvidedKey) => (PageBlobClient)WithCustomerProvidedKeyCore(customerProvidedKey); - - /// - /// Creates a new instance of the class - /// with an identical source but the specified - /// customer provided key. - /// - /// - /// The customer provided key to be used by the service to encrypt data. - /// - /// A new instance. - protected sealed override BlobBaseClient WithCustomerProvidedKeyCore(CustomerProvidedKey customerProvidedKey) - { - var uriBuilder = new UriBuilder(Uri) - { - Scheme = Constants.Blob.Https, - Port = Constants.Blob.HttpsPort - }; - return new PageBlobClient( - uriBuilder.Uri, - Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey)); + return new PageBlobClient(builder.ToUri(), Pipeline, ClientDiagnostics, CustomerProvidedKey); } ///// @@ -2147,7 +2112,7 @@ private async Task> StartCopyIncrementalInternal( try { // Create copySource Uri - PageBlobClient pageBlobUri = new PageBlobClient(sourceUri, Pipeline).WithSnapshot(snapshot); + PageBlobClient pageBlobUri = new PageBlobClient(sourceUri, Pipeline, ClientDiagnostics, CustomerProvidedKey).WithSnapshot(snapshot); return await BlobRestClient.PageBlob.CopyIncrementalAsync( ClientDiagnostics, @@ -2471,7 +2436,11 @@ public static partial class SpecializedBlobExtensions /// A new instance. public static PageBlobClient GetPageBlobClient( this BlobContainerClient client, - string blobName) - => new PageBlobClient(client.Uri.AppendToPath(blobName), client.Pipeline); + string blobName) => + new PageBlobClient( + client.Uri.AppendToPath(blobName), + client.Pipeline, + client.ClientDiagnostics, + client.CustomerProvidedKey); } } diff --git a/sdk/storage/Azure.Storage.Blobs/tests/AppendBlobClientTests.cs b/sdk/storage/Azure.Storage.Blobs/tests/AppendBlobClientTests.cs index 1ac8a19b65d2..c245cc17a9e7 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/AppendBlobClientTests.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/AppendBlobClientTests.cs @@ -149,7 +149,8 @@ public async Task CreateAsync_CpkHttpError() blob = InstrumentClient(new AppendBlobClient( blob.Uri, blob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + blob.ClientDiagnostics, + customerProvidedKey)); ; Assert.AreEqual(Constants.Blob.Http, blob.Uri.Scheme); @@ -376,7 +377,8 @@ public async Task AppendBlockAsync_CpkHttpError() httpBlob = InstrumentClient(new AppendBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); AppendBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); var data = GetRandomBuffer(Constants.KB); @@ -662,7 +664,8 @@ public async Task AppendBlockFromUriAsync_CpkHttpError() httpDestBlob = InstrumentClient(new AppendBlobClient( httpDestBlob.Uri, httpDestBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpDestBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpDestBlob.Uri.Scheme); AppendBlobClient httpsDestBlob = InstrumentClient(httpDestBlob.WithCustomerProvidedKey(customerProvidedKey)); await httpsDestBlob.CreateAsync(); diff --git a/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs b/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs index 2ea7ae87d60b..ef762e87a8b4 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/BlobBaseClientTests.cs @@ -192,7 +192,8 @@ public async Task DownloadAsync_CpkHttpError() httpBlob = InstrumentClient(new BlockBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); BlockBlobClient httpsblob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); using (var stream = new MemoryStream(data)) @@ -1218,12 +1219,10 @@ public async Task GetPropertiesAsync_CpkError() httpBlob = InstrumentClient(new AppendBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); - AppendBlobClient httpsBlob = InstrumentClient(new AppendBlobClient( - GetHttpsUri(httpBlob.Uri), - httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + AppendBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); await httpsBlob.CreateAsync(); // Act @@ -1616,7 +1615,8 @@ public async Task SetMetadataAsync_CpkError() httpBlob = InstrumentClient(new AppendBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); AppendBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); IDictionary metadata = BuildMetadata(); @@ -1745,7 +1745,8 @@ public async Task CreateSnapshotAsync_CpkHttpError() httpBlob = InstrumentClient(new AppendBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); AppendBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); await httpsBlob.CreateAsync(); diff --git a/sdk/storage/Azure.Storage.Blobs/tests/BlockBlobClientTests.cs b/sdk/storage/Azure.Storage.Blobs/tests/BlockBlobClientTests.cs index 4c414d2ca22f..d3b098137b54 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/BlockBlobClientTests.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/BlockBlobClientTests.cs @@ -151,7 +151,8 @@ public async Task StageBlockAsync_CpkHttpError() httpBlob = InstrumentClient(new BlockBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); BlockBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); @@ -377,7 +378,8 @@ public async Task StageBlockFromUriAsync_CpkHttpError() destBlob = InstrumentClient(new BlockBlobClient( destBlob.Uri, destBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + destBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, destBlob.Uri.Scheme); // Act @@ -1236,15 +1238,15 @@ public async Task UploadAsync_CpkHttpError() blob = InstrumentClient(new BlockBlobClient( blob.Uri, blob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + blob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, blob.Uri.Scheme); var data = GetRandomBuffer(Size); // Act using var stream = new MemoryStream(data); await TestHelper.AssertExpectedExceptionAsync( - blob.UploadAsync( - content: stream), + blob.UploadAsync(content: stream), actualException => Assert.AreEqual("Cannot use client-provided key without HTTPS.", actualException.Message)); } } diff --git a/sdk/storage/Azure.Storage.Blobs/tests/PageBlobClientTests.cs b/sdk/storage/Azure.Storage.Blobs/tests/PageBlobClientTests.cs index c69267bf0a4f..61a9325e4989 100644 --- a/sdk/storage/Azure.Storage.Blobs/tests/PageBlobClientTests.cs +++ b/sdk/storage/Azure.Storage.Blobs/tests/PageBlobClientTests.cs @@ -140,7 +140,8 @@ public async Task CreateAsync_CpkHttpError() blob = InstrumentClient(new PageBlobClient( blob.Uri, blob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + blob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, blob.Uri.Scheme); @@ -361,7 +362,8 @@ public async Task UploadPagesAsync_CpkHttpError() httpBlob = InstrumentClient(new PageBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); PageBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); var data = GetRandomBuffer(Constants.KB); @@ -579,10 +581,7 @@ public async Task ClearPagesAsync_CPK() // Arrange PageBlobClient blob = InstrumentClient(container.GetPageBlobClient(GetNewBlobName())); CustomerProvidedKey customerProvidedKey = GetCustomerProvidedKey(); - blob = InstrumentClient(new PageBlobClient( - GetHttpsUri(blob.Uri), - blob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + blob = InstrumentClient(blob.WithCustomerProvidedKey(customerProvidedKey)); await blob.CreateAsync(4 * Constants.KB); var data = GetRandomBuffer(4 * Constants.KB); using (var stream = new MemoryStream(data)) @@ -610,7 +609,8 @@ public async Task ClearPagesAsync_CpkHttpError() httpBlob = InstrumentClient(new PageBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); PageBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); @@ -1070,7 +1070,8 @@ public async Task ResizeAsync_CpkHttpError() httpBlob = InstrumentClient(new PageBlobClient( httpBlob.Uri, httpBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpBlob.Uri.Scheme); PageBlobClient httpsBlob = InstrumentClient(httpBlob.WithCustomerProvidedKey(customerProvidedKey)); @@ -1653,7 +1654,8 @@ public async Task UploadPagesFromUriAsync_CpkHttpError() httpDestBlob = InstrumentClient(new PageBlobClient( httpDestBlob.Uri, httpDestBlob.Pipeline, - new BlobClientOptions(customerProvidedKey: customerProvidedKey))); + httpDestBlob.ClientDiagnostics, + customerProvidedKey)); Assert.AreEqual(Constants.Blob.Http, httpDestBlob.Uri.Scheme); PageBlobClient httpsDestBlob = InstrumentClient(httpDestBlob.WithCustomerProvidedKey(customerProvidedKey)); diff --git a/sdk/storage/Azure.Storage.Blobs/tests/TestExtensions.cs b/sdk/storage/Azure.Storage.Blobs/tests/TestExtensions.cs new file mode 100644 index 000000000000..ce34de880150 --- /dev/null +++ b/sdk/storage/Azure.Storage.Blobs/tests/TestExtensions.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Azure.Core; +using Azure.Storage.Blobs; +using Azure.Storage.Blobs.Models; +using Azure.Storage.Blobs.Specialized; + +namespace Azure.Storage +{ + /// + /// Extension methods to make tests easier to author. + /// + public static partial class TestExtensions + { + private static Uri ToHttps(Uri uri) + { + RequestUriBuilder builder = new RequestUriBuilder(); + builder.Reset(uri); + builder.Scheme = Constants.Blob.Https; + builder.Port = Constants.Blob.HttpsPort; + return builder.ToUri(); + } + + public static AppendBlobClient WithCustomerProvidedKey( + this AppendBlobClient blob, + CustomerProvidedKey customerProvidedKey) => + new AppendBlobClient( + ToHttps(blob.Uri), + blob.Pipeline, + blob.ClientDiagnostics, + customerProvidedKey); + + public static BlockBlobClient WithCustomerProvidedKey( + this BlockBlobClient blob, + CustomerProvidedKey customerProvidedKey) => + new BlockBlobClient( + ToHttps(blob.Uri), + blob.Pipeline, + blob.ClientDiagnostics, + customerProvidedKey); + + public static PageBlobClient WithCustomerProvidedKey( + this PageBlobClient blob, + CustomerProvidedKey customerProvidedKey) => + new PageBlobClient( + ToHttps(blob.Uri), + blob.Pipeline, + blob.ClientDiagnostics, + customerProvidedKey); + } +} diff --git a/sdk/storage/Azure.Storage.Common/tests/Shared/TestExtensions.cs b/sdk/storage/Azure.Storage.Common/tests/Shared/TestExtensions.cs index 599ae5aa661a..60408b74f848 100644 --- a/sdk/storage/Azure.Storage.Common/tests/Shared/TestExtensions.cs +++ b/sdk/storage/Azure.Storage.Common/tests/Shared/TestExtensions.cs @@ -10,7 +10,7 @@ namespace Azure.Storage /// /// Extension methods to make tests easier to author. /// - public static class TestExtensions + public static partial class TestExtensions { /// /// Convert an IAsyncEnumerable into a List to make test verification