This is an automated email from the ASF dual-hosted git repository. fanng pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push: new a84fd189ac [#5900] feat(tag): support tag pre-event to Gravitino server (#5980) a84fd189ac is described below commit a84fd189ac1ae2313888beb718918f9639d84dbe Author: Lychee <62695685+amazinglyc...@users.noreply.github.com> AuthorDate: Sun Feb 9 05:02:15 2025 -0500 [#5900] feat(tag): support tag pre-event to Gravitino server (#5980) ### What changes were proposed in this pull request? Implemented pre-event handling for all tag-related operations, including: - listTags - listTagsInfo - getTag - createTag - alterTag - deleteTag - listMetadataObjectsForTag - listTagsForMetadataObject - listTagsInfoForMetadataObject - associateTagsForMetadataObject - getTagForMetadataObject ### Why are the changes needed? Fix: #5900 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? add UT --- .../gravitino/listener/TagEventDispatcher.java | 55 ++++-- .../listener/api/event/AlterTagPreEvent.java | 63 +++++++ .../AssociateTagsForMetadataObjectPreEvent.java | 78 +++++++++ .../listener/api/event/CreateTagPreEvent.java | 61 +++++++ .../listener/api/event/DeleteTagPreEvent.java | 48 ++++++ .../api/event/GetTagForMetadataObjectPreEvent.java | 62 +++++++ .../listener/api/event/GetTagPreEvent.java | 47 ++++++ .../event/ListMetadataObjectsForTagPreEvent.java | 47 ++++++ .../event/ListTagsForMetadataObjectPreEvent.java | 49 ++++++ .../ListTagsInfoForMetadataObjectPreEvent.java | 52 ++++++ .../listener/api/event/ListTagsInfoPreEvent.java | 46 +++++ .../listener/api/event/ListTagsPreEvent.java | 46 +++++ .../gravitino/listener/api/event/TagPreEvent.java | 37 ++++ .../gravitino/listener/api/info/TagInfo.java | 1 - .../gravitino/listener/api/event/TestTagEvent.java | 187 +++++++++++++++++++++ 15 files changed, 868 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java b/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java index 302d82a93c..c02c4eda65 100644 --- a/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java +++ b/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java @@ -22,16 +22,27 @@ import java.util.Map; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.exceptions.NoSuchTagException; import org.apache.gravitino.listener.api.event.AlterTagFailureEvent; +import org.apache.gravitino.listener.api.event.AlterTagPreEvent; import org.apache.gravitino.listener.api.event.AssociateTagsForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.AssociateTagsForMetadataObjectPreEvent; import org.apache.gravitino.listener.api.event.CreateTagFailureEvent; +import org.apache.gravitino.listener.api.event.CreateTagPreEvent; import org.apache.gravitino.listener.api.event.DeleteTagFailureEvent; +import org.apache.gravitino.listener.api.event.DeleteTagPreEvent; import org.apache.gravitino.listener.api.event.GetTagFailureEvent; import org.apache.gravitino.listener.api.event.GetTagForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.GetTagForMetadataObjectPreEvent; +import org.apache.gravitino.listener.api.event.GetTagPreEvent; import org.apache.gravitino.listener.api.event.ListMetadataObjectsForTagFailureEvent; +import org.apache.gravitino.listener.api.event.ListMetadataObjectsForTagPreEvent; import org.apache.gravitino.listener.api.event.ListTagsFailureEvent; import org.apache.gravitino.listener.api.event.ListTagsForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsForMetadataObjectPreEvent; import org.apache.gravitino.listener.api.event.ListTagsInfoFailureEvent; import org.apache.gravitino.listener.api.event.ListTagsInfoForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsInfoForMetadataObjectPreEvent; +import org.apache.gravitino.listener.api.event.ListTagsInfoPreEvent; +import org.apache.gravitino.listener.api.event.ListTagsPreEvent; import org.apache.gravitino.listener.api.info.TagInfo; import org.apache.gravitino.tag.Tag; import org.apache.gravitino.tag.TagChange; @@ -55,7 +66,7 @@ public class TagEventDispatcher implements TagDispatcher { @Override public String[] listTags(String metalake) { - // TODO: listTagsPreEvent + eventBus.dispatchEvent(new ListTagsPreEvent(PrincipalUtils.getCurrentUserName(), metalake)); try { // TODO: listTagsEvent return dispatcher.listTags(metalake); @@ -68,7 +79,7 @@ public class TagEventDispatcher implements TagDispatcher { @Override public Tag[] listTagsInfo(String metalake) { - // TODO: listTagsInfoPreEvent + eventBus.dispatchEvent(new ListTagsInfoPreEvent(PrincipalUtils.getCurrentUserName(), metalake)); try { // TODO: listTagsInfoEvent return dispatcher.listTagsInfo(metalake); @@ -81,7 +92,7 @@ public class TagEventDispatcher implements TagDispatcher { @Override public Tag getTag(String metalake, String name) throws NoSuchTagException { - // TODO: getTagPreEvent + eventBus.dispatchEvent(new GetTagPreEvent(PrincipalUtils.getCurrentUserName(), metalake, name)); try { // TODO: getTagEvent return dispatcher.getTag(metalake, name); @@ -97,6 +108,9 @@ public class TagEventDispatcher implements TagDispatcher { String metalake, String name, String comment, Map<String, String> properties) { TagInfo tagInfo = new TagInfo(name, comment, properties); // TODO: createTagPreEvent + + eventBus.dispatchEvent( + new CreateTagPreEvent(PrincipalUtils.getCurrentUserName(), metalake, tagInfo)); try { // TODO: createTagEvent return dispatcher.createTag(metalake, name, comment, properties); @@ -109,7 +123,10 @@ public class TagEventDispatcher implements TagDispatcher { @Override public Tag alterTag(String metalake, String name, TagChange... changes) { - // TODO: alterTagPreEvent + AlterTagPreEvent preEvent = + new AlterTagPreEvent(PrincipalUtils.getCurrentUserName(), metalake, name, changes); + + eventBus.dispatchEvent(preEvent); try { // TODO: alterTagEvent return dispatcher.alterTag(metalake, name, changes); @@ -123,7 +140,10 @@ public class TagEventDispatcher implements TagDispatcher { @Override public boolean deleteTag(String metalake, String name) { - // TODO: deleteTagPreEvent + DeleteTagPreEvent preEvent = + new DeleteTagPreEvent(PrincipalUtils.getCurrentUserName(), metalake, name); + + eventBus.dispatchEvent(preEvent); try { // TODO: deleteTagEvent return dispatcher.deleteTag(metalake, name); @@ -136,7 +156,8 @@ public class TagEventDispatcher implements TagDispatcher { @Override public MetadataObject[] listMetadataObjectsForTag(String metalake, String name) { - // TODO: listMetadataObjectsForTagPreEvent + eventBus.dispatchEvent( + new ListMetadataObjectsForTagPreEvent(PrincipalUtils.getCurrentUserName(), metalake, name)); try { // TODO: listMetadataObjectsForTagEvent return dispatcher.listMetadataObjectsForTag(metalake, name); @@ -150,7 +171,10 @@ public class TagEventDispatcher implements TagDispatcher { @Override public String[] listTagsForMetadataObject(String metalake, MetadataObject metadataObject) { - // TODO: listTagsForMetadataObjectPreEvent + eventBus.dispatchEvent( + new ListTagsForMetadataObjectPreEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject)); + try { // TODO: listTagsForMetadataObjectEvent return dispatcher.listTagsForMetadataObject(metalake, metadataObject); @@ -164,7 +188,9 @@ public class TagEventDispatcher implements TagDispatcher { @Override public Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject metadataObject) { - // TODO: listTagsInfoForMetadataObjectPreEvent + eventBus.dispatchEvent( + new ListTagsInfoForMetadataObjectPreEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject)); try { // TODO: listTagsInfoForMetadataObjectEvent return dispatcher.listTagsInfoForMetadataObject(metalake, metadataObject); @@ -179,7 +205,14 @@ public class TagEventDispatcher implements TagDispatcher { @Override public String[] associateTagsForMetadataObject( String metalake, MetadataObject metadataObject, String[] tagsToAdd, String[] tagsToRemove) { - // TODO: associateTagsForMetadataObjectPreEvent + eventBus.dispatchEvent( + new AssociateTagsForMetadataObjectPreEvent( + PrincipalUtils.getCurrentUserName(), + metalake, + metadataObject, + tagsToAdd, + tagsToRemove)); + try { // TODO: associateTagsForMetadataObjectEvent return dispatcher.associateTagsForMetadataObject( @@ -199,7 +232,9 @@ public class TagEventDispatcher implements TagDispatcher { @Override public Tag getTagForMetadataObject(String metalake, MetadataObject metadataObject, String name) { - // TODO: getTagForMetadataObjectPreEvent + eventBus.dispatchEvent( + new GetTagForMetadataObjectPreEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, name)); try { // TODO: getTagForMetadataObjectEvent return dispatcher.getTagForMetadataObject(metalake, metadataObject, name); diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagPreEvent.java new file mode 100644 index 0000000000..1328d8418b --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagPreEvent.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.tag.TagChange; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** Represents an event triggered before altering a tag. */ +@DeveloperApi +public class AlterTagPreEvent extends TagPreEvent { + + private final TagChange[] changes; + + /** + * Constructs a new AlterTagPreEvent instance. + * + * @param user The user responsible for the operation. + * @param metalake The namespace of the tag. + * @param name The name of the tag being altered. + * @param changes The changes being applied to the tag. + */ + public AlterTagPreEvent(String user, String metalake, String name, TagChange[] changes) { + super(user, NameIdentifierUtil.ofTag(metalake, name)); + this.changes = changes; + } + + /** + * Returns the changes being applied to the tag. + * + * @return An array of {@link TagChange}. + */ + public TagChange[] changes() { + return changes; + } + + /** + * Returns the operation type for this event. + * + * @return The operation type {@link OperationType#ALTER_TAG}. + */ + @Override + public OperationType operationType() { + return OperationType.ALTER_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectPreEvent.java new file mode 100644 index 0000000000..6a2ea2a4b9 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectPreEvent.java @@ -0,0 +1,78 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** Represents an event triggered before associating tags with a specific metadata object. */ +@DeveloperApi +public class AssociateTagsForMetadataObjectPreEvent extends TagPreEvent { + private final String[] tagsToAdd; + private final String[] tagsToRemove; + + /** + * Constructs the pre-event with user, metalake, metadata object, tags to add, and tags to remove. + * + * @param user The user initiating the operation. + * @param metalake The metalake environment name. + * @param metadataObject The metadata object for which tags will be associated. + * @param tagsToAdd Tags to be added to the metadata object. + * @param tagsToRemove Tags to be removed from the metadata object. + */ + public AssociateTagsForMetadataObjectPreEvent( + String user, + String metalake, + MetadataObject metadataObject, + String[] tagsToAdd, + String[] tagsToRemove) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject)); + this.tagsToAdd = tagsToAdd; + this.tagsToRemove = tagsToRemove; + } + + /** + * Returns the tags to be added. + * + * @return Array of tag names to be added. + */ + public String[] tagsToAdd() { + return tagsToAdd; + } + + /** + * Returns the tags to be removed. + * + * @return Array of tag names to be removed. + */ + public String[] tagsToRemove() { + return tagsToRemove; + } + + /** + * Returns the operation type for this event. + * + * @return The operation type, which is ASSOCIATE_TAGS_FOR_METADATA_OBJECT. + */ + @Override + public OperationType operationType() { + return OperationType.ASSOCIATE_TAGS_FOR_METADATA_OBJECT; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagPreEvent.java new file mode 100644 index 0000000000..28db4b5119 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagPreEvent.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.info.TagInfo; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** Represents an event triggered before the creation of a tag. */ +@DeveloperApi +public class CreateTagPreEvent extends TagPreEvent { + private final TagInfo tagInfo; + + /** + * Constructs a new {@code CreateTagPreEvent} instance. + * + * @param user The user who initiated the tag creation operation. + * @param metalake The metalake name where the tag resides. + * @param tagInfo The information about the tag to be created. + */ + public CreateTagPreEvent(String user, String metalake, TagInfo tagInfo) { + super(user, NameIdentifierUtil.ofTag(metalake, tagInfo.name())); + this.tagInfo = tagInfo; + } + + /** + * Returns the information about the tag. + * + * @return the tag information + */ + public TagInfo tagInfo() { + return tagInfo; + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.CREATE_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagPreEvent.java new file mode 100644 index 0000000000..1dafdcc58b --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagPreEvent.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** Represents an event triggered before deleting a tag. */ +@DeveloperApi +public class DeleteTagPreEvent extends TagPreEvent { + + /** + * Constructs a new {@code DeleteTagPreEvent} instance. + * + * @param user The user who initiated the tag deletion operation. + * @param metalake The metalake name where the tag resides. + * @param name The name of the tag to delete. + */ + public DeleteTagPreEvent(String user, String metalake, String name) { + super(user, NameIdentifierUtil.ofTag(metalake, name)); + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.DELETE_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectPreEvent.java new file mode 100644 index 0000000000..cae41d954f --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectPreEvent.java @@ -0,0 +1,62 @@ +/* + * 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.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** Represents an event triggered before retrieving a tag for a specific metadata object. */ +@DeveloperApi +public class GetTagForMetadataObjectPreEvent extends TagPreEvent { + private final String tagName; + + /** + * Constructs the pre-event with user, metalake, metadata object, and tag name. + * + * @param user The user initiating the operation. + * @param metalake The metalake environment name. + * @param metadataObject The metadata object associated with the tag. + * @param name The name of the tag being retrieved. + */ + public GetTagForMetadataObjectPreEvent( + String user, String metalake, MetadataObject metadataObject, String name) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject)); + this.tagName = name; + } + + /** + * Returns the name of the tag being retrieved. + * + * @return The tag name. + */ + public String tagName() { + return tagName; + } + + /** + * Returns the operation type for this event. + * + * @return The operation type, which is GET_TAG_FOR_METADATA_OBJECT. + */ + @Override + public OperationType operationType() { + return OperationType.GET_TAG_FOR_METADATA_OBJECT; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagPreEvent.java new file mode 100644 index 0000000000..f4238f76ae --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagPreEvent.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.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** Represents an event triggered before getting a tag. */ +@DeveloperApi +public class GetTagPreEvent extends TagPreEvent { + /** + * Constructs a new {@code GetTagPreEvent} instance. + * + * @param user The user who initiated the get tag operation. + * @param metalake The metalake name where the tag resides. + * @param name The name of the tag to get. + */ + public GetTagPreEvent(String user, String metalake, String name) { + super(user, NameIdentifierUtil.ofTag(metalake, name)); + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.GET_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagPreEvent.java new file mode 100644 index 0000000000..0bcb3abb99 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagPreEvent.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.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** Represents a pre-event for listing metadata objects associated with a tag. */ +@DeveloperApi +public class ListMetadataObjectsForTagPreEvent extends TagPreEvent { + /** + * Constructs a new ListMetadataObjectsForTagPreEvent instance. + * + * @param user The user performing the operation. + * @param metalake The name of the Metalake environment. + * @param name The name of the tag. + */ + public ListMetadataObjectsForTagPreEvent(String user, String metalake, String name) { + super(user, NameIdentifierUtil.ofTag(metalake, name)); + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_METADATA_OBJECTS_FOR_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectPreEvent.java new file mode 100644 index 0000000000..f4ebc2abd3 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectPreEvent.java @@ -0,0 +1,49 @@ +/* + * 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.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** Represents an event triggered before listing tags for a metadata object. */ +@DeveloperApi +public class ListTagsForMetadataObjectPreEvent extends TagPreEvent { + /** + * Constructs a new {@code ListTagsForMetadataObjectPreEvent} instance. + * + * @param user The user who initiated the operation. + * @param metalake The metalake name where the metadata object resides. + * @param metadataObject The metadata object for which tags are being listed. + */ + public ListTagsForMetadataObjectPreEvent( + String user, String metalake, MetadataObject metadataObject) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject)); + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_TAGS_FOR_METADATA_OBJECT; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectPreEvent.java new file mode 100644 index 0000000000..6b03746e90 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectPreEvent.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.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** + * Represents an event triggered before listing detailed tag information for a specific metadata + * object. + */ +@DeveloperApi +public class ListTagsInfoForMetadataObjectPreEvent extends TagPreEvent { + /** + * Constructs the pre-event with user, metalake, and metadata object details. + * + * @param user The user initiating the operation. + * @param metalake The metalake environment name. + * @param metadataObject The metadata object for which tags' information will be listed. + */ + public ListTagsInfoForMetadataObjectPreEvent( + String user, String metalake, MetadataObject metadataObject) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject)); + } + + /** + * Returns the operation type for this event. + * + * @return The operation type, which is LIST_TAGS_INFO_FOR_METADATA_OBJECT. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_TAGS_INFO_FOR_METADATA_OBJECT; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoPreEvent.java new file mode 100644 index 0000000000..542fac5a73 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoPreEvent.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event triggered before listing tags info. */ +@DeveloperApi +public class ListTagsInfoPreEvent extends TagPreEvent { + /** + * Constructs a new {@code ListTagsInfoPreEvent} instance. + * + * @param user The user who initiated the tag listing operation. + * @param metalake The metalake name where the tags are being listed. + */ + public ListTagsInfoPreEvent(String user, String metalake) { + super(user, NameIdentifier.of(metalake)); + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_TAGS_INFO; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsPreEvent.java new file mode 100644 index 0000000000..e9f8013b46 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsPreEvent.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event triggered before listing tags. */ +@DeveloperApi +public class ListTagsPreEvent extends TagPreEvent { + /** + * Constructs a new {@code ListTagsPreEvent} instance. + * + * @param user The user who initiated the tag listing operation. + * @param metalake The metalake name where the tags are being listed. + */ + public ListTagsPreEvent(String user, String metalake) { + super(user, NameIdentifier.of(metalake)); + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.LIST_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/TagPreEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/TagPreEvent.java new file mode 100644 index 0000000000..4cdac415a1 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/TagPreEvent.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; + +/** Represents a pre-event for tag operations. */ +@DeveloperApi +public abstract class TagPreEvent extends PreEvent { + /** + * Constructs a new {@code TagPreEvent} instance. + * + * @param user The user who initiated the tag operation. + * @param identifier The identifier of the tag involved in the operation. + */ + protected TagPreEvent(String user, NameIdentifier identifier) { + super(user, identifier); + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.java b/core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.java index 20164f4c93..81d6444ab5 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.java @@ -16,7 +16,6 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.gravitino.listener.api.info; import com.google.common.collect.ImmutableMap; diff --git a/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java b/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java index 1ac3001bd2..2eaa2a5a41 100644 --- a/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java +++ b/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java @@ -24,15 +24,19 @@ import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; import java.util.Arrays; +import java.util.Objects; import org.apache.gravitino.Entity; import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.exceptions.GravitinoRuntimeException; import org.apache.gravitino.listener.DummyEventListener; import org.apache.gravitino.listener.EventBus; import org.apache.gravitino.listener.TagEventDispatcher; +import org.apache.gravitino.listener.api.info.TagInfo; import org.apache.gravitino.tag.Tag; import org.apache.gravitino.tag.TagChange; import org.apache.gravitino.tag.TagDispatcher; +import org.apache.gravitino.utils.MetadataObjectUtil; import org.apache.gravitino.utils.NameIdentifierUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; @@ -43,6 +47,7 @@ import org.junit.jupiter.api.TestInstance.Lifecycle; @TestInstance(Lifecycle.PER_CLASS) public class TestTagEvent { private TagEventDispatcher failureDispatcher; + private TagEventDispatcher dispatcher; private DummyEventListener dummyEventListener; private Tag tag; @@ -53,6 +58,183 @@ public class TestTagEvent { EventBus eventBus = new EventBus(Arrays.asList(dummyEventListener)); TagDispatcher tagExceptionDispatcher = mockExceptionTagDispatcher(); this.failureDispatcher = new TagEventDispatcher(eventBus, tagExceptionDispatcher); + TagDispatcher tagDispatcher = mockTagDispatcher(); + this.dispatcher = new TagEventDispatcher(eventBus, tagDispatcher); + } + + @Test + void testListTagsEvent() { + dispatcher.listTags("metalake"); + PreEvent preEvent = dummyEventListener.popPreEvent(); + + Assertions.assertEquals("metalake", Objects.requireNonNull(preEvent.identifier()).toString()); + Assertions.assertEquals(ListTagsPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.LIST_TAG, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testListTagsInfo() { + dispatcher.listTagsInfo("metalake"); + PreEvent preEvent = dummyEventListener.popPreEvent(); + + Assertions.assertEquals("metalake", Objects.requireNonNull(preEvent.identifier()).toString()); + Assertions.assertEquals(ListTagsInfoPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.LIST_TAGS_INFO, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testGetTag() { + dispatcher.getTag("metalake", tag.name()); + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = NameIdentifierUtil.ofTag("metalake", tag.name()); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(GetTagPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.GET_TAG, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testCreateTag() { + dispatcher.createTag("metalake", tag.name(), tag.comment(), tag.properties()); + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = NameIdentifierUtil.ofTag("metalake", tag.name()); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(CreateTagPreEvent.class, preEvent.getClass()); + + TagInfo tagInfo = ((CreateTagPreEvent) preEvent).tagInfo(); + Assertions.assertEquals(tag.name(), tagInfo.name()); + Assertions.assertEquals(tag.properties(), tagInfo.properties()); + Assertions.assertEquals(tag.comment(), tagInfo.comment()); + + Assertions.assertEquals(OperationType.CREATE_TAG, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testAlterTag() { + TagChange change1 = TagChange.rename("newName"); + TagChange[] changes = {change1}; + + dispatcher.alterTag("metalake", tag.name(), changes); + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = NameIdentifierUtil.ofTag("metalake", tag.name()); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(AlterTagPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.ALTER_TAG, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + + TagChange[] eventChanges = ((AlterTagPreEvent) preEvent).changes(); + Assertions.assertArrayEquals(changes, eventChanges); + } + + @Test + void testDeleteTag() { + dispatcher.deleteTag("metalake", tag.name()); + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = NameIdentifierUtil.ofTag("metalake", tag.name()); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(DeleteTagPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.DELETE_TAG, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testListMetadataObjectsForTag() { + dispatcher.listMetadataObjectsForTag("metalake", tag.name()); + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = NameIdentifierUtil.ofTag("metalake", tag.name()); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(ListMetadataObjectsForTagPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.LIST_METADATA_OBJECTS_FOR_TAG, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testListTagsForMetadataObject() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + dispatcher.listTagsForMetadataObject("metalake", metadataObject); + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = MetadataObjectUtil.toEntityIdent("metalake", metadataObject); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(ListTagsForMetadataObjectPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(OperationType.LIST_TAGS_FOR_METADATA_OBJECT, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testListTagsInfoForMetadataObject() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + dispatcher.listTagsInfoForMetadataObject("metalake", metadataObject); + + PreEvent preEvent = dummyEventListener.popPreEvent(); + NameIdentifier identifier = MetadataObjectUtil.toEntityIdent("metalake", metadataObject); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(ListTagsInfoForMetadataObjectPreEvent.class, preEvent.getClass()); + Assertions.assertEquals( + OperationType.LIST_TAGS_INFO_FOR_METADATA_OBJECT, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testAssociateTagsForMetadataObject() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + String[] tagsToAdd = {"tag1", "tag2"}; + String[] tagsToRemove = {"tag3"}; + + dispatcher.associateTagsForMetadataObject("metalake", metadataObject, tagsToAdd, tagsToRemove); + PreEvent preEvent = dummyEventListener.popPreEvent(); + + NameIdentifier identifier = MetadataObjectUtil.toEntityIdent("metalake", metadataObject); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(AssociateTagsForMetadataObjectPreEvent.class, preEvent.getClass()); + Assertions.assertArrayEquals( + tagsToAdd, ((AssociateTagsForMetadataObjectPreEvent) preEvent).tagsToAdd()); + Assertions.assertArrayEquals( + tagsToRemove, ((AssociateTagsForMetadataObjectPreEvent) preEvent).tagsToRemove()); + + Assertions.assertEquals( + OperationType.ASSOCIATE_TAGS_FOR_METADATA_OBJECT, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); + } + + @Test + void testGetTagForMetadataObject() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + dispatcher.getTagForMetadataObject("metalake", metadataObject, tag.name()); + PreEvent preEvent = dummyEventListener.popPreEvent(); + + NameIdentifier identifier = MetadataObjectUtil.toEntityIdent("metalake", metadataObject); + + Assertions.assertEquals(identifier.toString(), preEvent.identifier().toString()); + Assertions.assertEquals(GetTagForMetadataObjectPreEvent.class, preEvent.getClass()); + Assertions.assertEquals(tag.name(), ((GetTagForMetadataObjectPreEvent) preEvent).tagName()); + Assertions.assertEquals(OperationType.GET_TAG_FOR_METADATA_OBJECT, preEvent.operationType()); + Assertions.assertEquals(OperationStatus.UNPROCESSED, preEvent.operationStatus()); } @Test @@ -241,4 +423,9 @@ public class TestTagEvent { throw new GravitinoRuntimeException("Exception for all methods"); }); } + + private TagDispatcher mockTagDispatcher() { + TagDispatcher mockDispatcher = mock(TagDispatcher.class); + return mockDispatcher; + } }