From 5232034e9e7aae5e3c319d722ad71ee747a6f17d Mon Sep 17 00:00:00 2001 From: Lin Jian Date: Wed, 25 Mar 2020 10:38:32 +0800 Subject: [PATCH] hide the versionId option in convenience layer --- .../storage-blob/review/storage-blob.api.md | 14 ++-- sdk/storage/storage-blob/src/Clients.ts | 74 ++++++------------- .../storage-blob/test/blobversioning.spec.ts | 62 ++++++---------- .../storage-blob/test/node/sas.spec.ts | 12 +-- 4 files changed, 59 insertions(+), 103 deletions(-) diff --git a/sdk/storage/storage-blob/review/storage-blob.api.md b/sdk/storage/storage-blob/review/storage-blob.api.md index 543ab6e247f6..82f17ee9b0fb 100644 --- a/sdk/storage/storage-blob/review/storage-blob.api.md +++ b/sdk/storage/storage-blob/review/storage-blob.api.md @@ -380,7 +380,7 @@ export class BlobClient extends StorageClient { syncCopyFromURL(copySource: string, options?: BlobSyncCopyFromURLOptions): Promise; undelete(options?: BlobUndeleteOptions): Promise; withSnapshot(snapshot: string): BlobClient; - withVersionId(versionId: string): BlobClient; + withVersion(versionId: string): BlobClient; } // @public @@ -454,7 +454,6 @@ export interface BlobDeleteOptions extends CommonOptions { conditions?: BlobRequestConditions; customerProvidedKey?: CpkInfo; deleteSnapshots?: DeleteSnapshotsOptionType; - versionId?: string; } // @public @@ -531,7 +530,6 @@ export interface BlobDownloadOptions extends CommonOptions { rangeGetContentCrc64?: boolean; rangeGetContentMD5?: boolean; snapshot?: string; - versionId?: string; } // @public @@ -552,7 +550,6 @@ export interface BlobDownloadToBufferOptions extends CommonOptions { customerProvidedKey?: CpkInfo; maxRetryRequestsPerBlock?: number; onProgress?: (progress: TransferProgressEvent) => void; - versionId?: string; } // @public @@ -560,7 +557,6 @@ export interface BlobExistsOptions extends CommonOptions { abortSignal?: AbortSignalLike; conditions?: BlobRequestConditions; customerProvidedKey?: CpkInfo; - versionId?: string; } // @public @@ -622,7 +618,6 @@ export interface BlobGetPropertiesOptions extends CommonOptions { abortSignal?: AbortSignalLike; conditions?: BlobRequestConditions; customerProvidedKey?: CpkInfo; - versionId?: string; } // @public @@ -1264,7 +1259,7 @@ export class ContainerClient extends StorageClient { get containerName(): string; create(options?: ContainerCreateOptions): Promise; delete(options?: ContainerDeleteMethodOptions): Promise; - deleteBlob(blobName: string, options?: BlobDeleteOptions): Promise; + deleteBlob(blobName: string, options?: ContainerDeleteBlobOptions): Promise; exists(options?: ContainerExistsOptions): Promise; getAccessPolicy(options?: ContainerGetAccessPolicyOptions): Promise; getAppendBlobClient(blobName: string): AppendBlobClient; @@ -1314,6 +1309,11 @@ export type ContainerCreateResponse = ContainerCreateHeaders & { }; }; +// @public +export interface ContainerDeleteBlobOptions extends BlobDeleteOptions { + versionId?: string; +} + // @public export interface ContainerDeleteHeaders { clientRequestId?: string; diff --git a/sdk/storage/storage-blob/src/Clients.ts b/sdk/storage/storage-blob/src/Clients.ts index 7b8080653422..7d6db853b4be 100644 --- a/sdk/storage/storage-blob/src/Clients.ts +++ b/sdk/storage/storage-blob/src/Clients.ts @@ -201,14 +201,6 @@ export interface BlobDownloadOptions extends CommonOptions { * @memberof BlobDownloadOptions */ snapshot?: string; - /** - * An opaque DateTime string value that, when present, specifies the version of the blob - * to retrieve. It's for service version 2019-10-10 and newer. - * - * @type {string} - * @memberof BlobDownloadOptions - */ - versionId?: string; /** * When this is set to true and download range of blob, the service returns the MD5 hash for the range, * as long as the range is less than or equal to 4 MB in size. @@ -298,14 +290,6 @@ export interface BlobExistsOptions extends CommonOptions { * @memberof BlobExistsOptions */ conditions?: BlobRequestConditions; - /** - * An opaque DateTime value that, when present, specifies the version - * of the blob to retrieve. It's for service version 2019-10-10 and newer. - * - * @type {string} - * @memberof BlobExistsOptions - */ - versionId?: string; } /** @@ -337,14 +321,6 @@ export interface BlobGetPropertiesOptions extends CommonOptions { * @memberof BlobGetPropertiesOptions */ customerProvidedKey?: CpkInfo; - /** - * An opaque DateTime value that, when present, specifies the version - * of the blob to retrieve. It's for service version 2019-10-10 and newer. - * - * @type {string} - * @memberof BlobGetPropertiesOptions - */ - versionId?: string; } /** @@ -385,14 +361,6 @@ export interface BlobDeleteOptions extends CommonOptions { * @memberof BlobDeleteOptions */ customerProvidedKey?: CpkInfo; - /** - * An opaque DateTime value that, when present, specifies the version - * of the blob to delete. It's for service version 2019-10-10 and newer. - * - * @type {string} - * @memberof BlobDeleteOptions - */ - versionId?: string; } /** @@ -890,14 +858,6 @@ export interface BlobDownloadToBufferOptions extends CommonOptions { * @memberof BlobDownloadToBufferOptions */ customerProvidedKey?: CpkInfo; - /** - * An opaque DateTime string value that, when present, specifies the version of the blob - * to retrieve. It's for service version 2019-10-10 and newer. - * - * @type {string} - * @memberof BlobDownloadToBufferOptions - */ - versionId?: string; } /** @@ -1106,7 +1066,7 @@ export class BlobClient extends StorageClient { * @returns {BlobClient} A new BlobClient object pointing to the version of this blob. * @memberof BlobClient */ - public withVersionId(versionId: string): BlobClient { + public withVersion(versionId: string): BlobClient { return new BlobClient( setURLParameter( this.url, @@ -1228,7 +1188,6 @@ export class BlobClient extends StorageClient { rangeGetContentMD5: options.rangeGetContentMD5, rangeGetContentCRC64: options.rangeGetContentCrc64, snapshot: options.snapshot, - versionId: options.versionId, cpkInfo: options.customerProvidedKey, spanOptions }); @@ -1274,7 +1233,6 @@ export class BlobClient extends StorageClient { rangeGetContentMD5: options.rangeGetContentMD5, rangeGetContentCRC64: options.rangeGetContentCrc64, snapshot: options.snapshot, - versionId: options.versionId, cpkInfo: options.customerProvidedKey }; @@ -1329,7 +1287,6 @@ export class BlobClient extends StorageClient { await this.getProperties({ abortSignal: options.abortSignal, customerProvidedKey: options.customerProvidedKey, - versionId: options.versionId, conditions: options.conditions, tracingOptions: { ...options.tracingOptions, @@ -1381,7 +1338,6 @@ export class BlobClient extends StorageClient { leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, cpkInfo: options.customerProvidedKey, - versionId: options.versionId, spanOptions }); } catch (e) { @@ -1415,7 +1371,6 @@ export class BlobClient extends StorageClient { deleteSnapshots: options.deleteSnapshots, leaseAccessConditions: options.conditions, modifiedAccessConditions: options.conditions, - versionId: options.versionId, spanOptions }); } catch (e) { @@ -1936,7 +1891,6 @@ export class BlobClient extends StorageClient { conditions: options.conditions, maxRetryRequests: options.maxRetryRequestsPerBlock, customerProvidedKey: options.customerProvidedKey, - versionId: options.versionId, tracingOptions: { ...options.tracingOptions, spanOptions @@ -5667,6 +5621,23 @@ export interface ContainerChangeLeaseOptions extends CommonOptions { conditions?: ModifiedAccessConditions; } +/** + * Options to configure the {@link ContainerClient.deleteBlob} operation. + * + * @export + * @interface ContainerDeleteBlobOptions + */ +export interface ContainerDeleteBlobOptions extends BlobDeleteOptions { + /** + * An opaque DateTime value that, when present, specifies the version + * of the blob to delete. It's for service version 2019-10-10 and newer. + * + * @type {string} + * @memberof ContainerDeleteBlobOptions + */ + versionId?: string; +} + /** * Options to configure Container - List Segment operations. * @@ -6410,17 +6381,20 @@ export class ContainerClient extends StorageClient { * @see https://docs.microsoft.com/en-us/rest/api/storageservices/delete-blob * * @param {string} blobName - * @param {BlobDeleteOptions} [options] Options to Blob Delete operation. + * @param {ContainerDeleteBlobOptions} [options] Options to Blob Delete operation. * @returns {Promise} Block blob deletion response data. * @memberof ContainerClient */ public async deleteBlob( blobName: string, - options: BlobDeleteOptions = {} + options: ContainerDeleteBlobOptions = {} ): Promise { const { span, spanOptions } = createSpan("ContainerClient-deleteBlob", options.tracingOptions); try { - const blobClient = this.getBlobClient(blobName); + let blobClient = this.getBlobClient(blobName); + if (options.versionId) { + blobClient = blobClient.withVersion(options.versionId); + } return await blobClient.delete({ ...options, tracingOptions: { ...options!.tracingOptions, spanOptions } diff --git a/sdk/storage/storage-blob/test/blobversioning.spec.ts b/sdk/storage/storage-blob/test/blobversioning.spec.ts index f04cea396cce..0710d2682aeb 100644 --- a/sdk/storage/storage-blob/test/blobversioning.spec.ts +++ b/sdk/storage/storage-blob/test/blobversioning.spec.ts @@ -88,43 +88,35 @@ describe("Blob versioning", () => { }); it("download a blob version", async () => { - const downloadRes = await blobClient.download(0, undefined, { - versionId: uploadRes.versionId - }); + const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); + const downloadRes = await blobVersionClient.download(); assert.deepStrictEqual(await bodyToString(downloadRes, content.length), content); assert.deepStrictEqual(downloadRes.versionId, uploadRes.versionId); - const downloadRes2 = await blobClient.download(undefined, undefined, { - versionId: uploadRes2.versionId - }); + + const downloadRes2 = await blobClient.withVersion(uploadRes2.versionId!).download(); assert.deepStrictEqual(await bodyToString(downloadRes2), ""); assert.deepStrictEqual(downloadRes2.versionId, uploadRes2.versionId); if (isNode) { - const downloadToBufferRes = await blobClient.downloadToBuffer(undefined, undefined, { - versionId: uploadRes.versionId - }); + const downloadToBufferRes = await blobVersionClient.downloadToBuffer(); assert.ok(downloadToBufferRes.equals(Buffer.from(content))); } }); it("download a version to file", async function () { if (!isNode) { this.skip(); } - recorder.skip("node", "Temp file - recorder doesn't support saving the file"); const downloadedFilePath = recorder.getUniqueName("downloadedtofile"); - await blobClient.downloadToFile(downloadedFilePath, undefined, undefined, { - versionId: uploadRes.versionId - }); + await blobClient.withVersion(uploadRes.versionId!).downloadToFile(downloadedFilePath); const downloadedFileContent = fs.readFileSync(downloadedFilePath); assert.ok(downloadedFileContent.equals(Buffer.from(downloadedFileContent))); fs.unlinkSync(downloadedFilePath); }); it("get properties of a blob version", async () => { - const getRes = await blobClient.getProperties({ - versionId: uploadRes.versionId, - }) + const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); + const getRes = await blobVersionClient.getProperties(); assert.equal(getRes.contentLength, content.length); assert.equal(getRes.versionId, uploadRes.versionId); assert.ok(!getRes.isCurrentVersion); @@ -138,29 +130,22 @@ describe("Blob versioning", () => { const snapshotRes = await blobClient.createSnapshot(); let exceptionCaught = false; try { - await blobClient.withSnapshot(snapshotRes.snapshot!).getProperties({ - versionId: uploadRes.versionId, - }); + await blobVersionClient.withSnapshot(snapshotRes.snapshot!).getProperties(); } catch (err) { assert.equal(err.details.errorCode, "MutuallyExclusiveQueryParameters"); exceptionCaught = true; } assert.ok(exceptionCaught); - const existRes = await blobClient.exists({ - versionId: uploadRes.versionId, - }) + const existRes = await blobVersionClient.exists(); assert.ok(existRes); }); it("delete a version", async () => { - await blobClient.delete({ - versionId: uploadRes.versionId, - }) + const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); + await blobVersionClient.delete(); - const versionExists = await blobClient.exists({ - versionId: uploadRes.versionId, - }); + const versionExists = await blobVersionClient.exists(); assert.ok(!versionExists); const rootExists = await blobClient.exists(); @@ -192,7 +177,7 @@ describe("Blob versioning", () => { const credential = getGenericCredential(""); let batchDeleteRequest = new BlobBatch(); for (let i = 0; i < blockBlobCount; i++) { - await batchDeleteRequest.deleteBlob(blockBlobClients[i].url, credential, { versionId: versions[i] }); + await batchDeleteRequest.deleteBlob(blockBlobClients[i].withVersion(versions[i]!).url, credential); } // Submit batch request and verify response. @@ -226,9 +211,7 @@ describe("Blob versioning", () => { await containerClient.deleteBlob(blobName, { versionId: uploadRes.versionId, }); - const versionExists = await blobClient.exists({ - versionId: uploadRes.versionId, - }); + const versionExists = await blobClient.withVersion(uploadRes.versionId!).exists(); assert.ok(!versionExists); let exceptionCaught: boolean = false; @@ -283,15 +266,13 @@ describe("Blob versioning", () => { const rootExists = await blobClient.exists(); assert.ok(!rootExists); - const versionExists = await blobClient.exists({ - versionId: uploadRes.versionId, - }); + const versionExists = await blobClient.withVersion(uploadRes.versionId!).exists(); assert.ok(versionExists); }); it("promote a version: as the copy source", async () => { - const versionBlobClient = blobClient.withVersionId(uploadRes.versionId!); - await versionBlobClient.getProperties(); + const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); + await blobVersionClient.getProperties(); const versionURL = setURLParameter(blobClient.url, "versionid", uploadRes.versionId); const copyRes = await (await blobClient.beginCopyFromURL(versionURL)).pollUntilDone(); @@ -366,10 +347,11 @@ describe("Blob versioning", () => { assert.ok(properties.deleteRetentionPolicy!.enabled, "deleteRetentionPolicy should be enabled."); } - await blobClient.delete({ versionId: uploadRes.versionId }); - assert.ok(!(await blobClient.exists({ versionId: uploadRes.versionId }))); + const blobVersionClient = blobClient.withVersion(uploadRes.versionId!); + await blobVersionClient.delete(); + assert.ok(!(await blobVersionClient.exists())); await blobClient.undelete(); - assert.ok(await blobClient.exists({ versionId: uploadRes.versionId })); + assert.ok(await blobVersionClient.exists()); }); }); diff --git a/sdk/storage/storage-blob/test/node/sas.spec.ts b/sdk/storage/storage-blob/test/node/sas.spec.ts index 13e47635b847..9c004820d151 100644 --- a/sdk/storage/storage-blob/test/node/sas.spec.ts +++ b/sdk/storage/storage-blob/test/node/sas.spec.ts @@ -884,10 +884,10 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { sharedKeyCredential as StorageSharedKeyCredential ); - const sasURL = `${blobClient.withVersionId(uploadRes.versionId!).url}&${blobSAS}`; + const sasURL = `${blobClient.withVersion(uploadRes.versionId!).url}&${blobSAS}`; const blobClientWithSAS = new BlobClient(sasURL, newPipeline(new AnonymousCredential())); - await blobClientWithSAS.delete({ versionId: uploadRes.versionId }); - assert.ok(!(await blobClientWithSAS.exists({ versionId: uploadRes.versionId }))); + await blobClientWithSAS.delete(); + assert.ok(!(await blobClientWithSAS.exists())); await containerClient.delete(); }); @@ -947,10 +947,10 @@ describe("Shared Access Signature (SAS) generation Node.js only", () => { accountName ); - const sasURL = `${blobClient.withVersionId(uploadRes.versionId!).url}&${blobSAS}`; + const sasURL = `${blobClient.withVersion(uploadRes.versionId!).url}&${blobSAS}`; const blobClientWithSAS = new BlobClient(sasURL, newPipeline(new AnonymousCredential())); - await blobClientWithSAS.delete({ versionId: uploadRes.versionId }); - assert.ok(!(await blobClientWithSAS.exists({ versionId: uploadRes.versionId }))); + await blobClientWithSAS.delete(); + assert.ok(!(await blobClientWithSAS.exists())); await containerClient.delete(); });