From f2e1619766c47dcb2e3d99228c57c74cd748c6a7 Mon Sep 17 00:00:00 2001 From: Frederik Rosenberg <9611091+frederikrosenberg@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:37:16 +0200 Subject: [PATCH] Only include metadata when requested (#2472) * Only include metadata when requested * Add test for listBlobHierarchySegment --------- Co-authored-by: Frederik Rosenberg --- ChangeLog.md | 3 ++- src/blob/handlers/ContainerHandler.ts | 10 ++++++++++ tests/blob/apis/container.test.ts | 26 ++++++++++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index ff49c163a..ef9a6865e 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -7,13 +7,14 @@ Blob: - Fixed an issue where all blob APIs allowed metadata names which were not valid C# identifiers. +- Fixed always including metadata on blob list even when not requested ## 2024.08 Version 3.32.0 General: - Bump mysql2 to resolve to 3.10.1 for security patches -- Fixed an issue where premature client disconnections led to all following requests failing with a 500 error. (issue #1346) +- Fixed an issue where premature client disconnections led to all following requests failing with a 500 error. (issue #1346) - Bump up service API version to 2024-11-04 Blob: diff --git a/src/blob/handlers/ContainerHandler.ts b/src/blob/handlers/ContainerHandler.ts index c8d82d786..e7703d46d 100644 --- a/src/blob/handlers/ContainerHandler.ts +++ b/src/blob/handlers/ContainerHandler.ts @@ -605,6 +605,7 @@ export default class ContainerHandler extends BaseHandler let includeSnapshots: boolean = false; let includeUncommittedBlobs: boolean = false; let includeTags: boolean = false; + let includeMetadata: boolean = false; if (options.include !== undefined) { options.include.forEach(element => { if (Models.ListBlobsIncludeItem.Snapshots.toLowerCase() === element.toLowerCase()) { @@ -616,6 +617,9 @@ export default class ContainerHandler extends BaseHandler if (Models.ListBlobsIncludeItem.Tags.toLowerCase() === element.toLowerCase()) { includeTags = true; } + if (Models.ListBlobsIncludeItem.Metadata.toLowerCase() === element.toLowerCase()) { + includeMetadata = true; + } }) } if ( @@ -657,6 +661,7 @@ export default class ContainerHandler extends BaseHandler deleted: item.deleted !== true ? undefined : true, snapshot: item.snapshot || undefined, blobTags: includeTags ? item.blobTags : undefined, + metadata: includeMetadata ? item.metadata : undefined, properties: { ...item.properties, etag: removeQuotationFromListBlobEtag(item.properties.etag), @@ -705,6 +710,7 @@ export default class ContainerHandler extends BaseHandler let includeSnapshots: boolean = false; let includeUncommittedBlobs: boolean = false; let includeTags: boolean = false; + let includeMetadata: boolean = false; if (options.include !== undefined) { options.include.forEach(element => { if (Models.ListBlobsIncludeItem.Snapshots.toLowerCase() === element.toLowerCase()) { @@ -716,6 +722,9 @@ export default class ContainerHandler extends BaseHandler if (Models.ListBlobsIncludeItem.Tags.toLowerCase() === element.toLowerCase()) { includeTags = true; } + if (Models.ListBlobsIncludeItem.Metadata.toLowerCase() === element.toLowerCase()) { + includeMetadata = true; + } } ) } @@ -760,6 +769,7 @@ export default class ContainerHandler extends BaseHandler ...item, snapshot: item.snapshot || undefined, blobTags: includeTags ? item.blobTags : undefined, + metadata: includeMetadata ? item.metadata : undefined, properties: { ...item.properties, etag: removeQuotationFromListBlobEtag(item.properties.etag), diff --git a/tests/blob/apis/container.test.ts b/tests/blob/apis/container.test.ts index 3a51cb75c..75db520c3 100644 --- a/tests/blob/apis/container.test.ts +++ b/tests/blob/apis/container.test.ts @@ -267,12 +267,18 @@ describe("ContainerAPIs", () => { it("listBlobHierarchySegment with default parameters @loki @sql", async () => { const blobClients = []; + const metadata = { + keya: "a", + keyb: "c" + }; for (let i = 0; i < 3; i++) { const blobClient = containerClient.getBlobClient( getUniqueName(`blockblob${i}/${i}`) ); const blockBlobClient = blobClient.getBlockBlobClient(); - await blockBlobClient.upload("", 0); + await blockBlobClient.upload("", 0, { + metadata + }); blobClients.push(blobClient); } @@ -298,6 +304,15 @@ describe("ContainerAPIs", () => { assert.ok(blob.url.indexOf(result.segment.blobPrefixes![i++].name)); } + for (const prefix of result.segment.blobPrefixes) { + const prefixResult = ( + await containerClient.listBlobsByHierarchy(delimiter, { prefix: prefix.name }).byPage().next() + ).value; + + assert.deepStrictEqual(prefixResult.segment.blobItems!.length, 1); + assert.deepStrictEqual(prefixResult.segment.blobItems![0].metadata, undefined); + } + for (const blob of blobClients) { await blob.delete(); } @@ -548,12 +563,18 @@ describe("ContainerAPIs", () => { it("should correctly list all blobs in the container using listBlobFlatSegment with default parameters @loki @sql", async () => { const blobClients = []; + const metadata = { + keya: "a", + keyb: "c" + }; for (let i = 0; i < 3; i++) { const blobClient = containerClient.getBlobClient( getUniqueName(`blockblob${i}/${i}`) ); const blockBlobClient = blobClient.getBlockBlobClient(); - await blockBlobClient.upload("", 0); + await blockBlobClient.upload("", 0, { + metadata + }); blobClients.push(blobClient); } @@ -581,6 +602,7 @@ describe("ContainerAPIs", () => { '"' + result.segment.blobItems![i].properties.etag + '"' ); assert.deepStrictEqual(result.segment.blobItems![i].snapshot, undefined); + assert.deepStrictEqual(result.segment.blobItems![i].metadata, undefined); i++; }