Skip to content

Add API to update segment ZK metadata without uploading - #19180

Open
goutamadwant wants to merge 3 commits into
apache:masterfrom
goutamadwant:update-segment-zk-metadata-api
Open

Add API to update segment ZK metadata without uploading#19180
goutamadwant wants to merge 3 commits into
apache:masterfrom
goutamadwant:update-segment-zk-metadata-api

Conversation

@goutamadwant

Copy link
Copy Markdown
Contributor

Closes #10458

What this PR does

  • Adds a dedicated PUT /segments/{tableNameWithType}/{segmentName}/metadata API for updating the segment ZK metadata custom map.
  • Validates the expected segment CRC through If-Match and uses the ZK record version for compare-and-set protection.
  • Routes unchanged single-segment conversions through the metadata-only API, avoiding segment compression and upload.
  • Falls back to the existing refresh-only upload path when a mixed-version controller does not expose the new endpoint.

Backward compatibility

The endpoint is additive. Existing upload behavior is unchanged for modified segments, and older controllers continue to work through the fallback path.

Tests

  • PinotSegmentRestletResourceTest
  • BaseSingleSegmentConversionExecutorTest
  • Pinot pre-commit checks for pinot-common, pinot-controller, and pinot-minion-builtin-tasks

@codecov-commenter

codecov-commenter commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 58.88889% with 37 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.95%. Comparing base (d3604a5) to head (f09bee0).
⚠️ Report is 37 commits behind head on master.

Files with missing lines Patch % Lines
...ot/plugin/minion/tasks/SegmentConversionUtils.java 0.00% 10 Missing ⚠️
...ler/api/resources/PinotSegmentRestletResource.java 70.00% 6 Missing and 3 partials ⚠️
...ion/tasks/BaseSingleSegmentConversionExecutor.java 60.00% 7 Missing and 1 partial ⚠️
...e/pinot/common/utils/FileUploadDownloadClient.java 0.00% 7 Missing ⚠️
...ta/segment/SegmentZKMetadataCustomMapModifier.java 86.95% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19180      +/-   ##
============================================
+ Coverage     66.62%   66.95%   +0.33%     
- Complexity     1423     1426       +3     
============================================
  Files          3443     3452       +9     
  Lines        218577   218610      +33     
  Branches      34792    34752      -40     
============================================
+ Hits         145624   146374     +750     
+ Misses        61218    60536     -682     
+ Partials      11735    11700      -35     
Flag Coverage Δ
custom-integration1 ?
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 66.95% <58.88%> (+0.33%) ⬆️
lane-a 100.00% <ø> (?)
lane-b 0.00% <ø> (?)
temurin 66.95% <58.88%> (+0.33%) ⬆️
unittests 66.95% <58.88%> (+0.33%) ⬆️
unittests1 57.68% <66.66%> (+0.55%) ⬆️
unittests2 39.06% <56.66%> (+0.12%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Jackie-Jiang Jackie-Jiang added enhancement Improvement to existing functionality ingestion Related to data ingestion pipeline rest-api Related to REST API endpoints labels Aug 7, 2026
@Jackie-Jiang

Copy link
Copy Markdown
Contributor

String.format("Segment CRC does not match for segment: %s in table: %s", segmentName, tableNameWithType),
Status.PRECONDITION_FAILED);
}
segmentZKMetadata.setCustomMap(customMapModifier.modifyMap(segmentZKMetadata.getCustomMap()));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the refreshTime should also be updated, similar to how segment refresh is handled:

// NOTE: Even though we don't need to refresh the segment, we should still update the following fields:
// - Creation time (not included in the crc)
// - Refresh time
// - Custom map

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a metadata-only segment update path to avoid recompressing and uploading unchanged segments.

Changes:

  • Adds a CRC-checked, CAS-protected controller API for updating segment custom metadata.
  • Routes unchanged minion conversions through the new API.
  • Adds mixed-version fallback behavior and tests.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
FileUploadDownloadClient.java Adds metadata-update URI and PUT support.
PinotSegmentRestletResource.java Implements the metadata update endpoint.
PinotSegmentRestletResourceTest.java Tests endpoint success and error cases.
BaseSingleSegmentConversionExecutor.java Skips uploads for unchanged segments.
SegmentConversionUtils.java Adds the minion-side API client.
BaseSingleSegmentConversionExecutorTest.java Tests metadata-only and fallback paths.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +155 to +156
} catch (HttpErrorStatusException e) {
if (e.getStatusCode() != HttpStatus.SC_NOT_FOUND) {
Comment on lines +158 to +160
mocked.when(() -> SegmentConversionUtils.updateSegmentZKMetadata(Mockito.anyString(), Mockito.anyString(),
Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any()))
.thenThrow(new HttpErrorStatusException("metadata API not found", HttpStatus.SC_NOT_FOUND));

@PUT
@Path("segments/{tableNameWithType}/{segmentName}/metadata")
@Authorize(targetType = TargetType.TABLE, paramName = "tableNameWithType", action = Actions.Table.UPLOAD_SEGMENT)
Comment on lines +362 to +366
SegmentZKMetadataCustomMapModifier customMapModifier;
try {
customMapModifier = new SegmentZKMetadataCustomMapModifier(customMapModifierJson);
} catch (Exception e) {
throw new ControllerApplicationException(LOGGER, "Invalid segment ZK metadata custom map modifier",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement to existing functionality ingestion Related to data ingestion pipeline rest-api Related to REST API endpoints

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add API to update ZK metadata of a segment

5 participants