Skip to content

Refactor: Move ETag computation from adaptor into IcebergCatalogHandler#4238

Open
Wency42601 wants to merge 1 commit intoapache:mainfrom
Wency42601:etag-in-handler
Open

Refactor: Move ETag computation from adaptor into IcebergCatalogHandler#4238
Wency42601 wants to merge 1 commit intoapache:mainfrom
Wency42601:etag-in-handler

Conversation

@Wency42601
Copy link
Copy Markdown

@Wency42601 Wency42601 commented Apr 18, 2026

Summary

Push the ETag computation out of IcebergCatalogAdapter (a JAX-RS
transport layer) and into IcebergCatalogHandler, where the semantics
of "a load-table response's etag" actually live. The adapter now only
copies the handler-provided etag onto the HTTP ETag header.
This also addresses the existing TODO in IcebergCatalogHandler.loadTable
about creating a canonical interface for associating etags with entities.

Changes

  • New ETaggedLoadTableResponse record pairing a LoadTableResponse
    with an Optional<String> etag.
  • IcebergCatalogHandler
    • New private withETag(LoadTableResponse, TableIdentifier) helper
      that centralizes the "metadata location -> etag" rule and the
      previously-adapter-side warning when metadataLocation is null.
    • Adapter-facing overloads now return the wrapper:
      • createTableDirect(ns, req, delegationModes, refreshEndpoint)
      • registerTable(ns, req)
      • loadTable(id, snapshots, IfNoneMatch, delegationModes, refreshEndpoint)
        (returns Optional<ETaggedLoadTableResponse>).
    • Simpler test-facing overloads (loadTable(id, snapshots),
      loadTableIfStale, createTableDirect(ns, req), etc.) keep their
      existing LoadTableResponse-shaped contracts by unwrapping via
      .response() / .map(ETaggedLoadTableResponse::response).
  • IcebergCatalogAdapter
    • Removed tryInsertETagHeader.
    • Added toResponseBuilder(ETaggedLoadTableResponse); only sets
      HttpHeaders.ETAG when the handler supplied one.
    • Updated createTable, loadTable (still 304s on Optional.empty()),
      and registerTable call sites.
    • Removed now-unused imports.

Test plan

  • New unit tests in IcebergCatalogAdapterETagTest covering the
    full adapter -> handler path end-to-end (6 tests, all pass):
    • createTableDirect sets ETag to
      IcebergHttpUtil.generateETagForMetadataFileLocation(metadataLocation).
    • Staged create omits ETag (no metadata location yet).
    • loadTable returns the same ETag as createTable.
    • loadTable with matching If-None-Match -> 304 Not Modified.
    • loadTable with mismatched If-None-Match -> 200 plus current
      ETag.
    • registerTable response carries the expected ETag.
  • Existing suites still green: IcebergCatalogHandlerAuthzTest
    (6005 tests), IcebergCatalogAdapterTest (17), IfNoneMatchTest (16).
  • :polaris-runtime-service:compileJava and compileTestJava
    succeed with no new warnings.

Checklist

  • 🛡️ Don't disclose security issues! (contact security@apache.org)
  • 🔗 Clearly explained why the changes are needed, or linked related issues: Fixes #
  • 🧪 Added/updated tests with good coverage, or manually tested (and explained how)
  • 💡 Added comments for complex logic
  • 🧾 Updated CHANGELOG.md (if needed)
  • 📚 Updated documentation in site/content/in-dev/unreleased (if needed)

@Wency42601 Wency42601 marked this pull request as ready for review April 18, 2026 01:46
@gh-yzou gh-yzou requested a review from flyrain April 18, 2026 01:48
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The Gradle Build Checks indicate there are format violations in this file that can be fixed with ./gradlew spotlessApply

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.

3 participants