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 302d82a93c7..da0052ea73e 100644 --- a/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java +++ b/core/src/main/java/org/apache/gravitino/listener/TagEventDispatcher.java @@ -21,16 +21,27 @@ 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.AlterTagFailureEvent; +import org.apache.gravitino.listener.api.event.AssociateTagsForMetadataObjectEvent; import org.apache.gravitino.listener.api.event.AssociateTagsForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.CreateTagEvent; import org.apache.gravitino.listener.api.event.CreateTagFailureEvent; +import org.apache.gravitino.listener.api.event.DeleteTagEvent; import org.apache.gravitino.listener.api.event.DeleteTagFailureEvent; +import org.apache.gravitino.listener.api.event.GetTagEvent; import org.apache.gravitino.listener.api.event.GetTagFailureEvent; +import org.apache.gravitino.listener.api.event.GetTagForMetadataObjectEvent; import org.apache.gravitino.listener.api.event.GetTagForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.ListMetadataObjectsForTagEvent; import org.apache.gravitino.listener.api.event.ListMetadataObjectsForTagFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagEvent; +import org.apache.gravitino.listener.api.event.ListTagInfoEvent; import org.apache.gravitino.listener.api.event.ListTagsFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsForMetadataObjectEvent; import org.apache.gravitino.listener.api.event.ListTagsForMetadataObjectFailureEvent; import org.apache.gravitino.listener.api.event.ListTagsInfoFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsInfoForMetadataObjectEvent; import org.apache.gravitino.listener.api.event.ListTagsInfoForMetadataObjectFailureEvent; import org.apache.gravitino.listener.api.info.TagInfo; import org.apache.gravitino.tag.Tag; @@ -57,8 +68,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) { eventBus.dispatchEvent( new ListTagsFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, e)); @@ -70,8 +82,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) { eventBus.dispatchEvent( new ListTagsInfoFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, e)); @@ -83,8 +97,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 (Exception e) { eventBus.dispatchEvent( new GetTagFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, name, e)); @@ -98,8 +114,13 @@ public Tag createTag( TagInfo tagInfo = new TagInfo(name, comment, 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) { eventBus.dispatchEvent( new CreateTagFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, tagInfo, e)); @@ -111,8 +132,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) { eventBus.dispatchEvent( new AlterTagFailureEvent( @@ -125,8 +152,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) { eventBus.dispatchEvent( new DeleteTagFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, name, e)); @@ -138,8 +167,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) { eventBus.dispatchEvent( new ListMetadataObjectsForTagFailureEvent( @@ -152,8 +184,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) { eventBus.dispatchEvent( new ListTagsForMetadataObjectFailureEvent( @@ -166,8 +201,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) { eventBus.dispatchEvent( new ListTagsInfoForMetadataObjectFailureEvent( @@ -181,9 +219,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) { eventBus.dispatchEvent( new AssociateTagsForMetadataObjectFailureEvent( @@ -201,8 +248,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) { eventBus.dispatchEvent( new GetTagForMetadataObjectFailureEvent( 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..48b4074287a --- /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.LIST_TAGS_INFO; + } +} 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/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/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java b/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java index 1ac3001bd2c..f76004b7ed9 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 @@ -19,17 +19,21 @@ package org.apache.gravitino.listener.api.event; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableMap; import java.util.Arrays; +import java.util.Map; import org.apache.gravitino.Entity; import org.apache.gravitino.MetadataObject; 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; @@ -42,6 +46,7 @@ @TestInstance(Lifecycle.PER_CLASS) public class TestTagEvent { + private TagEventDispatcher dispatcher; private TagEventDispatcher failureDispatcher; private DummyEventListener dummyEventListener; private Tag tag; @@ -51,10 +56,167 @@ 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); TagDispatcher tagExceptionDispatcher = mockExceptionTagDispatcher(); this.failureDispatcher = new TagEventDispatcher(eventBus, tagExceptionDispatcher); } + @Test + void testCreateTagEvent() { + dispatcher.createTag("metalake", tag.name(), tag.comment(), tag.properties()); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(CreateTagEvent.class, event.getClass()); + TagInfo tagInfo = ((CreateTagEvent) event).createdTagInfo(); + checkTagInfo(tagInfo, tag); + Assertions.assertEquals(OperationType.CREATE_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testGetTagEvent() { + String metalake = "metalake"; + + dispatcher.getTag(metalake, tag.name()); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(GetTagEvent.class, event.getClass()); + Assertions.assertEquals(OperationType.GET_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testListTagEvent() { + dispatcher.listTags("metalake"); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListTagEvent.class, event.getClass()); + Assertions.assertEquals(OperationType.LIST_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testListTagInfoEvent() { + Tag[] result = dispatcher.listTagsInfo("metalake"); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListTagInfoEvent.class, event.getClass()); + Assertions.assertEquals(OperationType.LIST_TAGS_INFO, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + Assertions.assertEquals(result, ((ListTagInfoEvent) event).tags()); + } + + @Test + void testAlterTagEvent() { + TagChange change1 = TagChange.rename("newName"); + TagChange change2 = TagChange.updateComment("new comment"); + TagChange change3 = TagChange.setProperty("key", "value"); + TagChange change4 = TagChange.removeProperty("oldKey"); + TagChange[] changes = new TagChange[] {change1, change2, change3, change4}; + dispatcher.alterTag("metalake", tag.name(), changes); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(AlterTagEvent.class, event.getClass()); + TagInfo tagInfo = ((AlterTagEvent) event).updatedTagInfo(); + checkTagInfo(tagInfo, tag); + Assertions.assertEquals(changes, ((AlterTagEvent) event).tagChanges()); + Assertions.assertEquals(OperationType.ALTER_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testDeleteTagEvent() { + dispatcher.deleteTag("metalake", tag.name()); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(DeleteTagEvent.class, event.getClass()); + Assertions.assertEquals(OperationType.DELETE_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testGetTagForMetadataObjectEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + dispatcher.getTagForMetadataObject("metalake", metadataObject, tag.name()); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(GetTagForMetadataObjectEvent.class, event.getClass()); + Assertions.assertEquals( + metadataObject, ((GetTagForMetadataObjectEvent) event).metadataObject()); + Assertions.assertEquals(OperationType.GET_TAG_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testListMetadataObjectsForTagEvent() { + dispatcher.listMetadataObjectsForTag("metalake", tag.name()); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(ListMetadataObjectsForTagEvent.class, event.getClass()); + Assertions.assertEquals(OperationType.LIST_METADATA_OBJECTS_FOR_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testAssociateTagsForMetadataObjectEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + String[] tagsToAssociate = new String[] {"tag1", "tag2"}; + String[] tagsToDisassociate = new String[] {"tag3", "tag4"}; + + dispatcher.associateTagsForMetadataObject( + "metalake", metadataObject, tagsToAssociate, tagsToDisassociate); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(AssociateTagsForMetadataObjectEvent.class, event.getClass()); + Assertions.assertEquals( + metadataObject, ((AssociateTagsForMetadataObjectEvent) event).metadataObject()); + Assertions.assertArrayEquals( + tagsToAssociate, ((AssociateTagsForMetadataObjectEvent) event).tagsToAdd()); + Assertions.assertArrayEquals( + tagsToDisassociate, ((AssociateTagsForMetadataObjectEvent) event).tagsToRemove()); + Assertions.assertEquals( + OperationType.ASSOCIATE_TAGS_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testListTagsForMetadataObjectEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + dispatcher.listTagsForMetadataObject("metalake", metadataObject); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(ListTagsForMetadataObjectEvent.class, event.getClass()); + Assertions.assertEquals( + metadataObject, ((ListTagsForMetadataObjectEvent) event).metadataObject()); + Assertions.assertEquals(OperationType.LIST_TAGS_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + + @Test + void testListTagsInfoForMetadataObjectEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + dispatcher.listTagsInfoForMetadataObject("metalake", metadataObject); + Event event = dummyEventListener.popPostEvent(); + + Assertions.assertEquals(ListTagsInfoForMetadataObjectEvent.class, event.getClass()); + Assertions.assertEquals( + metadataObject, ((ListTagsInfoForMetadataObjectEvent) event).metadataObject()); + Assertions.assertEquals( + OperationType.LIST_TAGS_INFO_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.SUCCESS, event.operationStatus()); + } + @Test void testCreateTagFailureEvent() { Assertions.assertThrowsExactly( @@ -226,6 +388,12 @@ void testAssociateTagsForMetadataObjectFailureEvent() { Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); } + private void checkTagInfo(TagInfo actualTagInfo, Tag expectedTag) { + Assertions.assertEquals(expectedTag.name(), actualTagInfo.name()); + Assertions.assertEquals(expectedTag.comment(), actualTagInfo.comment()); + Assertions.assertEquals(expectedTag.properties(), actualTagInfo.properties()); + } + private Tag mockTag() { Tag tag = mock(Tag.class); when(tag.name()).thenReturn("tag"); @@ -234,6 +402,46 @@ private Tag mockTag() { return tag; } + private TagDispatcher mockTagDispatcher() { + TagDispatcher dispatcher = mock(TagDispatcher.class); + String metalake = "metalake"; + String[] tagNames = new String[] {"tag1", "tag2"}; + Tag[] tags = new Tag[] {tag, tag}; + + when(dispatcher.createTag( + any(String.class), any(String.class), any(String.class), any(Map.class))) + .thenReturn(tag); + when(dispatcher.listTags(metalake)).thenReturn(tagNames); + when(dispatcher.listTagsInfo(metalake)).thenReturn(tags); + when(dispatcher.alterTag(any(String.class), any(String.class), any(TagChange[].class))) + .thenReturn(tag); + when(dispatcher.getTag(any(String.class), any(String.class))).thenReturn(tag); + when(dispatcher.deleteTag(metalake, tag.name())).thenReturn(true); + when(dispatcher.getTagForMetadataObject( + any(String.class), any(MetadataObject.class), any(String.class))) + .thenReturn(tag); + MetadataObject catalog = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + MetadataObject[] objects = new MetadataObject[] {catalog}; + + when(dispatcher.listMetadataObjectsForTag(any(String.class), any(String.class))) + .thenReturn(objects); + + when(dispatcher.associateTagsForMetadataObject( + any(String.class), any(MetadataObject.class), any(String[].class), any(String[].class))) + .thenReturn(new String[] {"tag1", "tag2"}); + + when(dispatcher.listTagsForMetadataObject(any(String.class), any(MetadataObject.class))) + .thenReturn(new String[] {"tag1", "tag2"}); + + when(dispatcher.listTagsInfoForMetadataObject(any(String.class), any(MetadataObject.class))) + .thenReturn(new Tag[] {tag, tag}); + + return dispatcher; + } + private TagDispatcher mockExceptionTagDispatcher() { return mock( TagDispatcher.class,