From 3806f9327a786ed53f5e94326773d4a2ca7f6e4b Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar Date: Mon, 11 May 2026 09:56:34 +0530 Subject: [PATCH 1/7] Add view CRUD event dispatching, hooks, audit mapping, and tests --- .../org/apache/gravitino/GravitinoEnv.java | 8 +- .../org/apache/gravitino/audit/AuditLog.java | 20 ++ .../gravitino/hook/ViewHookDispatcher.java | 127 +++++++ .../listener/ViewEventDispatcher.java | 174 ++++++++++ .../listener/api/event/AlterViewEvent.java | 52 +++ .../api/event/AlterViewFailureEvent.java | 45 +++ .../listener/api/event/AlterViewPreEvent.java | 44 +++ .../listener/api/event/CreateViewEvent.java | 44 +++ .../api/event/CreateViewFailureEvent.java | 45 +++ .../api/event/CreateViewPreEvent.java | 44 +++ .../listener/api/event/DropViewEvent.java | 43 +++ .../api/event/DropViewFailureEvent.java | 36 ++ .../listener/api/event/DropViewPreEvent.java | 36 ++ .../listener/api/event/ListViewEvent.java | 47 +++ .../api/event/ListViewFailureEvent.java | 44 +++ .../listener/api/event/ListViewPreEvent.java | 44 +++ .../listener/api/event/LoadViewEvent.java | 44 +++ .../api/event/LoadViewFailureEvent.java | 36 ++ .../listener/api/event/LoadViewPreEvent.java | 36 ++ .../listener/api/event/ViewEvent.java | 37 +++ .../listener/api/event/ViewFailureEvent.java | 32 ++ .../listener/api/event/ViewPreEvent.java | 31 ++ .../gravitino/listener/api/info/ViewInfo.java | 126 +++++++ .../apache/gravitino/audit/TestOperation.java | 77 +++++ .../listener/api/event/TestViewEvent.java | 311 ++++++++++++++++++ 25 files changed, 1580 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java create mode 100644 core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java diff --git a/core/src/main/java/org/apache/gravitino/GravitinoEnv.java b/core/src/main/java/org/apache/gravitino/GravitinoEnv.java index fd00c2a0e07..9eb4841f52d 100644 --- a/core/src/main/java/org/apache/gravitino/GravitinoEnv.java +++ b/core/src/main/java/org/apache/gravitino/GravitinoEnv.java @@ -68,6 +68,7 @@ import org.apache.gravitino.hook.TableHookDispatcher; import org.apache.gravitino.hook.TagHookDispatcher; import org.apache.gravitino.hook.TopicHookDispatcher; +import org.apache.gravitino.hook.ViewHookDispatcher; import org.apache.gravitino.job.BuiltInJobTemplateEventListener; import org.apache.gravitino.job.JobManager; import org.apache.gravitino.job.JobOperationDispatcher; @@ -88,6 +89,7 @@ import org.apache.gravitino.listener.TableEventDispatcher; import org.apache.gravitino.listener.TagEventDispatcher; import org.apache.gravitino.listener.TopicEventDispatcher; +import org.apache.gravitino.listener.ViewEventDispatcher; import org.apache.gravitino.lock.LockManager; import org.apache.gravitino.metalake.MetalakeDispatcher; import org.apache.gravitino.metalake.MetalakeManager; @@ -633,13 +635,13 @@ private void initGravitinoServerComponents() { new FunctionEventDispatcher(eventBus, functionNormalizeDispatcher); this.functionDispatcher = new FunctionHookDispatcher(functionEventDispatcher); - // TODO: Add ViewHookDispatcher and ViewEventDispatcher when needed for view-specific hooks - // and event handling. ViewOperationDispatcher viewOperationDispatcher = new ViewOperationDispatcher(catalogManager, entityStore, idGenerator); ViewNormalizeDispatcher viewNormalizeDispatcher = new ViewNormalizeDispatcher(viewOperationDispatcher, catalogManager); - this.viewDispatcher = viewNormalizeDispatcher; + ViewEventDispatcher viewEventDispatcher = + new ViewEventDispatcher(eventBus, viewNormalizeDispatcher); + this.viewDispatcher = new ViewHookDispatcher(viewEventDispatcher); this.statisticDispatcher = new StatisticEventDispatcher( diff --git a/core/src/main/java/org/apache/gravitino/audit/AuditLog.java b/core/src/main/java/org/apache/gravitino/audit/AuditLog.java index 1d03be7d3ef..2a0d60c9142 100644 --- a/core/src/main/java/org/apache/gravitino/audit/AuditLog.java +++ b/core/src/main/java/org/apache/gravitino/audit/AuditLog.java @@ -33,6 +33,8 @@ import org.apache.gravitino.listener.api.event.AlterTableFailureEvent; import org.apache.gravitino.listener.api.event.AlterTopicEvent; import org.apache.gravitino.listener.api.event.AlterTopicFailureEvent; +import org.apache.gravitino.listener.api.event.AlterViewEvent; +import org.apache.gravitino.listener.api.event.AlterViewFailureEvent; import org.apache.gravitino.listener.api.event.CreateCatalogEvent; import org.apache.gravitino.listener.api.event.CreateCatalogFailureEvent; import org.apache.gravitino.listener.api.event.CreateFilesetEvent; @@ -45,6 +47,8 @@ import org.apache.gravitino.listener.api.event.CreateTableFailureEvent; import org.apache.gravitino.listener.api.event.CreateTopicEvent; import org.apache.gravitino.listener.api.event.CreateTopicFailureEvent; +import org.apache.gravitino.listener.api.event.CreateViewEvent; +import org.apache.gravitino.listener.api.event.CreateViewFailureEvent; import org.apache.gravitino.listener.api.event.DisableCatalogEvent; import org.apache.gravitino.listener.api.event.DisableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.DisableMetalakeEvent; @@ -61,6 +65,8 @@ import org.apache.gravitino.listener.api.event.DropTableFailureEvent; import org.apache.gravitino.listener.api.event.DropTopicEvent; import org.apache.gravitino.listener.api.event.DropTopicFailureEvent; +import org.apache.gravitino.listener.api.event.DropViewEvent; +import org.apache.gravitino.listener.api.event.DropViewFailureEvent; import org.apache.gravitino.listener.api.event.EnableCatalogEvent; import org.apache.gravitino.listener.api.event.EnableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.EnableMetalakeEvent; @@ -85,6 +91,8 @@ import org.apache.gravitino.listener.api.event.ListTableFailureEvent; import org.apache.gravitino.listener.api.event.ListTopicEvent; import org.apache.gravitino.listener.api.event.ListTopicFailureEvent; +import org.apache.gravitino.listener.api.event.ListViewEvent; +import org.apache.gravitino.listener.api.event.ListViewFailureEvent; import org.apache.gravitino.listener.api.event.LoadCatalogEvent; import org.apache.gravitino.listener.api.event.LoadCatalogFailureEvent; import org.apache.gravitino.listener.api.event.LoadFilesetEvent; @@ -97,6 +105,8 @@ import org.apache.gravitino.listener.api.event.LoadTableFailureEvent; import org.apache.gravitino.listener.api.event.LoadTopicEvent; import org.apache.gravitino.listener.api.event.LoadTopicFailureEvent; +import org.apache.gravitino.listener.api.event.LoadViewEvent; +import org.apache.gravitino.listener.api.event.LoadViewFailureEvent; import org.apache.gravitino.listener.api.event.OperationStatus; import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.event.PartitionExistsEvent; @@ -551,6 +561,16 @@ public static Operation fromEvent(Event event) { return LOAD_TOPIC; } else if (event instanceof ListTopicEvent || event instanceof ListTopicFailureEvent) { return LIST_TOPIC; + } else if (event instanceof CreateViewEvent || event instanceof CreateViewFailureEvent) { + return CREATE_VIEW; + } else if (event instanceof AlterViewEvent || event instanceof AlterViewFailureEvent) { + return ALTER_VIEW; + } else if (event instanceof DropViewEvent || event instanceof DropViewFailureEvent) { + return DROP_VIEW; + } else if (event instanceof LoadViewEvent || event instanceof LoadViewFailureEvent) { + return LOAD_VIEW; + } else if (event instanceof ListViewEvent || event instanceof ListViewFailureEvent) { + return LIST_VIEW; } else if (event instanceof CreateFilesetEvent || event instanceof CreateFilesetFailureEvent) { return CREATE_FILESET; diff --git a/core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java b/core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java new file mode 100644 index 00000000000..75cd33cd081 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java @@ -0,0 +1,127 @@ +/* + * 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.hook; + +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; +import org.apache.gravitino.Entity; +import org.apache.gravitino.GravitinoEnv; +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.Namespace; +import org.apache.gravitino.authorization.AuthorizationUtils; +import org.apache.gravitino.authorization.Owner; +import org.apache.gravitino.authorization.OwnerDispatcher; +import org.apache.gravitino.catalog.CapabilityHelpers; +import org.apache.gravitino.catalog.ViewDispatcher; +import org.apache.gravitino.connector.capability.Capability; +import org.apache.gravitino.exceptions.NoSuchSchemaException; +import org.apache.gravitino.exceptions.NoSuchViewException; +import org.apache.gravitino.exceptions.ViewAlreadyExistsException; +import org.apache.gravitino.rel.Column; +import org.apache.gravitino.rel.Representation; +import org.apache.gravitino.rel.View; +import org.apache.gravitino.rel.ViewChange; +import org.apache.gravitino.utils.NameIdentifierUtil; +import org.apache.gravitino.utils.PrincipalUtils; + +/** + * Decorates {@link ViewDispatcher} with ownership and authorization hooks, matching {@link + * TableHookDispatcher}. + */ +public class ViewHookDispatcher implements ViewDispatcher { + private final ViewDispatcher dispatcher; + + public ViewHookDispatcher(ViewDispatcher dispatcher) { + this.dispatcher = dispatcher; + } + + @Override + public NameIdentifier[] listViews(Namespace namespace) throws NoSuchSchemaException { + return dispatcher.listViews(namespace); + } + + @Override + public View loadView(NameIdentifier ident) throws NoSuchViewException { + return dispatcher.loadView(ident); + } + + @Override + public boolean viewExists(NameIdentifier ident) { + return dispatcher.viewExists(ident); + } + + @Override + public View createView( + NameIdentifier ident, + @Nullable String comment, + Column[] columns, + Representation[] representations, + @Nullable String defaultCatalog, + @Nullable String defaultSchema, + Map properties) + throws NoSuchSchemaException, ViewAlreadyExistsException { + View view = + dispatcher.createView( + ident, comment, columns, representations, defaultCatalog, defaultSchema, properties); + OwnerDispatcher ownerManager = GravitinoEnv.getInstance().ownerDispatcher(); + if (ownerManager != null) { + NameIdentifier normalizedIdent = + CapabilityHelpers.applyCapabilities( + ident, Capability.Scope.VIEW, GravitinoEnv.getInstance().catalogManager()); + ownerManager.setOwner( + normalizedIdent.namespace().level(0), + NameIdentifierUtil.toMetadataObject(normalizedIdent, Entity.EntityType.VIEW), + PrincipalUtils.getCurrentUserName(), + Owner.Type.USER); + } + return view; + } + + @Override + public View alterView(NameIdentifier ident, ViewChange... changes) + throws NoSuchViewException, IllegalArgumentException { + ViewChange.RenameView lastRename = null; + List locations = null; + for (ViewChange change : changes) { + if (change instanceof ViewChange.RenameView) { + lastRename = (ViewChange.RenameView) change; + } + } + if (lastRename != null) { + locations = AuthorizationUtils.getMetadataObjectLocation(ident, Entity.EntityType.VIEW); + } + View altered = dispatcher.alterView(ident, changes); + if (lastRename != null) { + AuthorizationUtils.authorizationPluginRenamePrivileges( + ident, Entity.EntityType.VIEW, lastRename.getNewName(), locations); + } + return altered; + } + + @Override + public boolean dropView(NameIdentifier ident) { + List locations = + AuthorizationUtils.getMetadataObjectLocation(ident, Entity.EntityType.VIEW); + boolean dropped = dispatcher.dropView(ident); + AuthorizationUtils.authorizationPluginRemovePrivileges( + ident, Entity.EntityType.VIEW, locations); + return dropped; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java b/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java new file mode 100644 index 00000000000..552ddc49d3a --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java @@ -0,0 +1,174 @@ +/* + * 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; + +import java.util.Map; +import javax.annotation.Nullable; +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.Namespace; +import org.apache.gravitino.catalog.ViewDispatcher; +import org.apache.gravitino.catalog.ViewOperationDispatcher; +import org.apache.gravitino.exceptions.NoSuchSchemaException; +import org.apache.gravitino.exceptions.NoSuchViewException; +import org.apache.gravitino.exceptions.ViewAlreadyExistsException; +import org.apache.gravitino.listener.api.event.AlterViewEvent; +import org.apache.gravitino.listener.api.event.AlterViewFailureEvent; +import org.apache.gravitino.listener.api.event.AlterViewPreEvent; +import org.apache.gravitino.listener.api.event.CreateViewEvent; +import org.apache.gravitino.listener.api.event.CreateViewFailureEvent; +import org.apache.gravitino.listener.api.event.CreateViewPreEvent; +import org.apache.gravitino.listener.api.event.DropViewEvent; +import org.apache.gravitino.listener.api.event.DropViewFailureEvent; +import org.apache.gravitino.listener.api.event.DropViewPreEvent; +import org.apache.gravitino.listener.api.event.ListViewEvent; +import org.apache.gravitino.listener.api.event.ListViewFailureEvent; +import org.apache.gravitino.listener.api.event.ListViewPreEvent; +import org.apache.gravitino.listener.api.event.LoadViewEvent; +import org.apache.gravitino.listener.api.event.LoadViewFailureEvent; +import org.apache.gravitino.listener.api.event.LoadViewPreEvent; +import org.apache.gravitino.listener.api.info.ViewInfo; +import org.apache.gravitino.rel.Column; +import org.apache.gravitino.rel.Representation; +import org.apache.gravitino.rel.View; +import org.apache.gravitino.rel.ViewChange; +import org.apache.gravitino.utils.PrincipalUtils; + +/** + * Decorates a {@link ViewDispatcher} to dispatch pre/post/failure view events to an {@link + * EventBus}, mirroring {@link TableEventDispatcher}. + */ +public class ViewEventDispatcher implements ViewDispatcher { + + private final EventBus eventBus; + private final ViewDispatcher dispatcher; + + /** + * @param eventBus event bus for listener plugins + * @param dispatcher underlying dispatcher (for example {@link ViewOperationDispatcher} behind a + * normalize layer) + */ + public ViewEventDispatcher(EventBus eventBus, ViewDispatcher dispatcher) { + this.eventBus = eventBus; + this.dispatcher = dispatcher; + } + + @Override + public NameIdentifier[] listViews(Namespace namespace) throws NoSuchSchemaException { + eventBus.dispatchEvent(new ListViewPreEvent(PrincipalUtils.getCurrentUserName(), namespace)); + try { + NameIdentifier[] identifiers = dispatcher.listViews(namespace); + eventBus.dispatchEvent(new ListViewEvent(PrincipalUtils.getCurrentUserName(), namespace)); + return identifiers; + } catch (Exception e) { + eventBus.dispatchEvent( + new ListViewFailureEvent(PrincipalUtils.getCurrentUserName(), namespace, e)); + throw e; + } + } + + @Override + public View loadView(NameIdentifier ident) throws NoSuchViewException { + eventBus.dispatchEvent(new LoadViewPreEvent(PrincipalUtils.getCurrentUserName(), ident)); + try { + View view = dispatcher.loadView(ident); + eventBus.dispatchEvent( + new LoadViewEvent(PrincipalUtils.getCurrentUserName(), ident, new ViewInfo(view))); + return view; + } catch (Exception e) { + eventBus.dispatchEvent( + new LoadViewFailureEvent(PrincipalUtils.getCurrentUserName(), ident, e)); + throw e; + } + } + + @Override + public boolean viewExists(NameIdentifier ident) { + return dispatcher.viewExists(ident); + } + + @Override + public View createView( + NameIdentifier ident, + @Nullable String comment, + Column[] columns, + Representation[] representations, + @Nullable String defaultCatalog, + @Nullable String defaultSchema, + Map properties) + throws NoSuchSchemaException, ViewAlreadyExistsException { + ViewInfo createRequest = + new ViewInfo( + ident.name(), + columns, + comment, + representations, + defaultCatalog, + defaultSchema, + properties, + null); + eventBus.dispatchEvent( + new CreateViewPreEvent(PrincipalUtils.getCurrentUserName(), ident, createRequest)); + try { + View view = + dispatcher.createView( + ident, comment, columns, representations, defaultCatalog, defaultSchema, properties); + eventBus.dispatchEvent( + new CreateViewEvent(PrincipalUtils.getCurrentUserName(), ident, new ViewInfo(view))); + return view; + } catch (Exception e) { + eventBus.dispatchEvent( + new CreateViewFailureEvent(PrincipalUtils.getCurrentUserName(), ident, e, createRequest)); + throw e; + } + } + + @Override + public View alterView(NameIdentifier ident, ViewChange... changes) + throws NoSuchViewException, IllegalArgumentException { + eventBus.dispatchEvent( + new AlterViewPreEvent(PrincipalUtils.getCurrentUserName(), ident, changes)); + try { + View view = dispatcher.alterView(ident, changes); + eventBus.dispatchEvent( + new AlterViewEvent( + PrincipalUtils.getCurrentUserName(), ident, changes, new ViewInfo(view))); + return view; + } catch (Exception e) { + eventBus.dispatchEvent( + new AlterViewFailureEvent(PrincipalUtils.getCurrentUserName(), ident, e, changes)); + throw e; + } + } + + @Override + public boolean dropView(NameIdentifier ident) { + eventBus.dispatchEvent(new DropViewPreEvent(PrincipalUtils.getCurrentUserName(), ident)); + try { + boolean existed = dispatcher.dropView(ident); + eventBus.dispatchEvent( + new DropViewEvent(PrincipalUtils.getCurrentUserName(), ident, existed)); + return existed; + } catch (Exception e) { + eventBus.dispatchEvent( + new DropViewFailureEvent(PrincipalUtils.getCurrentUserName(), ident, e)); + throw e; + } + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java new file mode 100644 index 00000000000..587b492e21d --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java @@ -0,0 +1,52 @@ +/* + * 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; +import org.apache.gravitino.listener.api.info.ViewInfo; +import org.apache.gravitino.rel.ViewChange; + +/** Successful alter-view event. */ +@DeveloperApi +public final class AlterViewEvent extends ViewEvent { + private final ViewInfo updatedViewInfo; + private final ViewChange[] viewChanges; + + public AlterViewEvent( + String user, NameIdentifier identifier, ViewChange[] viewChanges, ViewInfo updatedViewInfo) { + super(user, identifier); + this.viewChanges = viewChanges.clone(); + this.updatedViewInfo = updatedViewInfo; + } + + public ViewInfo updatedViewInfo() { + return updatedViewInfo; + } + + public ViewChange[] viewChanges() { + return viewChanges; + } + + @Override + public OperationType operationType() { + return OperationType.ALTER_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java new file mode 100644 index 00000000000..916313c7d0e --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java @@ -0,0 +1,45 @@ +/* + * 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; +import org.apache.gravitino.rel.ViewChange; + +/** Failure event for altering a view. */ +@DeveloperApi +public final class AlterViewFailureEvent extends ViewFailureEvent { + private final ViewChange[] viewChanges; + + public AlterViewFailureEvent( + String user, NameIdentifier identifier, Exception exception, ViewChange[] viewChanges) { + super(user, identifier, exception); + this.viewChanges = viewChanges.clone(); + } + + public ViewChange[] viewChanges() { + return viewChanges; + } + + @Override + public OperationType operationType() { + return OperationType.ALTER_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.java new file mode 100644 index 00000000000..ff9fd259a65 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.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; +import org.apache.gravitino.rel.ViewChange; + +/** Pre-event before altering a view. */ +@DeveloperApi +public class AlterViewPreEvent extends ViewPreEvent { + private final ViewChange[] viewChanges; + + public AlterViewPreEvent(String user, NameIdentifier identifier, ViewChange[] viewChanges) { + super(user, identifier); + this.viewChanges = viewChanges; + } + + public ViewChange[] viewChanges() { + return viewChanges; + } + + @Override + public OperationType operationType() { + return OperationType.ALTER_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.java new file mode 100644 index 00000000000..aa40c5d1293 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.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; +import org.apache.gravitino.listener.api.info.ViewInfo; + +/** Successful create-view event. */ +@DeveloperApi +public final class CreateViewEvent extends ViewEvent { + private final ViewInfo createdViewInfo; + + public CreateViewEvent(String user, NameIdentifier identifier, ViewInfo createdViewInfo) { + super(user, identifier); + this.createdViewInfo = createdViewInfo; + } + + public ViewInfo createdViewInfo() { + return createdViewInfo; + } + + @Override + public OperationType operationType() { + return OperationType.CREATE_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java new file mode 100644 index 00000000000..0aa67b18534 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java @@ -0,0 +1,45 @@ +/* + * 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; +import org.apache.gravitino.listener.api.info.ViewInfo; + +/** Failure event for creating a view. */ +@DeveloperApi +public final class CreateViewFailureEvent extends ViewFailureEvent { + private final ViewInfo createViewRequest; + + public CreateViewFailureEvent( + String user, NameIdentifier identifier, Exception exception, ViewInfo createViewRequest) { + super(user, identifier, exception); + this.createViewRequest = createViewRequest; + } + + public ViewInfo createViewRequest() { + return createViewRequest; + } + + @Override + public OperationType operationType() { + return OperationType.CREATE_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.java new file mode 100644 index 00000000000..3295de6cbc7 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.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; +import org.apache.gravitino.listener.api.info.ViewInfo; + +/** Pre-event before creating a view. */ +@DeveloperApi +public class CreateViewPreEvent extends ViewPreEvent { + private final ViewInfo createViewRequest; + + public CreateViewPreEvent(String user, NameIdentifier identifier, ViewInfo createViewRequest) { + super(user, identifier); + this.createViewRequest = createViewRequest; + } + + public ViewInfo createViewRequest() { + return createViewRequest; + } + + @Override + public OperationType operationType() { + return OperationType.CREATE_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java new file mode 100644 index 00000000000..739bb46d98b --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java @@ -0,0 +1,43 @@ +/* + * 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; + +/** Successful drop-view event. */ +@DeveloperApi +public final class DropViewEvent extends ViewEvent { + private final boolean isExists; + + public DropViewEvent(String user, NameIdentifier identifier, boolean isExists) { + super(user, identifier); + this.isExists = isExists; + } + + public boolean isExists() { + return isExists; + } + + @Override + public OperationType operationType() { + return OperationType.DROP_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java new file mode 100644 index 00000000000..eb3bc6e0ea9 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java @@ -0,0 +1,36 @@ +/* + * 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; + +/** Failure event for dropping a view. */ +@DeveloperApi +public final class DropViewFailureEvent extends ViewFailureEvent { + public DropViewFailureEvent(String user, NameIdentifier identifier, Exception exception) { + super(user, identifier, exception); + } + + @Override + public OperationType operationType() { + return OperationType.DROP_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java new file mode 100644 index 00000000000..50ef2306fc8 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java @@ -0,0 +1,36 @@ +/* + * 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; + +/** Pre-event before dropping a view. */ +@DeveloperApi +public class DropViewPreEvent extends ViewPreEvent { + public DropViewPreEvent(String user, NameIdentifier identifier) { + super(user, identifier); + } + + @Override + public OperationType operationType() { + return OperationType.DROP_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java new file mode 100644 index 00000000000..a69ac37a29e --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java @@ -0,0 +1,47 @@ +/* + * 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.Namespace; +import org.apache.gravitino.annotation.DeveloperApi; + +/** + * Successful list-views event. Like {@link ListTableEvent}, listed identifiers are not stored on + * the event. + */ +@DeveloperApi +public final class ListViewEvent extends ViewEvent { + private final Namespace namespace; + + public ListViewEvent(String user, Namespace namespace) { + super(user, NameIdentifier.of(namespace.levels())); + this.namespace = namespace; + } + + public Namespace namespace() { + return namespace; + } + + @Override + public OperationType operationType() { + return OperationType.LIST_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.java new file mode 100644 index 00000000000..4bc18ce88d7 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.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.Namespace; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Failure event for listing views. */ +@DeveloperApi +public final class ListViewFailureEvent extends ViewFailureEvent { + private final Namespace namespace; + + public ListViewFailureEvent(String user, Namespace namespace, Exception exception) { + super(user, NameIdentifier.of(namespace.levels()), exception); + this.namespace = namespace; + } + + public Namespace namespace() { + return namespace; + } + + @Override + public OperationType operationType() { + return OperationType.LIST_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.java new file mode 100644 index 00000000000..ca6a6deb0d3 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.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.Namespace; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Pre-event before listing views in a namespace. */ +@DeveloperApi +public class ListViewPreEvent extends ViewPreEvent { + private final Namespace namespace; + + public ListViewPreEvent(String user, Namespace namespace) { + super(user, NameIdentifier.of(namespace.levels())); + this.namespace = namespace; + } + + public Namespace namespace() { + return namespace; + } + + @Override + public OperationType operationType() { + return OperationType.LIST_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java new file mode 100644 index 00000000000..c167f29b857 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.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; +import org.apache.gravitino.listener.api.info.ViewInfo; + +/** Successful load-view event. */ +@DeveloperApi +public final class LoadViewEvent extends ViewEvent { + private final ViewInfo loadedViewInfo; + + public LoadViewEvent(String user, NameIdentifier identifier, ViewInfo loadedViewInfo) { + super(user, identifier); + this.loadedViewInfo = loadedViewInfo; + } + + public ViewInfo loadedViewInfo() { + return loadedViewInfo; + } + + @Override + public OperationType operationType() { + return OperationType.LOAD_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java new file mode 100644 index 00000000000..94527945f0c --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java @@ -0,0 +1,36 @@ +/* + * 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; + +/** Failure event for loading a view. */ +@DeveloperApi +public final class LoadViewFailureEvent extends ViewFailureEvent { + public LoadViewFailureEvent(String user, NameIdentifier identifier, Exception exception) { + super(user, identifier, exception); + } + + @Override + public OperationType operationType() { + return OperationType.LOAD_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java new file mode 100644 index 00000000000..99e8e22370c --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java @@ -0,0 +1,36 @@ +/* + * 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; + +/** Pre-event before loading a view. */ +@DeveloperApi +public class LoadViewPreEvent extends ViewPreEvent { + public LoadViewPreEvent(String user, NameIdentifier identifier) { + super(user, identifier); + } + + @Override + public OperationType operationType() { + return OperationType.LOAD_VIEW; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java new file mode 100644 index 00000000000..86bf2029cc3 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java @@ -0,0 +1,37 @@ +/* + * 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; + +/** Base class for successful view operation events. */ +@DeveloperApi +public abstract class ViewEvent extends Event { + + protected ViewEvent(String user, NameIdentifier identifier) { + super(user, identifier); + } + + @Override + public OperationStatus operationStatus() { + return OperationStatus.SUCCESS; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java new file mode 100644 index 00000000000..cfe9707db45 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java @@ -0,0 +1,32 @@ +/* + * 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; + +/** Base class for view operation failure events. */ +@DeveloperApi +public abstract class ViewFailureEvent extends FailureEvent { + + protected ViewFailureEvent(String user, NameIdentifier identifier, Exception exception) { + super(user, identifier, exception); + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java new file mode 100644 index 00000000000..2d5c122e1f5 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java @@ -0,0 +1,31 @@ +/* + * 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; + +/** Pre-event base class for view operations. */ +@DeveloperApi +public abstract class ViewPreEvent extends PreEvent { + protected ViewPreEvent(String user, NameIdentifier identifier) { + super(user, identifier); + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java b/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java new file mode 100644 index 00000000000..0229ace6719 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java @@ -0,0 +1,126 @@ +/* + * 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.info; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import javax.annotation.Nullable; +import org.apache.gravitino.Audit; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.rel.Column; +import org.apache.gravitino.rel.Representation; +import org.apache.gravitino.rel.View; + +/** + * ViewInfo exposes view information for event listeners; it is read-only. Most fields are shallow + * copies internally, not deep copies, for performance. + */ +@DeveloperApi +public final class ViewInfo { + private final String name; + private final Column[] columns; + @Nullable private final String comment; + private final Representation[] representations; + @Nullable private final String defaultCatalog; + @Nullable private final String defaultSchema; + private final Map properties; + @Nullable private final Audit auditInfo; + + /** Constructs a ViewInfo from a {@link View}. */ + public ViewInfo(View view) { + this( + view.name(), + view.columns(), + view.comment(), + view.representations(), + view.defaultCatalog(), + view.defaultSchema(), + view.properties(), + view.auditInfo()); + } + + /** + * Constructs ViewInfo with the given fields. + * + * @param name View name + * @param columns Output columns + * @param comment Optional comment + * @param representations View representations (at least one in a valid create request) + * @param defaultCatalog Optional default catalog for the definition + * @param defaultSchema Optional default schema for the definition + * @param properties View properties; copied defensively + * @param auditInfo Optional audit information + */ + public ViewInfo( + String name, + Column[] columns, + @Nullable String comment, + Representation[] representations, + @Nullable String defaultCatalog, + @Nullable String defaultSchema, + Map properties, + @Nullable Audit auditInfo) { + this.name = name; + this.columns = columns == null ? new Column[0] : columns.clone(); + this.comment = comment; + this.representations = + representations == null ? new Representation[0] : representations.clone(); + this.defaultCatalog = defaultCatalog; + this.defaultSchema = defaultSchema; + this.properties = properties == null ? ImmutableMap.of() : ImmutableMap.copyOf(properties); + this.auditInfo = auditInfo; + } + + public String name() { + return name; + } + + public Column[] columns() { + return columns; + } + + @Nullable + public String comment() { + return comment; + } + + public Representation[] representations() { + return representations; + } + + @Nullable + public String defaultCatalog() { + return defaultCatalog; + } + + @Nullable + public String defaultSchema() { + return defaultSchema; + } + + public Map properties() { + return properties; + } + + @Nullable + public Audit auditInfo() { + return auditInfo; + } +} diff --git a/core/src/test/java/org/apache/gravitino/audit/TestOperation.java b/core/src/test/java/org/apache/gravitino/audit/TestOperation.java index 3a9bedb9832..ec24ff614e9 100644 --- a/core/src/test/java/org/apache/gravitino/audit/TestOperation.java +++ b/core/src/test/java/org/apache/gravitino/audit/TestOperation.java @@ -42,6 +42,8 @@ import org.apache.gravitino.listener.api.event.AlterTableFailureEvent; import org.apache.gravitino.listener.api.event.AlterTopicEvent; import org.apache.gravitino.listener.api.event.AlterTopicFailureEvent; +import org.apache.gravitino.listener.api.event.AlterViewEvent; +import org.apache.gravitino.listener.api.event.AlterViewFailureEvent; import org.apache.gravitino.listener.api.event.CreateCatalogEvent; import org.apache.gravitino.listener.api.event.CreateCatalogFailureEvent; import org.apache.gravitino.listener.api.event.CreateFilesetEvent; @@ -54,6 +56,8 @@ import org.apache.gravitino.listener.api.event.CreateTableFailureEvent; import org.apache.gravitino.listener.api.event.CreateTopicEvent; import org.apache.gravitino.listener.api.event.CreateTopicFailureEvent; +import org.apache.gravitino.listener.api.event.CreateViewEvent; +import org.apache.gravitino.listener.api.event.CreateViewFailureEvent; import org.apache.gravitino.listener.api.event.DisableCatalogEvent; import org.apache.gravitino.listener.api.event.DisableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.DisableMetalakeEvent; @@ -70,6 +74,8 @@ import org.apache.gravitino.listener.api.event.DropTableFailureEvent; import org.apache.gravitino.listener.api.event.DropTopicEvent; import org.apache.gravitino.listener.api.event.DropTopicFailureEvent; +import org.apache.gravitino.listener.api.event.DropViewEvent; +import org.apache.gravitino.listener.api.event.DropViewFailureEvent; import org.apache.gravitino.listener.api.event.EnableCatalogEvent; import org.apache.gravitino.listener.api.event.EnableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.EnableMetalakeEvent; @@ -91,6 +97,8 @@ import org.apache.gravitino.listener.api.event.ListTableFailureEvent; import org.apache.gravitino.listener.api.event.ListTopicEvent; import org.apache.gravitino.listener.api.event.ListTopicFailureEvent; +import org.apache.gravitino.listener.api.event.ListViewEvent; +import org.apache.gravitino.listener.api.event.ListViewFailureEvent; import org.apache.gravitino.listener.api.event.LoadCatalogEvent; import org.apache.gravitino.listener.api.event.LoadCatalogFailureEvent; import org.apache.gravitino.listener.api.event.LoadFilesetEvent; @@ -103,6 +111,8 @@ import org.apache.gravitino.listener.api.event.LoadTableFailureEvent; import org.apache.gravitino.listener.api.event.LoadTopicEvent; import org.apache.gravitino.listener.api.event.LoadTopicFailureEvent; +import org.apache.gravitino.listener.api.event.LoadViewEvent; +import org.apache.gravitino.listener.api.event.LoadViewFailureEvent; import org.apache.gravitino.listener.api.event.PartitionExistsEvent; import org.apache.gravitino.listener.api.event.PurgePartitionEvent; import org.apache.gravitino.listener.api.event.PurgePartitionFailureEvent; @@ -113,11 +123,15 @@ import org.apache.gravitino.listener.api.info.SchemaInfo; import org.apache.gravitino.listener.api.info.TableInfo; import org.apache.gravitino.listener.api.info.TopicInfo; +import org.apache.gravitino.listener.api.info.ViewInfo; import org.apache.gravitino.listener.api.info.partitions.IdentityPartitionInfo; import org.apache.gravitino.listener.api.info.partitions.PartitionInfo; import org.apache.gravitino.messaging.TopicChange; import org.apache.gravitino.rel.Column; +import org.apache.gravitino.rel.Representation; +import org.apache.gravitino.rel.SQLRepresentation; import org.apache.gravitino.rel.TableChange; +import org.apache.gravitino.rel.ViewChange; import org.apache.gravitino.rel.expressions.NamedReference; import org.apache.gravitino.rel.expressions.distributions.Distributions; import org.apache.gravitino.rel.expressions.distributions.Strategy; @@ -162,6 +176,10 @@ public class TestOperation { private TopicInfo topicInfo; + private NameIdentifier viewIdentifier; + + private ViewInfo viewInfo; + private NameIdentifier partitionIdentifier; private PartitionInfo partitionInfo; @@ -187,6 +205,9 @@ public void init() { this.topicIdentifier = mockTopicIdentifier(); this.topicInfo = mockTopicInfo(); + this.viewIdentifier = mockViewIdentifier(); + this.viewInfo = mockViewInfo(); + this.filesetIdentifier = mockFilesetIdentifier(); this.filesetInfo = mockFilesetInfo(); @@ -243,6 +264,14 @@ public void testCreateOperation() { new CreateTopicFailureEvent(USER, topicIdentifier, new Exception(), topicInfo); Assertions.assertEquals( AuditLog.Operation.fromEvent(createTopicFailureEvent), AuditLog.Operation.CREATE_TOPIC); + + Event createViewEvent = new CreateViewEvent(USER, viewIdentifier, viewInfo); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(createViewEvent), AuditLog.Operation.CREATE_VIEW); + Event createViewFailureEvent = + new CreateViewFailureEvent(USER, viewIdentifier, new Exception(), viewInfo); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(createViewFailureEvent), AuditLog.Operation.CREATE_VIEW); } @Test @@ -303,6 +332,14 @@ public void testAlterOperation() { new AlterTopicFailureEvent(USER, topicIdentifier, new Exception(), new TopicChange[] {}); Assertions.assertEquals( AuditLog.Operation.fromEvent(alterTopicFailureEvent), AuditLog.Operation.ALTER_TOPIC); + + Event alterViewEvent = new AlterViewEvent(USER, viewIdentifier, new ViewChange[] {}, viewInfo); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(alterViewEvent), AuditLog.Operation.ALTER_VIEW); + Event alterViewFailureEvent = + new AlterViewFailureEvent(USER, viewIdentifier, new Exception(), new ViewChange[] {}); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(alterViewFailureEvent), AuditLog.Operation.ALTER_VIEW); } @Test @@ -351,6 +388,13 @@ public void testDropOperation() { Event dropTopicFailureEvent = new DropTopicFailureEvent(USER, topicIdentifier, new Exception()); Assertions.assertEquals( AuditLog.Operation.fromEvent(dropTopicFailureEvent), AuditLog.Operation.DROP_TOPIC); + + Event dropViewEvent = new DropViewEvent(USER, viewIdentifier, true); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(dropViewEvent), AuditLog.Operation.DROP_VIEW); + Event dropViewFailureEvent = new DropViewFailureEvent(USER, viewIdentifier, new Exception()); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(dropViewFailureEvent), AuditLog.Operation.DROP_VIEW); } @Test @@ -426,6 +470,14 @@ public void testListOperation() { Assertions.assertEquals( AuditLog.Operation.fromEvent(listTopicFailureEvent), AuditLog.Operation.LIST_TOPIC); + Namespace viewNamespace = Namespace.of("metalake", "catalog", "schema"); + Event listViewEvent = new ListViewEvent(USER, viewNamespace); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(listViewEvent), AuditLog.Operation.LIST_VIEW); + Event listViewFailureEvent = new ListViewFailureEvent(USER, viewNamespace, new Exception()); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(listViewFailureEvent), AuditLog.Operation.LIST_VIEW); + Event listFilesetEvent = new ListFilesetEvent(USER, namespace); Assertions.assertEquals( AuditLog.Operation.fromEvent(listFilesetEvent), AuditLog.Operation.LIST_FILESET); @@ -489,6 +541,13 @@ public void testLoadOperation() { Event loadTopicFailureEvent = new LoadTopicFailureEvent(USER, topicIdentifier, new Exception()); Assertions.assertEquals( AuditLog.Operation.fromEvent(loadTopicFailureEvent), AuditLog.Operation.LOAD_TOPIC); + + Event loadViewEvent = new LoadViewEvent(USER, viewIdentifier, viewInfo); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(loadViewEvent), AuditLog.Operation.LOAD_VIEW); + Event loadViewFailureEvent = new LoadViewFailureEvent(USER, viewIdentifier, new Exception()); + Assertions.assertEquals( + AuditLog.Operation.fromEvent(loadViewFailureEvent), AuditLog.Operation.LOAD_VIEW); } @Test @@ -602,6 +661,24 @@ private TopicInfo mockTopicInfo() { return new TopicInfo("topic", "comment", ImmutableMap.of("a", "b"), null); } + private NameIdentifier mockViewIdentifier() { + return NameIdentifier.of("metalake", "catalog", "schema", "view"); + } + + private ViewInfo mockViewInfo() { + return new ViewInfo( + "view", + new Column[] {Column.of("a", Types.IntegerType.get())}, + "comment", + new Representation[] { + SQLRepresentation.builder().withDialect("trino").withSql("SELECT 1").build() + }, + "dc", + "ds", + ImmutableMap.of("a", "b"), + null); + } + private NameIdentifier mockPartitionIdentifier() { return NameIdentifier.of("metalake", "catalog", "schema", "table", PARTITION_NAME); } diff --git a/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java b/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java new file mode 100644 index 00000000000..8e451ad8be8 --- /dev/null +++ b/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java @@ -0,0 +1,311 @@ +/* + * 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 static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableMap; +import java.util.Arrays; +import java.util.Map; +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.Namespace; +import org.apache.gravitino.catalog.ViewDispatcher; +import org.apache.gravitino.exceptions.GravitinoRuntimeException; +import org.apache.gravitino.listener.DummyEventListener; +import org.apache.gravitino.listener.EventBus; +import org.apache.gravitino.listener.ViewEventDispatcher; +import org.apache.gravitino.listener.api.info.ViewInfo; +import org.apache.gravitino.rel.Column; +import org.apache.gravitino.rel.Representation; +import org.apache.gravitino.rel.SQLRepresentation; +import org.apache.gravitino.rel.View; +import org.apache.gravitino.rel.ViewChange; +import org.apache.gravitino.rel.types.Types; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +@TestInstance(Lifecycle.PER_CLASS) +public class TestViewEvent { + private ViewEventDispatcher dispatcher; + private ViewEventDispatcher failureDispatcher; + private DummyEventListener dummyEventListener; + private View view; + + @BeforeAll + void init() { + this.view = mockView(); + this.dummyEventListener = new DummyEventListener(); + EventBus eventBus = new EventBus(Arrays.asList(dummyEventListener)); + ViewDispatcher viewDispatcher = mockViewDispatcher(); + this.dispatcher = new ViewEventDispatcher(eventBus, viewDispatcher); + ViewDispatcher exceptionDispatcher = mockExceptionViewDispatcher(); + this.failureDispatcher = new ViewEventDispatcher(eventBus, exceptionDispatcher); + } + + @Test + void testCreateViewEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + dispatcher.createView( + identifier, + view.comment(), + view.columns(), + view.representations(), + view.defaultCatalog(), + view.defaultSchema(), + view.properties()); + + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(CreateViewEvent.class, event.getClass()); + checkViewInfo(((CreateViewEvent) event).createdViewInfo(), view); + Assertions.assertEquals(OperationType.CREATE_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + + PreEvent preEvent = dummyEventListener.popPreEvent(); + Assertions.assertEquals(identifier, preEvent.identifier()); + Assertions.assertEquals(CreateViewPreEvent.class, preEvent.getClass()); + checkViewInfo(((CreateViewPreEvent) preEvent).createViewRequest(), view); + Assertions.assertEquals(OperationType.CREATE_VIEW, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testLoadViewEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + dispatcher.loadView(identifier); + + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(LoadViewEvent.class, event.getClass()); + checkViewInfo(((LoadViewEvent) event).loadedViewInfo(), view); + Assertions.assertEquals(OperationType.LOAD_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + + PreEvent preEvent = dummyEventListener.popPreEvent(); + Assertions.assertEquals(identifier, preEvent.identifier()); + Assertions.assertEquals(LoadViewPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.LOAD_VIEW, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testAlterViewEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + ViewChange change = ViewChange.setProperty("a", "b"); + dispatcher.alterView(identifier, change); + + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(AlterViewEvent.class, event.getClass()); + checkViewInfo(((AlterViewEvent) event).updatedViewInfo(), view); + Assertions.assertEquals(1, ((AlterViewEvent) event).viewChanges().length); + Assertions.assertEquals(change, ((AlterViewEvent) event).viewChanges()[0]); + Assertions.assertEquals(OperationType.ALTER_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + + PreEvent preEvent = dummyEventListener.popPreEvent(); + Assertions.assertEquals(identifier, preEvent.identifier()); + Assertions.assertEquals(AlterViewPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(1, ((AlterViewPreEvent) preEvent).viewChanges().length); + Assertions.assertEquals(change, ((AlterViewPreEvent) preEvent).viewChanges()[0]); + Assertions.assertEquals(OperationType.ALTER_VIEW, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testDropViewEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + dispatcher.dropView(identifier); + + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(DropViewEvent.class, event.getClass()); + Assertions.assertTrue(((DropViewEvent) event).isExists()); + Assertions.assertEquals(OperationType.DROP_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + + PreEvent preEvent = dummyEventListener.popPreEvent(); + Assertions.assertEquals(identifier, preEvent.identifier()); + Assertions.assertEquals(DropViewPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.DROP_VIEW, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testListViewEvent() { + Namespace namespace = Namespace.of("metalake", "catalog", "schema"); + dispatcher.listViews(namespace); + + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(namespace.toString(), event.identifier().toString()); + Assertions.assertEquals(ListViewEvent.class, event.getClass()); + Assertions.assertEquals(namespace, ((ListViewEvent) event).namespace()); + Assertions.assertEquals(OperationType.LIST_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + + PreEvent preEvent = dummyEventListener.popPreEvent(); + Assertions.assertEquals(namespace.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(ListViewPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(namespace, ((ListViewPreEvent) preEvent).namespace()); + Assertions.assertEquals(OperationType.LIST_VIEW, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testCreateViewFailureEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> + failureDispatcher.createView( + identifier, + view.comment(), + view.columns(), + view.representations(), + view.defaultCatalog(), + view.defaultSchema(), + view.properties())); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(CreateViewFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((CreateViewFailureEvent) event).exception().getClass()); + checkViewInfo(((CreateViewFailureEvent) event).createViewRequest(), view); + Assertions.assertEquals(OperationType.CREATE_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testLoadViewFailureEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.loadView(identifier)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(LoadViewFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((LoadViewFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.LOAD_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testAlterViewFailureEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + ViewChange change = ViewChange.setProperty("a", "b"); + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.alterView(identifier, change)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(AlterViewFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((AlterViewFailureEvent) event).exception().getClass()); + Assertions.assertEquals(1, ((AlterViewFailureEvent) event).viewChanges().length); + Assertions.assertEquals(change, ((AlterViewFailureEvent) event).viewChanges()[0]); + Assertions.assertEquals(OperationType.ALTER_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testDropViewFailureEvent() { + NameIdentifier identifier = NameIdentifier.of("metalake", "catalog", "schema", view.name()); + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.dropView(identifier)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(DropViewFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((DropViewFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.DROP_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testListViewFailureEvent() { + Namespace namespace = Namespace.of("metalake", "catalog", "schema"); + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.listViews(namespace)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(namespace.toString(), event.identifier().toString()); + Assertions.assertEquals(ListViewFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((ListViewFailureEvent) event).exception().getClass()); + Assertions.assertEquals(namespace, ((ListViewFailureEvent) event).namespace()); + Assertions.assertEquals(OperationType.LIST_VIEW, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + private void checkViewInfo(ViewInfo viewInfo, View view) { + Assertions.assertEquals(view.name(), viewInfo.name()); + Assertions.assertEquals(view.comment(), viewInfo.comment()); + Assertions.assertEquals(view.defaultCatalog(), viewInfo.defaultCatalog()); + Assertions.assertEquals(view.defaultSchema(), viewInfo.defaultSchema()); + Assertions.assertEquals(view.properties(), viewInfo.properties()); + Assertions.assertArrayEquals(view.columns(), viewInfo.columns()); + Assertions.assertArrayEquals(view.representations(), viewInfo.representations()); + Assertions.assertEquals(view.auditInfo(), viewInfo.auditInfo()); + } + + private View mockView() { + View v = mock(View.class); + Representation rep = + SQLRepresentation.builder().withDialect("trino").withSql("SELECT 1").build(); + when(v.name()).thenReturn("view"); + when(v.comment()).thenReturn("comment"); + when(v.properties()).thenReturn(ImmutableMap.of("a", "b")); + when(v.columns()).thenReturn(new Column[] {Column.of("a", Types.IntegerType.get())}); + when(v.representations()).thenReturn(new Representation[] {rep}); + when(v.defaultCatalog()).thenReturn("dc"); + when(v.defaultSchema()).thenReturn("ds"); + when(v.auditInfo()).thenReturn(null); + return v; + } + + private ViewDispatcher mockViewDispatcher() { + ViewDispatcher d = mock(ViewDispatcher.class); + when(d.createView( + any(NameIdentifier.class), + any(), + any(Column[].class), + any(Representation[].class), + any(), + any(), + any(Map.class))) + .thenReturn(view); + when(d.loadView(any(NameIdentifier.class))).thenReturn(view); + when(d.dropView(any(NameIdentifier.class))).thenReturn(true); + when(d.listViews(any(Namespace.class))).thenReturn(null); + when(d.alterView(any(NameIdentifier.class), any(ViewChange.class))).thenReturn(view); + return d; + } + + private ViewDispatcher mockExceptionViewDispatcher() { + return mock( + ViewDispatcher.class, + invocation -> { + throw new GravitinoRuntimeException("Exception for all methods"); + }); + } +} From b562f237411008eb528a0ae1d1d8b45f49dae8a2 Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar <48627196+raushanprabhakar1@users.noreply.github.com> Date: Thu, 14 May 2026 17:48:06 +0530 Subject: [PATCH 2/7] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../org/apache/gravitino/listener/api/info/ViewInfo.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java b/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java index 0229ace6719..e9b31e843f9 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/info/ViewInfo.java @@ -88,37 +88,45 @@ public ViewInfo( this.auditInfo = auditInfo; } + /** Returns the view name. */ public String name() { return name; } + /** Returns the output columns of the view. */ public Column[] columns() { return columns; } + /** Returns the optional comment for the view. */ @Nullable public String comment() { return comment; } + /** Returns the view representations. */ public Representation[] representations() { return representations; } + /** Returns the optional default catalog used by the view definition. */ @Nullable public String defaultCatalog() { return defaultCatalog; } + /** Returns the optional default schema used by the view definition. */ @Nullable public String defaultSchema() { return defaultSchema; } + /** Returns the view properties. */ public Map properties() { return properties; } + /** Returns the optional audit information for the view. */ @Nullable public Audit auditInfo() { return auditInfo; From 3aca74210cbd1984012ec85e3a7dc197546f0245 Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar Date: Thu, 14 May 2026 23:52:52 +0530 Subject: [PATCH 3/7] addressing review comments --- .../apache/gravitino/authorization/AuthorizationUtils.java | 4 ++++ .../apache/gravitino/listener/api/event/LoadViewEvent.java | 5 +++++ .../gravitino/authorization/TestAuthorizationUtils.java | 6 ++++++ 3 files changed, 15 insertions(+) diff --git a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java index 4938ff60341..34632d965cb 100644 --- a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java +++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java @@ -602,6 +602,10 @@ public static List getMetadataObjectLocation( case TOPIC: // Topic doesn't have locations now. break; + case VIEW: + // Views are logical metadata objects without a single storage location; privilege plugins + // operate on metadata only (same idea as TOPIC). + break; default: throw new AuthorizationPluginException( "Failed to get location paths for metadata object %s type %s", ident, type); diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java index c167f29b857..a65f1c0885e 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java @@ -33,6 +33,11 @@ public LoadViewEvent(String user, NameIdentifier identifier, ViewInfo loadedView this.loadedViewInfo = loadedViewInfo; } + /** + * Returns the loaded view information. + * + * @return the loaded view information + */ public ViewInfo loadedViewInfo() { return loadedViewInfo; } diff --git a/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java b/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java index 3071e23f9a6..402fb595258 100644 --- a/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java +++ b/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java @@ -253,6 +253,12 @@ void testGetMetadataObjectLocation() throws IllegalAccessException { NameIdentifier.of("catalog", "schema", "fileset"), Entity.EntityType.TABLE); Assertions.assertEquals(1, locations.size()); Assertions.assertEquals("gs://bucket/1", locations.get(0)); + + Mockito.clearInvocations(catalogDispatcher, tableDispatcher); + locations = + AuthorizationUtils.getMetadataObjectLocation( + NameIdentifier.of("metalake", "catalog", "schema", "view"), Entity.EntityType.VIEW); + Assertions.assertTrue(locations.isEmpty()); } @Test From 5c5a677adac82c46ffa45e63c0983b024d08f510 Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar Date: Sun, 17 May 2026 02:09:50 +0530 Subject: [PATCH 4/7] addressing review feedbacks --- .../org/apache/gravitino/GravitinoEnv.java | 7 +- .../org/apache/gravitino/audit/AuditLog.java | 20 +-- .../gravitino/hook/ViewHookDispatcher.java | 127 ------------------ .../listener/ViewEventDispatcher.java | 30 ++--- .../api/event/{ => view}/AlterViewEvent.java | 3 +- .../{ => view}/AlterViewFailureEvent.java | 3 +- .../event/{ => view}/AlterViewPreEvent.java | 3 +- .../api/event/{ => view}/CreateViewEvent.java | 3 +- .../{ => view}/CreateViewFailureEvent.java | 3 +- .../event/{ => view}/CreateViewPreEvent.java | 3 +- .../api/event/{ => view}/DropViewEvent.java | 3 +- .../{ => view}/DropViewFailureEvent.java | 3 +- .../event/{ => view}/DropViewPreEvent.java | 3 +- .../api/event/{ => view}/ListViewEvent.java | 7 +- .../{ => view}/ListViewFailureEvent.java | 3 +- .../event/{ => view}/ListViewPreEvent.java | 3 +- .../api/event/{ => view}/LoadViewEvent.java | 3 +- .../{ => view}/LoadViewFailureEvent.java | 3 +- .../event/{ => view}/LoadViewPreEvent.java | 3 +- .../api/event/{ => view}/ViewEvent.java | 4 +- .../event/{ => view}/ViewFailureEvent.java | 3 +- .../api/event/{ => view}/ViewPreEvent.java | 3 +- .../apache/gravitino/audit/TestOperation.java | 20 +-- .../listener/api/event/TestViewEvent.java | 15 +++ 24 files changed, 94 insertions(+), 184 deletions(-) delete mode 100644 core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/AlterViewEvent.java (93%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/AlterViewFailureEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/AlterViewPreEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/CreateViewEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/CreateViewFailureEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/CreateViewPreEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/DropViewEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/DropViewFailureEvent.java (91%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/DropViewPreEvent.java (91%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/ListViewEvent.java (83%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/ListViewFailureEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/ListViewPreEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/LoadViewEvent.java (92%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/LoadViewFailureEvent.java (91%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/LoadViewPreEvent.java (91%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/ViewEvent.java (87%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/ViewFailureEvent.java (91%) rename core/src/main/java/org/apache/gravitino/listener/api/event/{ => view}/ViewPreEvent.java (91%) diff --git a/core/src/main/java/org/apache/gravitino/GravitinoEnv.java b/core/src/main/java/org/apache/gravitino/GravitinoEnv.java index 9eb4841f52d..7514d2b930e 100644 --- a/core/src/main/java/org/apache/gravitino/GravitinoEnv.java +++ b/core/src/main/java/org/apache/gravitino/GravitinoEnv.java @@ -68,7 +68,6 @@ import org.apache.gravitino.hook.TableHookDispatcher; import org.apache.gravitino.hook.TagHookDispatcher; import org.apache.gravitino.hook.TopicHookDispatcher; -import org.apache.gravitino.hook.ViewHookDispatcher; import org.apache.gravitino.job.BuiltInJobTemplateEventListener; import org.apache.gravitino.job.JobManager; import org.apache.gravitino.job.JobOperationDispatcher; @@ -635,13 +634,17 @@ private void initGravitinoServerComponents() { new FunctionEventDispatcher(eventBus, functionNormalizeDispatcher); this.functionDispatcher = new FunctionHookDispatcher(functionEventDispatcher); + // View operation chain: ViewEventDispatcher -> ViewNormalizeDispatcher -> + // ViewOperationDispatcher. + // TODO(#11007): Add ViewHookDispatcher for view ownership and privilege hooks when view + // privilege support is finalized. ViewOperationDispatcher viewOperationDispatcher = new ViewOperationDispatcher(catalogManager, entityStore, idGenerator); ViewNormalizeDispatcher viewNormalizeDispatcher = new ViewNormalizeDispatcher(viewOperationDispatcher, catalogManager); ViewEventDispatcher viewEventDispatcher = new ViewEventDispatcher(eventBus, viewNormalizeDispatcher); - this.viewDispatcher = new ViewHookDispatcher(viewEventDispatcher); + this.viewDispatcher = viewEventDispatcher; this.statisticDispatcher = new StatisticEventDispatcher( diff --git a/core/src/main/java/org/apache/gravitino/audit/AuditLog.java b/core/src/main/java/org/apache/gravitino/audit/AuditLog.java index 2a0d60c9142..bfd76e84cce 100644 --- a/core/src/main/java/org/apache/gravitino/audit/AuditLog.java +++ b/core/src/main/java/org/apache/gravitino/audit/AuditLog.java @@ -33,8 +33,6 @@ import org.apache.gravitino.listener.api.event.AlterTableFailureEvent; import org.apache.gravitino.listener.api.event.AlterTopicEvent; import org.apache.gravitino.listener.api.event.AlterTopicFailureEvent; -import org.apache.gravitino.listener.api.event.AlterViewEvent; -import org.apache.gravitino.listener.api.event.AlterViewFailureEvent; import org.apache.gravitino.listener.api.event.CreateCatalogEvent; import org.apache.gravitino.listener.api.event.CreateCatalogFailureEvent; import org.apache.gravitino.listener.api.event.CreateFilesetEvent; @@ -47,8 +45,6 @@ import org.apache.gravitino.listener.api.event.CreateTableFailureEvent; import org.apache.gravitino.listener.api.event.CreateTopicEvent; import org.apache.gravitino.listener.api.event.CreateTopicFailureEvent; -import org.apache.gravitino.listener.api.event.CreateViewEvent; -import org.apache.gravitino.listener.api.event.CreateViewFailureEvent; import org.apache.gravitino.listener.api.event.DisableCatalogEvent; import org.apache.gravitino.listener.api.event.DisableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.DisableMetalakeEvent; @@ -65,8 +61,6 @@ import org.apache.gravitino.listener.api.event.DropTableFailureEvent; import org.apache.gravitino.listener.api.event.DropTopicEvent; import org.apache.gravitino.listener.api.event.DropTopicFailureEvent; -import org.apache.gravitino.listener.api.event.DropViewEvent; -import org.apache.gravitino.listener.api.event.DropViewFailureEvent; import org.apache.gravitino.listener.api.event.EnableCatalogEvent; import org.apache.gravitino.listener.api.event.EnableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.EnableMetalakeEvent; @@ -91,8 +85,6 @@ import org.apache.gravitino.listener.api.event.ListTableFailureEvent; import org.apache.gravitino.listener.api.event.ListTopicEvent; import org.apache.gravitino.listener.api.event.ListTopicFailureEvent; -import org.apache.gravitino.listener.api.event.ListViewEvent; -import org.apache.gravitino.listener.api.event.ListViewFailureEvent; import org.apache.gravitino.listener.api.event.LoadCatalogEvent; import org.apache.gravitino.listener.api.event.LoadCatalogFailureEvent; import org.apache.gravitino.listener.api.event.LoadFilesetEvent; @@ -105,8 +97,6 @@ import org.apache.gravitino.listener.api.event.LoadTableFailureEvent; import org.apache.gravitino.listener.api.event.LoadTopicEvent; import org.apache.gravitino.listener.api.event.LoadTopicFailureEvent; -import org.apache.gravitino.listener.api.event.LoadViewEvent; -import org.apache.gravitino.listener.api.event.LoadViewFailureEvent; import org.apache.gravitino.listener.api.event.OperationStatus; import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.event.PartitionExistsEvent; @@ -115,6 +105,16 @@ import org.apache.gravitino.listener.api.event.PurgePartitionFailureEvent; import org.apache.gravitino.listener.api.event.PurgeTableEvent; import org.apache.gravitino.listener.api.event.PurgeTableFailureEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.DropViewEvent; +import org.apache.gravitino.listener.api.event.view.DropViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.ListViewEvent; +import org.apache.gravitino.listener.api.event.view.ListViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewFailureEvent; /** The interface define unified audit log schema. */ public interface AuditLog { diff --git a/core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java b/core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java deleted file mode 100644 index 75cd33cd081..00000000000 --- a/core/src/main/java/org/apache/gravitino/hook/ViewHookDispatcher.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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.hook; - -import java.util.List; -import java.util.Map; -import javax.annotation.Nullable; -import org.apache.gravitino.Entity; -import org.apache.gravitino.GravitinoEnv; -import org.apache.gravitino.NameIdentifier; -import org.apache.gravitino.Namespace; -import org.apache.gravitino.authorization.AuthorizationUtils; -import org.apache.gravitino.authorization.Owner; -import org.apache.gravitino.authorization.OwnerDispatcher; -import org.apache.gravitino.catalog.CapabilityHelpers; -import org.apache.gravitino.catalog.ViewDispatcher; -import org.apache.gravitino.connector.capability.Capability; -import org.apache.gravitino.exceptions.NoSuchSchemaException; -import org.apache.gravitino.exceptions.NoSuchViewException; -import org.apache.gravitino.exceptions.ViewAlreadyExistsException; -import org.apache.gravitino.rel.Column; -import org.apache.gravitino.rel.Representation; -import org.apache.gravitino.rel.View; -import org.apache.gravitino.rel.ViewChange; -import org.apache.gravitino.utils.NameIdentifierUtil; -import org.apache.gravitino.utils.PrincipalUtils; - -/** - * Decorates {@link ViewDispatcher} with ownership and authorization hooks, matching {@link - * TableHookDispatcher}. - */ -public class ViewHookDispatcher implements ViewDispatcher { - private final ViewDispatcher dispatcher; - - public ViewHookDispatcher(ViewDispatcher dispatcher) { - this.dispatcher = dispatcher; - } - - @Override - public NameIdentifier[] listViews(Namespace namespace) throws NoSuchSchemaException { - return dispatcher.listViews(namespace); - } - - @Override - public View loadView(NameIdentifier ident) throws NoSuchViewException { - return dispatcher.loadView(ident); - } - - @Override - public boolean viewExists(NameIdentifier ident) { - return dispatcher.viewExists(ident); - } - - @Override - public View createView( - NameIdentifier ident, - @Nullable String comment, - Column[] columns, - Representation[] representations, - @Nullable String defaultCatalog, - @Nullable String defaultSchema, - Map properties) - throws NoSuchSchemaException, ViewAlreadyExistsException { - View view = - dispatcher.createView( - ident, comment, columns, representations, defaultCatalog, defaultSchema, properties); - OwnerDispatcher ownerManager = GravitinoEnv.getInstance().ownerDispatcher(); - if (ownerManager != null) { - NameIdentifier normalizedIdent = - CapabilityHelpers.applyCapabilities( - ident, Capability.Scope.VIEW, GravitinoEnv.getInstance().catalogManager()); - ownerManager.setOwner( - normalizedIdent.namespace().level(0), - NameIdentifierUtil.toMetadataObject(normalizedIdent, Entity.EntityType.VIEW), - PrincipalUtils.getCurrentUserName(), - Owner.Type.USER); - } - return view; - } - - @Override - public View alterView(NameIdentifier ident, ViewChange... changes) - throws NoSuchViewException, IllegalArgumentException { - ViewChange.RenameView lastRename = null; - List locations = null; - for (ViewChange change : changes) { - if (change instanceof ViewChange.RenameView) { - lastRename = (ViewChange.RenameView) change; - } - } - if (lastRename != null) { - locations = AuthorizationUtils.getMetadataObjectLocation(ident, Entity.EntityType.VIEW); - } - View altered = dispatcher.alterView(ident, changes); - if (lastRename != null) { - AuthorizationUtils.authorizationPluginRenamePrivileges( - ident, Entity.EntityType.VIEW, lastRename.getNewName(), locations); - } - return altered; - } - - @Override - public boolean dropView(NameIdentifier ident) { - List locations = - AuthorizationUtils.getMetadataObjectLocation(ident, Entity.EntityType.VIEW); - boolean dropped = dispatcher.dropView(ident); - AuthorizationUtils.authorizationPluginRemovePrivileges( - ident, Entity.EntityType.VIEW, locations); - return dropped; - } -} diff --git a/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java b/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java index 552ddc49d3a..764e989c63c 100644 --- a/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java +++ b/core/src/main/java/org/apache/gravitino/listener/ViewEventDispatcher.java @@ -28,21 +28,21 @@ import org.apache.gravitino.exceptions.NoSuchSchemaException; import org.apache.gravitino.exceptions.NoSuchViewException; import org.apache.gravitino.exceptions.ViewAlreadyExistsException; -import org.apache.gravitino.listener.api.event.AlterViewEvent; -import org.apache.gravitino.listener.api.event.AlterViewFailureEvent; -import org.apache.gravitino.listener.api.event.AlterViewPreEvent; -import org.apache.gravitino.listener.api.event.CreateViewEvent; -import org.apache.gravitino.listener.api.event.CreateViewFailureEvent; -import org.apache.gravitino.listener.api.event.CreateViewPreEvent; -import org.apache.gravitino.listener.api.event.DropViewEvent; -import org.apache.gravitino.listener.api.event.DropViewFailureEvent; -import org.apache.gravitino.listener.api.event.DropViewPreEvent; -import org.apache.gravitino.listener.api.event.ListViewEvent; -import org.apache.gravitino.listener.api.event.ListViewFailureEvent; -import org.apache.gravitino.listener.api.event.ListViewPreEvent; -import org.apache.gravitino.listener.api.event.LoadViewEvent; -import org.apache.gravitino.listener.api.event.LoadViewFailureEvent; -import org.apache.gravitino.listener.api.event.LoadViewPreEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewPreEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewPreEvent; +import org.apache.gravitino.listener.api.event.view.DropViewEvent; +import org.apache.gravitino.listener.api.event.view.DropViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.DropViewPreEvent; +import org.apache.gravitino.listener.api.event.view.ListViewEvent; +import org.apache.gravitino.listener.api.event.view.ListViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.ListViewPreEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewPreEvent; import org.apache.gravitino.listener.api.info.ViewInfo; import org.apache.gravitino.rel.Column; import org.apache.gravitino.rel.Representation; diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewEvent.java similarity index 93% rename from core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewEvent.java index 587b492e21d..d9c73ca3310 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.info.ViewInfo; import org.apache.gravitino.rel.ViewChange; diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewFailureEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewFailureEvent.java index 916313c7d0e..0a8a6d9e740 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewFailureEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewFailureEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.rel.ViewChange; /** Failure event for altering a view. */ diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewPreEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewPreEvent.java index ff9fd259a65..022ad33026d 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterViewPreEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/AlterViewPreEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.rel.ViewChange; /** Pre-event before altering a view. */ diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewEvent.java index aa40c5d1293..df6f490db4a 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.info.ViewInfo; /** Successful create-view event. */ diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewFailureEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewFailureEvent.java index 0aa67b18534..e40f0fa3256 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewFailureEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewFailureEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.info.ViewInfo; /** Failure event for creating a view. */ diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewPreEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewPreEvent.java index 3295de6cbc7..16599a57a81 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateViewPreEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/CreateViewPreEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.info.ViewInfo; /** Pre-event before creating a view. */ diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewEvent.java index 739bb46d98b..0772f4323a3 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Successful drop-view event. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewFailureEvent.java similarity index 91% rename from core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewFailureEvent.java index eb3bc6e0ea9..07ec06f0291 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewFailureEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewFailureEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Failure event for dropping a view. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewPreEvent.java similarity index 91% rename from core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewPreEvent.java index 50ef2306fc8..3acb2fe4338 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/DropViewPreEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/DropViewPreEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Pre-event before dropping a view. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewEvent.java similarity index 83% rename from core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewEvent.java index a69ac37a29e..a4afbb59ebf 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewEvent.java @@ -17,15 +17,16 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.Namespace; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** - * Successful list-views event. Like {@link ListTableEvent}, listed identifiers are not stored on - * the event. + * Successful list-views event. Like {@link org.apache.gravitino.listener.api.event.ListTableEvent}, + * listed identifiers are not stored on the event. */ @DeveloperApi public final class ListViewEvent extends ViewEvent { diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewFailureEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewFailureEvent.java index 4bc18ce88d7..bf4b482dd60 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewFailureEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewFailureEvent.java @@ -17,11 +17,12 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.Namespace; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Failure event for listing views. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewPreEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewPreEvent.java index ca6a6deb0d3..3bd2acdf915 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/ListViewPreEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ListViewPreEvent.java @@ -17,11 +17,12 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.Namespace; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Pre-event before listing views in a namespace. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewEvent.java similarity index 92% rename from core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewEvent.java index a65f1c0885e..a8120131c93 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; import org.apache.gravitino.listener.api.info.ViewInfo; /** Successful load-view event. */ diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewFailureEvent.java similarity index 91% rename from core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewFailureEvent.java index 94527945f0c..100a978dce0 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewFailureEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewFailureEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Failure event for loading a view. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewPreEvent.java similarity index 91% rename from core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewPreEvent.java index 99e8e22370c..3f4ca917462 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/LoadViewPreEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/LoadViewPreEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.OperationType; /** Pre-event before loading a view. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewEvent.java similarity index 87% rename from core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewEvent.java index 86bf2029cc3..8fcdc1e2792 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewEvent.java @@ -17,10 +17,12 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.Event; +import org.apache.gravitino.listener.api.event.OperationStatus; /** Base class for successful view operation events. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewFailureEvent.java similarity index 91% rename from core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewFailureEvent.java index cfe9707db45..b14ce130e80 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewFailureEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewFailureEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.FailureEvent; /** Base class for view operation failure events. */ @DeveloperApi diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewPreEvent.java similarity index 91% rename from core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java rename to core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewPreEvent.java index 2d5c122e1f5..0d0a64da45c 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/ViewPreEvent.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/view/ViewPreEvent.java @@ -17,10 +17,11 @@ * under the License. */ -package org.apache.gravitino.listener.api.event; +package org.apache.gravitino.listener.api.event.view; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.event.PreEvent; /** Pre-event base class for view operations. */ @DeveloperApi diff --git a/core/src/test/java/org/apache/gravitino/audit/TestOperation.java b/core/src/test/java/org/apache/gravitino/audit/TestOperation.java index ec24ff614e9..2a7032e45e9 100644 --- a/core/src/test/java/org/apache/gravitino/audit/TestOperation.java +++ b/core/src/test/java/org/apache/gravitino/audit/TestOperation.java @@ -42,8 +42,6 @@ import org.apache.gravitino.listener.api.event.AlterTableFailureEvent; import org.apache.gravitino.listener.api.event.AlterTopicEvent; import org.apache.gravitino.listener.api.event.AlterTopicFailureEvent; -import org.apache.gravitino.listener.api.event.AlterViewEvent; -import org.apache.gravitino.listener.api.event.AlterViewFailureEvent; import org.apache.gravitino.listener.api.event.CreateCatalogEvent; import org.apache.gravitino.listener.api.event.CreateCatalogFailureEvent; import org.apache.gravitino.listener.api.event.CreateFilesetEvent; @@ -56,8 +54,6 @@ import org.apache.gravitino.listener.api.event.CreateTableFailureEvent; import org.apache.gravitino.listener.api.event.CreateTopicEvent; import org.apache.gravitino.listener.api.event.CreateTopicFailureEvent; -import org.apache.gravitino.listener.api.event.CreateViewEvent; -import org.apache.gravitino.listener.api.event.CreateViewFailureEvent; import org.apache.gravitino.listener.api.event.DisableCatalogEvent; import org.apache.gravitino.listener.api.event.DisableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.DisableMetalakeEvent; @@ -74,8 +70,6 @@ import org.apache.gravitino.listener.api.event.DropTableFailureEvent; import org.apache.gravitino.listener.api.event.DropTopicEvent; import org.apache.gravitino.listener.api.event.DropTopicFailureEvent; -import org.apache.gravitino.listener.api.event.DropViewEvent; -import org.apache.gravitino.listener.api.event.DropViewFailureEvent; import org.apache.gravitino.listener.api.event.EnableCatalogEvent; import org.apache.gravitino.listener.api.event.EnableCatalogFailureEvent; import org.apache.gravitino.listener.api.event.EnableMetalakeEvent; @@ -97,8 +91,6 @@ import org.apache.gravitino.listener.api.event.ListTableFailureEvent; import org.apache.gravitino.listener.api.event.ListTopicEvent; import org.apache.gravitino.listener.api.event.ListTopicFailureEvent; -import org.apache.gravitino.listener.api.event.ListViewEvent; -import org.apache.gravitino.listener.api.event.ListViewFailureEvent; import org.apache.gravitino.listener.api.event.LoadCatalogEvent; import org.apache.gravitino.listener.api.event.LoadCatalogFailureEvent; import org.apache.gravitino.listener.api.event.LoadFilesetEvent; @@ -111,12 +103,20 @@ import org.apache.gravitino.listener.api.event.LoadTableFailureEvent; import org.apache.gravitino.listener.api.event.LoadTopicEvent; import org.apache.gravitino.listener.api.event.LoadTopicFailureEvent; -import org.apache.gravitino.listener.api.event.LoadViewEvent; -import org.apache.gravitino.listener.api.event.LoadViewFailureEvent; import org.apache.gravitino.listener.api.event.PartitionExistsEvent; import org.apache.gravitino.listener.api.event.PurgePartitionEvent; import org.apache.gravitino.listener.api.event.PurgePartitionFailureEvent; import org.apache.gravitino.listener.api.event.PurgeTableEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.DropViewEvent; +import org.apache.gravitino.listener.api.event.view.DropViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.ListViewEvent; +import org.apache.gravitino.listener.api.event.view.ListViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewFailureEvent; import org.apache.gravitino.listener.api.info.CatalogInfo; import org.apache.gravitino.listener.api.info.FilesetInfo; import org.apache.gravitino.listener.api.info.MetalakeInfo; diff --git a/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java b/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java index 8e451ad8be8..1d9529ce22c 100644 --- a/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java +++ b/core/src/test/java/org/apache/gravitino/listener/api/event/TestViewEvent.java @@ -33,6 +33,21 @@ import org.apache.gravitino.listener.DummyEventListener; import org.apache.gravitino.listener.EventBus; import org.apache.gravitino.listener.ViewEventDispatcher; +import org.apache.gravitino.listener.api.event.view.AlterViewEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.AlterViewPreEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.CreateViewPreEvent; +import org.apache.gravitino.listener.api.event.view.DropViewEvent; +import org.apache.gravitino.listener.api.event.view.DropViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.DropViewPreEvent; +import org.apache.gravitino.listener.api.event.view.ListViewEvent; +import org.apache.gravitino.listener.api.event.view.ListViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.ListViewPreEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewFailureEvent; +import org.apache.gravitino.listener.api.event.view.LoadViewPreEvent; import org.apache.gravitino.listener.api.info.ViewInfo; import org.apache.gravitino.rel.Column; import org.apache.gravitino.rel.Representation; From 9aef049579814bd1594739336dd3137d68377750 Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar Date: Mon, 18 May 2026 13:20:53 +0530 Subject: [PATCH 5/7] fixing ci --- .../integration/test/RangerFilesetIT.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java index be3b87f0b43..19ccc10645e 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java @@ -122,7 +122,7 @@ public void stop() throws IOException { .filter(schema -> !schema.equals("default")) .forEach( (schema -> { - catalog.asSchemas().dropSchema(schema, false); + catalog.asSchemas().dropSchema(schema, true); })); Arrays.stream(metalake.listCatalogs()) .forEach((catalogName -> metalake.dropCatalog(catalogName, true))); @@ -489,10 +489,11 @@ void testReadWritePathE2E() throws IOException, RangerServiceException, Interrup return null; }); + String renamedFilesetName = "new_name"; catalog .asFilesetCatalog() .alterFileset( - NameIdentifier.of(schemaName, filenameRole), FilesetChange.rename("new_name")); + NameIdentifier.of(schemaName, filenameRole), FilesetChange.rename(renamedFilesetName)); UserGroupInformation.createProxyUser(userName, UserGroupInformation.getCurrentUser()) .doAs( (PrivilegedExceptionAction) @@ -506,19 +507,21 @@ void testReadWritePathE2E() throws IOException, RangerServiceException, Interrup }); Assertions.assertDoesNotThrow( () -> - userFileSystem.listFiles(new Path(storageLocation(filenameRole)), false)); + userFileSystem.listFiles( + new Path(storageLocation(renamedFilesetName)), false)); Assertions.assertDoesNotThrow( () -> userFileSystem.mkdirs( new Path( - String.format("%s/%s", storageLocation(filenameRole), "test3")))); + String.format( + "%s/%s", storageLocation(renamedFilesetName), "test3")))); userFileSystem.close(); return null; }); MetadataObject renamedFilesetObject = MetadataObjects.of( String.format("%s.%s", catalogName, schemaName), - "new_name", + renamedFilesetName, MetadataObject.Type.FILESET); metalake.revokePrivilegesFromRole( @@ -540,18 +543,20 @@ void testReadWritePathE2E() throws IOException, RangerServiceException, Interrup Assertions.assertThrows( Exception.class, () -> - userFileSystem.listFiles(new Path(storageLocation(filenameRole)), false)); + userFileSystem.listFiles( + new Path(storageLocation(renamedFilesetName)), false)); Assertions.assertThrows( Exception.class, () -> userFileSystem.mkdirs( new Path( - String.format("%s/%s", storageLocation(filenameRole), "test4")))); + String.format( + "%s/%s", storageLocation(renamedFilesetName), "test4")))); userFileSystem.close(); return null; }); - catalog.asFilesetCatalog().dropFileset(NameIdentifier.of(schemaName, "new_name")); + catalog.asFilesetCatalog().dropFileset(NameIdentifier.of(schemaName, renamedFilesetName)); } private void createCatalogAndSchema() { From b87f28c413a3e9ee36d56bfd28e68ac81cc965c8 Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar Date: Mon, 25 May 2026 18:49:08 +0530 Subject: [PATCH 6/7] reverting to main for /RangerFilesetIT.java --- .../integration/test/RangerFilesetIT.java | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java index 19ccc10645e..be3b87f0b43 100644 --- a/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java +++ b/authorizations/authorization-ranger/src/test/java/org/apache/gravitino/authorization/ranger/integration/test/RangerFilesetIT.java @@ -122,7 +122,7 @@ public void stop() throws IOException { .filter(schema -> !schema.equals("default")) .forEach( (schema -> { - catalog.asSchemas().dropSchema(schema, true); + catalog.asSchemas().dropSchema(schema, false); })); Arrays.stream(metalake.listCatalogs()) .forEach((catalogName -> metalake.dropCatalog(catalogName, true))); @@ -489,11 +489,10 @@ void testReadWritePathE2E() throws IOException, RangerServiceException, Interrup return null; }); - String renamedFilesetName = "new_name"; catalog .asFilesetCatalog() .alterFileset( - NameIdentifier.of(schemaName, filenameRole), FilesetChange.rename(renamedFilesetName)); + NameIdentifier.of(schemaName, filenameRole), FilesetChange.rename("new_name")); UserGroupInformation.createProxyUser(userName, UserGroupInformation.getCurrentUser()) .doAs( (PrivilegedExceptionAction) @@ -507,21 +506,19 @@ void testReadWritePathE2E() throws IOException, RangerServiceException, Interrup }); Assertions.assertDoesNotThrow( () -> - userFileSystem.listFiles( - new Path(storageLocation(renamedFilesetName)), false)); + userFileSystem.listFiles(new Path(storageLocation(filenameRole)), false)); Assertions.assertDoesNotThrow( () -> userFileSystem.mkdirs( new Path( - String.format( - "%s/%s", storageLocation(renamedFilesetName), "test3")))); + String.format("%s/%s", storageLocation(filenameRole), "test3")))); userFileSystem.close(); return null; }); MetadataObject renamedFilesetObject = MetadataObjects.of( String.format("%s.%s", catalogName, schemaName), - renamedFilesetName, + "new_name", MetadataObject.Type.FILESET); metalake.revokePrivilegesFromRole( @@ -543,20 +540,18 @@ void testReadWritePathE2E() throws IOException, RangerServiceException, Interrup Assertions.assertThrows( Exception.class, () -> - userFileSystem.listFiles( - new Path(storageLocation(renamedFilesetName)), false)); + userFileSystem.listFiles(new Path(storageLocation(filenameRole)), false)); Assertions.assertThrows( Exception.class, () -> userFileSystem.mkdirs( new Path( - String.format( - "%s/%s", storageLocation(renamedFilesetName), "test4")))); + String.format("%s/%s", storageLocation(filenameRole), "test4")))); userFileSystem.close(); return null; }); - catalog.asFilesetCatalog().dropFileset(NameIdentifier.of(schemaName, renamedFilesetName)); + catalog.asFilesetCatalog().dropFileset(NameIdentifier.of(schemaName, "new_name")); } private void createCatalogAndSchema() { From 77a0fdfdd685e7e9e1ca8665fec9aaf511e31adf Mon Sep 17 00:00:00 2001 From: Raushan Prabhakar Date: Mon, 25 May 2026 18:57:32 +0530 Subject: [PATCH 7/7] removing authorization related changes --- .../apache/gravitino/authorization/AuthorizationUtils.java | 4 ---- .../gravitino/authorization/TestAuthorizationUtils.java | 6 ------ 2 files changed, 10 deletions(-) diff --git a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java index 34632d965cb..4938ff60341 100644 --- a/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java +++ b/core/src/main/java/org/apache/gravitino/authorization/AuthorizationUtils.java @@ -602,10 +602,6 @@ public static List getMetadataObjectLocation( case TOPIC: // Topic doesn't have locations now. break; - case VIEW: - // Views are logical metadata objects without a single storage location; privilege plugins - // operate on metadata only (same idea as TOPIC). - break; default: throw new AuthorizationPluginException( "Failed to get location paths for metadata object %s type %s", ident, type); diff --git a/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java b/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java index 402fb595258..3071e23f9a6 100644 --- a/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java +++ b/core/src/test/java/org/apache/gravitino/authorization/TestAuthorizationUtils.java @@ -253,12 +253,6 @@ void testGetMetadataObjectLocation() throws IllegalAccessException { NameIdentifier.of("catalog", "schema", "fileset"), Entity.EntityType.TABLE); Assertions.assertEquals(1, locations.size()); Assertions.assertEquals("gs://bucket/1", locations.get(0)); - - Mockito.clearInvocations(catalogDispatcher, tableDispatcher); - locations = - AuthorizationUtils.getMetadataObjectLocation( - NameIdentifier.of("metalake", "catalog", "schema", "view"), Entity.EntityType.VIEW); - Assertions.assertTrue(locations.isEmpty()); } @Test