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 90ca0fda23d..e1c6f8bdd5e 100644 --- a/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java +++ b/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java @@ -21,9 +21,22 @@ import java.util.Map; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.exceptions.NoSuchTagException; +import org.apache.gravitino.listener.api.event.AlterTagEvent; +import org.apache.gravitino.listener.api.event.AssociateTagsForMetadataObjectEvent; +import org.apache.gravitino.listener.api.event.CreateTagEvent; +import org.apache.gravitino.listener.api.event.DeleteTagEvent; +import org.apache.gravitino.listener.api.event.GetTagEvent; +import org.apache.gravitino.listener.api.event.GetTagForMetadataObjectEvent; +import org.apache.gravitino.listener.api.event.ListMetadataObjectsForTagEvent; +import org.apache.gravitino.listener.api.event.ListTagEvent; +import org.apache.gravitino.listener.api.event.ListTagInfoEvent; +import org.apache.gravitino.listener.api.event.ListTagsForMetadataObjectEvent; +import org.apache.gravitino.listener.api.event.ListTagsInfoForMetadataObjectEvent; +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.PrincipalUtils; /** * {@code TagEventDispatcher} is a decorator for {@link TagDispatcher} that not only delegates tag @@ -32,10 +45,7 @@ * of tag operations. */ public class TagEventDispatcher implements TagDispatcher { - @SuppressWarnings("unused") private final EventBus eventBus; - - @SuppressWarnings("unused") private final TagDispatcher dispatcher; public TagEventDispatcher(EventBus eventBus, TagDispatcher dispatcher) { @@ -47,8 +57,9 @@ public TagEventDispatcher(EventBus eventBus, TagDispatcher dispatcher) { public String[] listTags(String metalake) { // TODO: listTagsPreEvent try { - // TODO: listTagsEvent - return dispatcher.listTags(metalake); + String[] tagNames = dispatcher.listTags(metalake); + eventBus.dispatchEvent(new ListTagEvent(PrincipalUtils.getCurrentUserName(), metalake)); + return tagNames; } catch (Exception e) { // TODO: listTagFailureEvent throw e; @@ -59,8 +70,10 @@ public String[] listTags(String metalake) { public Tag[] listTagsInfo(String metalake) { // TODO: listTagsInfoPreEvent try { - // TODO: listTagsInfoEvent - return dispatcher.listTagsInfo(metalake); + Tag[] tags = dispatcher.listTagsInfo(metalake); + eventBus.dispatchEvent( + new ListTagInfoEvent(PrincipalUtils.getCurrentUserName(), metalake, tags)); + return tags; } catch (Exception e) { // TODO: listTagsInfoFailureEvent throw e; @@ -71,8 +84,10 @@ public Tag[] listTagsInfo(String metalake) { public Tag getTag(String metalake, String name) throws NoSuchTagException { // TODO: getTagPreEvent try { - // TODO: getTagEvent - return dispatcher.getTag(metalake, name); + Tag tag = dispatcher.getTag(metalake, name); + eventBus.dispatchEvent( + new GetTagEvent(PrincipalUtils.getCurrentUserName(), metalake, name, tag)); + return tag; } catch (NoSuchTagException e) { // TODO: getTagFailureEvent throw e; @@ -84,8 +99,13 @@ public Tag createTag( String metalake, String name, String comment, Map properties) { // TODO: createTagPreEvent try { - // TODO: createTagEvent - return dispatcher.createTag(metalake, name, comment, properties); + Tag tag = dispatcher.createTag(metalake, name, comment, properties); + eventBus.dispatchEvent( + new CreateTagEvent( + PrincipalUtils.getCurrentUserName(), + metalake, + new TagInfo(tag.name(), tag.comment(), tag.properties()))); + return tag; } catch (Exception e) { // TODO: createTagFailureEvent throw e; @@ -96,8 +116,14 @@ public Tag createTag( public Tag alterTag(String metalake, String name, TagChange... changes) { // TODO: alterTagPreEvent try { - // TODO: alterTagEvent - return dispatcher.alterTag(metalake, name, changes); + Tag tag = dispatcher.alterTag(metalake, name, changes); + eventBus.dispatchEvent( + new AlterTagEvent( + PrincipalUtils.getCurrentUserName(), + metalake, + changes, + new TagInfo(tag.name(), tag.comment(), tag.properties()))); + return tag; } catch (Exception e) { // TODO: alterTagFailureEvent throw e; @@ -108,8 +134,10 @@ public Tag alterTag(String metalake, String name, TagChange... changes) { public boolean deleteTag(String metalake, String name) { // TODO: deleteTagPreEvent try { - // TODO: deleteTagEvent - return dispatcher.deleteTag(metalake, name); + boolean isExists = dispatcher.deleteTag(metalake, name); + eventBus.dispatchEvent( + new DeleteTagEvent(PrincipalUtils.getCurrentUserName(), metalake, isExists)); + return isExists; } catch (Exception e) { // TODO: deleteTagFailureEvent throw e; @@ -120,8 +148,11 @@ public boolean deleteTag(String metalake, String name) { public MetadataObject[] listMetadataObjectsForTag(String metalake, String name) { // TODO: listMetadataObjectsForTagPreEvent try { - // TODO: listMetadataObjectsForTagEvent - return dispatcher.listMetadataObjectsForTag(metalake, name); + MetadataObject[] metadataObjects = dispatcher.listMetadataObjectsForTag(metalake, name); + eventBus.dispatchEvent( + new ListMetadataObjectsForTagEvent( + PrincipalUtils.getCurrentUserName(), metalake, name, metadataObjects)); + return metadataObjects; } catch (Exception e) { // TODO: listMetadataObjectsForTagFailureEvent throw e; @@ -132,8 +163,11 @@ public MetadataObject[] listMetadataObjectsForTag(String metalake, String name) public String[] listTagsForMetadataObject(String metalake, MetadataObject metadataObject) { // TODO: listTagsForMetadataObjectPreEvent try { - // TODO: listTagsForMetadataObjectEvent - return dispatcher.listTagsForMetadataObject(metalake, metadataObject); + String[] tags = dispatcher.listTagsForMetadataObject(metalake, metadataObject); + eventBus.dispatchEvent( + new ListTagsForMetadataObjectEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, tags)); + return tags; } catch (Exception e) { // TODO: listTagsForMetadataObjectFailureEvent throw e; @@ -144,8 +178,11 @@ public String[] listTagsForMetadataObject(String metalake, MetadataObject metada public Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject metadataObject) { // TODO: listTagsInfoForMetadataObjectPreEvent try { - // TODO: listTagsInfoForMetadataObjectEvent - return dispatcher.listTagsInfoForMetadataObject(metalake, metadataObject); + Tag[] tags = dispatcher.listTagsInfoForMetadataObject(metalake, metadataObject); + eventBus.dispatchEvent( + new ListTagsInfoForMetadataObjectEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, tags)); + return tags; } catch (Exception e) { // TODO: listTagsInfoForMetadataObjectFailureEvent throw e; @@ -157,9 +194,18 @@ public String[] associateTagsForMetadataObject( String metalake, MetadataObject metadataObject, String[] tagsToAdd, String[] tagsToRemove) { // TODO: associateTagsForMetadataObjectPreEvent try { - // TODO: associateTagsForMetadataObjectEvent - return dispatcher.associateTagsForMetadataObject( - metalake, metadataObject, tagsToAdd, tagsToRemove); + String[] associatedTags = + dispatcher.associateTagsForMetadataObject( + metalake, metadataObject, tagsToAdd, tagsToRemove); + eventBus.dispatchEvent( + new AssociateTagsForMetadataObjectEvent( + PrincipalUtils.getCurrentUserName(), + metalake, + metadataObject, + tagsToAdd, + tagsToRemove, + associatedTags)); + return associatedTags; } catch (Exception e) { // TODO: associateTagsForMetadataObjectFailureEvent throw e; @@ -170,8 +216,11 @@ public String[] associateTagsForMetadataObject( public Tag getTagForMetadataObject(String metalake, MetadataObject metadataObject, String name) { // TODO: getTagForMetadataObjectPreEvent try { - // TODO: getTagForMetadataObjectEvent - return dispatcher.getTagForMetadataObject(metalake, metadataObject, name); + Tag tag = dispatcher.getTagForMetadataObject(metalake, metadataObject, name); + eventBus.dispatchEvent( + new GetTagForMetadataObjectEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, name, tag)); + return tag; } catch (Exception e) { // TODO: getTagForMetadataObjectFailureEvent throw e; diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagEvent.java new file mode 100644 index 00000000000..40942464f3f --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagEvent.java @@ -0,0 +1,79 @@ +/* + * 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.TagInfo; +import org.apache.gravitino.tag.TagChange; + +/** Represents an event triggered upon the successful alteration of a tag. */ +@DeveloperApi +public final class AlterTagEvent extends TagEvent { + private final TagInfo updatedTagInfo; + private final TagChange[] tagChanges; + + /** + * Constructs an instance of {@code AlterTagEvent}, encapsulating the key details about the + * successful alteration of a tag. + * + * @param user The username of the individual responsible for initiating the tag alteration. + * @param metalake The metalake from which the tag is being altered. + * @param tagChanges An array of {@link TagChange} objects representing the specific changes + * applied to the tag during the alteration process. + * @param updatedTagInfo The post-alteration state of the tag. + */ + public AlterTagEvent( + String user, String metalake, TagChange[] tagChanges, TagInfo updatedTagInfo) { + super(user, NameIdentifier.of(metalake)); + this.tagChanges = tagChanges.clone(); + this.updatedTagInfo = updatedTagInfo; + } + + /** + * Retrieves the final state of the tag as it was returned to the user after successful + * alteration. + * + * @return A {@link TagInfo} instance encapsulating the comprehensive details of the newly altered + * tag. + */ + public TagInfo updatedTagInfo() { + return updatedTagInfo; + } + + /** + * Retrieves the specific changes that were made to the tag during the alteration process. + * + * @return An array of {@link TagChange} objects detailing each modification applied to the tag. + */ + public TagChange[] tagChanges() { + return tagChanges; + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.ALTER_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectEvent.java new file mode 100644 index 00000000000..bd99533f2e5 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectEvent.java @@ -0,0 +1,116 @@ +/* + * 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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** + * Represents an event that is triggered upon successfully associating tags with a metadata object. + */ +@DeveloperApi +public final class AssociateTagsForMetadataObjectEvent extends TagEvent { + private final String metalake; + private final MetadataObject metadataObject; + private final String[] tagsToAdd; + private final String[] tagsToRemove; + private final String[] associatedTags; + + /** + * Constructs an instance of {@code AssociateTagsForMetadataObjectEvent}. + * + * @param user The username of the individual who initiated the tag association. + * @param metalake The metalake from which the tags were associated. + * @param metadataObject The metadata object with which the tags were associated. + * @param tagsToAdd The tags that were added. + * @param tagsToRemove The tags that were removed. + * @param associatedTags The resulting list of associated tags after the operation. + */ + public AssociateTagsForMetadataObjectEvent( + String user, + String metalake, + MetadataObject metadataObject, + String[] tagsToAdd, + String[] tagsToRemove, + String[] associatedTags) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + this.metadataObject = metadataObject; + this.tagsToAdd = tagsToAdd; + this.tagsToRemove = tagsToRemove; + this.associatedTags = associatedTags; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which the tags were associated. + */ + public String metalake() { + return metalake; + } + + /** + * Provides the metadata object associated with this event. + * + * @return The {@link MetadataObject} with which the tags were associated. + */ + public MetadataObject metadataObject() { + return metadataObject; + } + + /** + * Provides the tags that were added in this operation. + * + * @return An array of tag names that were added. + */ + public String[] tagsToAdd() { + return tagsToAdd; + } + + /** + * Provides the tags that were removed in this operation. + * + * @return An array of tag names that were removed. + */ + public String[] tagsToRemove() { + return tagsToRemove; + } + + /** + * Provides the resulting list of associated tags after the operation. + * + * @return An array of tag names representing the associated tags. + */ + public String[] associatedTags() { + return associatedTags; + } + + /** + * Returns the type of operation. + * + * @return The operation type. + */ + @Override + public OperationType operationType() { + return OperationType.ASSOCIATE_TAGS_FOR_METADATA_OBJECT; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagEvent.java new file mode 100644 index 00000000000..f6e9d0deeb8 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagEvent.java @@ -0,0 +1,64 @@ +/* + * 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.TagInfo; + +/** Represents an event that is activated upon the successful creation of a tag. */ +@DeveloperApi +public final class CreateTagEvent extends TagEvent { + private final TagInfo createdTagInfo; + + /** + * Constructs an instance of {@code CreateTagEvent}, capturing essential details about the + * successful creation of a tag. + * + * @param user The username of the individual who initiated the tag creation. + * @param metalake The metalake from which the tag was created. + * @param createdTagInfo The final state of the tag post-creation. + */ + public CreateTagEvent(String user, String metalake, TagInfo createdTagInfo) { + super(user, NameIdentifier.of(metalake)); + this.createdTagInfo = createdTagInfo; + } + + /** + * Provides the final state of the tag as it is presented to the user following the successful + * creation. + * + * @return A {@link TagInfo} object that encapsulates the detailed characteristics of the newly + * created tag. + */ + public TagInfo createdTagInfo() { + return createdTagInfo; + } + + /** + * 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/DeleteTagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagEvent.java new file mode 100644 index 00000000000..2ea84445970 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagEvent.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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event that is generated after a tag is successfully deleted. */ +@DeveloperApi +public final class DeleteTagEvent extends TagEvent { + private final boolean isExists; + + /** + * Constructs a new {@code DeleteTagEvent} instance, encapsulating information about the outcome + * of a tag delete operation. + * + * @param user The user who initiated the delete tag operation. + * @param metalake The metalake from which the tag was deleted. + * @param isExists A boolean flag indicating whether the tag existed at the time of the delete + * operation. + */ + public DeleteTagEvent(String user, String metalake, boolean isExists) { + super(user, NameIdentifier.of(metalake)); + this.isExists = isExists; + } + + /** + * Retrieves the existence status of the tag at the time of the delete operation. + * + * @return A boolean value indicating whether the tag existed. {@code true} if the tag existed, + * otherwise {@code false}. + */ + public boolean isExists() { + return isExists; + } + + /** + * 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/GetTagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagEvent.java new file mode 100644 index 00000000000..a95a01817ab --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagEvent.java @@ -0,0 +1,84 @@ +/* + * 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.tag.Tag; + +/** Represents an event that is triggered upon successfully retrieving a tag. */ +@DeveloperApi +public final class GetTagEvent extends TagEvent { + private final String metalake; + private final String tagName; + private final Tag tag; + + /** + * Constructs an instance of {@code GetTagEvent}. + * + * @param user The username of the individual who initiated the tag retrieval. + * @param metalake The metalake from which the tag was retrieved. + * @param tagName The name of the tag being retrieved. + * @param tag The {@link Tag} object representing the retrieved tag. + */ + public GetTagEvent(String user, String metalake, String tagName, Tag tag) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + this.tagName = tagName; + this.tag = tag; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which the tag was retrieved. + */ + public String metalake() { + return metalake; + } + + /** + * Provides the name of the retrieved tag. + * + * @return The name of the tag. + */ + public String tagName() { + return tagName; + } + + /** + * Provides the retrieved tag object. + * + * @return The {@link Tag} object. + */ + public Tag tag() { + return tag; + } + + /** + * 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/GetTagForMetadataObjectEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectEvent.java new file mode 100644 index 00000000000..38723d038ea --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectEvent.java @@ -0,0 +1,100 @@ +/* + * 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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.tag.Tag; + +/** + * Represents an event that is triggered upon successfully retrieving a tag for a metadata object. + */ +@DeveloperApi +public final class GetTagForMetadataObjectEvent extends TagEvent { + private final String metalake; + private final MetadataObject metadataObject; + private final String tagName; + private final Tag tag; + + /** + * Constructs an instance of {@code GetTagForMetadataObjectEvent}. + * + * @param user The username of the individual who initiated the tag retrieval. + * @param metalake The metalake from which the tag was retrieved. + * @param metadataObject The metadata object for which the tag was retrieved. + * @param tagName The name of the tag being retrieved. + * @param tag The {@link Tag} object representing the retrieved tag. + */ + public GetTagForMetadataObjectEvent( + String user, String metalake, MetadataObject metadataObject, String tagName, Tag tag) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + this.metadataObject = metadataObject; + this.tagName = tagName; + this.tag = tag; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which the tag was retrieved. + */ + public String metalake() { + return metalake; + } + + /** + * Provides the metadata object associated with this event. + * + * @return The {@link MetadataObject} for which the tag was retrieved. + */ + public MetadataObject metadataObject() { + return metadataObject; + } + + /** + * Provides the name of the retrieved tag. + * + * @return The name of the tag. + */ + public String tagName() { + return tagName; + } + + /** + * Provides the retrieved tag object. + * + * @return The {@link Tag} object. + */ + public Tag tag() { + return tag; + } + + /** + * Returns the type of operation. + * + * @return The operation type. + */ + @Override + public OperationType operationType() { + return OperationType.GET_TAG_FOR_METADATA_OBJECT; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagEvent.java new file mode 100644 index 00000000000..d081a366b4f --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagEvent.java @@ -0,0 +1,86 @@ +/* + * 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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event that is triggered upon successfully listing metadata objects for a tag. */ +@DeveloperApi +public final class ListMetadataObjectsForTagEvent extends TagEvent { + private final String metalake; + private final String tagName; + private final MetadataObject[] metadataObjects; + + /** + * Constructs an instance of {@code ListMetadataObjectsForTagEvent}. + * + * @param user The username of the individual who initiated the metadata objects listing. + * @param metalake The metalake from which metadata objects were listed. + * @param tagName The name of the tag for which metadata objects were listed. + * @param metadataObjects An array of {@link MetadataObject} representing the listed metadata + * objects. + */ + public ListMetadataObjectsForTagEvent( + String user, String metalake, String tagName, MetadataObject[] metadataObjects) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + this.tagName = tagName; + this.metadataObjects = metadataObjects; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which metadata objects were listed. + */ + public String metalake() { + return metalake; + } + + /** + * Provides the name of the tag associated with this event. + * + * @return The name of the tag. + */ + public String tagName() { + return tagName; + } + + /** + * Provides the metadata objects associated with this event. + * + * @return An array of {@link MetadataObject}. + */ + public MetadataObject[] metadataObjects() { + return metadataObjects; + } + + /** + * 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/ListTagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagEvent.java new file mode 100644 index 00000000000..6b4000e5ee2 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagEvent.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event that is triggered upon the successful listing of tags. */ +@DeveloperApi +public final class ListTagEvent extends TagEvent { + private final String metalake; + + /** + * Constructs an instance of {@code ListTagEvent}. + * + * @param user The username of the individual who initiated the tag listing. + * @param metalake The namespace from which tags were listed. + */ + public ListTagEvent(String user, String metalake) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which tags were listed. + */ + public String metalake() { + return 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/ListTagInfoEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagInfoEvent.java new file mode 100644 index 00000000000..1e70d9f7622 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagInfoEvent.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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.tag.Tag; + +/** Represents an event that is triggered upon the successful listing of tags. */ +@DeveloperApi +public final class ListTagInfoEvent extends TagEvent { + private final Tag[] tags; + + /** + * Constructs an instance of {@code ListTagsEvent}. + * + * @param user The username of the individual who initiated the tag listing. + * @param metalake The namespace from which tags were listed. + * @param tags An array of {@link Tag} objects representing the tags. + */ + public ListTagInfoEvent(String user, String metalake, Tag[] tags) { + super(user, NameIdentifier.of(metalake)); + this.tags = tags; + } + + /** + * Provides the tags associated with this event. + * + * @return An array of {@link Tag} objects. + */ + public Tag[] tags() { + return tags; + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.LISTINFO_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectEvent.java new file mode 100644 index 00000000000..60432af8c89 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectEvent.java @@ -0,0 +1,85 @@ +/* + * 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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event that is triggered upon successfully listing tags for a metadata object. */ +@DeveloperApi +public final class ListTagsForMetadataObjectEvent extends TagEvent { + private final String metalake; + private final MetadataObject metadataObject; + private final String[] tags; + + /** + * Constructs an instance of {@code ListTagsForMetadataObjectEvent}. + * + * @param user The username of the individual who initiated the tag listing. + * @param metalake The metalake from which tags were listed. + * @param metadataObject The metadata object for which tags were listed. + * @param tags An array of tag names representing the tags listed for the metadata object. + */ + public ListTagsForMetadataObjectEvent( + String user, String metalake, MetadataObject metadataObject, String[] tags) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + this.metadataObject = metadataObject; + this.tags = tags; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which tags were listed. + */ + public String metalake() { + return metalake; + } + + /** + * Provides the metadata object associated with this event. + * + * @return The {@link MetadataObject} for which tags were listed. + */ + public MetadataObject metadataObject() { + return metadataObject; + } + + /** + * Provides the tags associated with this event. + * + * @return An array of tag names. + */ + public String[] tags() { + return tags; + } + + /** + * 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/ListTagsInfoForMetadataObjectEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectEvent.java new file mode 100644 index 00000000000..f5bebe57937 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectEvent.java @@ -0,0 +1,89 @@ +/* + * 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.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.tag.Tag; + +/** + * Represents an event that is triggered upon successfully listing detailed tag information for a + * metadata object. + */ +@DeveloperApi +public final class ListTagsInfoForMetadataObjectEvent extends TagEvent { + private final String metalake; + private final MetadataObject metadataObject; + private final Tag[] tags; + + /** + * Constructs an instance of {@code ListTagsInfoForMetadataObjectEvent}. + * + * @param user The username of the individual who initiated the tag information listing. + * @param metalake The metalake from which tag information was listed. + * @param metadataObject The metadata object for which tag information was listed. + * @param tags An array of {@link Tag} objects representing the detailed tag information. + */ + public ListTagsInfoForMetadataObjectEvent( + String user, String metalake, MetadataObject metadataObject, Tag[] tags) { + super(user, NameIdentifier.of(metalake)); + this.metalake = metalake; + this.metadataObject = metadataObject; + this.tags = tags; + } + + /** + * Provides the metalake associated with this event. + * + * @return The metalake from which tag information was listed. + */ + public String metalake() { + return metalake; + } + + /** + * Provides the metadata object associated with this event. + * + * @return The {@link MetadataObject} for which tag information was listed. + */ + public MetadataObject metadataObject() { + return metadataObject; + } + + /** + * Provides the detailed tag information associated with this event. + * + * @return An array of {@link Tag} objects. + */ + public Tag[] tags() { + return tags; + } + + /** + * Returns the type of operation. + * + * @return The operation type. + */ + @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/OperationType.java b/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java index 00cbf1e1a4e..9c22684bf50 100644 --- a/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/OperationType.java @@ -86,5 +86,18 @@ public enum OperationType { RENAME_VIEW, LIST_VIEW, + // Tag event + CREATE_TAG, + ALTER_TAG, + LIST_TAG, + DELETE_TAG, + LISTINFO_TAG, + GET_TAG, + LIST_METADATA_OBJECTS_FOR_TAG, + LIST_TAGS_FOR_METADATA_OBJECT, + LIST_TAGS_INFO_FOR_METADATA_OBJECT, + ASSOCIATE_TAGS_FOR_METADATA_OBJECT, + GET_TAG_FOR_METADATA_OBJECT, + UNKNOWN, } diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/TagEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/TagEvent.java new file mode 100644 index 00000000000..e7f59ca9881 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/TagEvent.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 abstract base class for events related to tag operations. This class extends {@link + * Event} to provide a more specific context involving operations on tags, such as creation, + * deletion, or modification. + */ +@DeveloperApi +public abstract class TagEvent extends Event { + /** + * Constructs a new {@code TagEvent} with the specified user and tag identifier. + * + * @param user The user responsible for triggering the tag operation. + * @param identifier The identifier of the tag involved in the operation. + */ + protected TagEvent(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/info/TagInfo.java b/core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.java new file mode 100644 index 00000000000..20164f4c931 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.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.info; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import javax.annotation.Nullable; +import org.apache.gravitino.annotation.DeveloperApi; + +/** + * Provides access to metadata about a Tag instance, designed for use by event listeners. This class + * encapsulates the essential attributes of a Tag, including its name, optional description, + * properties, and audit information. + */ +@DeveloperApi +public final class TagInfo { + private final String name; + @Nullable private final String comment; + private final Map properties; + + /** + * Directly constructs TagInfo with specified details. + * + * @param name The name of the Tag. + * @param comment An optional description for the Tag. + * @param properties A map of properties associated with the Tag. + */ + public TagInfo(String name, String comment, Map properties) { + this.name = name; + this.comment = comment; + this.properties = properties == null ? ImmutableMap.of() : ImmutableMap.copyOf(properties); + } + + /** + * Returns the name of the Tag. + * + * @return The Tag's name. + */ + public String name() { + return name; + } + + /** + * Returns the optional comment describing the Tag. + * + * @return The comment, or null if not provided. + */ + @Nullable + public String comment() { + return comment; + } + + /** + * Returns the properties of the Tag. + * + * @return A map of Tag properties. + */ + public Map properties() { + return properties; + } +} 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 new file mode 100644 index 00000000000..ab8bcd8d6e3 --- /dev/null +++ b/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java @@ -0,0 +1,174 @@ +package org.apache.gravitino.listener.api.event; + +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +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.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.TestInstance; +import org.testcontainers.shaded.com.google.common.collect.ImmutableMap; + +import java.util.Arrays; +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class TestTagEvent { + private TagEventDispatcher dispatcher; + private TagEventDispatcher failureDispatcher; + private DummyEventListener dummyEventListener; + private Tag tag; + + @BeforeAll + void init() { + this.tag = mockTag(); + this.dummyEventListener = new DummyEventListener(); + EventBus eventBus = new EventBus(Arrays.asList(dummyEventListener)); + TagDispatcher tagDispatcher = mockTagDispatcher(); + this.dispatcher = new TagEventDispatcher(eventBus, tagDispatcher); + } + + @Test + void testCreateTagEvent() { + String metalake = "metalake"; + NameIdentifier identifier = NameIdentifier.of(metalake); + TagInfo tagInfo = new TagInfo("tagName", "test comment", ImmutableMap.of("key", "value")); + + dispatcher.createTag(metalake, tagInfo.name(), tagInfo.comment(), tagInfo.properties()); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(CreateTagEvent.class, event.getClass()); + Assertions.assertEquals(tagInfo.name(), ((CreateTagEvent) event).createdTagInfo().name()); + Assertions.assertEquals(tagInfo.comment(), ((CreateTagEvent) event).createdTagInfo().comment()); + Assertions.assertEquals(tagInfo.properties(), ((CreateTagEvent) event).createdTagInfo().properties()); + Assertions.assertEquals(OperationType.CREATE_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testListTagsEvent() { + String metalake = "metalake"; + NameIdentifier identifier = NameIdentifier.of(metalake); + String[] tagNames = new String[] {"tag1", "tag2"}; + + when(dispatcher.listTags(metalake)).thenReturn(tagNames); + + String[] result = dispatcher.listTags(metalake); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(ListTagEvent.class, event.getClass()); + Assertions.assertEquals(metalake, ((ListTagEvent)event).metalake()); + Assertions.assertEquals(OperationType.LIST_TAG, event.operationType()); + Assertions.assertArrayEquals(tagNames, result); + } + + @Test + void testAlterTagEvent() { + String metalake = "metalake"; + String tagName = "testTag"; + NameIdentifier identifier = NameIdentifier.of(metalake); + TagChange[] changes = new TagChange[] {TagChange.setProperty("key", "value")}; + + when(dispatcher.alterTag(metalake, tagName, changes)).thenReturn(tag); + + Tag result = dispatcher.alterTag(metalake, tagName, changes); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(AlterTagEvent.class, event.getClass()); + Assertions.assertEquals(tag.name(), ((AlterTagEvent) event).updatedTagInfo().name()); + Assertions.assertEquals(tag.comment(), ((AlterTagEvent) event).updatedTagInfo().comment()); + Assertions.assertEquals(tag.properties(), ((AlterTagEvent) event).updatedTagInfo().properties()); + Assertions.assertEquals(OperationType.ALTER_TAG, event.operationType()); + } + + + @Test + void testListTagsInfoEvent() { + String metalake = "metalake"; + NameIdentifier identifier = NameIdentifier.of(metalake); + Tag[] tags = new Tag[] {tag, tag}; + + when(dispatcher.listTagsInfo(metalake)).thenReturn(tags); + + Tag[] result = dispatcher.listTagsInfo(metalake); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(ListTagInfoEvent.class, event.getClass()); + Assertions.assertEquals(OperationType.LISTINFO_TAG, event.operationType()); + Assertions.assertArrayEquals(tags, result); + } + + @Test + void testGetTagEvent() { + String metalake = "metalake"; + String tagName = "testTag"; + NameIdentifier identifier = NameIdentifier.of(metalake, tagName); + + when(dispatcher.getTag(metalake, tagName)).thenReturn(tag); + + Tag result = dispatcher.getTag(metalake, tagName); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(GetTagEvent.class, event.getClass()); + Assertions.assertEquals(metalake, ((GetTagEvent) event).metalake()); + Assertions.assertEquals(tagName, ((GetTagEvent) event).tagName()); + Assertions.assertEquals(tag, ((GetTagEvent) event).tag()); + Assertions.assertEquals(OperationType.GET_TAG, event.operationType()); + } + + @Test + void testDeleteTagEvent() { + String metalake = "metalake"; + String tagName = "testTag"; + NameIdentifier identifier = NameIdentifier.of(metalake, tagName); + + when(dispatcher.deleteTag(metalake, tagName)).thenReturn(true); + + boolean result = dispatcher.deleteTag(metalake, tagName); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(identifier, event.identifier()); + Assertions.assertEquals(DeleteTagEvent.class, event.getClass()); + Assertions.assertTrue(((DeleteTagEvent) event).isExists()); + Assertions.assertEquals(OperationType.DELETE_TAG, event.operationType()); + Assertions.assertTrue(result); + } + + + + + + private Tag mockTag() { + Tag tag = mock(Tag.class); + when(tag.name()).thenReturn("tagName"); + when(tag.comment()).thenReturn("test comment"); + when(tag.properties()).thenReturn(ImmutableMap.of("key", "value")); + return tag; + } + + private TagDispatcher mockTagDispatcher() { + TagDispatcher dispatcher = mock(TagDispatcher.class); + when(dispatcher.createTag( + any(String.class), any(String.class), any(String.class), any(Map.class))) + .thenReturn(tag); + return dispatcher; + } + +}