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 c4618d9035 [#6713] feat(core): Support user failure event to Gravitino server (#6817) c4618d9035 is described below commit c4618d9035e78bad650b1cfc7922857dbc59b046 Author: Lord of Abyss <103809695+abyss-l...@users.noreply.github.com> AuthorDate: Wed Apr 2 17:18:52 2025 +0800 [#6713] feat(core): Support user failure event to Gravitino server (#6817) ### What changes were proposed in this pull request? Support user failure event to Gravitino server ### Why are the changes needed? Fix: #6713 ### Does this PR introduce _any_ user-facing change? Users can now listen for the user failure Event. ### How was this patch tested? local test. --- .../api/event/AccessControlEventDispatcher.java | 14 +-- .../listener/api/event/AddUserFailureEvent.java | 65 +++++++++++ .../listener/api/event/GetUserFailureEvent.java | 65 +++++++++++ .../api/event/GrantUserRolesFailureEvent.java | 77 +++++++++++++ .../api/event/ListUserNamesFailureEvent.java | 51 +++++++++ .../listener/api/event/ListUsersFailureEvent.java | 51 +++++++++ .../listener/api/event/RemoveUserFailureEvent.java | 65 +++++++++++ .../api/event/RevokeUserRolesFailureEvent.java | 78 +++++++++++++ .../listener/api/event/UserFailureEvent.java | 44 ++++++++ .../listener/api/event/TestUserEvent.java | 123 +++++++++++++++++++++ docs/gravitino-server-config.md | 24 ++-- 11 files changed, 638 insertions(+), 19 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 2cb3bcd8fb..59d6cfb3bb 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 @@ -77,7 +77,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return userObject; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new AddUserFailureEvent(initiator, metalake, e, user)); throw e; } } @@ -94,7 +94,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return isExists; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new RemoveUserFailureEvent(initiator, metalake, e, user)); throw e; } } @@ -112,7 +112,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return userObject; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new GetUserFailureEvent(initiator, metalake, e, user)); throw e; } } @@ -129,7 +129,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return users; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new ListUsersFailureEvent(initiator, metalake, e)); throw e; } } @@ -146,7 +146,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return userNames; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new ListUserNamesFailureEvent(initiator, metalake, e)); throw e; } } @@ -252,7 +252,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return userObject; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new GrantUserRolesFailureEvent(initiator, metalake, e, user, roles)); throw e; } } @@ -309,7 +309,7 @@ public class AccessControlEventDispatcher implements AccessControlDispatcher { return userObject; } catch (Exception e) { - // TODO: add failure event + eventBus.dispatchEvent(new RevokeUserRolesFailureEvent(initiator, metalake, e, user, roles)); throw e; } } diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AddUserFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AddUserFailureEvent.java new file mode 100644 index 0000000000..79ec431cb6 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AddUserFailureEvent.java @@ -0,0 +1,65 @@ +/* + * 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 triggered when an attempt to add a user to a metalake fails due to an + * exception. + */ +@DeveloperApi +public class AddUserFailureEvent extends UserFailureEvent { + private final String userName; + + /** + * Constructs a new {@code AddUserFailureEvent} instance. + * + * @param user the user who initiated the operation + * @param metalake the name of the metalake where the user was attempted to be added + * @param exception the exception encountered during the operation + * @param userName the name of the user that failed to be added + */ + public AddUserFailureEvent(String user, String metalake, Exception exception, String userName) { + super(user, NameIdentifierUtil.ofUser(metalake, userName), exception); + + this.userName = userName; + } + + /** + * Returns the name of the user that failed to be added. + * + * @return the username involved in the failure event + */ + public String userName() { + return userName; + } + + /** + * Returns the operation type for this event. + * + * @return the operation type for this event. + */ + @Override + public OperationType operationType() { + return OperationType.ADD_USER; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/GetUserFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetUserFailureEvent.java new file mode 100644 index 0000000000..8329ff7ca3 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetUserFailureEvent.java @@ -0,0 +1,65 @@ +/* + * 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 triggered when an attempt to retrieve a user from the metalake fails due to + * an exception. + */ +@DeveloperApi +public class GetUserFailureEvent extends UserFailureEvent { + private final String userName; + + /** + * Constructs a new {@code GetUserFailureEvent} instance. + * + * @param user the user who initiated the operation + * @param metalake the name of the metalake from which the user was attempted to be retrieved + * @param exception the exception encountered during the operation + * @param userName the name of the user that failed to be retrieved + */ + public GetUserFailureEvent(String user, String metalake, Exception exception, String userName) { + super(user, NameIdentifierUtil.ofUser(metalake, userName), exception); + + this.userName = userName; + } + + /** + * Returns the name of the user that failed to be retrieved. + * + * @return the username involved in the failure event + */ + public String userName() { + return userName; + } + + /** + * Returns the operation type for this event. + * + * @return the operation type for this event. + */ + @Override + public OperationType operationType() { + return OperationType.GET_USER; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/GrantUserRolesFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GrantUserRolesFailureEvent.java new file mode 100644 index 0000000000..5db68065bc --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GrantUserRolesFailureEvent.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 java.util.List; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to grant roles to a user fails due to an exception. + */ +@DeveloperApi +public class GrantUserRolesFailureEvent extends UserFailureEvent { + private final String userName; + private final List<String> roles; + + /** + * Constructs a new {@code GrantUserRolesFailureEvent} instance. + * + * @param initiator the user who initiated the operation + * @param metalake the name of the metalake where the operation was attempted + * @param exception the exception encountered during the operation + * @param userName the name of the user to whom the roles were attempted to be granted + * @param roles the list of roles that were attempted to be granted to the user + */ + public GrantUserRolesFailureEvent( + String initiator, String metalake, Exception exception, String userName, List<String> roles) { + super(initiator, NameIdentifierUtil.ofUser(metalake, userName), exception); + this.userName = userName; + this.roles = roles; + } + + /** + * Returns the name of the user to whom the roles were attempted to be granted. + * + * @return the username involved in the failure event + */ + public String userName() { + return userName; + } + + /** + * Returns the list of roles that were attempted to be granted to the user. + * + * @return the list of roles involved in the failure event + */ + public List<String> roles() { + return roles; + } + + /** + * Returns the operation type of this event. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.GRANT_USER_ROLES; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListUserNamesFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListUserNamesFailureEvent.java new file mode 100644 index 0000000000..c692047726 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListUserNamesFailureEvent.java @@ -0,0 +1,51 @@ +/* + * 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 triggered when an attempt to list usernames from a metalake fails due to an + * exception. + */ +@DeveloperApi +public class ListUserNamesFailureEvent extends UserFailureEvent { + /** + * Constructs a new {@code ListUserNamesFailureEvent} instance. + * + * @param user the user who initiated the operation + * @param metalake the name of the metalake where the operation was attempted + * @param exception the exception encountered during the operation + */ + protected ListUserNamesFailureEvent(String user, String metalake, Exception exception) { + super(user, NameIdentifierUtil.ofMetalake(metalake), exception); + } + + /** + * Returns the operation type for this event. + * + * @return the operation type for this event. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_USER_NAMES; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListUsersFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListUsersFailureEvent.java new file mode 100644 index 0000000000..3cd52e0654 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListUsersFailureEvent.java @@ -0,0 +1,51 @@ +/* + * 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 triggered when an attempt to list users from a metalake fails due to an + * exception. + */ +@DeveloperApi +public class ListUsersFailureEvent extends UserFailureEvent { + /** + * Constructs a new {@code ListUsersFailureEvent} instance. + * + * @param user the user who initiated the operation + * @param metalake the name of the metalake where the operation was attempted + * @param exception the exception encountered during the operation + */ + protected ListUsersFailureEvent(String user, String metalake, Exception exception) { + super(user, NameIdentifierUtil.ofMetalake(metalake), exception); + } + + /** + * Returns the operation type for this event. + * + * @return the operation type for this event. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_USERS; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveUserFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveUserFailureEvent.java new file mode 100644 index 0000000000..7d991568b9 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/RemoveUserFailureEvent.java @@ -0,0 +1,65 @@ +/* + * 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 triggered when an attempt to remove a user from a metalake fails due to an + * exception. + */ +@DeveloperApi +public class RemoveUserFailureEvent extends UserFailureEvent { + private final String userName; + + /** + * Constructs a new {@code RemoveUserFailureEvent} instance. + * + * @param user the user who initiated the operation + * @param metalake the name of the metalake from which the user was attempted to be removed + * @param exception the exception encountered during the operation + * @param userName the name of the user that failed to be removed + */ + public RemoveUserFailureEvent( + String user, String metalake, Exception exception, String userName) { + super(user, NameIdentifierUtil.ofUser(metalake, userName), exception); + this.userName = userName; + } + + /** + * Returns the name of the user that failed to be removed. + * + * @return the username involved in the failure event + */ + public String userName() { + return userName; + } + + /** + * Returns the operation type for this event. + * + * @return the operation type for this event. + */ + @Override + public OperationType operationType() { + return OperationType.REMOVE_USER; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeUserRolesFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeUserRolesFailureEvent.java new file mode 100644 index 0000000000..d64d02e794 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/RevokeUserRolesFailureEvent.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 java.util.List; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to revoke roles from a user fails due to an + * exception. + */ +@DeveloperApi +public class RevokeUserRolesFailureEvent extends UserFailureEvent { + private final String userName; + private final List<String> roles; + + /** + * Constructs a new {@code RevokeUserRolesFailureEvent} instance. + * + * @param initiator the user who initiated the operation + * @param metalake the name of the metalake where the operation was attempted + * @param exception the exception encountered during the operation + * @param userName the name of the user from whom the roles were attempted to be revoked + * @param roles the list of roles that were attempted to be revoked from the user + */ + public RevokeUserRolesFailureEvent( + String initiator, String metalake, Exception exception, String userName, List<String> roles) { + super(initiator, NameIdentifierUtil.ofUser(metalake, userName), exception); + this.userName = userName; + this.roles = roles; + } + + /** + * Returns the name of the user from whom the roles were attempted to be revoked. + * + * @return the username involved in the failure event + */ + public String userName() { + return userName; + } + + /** + * Returns the list of roles that were attempted to be revoked from the user. + * + * @return the list of roles involved in the failure event + */ + public List<String> roles() { + return roles; + } + + /** + * Returns the operation type of this event. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.REVOKE_USER_ROLES; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/UserFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/UserFailureEvent.java new file mode 100644 index 0000000000..cd1489648b --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/UserFailureEvent.java @@ -0,0 +1,44 @@ +/* + * 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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** + * Represents an event that is triggered when a user operation fails due to an exception. This event + * captures the user information, a unique identifier for the operation, and the exception that + * caused the failure. + */ +@DeveloperApi +public abstract class UserFailureEvent extends FailureEvent { + + /** + * Constructs a new {@code UserFailureEvent} instance. + * + * @param user the user who initiated the operation + * @param identifier the unique identifier associated with the user operation + * @param exception the exception encountered during the operation, providing details about the + * failure + */ + protected UserFailureEvent(String user, NameIdentifier identifier, Exception exception) { + super(user, identifier, exception); + } +} diff --git a/core/src/test/java/org/apache/gravitino/listener/api/event/TestUserEvent.java b/core/src/test/java/org/apache/gravitino/listener/api/event/TestUserEvent.java index 1d822367cf..d4fe9f00e8 100644 --- a/core/src/test/java/org/apache/gravitino/listener/api/event/TestUserEvent.java +++ b/core/src/test/java/org/apache/gravitino/listener/api/event/TestUserEvent.java @@ -121,6 +121,23 @@ public class TestUserEvent { validateUserInfo(userInfo, user); } + @Test + void testAddUserFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.addUser(METALAKE, userName)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(AddUserFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.ADD_USER, event.operationType()); + + AddUserFailureEvent addUserFailureEvent = (AddUserFailureEvent) event; + Assertions.assertEquals( + NameIdentifierUtil.ofUser(METALAKE, userName), addUserFailureEvent.identifier()); + Assertions.assertEquals(userName, addUserFailureEvent.userName()); + } + @Test void testGetUserPreEventWithExistingUser() { dispatcher.getUser(METALAKE, userName); @@ -178,6 +195,23 @@ public class TestUserEvent { NoSuchMetalakeException.class, () -> dispatcher.getUser(INEXIST_METALAKE, userName)); } + @Test + void testGetUserFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.getUser(METALAKE, inExistUserName)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(GetUserFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.GET_USER, event.operationType()); + + GetUserFailureEvent getUserFailureEvent = (GetUserFailureEvent) event; + Assertions.assertEquals(inExistIdentifier, getUserFailureEvent.identifier()); + Assertions.assertEquals(inExistUserName, getUserFailureEvent.userName()); + } + @Test void testListUserPreEvent() { dispatcher.listUsers(METALAKE); @@ -205,6 +239,22 @@ public class TestUserEvent { Assertions.assertEquals(NameIdentifier.of(METALAKE), listUsersEvent.identifier()); } + @Test + void testListUserFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.listUsers(INEXIST_METALAKE)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListUsersFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.LIST_USERS, event.operationType()); + + ListUsersFailureEvent listUsersFailureEvent = (ListUsersFailureEvent) event; + Assertions.assertEquals( + NameIdentifier.of(INEXIST_METALAKE), listUsersFailureEvent.identifier()); + } + @Test void testListUserNamesPreEvent() { dispatcher.listUserNames(METALAKE); @@ -232,6 +282,22 @@ public class TestUserEvent { Assertions.assertEquals(NameIdentifier.of(METALAKE), listUserNamesEvent.identifier()); } + @Test + void testListUserNamesFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.listUserNames(INEXIST_METALAKE)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListUserNamesFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.LIST_USER_NAMES, event.operationType()); + + ListUserNamesFailureEvent listUserNamesFailureEvent = (ListUserNamesFailureEvent) event; + Assertions.assertEquals( + NameIdentifier.of(INEXIST_METALAKE), listUserNamesFailureEvent.identifier()); + } + @Test void testRemoveUserPreEventWithExistingUser() { dispatcher.removeUser(METALAKE, userName); @@ -280,6 +346,23 @@ public class TestUserEvent { Assertions.assertEquals(inExistUserName, removeUserEvent.removedUserName()); } + @Test + void testRemoveUserFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.removeUser(METALAKE, inExistUserName)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(RemoveUserFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.REMOVE_USER, event.operationType()); + + RemoveUserFailureEvent removeUserFailureEvent = (RemoveUserFailureEvent) event; + Assertions.assertEquals(inExistIdentifier, removeUserFailureEvent.identifier()); + Assertions.assertEquals(inExistUserName, removeUserFailureEvent.userName()); + } + @Test void testGrantRolesToUserPreEvent() { dispatcher.grantRolesToUser(METALAKE, grantedRoles, userName); @@ -314,6 +397,26 @@ public class TestUserEvent { validateUserInfo(userInfo, user); } + @Test + void testGrantRolesToUserFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.grantRolesToUser(METALAKE, grantedRoles, inExistUserName)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(GrantUserRolesFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.GRANT_USER_ROLES, event.operationType()); + + GrantUserRolesFailureEvent grantUserRolesFailureEvent = (GrantUserRolesFailureEvent) event; + Assertions.assertEquals( + NameIdentifierUtil.ofUser(METALAKE, inExistUserName), + grantUserRolesFailureEvent.identifier()); + Assertions.assertEquals(inExistUserName, grantUserRolesFailureEvent.userName()); + Assertions.assertEquals(grantedRoles, grantUserRolesFailureEvent.roles()); + } + @Test void testRevokeRolesUserPreEvent() { dispatcher.revokeRolesFromUser(METALAKE, revokedRoles, otherUserName); @@ -348,6 +451,26 @@ public class TestUserEvent { validateUserInfo(userInfo, otherUser); } + @Test + void testRevokeRolesUserFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.revokeRolesFromUser(METALAKE, revokedRoles, inExistUserName)); + + // validate post-event + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(RevokeUserRolesFailureEvent.class, event.getClass()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + Assertions.assertEquals(OperationType.REVOKE_USER_ROLES, event.operationType()); + + RevokeUserRolesFailureEvent revokeUserRolesFailureEvent = (RevokeUserRolesFailureEvent) event; + Assertions.assertEquals( + NameIdentifierUtil.ofUser(METALAKE, inExistUserName), + revokeUserRolesFailureEvent.identifier()); + Assertions.assertEquals(inExistUserName, revokeUserRolesFailureEvent.userName()); + Assertions.assertEquals(revokedRoles, revokeUserRolesFailureEvent.roles()); + } + private AccessControlEventDispatcher mockUserDispatcher() { AccessControlEventDispatcher dispatcher = mock(AccessControlEventDispatcher.class); when(dispatcher.addUser(METALAKE, userName)).thenReturn(user); diff --git a/docs/gravitino-server-config.md b/docs/gravitino-server-config.md index 95ac479adf..7dfce90c7e 100644 --- a/docs/gravitino-server-config.md +++ b/docs/gravitino-server-config.md @@ -118,19 +118,19 @@ Gravitino triggers a pre-event before the operation, a post-event after the comp ##### Post-event -| Operation type | Post-event [...] -|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- [...] -| table operation | `CreateTableEvent`, `AlterTableEvent`, `DropTableEvent`, `LoadTableEvent`, `ListTableEvent`, `PurgeTableFailureEvent`, `CreateTableFailureEvent`, `AlterTableFailureEvent`, `DropTableFailureEvent`, `LoadTableFailureEvent`, `ListTableFailureEvent`, `PurgeTableFailureEvent` [...] -| fileset operation | `CreateFileSetEvent`, `AlterFileSetEvent`, `DropFileSetEvent`, `LoadFileSetEvent`, `ListFileSetEvent`, `CreateFileSetFailureEvent`, `AlterFileSetFailureEvent`, `DropFileSetFailureEvent`, `LoadFileSetFailureEvent`, `ListFileSetFailureEvent` [...] -| topic operation | `CreateTopicEvent`, `AlterTopicEvent`, `DropTopicEvent`, `LoadTopicEvent`, `ListTopicEvent`, `CreateTopicFailureEvent`, `AlterTopicFailureEvent`, `DropTopicFailureEvent`, `LoadTopicFailureEvent`, `ListTopicFailureEvent` [...] -| schema operation | `CreateSchemaEvent`, `AlterSchemaEvent`, `DropSchemaEvent`, `LoadSchemaEvent`, `ListSchemaEvent`, `CreateSchemaFailureEvent`, `AlterSchemaFailureEvent`, `DropSchemaFailureEvent`, `LoadSchemaFailureEvent`, `ListSchemaFailureEvent` [...] -| catalog operation | `CreateCatalogEvent`, `AlterCatalogEvent`, `DropCatalogEvent`, `LoadCatalogEvent`, `ListCatalogEvent`, `CreateCatalogFailureEvent`, `AlterCatalogFailureEvent`, `DropCatalogFailureEvent`, `LoadCatalogFailureEvent`, `ListCatalogFailureEvent` [...] -| metalake operation | `CreateMetalakeEvent`, `AlterMetalakeEvent`, `DropMetalakeEvent`, `LoadMetalakeEvent`, `ListMetalakeEvent`, `CreateMetalakeFailureEvent`, `AlterMetalakeFailureEvent`, `DropMetalakeFailureEvent`, `LoadMetalakeFailureEvent`, `ListMetalakeFailureEvent` [...] -| Iceberg REST server table operation | `IcebergCreateTableEvent`, `IcebergUpdateTableEvent`, `IcebergDropTableEvent`, `IcebergLoadTableEvent`, `IcebergListTableEvent`, `IcebergTableExistsEvent`, `IcebergRenameTableEvent`, `IcebergCreateTableFailureEvent`, `IcebergUpdateTableFailureEvent`, `IcebergDropTableFailureEvent`, `IcebergLoadTableFailureEvent`, `IcebergListTableFailureEvent`, `IcebergRenameTableFailureEvent`, `IcebergTableExistsFailureEvent` [...] +| Operation type | Post-event [...] +|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- [...] +| table operation | `CreateTableEvent`, `AlterTableEvent`, `DropTableEvent`, `LoadTableEvent`, `ListTableEvent`, `PurgeTableFailureEvent`, `CreateTableFailureEvent`, `AlterTableFailureEvent`, `DropTableFailureEvent`, `LoadTableFailureEvent`, `ListTableFailureEvent`, `PurgeTableFailureEvent` [...] +| fileset operation | `CreateFileSetEvent`, `AlterFileSetEvent`, `DropFileSetEvent`, `LoadFileSetEvent`, `ListFileSetEvent`, `CreateFileSetFailureEvent`, `AlterFileSetFailureEvent`, `DropFileSetFailureEvent`, `LoadFileSetFailureEvent`, `ListFileSetFailureEvent` [...] +| topic operation | `CreateTopicEvent`, `AlterTopicEvent`, `DropTopicEvent`, `LoadTopicEvent`, `ListTopicEvent`, `CreateTopicFailureEvent`, `AlterTopicFailureEvent`, `DropTopicFailureEvent`, `LoadTopicFailureEvent`, `ListTopicFailureEvent` [...] +| schema operation | `CreateSchemaEvent`, `AlterSchemaEvent`, `DropSchemaEvent`, `LoadSchemaEvent`, `ListSchemaEvent`, `CreateSchemaFailureEvent`, `AlterSchemaFailureEvent`, `DropSchemaFailureEvent`, `LoadSchemaFailureEvent`, `ListSchemaFailureEvent` [...] +| catalog operation | `CreateCatalogEvent`, `AlterCatalogEvent`, `DropCatalogEvent`, `LoadCatalogEvent`, `ListCatalogEvent`, `CreateCatalogFailureEvent`, `AlterCatalogFailureEvent`, `DropCatalogFailureEvent`, `LoadCatalogFailureEvent`, `ListCatalogFailureEvent` [...] +| metalake operation | `CreateMetalakeEvent`, `AlterMetalakeEvent`, `DropMetalakeEvent`, `LoadMetalakeEvent`, `ListMetalakeEvent`, `CreateMetalakeFailureEvent`, `AlterMetalakeFailureEvent`, `DropMetalakeFailureEvent`, `LoadMetalakeFailureEvent`, `ListMetalakeFailureEvent` [...] +| 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`, `GrantUserRolesEvent`, `RevokeUserRolesEvent` [...] -| group operation | `AddGroupEvent`, `GetGroupEvent`, `ListGroupNamesEvent`, `ListGroupsEvent`, `RemoveGroupEvent`, `GrantGroupRolesEvent`, `RevokeGroupRolesEvent` [...] +| 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`, `GrantUserRolesEvent`, `RevokeUserRolesEvent`, `AddUserFailureEvent`, `GetUserFailureEvent`, `GrantUserRolesFailureEvent`, `ListUserNamesFailureEvent`, `ListUsersFailureEvent`, `RemoveUserFailureEvent`, `RevokeUserRolesFailureEvent` [...] +| group operation | `AddGroupEvent`, `GetGroupEvent`, `ListGroupNamesEvent`, `ListGroupsEvent`, `RemoveGroupEvent`, `GrantGroupRolesEvent`, `RevokeGroupRolesEvent` [...]