This is an automated email from the ASF dual-hosted git repository.

honahx pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new baf01a546 [Issue 3209] Surface Intermediate Data as part of Polaris 
Events (#3456)
baf01a546 is described below

commit baf01a54696b28095a197cbde156d386913cfd3e
Author: Adnan Hemani <[email protected]>
AuthorDate: Thu Jan 29 08:27:57 2026 -0800

    [Issue 3209] Surface Intermediate Data as part of Polaris Events (#3456)
    
    Adds a RequestScoped annotation to AttributeMap, which allows us to inject 
this bean into intermediary business logic and be able to patch data from there 
back out to the PolarisEvent.
    
    @dimas-b had a great idea that we may be able to retire the Delegator model 
eventually by setting a "closing" hook on the RequestScoped bean - but for 
simplicity, I am introducing this smaller change that will solve the GH issue 
linked first and will investigate that approach later.
---
 .../PolarisCatalogsEventServiceDelegator.java      |  59 +++++-----
 ...PolarisPrincipalRolesEventServiceDelegator.java |  38 +++----
 .../PolarisPrincipalsEventServiceDelegator.java    |  42 +++----
 .../CatalogGenericTableEventServiceDelegator.java  |  18 +--
 .../service/catalog/iceberg/IcebergCatalog.java    |  10 +-
 .../catalog/iceberg/IcebergCatalogAdapter.java     |   9 +-
 .../catalog/iceberg/IcebergCatalogHandler.java     |  12 +-
 .../IcebergRestCatalogEventServiceDelegator.java   | 126 ++++++++++++---------
 ...bergRestConfigurationEventServiceDelegator.java |   6 +-
 .../policy/CatalogPolicyEventServiceDelegator.java |  34 +++---
 .../{AttributeMap.java => EventAttributeMap.java}  |  10 +-
 .../polaris/service/events/EventAttributes.java    |   7 ++
 .../polaris/service/events/PolarisEvent.java       |   6 +-
 .../service/ratelimiter/RateLimiterFilter.java     |   4 +-
 .../polaris/service/task/TaskExecutorImpl.java     |   6 +-
 .../service/admin/PolarisAuthzTestBase.java        |   2 +
 .../AbstractIcebergCatalogHandlerAuthzTest.java    |  12 +-
 .../iceberg/CommitTransactionEventTest.java        |  28 +++++
 ...ebergCatalogHandlerFineGrainedDisabledTest.java |   3 +-
 .../polaris/service/events/AttributeMapTest.java   |  24 ++--
 .../polaris/service/events/PolarisEventTest.java   |   2 +-
 .../cloudwatch/AwsCloudWatchEventListenerTest.java |   6 +-
 .../org/apache/polaris/service/TestServices.java   |   8 +-
 23 files changed, 276 insertions(+), 196 deletions(-)

diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisCatalogsEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisCatalogsEventServiceDelegator.java
index cc0e59fd4..c316a3d53 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisCatalogsEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisCatalogsEventServiceDelegator.java
@@ -42,7 +42,7 @@ import org.apache.polaris.core.admin.model.ViewGrant;
 import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.core.entity.PolarisPrivilege;
 import org.apache.polaris.service.admin.api.PolarisCatalogsApiService;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -64,13 +64,14 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG_NAME, 
request.getCatalog().getName())));
+            new EventAttributeMap()
+                .put(EventAttributes.CATALOG_NAME, 
request.getCatalog().getName())));
     Response resp = delegate.createCatalog(request, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG, (Catalog) 
resp.getEntity())));
+            new EventAttributeMap().put(EventAttributes.CATALOG, (Catalog) 
resp.getEntity())));
     return resp;
   }
 
@@ -81,13 +82,13 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_DELETE_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
+            new EventAttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
     Response resp = delegate.deleteCatalog(catalogName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_DELETE_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
+            new EventAttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
     return resp;
   }
 
@@ -98,13 +99,13 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_GET_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
+            new EventAttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
     Response resp = delegate.getCatalog(catalogName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_GET_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG, (Catalog) 
resp.getEntity())));
+            new EventAttributeMap().put(EventAttributes.CATALOG, (Catalog) 
resp.getEntity())));
     return resp;
   }
 
@@ -118,7 +119,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.UPDATE_CATALOG_REQUEST, updateRequest)));
     Response resp =
@@ -127,7 +128,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_CATALOG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG, (Catalog) 
resp.getEntity())));
+            new EventAttributeMap().put(EventAttributes.CATALOG, (Catalog) 
resp.getEntity())));
     return resp;
   }
 
@@ -137,13 +138,13 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_CATALOGS,
             eventMetadataFactory.create(),
-            new AttributeMap()));
+            new EventAttributeMap()));
     Response resp = delegate.listCatalogs(realmContext, securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_CATALOGS,
             eventMetadataFactory.create(),
-            new AttributeMap()));
+            new EventAttributeMap()));
     return resp;
   }
 
@@ -157,7 +158,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, 
request.getCatalogRole().getName())));
     Response resp = delegate.createCatalogRole(catalogName, request, 
realmContext, securityContext);
@@ -165,7 +166,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE, (CatalogRole) 
resp.getEntity())));
     return resp;
@@ -181,7 +182,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_DELETE_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     Response resp =
@@ -190,7 +191,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_DELETE_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     return resp;
@@ -206,7 +207,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_GET_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     Response resp =
@@ -215,7 +216,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_GET_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE, (CatalogRole) 
resp.getEntity())));
     return resp;
@@ -232,7 +233,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)
                 .put(EventAttributes.UPDATE_CATALOG_ROLE_REQUEST, 
updateRequest)));
@@ -243,7 +244,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE, (CatalogRole) 
resp.getEntity())));
     return resp;
@@ -256,13 +257,13 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_CATALOG_ROLES,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
+            new EventAttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
     Response resp = delegate.listCatalogRoles(catalogName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_CATALOG_ROLES,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
+            new EventAttributeMap().put(EventAttributes.CATALOG_NAME, 
catalogName)));
     return resp;
   }
 
@@ -277,7 +278,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_ADD_GRANT_TO_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)
                 .put(EventAttributes.ADD_GRANT_REQUEST, grantRequest)));
@@ -289,7 +290,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_ADD_GRANT_TO_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)
                 .put(EventAttributes.PRIVILEGE, 
getPrivilegeFromGrantResource(grantResource))
@@ -309,7 +310,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_REVOKE_GRANT_FROM_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)
                 .put(EventAttributes.REVOKE_GRANT_REQUEST, grantRequest)
@@ -322,7 +323,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_REVOKE_GRANT_FROM_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)
                 .put(EventAttributes.PRIVILEGE, 
getPrivilegeFromGrantResource(grantResource))
@@ -341,7 +342,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             
PolarisEventType.BEFORE_LIST_ASSIGNEE_PRINCIPAL_ROLES_FOR_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     Response resp =
@@ -351,7 +352,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             
PolarisEventType.AFTER_LIST_ASSIGNEE_PRINCIPAL_ROLES_FOR_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     return resp;
@@ -367,7 +368,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_GRANTS_FOR_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     Response resp =
@@ -377,7 +378,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_GRANTS_FOR_CATALOG_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
     return resp;
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
index 4d579b5f7..b26c52913 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
@@ -31,7 +31,7 @@ import org.apache.polaris.core.admin.model.PrincipalRole;
 import org.apache.polaris.core.admin.model.UpdatePrincipalRoleRequest;
 import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.admin.api.PolarisPrincipalRolesApiService;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -55,13 +55,13 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new 
AttributeMap().put(EventAttributes.CREATE_PRINCIPAL_ROLE_REQUEST, request)));
+            new 
EventAttributeMap().put(EventAttributes.CREATE_PRINCIPAL_ROLE_REQUEST, 
request)));
     Response resp = delegate.createPrincipalRole(request, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE, (PrincipalRole) 
resp.getEntity())));
     return resp;
   }
@@ -73,13 +73,13 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_DELETE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
     Response resp = delegate.deletePrincipalRole(principalRoleName, 
realmContext, securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_DELETE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
     return resp;
   }
 
@@ -90,13 +90,13 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_GET_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
     Response resp = delegate.getPrincipalRole(principalRoleName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_GET_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE, (PrincipalRole) 
resp.getEntity())));
     return resp;
   }
@@ -111,7 +111,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.UPDATE_PRINCIPAL_ROLE_REQUEST, 
updateRequest)));
     Response resp =
@@ -121,7 +121,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE, (PrincipalRole) 
resp.getEntity())));
     return resp;
   }
@@ -132,13 +132,13 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_PRINCIPAL_ROLES,
             eventMetadataFactory.create(),
-            new AttributeMap()));
+            new EventAttributeMap()));
     Response resp = delegate.listPrincipalRoles(realmContext, securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_PRINCIPAL_ROLES,
             eventMetadataFactory.create(),
-            new AttributeMap()));
+            new EventAttributeMap()));
     return resp;
   }
 
@@ -153,7 +153,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_ASSIGN_CATALOG_ROLE_TO_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, 
request.getCatalogRole().getName())));
@@ -164,7 +164,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.AFTER_ASSIGN_CATALOG_ROLE_TO_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, 
request.getCatalogRole().getName())));
@@ -182,7 +182,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_REVOKE_CATALOG_ROLE_FROM_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
@@ -193,7 +193,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.AFTER_REVOKE_CATALOG_ROLE_FROM_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CATALOG_ROLE_NAME, catalogRoleName)));
@@ -207,7 +207,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             
PolarisEventType.BEFORE_LIST_ASSIGNEE_PRINCIPALS_FOR_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
     Response resp =
         delegate.listAssigneePrincipalsForPrincipalRole(
             principalRoleName, realmContext, securityContext);
@@ -215,7 +215,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_ASSIGNEE_PRINCIPALS_FOR_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_ROLE_NAME, 
principalRoleName)));
     return resp;
   }
 
@@ -229,7 +229,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_CATALOG_ROLES_FOR_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.CATALOG_NAME, catalogName)));
     Response resp =
@@ -239,7 +239,7 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_CATALOG_ROLES_FOR_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)
                 .put(EventAttributes.CATALOG_NAME, catalogName)));
     return resp;
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
index 2b5e3decb..fe156d758 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
@@ -33,7 +33,7 @@ import 
org.apache.polaris.core.admin.model.ResetPrincipalRequest;
 import org.apache.polaris.core.admin.model.UpdatePrincipalRequest;
 import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.admin.api.PolarisPrincipalsApiService;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -55,14 +55,14 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_NAME, 
request.getPrincipal().getName())));
     Response resp = delegate.createPrincipal(request, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(
                     EventAttributes.PRINCIPAL,
                     ((PrincipalWithCredentials) 
resp.getEntity()).getPrincipal())));
@@ -79,7 +79,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_RESET_CREDENTIALS,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     Response resp =
         delegate.resetCredentials(
             principalName, resetPrincipalRequest, realmContext, 
securityContext);
@@ -87,7 +87,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.AFTER_RESET_CREDENTIALS,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(
                     EventAttributes.PRINCIPAL,
                     ((PrincipalWithCredentials) 
resp.getEntity()).getPrincipal())));
@@ -101,13 +101,13 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_DELETE_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     Response resp = delegate.deletePrincipal(principalName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_DELETE_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     return resp;
   }
 
@@ -118,13 +118,13 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_GET_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     Response resp = delegate.getPrincipal(principalName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_GET_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL, (Principal) 
resp.getEntity())));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL, (Principal) 
resp.getEntity())));
     return resp;
   }
 
@@ -138,7 +138,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_NAME, principalName)
                 .put(EventAttributes.UPDATE_PRINCIPAL_REQUEST, 
updateRequest)));
     Response resp =
@@ -147,7 +147,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_PRINCIPAL,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL, (Principal) 
resp.getEntity())));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL, (Principal) 
resp.getEntity())));
     return resp;
   }
 
@@ -158,14 +158,14 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_ROTATE_CREDENTIALS,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     Response resp = delegate.rotateCredentials(principalName, realmContext, 
securityContext);
     PrincipalWithCredentials principalWithCredentials = 
(PrincipalWithCredentials) resp.getEntity();
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_ROTATE_CREDENTIALS,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL, 
principalWithCredentials.getPrincipal())));
     return resp;
   }
@@ -176,13 +176,13 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_PRINCIPALS,
             eventMetadataFactory.create(),
-            new AttributeMap()));
+            new EventAttributeMap()));
     Response resp = delegate.listPrincipals(realmContext, securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_PRINCIPALS,
             eventMetadataFactory.create(),
-            new AttributeMap()));
+            new EventAttributeMap()));
     return resp;
   }
 
@@ -196,7 +196,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_ASSIGN_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_NAME, principalName)
                 .put(EventAttributes.PRINCIPAL_ROLE, 
request.getPrincipalRole())));
     Response resp =
@@ -205,7 +205,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.AFTER_ASSIGN_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_NAME, principalName)
                 .put(EventAttributes.PRINCIPAL_ROLE, 
request.getPrincipalRole())));
     return resp;
@@ -221,7 +221,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_REVOKE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_NAME, principalName)
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)));
     Response resp =
@@ -231,7 +231,7 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.AFTER_REVOKE_PRINCIPAL_ROLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.PRINCIPAL_NAME, principalName)
                 .put(EventAttributes.PRINCIPAL_ROLE_NAME, principalRoleName)));
     return resp;
@@ -244,14 +244,14 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_ASSIGNED_PRINCIPAL_ROLES,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     Response resp =
         delegate.listPrincipalRolesAssigned(principalName, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_ASSIGNED_PRINCIPAL_ROLES,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
+            new EventAttributeMap().put(EventAttributes.PRINCIPAL_NAME, 
principalName)));
     return resp;
   }
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/CatalogGenericTableEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/CatalogGenericTableEventServiceDelegator.java
index fd0680a7a..b9ba5a36d 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/CatalogGenericTableEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/generic/CatalogGenericTableEventServiceDelegator.java
@@ -29,7 +29,7 @@ import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.catalog.CatalogPrefixParser;
 import 
org.apache.polaris.service.catalog.api.PolarisCatalogGenericTableApiService;
 import org.apache.polaris.service.catalog.common.CatalogAdapter;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -60,7 +60,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_GENERIC_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.CREATE_GENERIC_TABLE_REQUEST, 
createGenericTableRequest)));
@@ -71,7 +71,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_GENERIC_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(
@@ -92,7 +92,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_DROP_GENERIC_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.GENERIC_TABLE_NAME, genericTable)));
@@ -102,7 +102,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_DROP_GENERIC_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.GENERIC_TABLE_NAME, genericTable)));
@@ -122,7 +122,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_GENERIC_TABLES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)));
     Response resp =
@@ -132,7 +132,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_GENERIC_TABLES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)));
     return resp;
@@ -150,7 +150,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LOAD_GENERIC_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.GENERIC_TABLE_NAME, genericTable)));
@@ -160,7 +160,7 @@ public class CatalogGenericTableEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LOAD_GENERIC_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
index 8de9687a8..46020d103 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java
@@ -132,7 +132,7 @@ import org.apache.polaris.service.catalog.io.FileIOFactory;
 import org.apache.polaris.service.catalog.io.FileIOUtil;
 import org.apache.polaris.service.catalog.io.StorageAccessConfigProvider;
 import 
org.apache.polaris.service.catalog.validation.IcebergPropertiesValidation;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -1407,7 +1407,7 @@ public class IcebergCatalog extends 
BaseMetastoreViewCatalog
             new PolarisEvent(
                 PolarisEventType.BEFORE_REFRESH_TABLE,
                 eventMetadataFactory.create(),
-                new AttributeMap()
+                new EventAttributeMap()
                     .put(EventAttributes.CATALOG_NAME, catalogName)
                     .put(EventAttributes.TABLE_IDENTIFIER, tableIdentifier)));
         refreshFromMetadataLocation(
@@ -1433,7 +1433,7 @@ public class IcebergCatalog extends 
BaseMetastoreViewCatalog
             new PolarisEvent(
                 PolarisEventType.AFTER_REFRESH_TABLE,
                 eventMetadataFactory.create(),
-                new AttributeMap()
+                new EventAttributeMap()
                     .put(EventAttributes.CATALOG_NAME, catalogName)
                     .put(EventAttributes.TABLE_IDENTIFIER, tableIdentifier)));
       }
@@ -1817,7 +1817,7 @@ public class IcebergCatalog extends 
BaseMetastoreViewCatalog
             new PolarisEvent(
                 PolarisEventType.BEFORE_REFRESH_VIEW,
                 eventMetadataFactory.create(),
-                new AttributeMap()
+                new EventAttributeMap()
                     .put(EventAttributes.CATALOG_NAME, catalogName)
                     .put(EventAttributes.VIEW_IDENTIFIER, identifier)));
         refreshFromMetadataLocation(
@@ -1845,7 +1845,7 @@ public class IcebergCatalog extends 
BaseMetastoreViewCatalog
             new PolarisEvent(
                 PolarisEventType.AFTER_REFRESH_VIEW,
                 eventMetadataFactory.create(),
-                new AttributeMap()
+                new EventAttributeMap()
                     .put(EventAttributes.CATALOG_NAME, catalogName)
                     .put(EventAttributes.VIEW_IDENTIFIER, identifier)));
       }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
index fb54b5572..59629a826 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java
@@ -71,6 +71,7 @@ import 
org.apache.polaris.service.catalog.common.CatalogAdapter;
 import org.apache.polaris.service.catalog.io.StorageAccessConfigProvider;
 import org.apache.polaris.service.config.ReservedProperties;
 import org.apache.polaris.service.context.catalog.CallContextCatalogFactory;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.http.IcebergHttpUtil;
 import org.apache.polaris.service.http.IfNoneMatch;
 import org.apache.polaris.service.reporting.PolarisMetricsReporter;
@@ -107,6 +108,7 @@ public class IcebergCatalogAdapter
   private final StorageAccessConfigProvider storageAccessConfigProvider;
   private final PolarisMetricsReporter metricsReporter;
   private final Clock clock;
+  private final EventAttributeMap eventAttributeMap;
 
   @Inject
   public IcebergCatalogAdapter(
@@ -125,7 +127,8 @@ public class IcebergCatalogAdapter
       @Any Instance<ExternalCatalogFactory> externalCatalogFactories,
       StorageAccessConfigProvider storageAccessConfigProvider,
       PolarisMetricsReporter metricsReporter,
-      Clock clock) {
+      Clock clock,
+      EventAttributeMap eventAttributeMap) {
     this.diagnostics = diagnostics;
     this.realmContext = realmContext;
     this.callContext = callContext;
@@ -143,6 +146,7 @@ public class IcebergCatalogAdapter
     this.storageAccessConfigProvider = storageAccessConfigProvider;
     this.metricsReporter = metricsReporter;
     this.clock = clock;
+    this.eventAttributeMap = eventAttributeMap;
   }
 
   /**
@@ -191,7 +195,8 @@ public class IcebergCatalogAdapter
         reservedProperties,
         catalogHandlerUtils,
         externalCatalogFactories,
-        storageAccessConfigProvider);
+        storageAccessConfigProvider,
+        eventAttributeMap);
   }
 
   @Override
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
index c5276ef6b..a5cc72f26 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java
@@ -121,6 +121,8 @@ import 
org.apache.polaris.service.catalog.common.CatalogUtils;
 import org.apache.polaris.service.catalog.io.StorageAccessConfigProvider;
 import org.apache.polaris.service.config.ReservedProperties;
 import org.apache.polaris.service.context.catalog.CallContextCatalogFactory;
+import org.apache.polaris.service.events.EventAttributeMap;
+import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.http.IcebergHttpUtil;
 import org.apache.polaris.service.http.IfNoneMatch;
 import org.apache.polaris.service.types.NotificationRequest;
@@ -183,6 +185,7 @@ public class IcebergCatalogHandler extends CatalogHandler 
implements AutoCloseab
   private final ReservedProperties reservedProperties;
   private final CatalogHandlerUtils catalogHandlerUtils;
   private final StorageAccessConfigProvider storageAccessConfigProvider;
+  private final EventAttributeMap eventAttributeMap;
 
   // Catalog instance will be initialized after authorizing resolver 
successfully resolves
   // the catalog entity.
@@ -208,7 +211,8 @@ public class IcebergCatalogHandler extends CatalogHandler 
implements AutoCloseab
       ReservedProperties reservedProperties,
       CatalogHandlerUtils catalogHandlerUtils,
       Instance<ExternalCatalogFactory> externalCatalogFactories,
-      StorageAccessConfigProvider storageAccessConfigProvider) {
+      StorageAccessConfigProvider storageAccessConfigProvider,
+      EventAttributeMap eventAttributeMap) {
     super(
         diagnostics,
         callContext,
@@ -225,6 +229,7 @@ public class IcebergCatalogHandler extends CatalogHandler 
implements AutoCloseab
     this.reservedProperties = reservedProperties;
     this.catalogHandlerUtils = catalogHandlerUtils;
     this.storageAccessConfigProvider = storageAccessConfigProvider;
+    this.eventAttributeMap = eventAttributeMap;
   }
 
   private CatalogEntity getResolvedCatalogEntity() {
@@ -1042,6 +1047,7 @@ public class IcebergCatalogHandler extends CatalogHandler 
implements AutoCloseab
         new TransactionWorkspaceMetaStoreManager(diagnostics, 
metaStoreManager);
     ((IcebergCatalog) 
baseCatalog).setMetaStoreManager(transactionMetaStoreManager);
 
+    List<TableMetadata> tableMetadataObjs = new ArrayList<>();
     commitTransactionRequest.tableChanges().stream()
         .forEach(
             change -> {
@@ -1092,6 +1098,8 @@ public class IcebergCatalogHandler extends CatalogHandler 
implements AutoCloseab
               if (!updatedMetadata.changes().isEmpty()) {
                 tableOps.commit(currentMetadata, updatedMetadata);
               }
+
+              tableMetadataObjs.add(updatedMetadata);
             });
 
     // Commit the collected updates in a single atomic operation
@@ -1105,6 +1113,8 @@ public class IcebergCatalogHandler extends CatalogHandler 
implements AutoCloseab
           "Transaction commit failed with status: %s, extraInfo: %s",
           result.getReturnStatus(), result.getExtraInformation());
     }
+
+    eventAttributeMap.put(EventAttributes.TABLE_METADATAS, tableMetadataObjs);
   }
 
   public ListTablesResponse listViews(Namespace namespace, String pageToken, 
Integer pageSize) {
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestCatalogEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestCatalogEventServiceDelegator.java
index 3a8a35e9e..00d0f6e08 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestCatalogEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestCatalogEventServiceDelegator.java
@@ -26,6 +26,8 @@ import jakarta.decorator.Delegate;
 import jakarta.inject.Inject;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
+import java.util.List;
+import org.apache.iceberg.TableMetadata;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.rest.requests.CommitTransactionRequest;
 import org.apache.iceberg.rest.requests.CreateNamespaceRequest;
@@ -45,7 +47,7 @@ import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.catalog.CatalogPrefixParser;
 import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService;
 import org.apache.polaris.service.catalog.common.CatalogAdapter;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -64,6 +66,7 @@ public class IcebergRestCatalogEventServiceDelegator
   @Inject PolarisEventListener polarisEventListener;
   @Inject PolarisEventMetadataFactory eventMetadataFactory;
   @Inject CatalogPrefixParser prefixParser;
+  @Inject EventAttributeMap eventAttributeMap;
 
   // Constructor for testing - allows manual dependency injection
   @VisibleForTesting
@@ -71,11 +74,13 @@ public class IcebergRestCatalogEventServiceDelegator
       IcebergCatalogAdapter delegate,
       PolarisEventListener polarisEventListener,
       PolarisEventMetadataFactory eventMetadataFactory,
-      CatalogPrefixParser prefixParser) {
+      CatalogPrefixParser prefixParser,
+      EventAttributeMap eventAttributeMap) {
     this.delegate = delegate;
     this.polarisEventListener = polarisEventListener;
     this.eventMetadataFactory = eventMetadataFactory;
     this.prefixParser = prefixParser;
+    this.eventAttributeMap = eventAttributeMap;
   }
 
   // Default constructor for CDI
@@ -92,7 +97,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_NAMESPACE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.CREATE_NAMESPACE_REQUEST, 
createNamespaceRequest)));
     Response resp =
@@ -102,7 +107,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_NAMESPACE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, 
createNamespaceResponse.namespace())
                 .put(EventAttributes.NAMESPACE_PROPERTIES, 
createNamespaceResponse.properties())));
@@ -122,7 +127,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_NAMESPACES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.PARENT_NAMESPACE_FQN, parent)));
     Response resp =
@@ -131,7 +136,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_NAMESPACES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.PARENT_NAMESPACE_FQN, parent)));
     return resp;
@@ -145,7 +150,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LOAD_NAMESPACE_METADATA,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, decodeNamespace(namespace))));
     Response resp =
@@ -155,7 +160,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LOAD_NAMESPACE_METADATA,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, 
getNamespaceResponse.namespace())
                 .put(EventAttributes.NAMESPACE_PROPERTIES, 
getNamespaceResponse.properties())));
@@ -171,7 +176,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CHECK_EXISTS_NAMESPACE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)));
     Response resp = delegate.namespaceExists(prefix, namespace, realmContext, 
securityContext);
@@ -179,7 +184,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CHECK_EXISTS_NAMESPACE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)));
     return resp;
@@ -193,7 +198,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_DROP_NAMESPACE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, decodeNamespace(namespace))));
     Response resp = delegate.dropNamespace(prefix, namespace, realmContext, 
securityContext);
@@ -201,7 +206,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_DROP_NAMESPACE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_FQN, namespace)));
     return resp;
@@ -220,7 +225,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_NAMESPACE_PROPERTIES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(
@@ -233,7 +238,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_NAMESPACE_PROPERTIES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(
@@ -256,7 +261,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.CREATE_TABLE_REQUEST, createTableRequest)
@@ -274,7 +279,7 @@ public class IcebergRestCatalogEventServiceDelegator
           new PolarisEvent(
               PolarisEventType.AFTER_CREATE_TABLE,
               eventMetadataFactory.create(),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.CATALOG_NAME, catalogName)
                   .put(EventAttributes.NAMESPACE, namespaceObj)
                   .put(EventAttributes.TABLE_NAME, createTableRequest.name())
@@ -297,7 +302,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_TABLES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)));
     Response resp =
@@ -306,7 +311,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_TABLES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)));
     return resp;
@@ -328,7 +333,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LOAD_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
@@ -345,11 +350,12 @@ public class IcebergRestCatalogEventServiceDelegator
             snapshots,
             realmContext,
             securityContext);
+
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_LOAD_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
@@ -370,7 +376,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CHECK_EXISTS_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)));
@@ -379,7 +385,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CHECK_EXISTS_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)));
@@ -400,7 +406,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_DROP_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
@@ -411,7 +417,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_DROP_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
@@ -432,7 +438,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_REGISTER_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.REGISTER_TABLE_REQUEST, 
registerTableRequest)));
@@ -443,7 +449,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_REGISTER_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, registerTableRequest.name())
@@ -462,7 +468,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_RENAME_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.RENAME_TABLE_REQUEST, 
renameTableRequest)));
     Response resp = delegate.renameTable(prefix, renameTableRequest, 
realmContext, securityContext);
@@ -470,7 +476,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_RENAME_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.RENAME_TABLE_REQUEST, 
renameTableRequest)));
     return resp;
@@ -490,7 +496,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
@@ -502,12 +508,14 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_TABLE,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
                 .put(EventAttributes.UPDATE_TABLE_REQUEST, commitTableRequest)
-                .put(EventAttributes.LOAD_TABLE_RESPONSE, (LoadTableResponse) 
resp.getEntity())));
+                .put(
+                    EventAttributes.TABLE_METADATA,
+                    ((LoadTableResponse) resp.getEntity()).tableMetadata())));
     return resp;
   }
 
@@ -524,7 +532,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.CREATE_VIEW_REQUEST, createViewRequest)));
@@ -534,7 +542,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, createViewRequest.name())
@@ -556,7 +564,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_VIEWS,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)));
     Response resp =
@@ -565,7 +573,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_VIEWS,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)));
     return resp;
@@ -584,7 +592,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LOAD_CREDENTIALS,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)));
@@ -594,7 +602,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LOAD_CREDENTIALS,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)));
@@ -614,7 +622,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LOAD_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)));
@@ -623,7 +631,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LOAD_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)
@@ -644,7 +652,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CHECK_EXISTS_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)));
@@ -653,7 +661,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CHECK_EXISTS_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)));
@@ -673,7 +681,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_DROP_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)));
@@ -682,7 +690,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_DROP_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)));
@@ -700,7 +708,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_RENAME_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.RENAME_TABLE_REQUEST, 
renameTableRequest)));
     Response resp = delegate.renameView(prefix, renameTableRequest, 
realmContext, securityContext);
@@ -708,7 +716,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_RENAME_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.RENAME_TABLE_REQUEST, 
renameTableRequest)));
     return resp;
@@ -728,7 +736,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_REPLACE_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)
@@ -740,7 +748,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_REPLACE_VIEW,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.VIEW_NAME, view)
@@ -760,7 +768,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_COMMIT_TRANSACTION,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.COMMIT_TRANSACTION_REQUEST, 
commitTransactionRequest)));
     for (UpdateTableRequest req : commitTransactionRequest.tableChanges()) {
@@ -768,7 +776,7 @@ public class IcebergRestCatalogEventServiceDelegator
           new PolarisEvent(
               PolarisEventType.BEFORE_UPDATE_TABLE,
               eventMetadataFactory.create(),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.CATALOG_NAME, catalogName)
                   .put(EventAttributes.NAMESPACE, req.identifier().namespace())
                   .put(EventAttributes.TABLE_NAME, req.identifier().name())
@@ -780,19 +788,27 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_COMMIT_TRANSACTION,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.COMMIT_TRANSACTION_REQUEST, 
commitTransactionRequest)));
-    for (UpdateTableRequest req : commitTransactionRequest.tableChanges()) {
+    List<TableMetadata> tableMetadataList =
+        eventAttributeMap.getRequired(EventAttributes.TABLE_METADATAS);
+    for (int i = 0; i < commitTransactionRequest.tableChanges().size(); i++) {
+      UpdateTableRequest req = commitTransactionRequest.tableChanges().get(i);
+      TableMetadata tableMetadata =
+          tableMetadataList != null && i < tableMetadataList.size()
+              ? tableMetadataList.get(i)
+              : null;
       polarisEventListener.onEvent(
           new PolarisEvent(
               PolarisEventType.AFTER_UPDATE_TABLE,
               eventMetadataFactory.create(),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.CATALOG_NAME, catalogName)
                   .put(EventAttributes.NAMESPACE, req.identifier().namespace())
                   .put(EventAttributes.TABLE_NAME, req.identifier().name())
-                  .put(EventAttributes.UPDATE_TABLE_REQUEST, req)));
+                  .put(EventAttributes.UPDATE_TABLE_REQUEST, req)
+                  .put(EventAttributes.TABLE_METADATA, tableMetadata)));
     }
     return resp;
   }
@@ -823,7 +839,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_SEND_NOTIFICATION,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)
@@ -835,7 +851,7 @@ public class IcebergRestCatalogEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_SEND_NOTIFICATION,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE, namespaceObj)
                 .put(EventAttributes.TABLE_NAME, table)));
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestConfigurationEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestConfigurationEventServiceDelegator.java
index 697d7d80f..06c238265 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestConfigurationEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergRestConfigurationEventServiceDelegator.java
@@ -29,7 +29,7 @@ import jakarta.ws.rs.core.SecurityContext;
 import org.apache.iceberg.rest.responses.ConfigResponse;
 import org.apache.polaris.core.context.RealmContext;
 import 
org.apache.polaris.service.catalog.api.IcebergRestConfigurationApiService;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -64,13 +64,13 @@ public class IcebergRestConfigurationEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_GET_CONFIG,
             eventMetadataFactory.create(),
-            new AttributeMap().put(EventAttributes.WAREHOUSE, warehouse)));
+            new EventAttributeMap().put(EventAttributes.WAREHOUSE, 
warehouse)));
     Response resp = delegate.getConfig(warehouse, realmContext, 
securityContext);
     polarisEventListener.onEvent(
         new PolarisEvent(
             PolarisEventType.AFTER_GET_CONFIG,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CONFIG_RESPONSE, (ConfigResponse) 
resp.getEntity())));
     return resp;
   }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/CatalogPolicyEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/CatalogPolicyEventServiceDelegator.java
index b415726dd..434323d27 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/CatalogPolicyEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/catalog/policy/CatalogPolicyEventServiceDelegator.java
@@ -29,7 +29,7 @@ import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.catalog.CatalogPrefixParser;
 import org.apache.polaris.service.catalog.api.PolarisCatalogPolicyApiService;
 import org.apache.polaris.service.catalog.common.CatalogAdapter;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -64,7 +64,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.CREATE_POLICY_REQUEST, 
createPolicyRequest)));
@@ -75,7 +75,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_CREATE_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.LOAD_POLICY_RESPONSE, 
(LoadPolicyResponse) resp.getEntity())));
@@ -96,7 +96,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LIST_POLICIES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_TYPE, policyType)));
@@ -107,7 +107,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LIST_POLICIES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_TYPE, policyType)));
@@ -126,7 +126,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_LOAD_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)));
@@ -136,7 +136,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_LOAD_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.LOAD_POLICY_RESPONSE, 
(LoadPolicyResponse) resp.getEntity())));
@@ -156,7 +156,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_UPDATE_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -168,7 +168,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_UPDATE_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.LOAD_POLICY_RESPONSE, 
(LoadPolicyResponse) resp.getEntity())));
@@ -188,7 +188,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_DROP_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -200,7 +200,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_DROP_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -221,7 +221,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_ATTACH_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -233,7 +233,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_ATTACH_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -254,7 +254,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_DETACH_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -266,7 +266,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_DETACH_POLICY,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.POLICY_NAME, policyName)
@@ -289,7 +289,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.BEFORE_GET_APPLICABLE_POLICIES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.TARGET_NAME, targetName)
@@ -308,7 +308,7 @@ public class CatalogPolicyEventServiceDelegator
         new PolarisEvent(
             PolarisEventType.AFTER_GET_APPLICABLE_POLICIES,
             eventMetadataFactory.create(),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, catalogName)
                 .put(EventAttributes.NAMESPACE_NAME, namespace)
                 .put(EventAttributes.TARGET_NAME, targetName)
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/AttributeMap.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributeMap.java
similarity index 87%
rename from 
runtime/service/src/main/java/org/apache/polaris/service/events/AttributeMap.java
rename to 
runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributeMap.java
index e2abf718c..1c5e2e498 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/AttributeMap.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributeMap.java
@@ -18,19 +18,21 @@
  */
 package org.apache.polaris.service.events;
 
+import jakarta.enterprise.context.RequestScoped;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
 
 /** A type-safe container for event attributes. This class is mutable and not 
thread-safe! */
-public final class AttributeMap {
+@RequestScoped
+public final class EventAttributeMap {
   private final Map<AttributeKey<?>, Object> attributes;
 
-  public AttributeMap() {
+  public EventAttributeMap() {
     this.attributes = new HashMap<>();
   }
 
-  public AttributeMap(AttributeMap other) {
+  public EventAttributeMap(EventAttributeMap other) {
     this.attributes = new HashMap<>(other.attributes);
   }
 
@@ -45,7 +47,7 @@ public final class AttributeMap {
             () -> new IllegalStateException("Required attribute " + key.name() 
+ " not found"));
   }
 
-  public <T> AttributeMap put(AttributeKey<T> key, T value) {
+  public <T> EventAttributeMap put(AttributeKey<T> key, T value) {
     if (value != null) {
       attributes.put(key, value);
     }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributes.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributes.java
index 7c62f84c3..138133d62 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributes.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/EventAttributes.java
@@ -19,7 +19,9 @@
 package org.apache.polaris.service.events;
 
 import com.google.common.reflect.TypeToken;
+import java.util.List;
 import java.util.Map;
+import org.apache.iceberg.TableMetadata;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.iceberg.rest.requests.CommitTransactionRequest;
@@ -109,6 +111,11 @@ public final class EventAttributes {
       new AttributeKey<>("rename_table_request", RenameTableRequest.class);
   public static final AttributeKey<LoadTableResponse> LOAD_TABLE_RESPONSE =
       new AttributeKey<>("load_table_response", LoadTableResponse.class);
+  public static final AttributeKey<TableMetadata> TABLE_METADATA =
+      new AttributeKey<>("table_metadata", TableMetadata.class);
+  // Used internally only. Not for external usage.
+  public static final AttributeKey<List<TableMetadata>> TABLE_METADATAS =
+      new AttributeKey<>("table_metadatas", new TypeToken<>() {});
   public static final AttributeKey<String> ACCESS_DELEGATION_MODE =
       new AttributeKey<>("access_delegation_mode", String.class);
   public static final AttributeKey<String> IF_NONE_MATCH_STRING =
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/PolarisEvent.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/PolarisEvent.java
index 2aaf83483..41097d49f 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/PolarisEvent.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/PolarisEvent.java
@@ -23,13 +23,13 @@ package org.apache.polaris.service.events;
  * attributes
  */
 public record PolarisEvent(
-    PolarisEventType type, PolarisEventMetadata metadata, AttributeMap 
attributes) {
+    PolarisEventType type, PolarisEventMetadata metadata, EventAttributeMap 
attributes) {
 
   public PolarisEvent {
-    attributes = new AttributeMap(attributes);
+    attributes = new EventAttributeMap(attributes);
   }
 
   public PolarisEvent(PolarisEventType type, PolarisEventMetadata metadata) {
-    this(type, metadata, new AttributeMap());
+    this(type, metadata, new EventAttributeMap());
   }
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/ratelimiter/RateLimiterFilter.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/ratelimiter/RateLimiterFilter.java
index d2884b32c..2572c7277 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/ratelimiter/RateLimiterFilter.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/ratelimiter/RateLimiterFilter.java
@@ -28,7 +28,7 @@ import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.ext.Provider;
 import java.io.IOException;
 import org.apache.polaris.service.config.FilterPriorities;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
@@ -67,7 +67,7 @@ public class RateLimiterFilter implements 
ContainerRequestFilter {
           new PolarisEvent(
               PolarisEventType.BEFORE_LIMIT_REQUEST_RATE,
               eventMetadataFactory.create(),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.HTTP_METHOD, ctx.getMethod())
                   .put(
                       EventAttributes.REQUEST_URI, 
ctx.getUriInfo().getAbsolutePath().toString())));
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/task/TaskExecutorImpl.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/task/TaskExecutorImpl.java
index 99d8e6bab..2808857fe 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/task/TaskExecutorImpl.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/task/TaskExecutorImpl.java
@@ -50,7 +50,7 @@ import 
org.apache.polaris.core.persistence.MetaStoreManagerFactory;
 import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
 import org.apache.polaris.service.context.catalog.PolarisPrincipalHolder;
 import org.apache.polaris.service.context.catalog.RealmContextHolder;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadata;
@@ -202,7 +202,7 @@ public class TaskExecutorImpl implements TaskExecutor {
         new PolarisEvent(
             PolarisEventType.BEFORE_ATTEMPT_TASK,
             eventMetadataFactory.copy(eventMetadata),
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.TASK_ENTITY_ID, taskEntityId)
                 .put(EventAttributes.TASK_ATTEMPT, attempt)));
 
@@ -251,7 +251,7 @@ public class TaskExecutorImpl implements TaskExecutor {
           new PolarisEvent(
               PolarisEventType.AFTER_ATTEMPT_TASK,
               eventMetadataFactory.copy(eventMetadata),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.TASK_ENTITY_ID, taskEntityId)
                   .put(EventAttributes.TASK_ATTEMPT, attempt)
                   .put(EventAttributes.TASK_SUCCESS, success)));
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java
index 64861f3b8..ffbd34423 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java
@@ -90,6 +90,7 @@ import 
org.apache.polaris.service.catalog.policy.PolicyCatalog;
 import org.apache.polaris.service.config.ReservedProperties;
 import 
org.apache.polaris.service.context.catalog.PolarisCallContextCatalogFactory;
 import org.apache.polaris.service.context.catalog.RealmContextHolder;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
 import org.apache.polaris.service.events.listeners.PolarisEventListener;
 import 
org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl;
@@ -204,6 +205,7 @@ public abstract class PolarisAuthzTestBase {
   @Inject protected CallContext callContext;
   @Inject protected RealmConfig realmConfig;
   @Inject protected RealmContextHolder realmContextHolder;
+  @Inject protected EventAttributeMap eventAttributeMap;
 
   protected IcebergCatalog baseCatalog;
   protected PolarisGenericTableCatalog genericTableCatalog;
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogHandlerAuthzTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogHandlerAuthzTest.java
index 79b2cf1d8..76aa2e4e1 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogHandlerAuthzTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogHandlerAuthzTest.java
@@ -132,7 +132,8 @@ public abstract class 
AbstractIcebergCatalogHandlerAuthzTest extends PolarisAuth
         reservedProperties,
         catalogHandlerUtils,
         emptyExternalCatalogFactory(),
-        storageAccessConfigProvider);
+        storageAccessConfigProvider,
+        eventAttributeMap);
   }
 
   protected void doTestInsufficientPrivileges(
@@ -273,7 +274,8 @@ public abstract class 
AbstractIcebergCatalogHandlerAuthzTest extends PolarisAuth
             reservedProperties,
             catalogHandlerUtils,
             emptyExternalCatalogFactory(),
-            storageAccessConfigProvider);
+            storageAccessConfigProvider,
+            eventAttributeMap);
 
     // a variety of actions are all disallowed because the principal's 
credentials must be rotated
     doTestInsufficientPrivileges(
@@ -312,7 +314,8 @@ public abstract class 
AbstractIcebergCatalogHandlerAuthzTest extends PolarisAuth
             reservedProperties,
             catalogHandlerUtils,
             emptyExternalCatalogFactory(),
-            storageAccessConfigProvider);
+            storageAccessConfigProvider,
+            eventAttributeMap);
 
     doTestSufficientPrivilegeSets(
         List.of(Set.of(PolarisPrivilege.NAMESPACE_LIST)),
@@ -1201,7 +1204,8 @@ public abstract class 
AbstractIcebergCatalogHandlerAuthzTest extends PolarisAuth
         reservedProperties,
         catalogHandlerUtils,
         emptyExternalCatalogFactory(),
-        storageAccessConfigProvider);
+        storageAccessConfigProvider,
+        eventAttributeMap);
   }
 
   @Test
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/CommitTransactionEventTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/CommitTransactionEventTest.java
index e0f4a2783..46822e28e 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/CommitTransactionEventTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/CommitTransactionEventTest.java
@@ -28,6 +28,7 @@ import java.nio.file.Path;
 import java.util.List;
 import java.util.Map;
 import org.apache.iceberg.MetadataUpdate;
+import org.apache.iceberg.TableMetadata;
 import org.apache.iceberg.UpdateRequirement;
 import org.apache.iceberg.catalog.Namespace;
 import org.apache.iceberg.catalog.TableIdentifier;
@@ -117,6 +118,33 @@ public class CommitTransactionEventTest {
         .isInstanceOf(IllegalStateException.class);
   }
 
+  @Test
+  void testLoadTableResponsesInCommitTransaction() {
+    TestServices testServices = createTestServices();
+    createCatalogAndNamespace(testServices, Map.of(), catalogLocation);
+
+    String table1Name = "test-table-5";
+    String table2Name = "test-table-6";
+    executeTransactionTest(false, table1Name, table2Name, testServices);
+
+    TestPolarisEventListener testEventListener =
+        (TestPolarisEventListener) testServices.polarisEventListener();
+
+    // Verify that AfterUpdateTable events contain LoadTableResponse objects
+    PolarisEvent afterUpdateTableEvent =
+        testEventListener.getLatest(PolarisEventType.AFTER_UPDATE_TABLE);
+
+    // Verify second table's LoadTableResponse
+    
assertThat(afterUpdateTableEvent.attributes().getRequired(EventAttributes.TABLE_NAME))
+        .isEqualTo(table2Name);
+    
assertThat(afterUpdateTableEvent.attributes().get(EventAttributes.TABLE_METADATA)).isPresent();
+    
assertThat(afterUpdateTableEvent.attributes().get(EventAttributes.TABLE_METADATA)).isNotEmpty();
+    TableMetadata metadata =
+        
afterUpdateTableEvent.attributes().getRequired(EventAttributes.TABLE_METADATA);
+    assertThat(metadata).isNotNull();
+    assertThat(metadata.properties()).containsEntry(propertyName, "value2");
+  }
+
   private void createCatalogAndNamespace(
       TestServices services, Map<String, String> catalogConfig, String 
catalogLocation) {
     CatalogProperties.Builder propertiesBuilder =
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java
index adeaa38a1..16cb0974f 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java
@@ -75,7 +75,8 @@ public class IcebergCatalogHandlerFineGrainedDisabledTest 
extends PolarisAuthzTe
         reservedProperties,
         catalogHandlerUtils,
         emptyExternalCatalogFactory(),
-        storageAccessConfigProvider);
+        storageAccessConfigProvider,
+        eventAttributeMap);
   }
 
   public static class Profile extends PolarisAuthzTestBase.Profile {
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/events/AttributeMapTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/events/AttributeMapTest.java
index e27444983..c7597197a 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/events/AttributeMapTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/events/AttributeMapTest.java
@@ -31,7 +31,7 @@ class AttributeMapTest {
 
   @Test
   void testPutAndGet() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
     map.put(STRING_KEY, "value");
 
     assertThat(map.get(STRING_KEY)).hasValue("value");
@@ -39,14 +39,14 @@ class AttributeMapTest {
 
   @Test
   void testGetReturnsEmptyForMissingKey() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
 
     assertThat(map.get(STRING_KEY)).isEmpty();
   }
 
   @Test
   void testGetRequired() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
     map.put(STRING_KEY, "value");
 
     assertThat(map.getRequired(STRING_KEY)).isEqualTo("value");
@@ -54,7 +54,7 @@ class AttributeMapTest {
 
   @Test
   void testGetRequiredThrowsForMissingKey() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
 
     assertThatThrownBy(() -> map.getRequired(STRING_KEY))
         .isInstanceOf(IllegalStateException.class)
@@ -63,7 +63,7 @@ class AttributeMapTest {
 
   @Test
   void testContains() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
     map.put(STRING_KEY, "value");
 
     assertThat(map.contains(STRING_KEY)).isTrue();
@@ -72,7 +72,7 @@ class AttributeMapTest {
 
   @Test
   void testNullValueIsIgnored() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
     map.put(STRING_KEY, null);
 
     assertThat(map.contains(STRING_KEY)).isFalse();
@@ -81,7 +81,7 @@ class AttributeMapTest {
 
   @Test
   void testSize() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
     assertThat(map.size()).isEqualTo(0);
 
     map.put(STRING_KEY, "value");
@@ -93,7 +93,7 @@ class AttributeMapTest {
 
   @Test
   void testIsEmpty() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
     assertThat(map.isEmpty()).isTrue();
 
     map.put(STRING_KEY, "value");
@@ -102,10 +102,10 @@ class AttributeMapTest {
 
   @Test
   void testCopyConstructor() {
-    AttributeMap original = new AttributeMap();
+    EventAttributeMap original = new EventAttributeMap();
     original.put(STRING_KEY, "value");
 
-    AttributeMap copy = new AttributeMap(original);
+    EventAttributeMap copy = new EventAttributeMap(original);
 
     assertThat(copy.getRequired(STRING_KEY)).isEqualTo("value");
 
@@ -116,9 +116,9 @@ class AttributeMapTest {
 
   @Test
   void testPutReturnsThis() {
-    AttributeMap map = new AttributeMap();
+    EventAttributeMap map = new EventAttributeMap();
 
-    AttributeMap result = map.put(STRING_KEY, "value");
+    EventAttributeMap result = map.put(STRING_KEY, "value");
 
     assertThat(result).isSameAs(map);
   }
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/events/PolarisEventTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/events/PolarisEventTest.java
index 68b1c7d6b..45d72eb3d 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/events/PolarisEventTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/events/PolarisEventTest.java
@@ -37,7 +37,7 @@ class PolarisEventTest {
         new PolarisEvent(
             PolarisEventType.BEFORE_CREATE_TABLE,
             TEST_METADATA,
-            new AttributeMap()
+            new EventAttributeMap()
                 .put(EventAttributes.CATALOG_NAME, TEST_CATALOG)
                 .put(EventAttributes.TABLE_NAME, TEST_TABLE));
 
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/events/jsonEventListener/aws/cloudwatch/AwsCloudWatchEventListenerTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/events/jsonEventListener/aws/cloudwatch/AwsCloudWatchEventListenerTest.java
index 110f146b6..28a5969af 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/events/jsonEventListener/aws/cloudwatch/AwsCloudWatchEventListenerTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/events/jsonEventListener/aws/cloudwatch/AwsCloudWatchEventListenerTest.java
@@ -36,7 +36,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.polaris.core.auth.PolarisPrincipal;
 import org.apache.polaris.service.config.PolarisIcebergObjectMapperCustomizer;
-import org.apache.polaris.service.events.AttributeMap;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.EventAttributes;
 import org.apache.polaris.service.events.PolarisEvent;
 import org.apache.polaris.service.events.PolarisEventMetadata;
@@ -194,7 +194,7 @@ class AwsCloudWatchEventListenerTest {
           new PolarisEvent(
               PolarisEventType.AFTER_REFRESH_TABLE,
               
PolarisEventMetadata.builder().realmId(REALM).user(PRINCIPAL).build(),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.CATALOG_NAME, "test_catalog")
                   .put(EventAttributes.TABLE_IDENTIFIER, testTable)));
 
@@ -256,7 +256,7 @@ class AwsCloudWatchEventListenerTest {
           new PolarisEvent(
               PolarisEventType.AFTER_REFRESH_TABLE,
               
PolarisEventMetadata.builder().realmId(REALM).user(PRINCIPAL).build(),
-              new AttributeMap()
+              new EventAttributeMap()
                   .put(EventAttributes.CATALOG_NAME, "test_catalog")
                   .put(EventAttributes.TABLE_IDENTIFIER, syncTestTable)));
 
diff --git 
a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
 
b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
index 30303121e..7b4e5c2dd 100644
--- 
a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
+++ 
b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
@@ -83,6 +83,7 @@ import 
org.apache.polaris.service.context.catalog.CallContextCatalogFactory;
 import 
org.apache.polaris.service.context.catalog.PolarisCallContextCatalogFactory;
 import org.apache.polaris.service.credentials.DefaultPolarisCredentialManager;
 import 
org.apache.polaris.service.credentials.connection.SigV4ConnectionCredentialVendor;
+import org.apache.polaris.service.events.EventAttributeMap;
 import org.apache.polaris.service.events.PolarisEventMetadata;
 import org.apache.polaris.service.events.PolarisEventMetadataFactory;
 import org.apache.polaris.service.events.listeners.PolarisEventListener;
@@ -334,6 +335,7 @@ public record TestServices(
       
Mockito.when(externalCatalogFactory.select(any())).thenReturn(externalCatalogFactory);
       Mockito.when(externalCatalogFactory.isUnsatisfied()).thenReturn(true);
 
+      EventAttributeMap eventAttributeMap = new EventAttributeMap();
       IcebergCatalogAdapter catalogService =
           new IcebergCatalogAdapter(
               diagnostics,
@@ -351,7 +353,8 @@ public record TestServices(
               externalCatalogFactory,
               storageAccessConfigProvider,
               new DefaultMetricsReporter(),
-              Clock.systemUTC());
+              Clock.systemUTC(),
+              eventAttributeMap);
 
       // Optionally wrap with event delegator
       IcebergRestCatalogApiService finalRestCatalogService = catalogService;
@@ -362,7 +365,8 @@ public record TestServices(
                 catalogService,
                 polarisEventListener,
                 eventMetadataFactory,
-                new DefaultCatalogPrefixParser());
+                new DefaultCatalogPrefixParser(),
+                eventAttributeMap);
         finalRestConfigurationService =
             new IcebergRestConfigurationEventServiceDelegator(
                 catalogService, polarisEventListener, eventMetadataFactory);

Reply via email to