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 <[email protected]>
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