From 266cb2e1a69274e3f95ce0d35b9f063a1e51487c Mon Sep 17 00:00:00 2001 From: Cheng-Yi Shih <48374270+cool9850311@users.noreply.github.com> Date: Tue, 7 Jan 2025 19:29:43 +0800 Subject: [PATCH] [#5902] feat: Add tag failure event to Gravitino server (#5944) ### What changes were proposed in this pull request? Add tag failure event to Gravitino server ### Why are the changes needed? Subtask: apache#5902 ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Unit tests. --- .../listener/TagEventDispatcher.java | 63 +++-- .../api/event/AlterTagFailureEvent.java | 67 +++++ ...iateTagsForMetadataObjectFailureEvent.java | 84 ++++++ .../api/event/CreateTagFailureEvent.java | 65 +++++ .../api/event/DeleteTagFailureEvent.java | 53 ++++ .../api/event/GetTagFailureEvent.java | 53 ++++ .../GetTagForMetadataObjectFailureEvent.java | 61 +++++ ...ListMetadataObjectsForTagFailureEvent.java | 53 ++++ .../api/event/ListTagsFailureEvent.java | 50 ++++ ...ListTagsForMetadataObjectFailureEvent.java | 55 ++++ .../api/event/ListTagsInfoFailureEvent.java | 52 ++++ ...TagsInfoForMetadataObjectFailureEvent.java | 55 ++++ .../listener/api/event/OperationType.java | 13 + .../listener/api/event/TagFailureEvent.java | 43 +++ .../gravitino/listener/api/info/TagInfo.java | 78 ++++++ .../relational/service/TagMetaService.java | 8 +- .../org/apache/gravitino/tag/TagManager.java | 45 ++-- .../gravitino/utils/NameIdentifierUtil.java | 10 + .../apache/gravitino/utils/NamespaceUtil.java | 11 + .../listener/api/event/TestTagEvent.java | 244 ++++++++++++++++++ .../storage/relational/TestJDBCBackend.java | 5 +- .../service/TestTagMetaService.java | 103 ++++---- docs/gravitino-server-config.md | 1 + 23 files changed, 1178 insertions(+), 94 deletions(-) create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/GetTagFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/event/TagFailureEvent.java create mode 100644 core/src/main/java/org/apache/gravitino/listener/api/info/TagInfo.java create mode 100644 core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java 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..302d82a93c7 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.AlterTagFailureEvent; +import org.apache.gravitino.listener.api.event.AssociateTagsForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.CreateTagFailureEvent; +import org.apache.gravitino.listener.api.event.DeleteTagFailureEvent; +import org.apache.gravitino.listener.api.event.GetTagFailureEvent; +import org.apache.gravitino.listener.api.event.GetTagForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.ListMetadataObjectsForTagFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsForMetadataObjectFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsInfoFailureEvent; +import org.apache.gravitino.listener.api.event.ListTagsInfoForMetadataObjectFailureEvent; +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) { @@ -50,7 +60,8 @@ public String[] listTags(String metalake) { // TODO: listTagsEvent return dispatcher.listTags(metalake); } catch (Exception e) { - // TODO: listTagFailureEvent + eventBus.dispatchEvent( + new ListTagsFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, e)); throw e; } } @@ -62,7 +73,8 @@ public Tag[] listTagsInfo(String metalake) { // TODO: listTagsInfoEvent return dispatcher.listTagsInfo(metalake); } catch (Exception e) { - // TODO: listTagsInfoFailureEvent + eventBus.dispatchEvent( + new ListTagsInfoFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, e)); throw e; } } @@ -73,8 +85,9 @@ public Tag getTag(String metalake, String name) throws NoSuchTagException { try { // TODO: getTagEvent return dispatcher.getTag(metalake, name); - } catch (NoSuchTagException e) { - // TODO: getTagFailureEvent + } catch (Exception e) { + eventBus.dispatchEvent( + new GetTagFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, name, e)); throw e; } } @@ -82,12 +95,14 @@ public Tag getTag(String metalake, String name) throws NoSuchTagException { @Override public Tag createTag( String metalake, String name, String comment, Map properties) { + TagInfo tagInfo = new TagInfo(name, comment, properties); // TODO: createTagPreEvent try { // TODO: createTagEvent return dispatcher.createTag(metalake, name, comment, properties); } catch (Exception e) { - // TODO: createTagFailureEvent + eventBus.dispatchEvent( + new CreateTagFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, tagInfo, e)); throw e; } } @@ -99,7 +114,9 @@ public Tag alterTag(String metalake, String name, TagChange... changes) { // TODO: alterTagEvent return dispatcher.alterTag(metalake, name, changes); } catch (Exception e) { - // TODO: alterTagFailureEvent + eventBus.dispatchEvent( + new AlterTagFailureEvent( + PrincipalUtils.getCurrentUserName(), metalake, name, changes, e)); throw e; } } @@ -111,7 +128,8 @@ public boolean deleteTag(String metalake, String name) { // TODO: deleteTagEvent return dispatcher.deleteTag(metalake, name); } catch (Exception e) { - // TODO: deleteTagFailureEvent + eventBus.dispatchEvent( + new DeleteTagFailureEvent(PrincipalUtils.getCurrentUserName(), metalake, name, e)); throw e; } } @@ -123,7 +141,9 @@ public MetadataObject[] listMetadataObjectsForTag(String metalake, String name) // TODO: listMetadataObjectsForTagEvent return dispatcher.listMetadataObjectsForTag(metalake, name); } catch (Exception e) { - // TODO: listMetadataObjectsForTagFailureEvent + eventBus.dispatchEvent( + new ListMetadataObjectsForTagFailureEvent( + PrincipalUtils.getCurrentUserName(), metalake, name, e)); throw e; } } @@ -135,7 +155,9 @@ public String[] listTagsForMetadataObject(String metalake, MetadataObject metada // TODO: listTagsForMetadataObjectEvent return dispatcher.listTagsForMetadataObject(metalake, metadataObject); } catch (Exception e) { - // TODO: listTagsForMetadataObjectFailureEvent + eventBus.dispatchEvent( + new ListTagsForMetadataObjectFailureEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, e)); throw e; } } @@ -147,7 +169,9 @@ public Tag[] listTagsInfoForMetadataObject(String metalake, MetadataObject metad // TODO: listTagsInfoForMetadataObjectEvent return dispatcher.listTagsInfoForMetadataObject(metalake, metadataObject); } catch (Exception e) { - // TODO: listTagsInfoForMetadataObjectFailureEvent + eventBus.dispatchEvent( + new ListTagsInfoForMetadataObjectFailureEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, e)); throw e; } } @@ -161,7 +185,14 @@ public String[] associateTagsForMetadataObject( return dispatcher.associateTagsForMetadataObject( metalake, metadataObject, tagsToAdd, tagsToRemove); } catch (Exception e) { - // TODO: associateTagsForMetadataObjectFailureEvent + eventBus.dispatchEvent( + new AssociateTagsForMetadataObjectFailureEvent( + PrincipalUtils.getCurrentUserName(), + metalake, + metadataObject, + tagsToAdd, + tagsToRemove, + e)); throw e; } } @@ -173,7 +204,9 @@ public Tag getTagForMetadataObject(String metalake, MetadataObject metadataObjec // TODO: getTagForMetadataObjectEvent return dispatcher.getTagForMetadataObject(metalake, metadataObject, name); } catch (Exception e) { - // TODO: getTagForMetadataObjectFailureEvent + eventBus.dispatchEvent( + new GetTagForMetadataObjectFailureEvent( + PrincipalUtils.getCurrentUserName(), metalake, metadataObject, name, e)); throw e; } } diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagFailureEvent.java new file mode 100644 index 00000000000..a15121fda83 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AlterTagFailureEvent.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.tag.TagChange; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to alter a tag in the database fails due to an + * exception. + */ +@DeveloperApi +public class AlterTagFailureEvent extends TagFailureEvent { + private final TagChange[] changes; + + /** + * Constructs a new AlterTagFailureEvent. + * + * @param user the user who attempted to alter the tag + * @param metalake the metalake identifier + * @param name the name of the tag + * @param changes the changes attempted to be made to the tag + * @param exception the exception that caused the failure + */ + public AlterTagFailureEvent( + String user, String metalake, String name, TagChange[] changes, Exception exception) { + super(user, NameIdentifierUtil.ofTag(metalake, name), exception); + this.changes = changes; + } + + /** + * Returns the changes attempted to be made to the tag. + * + * @return the changes attempted to be made to the tag + */ + public TagChange[] changes() { + return changes; + } + + /** + * 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/AssociateTagsForMetadataObjectFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectFailureEvent.java new file mode 100644 index 00000000000..c196e7f7edc --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/AssociateTagsForMetadataObjectFailureEvent.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.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** + * Represents an event triggered when an attempt to associate tags for a metadata object fails due + * to an exception. + */ +@DeveloperApi +public class AssociateTagsForMetadataObjectFailureEvent extends TagFailureEvent { + private final String[] tagsToAdd; + private final String[] tagsToRemove; + + /** + * Constructs a new {@code AssociateTagsForMetadataObjectFailureEvent} instance. + * + * @param user The user who initiated the operation. + * @param metalake The metalake name where the metadata object resides. + * @param metadataObject The metadata object for which tags are being associated. + * @param tagsToAdd The tags to add. + * @param tagsToRemove The tags to remove. + * @param exception The exception encountered during the operation, providing insights into the + * reasons behind the failure. + */ + public AssociateTagsForMetadataObjectFailureEvent( + String user, + String metalake, + MetadataObject metadataObject, + String[] tagsToAdd, + String[] tagsToRemove, + Exception exception) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject), exception); + this.tagsToAdd = tagsToAdd; + this.tagsToRemove = tagsToRemove; + } + + /** + * Returns the tags to add. + * + * @return The tags to add. + */ + public String[] tagsToAdd() { + return tagsToAdd; + } + + /** + * Returns the tags to remove. + * + * @return The tags to remove. + */ + public String[] tagsToRemove() { + return tagsToRemove; + } + + /** + * 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/CreateTagFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagFailureEvent.java new file mode 100644 index 00000000000..0ed1adeee7b --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/CreateTagFailureEvent.java @@ -0,0 +1,65 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.listener.api.info.TagInfo; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to create a tag in the database fails due to an + * exception. + */ +@DeveloperApi +public class CreateTagFailureEvent extends TagFailureEvent { + private final TagInfo tagInfo; + /** + * Constructs a new {@code CreateTagFailureEvent} instance. + * + * @param user The user who initiated the tag creation operation. + * @param metalake The metalake name where the tag resides. + * @param tagInfo The information about the tag to be created. + * @param exception The exception encountered during the tag creation operation, providing + * insights into the reasons behind the operation's failure. + */ + public CreateTagFailureEvent(String user, String metalake, TagInfo tagInfo, Exception exception) { + super(user, NameIdentifierUtil.ofTag(metalake, tagInfo.name()), exception); + this.tagInfo = tagInfo; + } + + /** + * Returns the information about the tag. + * + * @return the tag information + */ + public TagInfo tagInfo() { + return tagInfo; + } + + /** + * Returns the type of operation. + * + * @return the operation type. + */ + @Override + public OperationType operationType() { + return OperationType.CREATE_TAG; + } +} diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagFailureEvent.java new file mode 100644 index 00000000000..90e14796c1c --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/DeleteTagFailureEvent.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to delete a tag in the database fails due to an + * exception. + */ +@DeveloperApi +public class DeleteTagFailureEvent extends TagFailureEvent { + /** + * Constructs a new {@code DeleteTagFailureEvent} instance. + * + * @param user The user who initiated the tag deletion operation. + * @param metalake The metalake name where the tag resides. + * @param name The name of the tag to delete. + * @param exception The exception encountered during the tag deletion operation, providing + * insights into the reasons behind the operation's failure. + */ + public DeleteTagFailureEvent(String user, String metalake, String name, Exception exception) { + super(user, NameIdentifierUtil.ofTag(metalake, name), exception); + } + + /** + * 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/GetTagFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagFailureEvent.java new file mode 100644 index 00000000000..06650b3b53e --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagFailureEvent.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to get a tag from the database fails due to an + * exception. + */ +@DeveloperApi +public class GetTagFailureEvent extends TagFailureEvent { + /** + * Constructs a new {@code GetTagFailureEvent} instance. + * + * @param user The user who initiated the get tag operation. + * @param metalake The metalake name where the tag resides. + * @param name The name of the tag to get. + * @param exception The exception encountered during the get tag operation, providing insights + * into the reasons behind the operation's failure. + */ + public GetTagFailureEvent(String user, String metalake, String name, Exception exception) { + super(user, NameIdentifierUtil.ofTag(metalake, name), exception); + } + + /** + * 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/GetTagForMetadataObjectFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectFailureEvent.java new file mode 100644 index 00000000000..3489ac23bdb --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/GetTagForMetadataObjectFailureEvent.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.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** + * Represents an event triggered when an attempt to get a tag for a metadata object fails due to an + * exception. + */ +@DeveloperApi +public class GetTagForMetadataObjectFailureEvent extends TagFailureEvent { + + /** + * Constructs a new {@code GetTagForMetadataObjectFailureEvent} instance. + * + * @param user The user who initiated the operation. + * @param metalake The metalake name where the metadata object resides. + * @param metadataObject The metadata object for which the tag is being retrieved. + * @param name The name of the tag to retrieve. + * @param exception The exception encountered during the operation, providing insights into the + * reasons behind the failure. + */ + public GetTagForMetadataObjectFailureEvent( + String user, + String metalake, + MetadataObject metadataObject, + String name, + Exception exception) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject), exception); + } + + /** + * 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/ListMetadataObjectsForTagFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagFailureEvent.java new file mode 100644 index 00000000000..fa09c413b3d --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListMetadataObjectsForTagFailureEvent.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.NameIdentifierUtil; + +/** + * Represents an event triggered when an attempt to list metadata objects for a tag fails due to an + * exception. + */ +@DeveloperApi +public class ListMetadataObjectsForTagFailureEvent extends TagFailureEvent { + /** + * Constructs a new {@code ListMetadataObjectsForTagFailureEvent} instance. + * + * @param user The user who initiated the operation. + * @param metalake The metalake name where the tag resides. + * @param name The name of the tag. + * @param exception The exception encountered during the operation, providing insights into the + * reasons behind the failure. + */ + public ListMetadataObjectsForTagFailureEvent( + String user, String metalake, String name, Exception exception) { + super(user, NameIdentifierUtil.ofTag(metalake, name), exception); + } + + /** + * 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/ListTagsFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsFailureEvent.java new file mode 100644 index 00000000000..00a3401d142 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsFailureEvent.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** Represents an event triggered when an attempt to list tags fails due to an exception. */ +@DeveloperApi +public class ListTagsFailureEvent extends TagFailureEvent { + + /** + * Constructs a new {@code ListTagFailureEvent} instance. + * + * @param user The user who initiated the tag listing operation. + * @param metalake The metalake name where the tags are being listed. + * @param exception The exception encountered during the tag listing operation, providing insights + * into the reasons behind the failure. + */ + public ListTagsFailureEvent(String user, String metalake, Exception exception) { + super(user, NameIdentifier.of(metalake), exception); + } + + /** + * 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/ListTagsForMetadataObjectFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectFailureEvent.java new file mode 100644 index 00000000000..3e33c2bbdab --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsForMetadataObjectFailureEvent.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** + * Represents an event triggered when an attempt to list tags for a metadata object fails due to an + * exception. + */ +@DeveloperApi +public class ListTagsForMetadataObjectFailureEvent extends TagFailureEvent { + + /** + * Constructs a new {@code ListTagsForMetadataObjectFailureEvent} instance. + * + * @param user The user who initiated the operation. + * @param metalake The metalake name where the metadata object resides. + * @param metadataObject The metadata object for which tags are being listed. + * @param exception The exception encountered during the operation, providing insights into the + * reasons behind the failure. + */ + public ListTagsForMetadataObjectFailureEvent( + String user, String metalake, MetadataObject metadataObject, Exception exception) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject), exception); + } + + /** + * 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/ListTagsInfoFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoFailureEvent.java new file mode 100644 index 00000000000..50bf4a87ca1 --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoFailureEvent.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** + * Represents an event triggered when an attempt to list tag information fails due to an exception. + */ +@DeveloperApi +public class ListTagsInfoFailureEvent extends FailureEvent { + + /** + * Constructs a new {@code ListTagsInfoFailureEvent} instance. + * + * @param user The user who initiated the tag listing operation. + * @param metalake The metalake name where the tags are being listed. + * @param exception The exception encountered during the tag listing operation, providing insights + * into the reasons behind the failure. + */ + public ListTagsInfoFailureEvent(String user, String metalake, Exception exception) { + super(user, NameIdentifier.of(metalake), exception); + } + + /** + * 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/ListTagsInfoForMetadataObjectFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectFailureEvent.java new file mode 100644 index 00000000000..948076651ba --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/ListTagsInfoForMetadataObjectFailureEvent.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.MetadataObject; +import org.apache.gravitino.annotation.DeveloperApi; +import org.apache.gravitino.utils.MetadataObjectUtil; + +/** + * Represents an event triggered when an attempt to list tags info for a metadata object fails due + * to an exception. + */ +@DeveloperApi +public class ListTagsInfoForMetadataObjectFailureEvent extends TagFailureEvent { + /** + * Constructs a new {@code ListTagsInfoForMetadataObjectFailureEvent} instance. + * + * @param user The user who initiated the operation. + * @param metalake The metalake name where the metadata object resides. + * @param metadataObject The metadata object for which tags info is being listed. + * @param exception The exception encountered during the operation, providing insights into the + * reasons behind the failure. + */ + public ListTagsInfoForMetadataObjectFailureEvent( + String user, String metalake, MetadataObject metadataObject, Exception exception) { + super(user, MetadataObjectUtil.toEntityIdent(metalake, metadataObject), exception); + } + + /** + * 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 f9e5c9265c5..0585984665f 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 @@ -31,6 +31,19 @@ public enum OperationType { REGISTER_TABLE, TABLE_EXISTS, + // Tag operations + CREATE_TAG, + GET_TAG, + GET_TAG_FOR_METADATA_OBJECT, + DELETE_TAG, + ALTER_TAG, + LIST_TAG, + ASSOCIATE_TAGS_FOR_METADATA_OBJECT, + LIST_TAGS_FOR_METADATA_OBJECT, + LIST_TAGS_INFO_FOR_METADATA_OBJECT, + LIST_METADATA_OBJECTS_FOR_TAG, + LIST_TAGS_INFO, + // Schema operations CREATE_SCHEMA, DROP_SCHEMA, diff --git a/core/src/main/java/org/apache/gravitino/listener/api/event/TagFailureEvent.java b/core/src/main/java/org/apache/gravitino/listener/api/event/TagFailureEvent.java new file mode 100644 index 00000000000..7072cab45df --- /dev/null +++ b/core/src/main/java/org/apache/gravitino/listener/api/event/TagFailureEvent.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import org.apache.gravitino.NameIdentifier; +import org.apache.gravitino.annotation.DeveloperApi; + +/** + * Represents an event triggered when an attempt to perform a tag operation fails due to an + * exception. + */ +@DeveloperApi +public abstract class TagFailureEvent extends FailureEvent { + + /** + * Constructs a new {@code TagFailureEvent} instance. + * + * @param user The user who initiated the tag operation. + * @param identifier The identifier of the tag involved in the operation. + * @param exception The exception encountered during the tag operation, providing insights into + * the reasons behind the failure. + */ + protected TagFailureEvent(String user, NameIdentifier identifier, Exception exception) { + super(user, identifier, exception); + } +} 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/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java b/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java index 71b8275275f..5863877ae7b 100644 --- a/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java +++ b/core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java @@ -44,8 +44,8 @@ import org.apache.gravitino.storage.relational.utils.ExceptionUtils; import org.apache.gravitino.storage.relational.utils.POConverters; import org.apache.gravitino.storage.relational.utils.SessionUtils; -import org.apache.gravitino.tag.TagManager; import org.apache.gravitino.utils.NameIdentifierUtil; +import org.apache.gravitino.utils.NamespaceUtil; public class TagMetaService { @@ -179,7 +179,7 @@ public List listTagsForMetadataObject( } return tagPOs.stream() - .map(tagPO -> POConverters.fromTagPO(tagPO, TagManager.ofTagNamespace(metalake))) + .map(tagPO -> POConverters.fromTagPO(tagPO, NamespaceUtil.ofTag(metalake))) .collect(Collectors.toList()); } @@ -214,7 +214,7 @@ public TagEntity getTagForMetadataObject( tagIdent.name()); } - return POConverters.fromTagPO(tagPO, TagManager.ofTagNamespace(metalake)); + return POConverters.fromTagPO(tagPO, NamespaceUtil.ofTag(metalake)); } public List listAssociatedMetadataObjectsForTag(NameIdentifier tagIdent) @@ -327,7 +327,7 @@ public List associateTagsWithMetadataObject( metadataObjectId, metadataObject.type().toString())); return tagPOs.stream() - .map(tagPO -> POConverters.fromTagPO(tagPO, TagManager.ofTagNamespace(metalake))) + .map(tagPO -> POConverters.fromTagPO(tagPO, NamespaceUtil.ofTag(metalake))) .collect(Collectors.toList()); } catch (RuntimeException e) { diff --git a/core/src/main/java/org/apache/gravitino/tag/TagManager.java b/core/src/main/java/org/apache/gravitino/tag/TagManager.java index f7932fe2607..c03f6392fb8 100644 --- a/core/src/main/java/org/apache/gravitino/tag/TagManager.java +++ b/core/src/main/java/org/apache/gravitino/tag/TagManager.java @@ -34,7 +34,6 @@ import org.apache.gravitino.EntityStore; import org.apache.gravitino.MetadataObject; import org.apache.gravitino.NameIdentifier; -import org.apache.gravitino.Namespace; import org.apache.gravitino.exceptions.NoSuchEntityException; import org.apache.gravitino.exceptions.NoSuchMetadataObjectException; import org.apache.gravitino.exceptions.NoSuchTagException; @@ -47,6 +46,8 @@ import org.apache.gravitino.meta.TagEntity; import org.apache.gravitino.storage.IdGenerator; import org.apache.gravitino.utils.MetadataObjectUtil; +import org.apache.gravitino.utils.NameIdentifierUtil; +import org.apache.gravitino.utils.NamespaceUtil; import org.apache.gravitino.utils.PrincipalUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -82,14 +83,15 @@ public String[] listTags(String metalake) { public Tag[] listTagsInfo(String metalake) { return TreeLockUtils.doWithTreeLock( - NameIdentifier.of(ofTagNamespace(metalake).levels()), + NameIdentifier.of(NamespaceUtil.ofTag(metalake).levels()), LockType.READ, () -> { checkMetalake(NameIdentifier.of(metalake), entityStore); try { return entityStore - .list(ofTagNamespace(metalake), TagEntity.class, Entity.EntityType.TAG).stream() + .list(NamespaceUtil.ofTag(metalake), TagEntity.class, Entity.EntityType.TAG) + .stream() .toArray(Tag[]::new); } catch (IOException ioe) { LOG.error("Failed to list tags under metalake {}", metalake, ioe); @@ -103,7 +105,7 @@ public Tag createTag(String metalake, String name, String comment, Map tagProperties = properties == null ? Collections.emptyMap() : properties; return TreeLockUtils.doWithTreeLock( - NameIdentifier.of(ofTagNamespace(metalake).levels()), + NameIdentifier.of(NamespaceUtil.ofTag(metalake).levels()), LockType.WRITE, () -> { checkMetalake(NameIdentifier.of(metalake), entityStore); @@ -112,7 +114,7 @@ public Tag createTag(String metalake, String name, String comment, Map { checkMetalake(NameIdentifier.of(metalake), entityStore); try { return entityStore.get( - ofTagIdent(metalake, name), Entity.EntityType.TAG, TagEntity.class); + NameIdentifierUtil.ofTag(metalake, name), Entity.EntityType.TAG, TagEntity.class); } catch (NoSuchEntityException e) { throw new NoSuchTagException( "Tag with name %s under metalake %s does not exist", name, metalake); @@ -158,14 +160,14 @@ public Tag getTag(String metalake, String name) throws NoSuchTagException { public Tag alterTag(String metalake, String name, TagChange... changes) throws NoSuchTagException, IllegalArgumentException { return TreeLockUtils.doWithTreeLock( - NameIdentifier.of(ofTagNamespace(metalake).levels()), + NameIdentifier.of(NamespaceUtil.ofTag(metalake).levels()), LockType.WRITE, () -> { checkMetalake(NameIdentifier.of(metalake), entityStore); try { return entityStore.update( - ofTagIdent(metalake, name), + NameIdentifierUtil.ofTag(metalake, name), TagEntity.class, Entity.EntityType.TAG, tagEntity -> updateTagEntity(tagEntity, changes)); @@ -184,13 +186,14 @@ public Tag alterTag(String metalake, String name, TagChange... changes) public boolean deleteTag(String metalake, String name) { return TreeLockUtils.doWithTreeLock( - NameIdentifier.of(ofTagNamespace(metalake).levels()), + NameIdentifier.of(NamespaceUtil.ofTag(metalake).levels()), LockType.WRITE, () -> { checkMetalake(NameIdentifier.of(metalake), entityStore); try { - return entityStore.delete(ofTagIdent(metalake, name), Entity.EntityType.TAG); + return entityStore.delete( + NameIdentifierUtil.ofTag(metalake, name), Entity.EntityType.TAG); } catch (IOException ioe) { LOG.error("Failed to delete tag {} under metalake {}", name, metalake, ioe); throw new RuntimeException(ioe); @@ -200,7 +203,7 @@ public boolean deleteTag(String metalake, String name) { public MetadataObject[] listMetadataObjectsForTag(String metalake, String name) throws NoSuchTagException { - NameIdentifier tagId = ofTagIdent(metalake, name); + NameIdentifier tagId = NameIdentifierUtil.ofTag(metalake, name); return TreeLockUtils.doWithTreeLock( tagId, LockType.READ, @@ -259,7 +262,7 @@ public Tag getTagForMetadataObject(String metalake, MetadataObject metadataObjec throws NoSuchMetadataObjectException { NameIdentifier entityIdent = MetadataObjectUtil.toEntityIdent(metalake, metadataObject); Entity.EntityType entityType = MetadataObjectUtil.toEntityType(metadataObject); - NameIdentifier tagIdent = ofTagIdent(metalake, name); + NameIdentifier tagIdent = NameIdentifierUtil.ofTag(metalake, name); MetadataObjectUtil.checkMetadataObject(metalake, metadataObject); @@ -307,10 +310,12 @@ public String[] associateTagsForMetadataObject( tagsToRemoveSet.removeAll(common); NameIdentifier[] tagsToAddIdent = - tagsToAddSet.stream().map(tag -> ofTagIdent(metalake, tag)).toArray(NameIdentifier[]::new); + tagsToAddSet.stream() + .map(tag -> NameIdentifierUtil.ofTag(metalake, tag)) + .toArray(NameIdentifier[]::new); NameIdentifier[] tagsToRemoveIdent = tagsToRemoveSet.stream() - .map(tag -> ofTagIdent(metalake, tag)) + .map(tag -> NameIdentifierUtil.ofTag(metalake, tag)) .toArray(NameIdentifier[]::new); return TreeLockUtils.doWithTreeLock( @@ -318,7 +323,7 @@ public String[] associateTagsForMetadataObject( LockType.READ, () -> TreeLockUtils.doWithTreeLock( - NameIdentifier.of(ofTagNamespace(metalake).levels()), + NameIdentifier.of(NamespaceUtil.ofTag(metalake).levels()), LockType.WRITE, () -> { try { @@ -347,14 +352,6 @@ public String[] associateTagsForMetadataObject( })); } - public static Namespace ofTagNamespace(String metalake) { - return Namespace.of(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, Entity.TAG_SCHEMA_NAME); - } - - public static NameIdentifier ofTagIdent(String metalake, String tagName) { - return NameIdentifier.of(ofTagNamespace(metalake), tagName); - } - private TagEntity updateTagEntity(TagEntity tagEntity, TagChange... changes) { Map props = tagEntity.properties() == null diff --git a/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java b/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java index 2b7e69ebee0..47b203ed4d4 100644 --- a/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java +++ b/core/src/main/java/org/apache/gravitino/utils/NameIdentifierUtil.java @@ -93,6 +93,16 @@ public static NameIdentifier ofTable( return NameIdentifier.of(metalake, catalog, schema, table); } + /** + * Create the tag {@link NameIdentifier} with the given metalake and tag name. + * + * @param metalake The metalake name + * @param tagName The tag name + * @return The created tag {@link NameIdentifier} + */ + public static NameIdentifier ofTag(String metalake, String tagName) { + return NameIdentifier.of(NamespaceUtil.ofTag(metalake), tagName); + } /** * Create the column {@link NameIdentifier} with the given metalake, catalog, schema, table and * column name. diff --git a/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java b/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java index d0e473c5010..eebab093468 100644 --- a/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java +++ b/core/src/main/java/org/apache/gravitino/utils/NamespaceUtil.java @@ -20,6 +20,7 @@ import com.google.errorprone.annotations.FormatMethod; import com.google.errorprone.annotations.FormatString; +import org.apache.gravitino.Entity; import org.apache.gravitino.NameIdentifier; import org.apache.gravitino.Namespace; import org.apache.gravitino.exceptions.IllegalNamespaceException; @@ -71,6 +72,16 @@ public static Namespace ofTable(String metalake, String catalog, String schema) return Namespace.of(metalake, catalog, schema); } + /** + * Create a namespace for tag. + * + * @param metalake The metalake name + * @return A namespace for tag + */ + public static Namespace ofTag(String metalake) { + return Namespace.of(metalake, Entity.SYSTEM_CATALOG_RESERVED_NAME, Entity.TAG_SCHEMA_NAME); + } + /** * Create a namespace for column. * 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..1ac3001bd2c --- /dev/null +++ b/core/src/test/java/org/apache/gravitino/listener/api/event/TestTagEvent.java @@ -0,0 +1,244 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.listener.api.event; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.google.common.collect.ImmutableMap; +import java.util.Arrays; +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.tag.Tag; +import org.apache.gravitino.tag.TagChange; +import org.apache.gravitino.tag.TagDispatcher; +import org.apache.gravitino.utils.NameIdentifierUtil; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; + +@TestInstance(Lifecycle.PER_CLASS) +public class TestTagEvent { + 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 tagExceptionDispatcher = mockExceptionTagDispatcher(); + this.failureDispatcher = new TagEventDispatcher(eventBus, tagExceptionDispatcher); + } + + @Test + void testCreateTagFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.createTag("metalake", tag.name(), tag.comment(), tag.properties())); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(CreateTagFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((CreateTagFailureEvent) event).exception().getClass()); + Assertions.assertEquals(tag.name(), ((CreateTagFailureEvent) event).tagInfo().name()); + Assertions.assertEquals(tag.comment(), ((CreateTagFailureEvent) event).tagInfo().comment()); + Assertions.assertEquals( + tag.properties(), ((CreateTagFailureEvent) event).tagInfo().properties()); + Assertions.assertEquals(OperationType.CREATE_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testGetTagFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.getTag("metalake", tag.name())); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(GetTagFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((GetTagFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.GET_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testGetTagForMetadataObjectFailureEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.getTagForMetadataObject("metalake", metadataObject, tag.name())); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(GetTagForMetadataObjectFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, + ((GetTagForMetadataObjectFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.GET_TAG_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testDeleteTagFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.deleteTag("metalake", tag.name())); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(DeleteTagFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((DeleteTagFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.DELETE_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testAlterTagFailureEvent() { + 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}; + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.alterTag("metalake", tag.name(), changes)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(AlterTagFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((AlterTagFailureEvent) event).exception().getClass()); + Assertions.assertEquals(changes, ((AlterTagFailureEvent) event).changes()); + Assertions.assertEquals(OperationType.ALTER_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testListTagFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.listTags("metalake")); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListTagsFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((ListTagsFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.LIST_TAG, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testListTagsForMetadataObjectFailureEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.listTagsForMetadataObject("metalake", metadataObject)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListTagsForMetadataObjectFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, + ((ListTagsForMetadataObjectFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.LIST_TAGS_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testListTagsInfoFailureEvent() { + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, () -> failureDispatcher.listTagsInfo("metalake")); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListTagsInfoFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, ((ListTagsInfoFailureEvent) event).exception().getClass()); + Assertions.assertEquals(OperationType.LIST_TAGS_INFO, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testListTagsInfoForMetadataObjectFailureEvent() { + MetadataObject metadataObject = + NameIdentifierUtil.toMetadataObject( + NameIdentifierUtil.ofCatalog("metalake", "catalog_for_test"), + Entity.EntityType.CATALOG); + + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> failureDispatcher.listTagsInfoForMetadataObject("metalake", metadataObject)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(ListTagsInfoForMetadataObjectFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, + ((ListTagsInfoForMetadataObjectFailureEvent) event).exception().getClass()); + Assertions.assertEquals( + OperationType.LIST_TAGS_INFO_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + @Test + void testAssociateTagsForMetadataObjectFailureEvent() { + 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"}; + + Assertions.assertThrowsExactly( + GravitinoRuntimeException.class, + () -> + failureDispatcher.associateTagsForMetadataObject( + "metalake", metadataObject, tagsToAssociate, tagsToDisassociate)); + Event event = dummyEventListener.popPostEvent(); + Assertions.assertEquals(AssociateTagsForMetadataObjectFailureEvent.class, event.getClass()); + Assertions.assertEquals( + GravitinoRuntimeException.class, + ((AssociateTagsForMetadataObjectFailureEvent) event).exception().getClass()); + Assertions.assertEquals( + tagsToAssociate, ((AssociateTagsForMetadataObjectFailureEvent) event).tagsToAdd()); + Assertions.assertEquals( + tagsToDisassociate, ((AssociateTagsForMetadataObjectFailureEvent) event).tagsToRemove()); + Assertions.assertEquals( + OperationType.ASSOCIATE_TAGS_FOR_METADATA_OBJECT, event.operationType()); + Assertions.assertEquals(OperationStatus.FAILURE, event.operationStatus()); + } + + private Tag mockTag() { + Tag tag = mock(Tag.class); + when(tag.name()).thenReturn("tag"); + when(tag.comment()).thenReturn("comment"); + when(tag.properties()).thenReturn(ImmutableMap.of("color", "#FFFFFF")); + return tag; + } + + private TagDispatcher mockExceptionTagDispatcher() { + return mock( + TagDispatcher.class, + invocation -> { + throw new GravitinoRuntimeException("Exception for all methods"); + }); + } +} diff --git a/core/src/test/java/org/apache/gravitino/storage/relational/TestJDBCBackend.java b/core/src/test/java/org/apache/gravitino/storage/relational/TestJDBCBackend.java index 8cd2c802e86..f690a2256b0 100644 --- a/core/src/test/java/org/apache/gravitino/storage/relational/TestJDBCBackend.java +++ b/core/src/test/java/org/apache/gravitino/storage/relational/TestJDBCBackend.java @@ -85,7 +85,6 @@ import org.apache.gravitino.storage.relational.service.RoleMetaService; import org.apache.gravitino.storage.relational.session.SqlSessionFactoryHelper; import org.apache.gravitino.storage.relational.utils.SessionUtils; -import org.apache.gravitino.tag.TagManager; import org.apache.gravitino.utils.NamespaceUtil; import org.apache.ibatis.session.SqlSession; import org.junit.jupiter.api.AfterAll; @@ -657,7 +656,7 @@ public void testMetaLifeCycleFromCreationToDeletion() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag") - .withNamespace(TagManager.ofTagNamespace("metalake")) + .withNamespace(NamespaceUtil.ofTag("metalake")) .withComment("tag comment") .withAuditInfo(auditInfo) .build(); @@ -745,7 +744,7 @@ public void testMetaLifeCycleFromCreationToDeletion() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("another-tag") - .withNamespace(TagManager.ofTagNamespace("another-metalake")) + .withNamespace(NamespaceUtil.ofTag("another-metalake")) .withComment("another-tag comment") .withAuditInfo(auditInfo) .build(); diff --git a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTagMetaService.java b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTagMetaService.java index 8194a17061c..a81f222de99 100644 --- a/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTagMetaService.java +++ b/core/src/test/java/org/apache/gravitino/storage/relational/service/TestTagMetaService.java @@ -43,7 +43,8 @@ import org.apache.gravitino.rel.types.Types; import org.apache.gravitino.storage.RandomIdGenerator; import org.apache.gravitino.storage.relational.TestJDBCBackend; -import org.apache.gravitino.tag.TagManager; +import org.apache.gravitino.utils.NameIdentifierUtil; +import org.apache.gravitino.utils.NamespaceUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -67,7 +68,8 @@ public void testInsertAndGetTagByIdentifier() throws IOException { Exception excep = Assertions.assertThrows( NoSuchEntityException.class, - () -> tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag1"))); + () -> + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag1"))); Assertions.assertEquals("No such tag entity: tag1", excep.getMessage()); // Test get tag entity @@ -75,7 +77,7 @@ public void testInsertAndGetTagByIdentifier() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -83,7 +85,7 @@ public void testInsertAndGetTagByIdentifier() throws IOException { tagMetaService.insertTag(tagEntity, false); TagEntity resultTagEntity = - tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag1")); + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag1")); Assertions.assertEquals(tagEntity, resultTagEntity); // Test with null comment and properties. @@ -91,13 +93,13 @@ public void testInsertAndGetTagByIdentifier() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag2") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withAuditInfo(auditInfo) .build(); tagMetaService.insertTag(tagEntity1, false); TagEntity resultTagEntity1 = - tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag2")); + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals(tagEntity1, resultTagEntity1); Assertions.assertNull(resultTagEntity1.comment()); Assertions.assertNull(resultTagEntity1.properties()); @@ -107,7 +109,7 @@ public void testInsertAndGetTagByIdentifier() throws IOException { TagEntity.builder() .withId(tagEntity1.id()) .withName("tag3") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -118,7 +120,7 @@ public void testInsertAndGetTagByIdentifier() throws IOException { tagMetaService.insertTag(tagEntity2, true); TagEntity resultTagEntity2 = - tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag3")); + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag3")); Assertions.assertEquals(tagEntity2, resultTagEntity2); } @@ -133,7 +135,7 @@ public void testCreateAndListTags() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -144,7 +146,7 @@ public void testCreateAndListTags() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag2") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -152,7 +154,7 @@ public void testCreateAndListTags() throws IOException { tagMetaService.insertTag(tagEntity2, false); List tagEntities = - tagMetaService.listTagsByNamespace(TagManager.ofTagNamespace(metalakeName)); + tagMetaService.listTagsByNamespace(NamespaceUtil.ofTag(metalakeName)); Assertions.assertEquals(2, tagEntities.size()); Assertions.assertTrue(tagEntities.contains(tagEntity1)); Assertions.assertTrue(tagEntities.contains(tagEntity2)); @@ -169,7 +171,7 @@ public void testUpdateTag() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -182,7 +184,7 @@ public void testUpdateTag() throws IOException { NoSuchEntityException.class, () -> tagMetaService.updateTag( - TagManager.ofTagIdent(metalakeName, "tag2"), tagEntity -> tagEntity)); + NameIdentifierUtil.ofTag(metalakeName, "tag2"), tagEntity -> tagEntity)); Assertions.assertEquals("No such tag entity: tag2", excep.getMessage()); // Update tag entity. @@ -190,18 +192,18 @@ public void testUpdateTag() throws IOException { TagEntity.builder() .withId(tagEntity1.id()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment1") .withProperties(ImmutableMap.of("k2", "v2")) .withAuditInfo(auditInfo) .build(); TagEntity updatedTagEntity = tagMetaService.updateTag( - TagManager.ofTagIdent(metalakeName, "tag1"), tagEntity -> tagEntity2); + NameIdentifierUtil.ofTag(metalakeName, "tag1"), tagEntity -> tagEntity2); Assertions.assertEquals(tagEntity2, updatedTagEntity); TagEntity loadedTagEntity = - tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag1")); + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag1")); Assertions.assertEquals(tagEntity2, loadedTagEntity); // Update with different id. @@ -209,7 +211,7 @@ public void testUpdateTag() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment1") .withProperties(ImmutableMap.of("k2", "v2")) .withAuditInfo(auditInfo) @@ -220,7 +222,7 @@ public void testUpdateTag() throws IOException { IllegalArgumentException.class, () -> tagMetaService.updateTag( - TagManager.ofTagIdent(metalakeName, "tag1"), tagEntity -> tagEntity3)); + NameIdentifierUtil.ofTag(metalakeName, "tag1"), tagEntity -> tagEntity3)); Assertions.assertEquals( "The updated tag entity id: " + tagEntity3.id() @@ -230,7 +232,7 @@ public void testUpdateTag() throws IOException { excep1.getMessage()); TagEntity loadedTagEntity1 = - tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag1")); + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag1")); Assertions.assertEquals(tagEntity2, loadedTagEntity1); } @@ -245,23 +247,24 @@ public void testDeleteTag() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) .build(); tagMetaService.insertTag(tagEntity1, false); - boolean deleted = tagMetaService.deleteTag(TagManager.ofTagIdent(metalakeName, "tag1")); + boolean deleted = tagMetaService.deleteTag(NameIdentifierUtil.ofTag(metalakeName, "tag1")); Assertions.assertTrue(deleted); - deleted = tagMetaService.deleteTag(TagManager.ofTagIdent(metalakeName, "tag1")); + deleted = tagMetaService.deleteTag(NameIdentifierUtil.ofTag(metalakeName, "tag1")); Assertions.assertFalse(deleted); Exception excep = Assertions.assertThrows( NoSuchEntityException.class, - () -> tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag1"))); + () -> + tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag1"))); Assertions.assertEquals("No such tag entity: tag1", excep.getMessage()); } @@ -276,7 +279,7 @@ public void testDeleteMetalake() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -287,7 +290,7 @@ public void testDeleteMetalake() throws IOException { MetalakeMetaService.getInstance().deleteMetalake(metalake.nameIdentifier(), false)); Assertions.assertThrows( NoSuchEntityException.class, - () -> tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName, "tag1"))); + () -> tagMetaService.getTagByIdentifier(NameIdentifierUtil.ofTag(metalakeName, "tag1"))); // Test delete metalake with cascade. BaseMetalake metalake1 = @@ -298,7 +301,7 @@ public void testDeleteMetalake() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag2") - .withNamespace(TagManager.ofTagNamespace(metalakeName + "1")) + .withNamespace(NamespaceUtil.ofTag(metalakeName + "1")) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -309,7 +312,9 @@ public void testDeleteMetalake() throws IOException { MetalakeMetaService.getInstance().deleteMetalake(metalake1.nameIdentifier(), true)); Assertions.assertThrows( NoSuchEntityException.class, - () -> tagMetaService.getTagByIdentifier(TagManager.ofTagIdent(metalakeName + "1", "tag2"))); + () -> + tagMetaService.getTagByIdentifier( + NameIdentifierUtil.ofTag(metalakeName + "1", "tag2"))); } @Test @@ -345,7 +350,7 @@ public void testAssociateAndDisassociateTagsWithMetadataObject() throws IOExcept TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -356,7 +361,7 @@ public void testAssociateAndDisassociateTagsWithMetadataObject() throws IOExcept TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag2") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -367,7 +372,7 @@ public void testAssociateAndDisassociateTagsWithMetadataObject() throws IOExcept TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag3") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) @@ -377,9 +382,9 @@ public void testAssociateAndDisassociateTagsWithMetadataObject() throws IOExcept // Test associate tags with metadata object NameIdentifier[] tagsToAdd = new NameIdentifier[] { - TagManager.ofTagIdent(metalakeName, "tag1"), - TagManager.ofTagIdent(metalakeName, "tag2"), - TagManager.ofTagIdent(metalakeName, "tag3") + NameIdentifierUtil.ofTag(metalakeName, "tag1"), + NameIdentifierUtil.ofTag(metalakeName, "tag2"), + NameIdentifierUtil.ofTag(metalakeName, "tag3") }; List tagEntities = @@ -392,7 +397,7 @@ public void testAssociateAndDisassociateTagsWithMetadataObject() throws IOExcept // Test disassociate tags with metadata object NameIdentifier[] tagsToRemove = - new NameIdentifier[] {TagManager.ofTagIdent(metalakeName, "tag1")}; + new NameIdentifier[] {NameIdentifierUtil.ofTag(metalakeName, "tag1")}; List tagEntities1 = tagMetaService.associateTagsWithMetadataObject( @@ -425,12 +430,14 @@ public void testAssociateAndDisassociateTagsWithMetadataObject() throws IOExcept // Test associate and disassociate in-existent tags with metadata object NameIdentifier[] tagsToAdd1 = new NameIdentifier[] { - TagManager.ofTagIdent(metalakeName, "tag4"), TagManager.ofTagIdent(metalakeName, "tag5") + NameIdentifierUtil.ofTag(metalakeName, "tag4"), + NameIdentifierUtil.ofTag(metalakeName, "tag5") }; NameIdentifier[] tagsToRemove1 = new NameIdentifier[] { - TagManager.ofTagIdent(metalakeName, "tag6"), TagManager.ofTagIdent(metalakeName, "tag7") + NameIdentifierUtil.ofTag(metalakeName, "tag6"), + NameIdentifierUtil.ofTag(metalakeName, "tag7") }; List tagEntities4 = @@ -545,7 +552,7 @@ public void testGetTagForMetadataObject() throws IOException { tagMetaService.getTagForMetadataObject( NameIdentifier.of(metalakeName, "catalog1"), Entity.EntityType.CATALOG, - TagManager.ofTagIdent(metalakeName, "tag2")); + NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals("tag2", tagEntity.name()); // Test get tag for schema @@ -553,7 +560,7 @@ public void testGetTagForMetadataObject() throws IOException { tagMetaService.getTagForMetadataObject( NameIdentifier.of(metalakeName, "catalog1", "schema1"), Entity.EntityType.SCHEMA, - TagManager.ofTagIdent(metalakeName, "tag3")); + NameIdentifierUtil.ofTag(metalakeName, "tag3")); Assertions.assertEquals("tag3", tagEntity1.name()); // Test get tag for table @@ -561,7 +568,7 @@ public void testGetTagForMetadataObject() throws IOException { tagMetaService.getTagForMetadataObject( NameIdentifier.of(metalakeName, "catalog1", "schema1", "table1"), Entity.EntityType.TABLE, - TagManager.ofTagIdent(metalakeName, "tag2")); + NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals("tag2", tagEntity2.name()); // Test get tag for non-existent metadata object @@ -571,7 +578,7 @@ public void testGetTagForMetadataObject() throws IOException { tagMetaService.getTagForMetadataObject( NameIdentifier.of(metalakeName, "catalog1", "schema1", "table2"), Entity.EntityType.TABLE, - TagManager.ofTagIdent(metalakeName, "tag2"))); + NameIdentifierUtil.ofTag(metalakeName, "tag2"))); // Test get tag for non-existent tag Throwable e = @@ -581,7 +588,7 @@ public void testGetTagForMetadataObject() throws IOException { tagMetaService.getTagForMetadataObject( NameIdentifier.of(metalakeName, "catalog1", "schema1", "table1"), Entity.EntityType.TABLE, - TagManager.ofTagIdent(metalakeName, "tag4"))); + NameIdentifierUtil.ofTag(metalakeName, "tag4"))); Assertions.assertTrue(e.getMessage().contains("No such tag entity: tag4")); } @@ -594,7 +601,7 @@ public void testListAssociatedMetadataObjectsForTag() throws IOException { // Test list associated metadata objects for tag2 List metadataObjects = tagMetaService.listAssociatedMetadataObjectsForTag( - TagManager.ofTagIdent(metalakeName, "tag2")); + NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals(3, metadataObjects.size()); Assertions.assertTrue( @@ -609,7 +616,7 @@ public void testListAssociatedMetadataObjectsForTag() throws IOException { // Test list associated metadata objects for tag3 List metadataObjects1 = tagMetaService.listAssociatedMetadataObjectsForTag( - TagManager.ofTagIdent(metalakeName, "tag3")); + NameIdentifierUtil.ofTag(metalakeName, "tag3")); Assertions.assertEquals(3, metadataObjects1.size()); Assertions.assertTrue( @@ -624,7 +631,7 @@ public void testListAssociatedMetadataObjectsForTag() throws IOException { // Test list associated metadata objects for non-existent tag List metadataObjects2 = tagMetaService.listAssociatedMetadataObjectsForTag( - TagManager.ofTagIdent(metalakeName, "tag4")); + NameIdentifierUtil.ofTag(metalakeName, "tag4")); Assertions.assertEquals(0, metadataObjects2.size()); // Test metadata object non-exist scenario. @@ -635,7 +642,7 @@ public void testListAssociatedMetadataObjectsForTag() throws IOException { List metadataObjects3 = tagMetaService.listAssociatedMetadataObjectsForTag( - TagManager.ofTagIdent(metalakeName, "tag2")); + NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals(2, metadataObjects3.size()); Assertions.assertTrue( @@ -649,7 +656,7 @@ public void testListAssociatedMetadataObjectsForTag() throws IOException { List metadataObjects4 = tagMetaService.listAssociatedMetadataObjectsForTag( - TagManager.ofTagIdent(metalakeName, "tag2")); + NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals(1, metadataObjects4.size()); Assertions.assertTrue( @@ -659,7 +666,7 @@ public void testListAssociatedMetadataObjectsForTag() throws IOException { List metadataObjects5 = tagMetaService.listAssociatedMetadataObjectsForTag( - TagManager.ofTagIdent(metalakeName, "tag2")); + NameIdentifierUtil.ofTag(metalakeName, "tag2")); Assertions.assertEquals(0, metadataObjects5.size()); } @@ -729,7 +736,7 @@ public void testDeleteMetadataObjectForTag() throws IOException { TagEntity.builder() .withId(RandomIdGenerator.INSTANCE.nextId()) .withName("tag1") - .withNamespace(TagManager.ofTagNamespace(metalakeName)) + .withNamespace(NamespaceUtil.ofTag(metalakeName)) .withComment("comment") .withProperties(props) .withAuditInfo(auditInfo) diff --git a/docs/gravitino-server-config.md b/docs/gravitino-server-config.md index 452fda4f823..957c3edbc37 100644 --- a/docs/gravitino-server-config.md +++ b/docs/gravitino-server-config.md @@ -124,6 +124,7 @@ Gravitino triggers a pre-event before the operation, a post-event after the comp | catalog operation | `CreateCatalogEvent`, `AlterCatalogEvent`, `DropCatalogEvent`, `LoadCatalogEvent`, `ListCatalogEvent`, `CreateCatalogFailureEvent`, `AlterCatalogFailureEvent`, `DropCatalogFailureEvent`, `LoadCatalogFailureEvent`, `ListCatalogFailureEvent` | 0.5.0 | | metalake operation | `CreateMetalakeEvent`, `AlterMetalakeEvent`, `DropMetalakeEvent`, `LoadMetalakeEvent`, `ListMetalakeEvent`, `CreateMetalakeFailureEvent`, `AlterMetalakeFailureEvent`, `DropMetalakeFailureEvent`, `LoadMetalakeFailureEvent`, `ListMetalakeFailureEvent` | 0.5.0 | | Iceberg REST server table operation | `IcebergCreateTableEvent`, `IcebergUpdateTableEvent`, `IcebergDropTableEvent`, `IcebergLoadTableEvent`, `IcebergListTableEvent`, `IcebergTableExistsEvent`, `IcebergRenameTableEvent`, `IcebergCreateTableFailureEvent`, `IcebergUpdateTableFailureEvent`, `IcebergDropTableFailureEvent`, `IcebergLoadTableFailureEvent`, `IcebergListTableFailureEvent`, `IcebergRenameTableFailureEvent`, `IcebergTableExistsFailureEvent` | 0.7.0-incubating | +| tag operation | `ListTagsFailureEvent`, `ListTagInfoFailureEvent`, `CreateTagFailureEvent`, `GetTagFailureEvent`, `AlterTagFailureEvent`, `DeleteTagFailureEvent`, `ListMetadataObjectsForTagFailureEvent`, `ListTagsForMetadataObjectFailureEvent`, `ListTagsInfoForMetadataObjectFailureEvent`, `AssociateTagsForMetadataObjectFailureEvent`, `GetTagForMetadataObjectFailureEvent` | 0.8.0-incubating | ##### Pre-event