This is an automated email from the ASF dual-hosted git repository.

roryqi pushed a commit to branch ISSUE-6353
in repository https://gitbox.apache.org/repos/asf/gravitino.git

commit 97adf259872044c46c0f957b87b6515647ab301c
Author: Lord of Abyss <103809695+abyss-l...@users.noreply.github.com>
AuthorDate: Thu Jan 16 13:13:24 2025 +0800

    [#6242] improve(CLI): Add tag support to Models in Gravtitino CLI. (#6284)
    
    ### What changes were proposed in this pull request?
    
    Add tag support to Models in Gravtitino CLI. currently, the CLI support
    following actions:
    1. `UntagEntity`,
    2. `TagEntity`,
    3. `ListEntityTags`
    
    ### Why are the changes needed?
    
    Fix: #6242
    
    ### Does this PR introduce _any_ user-facing change?
    
    No
    
    ### How was this patch tested?
    
    local test.
---
 .../java/org/apache/gravitino/cli/FullName.java    | 14 ++++
 .../gravitino/cli/commands/ListEntityTags.java     | 42 +++++++++---
 .../apache/gravitino/cli/commands/TagEntity.java   | 51 ++++++++++----
 .../apache/gravitino/cli/commands/UntagEntity.java | 51 ++++++++++----
 .../apache/gravitino/cli/utils/FullNameUtil.java   | 79 +++++++++++++++++++++
 .../org/apache/gravitino/cli/TestFullNameUtil.java | 80 ++++++++++++++++++++++
 .../org/apache/gravitino/cli/TestFulllName.java    | 36 ++++++++++
 7 files changed, 318 insertions(+), 35 deletions(-)

diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/FullName.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/FullName.java
index 7a9481cb95..f6de0213ed 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/FullName.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/FullName.java
@@ -41,6 +41,20 @@ public class FullName {
     this.line = line;
   }
 
+  /**
+   * Retrieves the level of the full name.
+   *
+   * @return The level of the full name, or -1 if line does not contain a 
{@code --name} option.
+   */
+  public int getLevel() {
+    if (line.hasOption(GravitinoOptions.NAME)) {
+      String[] names = line.getOptionValue(GravitinoOptions.NAME).split("\\.");
+      return names.length;
+    }
+
+    return -1;
+  }
+
   /**
    * Retrieves the metalake name from the command line options, the 
GRAVITINO_METALAKE environment
    * variable or the Gravitino config file.
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListEntityTags.java
 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListEntityTags.java
index c0dc501732..90b1000fa0 100644
--- 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListEntityTags.java
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListEntityTags.java
@@ -20,15 +20,18 @@
 package org.apache.gravitino.cli.commands;
 
 import org.apache.gravitino.Catalog;
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.Schema;
 import org.apache.gravitino.cli.ErrorMessages;
 import org.apache.gravitino.cli.FullName;
+import org.apache.gravitino.cli.utils.FullNameUtil;
 import org.apache.gravitino.client.GravitinoClient;
 import org.apache.gravitino.exceptions.NoSuchCatalogException;
 import org.apache.gravitino.exceptions.NoSuchMetalakeException;
 import org.apache.gravitino.exceptions.NoSuchSchemaException;
 import org.apache.gravitino.exceptions.NoSuchTableException;
+import org.apache.gravitino.file.Fileset;
+import org.apache.gravitino.messaging.Topic;
+import org.apache.gravitino.model.Model;
 import org.apache.gravitino.rel.Table;
 
 /* Lists all tags in a metalake. */
@@ -58,17 +61,34 @@ public class ListEntityTags extends Command {
     try {
       GravitinoClient client = buildClient(metalake);
 
-      // TODO fileset and topic
-      if (name.hasTableName()) {
+      if (name.getLevel() == 3) {
         String catalog = name.getCatalogName();
-        String schema = name.getSchemaName();
-        String table = name.getTableName();
-        Table gTable =
-            client
-                .loadCatalog(catalog)
-                .asTableCatalog()
-                .loadTable(NameIdentifier.of(schema, table));
-        tags = gTable.supportsTags().listTags();
+        Catalog catalogObject = client.loadCatalog(catalog);
+        switch (catalogObject.type()) {
+          case RELATIONAL:
+            Table gTable = 
catalogObject.asTableCatalog().loadTable(FullNameUtil.toTable(name));
+            tags = gTable.supportsTags().listTags();
+            break;
+
+          case MODEL:
+            Model gModel = 
catalogObject.asModelCatalog().getModel(FullNameUtil.toModel(name));
+            tags = gModel.supportsTags().listTags();
+            break;
+
+          case FILESET:
+            Fileset fileset =
+                
catalogObject.asFilesetCatalog().loadFileset(FullNameUtil.toFileset(name));
+            tags = fileset.supportsTags().listTags();
+            break;
+
+          case MESSAGING:
+            Topic topic = 
catalogObject.asTopicCatalog().loadTopic(FullNameUtil.toTopic(name));
+            tags = topic.supportsTags().listTags();
+            break;
+
+          default:
+            break;
+        }
       } else if (name.hasSchemaName()) {
         String catalog = name.getCatalogName();
         String schema = name.getSchemaName();
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagEntity.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagEntity.java
index 4a06918850..3b97778818 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagEntity.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/TagEntity.java
@@ -20,16 +20,19 @@
 package org.apache.gravitino.cli.commands;
 
 import org.apache.gravitino.Catalog;
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.Schema;
 import org.apache.gravitino.cli.ErrorMessages;
 import org.apache.gravitino.cli.FullName;
+import org.apache.gravitino.cli.utils.FullNameUtil;
 import org.apache.gravitino.client.GravitinoClient;
 import org.apache.gravitino.exceptions.NoSuchCatalogException;
 import org.apache.gravitino.exceptions.NoSuchMetalakeException;
 import org.apache.gravitino.exceptions.NoSuchSchemaException;
 import org.apache.gravitino.exceptions.NoSuchTableException;
 import org.apache.gravitino.exceptions.TagAlreadyAssociatedException;
+import org.apache.gravitino.file.Fileset;
+import org.apache.gravitino.messaging.Topic;
+import org.apache.gravitino.model.Model;
 import org.apache.gravitino.rel.Table;
 
 public class TagEntity extends Command {
@@ -63,18 +66,42 @@ public class TagEntity extends Command {
     try {
       GravitinoClient client = buildClient(metalake);
 
-      // TODO fileset and topic
-      if (name.hasTableName()) {
+      if (name.getLevel() == 3) {
         String catalog = name.getCatalogName();
-        String schema = name.getSchemaName();
-        String table = name.getTableName();
-        Table gTable =
-            client
-                .loadCatalog(catalog)
-                .asTableCatalog()
-                .loadTable(NameIdentifier.of(schema, table));
-        tagsToAdd = gTable.supportsTags().associateTags(tags, null);
-        entity = table;
+        Catalog catalogObject = client.loadCatalog(catalog);
+        switch (catalogObject.type()) {
+          case RELATIONAL:
+            String table = name.getTableName();
+            entity = table;
+            Table gTable = 
catalogObject.asTableCatalog().loadTable(FullNameUtil.toTable(name));
+            tagsToAdd = gTable.supportsTags().associateTags(tags, null);
+            break;
+
+          case MODEL:
+            String model = name.getModelName();
+            entity = model;
+            Model gModel = 
catalogObject.asModelCatalog().getModel(FullNameUtil.toModel(name));
+            tagsToAdd = gModel.supportsTags().associateTags(tags, null);
+            break;
+
+          case FILESET:
+            String fileset = name.getFilesetName();
+            entity = fileset;
+            Fileset gFileset =
+                
catalogObject.asFilesetCatalog().loadFileset(FullNameUtil.toFileset(name));
+            gFileset.supportsTags().associateTags(tags, null);
+            break;
+
+          case MESSAGING:
+            String topic = name.getTopicName();
+            entity = topic;
+            Topic gTopic = 
catalogObject.asTopicCatalog().loadTopic(FullNameUtil.toTopic(name));
+            gTopic.supportsTags().associateTags(tags, null);
+            break;
+
+          default:
+            break;
+        }
       } else if (name.hasSchemaName()) {
         String catalog = name.getCatalogName();
         String schema = name.getSchemaName();
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UntagEntity.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UntagEntity.java
index e82d0da470..205242135b 100644
--- 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UntagEntity.java
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UntagEntity.java
@@ -20,15 +20,18 @@
 package org.apache.gravitino.cli.commands;
 
 import org.apache.gravitino.Catalog;
-import org.apache.gravitino.NameIdentifier;
 import org.apache.gravitino.Schema;
 import org.apache.gravitino.cli.ErrorMessages;
 import org.apache.gravitino.cli.FullName;
+import org.apache.gravitino.cli.utils.FullNameUtil;
 import org.apache.gravitino.client.GravitinoClient;
 import org.apache.gravitino.exceptions.NoSuchCatalogException;
 import org.apache.gravitino.exceptions.NoSuchMetalakeException;
 import org.apache.gravitino.exceptions.NoSuchSchemaException;
 import org.apache.gravitino.exceptions.NoSuchTableException;
+import org.apache.gravitino.file.Fileset;
+import org.apache.gravitino.messaging.Topic;
+import org.apache.gravitino.model.Model;
 import org.apache.gravitino.rel.Table;
 
 public class UntagEntity extends Command {
@@ -62,18 +65,42 @@ public class UntagEntity extends Command {
     try {
       GravitinoClient client = buildClient(metalake);
 
-      // TODO fileset and topic
-      if (name.hasTableName()) {
+      if (name.getLevel() == 3) {
         String catalog = name.getCatalogName();
-        String schema = name.getSchemaName();
-        String table = name.getTableName();
-        Table gTable =
-            client
-                .loadCatalog(catalog)
-                .asTableCatalog()
-                .loadTable(NameIdentifier.of(schema, table));
-        removeTags = gTable.supportsTags().associateTags(null, tags);
-        entity = table;
+        Catalog catalogObject = client.loadCatalog(catalog);
+        switch (catalogObject.type()) {
+          case RELATIONAL:
+            String table = name.getTableName();
+            entity = table;
+            Table gTable = 
catalogObject.asTableCatalog().loadTable(FullNameUtil.toTable(name));
+            removeTags = gTable.supportsTags().associateTags(null, tags);
+            break;
+
+          case MODEL:
+            String model = name.getModelName();
+            entity = model;
+            Model gModel = 
catalogObject.asModelCatalog().getModel(FullNameUtil.toModel(name));
+            removeTags = gModel.supportsTags().associateTags(null, tags);
+            break;
+
+          case FILESET:
+            String fileset = name.getFilesetName();
+            entity = fileset;
+            Fileset gFileset =
+                
catalogObject.asFilesetCatalog().loadFileset(FullNameUtil.toFileset(name));
+            removeTags = gFileset.supportsTags().associateTags(null, tags);
+            break;
+
+          case MESSAGING:
+            String topic = name.getTopicName();
+            entity = topic;
+            Topic gTopic = 
catalogObject.asTopicCatalog().loadTopic(FullNameUtil.toTopic(name));
+            removeTags = gTopic.supportsTags().associateTags(null, tags);
+            break;
+
+          default:
+            break;
+        }
       } else if (name.hasSchemaName()) {
         String catalog = name.getCatalogName();
         String schema = name.getSchemaName();
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/utils/FullNameUtil.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/utils/FullNameUtil.java
new file mode 100644
index 0000000000..6017b4246d
--- /dev/null
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/utils/FullNameUtil.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.cli.utils;
+
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.cli.FullName;
+
+/** Utility class for helping with creating NameIdentifiers from {@link 
FullName}. */
+public class FullNameUtil {
+
+  /**
+   * Returns a NameIdentifier for a model.
+   *
+   * @param fullName the {@link FullName} of the model.
+   * @return a NameIdentifier for the model.
+   */
+  public static NameIdentifier toModel(FullName fullName) {
+    String schema = fullName.getSchemaName();
+    String model = fullName.getModelName();
+
+    return NameIdentifier.of(schema, model);
+  }
+
+  /**
+   * Returns a NameIdentifier for a table.
+   *
+   * @param fullName the {@link FullName} of the table.
+   * @return a NameIdentifier for the table.
+   */
+  public static NameIdentifier toTable(FullName fullName) {
+    String schema = fullName.getSchemaName();
+    String table = fullName.getTableName();
+
+    return NameIdentifier.of(schema, table);
+  }
+
+  /**
+   * Returns a NameIdentifier for a fileset.
+   *
+   * @param fullName the {@link FullName} of the fileset.
+   * @return a NameIdentifier for the fileset.
+   */
+  public static NameIdentifier toFileset(FullName fullName) {
+    String schema = fullName.getSchemaName();
+    String fileset = fullName.getFilesetName();
+
+    return NameIdentifier.of(schema, fileset);
+  }
+
+  /**
+   * Returns a NameIdentifier for a topic.
+   *
+   * @param fullName the {@link FullName} of the topic.
+   * @return a NameIdentifier for the topic.
+   */
+  public static NameIdentifier toTopic(FullName fullName) {
+    String schema = fullName.getSchemaName();
+    String topic = fullName.getTopicName();
+
+    return NameIdentifier.of(schema, topic);
+  }
+}
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestFullNameUtil.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestFullNameUtil.java
new file mode 100644
index 0000000000..8123bb3342
--- /dev/null
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestFullNameUtil.java
@@ -0,0 +1,80 @@
+/*
+ * 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.cli;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.ParseException;
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.cli.utils.FullNameUtil;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class TestFullNameUtil {
+  private Options options;
+
+  @BeforeEach
+  public void setUp() {
+    Main.useExit = false;
+    options = new GravitinoOptions().options();
+  }
+
+  @Test
+  void testToModel() throws ParseException {
+    String[] args = {"table", "list", "-i", "--name", 
"Model_catalog.schema.model"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    NameIdentifier modelIdent = FullNameUtil.toModel(fullName);
+    Assertions.assertEquals("model", modelIdent.name());
+    Assertions.assertArrayEquals(new String[] {"schema"}, 
modelIdent.namespace().levels());
+  }
+
+  @Test
+  void testToTable() throws ParseException {
+    String[] args = {"table", "list", "-i", "--name", 
"Table_catalog.schema.table"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    NameIdentifier tableIdent = FullNameUtil.toTable(fullName);
+    Assertions.assertEquals("table", tableIdent.name());
+    Assertions.assertArrayEquals(new String[] {"schema"}, 
tableIdent.namespace().levels());
+  }
+
+  @Test
+  void testToFileset() throws ParseException {
+    String[] args = {"fileset", "list", "-i", "--name", 
"Fileset_catalog.schema.fileset"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    NameIdentifier filesetIdent = FullNameUtil.toFileset(fullName);
+    Assertions.assertEquals("fileset", filesetIdent.name());
+    Assertions.assertArrayEquals(new String[] {"schema"}, 
filesetIdent.namespace().levels());
+  }
+
+  @Test
+  void testToTopic() throws ParseException {
+    String[] args = {"topic", "list", "-i", "--name", 
"Topic_catalog.schema.topic"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    NameIdentifier topicIdent = FullNameUtil.toTopic(fullName);
+    Assertions.assertEquals("topic", topicIdent.name());
+    Assertions.assertArrayEquals(new String[] {"schema"}, 
topicIdent.namespace().levels());
+  }
+}
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestFulllName.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestFulllName.java
index f13d6e0920..c2e54c81d5 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestFulllName.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestFulllName.java
@@ -235,4 +235,40 @@ public class TestFulllName {
     String errOutput = new String(errContent.toByteArray(), 
StandardCharsets.UTF_8).trim();
     assertEquals(errOutput, ErrorMessages.MISSING_METALAKE);
   }
+
+  @Test
+  @SuppressWarnings("DefaultCharset")
+  void testGetLevelFromCatalog() throws ParseException {
+    String[] args = {"table", "list", "-i", "--name", "Hive_catalog"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    assertEquals(1, fullName.getLevel());
+  }
+
+  @Test
+  @SuppressWarnings("DefaultCharset")
+  void testGetLevelFromSchema() throws ParseException {
+    String[] args = {"table", "list", "-i", "--name", "Hive_catalog.default"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    assertEquals(2, fullName.getLevel());
+  }
+
+  @Test
+  @SuppressWarnings("DefaultCharset")
+  void testGetLevelFromTable() throws ParseException {
+    String[] args = {"table", "list", "-i", "--name", 
"Hive_catalog.default.sales"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    assertEquals(3, fullName.getLevel());
+  }
+
+  @Test
+  @SuppressWarnings("DefaultCharset")
+  void testGetLevelFromColumn() throws ParseException {
+    String[] args = {"table", "list", "-i", "--name", 
"Hive_catalog.default.sales.columns"};
+    CommandLine commandLine = new DefaultParser().parse(options, args);
+    FullName fullName = new FullName(commandLine);
+    assertEquals(4, fullName.getLevel());
+  }
 }

Reply via email to