Skip to content

HIVE-30150: Implement ETag-based freshness-aware table loading for HMS Iceberg REST Catalog - #6891

Open
Aggarwal-Raghav wants to merge 2 commits into
apache:masterfrom
Aggarwal-Raghav:HIVE-30150
Open

Aggarwal-Raghav wants to merge 2 commits into
apache:masterfrom
Aggarwal-Raghav:HIVE-30150

Conversation

@Aggarwal-Raghav

@Aggarwal-Raghav Aggarwal-Raghav commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Implemented freshness-aware table loading in HMSCatalogAdapter by computing and returning an ETag HTTP response header for table operations (CREATE_TABLE, REGISTER_TABLE, UPDATE_TABLE, LOAD_TABLE). Added RFC 9110–compliant evaluation of incoming If-None-Match headers, returning 304 Not Modified when table metadata is unchanged.

Why are the changes needed?

  • Without ETag support, every table refresh or repeated load transfers, parses, and deserializes the full table metadata payload, creating unnecessary network bandwidth and metastore CPU overhead.
  • Returning 304 Not Modified allows Iceberg REST clients to validate freshness and reuse their cached in-memory metadata without payload re-transmission.

Does this PR introduce any user-facing change?

Yes

  • Clients querying the HMS Iceberg REST Catalog now receive an ETag header on table responses.
  • Clients sending conditional If-None-Match requests will receive 304 Not Modified with an empty body when the metadata has not changed, resulting in faster refresh operations and reduced network usage.

How was this patch tested?

Wrote Junit tests.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doHead(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doHead(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
@Override
protected void doDelete(HttpServletRequest request, HttpServletResponse response)
throws IOException {
execute(ServletRequestContext.from(request), response);
- Prevent servlet stack trace leakage (Sonar S1989 / CWE-209)
- Reduce complexity of HMSCatalogAdapter#execute (Sonar S3776)
- Add RFC 9110 weak ETag comparison (W/) in matchesETag
- Add end-to-end integration test in BaseRESTCatalogTests
- Add stageCreate unit test in TestHMSCatalogAdapterETag
- Remove unused Route field and dead servlet methods
@Aggarwal-Raghav
Aggarwal-Raghav marked this pull request as ready for review October 18, 2026 11:54
@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants