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

jmclean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new c9d124b20 [#5962] feat(client): added audit cli command model (#6047)
c9d124b20 is described below

commit c9d124b2016900dde2ad1ee1bfba6a7387bf5ce1
Author: Vignesh Suresh Kumar <55813127+vigneshs...@users.noreply.github.com>
AuthorDate: Thu Jan 2 19:00:29 2025 -0500

    [#5962] feat(client): added audit cli command model (#6047)
    
    ### What changes were proposed in this pull request?
    
    The audit command is one of the commands suggested by @justinmclean as
    part of adding Model entity support for the CLI.
    
    Also includes addition of relevant testing code for Model entity CLI
    commands a whole.
    
    ### Why are the changes needed?
    
    To add audit functionality for a Model using the CLI
    
    Improvement: #5962
    
    ### Does this PR introduce _any_ user-facing change?
    
    Yes.
    
    The audit command for a model was added.
    
    ### How was this patch tested?
    
    Unit tests were added for Model CLI support and ran successfully for the
    audit command.
---
 .../org/apache/gravitino/cli/CommandEntities.java  |  1 +
 .../org/apache/gravitino/cli/ErrorMessages.java    |  1 +
 .../java/org/apache/gravitino/cli/FullName.java    |  2 +-
 .../apache/gravitino/cli/GravitinoCommandLine.java | 11 ++-
 .../apache/gravitino/cli/TestableCommandLine.java  |  6 ++
 .../apache/gravitino/cli/commands/ModelAudit.java  | 90 ++++++++++++++++++++++
 clients/cli/src/main/resources/model_help.txt      |  8 ++
 ...estModelCommand.java => TestModelCommands.java} | 24 +++++-
 docs/cli.md                                        |  4 +-
 9 files changed, 142 insertions(+), 5 deletions(-)

diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
index 2dd50974e..47a03b7be 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
@@ -47,6 +47,7 @@ public class CommandEntities {
     VALID_ENTITIES.add(SCHEMA);
     VALID_ENTITIES.add(TABLE);
     VALID_ENTITIES.add(COLUMN);
+    VALID_ENTITIES.add(MODEL);
     VALID_ENTITIES.add(USER);
     VALID_ENTITIES.add(GROUP);
     VALID_ENTITIES.add(TAG);
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
index 4bd523ec2..084b5c34c 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
@@ -57,6 +57,7 @@ public class ErrorMessages {
   public static final String UNKNOWN_ROLE = "Unknown role.";
   public static final String ROLE_EXISTS = "Role already exists.";
   public static final String TABLE_EXISTS = "Table already exists.";
+  public static final String MODEL_EXISTS = "Model already exists.";
   public static final String INVALID_SET_COMMAND =
       "Unsupported combination of options either use --name, --user, --group 
or --property and --value.";
   public static final String INVALID_REMOVE_COMMAND =
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 c21d21af4..a3b206dfd 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
@@ -99,7 +99,7 @@ public class FullName {
   /**
    * Retrieves the model name from the second part of the full name option.
    *
-   * @return The model name, or null if not found
+   * @return The model name, or null if not found.
    */
   public String getModelName() {
     return getNamePart(2);
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
index 8cd335beb..c23fb8b7c 100644
--- 
a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
@@ -140,6 +140,8 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
       handleCatalogCommand();
     } else if (entity.equals(CommandEntities.METALAKE)) {
       handleMetalakeCommand();
+    } else if (entity.equals(CommandEntities.MODEL)) {
+      handleModelCommand();
     } else if (entity.equals(CommandEntities.TOPIC)) {
       handleTopicCommand();
     } else if (entity.equals(CommandEntities.FILESET)) {
@@ -1152,6 +1154,9 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     }
   }
 
+  /**
+   * Handles the command execution for Models based on command type and the 
command line options.
+   */
   private void handleModelCommand() {
     String url = getUrl();
     String auth = getAuth();
@@ -1180,7 +1185,11 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
 
     switch (command) {
       case CommandActions.DETAILS:
-        newModelDetails(url, ignore, metalake, catalog, schema, 
model).handle();
+        if (line.hasOption(GravitinoOptions.AUDIT)) {
+          newModelAudit(url, ignore, metalake, catalog, schema, 
model).handle();
+        } else {
+          newModelDetails(url, ignore, metalake, catalog, schema, 
model).handle();
+        }
         break;
 
       default:
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
index 3cfd84ad8..6a4687491 100644
--- 
a/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
@@ -80,6 +80,7 @@ import org.apache.gravitino.cli.commands.MetalakeAudit;
 import org.apache.gravitino.cli.commands.MetalakeDetails;
 import org.apache.gravitino.cli.commands.MetalakeDisable;
 import org.apache.gravitino.cli.commands.MetalakeEnable;
+import org.apache.gravitino.cli.commands.ModelAudit;
 import org.apache.gravitino.cli.commands.ModelDetails;
 import org.apache.gravitino.cli.commands.OwnerDetails;
 import org.apache.gravitino.cli.commands.RemoveAllTags;
@@ -915,6 +916,11 @@ public class TestableCommandLine {
     return new ListModel(url, ignore, metalake, catalog, schema);
   }
 
+  protected ModelAudit newModelAudit(
+      String url, boolean ignore, String metalake, String catalog, String 
schema, String model) {
+    return new ModelAudit(url, ignore, metalake, catalog, schema, model);
+  }
+
   protected ModelDetails newModelDetails(
       String url, boolean ignore, String metalake, String catalog, String 
schema, String model) {
     return new ModelDetails(url, ignore, metalake, catalog, schema, model);
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ModelAudit.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ModelAudit.java
new file mode 100644
index 000000000..841afd2de
--- /dev/null
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ModelAudit.java
@@ -0,0 +1,90 @@
+/*
+ * 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.commands;
+
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchCatalogException;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchModelException;
+import org.apache.gravitino.model.Model;
+import org.apache.gravitino.model.ModelCatalog;
+
+/** Displays the audit information of a model. */
+public class ModelAudit extends AuditCommand {
+
+  protected final String metalake;
+  protected final String catalog;
+  protected final String schema;
+  protected final String model;
+
+  /**
+   * Displays the audit information of a model.
+   *
+   * @param url The URL of the Gravitino server.
+   * @param ignoreVersions If true don't check the client/server versions 
match.
+   * @param metalake The name of the metalake.
+   * @param catalog The name of the catalog.
+   * @param schema The name of the schema.
+   * @param model The name of the model.
+   */
+  public ModelAudit(
+      String url,
+      boolean ignoreVersions,
+      String metalake,
+      String catalog,
+      String schema,
+      String model) {
+    super(url, ignoreVersions);
+    this.metalake = metalake;
+    this.catalog = catalog;
+    this.schema = schema;
+    this.model = model;
+  }
+
+  /** Displays the audit information of a model. */
+  @Override
+  public void handle() {
+    NameIdentifier name = NameIdentifier.of(schema, model);
+    Model result;
+
+    try (GravitinoClient client = buildClient(this.metalake)) {
+      ModelCatalog modelCatalog = client.loadCatalog(catalog).asModelCatalog();
+      result = modelCatalog.getModel(name);
+    } catch (NoSuchMetalakeException err) {
+      System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+      return;
+    } catch (NoSuchCatalogException err) {
+      System.err.println(ErrorMessages.UNKNOWN_CATALOG);
+      return;
+    } catch (NoSuchModelException err) {
+      System.err.println(ErrorMessages.UNKNOWN_MODEL);
+      return;
+    } catch (Exception exp) {
+      System.err.println(exp.getMessage());
+      return;
+    }
+
+    if (result != null) {
+      displayAuditInfo(result.auditInfo());
+    }
+  }
+}
diff --git a/clients/cli/src/main/resources/model_help.txt 
b/clients/cli/src/main/resources/model_help.txt
new file mode 100644
index 000000000..04e9b8262
--- /dev/null
+++ b/clients/cli/src/main/resources/model_help.txt
@@ -0,0 +1,8 @@
+gcli model [details]
+
+Please set the metalake in the Gravitino configuration file or the environment 
variable before running any of these commands.
+
+Example commands
+
+Show model audit information
+gcli model details --name catalog_postgres.hr --audit
\ No newline at end of file
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommand.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java
similarity index 90%
rename from 
clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommand.java
rename to 
clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java
index d222655b6..e486c41a9 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommand.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java
@@ -38,13 +38,14 @@ import java.util.Collections;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Options;
 import org.apache.gravitino.cli.commands.ListModel;
+import org.apache.gravitino.cli.commands.ModelAudit;
 import org.apache.gravitino.cli.commands.ModelDetails;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.testcontainers.shaded.com.google.common.base.Joiner;
 
-public class TestModelCommand {
+public class TestModelCommands {
   private final Joiner joiner = Joiner.on(", ").skipNulls();
   private CommandLine mockCommandLine;
   private Options mockOptions;
@@ -267,4 +268,25 @@ public class TestModelCommand {
             + joiner.join(Collections.singletonList(CommandEntities.MODEL)),
         output);
   }
+
+  @Test
+  void testModelAuditCommand() {
+    ModelAudit mockAudit = mock(ModelAudit.class);
+    
when(mockCommandLine.hasOption(GravitinoOptions.METALAKE)).thenReturn(true);
+    
when(mockCommandLine.getOptionValue(GravitinoOptions.METALAKE)).thenReturn("metalake_demo");
+    when(mockCommandLine.hasOption(GravitinoOptions.NAME)).thenReturn(true);
+    
when(mockCommandLine.getOptionValue(GravitinoOptions.NAME)).thenReturn("catalog.schema.model");
+    when(mockCommandLine.hasOption(GravitinoOptions.AUDIT)).thenReturn(true);
+
+    GravitinoCommandLine commandLine =
+        spy(
+            new GravitinoCommandLine(
+                mockCommandLine, mockOptions, CommandEntities.MODEL, 
CommandActions.DETAILS));
+    doReturn(mockAudit)
+        .when(commandLine)
+        .newModelAudit(
+            GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo", 
"catalog", "schema", "model");
+    commandLine.handleCommandLine();
+    verify(mockAudit).handle();
+  }
 }
diff --git a/docs/cli.md b/docs/cli.md
index 64d720f2e..0cc7dee4a 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -23,11 +23,11 @@ alias gcli='java -jar 
../../cli/build/libs/gravitino-cli-*-incubating-SNAPSHOT.j
 Or you use the `gcli.sh` script found in the `clients/cli/bin/` directory to 
run the CLI.
 
 ## Usage
-
+f
 The general structure for running commands with the Gravitino CLI is `gcli 
entity command [options]`.
 
  ```bash
-  usage: gcli 
[metalake|catalog|schema|table|column|user|group|tag|topic|fileset] 
[list|details|create|delete|update|set|remove|properties|revoke|grant] [options]
+  usage: gcli 
[metalake|catalog|schema|model|table|column|user|group|tag|topic|fileset] 
[list|details|create|delete|update|set|remove|properties|revoke|grant] [options]
   Options
  usage: gcli
  -a,--audit              display audit information

Reply via email to