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

yufei 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 553cb06e5 Service: Add Events for PolarisServiceImpl APIs (#2482)
553cb06e5 is described below

commit 553cb06e5dcfe1019a7f8565af13bc4ebf9e2e5b
Author: Adnan Hemani <[email protected]>
AuthorDate: Fri Sep 19 14:43:35 2025 -0700

    Service: Add Events for PolarisServiceImpl APIs (#2482)
---
 .../PolarisCatalogsEventServiceDelegator.java      |  95 +++++++--
 ...PolarisPrincipalRolesEventServiceDelegator.java |  87 ++++++--
 .../PolarisPrincipalsEventServiceDelegator.java    |  92 ++++++--
 .../polaris/service/admin/PolarisServiceImpl.java  |  36 ++--
 .../service/events/CatalogsServiceEvents.java      | 148 +++++++++++++
 .../events/PrincipalRolesServiceEvents.java        |  78 +++++++
 .../service/events/PrincipalsServiceEvents.java    |  74 +++++++
 .../events/listeners/PolarisEventListener.java     | 234 +++++++++++++++++++++
 .../listeners/PolarisPersistenceEventListener.java |  17 ++
 .../service/admin/PolarisServiceImplTest.java      |   3 +-
 .../org/apache/polaris/service/TestServices.java   |   3 +-
 11 files changed, 801 insertions(+), 66 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 76c320ae6..f84cafa04 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
@@ -26,6 +26,8 @@ import jakarta.inject.Inject;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
 import org.apache.polaris.core.admin.model.AddGrantRequest;
+import org.apache.polaris.core.admin.model.Catalog;
+import org.apache.polaris.core.admin.model.CatalogRole;
 import org.apache.polaris.core.admin.model.CreateCatalogRequest;
 import org.apache.polaris.core.admin.model.CreateCatalogRoleRequest;
 import org.apache.polaris.core.admin.model.RevokeGrantRequest;
@@ -33,29 +35,43 @@ import 
org.apache.polaris.core.admin.model.UpdateCatalogRequest;
 import org.apache.polaris.core.admin.model.UpdateCatalogRoleRequest;
 import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.admin.api.PolarisCatalogsApiService;
+import org.apache.polaris.service.events.CatalogsServiceEvents;
+import org.apache.polaris.service.events.listeners.PolarisEventListener;
 
 @Decorator
 @Priority(1000)
 public class PolarisCatalogsEventServiceDelegator implements 
PolarisCatalogsApiService {
 
   @Inject @Delegate PolarisCatalogsApiService delegate;
+  @Inject PolarisEventListener polarisEventListener;
 
   @Override
   public Response createCatalog(
       CreateCatalogRequest request, RealmContext realmContext, SecurityContext 
securityContext) {
+    // TODO: After changing the API response, we should change this to emit 
the corresponding event.
     return delegate.createCatalog(request, realmContext, securityContext);
   }
 
   @Override
   public Response deleteCatalog(
       String catalogName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.deleteCatalog(catalogName, realmContext, securityContext);
+    polarisEventListener.onBeforeDeleteCatalog(
+        new CatalogsServiceEvents.BeforeDeleteCatalogEvent(catalogName));
+    Response resp = delegate.deleteCatalog(catalogName, realmContext, 
securityContext);
+    polarisEventListener.onAfterDeleteCatalog(
+        new CatalogsServiceEvents.AfterDeleteCatalogEvent(catalogName));
+    return resp;
   }
 
   @Override
   public Response getCatalog(
       String catalogName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.getCatalog(catalogName, realmContext, securityContext);
+    polarisEventListener.onBeforeGetCatalog(
+        new CatalogsServiceEvents.BeforeGetCatalogEvent(catalogName));
+    Response resp = delegate.getCatalog(catalogName, realmContext, 
securityContext);
+    polarisEventListener.onAfterGetCatalog(
+        new CatalogsServiceEvents.AfterGetCatalogEvent((Catalog) 
resp.getEntity()));
+    return resp;
   }
 
   @Override
@@ -64,12 +80,21 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       UpdateCatalogRequest updateRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.updateCatalog(catalogName, updateRequest, realmContext, 
securityContext);
+    polarisEventListener.onBeforeUpdateCatalog(
+        new CatalogsServiceEvents.BeforeUpdateCatalogEvent(catalogName, 
updateRequest));
+    Response resp =
+        delegate.updateCatalog(catalogName, updateRequest, realmContext, 
securityContext);
+    polarisEventListener.onAfterUpdateCatalog(
+        new CatalogsServiceEvents.AfterUpdateCatalogEvent((Catalog) 
resp.getEntity()));
+    return resp;
   }
 
   @Override
   public Response listCatalogs(RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.listCatalogs(realmContext, securityContext);
+    polarisEventListener.onBeforeListCatalog(new 
CatalogsServiceEvents.BeforeListCatalogEvent());
+    Response resp = delegate.listCatalogs(realmContext, securityContext);
+    polarisEventListener.onAfterListCatalog(new 
CatalogsServiceEvents.AfterListCatalogEvent());
+    return resp;
   }
 
   @Override
@@ -78,6 +103,7 @@ public class PolarisCatalogsEventServiceDelegator implements 
PolarisCatalogsApiS
       CreateCatalogRoleRequest request,
       RealmContext realmContext,
       SecurityContext securityContext) {
+    // TODO: After changing the API response, we should change this to emit 
the corresponding event.
     return delegate.createCatalogRole(catalogName, request, realmContext, 
securityContext);
   }
 
@@ -87,7 +113,13 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       String catalogRoleName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.deleteCatalogRole(catalogName, catalogRoleName, 
realmContext, securityContext);
+    polarisEventListener.onBeforeDeleteCatalogRole(
+        new CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent(catalogName, 
catalogRoleName));
+    Response resp =
+        delegate.deleteCatalogRole(catalogName, catalogRoleName, realmContext, 
securityContext);
+    polarisEventListener.onAfterDeleteCatalogRole(
+        new CatalogsServiceEvents.AfterDeleteCatalogRoleEvent(catalogName, 
catalogRoleName));
+    return resp;
   }
 
   @Override
@@ -96,7 +128,14 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       String catalogRoleName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.getCatalogRole(catalogName, catalogRoleName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeGetCatalogRole(
+        new CatalogsServiceEvents.BeforeGetCatalogRoleEvent(catalogName, 
catalogRoleName));
+    Response resp =
+        delegate.getCatalogRole(catalogName, catalogRoleName, realmContext, 
securityContext);
+    polarisEventListener.onAfterGetCatalogRole(
+        new CatalogsServiceEvents.AfterGetCatalogRoleEvent(
+            catalogName, (CatalogRole) resp.getEntity()));
+    return resp;
   }
 
   @Override
@@ -106,14 +145,27 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       UpdateCatalogRoleRequest updateRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.updateCatalogRole(
-        catalogName, catalogRoleName, updateRequest, realmContext, 
securityContext);
+    polarisEventListener.onBeforeUpdateCatalogRole(
+        new CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent(
+            catalogName, catalogRoleName, updateRequest));
+    Response resp =
+        delegate.updateCatalogRole(
+            catalogName, catalogRoleName, updateRequest, realmContext, 
securityContext);
+    polarisEventListener.onAfterUpdateCatalogRole(
+        new CatalogsServiceEvents.AfterUpdateCatalogRoleEvent(
+            catalogName, (CatalogRole) resp.getEntity()));
+    return resp;
   }
 
   @Override
   public Response listCatalogRoles(
       String catalogName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.listCatalogRoles(catalogName, realmContext, 
securityContext);
+    polarisEventListener.onAfterListCatalogRoles(
+        new CatalogsServiceEvents.AfterListCatalogRolesEvent(catalogName));
+    Response resp = delegate.listCatalogRoles(catalogName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeListCatalogRoles(
+        new CatalogsServiceEvents.BeforeListCatalogRolesEvent(catalogName));
+    return resp;
   }
 
   @Override
@@ -123,6 +175,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       AddGrantRequest grantRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
+    // TODO: After changing the API response, we should change this to emit 
the corresponding event.
     return delegate.addGrantToCatalogRole(
         catalogName, catalogRoleName, grantRequest, realmContext, 
securityContext);
   }
@@ -135,6 +188,7 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       RevokeGrantRequest grantRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
+    // TODO: After changing the API response, we should change this to emit 
the corresponding event.
     return delegate.revokeGrantFromCatalogRole(
         catalogName, catalogRoleName, cascade, grantRequest, realmContext, 
securityContext);
   }
@@ -145,8 +199,16 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       String catalogRoleName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.listAssigneePrincipalRolesForCatalogRole(
-        catalogName, catalogRoleName, realmContext, securityContext);
+    polarisEventListener.onBeforeListAssigneePrincipalRolesForCatalogRole(
+        new 
CatalogsServiceEvents.BeforeListAssigneePrincipalRolesForCatalogRoleEvent(
+            catalogName, catalogRoleName));
+    Response resp =
+        delegate.listAssigneePrincipalRolesForCatalogRole(
+            catalogName, catalogRoleName, realmContext, securityContext);
+    polarisEventListener.onAfterListAssigneePrincipalRolesForCatalogRole(
+        new 
CatalogsServiceEvents.AfterListAssigneePrincipalRolesForCatalogRoleEvent(
+            catalogName, catalogRoleName));
+    return resp;
   }
 
   @Override
@@ -155,7 +217,14 @@ public class PolarisCatalogsEventServiceDelegator 
implements PolarisCatalogsApiS
       String catalogRoleName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.listGrantsForCatalogRole(
-        catalogName, catalogRoleName, realmContext, securityContext);
+    polarisEventListener.onBeforeListGrantsForCatalogRole(
+        new CatalogsServiceEvents.BeforeListGrantsForCatalogRoleEvent(
+            catalogName, catalogRoleName));
+    Response resp =
+        delegate.listGrantsForCatalogRole(
+            catalogName, catalogRoleName, realmContext, securityContext);
+    polarisEventListener.onAfterListGrantsForCatalogRole(
+        new 
CatalogsServiceEvents.AfterListGrantsForCatalogRoleEvent(catalogName, 
catalogRoleName));
+    return resp;
   }
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
index d473906a3..5691a489c 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalRolesEventServiceDelegator.java
@@ -27,34 +27,50 @@ import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
 import org.apache.polaris.core.admin.model.CreatePrincipalRoleRequest;
 import org.apache.polaris.core.admin.model.GrantCatalogRoleRequest;
+import org.apache.polaris.core.admin.model.PrincipalRole;
 import org.apache.polaris.core.admin.model.UpdatePrincipalRoleRequest;
 import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.admin.api.PolarisPrincipalRolesApiService;
+import org.apache.polaris.service.events.PrincipalRolesServiceEvents;
+import org.apache.polaris.service.events.listeners.PolarisEventListener;
 
 @Decorator
 @Priority(1000)
 public class PolarisPrincipalRolesEventServiceDelegator implements 
PolarisPrincipalRolesApiService {
 
   @Inject @Delegate PolarisPrincipalRolesApiService delegate;
+  @Inject PolarisEventListener polarisEventListener;
 
   @Override
   public Response createPrincipalRole(
       CreatePrincipalRoleRequest request,
       RealmContext realmContext,
       SecurityContext securityContext) {
+    // TODO: After changing the API response, we should change this to emit 
the corresponding event.
     return delegate.createPrincipalRole(request, realmContext, 
securityContext);
   }
 
   @Override
   public Response deletePrincipalRole(
       String principalRoleName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.deletePrincipalRole(principalRoleName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeDeletePrincipalRole(
+        new 
PrincipalRolesServiceEvents.BeforeDeletePrincipalRoleEvent(principalRoleName));
+    Response resp = delegate.deletePrincipalRole(principalRoleName, 
realmContext, securityContext);
+    polarisEventListener.onAfterDeletePrincipalRole(
+        new 
PrincipalRolesServiceEvents.AfterDeletePrincipalRoleEvent(principalRoleName));
+    return resp;
   }
 
   @Override
   public Response getPrincipalRole(
       String principalRoleName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.getPrincipalRole(principalRoleName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeGetPrincipalRole(
+        new 
PrincipalRolesServiceEvents.BeforeGetPrincipalRoleEvent(principalRoleName));
+    Response resp = delegate.getPrincipalRole(principalRoleName, realmContext, 
securityContext);
+    polarisEventListener.onAfterGetPrincipalRole(
+        new PrincipalRolesServiceEvents.AfterGetPrincipalRoleEvent(
+            (PrincipalRole) resp.getEntity()));
+    return resp;
   }
 
   @Override
@@ -63,13 +79,26 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
       UpdatePrincipalRoleRequest updateRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.updatePrincipalRole(
-        principalRoleName, updateRequest, realmContext, securityContext);
+    polarisEventListener.onBeforeUpdatePrincipalRole(
+        new PrincipalRolesServiceEvents.BeforeUpdatePrincipalRoleEvent(
+            principalRoleName, updateRequest));
+    Response resp =
+        delegate.updatePrincipalRole(
+            principalRoleName, updateRequest, realmContext, securityContext);
+    polarisEventListener.onAfterUpdatePrincipalRole(
+        new PrincipalRolesServiceEvents.AfterUpdatePrincipalRoleEvent(
+            (PrincipalRole) resp.getEntity()));
+    return resp;
   }
 
   @Override
   public Response listPrincipalRoles(RealmContext realmContext, 
SecurityContext securityContext) {
-    return delegate.listPrincipalRoles(realmContext, securityContext);
+    polarisEventListener.onBeforeListPrincipalRoles(
+        new PrincipalRolesServiceEvents.BeforeListPrincipalRolesEvent());
+    Response resp = delegate.listPrincipalRoles(realmContext, securityContext);
+    polarisEventListener.onAfterListPrincipalRoles(
+        new PrincipalRolesServiceEvents.AfterListPrincipalRolesEvent());
+    return resp;
   }
 
   @Override
@@ -79,8 +108,16 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
       GrantCatalogRoleRequest request,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.assignCatalogRoleToPrincipalRole(
-        principalRoleName, catalogName, request, realmContext, 
securityContext);
+    polarisEventListener.onBeforeAssignCatalogRoleToPrincipalRole(
+        new 
PrincipalRolesServiceEvents.BeforeAssignCatalogRoleToPrincipalRoleEvent(
+            principalRoleName, catalogName, 
request.getCatalogRole().getName()));
+    Response resp =
+        delegate.assignCatalogRoleToPrincipalRole(
+            principalRoleName, catalogName, request, realmContext, 
securityContext);
+    polarisEventListener.onAfterAssignCatalogRoleToPrincipalRole(
+        new 
PrincipalRolesServiceEvents.AfterAssignCatalogRoleToPrincipalRoleEvent(
+            principalRoleName, catalogName, 
request.getCatalogRole().getName()));
+    return resp;
   }
 
   @Override
@@ -90,15 +127,31 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
       String catalogRoleName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.revokeCatalogRoleFromPrincipalRole(
-        principalRoleName, catalogName, catalogRoleName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeRevokeCatalogRoleFromPrincipalRole(
+        new 
PrincipalRolesServiceEvents.BeforeRevokeCatalogRoleFromPrincipalRoleEvent(
+            principalRoleName, catalogName, catalogRoleName));
+    Response resp =
+        delegate.revokeCatalogRoleFromPrincipalRole(
+            principalRoleName, catalogName, catalogRoleName, realmContext, 
securityContext);
+    polarisEventListener.onAfterRevokeCatalogRoleFromPrincipalRole(
+        new 
PrincipalRolesServiceEvents.AfterRevokeCatalogRoleFromPrincipalRoleEvent(
+            principalRoleName, catalogName, catalogRoleName));
+    return resp;
   }
 
   @Override
   public Response listAssigneePrincipalsForPrincipalRole(
       String principalRoleName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.listAssigneePrincipalsForPrincipalRole(
-        principalRoleName, realmContext, securityContext);
+    polarisEventListener.onBeforeListAssigneePrincipalsForPrincipalRole(
+        new 
PrincipalRolesServiceEvents.BeforeListAssigneePrincipalsForPrincipalRoleEvent(
+            principalRoleName));
+    Response resp =
+        delegate.listAssigneePrincipalsForPrincipalRole(
+            principalRoleName, realmContext, securityContext);
+    polarisEventListener.onAfterListAssigneePrincipalsForPrincipalRole(
+        new 
PrincipalRolesServiceEvents.AfterListAssigneePrincipalsForPrincipalRoleEvent(
+            principalRoleName));
+    return resp;
   }
 
   @Override
@@ -107,7 +160,15 @@ public class PolarisPrincipalRolesEventServiceDelegator 
implements PolarisPrinci
       String catalogName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.listCatalogRolesForPrincipalRole(
-        principalRoleName, catalogName, realmContext, securityContext);
+    polarisEventListener.onBeforeListCatalogRolesForPrincipalRole(
+        new 
PrincipalRolesServiceEvents.BeforeListCatalogRolesForPrincipalRoleEvent(
+            principalRoleName, catalogName));
+    Response resp =
+        delegate.listCatalogRolesForPrincipalRole(
+            principalRoleName, catalogName, realmContext, securityContext);
+    polarisEventListener.onAfterListCatalogRolesForPrincipalRole(
+        new 
PrincipalRolesServiceEvents.AfterListCatalogRolesForPrincipalRoleEvent(
+            principalRoleName, catalogName));
+    return resp;
   }
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
index 34bc132c0..fbef82a45 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisPrincipalsEventServiceDelegator.java
@@ -27,21 +27,32 @@ import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
 import org.apache.polaris.core.admin.model.CreatePrincipalRequest;
 import org.apache.polaris.core.admin.model.GrantPrincipalRoleRequest;
+import org.apache.polaris.core.admin.model.Principal;
+import org.apache.polaris.core.admin.model.PrincipalWithCredentials;
 import org.apache.polaris.core.admin.model.ResetPrincipalRequest;
 import org.apache.polaris.core.admin.model.UpdatePrincipalRequest;
 import org.apache.polaris.core.context.RealmContext;
 import org.apache.polaris.service.admin.api.PolarisPrincipalsApiService;
+import org.apache.polaris.service.events.PrincipalsServiceEvents;
+import org.apache.polaris.service.events.listeners.PolarisEventListener;
 
 @Decorator
 @Priority(1000)
 public class PolarisPrincipalsEventServiceDelegator implements 
PolarisPrincipalsApiService {
 
   @Inject @Delegate PolarisPrincipalsApiService delegate;
+  @Inject PolarisEventListener polarisEventListener;
 
   @Override
   public Response createPrincipal(
       CreatePrincipalRequest request, RealmContext realmContext, 
SecurityContext securityContext) {
-    return delegate.createPrincipal(request, realmContext, securityContext);
+    polarisEventListener.onBeforeCreatePrincipal(
+        new 
PrincipalsServiceEvents.BeforeCreatePrincipalEvent(request.getPrincipal().getName()));
+    Response resp = delegate.createPrincipal(request, realmContext, 
securityContext);
+    polarisEventListener.onAfterCreatePrincipal(
+        new PrincipalsServiceEvents.AfterCreatePrincipalEvent(
+            ((PrincipalWithCredentials) resp.getEntity()).getPrincipal()));
+    return resp;
   }
 
   @Override
@@ -50,20 +61,37 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
       ResetPrincipalRequest resetPrincipalRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.resetCredentials(
-        principalName, resetPrincipalRequest, realmContext, securityContext);
+    polarisEventListener.onBeforeResetCredentials(
+        new 
PrincipalsServiceEvents.BeforeResetCredentialsEvent(principalName));
+    Response resp =
+        delegate.resetCredentials(
+            principalName, resetPrincipalRequest, realmContext, 
securityContext);
+    polarisEventListener.onAfterResetCredentials(
+        new PrincipalsServiceEvents.AfterResetCredentialsEvent(
+            ((PrincipalWithCredentials) resp.getEntity()).getPrincipal()));
+    return resp;
   }
 
   @Override
   public Response deletePrincipal(
       String principalName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.deletePrincipal(principalName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeDeletePrincipal(
+        new PrincipalsServiceEvents.BeforeDeletePrincipalEvent(principalName));
+    Response resp = delegate.deletePrincipal(principalName, realmContext, 
securityContext);
+    polarisEventListener.onAfterDeletePrincipal(
+        new PrincipalsServiceEvents.AfterDeletePrincipalEvent(principalName));
+    return resp;
   }
 
   @Override
   public Response getPrincipal(
       String principalName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.getPrincipal(principalName, realmContext, securityContext);
+    polarisEventListener.onBeforeGetPrincipal(
+        new PrincipalsServiceEvents.BeforeGetPrincipalEvent(principalName));
+    Response resp = delegate.getPrincipal(principalName, realmContext, 
securityContext);
+    polarisEventListener.onAfterGetPrincipal(
+        new PrincipalsServiceEvents.AfterGetPrincipalEvent((Principal) 
resp.getEntity()));
+    return resp;
   }
 
   @Override
@@ -72,18 +100,36 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
       UpdatePrincipalRequest updateRequest,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.updatePrincipal(principalName, updateRequest, 
realmContext, securityContext);
+    polarisEventListener.onBeforeUpdatePrincipal(
+        new PrincipalsServiceEvents.BeforeUpdatePrincipalEvent(principalName, 
updateRequest));
+    Response resp =
+        delegate.updatePrincipal(principalName, updateRequest, realmContext, 
securityContext);
+    polarisEventListener.onAfterUpdatePrincipal(
+        new PrincipalsServiceEvents.AfterUpdatePrincipalEvent((Principal) 
resp.getEntity()));
+    return resp;
   }
 
   @Override
   public Response rotateCredentials(
       String principalName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.rotateCredentials(principalName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeRotateCredentials(
+        new 
PrincipalsServiceEvents.BeforeRotateCredentialsEvent(principalName));
+    Response resp = delegate.rotateCredentials(principalName, realmContext, 
securityContext);
+    PrincipalWithCredentials principalWithCredentials = 
(PrincipalWithCredentials) resp.getEntity();
+    polarisEventListener.onAfterRotateCredentials(
+        new PrincipalsServiceEvents.AfterRotateCredentialsEvent(
+            principalWithCredentials.getPrincipal()));
+    return resp;
   }
 
   @Override
   public Response listPrincipals(RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.listPrincipals(realmContext, securityContext);
+    polarisEventListener.onBeforeListPrincipals(
+        new PrincipalsServiceEvents.BeforeListPrincipalsEvent());
+    Response resp = delegate.listPrincipals(realmContext, securityContext);
+    polarisEventListener.onAfterListPrincipals(
+        new PrincipalsServiceEvents.AfterListPrincipalsEvent());
+    return resp;
   }
 
   @Override
@@ -92,7 +138,15 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
       GrantPrincipalRoleRequest request,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.assignPrincipalRole(principalName, request, realmContext, 
securityContext);
+    polarisEventListener.onBeforeAssignPrincipalRole(
+        new PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent(
+            principalName, request.getPrincipalRole()));
+    Response resp =
+        delegate.assignPrincipalRole(principalName, request, realmContext, 
securityContext);
+    polarisEventListener.onAfterAssignPrincipalRole(
+        new PrincipalsServiceEvents.AfterAssignPrincipalRoleEvent(
+            principalName, request.getPrincipalRole()));
+    return resp;
   }
 
   @Override
@@ -101,13 +155,27 @@ public class PolarisPrincipalsEventServiceDelegator 
implements PolarisPrincipals
       String principalRoleName,
       RealmContext realmContext,
       SecurityContext securityContext) {
-    return delegate.revokePrincipalRole(
-        principalName, principalRoleName, realmContext, securityContext);
+    polarisEventListener.onBeforeRevokePrincipalRole(
+        new PrincipalsServiceEvents.BeforeRevokePrincipalRoleEvent(
+            principalName, principalRoleName));
+    Response resp =
+        delegate.revokePrincipalRole(
+            principalName, principalRoleName, realmContext, securityContext);
+    polarisEventListener.onAfterRevokePrincipalRole(
+        new PrincipalsServiceEvents.AfterRevokePrincipalRoleEvent(
+            principalName, principalRoleName));
+    return resp;
   }
 
   @Override
   public Response listPrincipalRolesAssigned(
       String principalName, RealmContext realmContext, SecurityContext 
securityContext) {
-    return delegate.listPrincipalRolesAssigned(principalName, realmContext, 
securityContext);
+    polarisEventListener.onBeforeListAssignedPrincipalRoles(
+        new 
PrincipalsServiceEvents.BeforeListAssignedPrincipalRolesEvent(principalName));
+    Response resp =
+        delegate.listPrincipalRolesAssigned(principalName, realmContext, 
securityContext);
+    polarisEventListener.onAfterListAssignedPrincipalRoles(
+        new 
PrincipalsServiceEvents.AfterListAssignedPrincipalRolesEvent(principalName));
+    return resp;
   }
 }
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java
index 48ad7027e..81df76ada 100644
--- 
a/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/admin/PolarisServiceImpl.java
@@ -76,7 +76,6 @@ import 
org.apache.polaris.service.admin.api.PolarisCatalogsApiService;
 import org.apache.polaris.service.admin.api.PolarisPrincipalRolesApiService;
 import org.apache.polaris.service.admin.api.PolarisPrincipalsApiService;
 import org.apache.polaris.service.config.ReservedProperties;
-import org.apache.polaris.service.events.listeners.PolarisEventListener;
 import org.apache.polaris.service.types.PolicyIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -90,18 +89,15 @@ public class PolarisServiceImpl
   private static final Logger LOGGER = 
LoggerFactory.getLogger(PolarisServiceImpl.class);
   private final RealmConfig realmConfig;
   private final ReservedProperties reservedProperties;
-  private final PolarisEventListener polarisEventListener;
   private final PolarisAdminService adminService;
 
   @Inject
   public PolarisServiceImpl(
       RealmConfig realmConfig,
       ReservedProperties reservedProperties,
-      PolarisEventListener polarisEventListener,
       PolarisAdminService adminService) {
     this.realmConfig = realmConfig;
     this.reservedProperties = reservedProperties;
-    this.polarisEventListener = polarisEventListener;
     this.adminService = adminService;
   }
 
@@ -573,13 +569,13 @@ public class PolarisServiceImpl
         catalogRoleName,
         catalogName);
     PrivilegeResult result;
+    PolarisPrivilege privilege;
     switch (grantRequest.getGrant()) {
       // The per-securable-type Privilege enums must be exact String match for 
a subset of all
       // PolarisPrivilege values.
       case ViewGrant viewGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(viewGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(viewGrant.getPrivilege().toString());
           String viewName = viewGrant.getViewName();
           String[] namespaceParts = viewGrant.getNamespace().toArray(new 
String[0]);
           result =
@@ -592,8 +588,7 @@ public class PolarisServiceImpl
         }
       case TableGrant tableGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(tableGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(tableGrant.getPrivilege().toString());
           String tableName = tableGrant.getTableName();
           String[] namespaceParts = tableGrant.getNamespace().toArray(new 
String[0]);
           result =
@@ -606,8 +601,7 @@ public class PolarisServiceImpl
         }
       case NamespaceGrant namespaceGrant:
         {
-          PolarisPrivilege privilege =
-              
PolarisPrivilege.valueOf(namespaceGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(namespaceGrant.getPrivilege().toString());
           String[] namespaceParts = namespaceGrant.getNamespace().toArray(new 
String[0]);
           result =
               adminService.grantPrivilegeOnNamespaceToRole(
@@ -616,16 +610,14 @@ public class PolarisServiceImpl
         }
       case CatalogGrant catalogGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(catalogGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(catalogGrant.getPrivilege().toString());
           result =
               adminService.grantPrivilegeOnCatalogToRole(catalogName, 
catalogRoleName, privilege);
           break;
         }
       case PolicyGrant policyGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(policyGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(policyGrant.getPrivilege().toString());
           String policyName = policyGrant.getPolicyName();
           String[] namespaceParts = policyGrant.getNamespace().toArray(new 
String[0]);
           result =
@@ -667,13 +659,13 @@ public class PolarisServiceImpl
     }
 
     PrivilegeResult result;
+    PolarisPrivilege privilege;
     switch (grantRequest.getGrant()) {
       // The per-securable-type Privilege enums must be exact String match for 
a subset of all
       // PolarisPrivilege values.
       case ViewGrant viewGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(viewGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(viewGrant.getPrivilege().toString());
           String viewName = viewGrant.getViewName();
           String[] namespaceParts = viewGrant.getNamespace().toArray(new 
String[0]);
           result =
@@ -686,8 +678,7 @@ public class PolarisServiceImpl
         }
       case TableGrant tableGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(tableGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(tableGrant.getPrivilege().toString());
           String tableName = tableGrant.getTableName();
           String[] namespaceParts = tableGrant.getNamespace().toArray(new 
String[0]);
           result =
@@ -700,8 +691,7 @@ public class PolarisServiceImpl
         }
       case NamespaceGrant namespaceGrant:
         {
-          PolarisPrivilege privilege =
-              
PolarisPrivilege.valueOf(namespaceGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(namespaceGrant.getPrivilege().toString());
           String[] namespaceParts = namespaceGrant.getNamespace().toArray(new 
String[0]);
           result =
               adminService.revokePrivilegeOnNamespaceFromRole(
@@ -710,8 +700,7 @@ public class PolarisServiceImpl
         }
       case CatalogGrant catalogGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(catalogGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(catalogGrant.getPrivilege().toString());
           result =
               adminService.revokePrivilegeOnCatalogFromRole(
                   catalogName, catalogRoleName, privilege);
@@ -719,8 +708,7 @@ public class PolarisServiceImpl
         }
       case PolicyGrant policyGrant:
         {
-          PolarisPrivilege privilege =
-              PolarisPrivilege.valueOf(policyGrant.getPrivilege().toString());
+          privilege = 
PolarisPrivilege.valueOf(policyGrant.getPrivilege().toString());
           String policyName = policyGrant.getPolicyName();
           String[] namespaceParts = policyGrant.getNamespace().toArray(new 
String[0]);
           result =
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
new file mode 100644
index 000000000..6242d91c3
--- /dev/null
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/CatalogsServiceEvents.java
@@ -0,0 +1,148 @@
+/*
+ * 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;
+
+import org.apache.polaris.core.admin.model.AddGrantRequest;
+import org.apache.polaris.core.admin.model.Catalog;
+import org.apache.polaris.core.admin.model.CatalogRole;
+import org.apache.polaris.core.admin.model.GrantResource;
+import org.apache.polaris.core.admin.model.RevokeGrantRequest;
+import org.apache.polaris.core.admin.model.UpdateCatalogRequest;
+import org.apache.polaris.core.admin.model.UpdateCatalogRoleRequest;
+import org.apache.polaris.core.entity.PolarisPrivilege;
+
+public class CatalogsServiceEvents {
+  public record BeforeCreateCatalogEvent(String catalogName) implements 
PolarisEvent {}
+
+  public record AfterCreateCatalogEvent(Catalog catalog) implements 
PolarisEvent {}
+
+  public record BeforeDeleteCatalogEvent(String catalogName) implements 
PolarisEvent {}
+
+  public record AfterDeleteCatalogEvent(String catalogName) implements 
PolarisEvent {}
+
+  public record BeforeGetCatalogEvent(String catalogName) implements 
PolarisEvent {}
+
+  public record AfterGetCatalogEvent(Catalog catalog) implements PolarisEvent 
{}
+
+  public record BeforeUpdateCatalogEvent(String catalogName, 
UpdateCatalogRequest updateRequest)
+      implements PolarisEvent {}
+
+  public record AfterUpdateCatalogEvent(Catalog catalog) implements 
PolarisEvent {}
+
+  public record BeforeListCatalogEvent() implements PolarisEvent {}
+
+  public record AfterListCatalogEvent() implements PolarisEvent {}
+
+  public record BeforeCreateCatalogRoleEvent(String catalogName, String 
catalogRoleName)
+      implements PolarisEvent {}
+
+  public record AfterCreateCatalogRoleEvent(String catalogName, CatalogRole 
catalogRole)
+      implements PolarisEvent {}
+
+  public record BeforeDeleteCatalogRoleEvent(String catalogName, String 
catalogRoleName)
+      implements PolarisEvent {}
+
+  public record AfterDeleteCatalogRoleEvent(String catalogName, String 
catalogRoleName)
+      implements PolarisEvent {}
+
+  public record BeforeGetCatalogRoleEvent(String catalogName, String 
catalogRoleName)
+      implements PolarisEvent {}
+
+  public record AfterGetCatalogRoleEvent(String catalogName, CatalogRole 
catalogRole)
+      implements PolarisEvent {}
+
+  public record BeforeUpdateCatalogRoleEvent(
+      String catalogName, String catalogRoleName, UpdateCatalogRoleRequest 
updateRequest)
+      implements PolarisEvent {}
+
+  public record AfterUpdateCatalogRoleEvent(String catalogName, CatalogRole 
updatedCatalogRole)
+      implements PolarisEvent {}
+
+  public record BeforeListCatalogRolesEvent(String catalogName) implements 
PolarisEvent {}
+
+  public record AfterListCatalogRolesEvent(String catalogName) implements 
PolarisEvent {}
+
+  /**
+   * Event fired before a grant is added to a catalog role in Polaris.
+   *
+   * @param catalogName the name of the catalog
+   * @param catalogRoleName the name of the catalog role
+   * @param grantRequest the grant request
+   */
+  public record BeforeAddGrantToCatalogRoleEvent(
+      String catalogName, String catalogRoleName, AddGrantRequest grantRequest)
+      implements PolarisEvent {}
+
+  /**
+   * Event fired after a grant is added to a catalog role in Polaris.
+   *
+   * @param catalogName the name of the catalog
+   * @param catalogRoleName the name of the catalog role
+   * @param privilege the privilege granted
+   * @param grantResource the grant resource
+   */
+  public record AfterAddGrantToCatalogRoleEvent(
+      String catalogName,
+      String catalogRoleName,
+      PolarisPrivilege privilege,
+      GrantResource grantResource)
+      implements PolarisEvent {}
+
+  /**
+   * Event fired before a grant is revoked from a catalog role in Polaris.
+   *
+   * @param catalogName the name of the catalog
+   * @param catalogRoleName the name of the catalog role
+   * @param grantRequest the revoke grant request
+   * @param cascade whether the revoke is cascading
+   */
+  public record BeforeRevokeGrantFromCatalogRoleEvent(
+      String catalogName, String catalogRoleName, RevokeGrantRequest 
grantRequest, Boolean cascade)
+      implements PolarisEvent {}
+
+  /**
+   * Event fired after a grant is revoked from a catalog role in Polaris.
+   *
+   * @param catalogName the name of the catalog
+   * @param catalogRoleName the name of the catalog role
+   * @param privilege the privilege revoked
+   * @param grantResource the revoke grant resource
+   * @param cascade whether to cascade the revocation
+   */
+  public record AfterRevokeGrantFromCatalogRoleEvent(
+      String catalogName,
+      String catalogRoleName,
+      PolarisPrivilege privilege,
+      GrantResource grantResource,
+      Boolean cascade)
+      implements PolarisEvent {}
+
+  public record BeforeListAssigneePrincipalRolesForCatalogRoleEvent(
+      String catalogName, String catalogRoleName) implements PolarisEvent {}
+
+  public record AfterListAssigneePrincipalRolesForCatalogRoleEvent(
+      String catalogName, String catalogRoleName) implements PolarisEvent {}
+
+  public record BeforeListGrantsForCatalogRoleEvent(String catalogName, String 
catalogRoleName)
+      implements PolarisEvent {}
+
+  public record AfterListGrantsForCatalogRoleEvent(String catalogName, String 
catalogRoleName)
+      implements PolarisEvent {}
+}
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/PrincipalRolesServiceEvents.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/PrincipalRolesServiceEvents.java
new file mode 100644
index 000000000..932893cfe
--- /dev/null
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/PrincipalRolesServiceEvents.java
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+import org.apache.polaris.core.admin.model.CreatePrincipalRoleRequest;
+import org.apache.polaris.core.admin.model.PrincipalRole;
+import org.apache.polaris.core.admin.model.UpdatePrincipalRoleRequest;
+
+public class PrincipalRolesServiceEvents {
+  public record AfterCreatePrincipalRoleEvent(PrincipalRole principalRole)
+      implements PolarisEvent {}
+
+  public record BeforeCreatePrincipalRoleEvent(
+      CreatePrincipalRoleRequest createPrincipalRoleRequest) implements 
PolarisEvent {}
+
+  public record AfterDeletePrincipalRoleEvent(String principalRoleName) 
implements PolarisEvent {}
+
+  public record BeforeDeletePrincipalRoleEvent(String principalRoleName) 
implements PolarisEvent {}
+
+  public record AfterGetPrincipalRoleEvent(PrincipalRole principalRole) 
implements PolarisEvent {}
+
+  public record BeforeGetPrincipalRoleEvent(String principalRoleName) 
implements PolarisEvent {}
+
+  public record AfterUpdatePrincipalRoleEvent(PrincipalRole 
updatedPrincipalRole)
+      implements PolarisEvent {}
+
+  public record BeforeUpdatePrincipalRoleEvent(
+      String principalRoleName, UpdatePrincipalRoleRequest updateRequest) 
implements PolarisEvent {}
+
+  public record AfterListPrincipalRolesEvent() implements PolarisEvent {}
+
+  public record BeforeListPrincipalRolesEvent() implements PolarisEvent {}
+
+  public record AfterAssignCatalogRoleToPrincipalRoleEvent(
+      String principalRoleName, String catalogName, String catalogRoleName)
+      implements PolarisEvent {}
+
+  public record BeforeAssignCatalogRoleToPrincipalRoleEvent(
+      String principalRoleName, String catalogName, String catalogRoleName)
+      implements PolarisEvent {}
+
+  public record AfterRevokeCatalogRoleFromPrincipalRoleEvent(
+      String principalRoleName, String catalogName, String catalogRoleName)
+      implements PolarisEvent {}
+
+  public record BeforeRevokeCatalogRoleFromPrincipalRoleEvent(
+      String principalRoleName, String catalogName, String catalogRoleName)
+      implements PolarisEvent {}
+
+  public record AfterListAssigneePrincipalsForPrincipalRoleEvent(String 
principalRoleName)
+      implements PolarisEvent {}
+
+  public record BeforeListAssigneePrincipalsForPrincipalRoleEvent(String 
principalRoleName)
+      implements PolarisEvent {}
+
+  public record AfterListCatalogRolesForPrincipalRoleEvent(
+      String principalRoleName, String catalogName) implements PolarisEvent {}
+
+  public record BeforeListCatalogRolesForPrincipalRoleEvent(
+      String principalRoleName, String catalogName) implements PolarisEvent {}
+}
diff --git 
a/runtime/service/src/main/java/org/apache/polaris/service/events/PrincipalsServiceEvents.java
 
b/runtime/service/src/main/java/org/apache/polaris/service/events/PrincipalsServiceEvents.java
new file mode 100644
index 000000000..add87652a
--- /dev/null
+++ 
b/runtime/service/src/main/java/org/apache/polaris/service/events/PrincipalsServiceEvents.java
@@ -0,0 +1,74 @@
+/*
+ * 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;
+
+import org.apache.polaris.core.admin.model.Principal;
+import org.apache.polaris.core.admin.model.PrincipalRole;
+import org.apache.polaris.core.admin.model.UpdatePrincipalRequest;
+
+public class PrincipalsServiceEvents {
+  public record AfterCreatePrincipalEvent(Principal principal) implements 
PolarisEvent {}
+
+  public record BeforeCreatePrincipalEvent(String principalName) implements 
PolarisEvent {}
+
+  public record AfterDeletePrincipalEvent(String principalName) implements 
PolarisEvent {}
+
+  public record BeforeDeletePrincipalEvent(String principalName) implements 
PolarisEvent {}
+
+  public record AfterGetPrincipalEvent(Principal principal) implements 
PolarisEvent {}
+
+  public record BeforeGetPrincipalEvent(String principalName) implements 
PolarisEvent {}
+
+  public record AfterUpdatePrincipalEvent(Principal principal) implements 
PolarisEvent {}
+
+  public record BeforeUpdatePrincipalEvent(
+      String principalName, UpdatePrincipalRequest updatePrincipalRequest)
+      implements PolarisEvent {}
+
+  public record AfterRotateCredentialsEvent(Principal rotatedPrincipal) 
implements PolarisEvent {}
+
+  public record BeforeRotateCredentialsEvent(String principalName) implements 
PolarisEvent {}
+
+  public record AfterListPrincipalsEvent() implements PolarisEvent {}
+
+  public record BeforeListPrincipalsEvent() implements PolarisEvent {}
+
+  public record AfterAssignPrincipalRoleEvent(String principalName, 
PrincipalRole principalRole)
+      implements PolarisEvent {}
+
+  public record BeforeAssignPrincipalRoleEvent(String principalName, 
PrincipalRole principalRole)
+      implements PolarisEvent {}
+
+  public record AfterRevokePrincipalRoleEvent(String principalName, String 
principalRoleName)
+      implements PolarisEvent {}
+
+  public record BeforeRevokePrincipalRoleEvent(String principalName, String 
principalRoleName)
+      implements PolarisEvent {}
+
+  public record AfterListAssignedPrincipalRolesEvent(String principalName)
+      implements PolarisEvent {}
+
+  public record BeforeListAssignedPrincipalRolesEvent(String principalName)
+      implements PolarisEvent {}
+
+  public record BeforeResetCredentialsEvent(String principalName) implements 
PolarisEvent {}
+
+  public record AfterResetCredentialsEvent(Principal principal) implements 
PolarisEvent {}
+}
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 20dc304d0..4ad7e642f 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
@@ -23,7 +23,10 @@ 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.PrincipalRolesServiceEvents;
+import org.apache.polaris.service.events.PrincipalsServiceEvents;
 
 /**
  * Represents an event listener that can respond to notable moments during 
Polaris's execution.
@@ -70,6 +73,237 @@ public abstract class PolarisEventListener {
   /** {@link IcebergRestCatalogEvents.AfterCreateNamespaceEvent} */
   public void 
onAfterCreateNamespace(IcebergRestCatalogEvents.AfterCreateNamespaceEvent 
event) {}
 
+  /** {@link CatalogsServiceEvents.BeforeCreateCatalogEvent} */
+  public void 
onBeforeCreateCatalog(CatalogsServiceEvents.BeforeCreateCatalogEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterCreateCatalogEvent} */
+  public void 
onAfterCreateCatalog(CatalogsServiceEvents.AfterCreateCatalogEvent event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeDeleteCatalogEvent} */
+  public void 
onBeforeDeleteCatalog(CatalogsServiceEvents.BeforeDeleteCatalogEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterDeleteCatalogEvent} */
+  public void 
onAfterDeleteCatalog(CatalogsServiceEvents.AfterDeleteCatalogEvent event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeGetCatalogEvent} */
+  public void onBeforeGetCatalog(CatalogsServiceEvents.BeforeGetCatalogEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.AfterGetCatalogEvent} */
+  public void onAfterGetCatalog(CatalogsServiceEvents.AfterGetCatalogEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeUpdateCatalogEvent} */
+  public void 
onBeforeUpdateCatalog(CatalogsServiceEvents.BeforeUpdateCatalogEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterUpdateCatalogEvent} */
+  public void 
onAfterUpdateCatalog(CatalogsServiceEvents.AfterUpdateCatalogEvent event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeListCatalogEvent} */
+  public void onBeforeListCatalog(CatalogsServiceEvents.BeforeListCatalogEvent 
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) 
{}
+
+  /** {@link PrincipalsServiceEvents.BeforeDeletePrincipalEvent} */
+  public void 
onBeforeDeletePrincipal(PrincipalsServiceEvents.BeforeDeletePrincipalEvent 
event) {}
+
+  /** {@link PrincipalsServiceEvents.AfterDeletePrincipalEvent} */
+  public void 
onAfterDeletePrincipal(PrincipalsServiceEvents.AfterDeletePrincipalEvent event) 
{}
+
+  /** {@link PrincipalsServiceEvents.BeforeGetPrincipalEvent} */
+  public void 
onBeforeGetPrincipal(PrincipalsServiceEvents.BeforeGetPrincipalEvent event) {}
+
+  /** {@link PrincipalsServiceEvents.AfterGetPrincipalEvent} */
+  public void 
onAfterGetPrincipal(PrincipalsServiceEvents.AfterGetPrincipalEvent event) {}
+
+  /** {@link PrincipalsServiceEvents.BeforeUpdatePrincipalEvent} */
+  public void 
onBeforeUpdatePrincipal(PrincipalsServiceEvents.BeforeUpdatePrincipalEvent 
event) {}
+
+  /** {@link PrincipalsServiceEvents.AfterUpdatePrincipalEvent} */
+  public void 
onAfterUpdatePrincipal(PrincipalsServiceEvents.AfterUpdatePrincipalEvent event) 
{}
+
+  /** {@link PrincipalsServiceEvents.BeforeRotateCredentialsEvent} */
+  public void onBeforeRotateCredentials(
+      PrincipalsServiceEvents.BeforeRotateCredentialsEvent event) {}
+
+  /** {@link PrincipalsServiceEvents.AfterRotateCredentialsEvent} */
+  public void 
onAfterRotateCredentials(PrincipalsServiceEvents.AfterRotateCredentialsEvent 
event) {}
+
+  /** {@link PrincipalsServiceEvents.BeforeListPrincipalsEvent} */
+  public void 
onBeforeListPrincipals(PrincipalsServiceEvents.BeforeListPrincipalsEvent event) 
{}
+
+  /** {@link PrincipalsServiceEvents.AfterListPrincipalsEvent} */
+  public void 
onAfterListPrincipals(PrincipalsServiceEvents.AfterListPrincipalsEvent event) {}
+
+  /** {@link PrincipalsServiceEvents.BeforeResetCredentialsEvent} */
+  public void 
onBeforeResetCredentials(PrincipalsServiceEvents.BeforeResetCredentialsEvent 
event) {}
+
+  /** {@link PrincipalsServiceEvents.AfterResetCredentialsEvent} */
+  public void 
onAfterResetCredentials(PrincipalsServiceEvents.AfterResetCredentialsEvent 
event) {}
+
+  /** {@link PrincipalRolesServiceEvents.BeforeCreatePrincipalRoleEvent} */
+  public void onBeforeCreatePrincipalRole(
+      PrincipalRolesServiceEvents.BeforeCreatePrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.AfterCreatePrincipalRoleEvent} */
+  public void onAfterCreatePrincipalRole(
+      PrincipalRolesServiceEvents.AfterCreatePrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.BeforeDeletePrincipalRoleEvent} */
+  public void onBeforeDeletePrincipalRole(
+      PrincipalRolesServiceEvents.BeforeDeletePrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.AfterDeletePrincipalRoleEvent} */
+  public void onAfterDeletePrincipalRole(
+      PrincipalRolesServiceEvents.AfterDeletePrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.BeforeGetPrincipalRoleEvent} */
+  public void onBeforeGetPrincipalRole(
+      PrincipalRolesServiceEvents.BeforeGetPrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.AfterGetPrincipalRoleEvent} */
+  public void onAfterGetPrincipalRole(
+      PrincipalRolesServiceEvents.AfterGetPrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.BeforeUpdatePrincipalRoleEvent} */
+  public void onBeforeUpdatePrincipalRole(
+      PrincipalRolesServiceEvents.BeforeUpdatePrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.AfterUpdatePrincipalRoleEvent} */
+  public void onAfterUpdatePrincipalRole(
+      PrincipalRolesServiceEvents.AfterUpdatePrincipalRoleEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.BeforeListPrincipalRolesEvent} */
+  public void onBeforeListPrincipalRoles(
+      PrincipalRolesServiceEvents.BeforeListPrincipalRolesEvent event) {}
+
+  /** {@link PrincipalRolesServiceEvents.AfterListPrincipalRolesEvent} */
+  public void onAfterListPrincipalRoles(
+      PrincipalRolesServiceEvents.AfterListPrincipalRolesEvent event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeCreateCatalogRoleEvent} */
+  public void 
onBeforeCreateCatalogRole(CatalogsServiceEvents.BeforeCreateCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.AfterCreateCatalogRoleEvent} */
+  public void 
onAfterCreateCatalogRole(CatalogsServiceEvents.AfterCreateCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent} */
+  public void 
onBeforeDeleteCatalogRole(CatalogsServiceEvents.BeforeDeleteCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.AfterDeleteCatalogRoleEvent} */
+  public void 
onAfterDeleteCatalogRole(CatalogsServiceEvents.AfterDeleteCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeGetCatalogRoleEvent} */
+  public void 
onBeforeGetCatalogRole(CatalogsServiceEvents.BeforeGetCatalogRoleEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterGetCatalogRoleEvent} */
+  public void 
onAfterGetCatalogRole(CatalogsServiceEvents.AfterGetCatalogRoleEvent event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent} */
+  public void 
onBeforeUpdateCatalogRole(CatalogsServiceEvents.BeforeUpdateCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.AfterUpdateCatalogRoleEvent} */
+  public void 
onAfterUpdateCatalogRole(CatalogsServiceEvents.AfterUpdateCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeListCatalogRolesEvent} */
+  public void 
onBeforeListCatalogRoles(CatalogsServiceEvents.BeforeListCatalogRolesEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.AfterListCatalogRolesEvent} */
+  public void 
onAfterListCatalogRoles(CatalogsServiceEvents.AfterListCatalogRolesEvent event) 
{}
+
+  /** {@link PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent} */
+  public void onBeforeAssignPrincipalRole(
+      PrincipalsServiceEvents.BeforeAssignPrincipalRoleEvent 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(
+      PrincipalRolesServiceEvents.BeforeAssignCatalogRoleToPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.AfterAssignCatalogRoleToPrincipalRoleEvent} */
+  public void onAfterAssignCatalogRoleToPrincipalRole(
+      PrincipalRolesServiceEvents.AfterAssignCatalogRoleToPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.BeforeRevokeCatalogRoleFromPrincipalRoleEvent} */
+  public void onBeforeRevokeCatalogRoleFromPrincipalRole(
+      
PrincipalRolesServiceEvents.BeforeRevokeCatalogRoleFromPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.AfterRevokeCatalogRoleFromPrincipalRoleEvent} */
+  public void onAfterRevokeCatalogRoleFromPrincipalRole(
+      PrincipalRolesServiceEvents.AfterRevokeCatalogRoleFromPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.BeforeListAssigneePrincipalsForPrincipalRoleEvent} 
*/
+  public void onBeforeListAssigneePrincipalsForPrincipalRole(
+      
PrincipalRolesServiceEvents.BeforeListAssigneePrincipalsForPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.AfterListAssigneePrincipalsForPrincipalRoleEvent} */
+  public void onAfterListAssigneePrincipalsForPrincipalRole(
+      
PrincipalRolesServiceEvents.AfterListAssigneePrincipalsForPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.BeforeListCatalogRolesForPrincipalRoleEvent} */
+  public void onBeforeListCatalogRolesForPrincipalRole(
+      PrincipalRolesServiceEvents.BeforeListCatalogRolesForPrincipalRoleEvent 
event) {}
+
+  /** {@link 
PrincipalRolesServiceEvents.AfterListCatalogRolesForPrincipalRoleEvent} */
+  public void onAfterListCatalogRolesForPrincipalRole(
+      PrincipalRolesServiceEvents.AfterListCatalogRolesForPrincipalRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeAddGrantToCatalogRoleEvent} */
+  public void onBeforeAddGrantToCatalogRole(
+      CatalogsServiceEvents.BeforeAddGrantToCatalogRoleEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterAddGrantToCatalogRoleEvent} */
+  public void onAfterAddGrantToCatalogRole(
+      CatalogsServiceEvents.AfterAddGrantToCatalogRoleEvent event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeRevokeGrantFromCatalogRoleEvent} */
+  public void onBeforeRevokeGrantFromCatalogRole(
+      CatalogsServiceEvents.BeforeRevokeGrantFromCatalogRoleEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterRevokeGrantFromCatalogRoleEvent} */
+  public void onAfterRevokeGrantFromCatalogRole(
+      CatalogsServiceEvents.AfterRevokeGrantFromCatalogRoleEvent event) {}
+
+  /** {@link 
CatalogsServiceEvents.BeforeListAssigneePrincipalRolesForCatalogRoleEvent} */
+  public void onBeforeListAssigneePrincipalRolesForCatalogRole(
+      
CatalogsServiceEvents.BeforeListAssigneePrincipalRolesForCatalogRoleEvent 
event) {}
+
+  /** {@link 
CatalogsServiceEvents.AfterListAssigneePrincipalRolesForCatalogRoleEvent} */
+  public void onAfterListAssigneePrincipalRolesForCatalogRole(
+      CatalogsServiceEvents.AfterListAssigneePrincipalRolesForCatalogRoleEvent 
event) {}
+
+  /** {@link CatalogsServiceEvents.BeforeListGrantsForCatalogRoleEvent} */
+  public void onBeforeListGrantsForCatalogRole(
+      CatalogsServiceEvents.BeforeListGrantsForCatalogRoleEvent event) {}
+
+  /** {@link CatalogsServiceEvents.AfterListGrantsForCatalogRoleEvent} */
+  public void onAfterListGrantsForCatalogRole(
+      CatalogsServiceEvents.AfterListGrantsForCatalogRoleEvent event) {}
+
   /** {@link IcebergRestCatalogEvents.BeforeListNamespacesEvent} */
   public void 
onBeforeListNamespaces(IcebergRestCatalogEvents.BeforeListNamespacesEvent 
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 11771797a..d33727cc3 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
@@ -28,6 +28,7 @@ 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 {
@@ -90,6 +91,22 @@ public abstract class PolarisPersistenceEventListener 
extends PolarisEventListen
     processEvent(polarisEvent);
   }
 
+  @Override
+  public void 
onAfterCreateCatalog(CatalogsServiceEvents.AfterCreateCatalogEvent event) {
+    ContextSpecificInformation contextSpecificInformation = 
getContextSpecificInformation();
+    PolarisEvent polarisEvent =
+        new PolarisEvent(
+            event.catalog().getName(),
+            org.apache.polaris.service.events.PolarisEvent.createEventId(),
+            getRequestId(),
+            event.getClass().getSimpleName(),
+            contextSpecificInformation.timestamp(),
+            contextSpecificInformation.principalName(),
+            PolarisEvent.ResourceType.CATALOG,
+            event.catalog().getName());
+    processEvent(polarisEvent);
+  }
+
   public record ContextSpecificInformation(long timestamp, @Nullable String 
principalName) {}
 
   protected abstract ContextSpecificInformation 
getContextSpecificInformation();
diff --git 
a/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java
 
b/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java
index 4f474457d..926c6c89c 100644
--- 
a/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java
+++ 
b/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisServiceImplTest.java
@@ -96,8 +96,7 @@ public class PolarisServiceImplTest {
             securityContext,
             polarisAuthorizer,
             reservedProperties);
-    polarisService =
-        new PolarisServiceImpl(realmConfig, reservedProperties, 
polarisEventListener, adminService);
+    polarisService = new PolarisServiceImpl(realmConfig, reservedProperties, 
adminService);
   }
 
   @Test
diff --git 
a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
 
b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
index 89fcf893b..89a27307d 100644
--- 
a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
+++ 
b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java
@@ -292,8 +292,7 @@ public record TestServices(
               reservedProperties);
       PolarisCatalogsApi catalogsApi =
           new PolarisCatalogsApi(
-              new PolarisServiceImpl(
-                  realmConfig, reservedProperties, polarisEventListener, 
adminService));
+              new PolarisServiceImpl(realmConfig, reservedProperties, 
adminService));
 
       return new TestServices(
           clock,

Reply via email to