Skip to content

Return user metadata in GetObjectAttributes API#6070

Open
maeldonn wants to merge 5 commits intofeature/CLDSRV-817/get-object-attributesfrom
feature/CLDSRV-844/user-metadata
Open

Return user metadata in GetObjectAttributes API#6070
maeldonn wants to merge 5 commits intofeature/CLDSRV-817/get-object-attributesfrom
feature/CLDSRV-844/user-metadata

Conversation

@maeldonn
Copy link

@maeldonn maeldonn commented Feb 4, 2026

Issue: CLDSRV-817

@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 2e7333e to 2b69771 Compare February 4, 2026 10:04
@codecov
Copy link

codecov bot commented Feb 4, 2026

❌ 4 Tests Failed:

Tests completed Failed Passed Skipped
8221 4 8217 0
View the full list of 4 ❄️ flaky test(s)
"after each" hook for "should put an object and set the acl via query param"::PUT object With v4 signature "after each" hook for "should put an object and set the acl via query param"

Flake rate in main: 100.00% (Passed 0 times, Failed 18 times)

Stack Traces | 0.013s run time
Expected values to be strictly equal:
+ actual - expected

+ '404 NOT FOUND'
- '200 OK'
"after each" hook for "should put an object and set the acl via query param"::PUT object With v4 signature "after each" hook for "should put an object and set the acl via query param"

Flake rate in main: 100.00% (Passed 0 times, Failed 18 times)

Stack Traces | 0.013s run time
done() called multiple times in hook <PUT object With v4 signature "after each" hook for "should put an object and set the acl via query param"> of file .../test/object/put.js
"after each" hook for "should put object with valid object lock retention date and mode when object lock is enabled on the bucket"::PUT object with object lock With default signature "after each" hook for "should put object with valid object lock retention date and mode when object lock is enabled on the bucket"

Flake rate in main: 100.00% (Passed 0 times, Failed 18 times)

Stack Traces | 0.005s run time
The specified bucket does not exist.
"before each" hook for "should put object with valid object lock retention date and mode when object lock is enabled on the bucket"::PUT object with object lock With default signature "before each" hook for "should put object with valid object lock retention date and mode when object lock is enabled on the bucket"

Flake rate in main: 100.00% (Passed 0 times, Failed 18 times)

Stack Traces | 0.006s run time
The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again.

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch 4 times, most recently from 95b17ef to ab4f29a Compare February 4, 2026 14:38
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 64cd8a1 to 4a72a6d Compare February 4, 2026 14:41
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from ab4f29a to fc3441c Compare February 4, 2026 14:41
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 4a72a6d to 92bd9be Compare February 4, 2026 14:47
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch 2 times, most recently from 4b757aa to 78dd47a Compare February 4, 2026 15:50
@maeldonn maeldonn requested review from a team, SylvainSenechal and benzekrimaha February 4, 2026 16:35
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 78dd47a to 1a3d966 Compare February 9, 2026 14:41
@DarkIsDude DarkIsDude removed their request for review February 10, 2026 09:44
headers[headerName]
?.split(',')
.map(attr => attr.trim())
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait so it means even if the attribute is not in supportedAttribute, it will be returned as lower cased ?
Shouldn't this be a filter instead ?

I mean, ok I guess the overall function works because later there is the attributes.some() and has() thing, but could it be clearer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyways, maybe the funciton is good enough as it is, but if you're able to make it a bit clearer it's nice, cause it's doing multiple thing that aren't completely obvious from the function name, it looks like it's gonna do some generic parsing, then ends up doing lowercasing and having a special case for x-amz-meta. Maybe renaming function name and intermediates variables help

Copy link
Author

@maeldonn maeldonn Feb 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's not a supported attribute:

  1. It's user metadata so it's ok
  2. It's something else -> will throw an exception

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems uselessly innefficient: we traverse the list 3 times to do the same thing...

  • trim() can be done in the same iteration, no need to the extra strings/list allocation
  • isn't user metadata already mandated (by spec) to be lower case? do we do the same lower case conversion in other APIs? if not, not need to be more accommodating here
  • if an attribute is in the supportedAttributes, there is no point making another check for the prefix (and rechecking later it is a supported attribute, if there is no prefix)
Suggested change
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
const attributes =
headers[headerName]?.split(',').map(attr => {
const res = attr.trim())
if (!supportedAttributes.has(res) && !res.startsWith('x-amz-meta-')) {
throw errorInstances.InvalidArgument.customizeDescription('Invalid attribute name specified.');
}
return res;
});

Copy link
Contributor

@SylvainSenechal SylvainSenechal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments to address, 2 tests to add

headers[headerName]
?.split(',')
.map(attr => attr.trim())
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems uselessly innefficient: we traverse the list 3 times to do the same thing...

  • trim() can be done in the same iteration, no need to the extra strings/list allocation
  • isn't user metadata already mandated (by spec) to be lower case? do we do the same lower case conversion in other APIs? if not, not need to be more accommodating here
  • if an attribute is in the supportedAttributes, there is no point making another check for the prefix (and rechecking later it is a supported attribute, if there is no prefix)
Suggested change
.map(attr => (supportedAttributes.has(attr) ? attr : attr.toLowerCase())) ?? [];
const attributes =
headers[headerName]?.split(',').map(attr => {
const res = attr.trim())
if (!supportedAttributes.has(res) && !res.startsWith('x-amz-meta-')) {
throw errorInstances.InvalidArgument.customizeDescription('Invalid attribute name specified.');
}
return res;
});

@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 4868753 to c762cd8 Compare February 12, 2026 10:11
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from e040894 to 63d9d12 Compare February 12, 2026 13:59
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from c762cd8 to bef8034 Compare February 12, 2026 15:00
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch 2 times, most recently from 704c58d to 34f10d2 Compare February 12, 2026 17:07
@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch from 3ebd2ab to e118699 Compare February 13, 2026 14:21
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 34f10d2 to 74c8a30 Compare February 13, 2026 14:22
@delthas delthas removed their request for review February 16, 2026 10:08
Copy link
Contributor

@benzekrimaha benzekrimaha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

couple comments but nothing blocking for me , approving

userMetadata.add(attribute);
}

if (optionalAttributes.has('RestoreStatus')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the previous code was done purposely for efficiency to avoid repeatedly iterating through every attribute : not really an improvement here...

esp. ideally we want to reuse the whole logic (i.e. same single pass iteration), not just extractUserMetadata. Especially we don't really care if extra attributes are supported in this "generation" stage, as the "supported" attributes will be validated earlier when receiving the API (some the optionalAttributes should only contain the allowed parameters.

(but this requires following the same pattern as all APIs, and generate XML manually instead of using xml2js.Builder)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted to the listObjectV2 implementation and created an utility function for the two APIs.

@maeldonn maeldonn force-pushed the feature/CLDSRV-817/get-object-attributes branch 3 times, most recently from ddde8bf to fd17bad Compare February 17, 2026 19:04
@maeldonn maeldonn force-pushed the feature/CLDSRV-844/user-metadata branch from 7174c7d to 504d20e Compare February 17, 2026 22:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants