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

adutra 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 19742cc20 Fix & enhancements to the Events API hierarchy (#2629)
19742cc20 is described below

commit 19742cc20f4bc0b7e5a315a62f89c6085ad81b7d
Author: Alexandre Dutra <[email protected]>
AuthorDate: Fri Sep 26 10:23:20 2025 +0200

    Fix & enhancements to the Events API hierarchy (#2629)
    
    Summary of changes:
    
    - Turned `PolarisEventListener` into an interface to facilitate 
implementation / mocking
    - Added missing `implements PolarisEvent` to many event records
    - Removed unused method overrides
    - Added missing method overrides to `TestPolarisEventListener`
---
 .../PolarisCatalogsEventServiceDelegator.java      |   4 +-
 .../events/CatalogGenericTableServiceEvents.java   |  27 +-
 .../service/events/CatalogPolicyServiceEvents.java |  48 +-
 .../service/events/CatalogsServiceEvents.java      |   4 +-
 .../service/events/IcebergRestCatalogEvents.java   | 151 ++--
 .../PropertyMapEventListener.java                  |   2 +-
 .../events/listeners/NoOpPolarisEventListener.java |   2 +-
 .../events/listeners/PolarisEventListener.java     | 532 ++++++--------
 .../listeners/PolarisPersistenceEventListener.java |  37 +-
 .../events/listeners/TestPolarisEventListener.java | 772 ++++++++++++++++++++-
 .../events/listeners/PolarisEventListenerTest.java |  85 +++
 .../listeners/TestPolarisEventListenerTest.java}   |  25 +-
 12 files changed, 1226 insertions(+), 463 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 f84cafa04..1695334ed 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
@@ -91,9 +91,9 @@ public class PolarisCatalogsEventServiceDelegator implements 
PolarisCatalogsApiS
 
   @Override
   public Response listCatalogs(RealmContext realmContext, SecurityContext 
securityContext) {
-    polarisEventListener.onBeforeListCatalog(new 
CatalogsServiceEvents.BeforeListCatalogEvent());
+    polarisEventListener.onBeforeListCatalogs(new 
CatalogsServiceEvents.BeforeListCatalogsEvent());
     Response resp = delegate.listCatalogs(realmContext, securityContext);
-    polarisEventListener.onAfterListCatalog(new 
CatalogsServiceEvents.AfterListCatalogEvent());
+    polarisEventListener.onAfterListCatalogs(new 
CatalogsServiceEvents.AfterListCatalogsEvent());
     return resp;
   }
 
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogGenericTableServiceEvents.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogGenericTableServiceEvents.java
index a533e88c7..ec5e37992 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogGenericTableServiceEvents.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogGenericTableServiceEvents.java
@@ -24,24 +24,27 @@ import org.apache.polaris.service.types.GenericTable;
 
 public class CatalogGenericTableServiceEvents {
   public record BeforeCreateGenericTableEvent(
-      String catalogName, String namespace, CreateGenericTableRequest request) 
{}
+      String catalogName, String namespace, CreateGenericTableRequest request)
+      implements PolarisEvent {}
 
   public record AfterCreateGenericTableEvent(
-      String catalogName, String namespace, GenericTable table) {}
+      String catalogName, String namespace, GenericTable table) implements 
PolarisEvent {}
 
-  public record BeforeDropGenericTableEvent(
-      String catalogName, String namespace, String tableName) {}
+  public record BeforeDropGenericTableEvent(String catalogName, String 
namespace, String tableName)
+      implements PolarisEvent {}
 
-  public record AfterDropGenericTableEvent(
-      String catalogName, String namespace, String tableName) {}
+  public record AfterDropGenericTableEvent(String catalogName, String 
namespace, String tableName)
+      implements PolarisEvent {}
 
-  public record BeforeListGenericTablesEvent(String catalogName, String 
namespace) {}
+  public record BeforeListGenericTablesEvent(String catalogName, String 
namespace)
+      implements PolarisEvent {}
 
-  public record AfterListGenericTablesEvent(String catalogName, String 
namespace) {}
+  public record AfterListGenericTablesEvent(String catalogName, String 
namespace)
+      implements PolarisEvent {}
 
-  public record BeforeLoadGenericTableEvent(
-      String catalogName, String namespace, String tableName) {}
+  public record BeforeLoadGenericTableEvent(String catalogName, String 
namespace, String tableName)
+      implements PolarisEvent {}
 
-  public record AfterLoadGenericTableEvent(
-      String catalogName, String namespace, GenericTable table) {}
+  public record AfterLoadGenericTableEvent(String catalogName, String 
namespace, GenericTable table)
+      implements PolarisEvent {}
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogPolicyServiceEvents.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogPolicyServiceEvents.java
index a550ed10d..fb302ff42 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogPolicyServiceEvents.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogPolicyServiceEvents.java
@@ -34,68 +34,84 @@ public class CatalogPolicyServiceEvents {
 
   // Policy CRUD Events
   public record BeforeCreatePolicyEvent(
-      String catalogName, String namespace, CreatePolicyRequest 
createPolicyRequest) {}
+      String catalogName, String namespace, CreatePolicyRequest 
createPolicyRequest)
+      implements PolarisEvent {}
 
   public record AfterCreatePolicyEvent(
-      String catalogName, String namespace, LoadPolicyResponse 
loadPolicyResponse) {}
+      String catalogName, String namespace, LoadPolicyResponse 
loadPolicyResponse)
+      implements PolarisEvent {}
 
-  public record BeforeListPoliciesEvent(String catalogName, String namespace, 
String policyType) {}
+  public record BeforeListPoliciesEvent(String catalogName, String namespace, 
String policyType)
+      implements PolarisEvent {}
 
-  public record AfterListPoliciesEvent(String catalogName, String namespace, 
String policyType) {}
+  public record AfterListPoliciesEvent(String catalogName, String namespace, 
String policyType)
+      implements PolarisEvent {}
 
-  public record BeforeLoadPolicyEvent(String catalogName, String namespace, 
String policyName) {}
+  public record BeforeLoadPolicyEvent(String catalogName, String namespace, 
String policyName)
+      implements PolarisEvent {}
 
   public record AfterLoadPolicyEvent(
-      String catalogName, String namespace, LoadPolicyResponse 
loadPolicyResponse) {}
+      String catalogName, String namespace, LoadPolicyResponse 
loadPolicyResponse)
+      implements PolarisEvent {}
 
   public record BeforeUpdatePolicyEvent(
       String catalogName,
       String namespace,
       String policyName,
-      UpdatePolicyRequest updatePolicyRequest) {}
+      UpdatePolicyRequest updatePolicyRequest)
+      implements PolarisEvent {}
 
   public record AfterUpdatePolicyEvent(
-      String catalogName, String namespace, LoadPolicyResponse 
loadPolicyResponse) {}
+      String catalogName, String namespace, LoadPolicyResponse 
loadPolicyResponse)
+      implements PolarisEvent {}
 
   public record BeforeDropPolicyEvent(
-      String catalogName, String namespace, String policyName, Boolean 
detachAll) {}
+      String catalogName, String namespace, String policyName, Boolean 
detachAll)
+      implements PolarisEvent {}
 
   public record AfterDropPolicyEvent(
-      String catalogName, String namespace, String policyName, Boolean 
detachAll) {}
+      String catalogName, String namespace, String policyName, Boolean 
detachAll)
+      implements PolarisEvent {}
 
   // Policy Attachment Events
   public record BeforeAttachPolicyEvent(
       String catalogName,
       String namespace,
       String policyName,
-      AttachPolicyRequest attachPolicyRequest) {}
+      AttachPolicyRequest attachPolicyRequest)
+      implements PolarisEvent {}
 
   public record AfterAttachPolicyEvent(
       String catalogName,
       String namespace,
       String policyName,
-      AttachPolicyRequest attachPolicyRequest) {}
+      AttachPolicyRequest attachPolicyRequest)
+      implements PolarisEvent {}
 
   public record BeforeDetachPolicyEvent(
       String catalogName,
       String namespace,
       String policyName,
-      DetachPolicyRequest detachPolicyRequest) {}
+      DetachPolicyRequest detachPolicyRequest)
+      implements PolarisEvent {}
 
   public record AfterDetachPolicyEvent(
       String catalogName,
       String namespace,
       String policyName,
-      DetachPolicyRequest detachPolicyRequest) {}
+      DetachPolicyRequest detachPolicyRequest)
+      implements PolarisEvent {}
 
   // Policy Query Events
   public record BeforeGetApplicablePoliciesEvent(
-      String catalogName, String namespace, String targetName, String 
policyType) {}
+      String catalogName, String namespace, String targetName, String 
policyType)
+      implements PolarisEvent {}
 
   public record AfterGetApplicablePoliciesEvent(
       String catalogName,
       String namespace,
       String targetName,
       String policyType,
-      GetApplicablePoliciesResponse getApplicablePoliciesResponse) {}
+      GetApplicablePoliciesResponse getApplicablePoliciesResponse)
+      implements PolarisEvent {}
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogsServiceEvents.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogsServiceEvents.java
index 6242d91c3..918e34c70 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogsServiceEvents.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogsServiceEvents.java
@@ -46,9 +46,9 @@ public class CatalogsServiceEvents {
 
   public record AfterUpdateCatalogEvent(Catalog catalog) implements 
PolarisEvent {}
 
-  public record BeforeListCatalogEvent() implements PolarisEvent {}
+  public record BeforeListCatalogsEvent() implements PolarisEvent {}
 
-  public record AfterListCatalogEvent() implements PolarisEvent {}
+  public record AfterListCatalogsEvent() implements PolarisEvent {}
 
   public record BeforeCreateCatalogRoleEvent(String catalogName, String 
catalogRoleName)
       implements PolarisEvent {}
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/IcebergRestCatalogEvents.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/IcebergRestCatalogEvents.java
index 76d3cf298..607ff43e4 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/IcebergRestCatalogEvents.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/IcebergRestCatalogEvents.java
@@ -47,54 +47,69 @@ public class IcebergRestCatalogEvents {
 
   // Namespace Events
   public record BeforeCreateNamespaceEvent(
-      String catalogName, CreateNamespaceRequest createNamespaceRequest) {}
+      String catalogName, CreateNamespaceRequest createNamespaceRequest) 
implements PolarisEvent {}
 
   public record AfterCreateNamespaceEvent(
-      String catalogName, Namespace namespace, Map<String, String> 
namespaceProperties) {}
+      String catalogName, Namespace namespace, Map<String, String> 
namespaceProperties)
+      implements PolarisEvent {}
 
-  public record BeforeListNamespacesEvent(String catalogName, String parent) {}
+  public record BeforeListNamespacesEvent(String catalogName, String parent)
+      implements PolarisEvent {}
 
-  public record AfterListNamespacesEvent(String catalogName, String parent) {}
+  public record AfterListNamespacesEvent(String catalogName, String parent)
+      implements PolarisEvent {}
 
-  public record BeforeLoadNamespaceMetadataEvent(String catalogName, Namespace 
namespace) {}
+  public record BeforeLoadNamespaceMetadataEvent(String catalogName, Namespace 
namespace)
+      implements PolarisEvent {}
 
   public record AfterLoadNamespaceMetadataEvent(
-      String catalogName, Namespace namespace, Map<String, String> 
namespaceProperties) {}
+      String catalogName, Namespace namespace, Map<String, String> 
namespaceProperties)
+      implements PolarisEvent {}
 
-  public record BeforeCheckExistsNamespaceEvent(String catalogName, Namespace 
namespace) {}
+  public record BeforeCheckExistsNamespaceEvent(String catalogName, Namespace 
namespace)
+      implements PolarisEvent {}
 
-  public record AfterCheckExistsNamespaceEvent(String catalogName, Namespace 
namespace) {}
+  public record AfterCheckExistsNamespaceEvent(String catalogName, Namespace 
namespace)
+      implements PolarisEvent {}
 
-  public record BeforeDropNamespaceEvent(String catalogName, Namespace 
namespace) {}
+  public record BeforeDropNamespaceEvent(String catalogName, Namespace 
namespace)
+      implements PolarisEvent {}
 
-  public record AfterDropNamespaceEvent(String catalogName, String namespace) 
{}
+  public record AfterDropNamespaceEvent(String catalogName, String namespace)
+      implements PolarisEvent {}
 
   public record BeforeUpdateNamespacePropertiesEvent(
       String catalogName,
       Namespace namespace,
-      UpdateNamespacePropertiesRequest updateNamespacePropertiesRequest) {}
+      UpdateNamespacePropertiesRequest updateNamespacePropertiesRequest)
+      implements PolarisEvent {}
 
   public record AfterUpdateNamespacePropertiesEvent(
       String catalogName,
       Namespace namespace,
-      UpdateNamespacePropertiesResponse updateNamespacePropertiesResponse) {}
+      UpdateNamespacePropertiesResponse updateNamespacePropertiesResponse)
+      implements PolarisEvent {}
 
   // Table Events
   public record BeforeCreateTableEvent(
       String catalogName,
       Namespace namespace,
       CreateTableRequest createTableRequest,
-      String accessDelegationMode) {}
+      String accessDelegationMode)
+      implements PolarisEvent {}
 
   public record AfterCreateTableEvent(
       String catalogName,
       Namespace namespace,
       String tableName,
-      LoadTableResponse loadTableResponse) {}
+      LoadTableResponse loadTableResponse)
+      implements PolarisEvent {}
 
-  public record BeforeListTablesEvent(String catalogName, Namespace namespace) 
{}
+  public record BeforeListTablesEvent(String catalogName, Namespace namespace)
+      implements PolarisEvent {}
 
-  public record AfterListTablesEvent(String catalogName, Namespace namespace) 
{}
+  public record AfterListTablesEvent(String catalogName, Namespace namespace)
+      implements PolarisEvent {}
 
   public record BeforeLoadTableEvent(
       String catalogName,
@@ -102,111 +117,139 @@ public class IcebergRestCatalogEvents {
       String table,
       String accessDelegationMode,
       String ifNoneMatchString,
-      String snapshots) {}
+      String snapshots)
+      implements PolarisEvent {}
 
   public record AfterLoadTableEvent(
-      String catalogName, Namespace namespace, LoadTableResponse 
loadTableResponse) {}
+      String catalogName, Namespace namespace, LoadTableResponse 
loadTableResponse)
+      implements PolarisEvent {}
 
-  public record BeforeCheckExistsTableEvent(
-      String catalogName, Namespace namespace, String table) {}
+  public record BeforeCheckExistsTableEvent(String catalogName, Namespace 
namespace, String table)
+      implements PolarisEvent {}
 
-  public record AfterCheckExistsTableEvent(String catalogName, Namespace 
namespace, String table) {}
+  public record AfterCheckExistsTableEvent(String catalogName, Namespace 
namespace, String table)
+      implements PolarisEvent {}
 
   public record BeforeDropTableEvent(
-      String catalogName, Namespace namespace, String table, Boolean 
purgeRequested) {}
+      String catalogName, Namespace namespace, String table, Boolean 
purgeRequested)
+      implements PolarisEvent {}
 
   public record AfterDropTableEvent(
-      String catalogName, Namespace namespace, String table, Boolean 
purgeRequested) {}
+      String catalogName, Namespace namespace, String table, Boolean 
purgeRequested)
+      implements PolarisEvent {}
 
   public record BeforeRegisterTableEvent(
-      String catalogName, Namespace namespace, RegisterTableRequest 
registerTableRequest) {}
+      String catalogName, Namespace namespace, RegisterTableRequest 
registerTableRequest)
+      implements PolarisEvent {}
 
   public record AfterRegisterTableEvent(
-      String catalogName, Namespace namespace, LoadTableResponse 
loadTableResponse) {}
+      String catalogName, Namespace namespace, LoadTableResponse 
loadTableResponse)
+      implements PolarisEvent {}
 
-  public record BeforeRenameTableEvent(String catalogName, RenameTableRequest 
renameTableRequest) {}
+  public record BeforeRenameTableEvent(String catalogName, RenameTableRequest 
renameTableRequest)
+      implements PolarisEvent {}
 
-  public record AfterRenameTableEvent(String catalogName, RenameTableRequest 
renameTableRequest) {}
+  public record AfterRenameTableEvent(String catalogName, RenameTableRequest 
renameTableRequest)
+      implements PolarisEvent {}
 
   public record BeforeUpdateTableEvent(
       String catalogName,
       Namespace namespace,
       String sourceTable,
-      CommitTableRequest commitTableRequest) {}
+      CommitTableRequest commitTableRequest)
+      implements PolarisEvent {}
 
   public record AfterUpdateTableEvent(
       String catalogName,
       Namespace namespace,
       String sourceTable,
-      LoadTableResponse loadTableResponse) {}
+      LoadTableResponse loadTableResponse)
+      implements PolarisEvent {}
 
   // View Events
   public record BeforeCreateViewEvent(
-      String catalogName, Namespace namespace, CreateViewRequest 
createViewRequest) {}
+      String catalogName, Namespace namespace, CreateViewRequest 
createViewRequest)
+      implements PolarisEvent {}
 
   public record AfterCreateViewEvent(
-      String catalogName, Namespace namespace, LoadViewResponse 
loadViewResponse) {}
+      String catalogName, Namespace namespace, LoadViewResponse 
loadViewResponse)
+      implements PolarisEvent {}
 
-  public record BeforeListViewsEvent(String catalogName, Namespace namespace) 
{}
+  public record BeforeListViewsEvent(String catalogName, Namespace namespace)
+      implements PolarisEvent {}
 
-  public record AfterListViewsEvent(String catalogName, Namespace namespace) {}
+  public record AfterListViewsEvent(String catalogName, Namespace namespace)
+      implements PolarisEvent {}
 
-  public record BeforeLoadViewEvent(String catalogName, Namespace namespace, 
String view) {}
+  public record BeforeLoadViewEvent(String catalogName, Namespace namespace, 
String view)
+      implements PolarisEvent {}
 
   public record AfterLoadViewEvent(
-      String catalogName, Namespace namespace, LoadViewResponse 
loadViewResponse) {}
+      String catalogName, Namespace namespace, LoadViewResponse 
loadViewResponse)
+      implements PolarisEvent {}
 
-  public record BeforeCheckExistsViewEvent(String catalogName, Namespace 
namespace, String view) {}
+  public record BeforeCheckExistsViewEvent(String catalogName, Namespace 
namespace, String view)
+      implements PolarisEvent {}
 
-  public record AfterCheckExistsViewEvent(String catalogName, Namespace 
namespace, String view) {}
+  public record AfterCheckExistsViewEvent(String catalogName, Namespace 
namespace, String view)
+      implements PolarisEvent {}
 
-  public record BeforeDropViewEvent(String catalogName, Namespace namespace, 
String view) {}
+  public record BeforeDropViewEvent(String catalogName, Namespace namespace, 
String view)
+      implements PolarisEvent {}
 
-  public record AfterDropViewEvent(String catalogName, Namespace namespace, 
String view) {}
+  public record AfterDropViewEvent(String catalogName, Namespace namespace, 
String view)
+      implements PolarisEvent {}
 
-  public record BeforeRenameViewEvent(String catalogName, RenameTableRequest 
renameTableRequest) {}
+  public record BeforeRenameViewEvent(String catalogName, RenameTableRequest 
renameTableRequest)
+      implements PolarisEvent {}
 
-  public record AfterRenameViewEvent(String catalogName, RenameTableRequest 
renameTableRequest) {}
+  public record AfterRenameViewEvent(String catalogName, RenameTableRequest 
renameTableRequest)
+      implements PolarisEvent {}
 
   public record BeforeReplaceViewEvent(
       String catalogName,
       Namespace namespace,
       String sourceView,
-      CommitViewRequest commitViewRequest) {}
+      CommitViewRequest commitViewRequest)
+      implements PolarisEvent {}
 
   public record AfterReplaceViewEvent(
-      String catalogName,
-      Namespace namespace,
-      String sourceView,
-      LoadViewResponse loadViewResponse) {}
+      String catalogName, Namespace namespace, String sourceView, 
LoadViewResponse loadViewResponse)
+      implements PolarisEvent {}
 
   // Credential Events
-  public record BeforeLoadCredentialsEvent(String catalogName, Namespace 
namespace, String table) {}
+  public record BeforeLoadCredentialsEvent(String catalogName, Namespace 
namespace, String table)
+      implements PolarisEvent {}
 
-  public record AfterLoadCredentialsEvent(String catalogName, Namespace 
namespace, String table) {}
+  public record AfterLoadCredentialsEvent(String catalogName, Namespace 
namespace, String table)
+      implements PolarisEvent {}
 
   // Transaction Events
   public record BeforeCommitTransactionEvent(
-      String catalogName, CommitTransactionRequest commitTransactionRequest) {}
+      String catalogName, CommitTransactionRequest commitTransactionRequest)
+      implements PolarisEvent {}
 
   // TODO: Add all PolarisEntities that were modified with this transaction.
   public record AfterCommitTransactionEvent(
-      String catalogName, CommitTransactionRequest commitTransactionRequest) {}
+      String catalogName, CommitTransactionRequest commitTransactionRequest)
+      implements PolarisEvent {}
 
   // Notification Events
   public record BeforeSendNotificationEvent(
       String catalogName,
       Namespace namespace,
       String table,
-      NotificationRequest notificationRequest) {}
+      NotificationRequest notificationRequest)
+      implements PolarisEvent {}
 
   // TODO: Add result once SendNotification API changes are confirmed to 
return the result.
-  public record AfterSendNotificationEvent(String catalogName, Namespace 
namespace, String table) {}
+  public record AfterSendNotificationEvent(String catalogName, Namespace 
namespace, String table)
+      implements PolarisEvent {}
 
   // Configuration Events
-  public record BeforeGetConfigEvent(String warehouse) {}
+  public record BeforeGetConfigEvent(String warehouse) implements PolarisEvent 
{}
 
-  public record AfterGetConfigEvent(ConfigResponse configResponse) {}
+  public record AfterGetConfigEvent(ConfigResponse configResponse) implements 
PolarisEvent {}
 
   // Legacy events
   public record BeforeCommitTableEvent(
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/jsonEventListener/PropertyMapEventListener.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/jsonEventListener/PropertyMapEventListener.java
index 3d23129e6..63311fc03 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/jsonEventListener/PropertyMapEventListener.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/jsonEventListener/PropertyMapEventListener.java
@@ -30,7 +30,7 @@ import 
org.apache.polaris.service.events.listeners.PolarisEventListener;
  * {{@code @link#transformAndSendEvent(HashMap)}} method to define how the 
event data should be
  * transformed into a JSON string, transmitted, and/or stored.
  */
-public abstract class PropertyMapEventListener extends PolarisEventListener {
+public abstract class PropertyMapEventListener implements PolarisEventListener 
{
   protected abstract void transformAndSendEvent(HashMap<String, Object> 
properties);
 
   @Override
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
index c02dfe481..bfef6e96e 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
@@ -24,4 +24,4 @@ import jakarta.enterprise.context.ApplicationScoped;
 /** Event listener that does nothing. */
 @ApplicationScoped
 @Identifier("no-op")
-public class NoOpPolarisEventListener extends PolarisEventListener {}
+public class NoOpPolarisEventListener implements PolarisEventListener {}
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisEventListener.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisEventListener.java
index 4ad7e642f..113dcd0d9 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisEventListener.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisEventListener.java
@@ -32,518 +32,400 @@ import 
org.apache.polaris.service.events.PrincipalsServiceEvents;
  * Represents an event listener that can respond to notable moments during 
Polaris's execution.
  * Event details are documented under the event objects themselves.
  */
-public abstract class PolarisEventListener {
-  /** {@link BeforeLimitRequestRateEvent} */
-  public void onBeforeLimitRequestRate(BeforeLimitRequestRateEvent event) {}
+public interface PolarisEventListener {
 
-  /** {@link IcebergRestCatalogEvents.BeforeCommitTableEvent} */
-  public void 
onBeforeCommitTable(IcebergRestCatalogEvents.BeforeCommitTableEvent event) {}
+  /*
+   API Compatibility Note: any new methods added to this interface must have a 
default
+   implementation in order to preserve binary compatibility.
+  */
 
-  /** {@link IcebergRestCatalogEvents.AfterCommitTableEvent} */
-  public void 
onAfterCommitTable(IcebergRestCatalogEvents.AfterCommitTableEvent event) {}
+  // ============= Catalog Events =============
 
-  /** {@link IcebergRestCatalogEvents.BeforeCommitViewEvent} */
-  public void 
onBeforeCommitView(IcebergRestCatalogEvents.BeforeCommitViewEvent event) {}
+  default void 
onBeforeCreateCatalog(CatalogsServiceEvents.BeforeCreateCatalogEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCommitViewEvent} */
-  public void onAfterCommitView(IcebergRestCatalogEvents.AfterCommitViewEvent 
event) {}
+  default void 
onAfterCreateCatalog(CatalogsServiceEvents.AfterCreateCatalogEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeRefreshTableEvent} */
-  public void 
onBeforeRefreshTable(IcebergRestCatalogEvents.BeforeRefreshTableEvent event) {}
+  default void 
onBeforeDeleteCatalog(CatalogsServiceEvents.BeforeDeleteCatalogEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterRefreshTableEvent} */
-  public void 
onAfterRefreshTable(IcebergRestCatalogEvents.AfterRefreshTableEvent event) {}
+  default void 
onAfterDeleteCatalog(CatalogsServiceEvents.AfterDeleteCatalogEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeRefreshViewEvent} */
-  public void 
onBeforeRefreshView(IcebergRestCatalogEvents.BeforeRefreshViewEvent event) {}
+  default void onBeforeGetCatalog(CatalogsServiceEvents.BeforeGetCatalogEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterRefreshViewEvent} */
-  public void 
onAfterRefreshView(IcebergRestCatalogEvents.AfterRefreshViewEvent event) {}
+  default void onAfterGetCatalog(CatalogsServiceEvents.AfterGetCatalogEvent 
event) {}
 
-  /** {@link BeforeAttemptTaskEvent} */
-  public void onBeforeAttemptTask(BeforeAttemptTaskEvent event) {}
+  default void 
onBeforeUpdateCatalog(CatalogsServiceEvents.BeforeUpdateCatalogEvent event) {}
 
-  /** {@link AfterAttemptTaskEvent} */
-  public void onAfterAttemptTask(AfterAttemptTaskEvent event) {}
+  default void 
onAfterUpdateCatalog(CatalogsServiceEvents.AfterUpdateCatalogEvent event) {}
 
-  // Iceberg REST Catalog Namespace Events
-  /** {@link IcebergRestCatalogEvents.BeforeCreateNamespaceEvent} */
-  public void 
onBeforeCreateNamespace(IcebergRestCatalogEvents.BeforeCreateNamespaceEvent 
event) {}
+  default void 
onBeforeListCatalogs(CatalogsServiceEvents.BeforeListCatalogsEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCreateNamespaceEvent} */
-  public void 
onAfterCreateNamespace(IcebergRestCatalogEvents.AfterCreateNamespaceEvent 
event) {}
+  default void 
onAfterListCatalogs(CatalogsServiceEvents.AfterListCatalogsEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeCreateCatalogEvent} */
-  public void 
onBeforeCreateCatalog(CatalogsServiceEvents.BeforeCreateCatalogEvent event) {}
+  // ============= Principal Events =============
 
-  /** {@link CatalogsServiceEvents.AfterCreateCatalogEvent} */
-  public void 
onAfterCreateCatalog(CatalogsServiceEvents.AfterCreateCatalogEvent event) {}
+  default void 
onBeforeCreatePrincipal(PrincipalsServiceEvents.BeforeCreatePrincipalEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeDeleteCatalogEvent} */
-  public void 
onBeforeDeleteCatalog(CatalogsServiceEvents.BeforeDeleteCatalogEvent event) {}
+  default void 
onAfterCreatePrincipal(PrincipalsServiceEvents.AfterCreatePrincipalEvent event) 
{}
 
-  /** {@link CatalogsServiceEvents.AfterDeleteCatalogEvent} */
-  public void 
onAfterDeleteCatalog(CatalogsServiceEvents.AfterDeleteCatalogEvent event) {}
+  default void 
onBeforeDeletePrincipal(PrincipalsServiceEvents.BeforeDeletePrincipalEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeGetCatalogEvent} */
-  public void onBeforeGetCatalog(CatalogsServiceEvents.BeforeGetCatalogEvent 
event) {}
+  default void 
onAfterDeletePrincipal(PrincipalsServiceEvents.AfterDeletePrincipalEvent event) 
{}
 
-  /** {@link CatalogsServiceEvents.AfterGetCatalogEvent} */
-  public void onAfterGetCatalog(CatalogsServiceEvents.AfterGetCatalogEvent 
event) {}
+  default void 
onBeforeGetPrincipal(PrincipalsServiceEvents.BeforeGetPrincipalEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeUpdateCatalogEvent} */
-  public void 
onBeforeUpdateCatalog(CatalogsServiceEvents.BeforeUpdateCatalogEvent event) {}
+  default void 
onAfterGetPrincipal(PrincipalsServiceEvents.AfterGetPrincipalEvent event) {}
 
-  /** {@link CatalogsServiceEvents.AfterUpdateCatalogEvent} */
-  public void 
onAfterUpdateCatalog(CatalogsServiceEvents.AfterUpdateCatalogEvent event) {}
+  default void 
onBeforeUpdatePrincipal(PrincipalsServiceEvents.BeforeUpdatePrincipalEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeListCatalogEvent} */
-  public void onBeforeListCatalog(CatalogsServiceEvents.BeforeListCatalogEvent 
event) {}
+  default void 
onAfterUpdatePrincipal(PrincipalsServiceEvents.AfterUpdatePrincipalEvent event) 
{}
 
-  /** {@link CatalogsServiceEvents.AfterListCatalogEvent} */
-  public void onAfterListCatalog(CatalogsServiceEvents.AfterListCatalogEvent 
event) {}
-
-  /** {@link PrincipalsServiceEvents.BeforeCreatePrincipalEvent} */
-  public void 
onBeforeCreatePrincipal(PrincipalsServiceEvents.BeforeCreatePrincipalEvent 
event) {}
-
-  /** {@link PrincipalsServiceEvents.AfterCreatePrincipalEvent} */
-  public void 
onAfterCreatePrincipal(PrincipalsServiceEvents.AfterCreatePrincipalEvent event) 
{}
+  default void onBeforeRotateCredentials(
+      PrincipalsServiceEvents.BeforeRotateCredentialsEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.BeforeDeletePrincipalEvent} */
-  public void 
onBeforeDeletePrincipal(PrincipalsServiceEvents.BeforeDeletePrincipalEvent 
event) {}
+  default void onAfterRotateCredentials(
+      PrincipalsServiceEvents.AfterRotateCredentialsEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.AfterDeletePrincipalEvent} */
-  public void 
onAfterDeletePrincipal(PrincipalsServiceEvents.AfterDeletePrincipalEvent event) 
{}
+  default void 
onBeforeListPrincipals(PrincipalsServiceEvents.BeforeListPrincipalsEvent event) 
{}
 
-  /** {@link PrincipalsServiceEvents.BeforeGetPrincipalEvent} */
-  public void 
onBeforeGetPrincipal(PrincipalsServiceEvents.BeforeGetPrincipalEvent event) {}
+  default void 
onAfterListPrincipals(PrincipalsServiceEvents.AfterListPrincipalsEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.AfterGetPrincipalEvent} */
-  public void 
onAfterGetPrincipal(PrincipalsServiceEvents.AfterGetPrincipalEvent event) {}
+  default void onBeforeResetCredentials(
+      PrincipalsServiceEvents.BeforeResetCredentialsEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.BeforeUpdatePrincipalEvent} */
-  public void 
onBeforeUpdatePrincipal(PrincipalsServiceEvents.BeforeUpdatePrincipalEvent 
event) {}
+  default void 
onAfterResetCredentials(PrincipalsServiceEvents.AfterResetCredentialsEvent 
event) {}
 
-  /** {@link PrincipalsServiceEvents.AfterUpdatePrincipalEvent} */
-  public void 
onAfterUpdatePrincipal(PrincipalsServiceEvents.AfterUpdatePrincipalEvent event) 
{}
+  default void onBeforeAssignPrincipalRole(
+      PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.BeforeRotateCredentialsEvent} */
-  public void onBeforeRotateCredentials(
-      PrincipalsServiceEvents.BeforeRotateCredentialsEvent event) {}
+  default void onAfterAssignPrincipalRole(
+      PrincipalsServiceEvents.AfterAssignPrincipalRoleEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.AfterRotateCredentialsEvent} */
-  public void 
onAfterRotateCredentials(PrincipalsServiceEvents.AfterRotateCredentialsEvent 
event) {}
+  default void onBeforeRevokePrincipalRole(
+      PrincipalsServiceEvents.BeforeRevokePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.BeforeListPrincipalsEvent} */
-  public void 
onBeforeListPrincipals(PrincipalsServiceEvents.BeforeListPrincipalsEvent event) 
{}
+  default void onAfterRevokePrincipalRole(
+      PrincipalsServiceEvents.AfterRevokePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.AfterListPrincipalsEvent} */
-  public void 
onAfterListPrincipals(PrincipalsServiceEvents.AfterListPrincipalsEvent event) {}
+  default void onBeforeListAssignedPrincipalRoles(
+      PrincipalsServiceEvents.BeforeListAssignedPrincipalRolesEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.BeforeResetCredentialsEvent} */
-  public void 
onBeforeResetCredentials(PrincipalsServiceEvents.BeforeResetCredentialsEvent 
event) {}
+  default void onAfterListAssignedPrincipalRoles(
+      PrincipalsServiceEvents.AfterListAssignedPrincipalRolesEvent event) {}
 
-  /** {@link PrincipalsServiceEvents.AfterResetCredentialsEvent} */
-  public void 
onAfterResetCredentials(PrincipalsServiceEvents.AfterResetCredentialsEvent 
event) {}
+  // ============= Principal Role Events =============
 
-  /** {@link PrincipalRolesServiceEvents.BeforeCreatePrincipalRoleEvent} */
-  public void onBeforeCreatePrincipalRole(
+  default void onBeforeCreatePrincipalRole(
       PrincipalRolesServiceEvents.BeforeCreatePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.AfterCreatePrincipalRoleEvent} */
-  public void onAfterCreatePrincipalRole(
+  default void onAfterCreatePrincipalRole(
       PrincipalRolesServiceEvents.AfterCreatePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.BeforeDeletePrincipalRoleEvent} */
-  public void onBeforeDeletePrincipalRole(
+  default void onBeforeDeletePrincipalRole(
       PrincipalRolesServiceEvents.BeforeDeletePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.AfterDeletePrincipalRoleEvent} */
-  public void onAfterDeletePrincipalRole(
+  default void onAfterDeletePrincipalRole(
       PrincipalRolesServiceEvents.AfterDeletePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.BeforeGetPrincipalRoleEvent} */
-  public void onBeforeGetPrincipalRole(
+  default void onBeforeGetPrincipalRole(
       PrincipalRolesServiceEvents.BeforeGetPrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.AfterGetPrincipalRoleEvent} */
-  public void onAfterGetPrincipalRole(
+  default void onAfterGetPrincipalRole(
       PrincipalRolesServiceEvents.AfterGetPrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.BeforeUpdatePrincipalRoleEvent} */
-  public void onBeforeUpdatePrincipalRole(
+  default void onBeforeUpdatePrincipalRole(
       PrincipalRolesServiceEvents.BeforeUpdatePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.AfterUpdatePrincipalRoleEvent} */
-  public void onAfterUpdatePrincipalRole(
+  default void onAfterUpdatePrincipalRole(
       PrincipalRolesServiceEvents.AfterUpdatePrincipalRoleEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.BeforeListPrincipalRolesEvent} */
-  public void onBeforeListPrincipalRoles(
+  default void onBeforeListPrincipalRoles(
       PrincipalRolesServiceEvents.BeforeListPrincipalRolesEvent event) {}
 
-  /** {@link PrincipalRolesServiceEvents.AfterListPrincipalRolesEvent} */
-  public void onAfterListPrincipalRoles(
+  default void onAfterListPrincipalRoles(
       PrincipalRolesServiceEvents.AfterListPrincipalRolesEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeCreateCatalogRoleEvent} */
-  public void 
onBeforeCreateCatalogRole(CatalogsServiceEvents.BeforeCreateCatalogRoleEvent 
event) {}
+  // ============= Catalog Role Events =============
 
-  /** {@link CatalogsServiceEvents.AfterCreateCatalogRoleEvent} */
-  public void 
onAfterCreateCatalogRole(CatalogsServiceEvents.AfterCreateCatalogRoleEvent 
event) {}
+  default void onBeforeCreateCatalogRole(
+      CatalogsServiceEvents.BeforeCreateCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent} */
-  public void 
onBeforeDeleteCatalogRole(CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent 
event) {}
+  default void 
onAfterCreateCatalogRole(CatalogsServiceEvents.AfterCreateCatalogRoleEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.AfterDeleteCatalogRoleEvent} */
-  public void 
onAfterDeleteCatalogRole(CatalogsServiceEvents.AfterDeleteCatalogRoleEvent 
event) {}
+  default void onBeforeDeleteCatalogRole(
+      CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeGetCatalogRoleEvent} */
-  public void 
onBeforeGetCatalogRole(CatalogsServiceEvents.BeforeGetCatalogRoleEvent event) {}
+  default void 
onAfterDeleteCatalogRole(CatalogsServiceEvents.AfterDeleteCatalogRoleEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.AfterGetCatalogRoleEvent} */
-  public void 
onAfterGetCatalogRole(CatalogsServiceEvents.AfterGetCatalogRoleEvent event) {}
+  default void 
onBeforeGetCatalogRole(CatalogsServiceEvents.BeforeGetCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent} */
-  public void 
onBeforeUpdateCatalogRole(CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent 
event) {}
+  default void 
onAfterGetCatalogRole(CatalogsServiceEvents.AfterGetCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.AfterUpdateCatalogRoleEvent} */
-  public void 
onAfterUpdateCatalogRole(CatalogsServiceEvents.AfterUpdateCatalogRoleEvent 
event) {}
+  default void onBeforeUpdateCatalogRole(
+      CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeListCatalogRolesEvent} */
-  public void 
onBeforeListCatalogRoles(CatalogsServiceEvents.BeforeListCatalogRolesEvent 
event) {}
+  default void 
onAfterUpdateCatalogRole(CatalogsServiceEvents.AfterUpdateCatalogRoleEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.AfterListCatalogRolesEvent} */
-  public void 
onAfterListCatalogRoles(CatalogsServiceEvents.AfterListCatalogRolesEvent event) 
{}
+  default void 
onBeforeListCatalogRoles(CatalogsServiceEvents.BeforeListCatalogRolesEvent 
event) {}
 
-  /** {@link PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent} */
-  public void onBeforeAssignPrincipalRole(
-      PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent event) {}
+  default void 
onAfterListCatalogRoles(CatalogsServiceEvents.AfterListCatalogRolesEvent event) 
{}
 
-  /** {@link PrincipalsServiceEvents.AfterAssignPrincipalRoleEvent} */
-  public void onAfterAssignPrincipalRole(
-      PrincipalsServiceEvents.AfterAssignPrincipalRoleEvent event) {}
-
-  /** {@link PrincipalsServiceEvents.BeforeRevokePrincipalRoleEvent} */
-  public void onBeforeRevokePrincipalRole(
-      PrincipalsServiceEvents.BeforeRevokePrincipalRoleEvent event) {}
-
-  /** {@link PrincipalsServiceEvents.AfterRevokePrincipalRoleEvent} */
-  public void onAfterRevokePrincipalRole(
-      PrincipalsServiceEvents.AfterRevokePrincipalRoleEvent event) {}
-
-  /** {@link PrincipalsServiceEvents.BeforeListAssignedPrincipalRolesEvent} */
-  public void onBeforeListAssignedPrincipalRoles(
-      PrincipalsServiceEvents.BeforeListAssignedPrincipalRolesEvent event) {}
-
-  /** {@link PrincipalsServiceEvents.AfterListAssignedPrincipalRolesEvent} */
-  public void onAfterListAssignedPrincipalRoles(
-      PrincipalsServiceEvents.AfterListAssignedPrincipalRolesEvent event) {}
-
-  /** {@link 
PrincipalRolesServiceEvents.BeforeAssignCatalogRoleToPrincipalRoleEvent} */
-  public void onBeforeAssignCatalogRoleToPrincipalRole(
+  default void onBeforeAssignCatalogRoleToPrincipalRole(
       PrincipalRolesServiceEvents.BeforeAssignCatalogRoleToPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.AfterAssignCatalogRoleToPrincipalRoleEvent} */
-  public void onAfterAssignCatalogRoleToPrincipalRole(
+  default void onAfterAssignCatalogRoleToPrincipalRole(
       PrincipalRolesServiceEvents.AfterAssignCatalogRoleToPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.BeforeRevokeCatalogRoleFromPrincipalRoleEvent} */
-  public void onBeforeRevokeCatalogRoleFromPrincipalRole(
+  default void onBeforeRevokeCatalogRoleFromPrincipalRole(
       
PrincipalRolesServiceEvents.BeforeRevokeCatalogRoleFromPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.AfterRevokeCatalogRoleFromPrincipalRoleEvent} */
-  public void onAfterRevokeCatalogRoleFromPrincipalRole(
+  default void onAfterRevokeCatalogRoleFromPrincipalRole(
       PrincipalRolesServiceEvents.AfterRevokeCatalogRoleFromPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.BeforeListAssigneePrincipalsForPrincipalRoleEvent} 
*/
-  public void onBeforeListAssigneePrincipalsForPrincipalRole(
+  default void onBeforeListAssigneePrincipalsForPrincipalRole(
       
PrincipalRolesServiceEvents.BeforeListAssigneePrincipalsForPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.AfterListAssigneePrincipalsForPrincipalRoleEvent} */
-  public void onAfterListAssigneePrincipalsForPrincipalRole(
+  default void onAfterListAssigneePrincipalsForPrincipalRole(
       
PrincipalRolesServiceEvents.AfterListAssigneePrincipalsForPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.BeforeListCatalogRolesForPrincipalRoleEvent} */
-  public void onBeforeListCatalogRolesForPrincipalRole(
+  default void onBeforeListCatalogRolesForPrincipalRole(
       PrincipalRolesServiceEvents.BeforeListCatalogRolesForPrincipalRoleEvent 
event) {}
 
-  /** {@link 
PrincipalRolesServiceEvents.AfterListCatalogRolesForPrincipalRoleEvent} */
-  public void onAfterListCatalogRolesForPrincipalRole(
+  default void onAfterListCatalogRolesForPrincipalRole(
       PrincipalRolesServiceEvents.AfterListCatalogRolesForPrincipalRoleEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeAddGrantToCatalogRoleEvent} */
-  public void onBeforeAddGrantToCatalogRole(
+  default void onBeforeAddGrantToCatalogRole(
       CatalogsServiceEvents.BeforeAddGrantToCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.AfterAddGrantToCatalogRoleEvent} */
-  public void onAfterAddGrantToCatalogRole(
+  default void onAfterAddGrantToCatalogRole(
       CatalogsServiceEvents.AfterAddGrantToCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeRevokeGrantFromCatalogRoleEvent} */
-  public void onBeforeRevokeGrantFromCatalogRole(
+  default void onBeforeRevokeGrantFromCatalogRole(
       CatalogsServiceEvents.BeforeRevokeGrantFromCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.AfterRevokeGrantFromCatalogRoleEvent} */
-  public void onAfterRevokeGrantFromCatalogRole(
+  default void onAfterRevokeGrantFromCatalogRole(
       CatalogsServiceEvents.AfterRevokeGrantFromCatalogRoleEvent event) {}
 
-  /** {@link 
CatalogsServiceEvents.BeforeListAssigneePrincipalRolesForCatalogRoleEvent} */
-  public void onBeforeListAssigneePrincipalRolesForCatalogRole(
+  default void onBeforeListAssigneePrincipalRolesForCatalogRole(
       
CatalogsServiceEvents.BeforeListAssigneePrincipalRolesForCatalogRoleEvent 
event) {}
 
-  /** {@link 
CatalogsServiceEvents.AfterListAssigneePrincipalRolesForCatalogRoleEvent} */
-  public void onAfterListAssigneePrincipalRolesForCatalogRole(
+  default void onAfterListAssigneePrincipalRolesForCatalogRole(
       CatalogsServiceEvents.AfterListAssigneePrincipalRolesForCatalogRoleEvent 
event) {}
 
-  /** {@link CatalogsServiceEvents.BeforeListGrantsForCatalogRoleEvent} */
-  public void onBeforeListGrantsForCatalogRole(
+  default void onBeforeListGrantsForCatalogRole(
       CatalogsServiceEvents.BeforeListGrantsForCatalogRoleEvent event) {}
 
-  /** {@link CatalogsServiceEvents.AfterListGrantsForCatalogRoleEvent} */
-  public void onAfterListGrantsForCatalogRole(
+  default void onAfterListGrantsForCatalogRole(
       CatalogsServiceEvents.AfterListGrantsForCatalogRoleEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeListNamespacesEvent} */
-  public void 
onBeforeListNamespaces(IcebergRestCatalogEvents.BeforeListNamespacesEvent 
event) {}
+  // ============= Iceberg REST Namespace Events =============
+
+  default void 
onBeforeCreateNamespace(IcebergRestCatalogEvents.BeforeCreateNamespaceEvent 
event) {}
+
+  default void 
onAfterCreateNamespace(IcebergRestCatalogEvents.AfterCreateNamespaceEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterListNamespacesEvent} */
-  public void 
onAfterListNamespaces(IcebergRestCatalogEvents.AfterListNamespacesEvent event) 
{}
+  default void 
onBeforeListNamespaces(IcebergRestCatalogEvents.BeforeListNamespacesEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeLoadNamespaceMetadataEvent} */
-  public void onBeforeLoadNamespaceMetadata(
+  default void 
onAfterListNamespaces(IcebergRestCatalogEvents.AfterListNamespacesEvent event) 
{}
+
+  default void onBeforeLoadNamespaceMetadata(
       IcebergRestCatalogEvents.BeforeLoadNamespaceMetadataEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterLoadNamespaceMetadataEvent} */
-  public void onAfterLoadNamespaceMetadata(
+  default void onAfterLoadNamespaceMetadata(
       IcebergRestCatalogEvents.AfterLoadNamespaceMetadataEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeCheckExistsNamespaceEvent} */
-  public void onBeforeCheckExistsNamespace(
+  default void onBeforeCheckExistsNamespace(
       IcebergRestCatalogEvents.BeforeCheckExistsNamespaceEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCheckExistsNamespaceEvent} */
-  public void onAfterCheckExistsNamespace(
+  default void onAfterCheckExistsNamespace(
       IcebergRestCatalogEvents.AfterCheckExistsNamespaceEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeDropNamespaceEvent} */
-  public void 
onBeforeDropNamespace(IcebergRestCatalogEvents.BeforeDropNamespaceEvent event) 
{}
+  default void 
onBeforeDropNamespace(IcebergRestCatalogEvents.BeforeDropNamespaceEvent event) 
{}
 
-  /** {@link IcebergRestCatalogEvents.AfterDropNamespaceEvent} */
-  public void 
onAfterDropNamespace(IcebergRestCatalogEvents.AfterDropNamespaceEvent event) {}
+  default void 
onAfterDropNamespace(IcebergRestCatalogEvents.AfterDropNamespaceEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeUpdateNamespacePropertiesEvent} */
-  public void onBeforeUpdateNamespaceProperties(
+  default void onBeforeUpdateNamespaceProperties(
       IcebergRestCatalogEvents.BeforeUpdateNamespacePropertiesEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterUpdateNamespacePropertiesEvent} */
-  public void onAfterUpdateNamespaceProperties(
+  default void onAfterUpdateNamespaceProperties(
       IcebergRestCatalogEvents.AfterUpdateNamespacePropertiesEvent event) {}
 
-  // Iceberg REST Catalog Table Events
-  /** {@link IcebergRestCatalogEvents.BeforeCreateTableEvent} */
-  public void 
onBeforeCreateTable(IcebergRestCatalogEvents.BeforeCreateTableEvent event) {}
+  // ============= Iceberg REST Table Events =============
+
+  default void 
onBeforeCreateTable(IcebergRestCatalogEvents.BeforeCreateTableEvent event) {}
+
+  default void 
onAfterCreateTable(IcebergRestCatalogEvents.AfterCreateTableEvent event) {}
+
+  default void 
onBeforeCommitTable(IcebergRestCatalogEvents.BeforeCommitTableEvent event) {}
+
+  default void 
onAfterCommitTable(IcebergRestCatalogEvents.AfterCommitTableEvent event) {}
+
+  default void 
onBeforeRefreshTable(IcebergRestCatalogEvents.BeforeRefreshTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCreateTableEvent} */
-  public void 
onAfterCreateTable(IcebergRestCatalogEvents.AfterCreateTableEvent event) {}
+  default void 
onAfterRefreshTable(IcebergRestCatalogEvents.AfterRefreshTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeListTablesEvent} */
-  public void 
onBeforeListTables(IcebergRestCatalogEvents.BeforeListTablesEvent event) {}
+  default void 
onBeforeListTables(IcebergRestCatalogEvents.BeforeListTablesEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterListTablesEvent} */
-  public void onAfterListTables(IcebergRestCatalogEvents.AfterListTablesEvent 
event) {}
+  default void onAfterListTables(IcebergRestCatalogEvents.AfterListTablesEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeLoadTableEvent} */
-  public void onBeforeLoadTable(IcebergRestCatalogEvents.BeforeLoadTableEvent 
event) {}
+  default void onBeforeLoadTable(IcebergRestCatalogEvents.BeforeLoadTableEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterLoadTableEvent} */
-  public void onAfterLoadTable(IcebergRestCatalogEvents.AfterLoadTableEvent 
event) {}
+  default void onAfterLoadTable(IcebergRestCatalogEvents.AfterLoadTableEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeCheckExistsTableEvent} */
-  public void onBeforeCheckExistsTable(
+  default void onBeforeCheckExistsTable(
       IcebergRestCatalogEvents.BeforeCheckExistsTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCheckExistsTableEvent} */
-  public void 
onAfterCheckExistsTable(IcebergRestCatalogEvents.AfterCheckExistsTableEvent 
event) {}
+  default void 
onAfterCheckExistsTable(IcebergRestCatalogEvents.AfterCheckExistsTableEvent 
event) {}
+
+  default void onBeforeDropTable(IcebergRestCatalogEvents.BeforeDropTableEvent 
event) {}
+
+  default void onAfterDropTable(IcebergRestCatalogEvents.AfterDropTableEvent 
event) {}
+
+  default void 
onBeforeRegisterTable(IcebergRestCatalogEvents.BeforeRegisterTableEvent event) 
{}
+
+  default void 
onAfterRegisterTable(IcebergRestCatalogEvents.AfterRegisterTableEvent event) {}
+
+  default void 
onBeforeRenameTable(IcebergRestCatalogEvents.BeforeRenameTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeDropTableEvent} */
-  public void onBeforeDropTable(IcebergRestCatalogEvents.BeforeDropTableEvent 
event) {}
+  default void 
onAfterRenameTable(IcebergRestCatalogEvents.AfterRenameTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterDropTableEvent} */
-  public void onAfterDropTable(IcebergRestCatalogEvents.AfterDropTableEvent 
event) {}
+  default void 
onBeforeUpdateTable(IcebergRestCatalogEvents.BeforeUpdateTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeRegisterTableEvent} */
-  public void 
onBeforeRegisterTable(IcebergRestCatalogEvents.BeforeRegisterTableEvent event) 
{}
+  default void 
onAfterUpdateTable(IcebergRestCatalogEvents.AfterUpdateTableEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterRegisterTableEvent} */
-  public void 
onAfterRegisterTable(IcebergRestCatalogEvents.AfterRegisterTableEvent event) {}
+  // ============ Iceberg REST View Events =============
 
-  /** {@link IcebergRestCatalogEvents.BeforeRenameTableEvent} */
-  public void 
onBeforeRenameTable(IcebergRestCatalogEvents.BeforeRenameTableEvent event) {}
+  default void 
onBeforeCreateView(IcebergRestCatalogEvents.BeforeCreateViewEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterRenameTableEvent} */
-  public void 
onAfterRenameTable(IcebergRestCatalogEvents.AfterRenameTableEvent event) {}
+  default void onAfterCreateView(IcebergRestCatalogEvents.AfterCreateViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeUpdateTableEvent} */
-  public void 
onBeforeUpdateTable(IcebergRestCatalogEvents.BeforeUpdateTableEvent event) {}
+  default void 
onBeforeCommitView(IcebergRestCatalogEvents.BeforeCommitViewEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterUpdateTableEvent} */
-  public void 
onAfterUpdateTable(IcebergRestCatalogEvents.AfterUpdateTableEvent event) {}
+  default void onAfterCommitView(IcebergRestCatalogEvents.AfterCommitViewEvent 
event) {}
 
-  // Iceberg REST Catalog View Events
-  /** {@link IcebergRestCatalogEvents.BeforeCreateViewEvent} */
-  public void 
onBeforeCreateView(IcebergRestCatalogEvents.BeforeCreateViewEvent event) {}
+  default void 
onBeforeRefreshView(IcebergRestCatalogEvents.BeforeRefreshViewEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCreateViewEvent} */
-  public void onAfterCreateView(IcebergRestCatalogEvents.AfterCreateViewEvent 
event) {}
+  default void 
onAfterRefreshView(IcebergRestCatalogEvents.AfterRefreshViewEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeListViewsEvent} */
-  public void onBeforeListViews(IcebergRestCatalogEvents.BeforeListViewsEvent 
event) {}
+  default void onBeforeListViews(IcebergRestCatalogEvents.BeforeListViewsEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterListViewsEvent} */
-  public void onAfterListViews(IcebergRestCatalogEvents.AfterListViewsEvent 
event) {}
+  default void onAfterListViews(IcebergRestCatalogEvents.AfterListViewsEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeLoadViewEvent} */
-  public void onBeforeLoadView(IcebergRestCatalogEvents.BeforeLoadViewEvent 
event) {}
+  default void onBeforeLoadView(IcebergRestCatalogEvents.BeforeLoadViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterLoadViewEvent} */
-  public void onAfterLoadView(IcebergRestCatalogEvents.AfterLoadViewEvent 
event) {}
+  default void onAfterLoadView(IcebergRestCatalogEvents.AfterLoadViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeCheckExistsViewEvent} */
-  public void 
onBeforeCheckExistsView(IcebergRestCatalogEvents.BeforeCheckExistsViewEvent 
event) {}
+  default void 
onBeforeCheckExistsView(IcebergRestCatalogEvents.BeforeCheckExistsViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCheckExistsViewEvent} */
-  public void 
onAfterCheckExistsView(IcebergRestCatalogEvents.AfterCheckExistsViewEvent 
event) {}
+  default void 
onAfterCheckExistsView(IcebergRestCatalogEvents.AfterCheckExistsViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeDropViewEvent} */
-  public void onBeforeDropView(IcebergRestCatalogEvents.BeforeDropViewEvent 
event) {}
+  default void onBeforeDropView(IcebergRestCatalogEvents.BeforeDropViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterDropViewEvent} */
-  public void onAfterDropView(IcebergRestCatalogEvents.AfterDropViewEvent 
event) {}
+  default void onAfterDropView(IcebergRestCatalogEvents.AfterDropViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeRenameViewEvent} */
-  public void 
onBeforeRenameView(IcebergRestCatalogEvents.BeforeRenameViewEvent event) {}
+  default void 
onBeforeRenameView(IcebergRestCatalogEvents.BeforeRenameViewEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterRenameViewEvent} */
-  public void onAfterRenameView(IcebergRestCatalogEvents.AfterRenameViewEvent 
event) {}
+  default void onAfterRenameView(IcebergRestCatalogEvents.AfterRenameViewEvent 
event) {}
 
-  /** {@link IcebergRestCatalogEvents.BeforeReplaceViewEvent} */
-  public void 
onBeforeReplaceView(IcebergRestCatalogEvents.BeforeReplaceViewEvent event) {}
+  default void 
onBeforeReplaceView(IcebergRestCatalogEvents.BeforeReplaceViewEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterReplaceViewEvent} */
-  public void 
onAfterReplaceView(IcebergRestCatalogEvents.AfterReplaceViewEvent event) {}
+  default void 
onAfterReplaceView(IcebergRestCatalogEvents.AfterReplaceViewEvent event) {}
 
-  // Iceberg REST Catalog Credential Events
-  /** {@link IcebergRestCatalogEvents.BeforeLoadCredentialsEvent} */
-  public void 
onBeforeLoadCredentials(IcebergRestCatalogEvents.BeforeLoadCredentialsEvent 
event) {}
+  // ============ Iceberg REST Credential Events =============
 
-  /** {@link IcebergRestCatalogEvents.AfterLoadCredentialsEvent} */
-  public void 
onAfterLoadCredentials(IcebergRestCatalogEvents.AfterLoadCredentialsEvent 
event) {}
+  default void 
onBeforeLoadCredentials(IcebergRestCatalogEvents.BeforeLoadCredentialsEvent 
event) {}
 
-  // Iceberg REST Catalog Transactions Events
-  /** {@link IcebergRestCatalogEvents.BeforeCommitTransactionEvent} */
-  public void onBeforeCommitTransaction(
+  default void 
onAfterLoadCredentials(IcebergRestCatalogEvents.AfterLoadCredentialsEvent 
event) {}
+
+  // ============ Iceberg REST Transaction Events =============
+
+  default void onBeforeCommitTransaction(
       IcebergRestCatalogEvents.BeforeCommitTransactionEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterCommitTransactionEvent} */
-  public void onAfterCommitTransaction(
+  default void onAfterCommitTransaction(
       IcebergRestCatalogEvents.AfterCommitTransactionEvent event) {}
 
-  // Iceberg REST Catalog Notification Events
-  /** {@link IcebergRestCatalogEvents.BeforeSendNotificationEvent} */
-  public void onBeforeSendNotification(
+  // ============ Iceberg REST Notification Events =============
+
+  default void onBeforeSendNotification(
       IcebergRestCatalogEvents.BeforeSendNotificationEvent event) {}
 
-  /** {@link IcebergRestCatalogEvents.AfterSendNotificationEvent} */
-  public void 
onAfterSendNotification(IcebergRestCatalogEvents.AfterSendNotificationEvent 
event) {}
+  default void 
onAfterSendNotification(IcebergRestCatalogEvents.AfterSendNotificationEvent 
event) {}
 
-  // Iceberg REST Catalog Configuration Events
-  /** {@link IcebergRestCatalogEvents.BeforeGetConfigEvent} */
-  public void onBeforeGetConfig(IcebergRestCatalogEvents.BeforeGetConfigEvent 
event) {}
+  // ============ Iceberg REST Configuration Events =============
 
-  /** {@link IcebergRestCatalogEvents.AfterGetConfigEvent} */
-  public void onAfterGetConfig(IcebergRestCatalogEvents.AfterGetConfigEvent 
event) {}
+  default void onBeforeGetConfig(IcebergRestCatalogEvents.BeforeGetConfigEvent 
event) {}
 
-  // Catalog Policy Service Events
-  /** {@link CatalogPolicyServiceEvents.BeforeCreatePolicyEvent} */
-  public void 
onBeforeCreatePolicy(CatalogPolicyServiceEvents.BeforeCreatePolicyEvent event) 
{}
+  default void onAfterGetConfig(IcebergRestCatalogEvents.AfterGetConfigEvent 
event) {}
 
-  /** {@link CatalogPolicyServiceEvents.AfterCreatePolicyEvent} */
-  public void 
onAfterCreatePolicy(CatalogPolicyServiceEvents.AfterCreatePolicyEvent event) {}
+  // ============= Policy Events =============
 
-  /** {@link CatalogPolicyServiceEvents.BeforeListPoliciesEvent} */
-  public void 
onBeforeListPolicies(CatalogPolicyServiceEvents.BeforeListPoliciesEvent event) 
{}
+  default void 
onBeforeCreatePolicy(CatalogPolicyServiceEvents.BeforeCreatePolicyEvent event) 
{}
 
-  /** {@link CatalogPolicyServiceEvents.AfterListPoliciesEvent} */
-  public void 
onAfterListPolicies(CatalogPolicyServiceEvents.AfterListPoliciesEvent event) {}
+  default void 
onAfterCreatePolicy(CatalogPolicyServiceEvents.AfterCreatePolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.BeforeLoadPolicyEvent} */
-  public void 
onBeforeLoadPolicy(CatalogPolicyServiceEvents.BeforeLoadPolicyEvent event) {}
+  default void 
onBeforeListPolicies(CatalogPolicyServiceEvents.BeforeListPoliciesEvent event) 
{}
 
-  /** {@link CatalogPolicyServiceEvents.AfterLoadPolicyEvent} */
-  public void 
onAfterLoadPolicy(CatalogPolicyServiceEvents.AfterLoadPolicyEvent event) {}
+  default void 
onAfterListPolicies(CatalogPolicyServiceEvents.AfterListPoliciesEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.BeforeUpdatePolicyEvent} */
-  public void 
onBeforeUpdatePolicy(CatalogPolicyServiceEvents.BeforeUpdatePolicyEvent event) 
{}
+  default void 
onBeforeLoadPolicy(CatalogPolicyServiceEvents.BeforeLoadPolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.AfterUpdatePolicyEvent} */
-  public void 
onAfterUpdatePolicy(CatalogPolicyServiceEvents.AfterUpdatePolicyEvent event) {}
+  default void 
onAfterLoadPolicy(CatalogPolicyServiceEvents.AfterLoadPolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.BeforeDropPolicyEvent} */
-  public void 
onBeforeDropPolicy(CatalogPolicyServiceEvents.BeforeDropPolicyEvent event) {}
+  default void 
onBeforeUpdatePolicy(CatalogPolicyServiceEvents.BeforeUpdatePolicyEvent event) 
{}
 
-  /** {@link CatalogPolicyServiceEvents.AfterDropPolicyEvent} */
-  public void 
onAfterDropPolicy(CatalogPolicyServiceEvents.AfterDropPolicyEvent event) {}
+  default void 
onAfterUpdatePolicy(CatalogPolicyServiceEvents.AfterUpdatePolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.BeforeAttachPolicyEvent} */
-  public void 
onBeforeAttachPolicy(CatalogPolicyServiceEvents.BeforeAttachPolicyEvent event) 
{}
+  default void 
onBeforeDropPolicy(CatalogPolicyServiceEvents.BeforeDropPolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.AfterAttachPolicyEvent} */
-  public void 
onAfterAttachPolicy(CatalogPolicyServiceEvents.AfterAttachPolicyEvent event) {}
+  default void 
onAfterDropPolicy(CatalogPolicyServiceEvents.AfterDropPolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.BeforeDetachPolicyEvent} */
-  public void 
onBeforeDetachPolicy(CatalogPolicyServiceEvents.BeforeDetachPolicyEvent event) 
{}
+  default void 
onBeforeAttachPolicy(CatalogPolicyServiceEvents.BeforeAttachPolicyEvent event) 
{}
 
-  /** {@link CatalogPolicyServiceEvents.AfterDetachPolicyEvent} */
-  public void 
onAfterDetachPolicy(CatalogPolicyServiceEvents.AfterDetachPolicyEvent event) {}
+  default void 
onAfterAttachPolicy(CatalogPolicyServiceEvents.AfterAttachPolicyEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.BeforeGetApplicablePoliciesEvent} */
-  public void onBeforeGetApplicablePolicies(
+  default void 
onBeforeDetachPolicy(CatalogPolicyServiceEvents.BeforeDetachPolicyEvent event) 
{}
+
+  default void 
onAfterDetachPolicy(CatalogPolicyServiceEvents.AfterDetachPolicyEvent event) {}
+
+  default void onBeforeGetApplicablePolicies(
       CatalogPolicyServiceEvents.BeforeGetApplicablePoliciesEvent event) {}
 
-  /** {@link CatalogPolicyServiceEvents.AfterGetApplicablePoliciesEvent} */
-  public void onAfterGetApplicablePolicies(
+  default void onAfterGetApplicablePolicies(
       CatalogPolicyServiceEvents.AfterGetApplicablePoliciesEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.BeforeCreateGenericTableEvent} */
-  public void onBeforeCreateGenericTable(
+  // ============= Generic Table Events =============
+
+  default void onBeforeCreateGenericTable(
       CatalogGenericTableServiceEvents.BeforeCreateGenericTableEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.AfterCreateGenericTableEvent} */
-  public void onAfterCreateGenericTable(
+  default void onAfterCreateGenericTable(
       CatalogGenericTableServiceEvents.AfterCreateGenericTableEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.BeforeDropGenericTableEvent} */
-  public void onBeforeDropGenericTable(
+  default void onBeforeDropGenericTable(
       CatalogGenericTableServiceEvents.BeforeDropGenericTableEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.AfterDropGenericTableEvent} */
-  public void onAfterDropGenericTable(
+  default void onAfterDropGenericTable(
       CatalogGenericTableServiceEvents.AfterDropGenericTableEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.BeforeListGenericTablesEvent} */
-  public void onBeforeListGenericTables(
+  default void onBeforeListGenericTables(
       CatalogGenericTableServiceEvents.BeforeListGenericTablesEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.AfterListGenericTablesEvent} */
-  public void onAfterListGenericTables(
+  default void onAfterListGenericTables(
       CatalogGenericTableServiceEvents.AfterListGenericTablesEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.BeforeLoadGenericTableEvent} */
-  public void onBeforeLoadGenericTable(
+  default void onBeforeLoadGenericTable(
       CatalogGenericTableServiceEvents.BeforeLoadGenericTableEvent event) {}
 
-  /** {@link CatalogGenericTableServiceEvents.AfterLoadGenericTableEvent} */
-  public void onAfterLoadGenericTable(
+  default void onAfterLoadGenericTable(
       CatalogGenericTableServiceEvents.AfterLoadGenericTableEvent event) {}
+
+  // ============= Task Execution Events =============
+
+  default void onBeforeAttemptTask(BeforeAttemptTaskEvent event) {}
+
+  default void onAfterAttemptTask(AfterAttemptTaskEvent event) {}
+
+  // ============= Rate Limiting Events =============
+
+  default void onBeforeLimitRequestRate(BeforeLimitRequestRateEvent event) {}
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisPersistenceEventListener.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisPersistenceEventListener.java
index d33727cc3..f2f0c960a 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisPersistenceEventListener.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/PolarisPersistenceEventListener.java
@@ -25,47 +25,12 @@ import org.apache.iceberg.TableMetadata;
 import org.apache.iceberg.TableMetadataParser;
 import org.apache.iceberg.catalog.TableIdentifier;
 import org.apache.polaris.core.entity.PolarisEvent;
-import org.apache.polaris.service.events.AfterAttemptTaskEvent;
-import org.apache.polaris.service.events.BeforeAttemptTaskEvent;
-import org.apache.polaris.service.events.BeforeLimitRequestRateEvent;
 import org.apache.polaris.service.events.CatalogsServiceEvents;
 import org.apache.polaris.service.events.IcebergRestCatalogEvents;
 
-public abstract class PolarisPersistenceEventListener extends 
PolarisEventListener {
+public abstract class PolarisPersistenceEventListener implements 
PolarisEventListener {
 
   // TODO: Ensure all events (except RateLimiter ones) call `processEvent`
-  @Override
-  public final void onBeforeLimitRequestRate(BeforeLimitRequestRateEvent 
event) {}
-
-  @Override
-  public void 
onBeforeCommitTable(IcebergRestCatalogEvents.BeforeCommitTableEvent event) {}
-
-  @Override
-  public void 
onAfterCommitTable(IcebergRestCatalogEvents.AfterCommitTableEvent event) {}
-
-  @Override
-  public void 
onBeforeCommitView(IcebergRestCatalogEvents.BeforeCommitViewEvent event) {}
-
-  @Override
-  public void onAfterCommitView(IcebergRestCatalogEvents.AfterCommitViewEvent 
event) {}
-
-  @Override
-  public void 
onBeforeRefreshTable(IcebergRestCatalogEvents.BeforeRefreshTableEvent event) {}
-
-  @Override
-  public void 
onAfterRefreshTable(IcebergRestCatalogEvents.AfterRefreshTableEvent event) {}
-
-  @Override
-  public void 
onBeforeRefreshView(IcebergRestCatalogEvents.BeforeRefreshViewEvent event) {}
-
-  @Override
-  public void 
onAfterRefreshView(IcebergRestCatalogEvents.AfterRefreshViewEvent event) {}
-
-  @Override
-  public void onBeforeAttemptTask(BeforeAttemptTaskEvent event) {}
-
-  @Override
-  public void onAfterAttemptTask(AfterAttemptTaskEvent event) {}
 
   @Override
   public void 
onAfterCreateTable(IcebergRestCatalogEvents.AfterCreateTableEvent event) {
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/TestPolarisEventListener.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/TestPolarisEventListener.java
index d0b9b5f92..579fe1bf9 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/TestPolarisEventListener.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/TestPolarisEventListener.java
@@ -26,22 +26,462 @@ import java.util.List;
 import org.apache.polaris.service.events.AfterAttemptTaskEvent;
 import org.apache.polaris.service.events.BeforeAttemptTaskEvent;
 import org.apache.polaris.service.events.BeforeLimitRequestRateEvent;
+import org.apache.polaris.service.events.CatalogGenericTableServiceEvents;
+import org.apache.polaris.service.events.CatalogPolicyServiceEvents;
+import org.apache.polaris.service.events.CatalogsServiceEvents;
 import org.apache.polaris.service.events.IcebergRestCatalogEvents;
 import org.apache.polaris.service.events.PolarisEvent;
+import org.apache.polaris.service.events.PrincipalRolesServiceEvents;
+import org.apache.polaris.service.events.PrincipalsServiceEvents;
 
 /** Event listener that stores all emitted events forever. Not recommended for 
use in production. */
 @ApplicationScoped
 @Identifier("test")
-public class TestPolarisEventListener extends PolarisEventListener {
+public class TestPolarisEventListener implements PolarisEventListener {
   private final List<PolarisEvent> history = new ArrayList<>();
 
   public <T> T getLatest(Class<T> type) {
-    return (T)
-        
Streams.findLast(history.stream().filter(type::isInstance)).map(type::cast).orElseThrow();
+    return Streams.findLast(history.stream().filter(type::isInstance))
+        .map(type::cast)
+        .orElseThrow();
   }
 
   @Override
-  public void onBeforeLimitRequestRate(BeforeLimitRequestRateEvent event) {
+  public void 
onBeforeCreateCatalog(CatalogsServiceEvents.BeforeCreateCatalogEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCreateCatalog(CatalogsServiceEvents.AfterCreateCatalogEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeDeleteCatalog(CatalogsServiceEvents.BeforeDeleteCatalogEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterDeleteCatalog(CatalogsServiceEvents.AfterDeleteCatalogEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeGetCatalog(CatalogsServiceEvents.BeforeGetCatalogEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterGetCatalog(CatalogsServiceEvents.AfterGetCatalogEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeUpdateCatalog(CatalogsServiceEvents.BeforeUpdateCatalogEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterUpdateCatalog(CatalogsServiceEvents.AfterUpdateCatalogEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeListCatalogs(CatalogsServiceEvents.BeforeListCatalogsEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListCatalogs(CatalogsServiceEvents.AfterListCatalogsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCreatePrincipal(PrincipalsServiceEvents.BeforeCreatePrincipalEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCreatePrincipal(PrincipalsServiceEvents.AfterCreatePrincipalEvent event) 
{
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeDeletePrincipal(PrincipalsServiceEvents.BeforeDeletePrincipalEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterDeletePrincipal(PrincipalsServiceEvents.AfterDeletePrincipalEvent event) 
{
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeGetPrincipal(PrincipalsServiceEvents.BeforeGetPrincipalEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterGetPrincipal(PrincipalsServiceEvents.AfterGetPrincipalEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeUpdatePrincipal(PrincipalsServiceEvents.BeforeUpdatePrincipalEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterUpdatePrincipal(PrincipalsServiceEvents.AfterUpdatePrincipalEvent event) 
{
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeRotateCredentials(
+      PrincipalsServiceEvents.BeforeRotateCredentialsEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterRotateCredentials(PrincipalsServiceEvents.AfterRotateCredentialsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeListPrincipals(PrincipalsServiceEvents.BeforeListPrincipalsEvent event) 
{
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterListPrincipals(PrincipalsServiceEvents.AfterListPrincipalsEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeResetCredentials(PrincipalsServiceEvents.BeforeResetCredentialsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterResetCredentials(PrincipalsServiceEvents.AfterResetCredentialsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeAssignPrincipalRole(
+      PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterAssignPrincipalRole(
+      PrincipalsServiceEvents.AfterAssignPrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeRevokePrincipalRole(
+      PrincipalsServiceEvents.BeforeRevokePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterRevokePrincipalRole(
+      PrincipalsServiceEvents.AfterRevokePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListAssignedPrincipalRoles(
+      PrincipalsServiceEvents.BeforeListAssignedPrincipalRolesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListAssignedPrincipalRoles(
+      PrincipalsServiceEvents.AfterListAssignedPrincipalRolesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeCreatePrincipalRole(
+      PrincipalRolesServiceEvents.BeforeCreatePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterCreatePrincipalRole(
+      PrincipalRolesServiceEvents.AfterCreatePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeDeletePrincipalRole(
+      PrincipalRolesServiceEvents.BeforeDeletePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterDeletePrincipalRole(
+      PrincipalRolesServiceEvents.AfterDeletePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeGetPrincipalRole(
+      PrincipalRolesServiceEvents.BeforeGetPrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterGetPrincipalRole(
+      PrincipalRolesServiceEvents.AfterGetPrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeUpdatePrincipalRole(
+      PrincipalRolesServiceEvents.BeforeUpdatePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterUpdatePrincipalRole(
+      PrincipalRolesServiceEvents.AfterUpdatePrincipalRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListPrincipalRoles(
+      PrincipalRolesServiceEvents.BeforeListPrincipalRolesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListPrincipalRoles(
+      PrincipalRolesServiceEvents.AfterListPrincipalRolesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCreateCatalogRole(CatalogsServiceEvents.BeforeCreateCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCreateCatalogRole(CatalogsServiceEvents.AfterCreateCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeDeleteCatalogRole(CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterDeleteCatalogRole(CatalogsServiceEvents.AfterDeleteCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeGetCatalogRole(CatalogsServiceEvents.BeforeGetCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterGetCatalogRole(CatalogsServiceEvents.AfterGetCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeUpdateCatalogRole(CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterUpdateCatalogRole(CatalogsServiceEvents.AfterUpdateCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeListCatalogRoles(CatalogsServiceEvents.BeforeListCatalogRolesEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterListCatalogRoles(CatalogsServiceEvents.AfterListCatalogRolesEvent event) 
{
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeAssignCatalogRoleToPrincipalRole(
+      PrincipalRolesServiceEvents.BeforeAssignCatalogRoleToPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterAssignCatalogRoleToPrincipalRole(
+      PrincipalRolesServiceEvents.AfterAssignCatalogRoleToPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeRevokeCatalogRoleFromPrincipalRole(
+      
PrincipalRolesServiceEvents.BeforeRevokeCatalogRoleFromPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterRevokeCatalogRoleFromPrincipalRole(
+      PrincipalRolesServiceEvents.AfterRevokeCatalogRoleFromPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListAssigneePrincipalsForPrincipalRole(
+      
PrincipalRolesServiceEvents.BeforeListAssigneePrincipalsForPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListAssigneePrincipalsForPrincipalRole(
+      
PrincipalRolesServiceEvents.AfterListAssigneePrincipalsForPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListCatalogRolesForPrincipalRole(
+      PrincipalRolesServiceEvents.BeforeListCatalogRolesForPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListCatalogRolesForPrincipalRole(
+      PrincipalRolesServiceEvents.AfterListCatalogRolesForPrincipalRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeAddGrantToCatalogRole(
+      CatalogsServiceEvents.BeforeAddGrantToCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterAddGrantToCatalogRole(
+      CatalogsServiceEvents.AfterAddGrantToCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeRevokeGrantFromCatalogRole(
+      CatalogsServiceEvents.BeforeRevokeGrantFromCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterRevokeGrantFromCatalogRole(
+      CatalogsServiceEvents.AfterRevokeGrantFromCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListAssigneePrincipalRolesForCatalogRole(
+      
CatalogsServiceEvents.BeforeListAssigneePrincipalRolesForCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListAssigneePrincipalRolesForCatalogRole(
+      CatalogsServiceEvents.AfterListAssigneePrincipalRolesForCatalogRoleEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListGrantsForCatalogRole(
+      CatalogsServiceEvents.BeforeListGrantsForCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListGrantsForCatalogRole(
+      CatalogsServiceEvents.AfterListGrantsForCatalogRoleEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCreateNamespace(IcebergRestCatalogEvents.BeforeCreateNamespaceEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCreateNamespace(IcebergRestCatalogEvents.AfterCreateNamespaceEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeListNamespaces(IcebergRestCatalogEvents.BeforeListNamespacesEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterListNamespaces(IcebergRestCatalogEvents.AfterListNamespacesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeLoadNamespaceMetadata(
+      IcebergRestCatalogEvents.BeforeLoadNamespaceMetadataEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterLoadNamespaceMetadata(
+      IcebergRestCatalogEvents.AfterLoadNamespaceMetadataEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeCheckExistsNamespace(
+      IcebergRestCatalogEvents.BeforeCheckExistsNamespaceEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterCheckExistsNamespace(
+      IcebergRestCatalogEvents.AfterCheckExistsNamespaceEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeDropNamespace(IcebergRestCatalogEvents.BeforeDropNamespaceEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterDropNamespace(IcebergRestCatalogEvents.AfterDropNamespaceEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeUpdateNamespaceProperties(
+      IcebergRestCatalogEvents.BeforeUpdateNamespacePropertiesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterUpdateNamespaceProperties(
+      IcebergRestCatalogEvents.AfterUpdateNamespacePropertiesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCreateTable(IcebergRestCatalogEvents.BeforeCreateTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCreateTable(IcebergRestCatalogEvents.AfterCreateTableEvent event) {
     history.add(event);
   }
 
@@ -56,22 +496,102 @@ public class TestPolarisEventListener extends 
PolarisEventListener {
   }
 
   @Override
-  public void 
onBeforeCommitView(IcebergRestCatalogEvents.BeforeCommitViewEvent event) {
+  public void 
onBeforeRefreshTable(IcebergRestCatalogEvents.BeforeRefreshTableEvent event) {
     history.add(event);
   }
 
   @Override
-  public void onAfterCommitView(IcebergRestCatalogEvents.AfterCommitViewEvent 
event) {
+  public void 
onAfterRefreshTable(IcebergRestCatalogEvents.AfterRefreshTableEvent event) {
     history.add(event);
   }
 
   @Override
-  public void 
onBeforeRefreshTable(IcebergRestCatalogEvents.BeforeRefreshTableEvent event) {
+  public void 
onBeforeListTables(IcebergRestCatalogEvents.BeforeListTablesEvent event) {
     history.add(event);
   }
 
   @Override
-  public void 
onAfterRefreshTable(IcebergRestCatalogEvents.AfterRefreshTableEvent event) {
+  public void onAfterListTables(IcebergRestCatalogEvents.AfterListTablesEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeLoadTable(IcebergRestCatalogEvents.BeforeLoadTableEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterLoadTable(IcebergRestCatalogEvents.AfterLoadTableEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCheckExistsTable(IcebergRestCatalogEvents.BeforeCheckExistsTableEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCheckExistsTable(IcebergRestCatalogEvents.AfterCheckExistsTableEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeDropTable(IcebergRestCatalogEvents.BeforeDropTableEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterDropTable(IcebergRestCatalogEvents.AfterDropTableEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeRegisterTable(IcebergRestCatalogEvents.BeforeRegisterTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterRegisterTable(IcebergRestCatalogEvents.AfterRegisterTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeRenameTable(IcebergRestCatalogEvents.BeforeRenameTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterRenameTable(IcebergRestCatalogEvents.AfterRenameTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeUpdateTable(IcebergRestCatalogEvents.BeforeUpdateTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterUpdateTable(IcebergRestCatalogEvents.AfterUpdateTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCreateView(IcebergRestCatalogEvents.BeforeCreateViewEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterCreateView(IcebergRestCatalogEvents.AfterCreateViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCommitView(IcebergRestCatalogEvents.BeforeCommitViewEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterCommitView(IcebergRestCatalogEvents.AfterCommitViewEvent 
event) {
     history.add(event);
   }
 
@@ -85,6 +605,237 @@ public class TestPolarisEventListener extends 
PolarisEventListener {
     history.add(event);
   }
 
+  @Override
+  public void onBeforeListViews(IcebergRestCatalogEvents.BeforeListViewsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListViews(IcebergRestCatalogEvents.AfterListViewsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeLoadView(IcebergRestCatalogEvents.BeforeLoadViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterLoadView(IcebergRestCatalogEvents.AfterLoadViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCheckExistsView(IcebergRestCatalogEvents.BeforeCheckExistsViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCheckExistsView(IcebergRestCatalogEvents.AfterCheckExistsViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeDropView(IcebergRestCatalogEvents.BeforeDropViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterDropView(IcebergRestCatalogEvents.AfterDropViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeRenameView(IcebergRestCatalogEvents.BeforeRenameViewEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterRenameView(IcebergRestCatalogEvents.AfterRenameViewEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeReplaceView(IcebergRestCatalogEvents.BeforeReplaceViewEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterReplaceView(IcebergRestCatalogEvents.AfterReplaceViewEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeLoadCredentials(IcebergRestCatalogEvents.BeforeLoadCredentialsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterLoadCredentials(IcebergRestCatalogEvents.AfterLoadCredentialsEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeCommitTransaction(
+      IcebergRestCatalogEvents.BeforeCommitTransactionEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCommitTransaction(IcebergRestCatalogEvents.AfterCommitTransactionEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeSendNotification(IcebergRestCatalogEvents.BeforeSendNotificationEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterSendNotification(IcebergRestCatalogEvents.AfterSendNotificationEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeGetConfig(IcebergRestCatalogEvents.BeforeGetConfigEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterGetConfig(IcebergRestCatalogEvents.AfterGetConfigEvent 
event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeCreatePolicy(CatalogPolicyServiceEvents.BeforeCreatePolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterCreatePolicy(CatalogPolicyServiceEvents.AfterCreatePolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeListPolicies(CatalogPolicyServiceEvents.BeforeListPoliciesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterListPolicies(CatalogPolicyServiceEvents.AfterListPoliciesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeLoadPolicy(CatalogPolicyServiceEvents.BeforeLoadPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterLoadPolicy(CatalogPolicyServiceEvents.AfterLoadPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeUpdatePolicy(CatalogPolicyServiceEvents.BeforeUpdatePolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterUpdatePolicy(CatalogPolicyServiceEvents.AfterUpdatePolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeDropPolicy(CatalogPolicyServiceEvents.BeforeDropPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterDropPolicy(CatalogPolicyServiceEvents.AfterDropPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeAttachPolicy(CatalogPolicyServiceEvents.BeforeAttachPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterAttachPolicy(CatalogPolicyServiceEvents.AfterAttachPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onBeforeDetachPolicy(CatalogPolicyServiceEvents.BeforeDetachPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void 
onAfterDetachPolicy(CatalogPolicyServiceEvents.AfterDetachPolicyEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeGetApplicablePolicies(
+      CatalogPolicyServiceEvents.BeforeGetApplicablePoliciesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterGetApplicablePolicies(
+      CatalogPolicyServiceEvents.AfterGetApplicablePoliciesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeCreateGenericTable(
+      CatalogGenericTableServiceEvents.BeforeCreateGenericTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterCreateGenericTable(
+      CatalogGenericTableServiceEvents.AfterCreateGenericTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeDropGenericTable(
+      CatalogGenericTableServiceEvents.BeforeDropGenericTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterDropGenericTable(
+      CatalogGenericTableServiceEvents.AfterDropGenericTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeListGenericTables(
+      CatalogGenericTableServiceEvents.BeforeListGenericTablesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterListGenericTables(
+      CatalogGenericTableServiceEvents.AfterListGenericTablesEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onBeforeLoadGenericTable(
+      CatalogGenericTableServiceEvents.BeforeLoadGenericTableEvent event) {
+    history.add(event);
+  }
+
+  @Override
+  public void onAfterLoadGenericTable(
+      CatalogGenericTableServiceEvents.AfterLoadGenericTableEvent event) {
+    history.add(event);
+  }
+
   @Override
   public void onBeforeAttemptTask(BeforeAttemptTaskEvent event) {
     history.add(event);
@@ -94,4 +845,9 @@ public class TestPolarisEventListener extends 
PolarisEventListener {
   public void onAfterAttemptTask(AfterAttemptTaskEvent event) {
     history.add(event);
   }
+
+  @Override
+  public void onBeforeLimitRequestRate(BeforeLimitRequestRateEvent event) {
+    history.add(event);
+  }
 }
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/events/listeners/PolarisEventListenerTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/events/listeners/PolarisEventListenerTest.java
new file mode 100644
index 000000000..257113d00
--- /dev/null
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/events/listeners/PolarisEventListenerTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.polaris.service.events.listeners;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Collectors;
+import org.apache.polaris.service.events.PolarisEvent;
+import org.jboss.jandex.ClassInfo;
+import org.jboss.jandex.DotName;
+import org.jboss.jandex.Index;
+import org.jboss.jandex.IndexReader;
+import org.junit.jupiter.api.Test;
+
+/** Test that PolarisEventListener interface is well-formed and consistent. */
+class PolarisEventListenerTest {
+
+  @Test
+  void testAllMethodsWellFormed() {
+    for (Method method : PolarisEventListener.class.getMethods()) {
+      assertThat(method.isDefault()).as("Method %s is not default", 
method.getName()).isTrue();
+      assertThat(method.getReturnType())
+          .as("Method %s does not return void", method.getName())
+          .isEqualTo(void.class);
+      assertThat(method.getParameters())
+          .as("Method %s does not have exactly 1 parameter", method.getName())
+          .hasSize(1);
+      Class<?> eventType = method.getParameters()[0].getType();
+      assertThat(PolarisEvent.class).isAssignableFrom(eventType);
+      String expectedMethodName =
+          "on" + 
method.getParameterTypes()[0].getSimpleName().replace("Event", "");
+      assertThat(method.getName()).isEqualTo(expectedMethodName);
+    }
+  }
+
+  @Test
+  void testAllEventTypesHandled() throws IOException {
+    Index index;
+    try (InputStream is = 
getClass().getClassLoader().getResourceAsStream("META-INF/jandex.idx")) {
+      index = new IndexReader(is).read();
+    }
+
+    // Find all classes that implement PolarisEvent
+    Set<String> eventTypes =
+        
index.getAllKnownImplementors(DotName.createSimple(PolarisEvent.class)).stream()
+            .map(ClassInfo::name)
+            .map(DotName::toString)
+            .collect(Collectors.toSet());
+
+    assertThat(eventTypes).isNotEmpty();
+
+    // Find all event types that have corresponding listener methods
+    Set<String> handledEventTypes =
+        Arrays.stream(PolarisEventListener.class.getMethods())
+            .filter(method -> method.getParameterCount() == 1)
+            .filter(method -> 
PolarisEvent.class.isAssignableFrom(method.getParameterTypes()[0]))
+            .map(method -> method.getParameterTypes()[0].getName())
+            .collect(Collectors.toSet());
+
+    // Check that all PolarisEvent implementations have corresponding listener 
methods
+    assertThat(handledEventTypes).containsAll(eventTypes);
+  }
+}
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/events/listeners/TestPolarisEventListenerTest.java
similarity index 59%
copy from 
runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
copy to 
runtime/service/src/test/java/org/apache/polaris/service/events/listeners/TestPolarisEventListenerTest.java
index c02dfe481..3d856c99a 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/events/listeners/NoOpPolarisEventListener.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/events/listeners/TestPolarisEventListenerTest.java
@@ -16,12 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
 package org.apache.polaris.service.events.listeners;
 
-import io.smallrye.common.annotation.Identifier;
-import jakarta.enterprise.context.ApplicationScoped;
+import java.lang.reflect.Method;
+import org.junit.jupiter.api.Test;
+
+class TestPolarisEventListenerTest {
 
-/** Event listener that does nothing. */
-@ApplicationScoped
-@Identifier("no-op")
-public class NoOpPolarisEventListener extends PolarisEventListener {}
+  @Test
+  @SuppressWarnings("ReturnValueIgnored")
+  void testAllMethodsOverridden() {
+    for (Method method : PolarisEventListener.class.getMethods()) {
+      try {
+        TestPolarisEventListener.class.getDeclaredMethod(
+            method.getName(), method.getParameterTypes());
+      } catch (NoSuchMethodException e) {
+        throw new AssertionError(
+            "Method " + method.getName() + " is not overridden in 
TestPolarisEventListener");
+      }
+    }
+  }
+}

Reply via email to