nevzheng opened a new issue, #12722: URL: https://github.com/apache/gravitino/issues/12722
## Summary Iceberg REST table events already expose `customInfo()`, but today that map is only the request HTTP headers (`IcebergEvent.customInfo()` returns `icebergRequestContext.httpHeaders()`). An inner dispatcher that applied a policy, enforced a validation, or made a decision has no way to get that fact into the terminal Iceberg create/update/load event the outer layer publishes. That leaves an audit record that says an operation happened without saying anything a middle layer knew about it. The layer's only options today are to publish a separate event, which breaks the one-operation-one-event shape audit consumers rely on, or to drop the fact. This is the Iceberg REST counterpart of #12691 / #12692, which already landed the same hand-off for Gravitino `TableEventDispatcher`. ## Desired outcome An inner dispatcher layer can attach `Map<String, String>` audit facts to the terminal Iceberg table event the outer dispatcher already emits, so a single audit record carries both what happened and what the chain knew about it. Enrichment should change what an event carries and nothing else. Dispatch semantics, error propagation, and the caller-visible result of the operation should be identical whether or not facts were attached. Facts must appear on `customInfo()` only. They must not leak into `httpHeaders()`. ## Scope and boundaries In scope: Iceberg REST create, update, and load table events (success and failure) and whatever hand-off lets an inner layer supply facts to `IcebergTableEventDispatcher`. Out of scope: whether a listener that throws should fail the caller. Today Iceberg dispatch lets that exception propagate. Whether to isolate listener failures is a question about dispatcher semantics that applies equally to events carrying no custom info. Bundling it here would change existing behavior under cover of an additive feature. Also out of scope: drop/list/rename and other Iceberg operations; Gravitino `TableEventDispatcher` (already covered by #12692); any encryption-, KMS-, or policy-specific keys. ## Evidence - `IcebergEvent.customInfo()` currently returns only HTTP headers. - `BaseEvent` already declares `customInfo()`, and #12692 already lets an inner Gravitino table dispatcher stash facts on `RequestContext` for the outer dispatcher to take. - Iceberg REST has the same layered shape: an inner dispatcher may know a fact, `IcebergTableEventDispatcher` is the layer that emits the event. ## Supporting details A proposed approach, not a decided one: - Give `IcebergRequestContext` an immutable extras map (`auditExtras` / `withAuditExtras`) that is not part of `httpHeaders()`. - Reuse the existing `RequestContext.setAuditExtras` / `takeAuditExtras` hand-off from #12692 so an inner layer can stash facts for the current request. - Have `IcebergTableEventDispatcher` take those facts on create/update/load success and failure, and merge them into `customInfo()` beside headers. The contributing layer and the emitting layer are not in the same call frame, so the hand-off needs a home. `RequestContext` already holds per-request state of this shape after #12692. ## How we will know it worked - Create/update/load success and failure events include stashed extras on `customInfo()` together with headers. - Operations that stash nothing keep today's header-only `customInfo()`. - Extras never appear on `httpHeaders()`. - A listener exception propagates the same way with or without extras. - No fact survives into the next operation on the same thread. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
