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

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


The following commit(s) were added to refs/heads/main by this push:
     new 6cbf907e9a [#6741] feat(core): Support group event to Gravitino server 
(#6801)
6cbf907e9a is described below

commit 6cbf907e9ac2c32349208ab1bd6c2ed36c29abe9
Author: Lord of Abyss <[email protected]>
AuthorDate: Wed Apr 2 08:39:06 2025 +0800

    [#6741] feat(core): Support group event to Gravitino server (#6801)
    
    ### What changes were proposed in this pull request?
    
    Support group event to Gravitino server.
    
    ### Why are the changes needed?
    
    Fix: #6741
    
    ### Does this PR introduce _any_ user-facing change?
    
    Users can now listen for the User Event.
    
    ### How was this patch tested?
    
    local test.
---
 .../api/event/AccessControlEventDispatcher.java    |  64 +++++--
 .../{AddGroupPreEvent.java => AddGroupEvent.java}  |  35 ++--
 .../listener/api/event/AddGroupPreEvent.java       |  18 +-
 .../{GetGroupPreEvent.java => GetGroupEvent.java}  |  35 ++--
 .../listener/api/event/GetGroupPreEvent.java       |  18 +-
 .../listener/api/event/GrantGroupRolesEvent.java   |  77 ++++++++
 ...pPreEvent.java => GrantGroupRolesPreEvent.java} |  40 ++--
 .../{ListGroupsPreEvent.java => GroupEvent.java}   |  30 +--
 ...NamesPreEvent.java => ListGroupNamesEvent.java} |  16 +-
 .../listener/api/event/ListGroupNamesPreEvent.java |  12 +-
 ...istGroupsPreEvent.java => ListGroupsEvent.java} |  17 +-
 .../listener/api/event/ListGroupsPreEvent.java     |  14 +-
 .../listener/api/event/OperationType.java          |   2 +
 .../listener/api/event/RemoveGroupEvent.java       |  77 ++++++++
 .../listener/api/event/RemoveGroupPreEvent.java    |  19 +-
 .../listener/api/event/RevokeGroupRolesEvent.java  |  78 ++++++++
 .../api/event/RevokeGroupRolesPreEvent.java        |  75 ++++++++
 .../GroupInfo.java}                                |  40 ++--
 .../apache/gravitino/utils/NameIdentifierUtil.java |  11 ++
 .../org/apache/gravitino/utils/NamespaceUtil.java  |  10 +
 .../listener/api/event/TestGroupEvent.java         | 212 ++++++++++++++++++++-
 .../gravitino/utils/TestNameIdentifierUtil.java    |  19 +-
 .../apache/gravitino/utils/TestNamespaceUtil.java  |  24 +++
 docs/gravitino-server-config.md                    |   8 +-
 24 files changed, 795 insertions(+), 156 deletions(-)

diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AccessControlEventDispatcher.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/AccessControlEventDispatcher.java
index 9004f7fa70..2cb3bcd8fb 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AccessControlEventDispatcher.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/AccessControlEventDispatcher.java
@@ -23,7 +23,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import org.apache.gravitino.MetadataObject;
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.authorization.AccessControlDispatcher;
 import org.apache.gravitino.authorization.Group;
 import org.apache.gravitino.authorization.Privilege;
@@ -40,6 +39,7 @@ import org.apache.gravitino.exceptions.NoSuchUserException;
 import org.apache.gravitino.exceptions.RoleAlreadyExistsException;
 import org.apache.gravitino.exceptions.UserAlreadyExistsException;
 import org.apache.gravitino.listener.EventBus;
+import org.apache.gravitino.listener.api.info.GroupInfo;
 import org.apache.gravitino.listener.api.info.UserInfo;
 import org.apache.gravitino.utils.PrincipalUtils;
 
@@ -155,11 +155,14 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
   @Override
   public Group addGroup(String metalake, String group)
       throws GroupAlreadyExistsException, NoSuchMetalakeException {
+    String initiator = PrincipalUtils.getCurrentUserName();
+
+    eventBus.dispatchEvent(new AddGroupPreEvent(initiator, metalake, group));
     try {
-      String initiator = PrincipalUtils.getCurrentUserName();
+      Group groupObject = dispatcher.addGroup(metalake, group);
+      eventBus.dispatchEvent(new AddGroupEvent(initiator, metalake, new 
GroupInfo(groupObject)));
 
-      eventBus.dispatchEvent(new AddGroupPreEvent(initiator, 
NameIdentifier.of(metalake), group));
-      return dispatcher.addGroup(metalake, group);
+      return groupObject;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
@@ -169,12 +172,14 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
   /** {@inheritDoc} */
   @Override
   public boolean removeGroup(String metalake, String group) throws 
NoSuchMetalakeException {
+    String initiator = PrincipalUtils.getCurrentUserName();
+
+    eventBus.dispatchEvent(new RemoveGroupPreEvent(initiator, metalake, 
group));
     try {
-      String initiator = PrincipalUtils.getCurrentUserName();
+      boolean isExists = dispatcher.removeGroup(metalake, group);
+      eventBus.dispatchEvent(new RemoveGroupEvent(initiator, metalake, group, 
isExists));
 
-      eventBus.dispatchEvent(
-          new RemoveGroupPreEvent(initiator, NameIdentifier.of(metalake), 
group));
-      return dispatcher.removeGroup(metalake, group);
+      return isExists;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
@@ -187,9 +192,12 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
       throws NoSuchGroupException, NoSuchMetalakeException {
     String initiator = PrincipalUtils.getCurrentUserName();
 
-    eventBus.dispatchEvent(new GetGroupPreEvent(initiator, 
NameIdentifier.of(metalake), group));
+    eventBus.dispatchEvent(new GetGroupPreEvent(initiator, metalake, group));
     try {
-      return dispatcher.getGroup(metalake, group);
+      Group groupObject = dispatcher.getGroup(metalake, group);
+      eventBus.dispatchEvent(new GetGroupEvent(initiator, metalake, new 
GroupInfo(groupObject)));
+
+      return groupObject;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
@@ -201,10 +209,12 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
   public Group[] listGroups(String metalake) {
     String initiator = PrincipalUtils.getCurrentUserName();
 
-    eventBus.dispatchEvent(new ListGroupsPreEvent(initiator, 
NameIdentifier.of(metalake)));
+    eventBus.dispatchEvent(new ListGroupsPreEvent(initiator, metalake));
     try {
-      // TODO: add Event
-      return dispatcher.listGroups(metalake);
+      Group[] groups = dispatcher.listGroups(metalake);
+      eventBus.dispatchEvent(new ListGroupsEvent(initiator, metalake));
+
+      return groups;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
@@ -216,10 +226,12 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
   public String[] listGroupNames(String metalake) {
     String initiator = PrincipalUtils.getCurrentUserName();
 
-    eventBus.dispatchEvent(new ListGroupNamesPreEvent(initiator, 
NameIdentifier.of(metalake)));
+    eventBus.dispatchEvent(new ListGroupNamesPreEvent(initiator, metalake));
     try {
-      // TODO: add Event
-      return dispatcher.listGroupNames(metalake);
+      String[] groupNames = dispatcher.listGroupNames(metalake);
+      eventBus.dispatchEvent(new ListGroupNamesEvent(initiator, metalake));
+
+      return groupNames;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
@@ -249,9 +261,15 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
   @Override
   public Group grantRolesToGroup(String metalake, List<String> roles, String 
group)
       throws NoSuchGroupException, IllegalRoleException, 
NoSuchMetalakeException {
+    String initiator = PrincipalUtils.getCurrentUserName();
+
+    eventBus.dispatchEvent(new GrantGroupRolesPreEvent(initiator, metalake, 
group, roles));
     try {
-      // TODO: add Event
-      return dispatcher.grantRolesToGroup(metalake, roles, group);
+      Group groupObject = dispatcher.grantRolesToGroup(metalake, roles, group);
+      eventBus.dispatchEvent(
+          new GrantGroupRolesEvent(initiator, metalake, new 
GroupInfo(groupObject), roles));
+
+      return groupObject;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
@@ -262,9 +280,15 @@ public class AccessControlEventDispatcher implements 
AccessControlDispatcher {
   @Override
   public Group revokeRolesFromGroup(String metalake, List<String> roles, 
String group)
       throws NoSuchGroupException, IllegalRoleException, 
NoSuchMetalakeException {
+    String initiator = PrincipalUtils.getCurrentUserName();
+
+    eventBus.dispatchEvent(new RevokeGroupRolesPreEvent(initiator, metalake, 
group, roles));
     try {
-      // TODO: add Event
-      return dispatcher.revokeRolesFromGroup(metalake, roles, group);
+      Group groupObject = dispatcher.revokeRolesFromGroup(metalake, roles, 
group);
+      eventBus.dispatchEvent(
+          new RevokeGroupRolesEvent(initiator, metalake, new 
GroupInfo(groupObject), roles));
+
+      return groupObject;
     } catch (Exception e) {
       // TODO: add failure event
       throw e;
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
 b/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupEvent.java
similarity index 51%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
copy to 
core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupEvent.java
index 85594ef31a..248111915f 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupEvent.java
@@ -19,41 +19,42 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.listener.api.info.GroupInfo;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before add a group to a metalake. */
+/** Represents an event triggered when a group is successfully added to a 
metalake. */
 @DeveloperApi
-public class AddGroupPreEvent extends GroupPreEvent {
-  private final String groupName;
+public class AddGroupEvent extends GroupEvent {
+  private final GroupInfo addedGroupInfo;
 
   /**
-   * Construct a new {@link AddGroupPreEvent} instance with the given 
initiator, identifier and
-   * group name.
+   * Constructs a new {@link AddGroupEvent} with the specified initiator, 
metalake name, and group
+   * information.
    *
    * @param initiator the user who initiated the add-group request.
-   * @param identifier the identifier of the metalake which the group is being 
added to.
-   * @param groupName the group name which is requested to be added to the 
metalake.
+   * @param metalake the name of the metalake where the group was added.
+   * @param addedGroupInfo the information about the group that was added.
    */
-  protected AddGroupPreEvent(String initiator, NameIdentifier identifier, 
String groupName) {
-    super(initiator, identifier);
+  protected AddGroupEvent(String initiator, String metalake, GroupInfo 
addedGroupInfo) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, 
addedGroupInfo.name()));
 
-    this.groupName = groupName;
+    this.addedGroupInfo = addedGroupInfo;
   }
 
   /**
-   * Returns the group information which is being added to the metalake.
+   * Retrieves the {@link GroupInfo} of the group that was added to the 
metalake.
    *
-   * @return the group name which is requested to be added to the metalake.
+   * @return the {@link GroupInfo} object containing details of the added 
group.
    */
-  public String groupName() {
-    return groupName;
+  public GroupInfo addedGroupInfo() {
+    return addedGroupInfo;
   }
 
   /**
-   * Returns the operation type of this event.
+   * Returns the operation type for this event.
    *
-   * @return the operation type.
+   * @return the operation type for this event.
    */
   @Override
   public OperationType operationType() {
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
index 85594ef31a..f0a8df36ee 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
@@ -19,32 +19,32 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before add a group to a metalake. */
+/** Represents an event triggered before a group is added to a metalake. */
 @DeveloperApi
 public class AddGroupPreEvent extends GroupPreEvent {
   private final String groupName;
 
   /**
-   * Construct a new {@link AddGroupPreEvent} instance with the given 
initiator, identifier and
+   * Constructs a new {@link AddGroupPreEvent} with the specified initiator, 
metalake name, and
    * group name.
    *
    * @param initiator the user who initiated the add-group request.
-   * @param identifier the identifier of the metalake which the group is being 
added to.
-   * @param groupName the group name which is requested to be added to the 
metalake.
+   * @param metalake the name of the metalake where the group is to be added.
+   * @param groupName the name of the group that is requested to be added to 
the metalake.
    */
-  protected AddGroupPreEvent(String initiator, NameIdentifier identifier, 
String groupName) {
-    super(initiator, identifier);
+  protected AddGroupPreEvent(String initiator, String metalake, String 
groupName) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, groupName));
 
     this.groupName = groupName;
   }
 
   /**
-   * Returns the group information which is being added to the metalake.
+   * Retrieves the name of the group that is being requested to be added to 
the metalake.
    *
-   * @return the group name which is requested to be added to the metalake.
+   * @return the name of the group to be added.
    */
   public String groupName() {
     return groupName;
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
 b/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupEvent.java
similarity index 51%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
copy to 
core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupEvent.java
index ea09c34d85..05c7d54e43 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupEvent.java
@@ -19,35 +19,38 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.listener.api.info.GroupInfo;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before get a group from specific metalake */
+/**
+ * Represents an event triggered after a group is successfully retrieved from 
a specific metalake.
+ */
 @DeveloperApi
-public class GetGroupPreEvent extends GroupPreEvent {
-  private final String groupName;
+public class GetGroupEvent extends GroupEvent {
+  private final GroupInfo loadedGroupInfo;
 
   /**
-   * Construct a new {@link GetGroupPreEvent} instance with the given 
initiator and identifier and
-   * group name.
+   * Constructs a new {@link GetGroupEvent} with the specified initiator, 
metalake name, and group
+   * information.
    *
-   * @param initiator the user who initiated the get-group request.
-   * @param identifier the identifier of the metalake which the group is 
getting retrieved from.
-   * @param groupName the group name which is requested to be retrieved.
+   * @param initiator the user who initiated the group retrieval request.
+   * @param metalake the name of the metalake from which the group is 
retrieved.
+   * @param loadedGroupInfo the information of the group that was retrieved.
    */
-  protected GetGroupPreEvent(String initiator, NameIdentifier identifier, 
String groupName) {
-    super(initiator, identifier);
+  protected GetGroupEvent(String initiator, String metalake, GroupInfo 
loadedGroupInfo) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, 
loadedGroupInfo.name()));
 
-    this.groupName = groupName;
+    this.loadedGroupInfo = loadedGroupInfo;
   }
 
   /**
-   * Returns the group info for the group which is getting retrieved.
+   * Retrieves the {@link GroupInfo} of the group that was successfully 
retrieved from the metalake.
    *
-   * @return the group name which is requested to be retrieved.
+   * @return the {@link GroupInfo} object containing details of the retrieved 
group.
    */
-  public String groupName() {
-    return groupName;
+  public GroupInfo loadedGroupInfo() {
+    return loadedGroupInfo;
   }
 
   /**
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
index ea09c34d85..fbc67fc0ea 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GetGroupPreEvent.java
@@ -19,32 +19,32 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before get a group from specific metalake */
+/** Represents an event triggered before a group is retrieved from a specific 
metalake. */
 @DeveloperApi
 public class GetGroupPreEvent extends GroupPreEvent {
   private final String groupName;
 
   /**
-   * Construct a new {@link GetGroupPreEvent} instance with the given 
initiator and identifier and
+   * Constructs a new {@link GetGroupPreEvent} with the specified initiator, 
metalake name, and
    * group name.
    *
    * @param initiator the user who initiated the get-group request.
-   * @param identifier the identifier of the metalake which the group is 
getting retrieved from.
-   * @param groupName the group name which is requested to be retrieved.
+   * @param metalake the name of the metalake from which the group is being 
retrieved.
+   * @param groupName the name of the group that is requested to be retrieved.
    */
-  protected GetGroupPreEvent(String initiator, NameIdentifier identifier, 
String groupName) {
-    super(initiator, identifier);
+  protected GetGroupPreEvent(String initiator, String metalake, String 
groupName) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, groupName));
 
     this.groupName = groupName;
   }
 
   /**
-   * Returns the group info for the group which is getting retrieved.
+   * Retrieves the name of the group that is being requested to be retrieved.
    *
-   * @return the group name which is requested to be retrieved.
+   * @return the name of the group to be retrieved.
    */
   public String groupName() {
     return groupName;
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/GrantGroupRolesEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GrantGroupRolesEvent.java
new file mode 100644
index 0000000000..04c754ed02
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GrantGroupRolesEvent.java
@@ -0,0 +1,77 @@
+/*
+ * 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.gravitino.listener.api.event;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.listener.api.info.GroupInfo;
+import org.apache.gravitino.utils.NameIdentifierUtil;
+
+/** Represents an event triggered after roles are granted to a group. */
+@DeveloperApi
+public class GrantGroupRolesEvent extends GroupEvent {
+  private final GroupInfo grantedGroupInfo;
+  private final List<String> roles;
+
+  /**
+   * Constructs a new {@link GrantGroupRolesEvent} with the specified 
initiator, metalake name,
+   * group information, and granted roles.
+   *
+   * @param initiator the user who initiated the role-granting operation.
+   * @param metalake the name of the metalake where the operation takes place.
+   * @param grantedGroupInfo the group information of the group to which roles 
are granted.
+   * @param roles the list of roles granted to the group.
+   */
+  public GrantGroupRolesEvent(
+      String initiator, String metalake, GroupInfo grantedGroupInfo, 
List<String> roles) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, 
grantedGroupInfo.name()));
+    this.grantedGroupInfo = grantedGroupInfo;
+    this.roles = roles == null ? null : ImmutableList.copyOf(roles);
+  }
+
+  /**
+   * Retrieves the {@link GroupInfo} of the group to which roles have been 
granted.
+   *
+   * @return the {@link GroupInfo} instance containing the details of the 
granted group.
+   */
+  public GroupInfo grantedGroupInfo() {
+    return grantedGroupInfo;
+  }
+
+  /**
+   * Returns the list of roles that have been granted to the group.
+   *
+   * @return the list of roles granted to the group.
+   */
+  public List<String> roles() {
+    return roles;
+  }
+
+  /**
+   * Returns the operation type of this event.
+   *
+   * @return the operation type.
+   */
+  @Override
+  public OperationType operationType() {
+    return OperationType.GRANT_GROUP_ROLES;
+  }
+}
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GrantGroupRolesPreEvent.java
similarity index 50%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
copy to 
core/src/main/java/org/apache/gravitino/listener/api/event/GrantGroupRolesPreEvent.java
index 85594ef31a..3777d1695c 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/AddGroupPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/GrantGroupRolesPreEvent.java
@@ -19,37 +19,51 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
+import java.util.List;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before add a group to a metalake. */
+/** Represents an event triggered before roles are granted to a group. */
 @DeveloperApi
-public class AddGroupPreEvent extends GroupPreEvent {
+public class GrantGroupRolesPreEvent extends GroupPreEvent {
   private final String groupName;
+  private final List<String> roles;
 
   /**
-   * Construct a new {@link AddGroupPreEvent} instance with the given 
initiator, identifier and
-   * group name.
+   * Constructs a new {@link GrantGroupRolesPreEvent} with the specified 
initiator, metalake name,
+   * group name, and roles to be granted.
    *
-   * @param initiator the user who initiated the add-group request.
-   * @param identifier the identifier of the metalake which the group is being 
added to.
-   * @param groupName the group name which is requested to be added to the 
metalake.
+   * @param initiator the user who initiated the role-granting event.
+   * @param metalake the name of the metalake where the operation will be 
performed.
+   * @param groupName the name of the group to which roles will be granted.
+   * @param roles the list of roles to be granted to the group.
    */
-  protected AddGroupPreEvent(String initiator, NameIdentifier identifier, 
String groupName) {
-    super(initiator, identifier);
+  public GrantGroupRolesPreEvent(
+      String initiator, String metalake, String groupName, List<String> roles) 
{
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, groupName));
 
     this.groupName = groupName;
+    this.roles = roles;
   }
 
   /**
-   * Returns the group information which is being added to the metalake.
+   * Retrieves the name of the group to which roles will be granted.
    *
-   * @return the group name which is requested to be added to the metalake.
+   * @return the name of the group.
    */
   public String groupName() {
     return groupName;
   }
 
+  /**
+   * Returns the list of roles that are being granted to the group.
+   *
+   * @return the list of roles to be granted.
+   */
+  public List<String> roles() {
+    return roles;
+  }
+
   /**
    * Returns the operation type of this event.
    *
@@ -57,6 +71,6 @@ public class AddGroupPreEvent extends GroupPreEvent {
    */
   @Override
   public OperationType operationType() {
-    return OperationType.ADD_GROUP;
+    return OperationType.GRANT_GROUP_ROLES;
   }
 }
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
 b/core/src/main/java/org/apache/gravitino/listener/api/event/GroupEvent.java
similarity index 52%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
copy to 
core/src/main/java/org/apache/gravitino/listener/api/event/GroupEvent.java
index 4461a04a03..1d9e2e2410 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
+++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GroupEvent.java
@@ -22,26 +22,30 @@ package org.apache.gravitino.listener.api.event;
 import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
 
-/** Represents an event triggered before list groups from specific metalake */
+/**
+ * Represents an abstract base class for events related to group operations. 
This class extends
+ * {@link Event} to provide a more specific context involving operations 
performed by groups. It
+ * captures essential information including the user performing the operation 
and the identifier of
+ * the metalake being operated on.
+ *
+ * <p>Concrete implementations of this class should provide additional details 
pertinent to the
+ * specific type of group operation being represented.
+ */
 @DeveloperApi
-public class ListGroupsPreEvent extends GroupPreEvent {
+public abstract class GroupEvent extends Event {
   /**
-   * Construct a new {@code ListGroupPreEvent} instance with the given 
initiator and identifier.
+   * Construct a new {@link GroupEvent} instance with the given initiator and 
identifier.
    *
-   * @param initiator the user who initiated the list group operation.
-   * @param identifier the identifier of the metalake which is being listed.
+   * @param initiator the user who triggered the event.
+   * @param identifier the identifier of the metalake being operated on.
    */
-  protected ListGroupsPreEvent(String initiator, NameIdentifier identifier) {
+  protected GroupEvent(String initiator, NameIdentifier identifier) {
     super(initiator, identifier);
   }
 
-  /**
-   * Returns the operation type for this event.
-   *
-   * @return the operation type for this event.
-   */
+  /** {@inheritDoc} */
   @Override
-  public OperationType operationType() {
-    return OperationType.LIST_GROUPS;
+  public OperationStatus operationStatus() {
+    return OperationStatus.SUCCESS;
   }
 }
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesEvent.java
similarity index 69%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
copy to 
core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesEvent.java
index cf0e702e21..297df5cc0a 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesEvent.java
@@ -19,19 +19,23 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before list group name from specific 
metalake */
+/**
+ * Represents an event triggered after successfully listing group names from a 
specific metalake.
+ */
 @DeveloperApi
-public class ListGroupNamesPreEvent extends GroupPreEvent {
+public class ListGroupNamesEvent extends GroupEvent {
 
   /**
+   * Constructs a new {@link ListGroupNamesEvent} with the specified initiator 
and metalake name.
+   *
    * @param initiator the user who initiated the list-group-names request.
-   * @param identifier the identifier of the metalake which is being listed.
+   * @param metalake the name of the metalake from which group names are 
listed.
    */
-  protected ListGroupNamesPreEvent(String initiator, NameIdentifier 
identifier) {
-    super(initiator, identifier);
+  protected ListGroupNamesEvent(String initiator, String metalake) {
+    super(initiator, NameIdentifierUtil.ofMetalake(metalake));
   }
 
   /**
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
index cf0e702e21..b4c8886019 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupNamesPreEvent.java
@@ -19,19 +19,21 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before list group name from specific 
metalake */
+/** Represents an event triggered before listing group names from a specific 
metalake. */
 @DeveloperApi
 public class ListGroupNamesPreEvent extends GroupPreEvent {
 
   /**
+   * Constructs a new {@link ListGroupNamesPreEvent} with the specified 
initiator and metalake name.
+   *
    * @param initiator the user who initiated the list-group-names request.
-   * @param identifier the identifier of the metalake which is being listed.
+   * @param metalake the name of the metalake from which group names will be 
listed.
    */
-  protected ListGroupNamesPreEvent(String initiator, NameIdentifier 
identifier) {
-    super(initiator, identifier);
+  protected ListGroupNamesPreEvent(String initiator, String metalake) {
+    super(initiator, NameIdentifierUtil.ofMetalake(metalake));
   }
 
   /**
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsEvent.java
similarity index 66%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
copy to 
core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsEvent.java
index 4461a04a03..e732cdff92 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsEvent.java
@@ -19,20 +19,21 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before list groups from specific metalake */
+/** Represents an event triggered after successfully listing groups from a 
specific metalake. */
 @DeveloperApi
-public class ListGroupsPreEvent extends GroupPreEvent {
+public class ListGroupsEvent extends GroupEvent {
+
   /**
-   * Construct a new {@code ListGroupPreEvent} instance with the given 
initiator and identifier.
+   * Constructs a new {@link ListGroupsEvent} with the specified initiator and 
metalake name.
    *
-   * @param initiator the user who initiated the list group operation.
-   * @param identifier the identifier of the metalake which is being listed.
+   * @param initiator the user who initiated the list-groups request.
+   * @param metalake the name of the metalake from which the groups were 
listed.
    */
-  protected ListGroupsPreEvent(String initiator, NameIdentifier identifier) {
-    super(initiator, identifier);
+  protected ListGroupsEvent(String initiator, String metalake) {
+    super(initiator, NameIdentifierUtil.ofMetalake(metalake));
   }
 
   /**
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
index 4461a04a03..a709e83a57 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
@@ -19,20 +19,20 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before list groups from specific metalake */
+/** Represents an event triggered before listing groups from a specific 
metalake. */
 @DeveloperApi
 public class ListGroupsPreEvent extends GroupPreEvent {
   /**
-   * Construct a new {@code ListGroupPreEvent} instance with the given 
initiator and identifier.
+   * Constructs a new {@link ListGroupsPreEvent} with the specified initiator 
and metalake name.
    *
-   * @param initiator the user who initiated the list group operation.
-   * @param identifier the identifier of the metalake which is being listed.
+   * @param initiator the user who initiated the list-groups request.
+   * @param metalake the name of the metalake from which groups will be listed.
    */
-  protected ListGroupsPreEvent(String initiator, NameIdentifier identifier) {
-    super(initiator, identifier);
+  protected ListGroupsPreEvent(String initiator, String metalake) {
+    super(initiator, NameIdentifierUtil.ofMetalake(metalake));
   }
 
   /**
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java 
b/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java
index a61d68dd6f..7905109421 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java
@@ -128,6 +128,8 @@ public enum OperationType {
   GET_GROUP,
   LIST_GROUPS,
   LIST_GROUP_NAMES,
+  GRANT_GROUP_ROLES,
+  REVOKE_GROUP_ROLES,
 
   // TODO ROLE
 
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupEvent.java
new file mode 100644
index 0000000000..417070cb5d
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupEvent.java
@@ -0,0 +1,77 @@
+/*
+ * 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.gravitino.listener.api.event;
+
+import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
+
+/** Represents an event that is triggered after a group is successfully 
removed from a metalake. */
+@DeveloperApi
+public class RemoveGroupEvent extends GroupEvent {
+  private final String removedGroupName;
+  private final boolean isExists;
+
+  /**
+   * Constructs a new {@link RemoveGroupEvent} with the specified initiator, 
metalake name, removed
+   * group name, and existence status.
+   *
+   * @param initiator the user who initiated the remove group operation.
+   * @param metalake the name of the metalake from which the group was removed.
+   * @param removedGroupName the name of the group that was removed.
+   * @param isExists {@code true} if the group was successfully removed, 
{@code false} if there was
+   *     no such group in the metalake.
+   */
+  protected RemoveGroupEvent(
+      String initiator, String metalake, String removedGroupName, boolean 
isExists) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, removedGroupName));
+
+    this.removedGroupName = removedGroupName;
+    this.isExists = isExists;
+  }
+
+  /**
+   * Returns the name of the group that was removed.
+   *
+   * @return the name of the removed group.
+   */
+  public String removedGroupName() {
+    return removedGroupName;
+  }
+
+  /**
+   * Returns whether the group was removed from the metalake.
+   *
+   * @return {@code true} if the group was removed, {@code false} if no such 
group exists in the
+   *     metalake.
+   */
+  public boolean isExists() {
+    return isExists;
+  }
+
+  /**
+   * Returns the operation type of this event.
+   *
+   * @return the operation type of this event.
+   */
+  @Override
+  public OperationType operationType() {
+    return OperationType.REMOVE_GROUP;
+  }
+}
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupPreEvent.java
index b42b90d739..bafe80c126 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupPreEvent.java
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveGroupPreEvent.java
@@ -19,31 +19,32 @@
 
 package org.apache.gravitino.listener.api.event;
 
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 
-/** Represents an event triggered before remove a group from specific 
metalake. */
+/** Represents an event triggered before removing a group from a specific 
metalake. */
 @DeveloperApi
 public class RemoveGroupPreEvent extends GroupPreEvent {
   private final String groupName;
 
   /**
-   * Construct a new {@link RemoveGroupPreEvent} instance with initiator, 
identifier and group name.
+   * Constructs a new {@link RemoveGroupPreEvent} with the specified 
initiator, metalake name, and
+   * group name.
    *
    * @param initiator the user who initiated the remove group operation.
-   * @param identifier the identifier of the metalake where the group is 
removed.
-   * @param groupName the group name which is requested to be removed from the 
metalake.
+   * @param metalake the name of the metalake from which the group will be 
removed.
+   * @param groupName the name of the group that is requested to be removed 
from the metalake.
    */
-  protected RemoveGroupPreEvent(String initiator, NameIdentifier identifier, 
String groupName) {
-    super(initiator, identifier);
+  protected RemoveGroupPreEvent(String initiator, String metalake, String 
groupName) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, groupName));
 
     this.groupName = groupName;
   }
 
   /**
-   * Returns the group information which is being removed from the metalake.
+   * Returns the name of the group that is being removed from the metalake.
    *
-   * @return the group name which is requested to be removed from the metalake.
+   * @return the name of the group requested to be removed.
    */
   public String groupName() {
     return groupName;
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeGroupRolesEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeGroupRolesEvent.java
new file mode 100644
index 0000000000..48f928a821
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeGroupRolesEvent.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.gravitino.listener.api.event;
+
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.listener.api.info.GroupInfo;
+import org.apache.gravitino.utils.NameIdentifierUtil;
+
+/** Represents an event triggered after the operation of revoking roles from a 
group. */
+@DeveloperApi
+public class RevokeGroupRolesEvent extends GroupEvent {
+  private final GroupInfo revokedGroupInfo;
+  private final List<String> roles;
+
+  /**
+   * Constructs a new {@link RevokeGroupRolesEvent} with the specified 
initiator, metalake name,
+   * revoked group information, and the list of revoked roles.
+   *
+   * @param initiator the user who initiated the role-revocation operation.
+   * @param metalake the name of the metalake that the operation affects.
+   * @param revokedGroupInfo the group information of the group whose roles 
are being revoked.
+   * @param roles the list of roles that have been revoked from the group.
+   */
+  public RevokeGroupRolesEvent(
+      String initiator, String metalake, GroupInfo revokedGroupInfo, 
List<String> roles) {
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, 
revokedGroupInfo.name()));
+
+    this.revokedGroupInfo = revokedGroupInfo;
+    this.roles = roles == null ? null : ImmutableList.copyOf(roles);
+  }
+
+  /**
+   * Returns the group information of the group whose roles have been revoked.
+   *
+   * @return the {@link GroupInfo} instance containing the details of the 
group.
+   */
+  public GroupInfo revokedGroupInfo() {
+    return revokedGroupInfo;
+  }
+
+  /**
+   * Returns the list of roles that have been revoked from the group.
+   *
+   * @return the list of revoked roles.
+   */
+  public List<String> roles() {
+    return roles;
+  }
+
+  /**
+   * Returns the operation type of this event.
+   *
+   * @return the operation type.
+   */
+  @Override
+  public OperationType operationType() {
+    return OperationType.REVOKE_GROUP_ROLES;
+  }
+}
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeGroupRolesPreEvent.java
 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeGroupRolesPreEvent.java
new file mode 100644
index 0000000000..5ac2405622
--- /dev/null
+++ 
b/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeGroupRolesPreEvent.java
@@ -0,0 +1,75 @@
+/*
+ * 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.gravitino.listener.api.event;
+
+import java.util.List;
+import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.utils.NameIdentifierUtil;
+
+/** Represents an event triggered before revoking roles from a group. */
+@DeveloperApi
+public class RevokeGroupRolesPreEvent extends GroupPreEvent {
+  private final String groupName;
+  private final List<String> roles;
+
+  /**
+   * Constructs a new {@link RevokeGroupRolesPreEvent} instance with the 
specified initiator,
+   * metalake, group name, and roles to be revoked.
+   *
+   * @param initiator the user who initiated the event to revoke roles.
+   * @param metalake the name of the metalake on which the operation is being 
performed.
+   * @param groupName the name of the group whose roles are being revoked.
+   * @param roles the list of roles to be revoked from the group.
+   */
+  public RevokeGroupRolesPreEvent(
+      String initiator, String metalake, String groupName, List<String> roles) 
{
+    super(initiator, NameIdentifierUtil.ofGroup(metalake, groupName));
+    this.groupName = groupName;
+    this.roles = roles;
+  }
+
+  /**
+   * Returns the name of the group whose roles are being revoked.
+   *
+   * @return the group name of the group.
+   */
+  public String groupName() {
+    return groupName;
+  }
+
+  /**
+   * Returns the list of roles that are being revoked from the group.
+   *
+   * @return the list of roles to be revoked.
+   */
+  public List<String> roles() {
+    return roles;
+  }
+
+  /**
+   * Returns the operation type of this event.
+   *
+   * @return the operation type.
+   */
+  @Override
+  public OperationType operationType() {
+    return OperationType.REVOKE_GROUP_ROLES;
+  }
+}
diff --git 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
 b/core/src/main/java/org/apache/gravitino/listener/api/info/GroupInfo.java
similarity index 53%
copy from 
core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
copy to core/src/main/java/org/apache/gravitino/listener/api/info/GroupInfo.java
index 4461a04a03..a1479cc5ef 100644
--- 
a/core/src/main/java/org/apache/gravitino/listener/api/event/ListGroupsPreEvent.java
+++ b/core/src/main/java/org/apache/gravitino/listener/api/info/GroupInfo.java
@@ -17,31 +17,43 @@
  * under the License.
  */
 
-package org.apache.gravitino.listener.api.event;
+package org.apache.gravitino.listener.api.info;
 
-import org.apache.gravitino.NameIdentifier;
+import java.util.List;
 import org.apache.gravitino.annotation.DeveloperApi;
+import org.apache.gravitino.authorization.Group;
 
-/** Represents an event triggered before list groups from specific metalake */
+/** Provides read-only access to group information for event listeners. */
 @DeveloperApi
-public class ListGroupsPreEvent extends GroupPreEvent {
+public class GroupInfo {
+  private final String name;
+  private List<String> roles;
+
+  /**
+   * Constructs a new {@link GroupInfo} instance from the specified {@link 
Group} object.
+   *
+   * @param group the {@link Group} object from which to create the {@link 
GroupInfo}.
+   */
+  public GroupInfo(Group group) {
+    this.name = group.name();
+    this.roles = group.roles();
+  }
+
   /**
-   * Construct a new {@code ListGroupPreEvent} instance with the given 
initiator and identifier.
+   * Returns the name of the group.
    *
-   * @param initiator the user who initiated the list group operation.
-   * @param identifier the identifier of the metalake which is being listed.
+   * @return The name of the group.
    */
-  protected ListGroupsPreEvent(String initiator, NameIdentifier identifier) {
-    super(initiator, identifier);
+  public String name() {
+    return name;
   }
 
   /**
-   * Returns the operation type for this event.
+   * Returns the roles of the roles.
    *
-   * @return the operation type for this event.
+   * @return The roles of the group.
    */
-  @Override
-  public OperationType operationType() {
-    return OperationType.LIST_GROUPS;
+  public List<String> roles() {
+    return roles;
   }
 }
diff --git 
a/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java 
b/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java
index ba2aa6fa89..b2b3d83bed 100644
--- a/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java
+++ b/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java
@@ -509,4 +509,15 @@ public class NameIdentifierUtil {
       return identifier.name();
     }
   }
+
+  /**
+   * Create the group {@link NameIdentifier} with the given metalake and group 
name.
+   *
+   * @param metalake The metalake name
+   * @param groupName The group name
+   * @return the created group {@link NameIdentifier}
+   */
+  public static NameIdentifier ofGroup(String metalake, String groupName) {
+    return NameIdentifier.of(NamespaceUtil.ofGroup(metalake), groupName);
+  }
 }
diff --git a/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java 
b/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java
index 3b9d56087d..76670b0066 100644
--- a/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java
+++ b/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java
@@ -92,6 +92,16 @@ public class NamespaceUtil {
     return Namespace.of(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.USER_SCHEMA_NAME);
   }
 
+  /**
+   * Create a namespace for group.
+   *
+   * @param metalake The metalake name
+   * @return A namespace for group
+   */
+  public static Namespace ofGroup(String metalake) {
+    return Namespace.of(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.GROUP_SCHEMA_NAME);
+  }
+
   /**
    * Create a namespace for column.
    *
diff --git 
a/core/src/test/java/org/apache/gravitino/listener/api/event/TestGroupEvent.java
 
b/core/src/test/java/org/apache/gravitino/listener/api/event/TestGroupEvent.java
index 22c6301362..44d7ae1936 100644
--- 
a/core/src/test/java/org/apache/gravitino/listener/api/event/TestGroupEvent.java
+++ 
b/core/src/test/java/org/apache/gravitino/listener/api/event/TestGroupEvent.java
@@ -32,6 +32,8 @@ import org.apache.gravitino.exceptions.NoSuchGroupException;
 import org.apache.gravitino.exceptions.NoSuchMetalakeException;
 import org.apache.gravitino.listener.DummyEventListener;
 import org.apache.gravitino.listener.EventBus;
+import org.apache.gravitino.listener.api.info.GroupInfo;
+import org.apache.gravitino.utils.NameIdentifierUtil;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -51,6 +53,8 @@ public class TestGroupEvent {
   private Group group;
   private Group otherGroup;
   private NameIdentifier identifier;
+  private List<String> grantedRoles;
+  private List<String> revokedRoles;
 
   @BeforeAll
   void init() {
@@ -60,6 +64,8 @@ public class TestGroupEvent {
     this.group = getMockGroup(groupName, ImmutableList.of("test", "engineer"));
     this.otherGroup = getMockGroup(otherGroupName, null);
     this.identifier = NameIdentifier.of(METALAKE);
+    this.grantedRoles = ImmutableList.of("test", "engineer");
+    this.revokedRoles = ImmutableList.of("admin", "scientist");
 
     this.dummyEventListener = new DummyEventListener();
     EventBus eventBus = new 
EventBus(Collections.singletonList(dummyEventListener));
@@ -70,6 +76,14 @@ public class TestGroupEvent {
     System.out.println(failureDispatcher);
   }
 
+  @Test
+  void testGroupInfo() {
+    Group mockGroup = getMockGroup("group_test", ImmutableList.of("test", 
"engineer"));
+    GroupInfo groupInfo = new GroupInfo(mockGroup);
+
+    validateGroup(groupInfo, mockGroup);
+  }
+
   @Test
   void testAddGroupPreEvent() {
     dispatcher.addGroup(METALAKE, groupName);
@@ -81,10 +95,28 @@ public class TestGroupEvent {
     Assertions.assertEquals(OperationType.ADD_GROUP, preEvent.operationType());
 
     AddGroupPreEvent addGroupPreEvent = (AddGroupPreEvent) preEvent;
-    Assertions.assertEquals(identifier, addGroupPreEvent.identifier());
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
addGroupPreEvent.identifier());
     Assertions.assertEquals(groupName, addGroupPreEvent.groupName());
   }
 
+  @Test
+  void testAddGroupEvent() {
+    dispatcher.addGroup(METALAKE, groupName);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(AddGroupEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.ADD_GROUP, event.operationType());
+
+    AddGroupEvent addGroupEvent = (AddGroupEvent) event;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
addGroupEvent.identifier());
+
+    validateGroup(addGroupEvent.addedGroupInfo(), group);
+  }
+
   @Test
   void testGetGroupPreEventWithExistingGroup() {
     dispatcher.getGroup(METALAKE, groupName);
@@ -96,7 +128,8 @@ public class TestGroupEvent {
     Assertions.assertEquals(OperationType.GET_GROUP, preEvent.operationType());
 
     GetGroupPreEvent getGroupPreEvent = (GetGroupPreEvent) preEvent;
-    Assertions.assertEquals(identifier, getGroupPreEvent.identifier());
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
getGroupPreEvent.identifier());
     Assertions.assertEquals(groupName, getGroupPreEvent.groupName());
   }
 
@@ -112,6 +145,35 @@ public class TestGroupEvent {
         NoSuchMetalakeException.class, () -> 
dispatcher.getGroup(INEXIST_METALAKE, groupName));
   }
 
+  @Test
+  void testGetGroupEventWithExistingGroup() {
+    dispatcher.getGroup(METALAKE, groupName);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(GetGroupEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.GET_GROUP, event.operationType());
+
+    GetGroupEvent getGroupEvent = (GetGroupEvent) event;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
getGroupEvent.identifier());
+
+    validateGroup(getGroupEvent.loadedGroupInfo(), group);
+  }
+
+  @Test
+  void testGetGroupEventWithInexistMetalake() {
+    Assertions.assertThrows(
+        NoSuchMetalakeException.class, () -> 
dispatcher.getGroup(INEXIST_METALAKE, groupName));
+  }
+
+  @Test
+  void testGetGroupEventWithGroupNotFound() {
+    Assertions.assertThrows(
+        NoSuchGroupException.class, () -> dispatcher.getGroup(METALAKE, 
inExistGroupName));
+  }
+
   @Test
   void testListGroupsPreEvent() {
     dispatcher.listGroups(METALAKE);
@@ -126,6 +188,20 @@ public class TestGroupEvent {
     Assertions.assertEquals(identifier, listGroupsPreEvent.identifier());
   }
 
+  @Test
+  void testListGroupsEvent() {
+    dispatcher.listGroups(METALAKE);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(ListGroupsEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.LIST_GROUPS, event.operationType());
+
+    ListGroupsEvent listGroupsEvent = (ListGroupsEvent) event;
+    Assertions.assertEquals(identifier, listGroupsEvent.identifier());
+  }
+
   @Test
   void testListGroupNamesPreEvent() {
     dispatcher.listGroupNames(METALAKE);
@@ -140,6 +216,20 @@ public class TestGroupEvent {
     Assertions.assertEquals(identifier, listGroupNamesPreEvent.identifier());
   }
 
+  @Test
+  void testListGroupNamesEvent() {
+    dispatcher.listGroupNames(METALAKE);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(ListGroupNamesEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.LIST_GROUP_NAMES, 
event.operationType());
+
+    ListGroupNamesEvent listGroupNamesEvent = (ListGroupNamesEvent) event;
+    Assertions.assertEquals(identifier, listGroupNamesEvent.identifier());
+  }
+
   @Test
   void testRemoveGroupPreEvent() {
     dispatcher.removeGroup(METALAKE, groupName);
@@ -151,10 +241,118 @@ public class TestGroupEvent {
     Assertions.assertEquals(OperationType.REMOVE_GROUP, 
preEvent.operationType());
 
     RemoveGroupPreEvent removeGroupPreEvent = (RemoveGroupPreEvent) preEvent;
-    Assertions.assertEquals(identifier, removeGroupPreEvent.identifier());
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
removeGroupPreEvent.identifier());
     Assertions.assertEquals(groupName, removeGroupPreEvent.groupName());
   }
 
+  @Test
+  void testRemoveGroupEventWithExistingGroup() {
+    dispatcher.removeGroup(METALAKE, groupName);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(RemoveGroupEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.REMOVE_GROUP, event.operationType());
+
+    RemoveGroupEvent removeGroupEvent = (RemoveGroupEvent) event;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
removeGroupEvent.identifier());
+    Assertions.assertTrue(removeGroupEvent.isExists());
+    Assertions.assertEquals(groupName, removeGroupEvent.removedGroupName());
+  }
+
+  @Test
+  void testRemoveGroupEventWithNonExistingGroup() {
+    dispatcher.removeGroup(METALAKE, inExistGroupName);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(RemoveGroupEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.REMOVE_GROUP, event.operationType());
+
+    RemoveGroupEvent removeGroupEvent = (RemoveGroupEvent) event;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, inExistGroupName), 
removeGroupEvent.identifier());
+    Assertions.assertFalse(removeGroupEvent.isExists());
+    Assertions.assertEquals(inExistGroupName, 
removeGroupEvent.removedGroupName());
+  }
+
+  @Test
+  void testGrantRolesToGroupPreEvent() {
+    dispatcher.grantRolesToGroup(METALAKE, grantedRoles, groupName);
+
+    // validate pre-event
+    PreEvent preEvent = dummyEventListener.popPreEvent();
+    Assertions.assertEquals(GrantGroupRolesPreEvent.class, 
preEvent.getClass());
+    Assertions.assertEquals(OperationStatus.UNPROCESSED, 
preEvent.operationStatus());
+    Assertions.assertEquals(OperationType.GRANT_GROUP_ROLES, 
preEvent.operationType());
+
+    GrantGroupRolesPreEvent grantGroupRolesPreEvent = 
(GrantGroupRolesPreEvent) preEvent;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
grantGroupRolesPreEvent.identifier());
+    String grantedUserName = grantGroupRolesPreEvent.groupName();
+    Assertions.assertEquals(groupName, grantedUserName);
+    Assertions.assertEquals(grantedRoles, grantGroupRolesPreEvent.roles());
+  }
+
+  @Test
+  void testGrantRolesToGroupEvent() {
+    dispatcher.grantRolesToGroup(METALAKE, grantedRoles, groupName);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(GrantGroupRolesEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.GRANT_GROUP_ROLES, 
event.operationType());
+
+    GrantGroupRolesEvent grantGroupRolesEvent = (GrantGroupRolesEvent) event;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, groupName), 
grantGroupRolesEvent.identifier());
+    GroupInfo groupInfo = grantGroupRolesEvent.grantedGroupInfo();
+
+    validateGroup(groupInfo, group);
+  }
+
+  @Test
+  void testRevokeRolesFromGroupPreEvent() {
+    dispatcher.revokeRolesFromGroup(METALAKE, revokedRoles, otherGroupName);
+
+    // validate pre-event
+    PreEvent preEvent = dummyEventListener.popPreEvent();
+    Assertions.assertEquals(RevokeGroupRolesPreEvent.class, 
preEvent.getClass());
+    Assertions.assertEquals(OperationStatus.UNPROCESSED, 
preEvent.operationStatus());
+    Assertions.assertEquals(OperationType.REVOKE_GROUP_ROLES, 
preEvent.operationType());
+
+    RevokeGroupRolesPreEvent revokeGroupRolesPreEvent = 
(RevokeGroupRolesPreEvent) preEvent;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, otherGroupName),
+        revokeGroupRolesPreEvent.identifier());
+    String revokedUserName = revokeGroupRolesPreEvent.groupName();
+    Assertions.assertEquals(otherGroupName, revokedUserName);
+    Assertions.assertEquals(revokedRoles, revokeGroupRolesPreEvent.roles());
+  }
+
+  @Test
+  void testRevokeRolesFromGroupEvent() {
+    dispatcher.revokeRolesFromGroup(METALAKE, revokedRoles, otherGroupName);
+
+    // validate event
+    Event event = dummyEventListener.popPostEvent();
+    Assertions.assertEquals(RevokeGroupRolesEvent.class, event.getClass());
+    Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus());
+    Assertions.assertEquals(OperationType.REVOKE_GROUP_ROLES, 
event.operationType());
+
+    RevokeGroupRolesEvent revokeGroupRolesEvent = (RevokeGroupRolesEvent) 
event;
+    Assertions.assertEquals(
+        NameIdentifierUtil.ofGroup(METALAKE, otherGroupName), 
revokeGroupRolesEvent.identifier());
+    GroupInfo groupInfo = revokeGroupRolesEvent.revokedGroupInfo();
+
+    validateGroup(groupInfo, otherGroup);
+  }
+
   private Group getMockGroup(String name, List<String> roles) {
     Group mockGroup = mock(Group.class);
     when(mockGroup.name()).thenReturn(name);
@@ -179,6 +377,9 @@ public class TestGroupEvent {
         .thenThrow(new NoSuchGroupException("group not found"));
     when(dispatcher.getGroup(INEXIST_METALAKE, groupName))
         .thenThrow(new NoSuchMetalakeException("metalake not found"));
+    when(dispatcher.grantRolesToGroup(METALAKE, grantedRoles, 
groupName)).thenReturn(group);
+    when(dispatcher.revokeRolesFromGroup(METALAKE, revokedRoles, 
otherGroupName))
+        .thenReturn(otherGroup);
 
     return dispatcher;
   }
@@ -190,4 +391,9 @@ public class TestGroupEvent {
           throw new GravitinoRuntimeException("Exception for all methods");
         });
   }
+
+  private void validateGroup(GroupInfo groupInfo, Group group) {
+    Assertions.assertEquals(group.name(), groupInfo.name());
+    Assertions.assertEquals(group.roles(), groupInfo.roles());
+  }
 }
diff --git 
a/core/src/test/java/org/apache/gravitino/utils/TestNameIdentifierUtil.java 
b/core/src/test/java/org/apache/gravitino/utils/TestNameIdentifierUtil.java
index 8dc9170b9f..fcd7455f7c 100644
--- a/core/src/test/java/org/apache/gravitino/utils/TestNameIdentifierUtil.java
+++ b/core/src/test/java/org/apache/gravitino/utils/TestNameIdentifierUtil.java
@@ -165,11 +165,22 @@ public class TestNameIdentifierUtil {
         Joiner.on(".")
             .join(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.USER_SCHEMA_NAME, userName),
         nameIdentifier.toString());
-    Assertions.assertEquals(
-        Joiner.on(".").join(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.USER_SCHEMA_NAME),
-        NamespaceUtil.ofUser(metalake).toString());
     Assertions.assertThrows(
         IllegalArgumentException.class, () -> NameIdentifierUtil.ofUser(null, 
userName));
-    Assertions.assertThrows(IllegalArgumentException.class, () -> 
NamespaceUtil.ofUser(null));
+  }
+
+  @Test
+  void testOfGroup() {
+    String groupName = "groupA";
+    String metalake = "demo_metalake";
+
+    NameIdentifier nameIdentifier = NameIdentifierUtil.ofGroup(metalake, 
groupName);
+    Assertions.assertEquals(
+        Joiner.on(".")
+            .join(
+                metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.GROUP_SCHEMA_NAME, groupName),
+        nameIdentifier.toString());
+    Assertions.assertThrows(
+        IllegalArgumentException.class, () -> NameIdentifierUtil.ofGroup(null, 
groupName));
   }
 }
diff --git 
a/core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java 
b/core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
index 71ba8e4c7d..9c26043a12 100644
--- a/core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
+++ b/core/src/test/java/org/apache/gravitino/utils/TestNamespaceUtil.java
@@ -18,6 +18,8 @@
  */
 package org.apache.gravitino.utils;
 
+import com.google.common.base.Joiner;
+import org.apache.gravitino.Entity;
 import org.apache.gravitino.Namespace;
 import org.apache.gravitino.exceptions.IllegalNamespaceException;
 import org.junit.jupiter.api.Assertions;
@@ -82,4 +84,26 @@ public class TestNamespaceUtil {
     Assertions.assertTrue(
         excep5.getMessage().contains("Model version namespace must be non-null 
and have 4 levels"));
   }
+
+  @Test
+  void testOfUser() {
+    String metalake = "metalake";
+    Assertions.assertEquals(
+        Joiner.on(".").join(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.USER_SCHEMA_NAME),
+        NamespaceUtil.ofUser(metalake).toString());
+
+    Assertions.assertThrows(IllegalArgumentException.class, () -> 
NamespaceUtil.ofUser(null));
+  }
+
+  @Test
+  void testOfGroup() {
+    String metalake = "metalake";
+    Namespace namespace = NamespaceUtil.ofGroup(metalake);
+
+    Assertions.assertEquals(
+        Joiner.on(".")
+            .join(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, 
Entity.GROUP_SCHEMA_NAME),
+        namespace.toString());
+    Assertions.assertThrows(IllegalArgumentException.class, () -> 
NamespaceUtil.ofGroup(null));
+  }
 }
diff --git a/docs/gravitino-server-config.md b/docs/gravitino-server-config.md
index 2a04ca2ce6..95ac479adf 100644
--- a/docs/gravitino-server-config.md
+++ b/docs/gravitino-server-config.md
@@ -129,7 +129,9 @@ Gravitino triggers a pre-event before the operation, a 
post-event after the comp
 | Iceberg REST server table operation | `IcebergCreateTableEvent`, 
`IcebergUpdateTableEvent`, `IcebergDropTableEvent`, `IcebergLoadTableEvent`, 
`IcebergListTableEvent`, `IcebergTableExistsEvent`, `IcebergRenameTableEvent`, 
`IcebergCreateTableFailureEvent`, `IcebergUpdateTableFailureEvent`, 
`IcebergDropTableFailureEvent`, `IcebergLoadTableFailureEvent`, 
`IcebergListTableFailureEvent`, `IcebergRenameTableFailureEvent`, 
`IcebergTableExistsFailureEvent`                                        [...]
 | tag operation                       | `ListTagsEvent`, `ListTagsInfoEvent`, 
`CreateTagEvent`, `GetTagEvent`, `AlterTagEvent`, `DeleteTagEvent`, 
`ListMetadataObjectsForTagEvent`, `ListTagsForMetadataObjectEvent`, 
`ListTagsInfoForMetadataObjectEvent`, `AssociateTagsForMetadataObjectEvent`, 
`GetTagForMetadataObjectEvent`, `ListTagsFailureEvent`, 
`ListTagInfoFailureEvent`, `CreateTagFailureEvent`, `GetTagFailureEvent`, 
`AlterTagFailureEvent`, `DeleteTagFailureEvent`, `ListMetadataObjectsFo [...]
 | model operation                     | `DeleteModelEvent`,  
`DeleteModelVersionEvent`,  `GetModelEvent`, `GetModelVersionEvent`, 
`LinkModelVersionEvent`, `ListModelEvent`, `ListModelVersionsEvent`,  
`RegisterAndLinkModelEvent`, `RegisterModelEvent`,  `DeleteModelFailureEvent`, 
`DeleteModelVersionFailureEvent`, `GetModelFailureEvent`, 
`GetModelVersionFailureEvent`, `LinkModelVersionFailureEvent`, 
`ListModelFailureEvent`, `ListModelVersionFailureEvent`, 
`RegisterAndLinkModelFailureEvent`, [...]
-| user operation                     | `AddUserEvent`, `GetUserEvent`, 
`ListUserNamesEvent`, `ListUsersEvent`, `RemoveUserEvent`                       
                                                                                
                                                                                
                                                                                
                                                                                
                      [...]
+| user operation                     | `AddUserEvent`, `GetUserEvent`, 
`ListUserNamesEvent`, `ListUsersEvent`, `RemoveUserEvent`, 
`GrantUserRolesEvent`, `RevokeUserRolesEvent`                                   
                                                                                
                                                                                
                                                                                
                                           [...]
+| group operation                     | `AddGroupEvent`, `GetGroupEvent`, 
`ListGroupNamesEvent`, `ListGroupsEvent`, `RemoveGroupEvent`, 
`GrantGroupRolesEvent`, `RevokeGroupRolesEvent`                                 
                                                                                
                                                                                
                                                                                
                                     [...]
+
 
 
 ##### Pre-event
@@ -145,8 +147,8 @@ Gravitino triggers a pre-event before the operation, a 
post-event after the comp
 | Gravitino server fileset operation   | `CreateFilesetPreEvent`, 
`AlterFilesetPreEvent`, `DropFilesetPreEvent`, 
`LoadFilesetPreEvent`,`ListFilesetPreEvent`,`GetFileLocationPreEvent`           
                                                                                
                                                                                
   | 0.8.0-incubating |
 | Gravitino server model operation     | `DeleteModelPreEvent`, 
`DeleteModelVersionPreEvent`, 
`RegisterAndLinkModelPreEvent`,`GetModelPreEvent`, 
`GetModelVersionPreEvent`,`LinkModelVersionPreEvent`,`ListModelPreEvent`,`RegisterModelPreEvent`
                                                                                
                                   | 0.9.0-incubating |
 | Gravitino server tag operation       | `ListTagsPreEvent`, 
`ListTagsInfoPreEvent`, `CreateTagPreEvent`, `GetTagPreEvent`, 
`AlterTagPreEvent`, `DeleteTagPreEvent`, `ListMetadataObjectsForTagPreEvent`, 
`ListTagsForMetadataObjectPreEvent`, `ListTagsInfoForMetadataObjectPreEvent`, 
`AssociateTagsForMetadataObjectPreEvent`, `GetTagForMetadataObjectPreEvent` | 
0.9.0-incubating |
-| Gravitino server user operation      | `AddUserPreEvent`, `GetUserPreEvent`, 
`ListUserNamesPreEvent`, `ListUsersPreEvent`, `RemoveUserPreEvent`              
                                                                                
                                                                                
                                     | 0.9.0-incubating |
-| Gravitino server group operation     | `AddGroupPreEvent`, 
`GetGroupPreEvent`, `ListGroupNamesPreEvent`, `ListGroupsPreEvent`, 
`RemoveGroupPreEvent`                                                           
                                                                                
                                                                   | 
0.9.0-incubating |
+| Gravitino server user operation      | `AddUserPreEvent`, `GetUserPreEvent`, 
`ListUserNamesPreEvent`, `ListUsersPreEvent`, `RemoveUserPreEvent`, 
`GrantUserRolesPreEvent`, `RevokeUserRolesPreEvent`                             
                                                                                
                                                 | 0.9.0-incubating |
+| Gravitino server group operation     | `AddGroupPreEvent`, 
`GetGroupPreEvent`, `ListGroupNamesPreEvent`, `ListGroupsPreEvent`, 
`RemoveGroupPreEvent`, `GrantGroupRolesPreEvent`, `RevokeGroupRolesPreEvent`    
                                                                                
                                                                   | 
0.9.0-incubating |
 
 #### Event listener plugin
 

Reply via email to