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 d5a29a4161 [#6112] fix(CLI): Refactor the validation logic of column 
and model (#6120)
d5a29a4161 is described below

commit d5a29a41615539cf77b82438338eeeeeff222d7d
Author: Lord of Abyss <103809695+abyss-l...@users.noreply.github.com>
AuthorDate: Tue Jan 7 09:25:04 2025 +0800

    [#6112] fix(CLI): Refactor the validation logic of column and model (#6120)
    
    ### What changes were proposed in this pull request?
    
    Refactor the validation logic of column and model.
    
    ### Why are the changes needed?
    
    Fix: #6112
    
    ### Does this PR introduce _any_ user-facing change?
    
    No
    
    ### How was this patch tested?
    
    ut + local test
    ```bash
    gcli model update -m demo_metalake --name catalog.schema.model
    # Missing --uri option.
    
    gcli column update -m demo_metalake --name 
Hive_catalog.default.test_dates.id --default
    # Missing --datatype option.
    ```
---
 .../org/apache/gravitino/cli/ErrorMessages.java    |  1 +
 .../apache/gravitino/cli/GravitinoCommandLine.java | 35 ++++++++-------
 .../apache/gravitino/cli/commands/LinkModel.java   |  6 +++
 .../cli/commands/UpdateColumnDefault.java          |  6 +++
 .../apache/gravitino/cli/TestCatalogCommands.java  |  1 +
 .../apache/gravitino/cli/TestColumnCommands.java   | 33 ++++++++++++++
 .../apache/gravitino/cli/TestModelCommands.java    | 50 ++++++++++++----------
 .../apache/gravitino/cli/TestSchemaCommands.java   |  1 +
 .../apache/gravitino/cli/TestTableCommands.java    |  1 +
 9 files changed, 96 insertions(+), 38 deletions(-)

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 c839ad162b..abc6421d95 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
@@ -49,6 +49,7 @@ public class ErrorMessages {
 
   public static final String MALFORMED_NAME = "Malformed entity name.";
   public static final String MISSING_COLUMN_FILE = "Missing --columnfile 
option.";
+  public static final String MISSING_DATATYPE = "Missing --datatype option.";
   public static final String MISSING_ENTITIES = "Missing required entity 
names: ";
 
   public static final String MISSING_GROUP = "Missing --group option.";
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 f93da3003c..07a1ecd5b7 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
@@ -257,7 +257,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
 
     // Handle the CommandActions.LIST action separately as it doesn't use 
`catalog`
     if (CommandActions.LIST.equals(command)) {
-      newListCatalogs(url, ignore, outputFormat, metalake).handle();
+      newListCatalogs(url, ignore, outputFormat, metalake).validate().handle();
       return;
     }
 
@@ -356,7 +356,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     // Handle the CommandActions.LIST action separately as it doesn't use 
`schema`
     if (CommandActions.LIST.equals(command)) {
       checkEntities(missingEntities);
-      newListSchema(url, ignore, metalake, catalog).handle();
+      newListSchema(url, ignore, metalake, catalog).validate().handle();
       return;
     }
 
@@ -429,7 +429,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     // Handle CommandActions.LIST action separately as it doesn't require the 
`table`
     if (CommandActions.LIST.equals(command)) {
       checkEntities(missingEntities);
-      newListTables(url, ignore, metalake, catalog, schema).handle();
+      newListTables(url, ignore, metalake, catalog, 
schema).validate().handle();
       return;
     }
 
@@ -833,7 +833,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
 
     if (CommandActions.LIST.equals(command)) {
       checkEntities(missingEntities);
-      newListColumns(url, ignore, metalake, catalog, schema, table).handle();
+      newListColumns(url, ignore, metalake, catalog, schema, 
table).validate().handle();
       return;
     }
 
@@ -844,7 +844,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     switch (command) {
       case CommandActions.DETAILS:
         if (line.hasOption(GravitinoOptions.AUDIT)) {
-          newColumnAudit(url, ignore, metalake, catalog, schema, table, 
column).handle();
+          newColumnAudit(url, ignore, metalake, catalog, schema, table, 
column).validate().handle();
         } else {
           System.err.println(ErrorMessages.UNSUPPORTED_ACTION);
           Main.exit(-1);
@@ -878,12 +878,13 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
                   nullable,
                   autoIncrement,
                   defaultValue)
+              .validate()
               .handle();
           break;
         }
 
       case CommandActions.DELETE:
-        newDeleteColumn(url, ignore, metalake, catalog, schema, table, 
column).handle();
+        newDeleteColumn(url, ignore, metalake, catalog, schema, table, 
column).validate().handle();
         break;
 
       case CommandActions.UPDATE:
@@ -891,34 +892,40 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
           if (line.hasOption(GravitinoOptions.COMMENT)) {
             String comment = line.getOptionValue(GravitinoOptions.COMMENT);
             newUpdateColumnComment(url, ignore, metalake, catalog, schema, 
table, column, comment)
+                .validate()
                 .handle();
           }
           if (line.hasOption(GravitinoOptions.RENAME)) {
             String newName = line.getOptionValue(GravitinoOptions.RENAME);
             newUpdateColumnName(url, ignore, metalake, catalog, schema, table, 
column, newName)
+                .validate()
                 .handle();
           }
           if (line.hasOption(GravitinoOptions.DATATYPE)
               && !line.hasOption(GravitinoOptions.DEFAULT)) {
             String datatype = line.getOptionValue(GravitinoOptions.DATATYPE);
             newUpdateColumnDatatype(url, ignore, metalake, catalog, schema, 
table, column, datatype)
+                .validate()
                 .handle();
           }
           if (line.hasOption(GravitinoOptions.POSITION)) {
             String position = line.getOptionValue(GravitinoOptions.POSITION);
             newUpdateColumnPosition(url, ignore, metalake, catalog, schema, 
table, column, position)
+                .validate()
                 .handle();
           }
           if (line.hasOption(GravitinoOptions.NULL)) {
             boolean nullable = 
line.getOptionValue(GravitinoOptions.NULL).equals("true");
             newUpdateColumnNullability(
                     url, ignore, metalake, catalog, schema, table, column, 
nullable)
+                .validate()
                 .handle();
           }
           if (line.hasOption(GravitinoOptions.AUTO)) {
             boolean autoIncrement = 
line.getOptionValue(GravitinoOptions.AUTO).equals("true");
             newUpdateColumnAutoIncrement(
                     url, ignore, metalake, catalog, schema, table, column, 
autoIncrement)
+                .validate()
                 .handle();
           }
           if (line.hasOption(GravitinoOptions.DEFAULT)) {
@@ -926,6 +933,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
             String dataType = line.getOptionValue(GravitinoOptions.DATATYPE);
             newUpdateColumnDefault(
                     url, ignore, metalake, catalog, schema, table, column, 
defaultValue, dataType)
+                .validate()
                 .handle();
           }
           break;
@@ -1207,7 +1215,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     // Handle CommandActions.LIST action separately as it doesn't require the 
`model`
     if (CommandActions.LIST.equals(command)) {
       checkEntities(missingEntities);
-      newListModel(url, ignore, metalake, catalog, schema).handle();
+      newListModel(url, ignore, metalake, catalog, schema).validate().handle();
       return;
     }
 
@@ -1218,15 +1226,15 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     switch (command) {
       case CommandActions.DETAILS:
         if (line.hasOption(GravitinoOptions.AUDIT)) {
-          newModelAudit(url, ignore, metalake, catalog, schema, 
model).handle();
+          newModelAudit(url, ignore, metalake, catalog, schema, 
model).validate().handle();
         } else {
-          newModelDetails(url, ignore, metalake, catalog, schema, 
model).handle();
+          newModelDetails(url, ignore, metalake, catalog, schema, 
model).validate().handle();
         }
         break;
 
       case CommandActions.DELETE:
         boolean force = line.hasOption(GravitinoOptions.FORCE);
-        newDeleteModel(url, ignore, force, metalake, catalog, schema, 
model).handle();
+        newDeleteModel(url, ignore, force, metalake, catalog, schema, 
model).validate().handle();
         break;
 
       case CommandActions.CREATE:
@@ -1235,17 +1243,13 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
         Map<String, String> createPropertyMap = new 
Properties().parse(createProperties);
         newCreateModel(
                 url, ignore, metalake, catalog, schema, model, createComment, 
createPropertyMap)
+            .validate()
             .handle();
         break;
 
       case CommandActions.UPDATE:
         String[] alias = line.getOptionValues(GravitinoOptions.ALIAS);
         String uri = line.getOptionValue(GravitinoOptions.URI);
-        if (uri == null) {
-          System.err.println(ErrorMessages.MISSING_URI);
-          Main.exit(-1);
-        }
-
         String linkComment = line.getOptionValue(GravitinoOptions.COMMENT);
         String[] linkProperties = 
line.getOptionValues(CommandActions.PROPERTIES);
         Map<String, String> linkPropertityMap = new 
Properties().parse(linkProperties);
@@ -1260,6 +1264,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
                 alias,
                 linkComment,
                 linkPropertityMap)
+            .validate()
             .handle();
         break;
 
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/LinkModel.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/LinkModel.java
index 6e8a4ffb76..cf34eae882 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/LinkModel.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/LinkModel.java
@@ -103,4 +103,10 @@ public class LinkModel extends Command {
     System.out.println(
         "Linked model " + model + " to " + uri + " with aliases " + 
Arrays.toString(alias));
   }
+
+  @Override
+  public Command validate() {
+    if (uri == null) exitWithError(ErrorMessages.MISSING_URI);
+    return super.validate();
+  }
 }
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UpdateColumnDefault.java
 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UpdateColumnDefault.java
index 7c7c2d3b40..976cf62305 100644
--- 
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UpdateColumnDefault.java
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UpdateColumnDefault.java
@@ -103,4 +103,10 @@ public class UpdateColumnDefault extends Command {
 
     System.out.println(column + " default changed.");
   }
+
+  @Override
+  public Command validate() {
+    if (dataType == null) exitWithError(ErrorMessages.MISSING_DATATYPE);
+    return super.validate();
+  }
 }
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestCatalogCommands.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestCatalogCommands.java
index 04c0dacc13..afa19b94c5 100644
--- 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestCatalogCommands.java
+++ 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestCatalogCommands.java
@@ -92,6 +92,7 @@ class TestCatalogCommands {
     doReturn(mockList)
         .when(commandLine)
         .newListCatalogs(GravitinoCommandLine.DEFAULT_URL, false, null, 
"metalake_demo");
+    doReturn(mockList).when(mockList).validate();
     commandLine.handleCommandLine();
     verify(mockList).handle();
   }
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestColumnCommands.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestColumnCommands.java
index 2d1e12debc..31a3139482 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestColumnCommands.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestColumnCommands.java
@@ -93,6 +93,7 @@ class TestColumnCommands {
         .when(commandLine)
         .newListColumns(
             GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo", 
"catalog", "schema", "users");
+    doReturn(mockList).when(mockList).validate();
     commandLine.handleCommandLine();
     verify(mockList).handle();
   }
@@ -120,6 +121,7 @@ class TestColumnCommands {
             "schema",
             "users",
             "name");
+    doReturn(mockAudit).when(mockAudit).validate();
     commandLine.handleCommandLine();
     verify(mockAudit).handle();
   }
@@ -187,6 +189,7 @@ class TestColumnCommands {
             true,
             false,
             null);
+    doReturn(mockAddColumn).when(mockAddColumn).validate();
     commandLine.handleCommandLine();
     verify(mockAddColumn).handle();
   }
@@ -214,6 +217,7 @@ class TestColumnCommands {
             "schema",
             "users",
             "name");
+    doReturn(mockDelete).when(mockDelete).validate();
     commandLine.handleCommandLine();
     verify(mockDelete).handle();
   }
@@ -246,6 +250,7 @@ class TestColumnCommands {
             "users",
             "name",
             "new comment");
+    doReturn(mockUpdateColumn).when(mockUpdateColumn).validate();
     commandLine.handleCommandLine();
     verify(mockUpdateColumn).handle();
   }
@@ -278,6 +283,7 @@ class TestColumnCommands {
             "users",
             "name",
             "renamed");
+    doReturn(mockUpdateName).when(mockUpdateName).validate();
     commandLine.handleCommandLine();
     verify(mockUpdateName).handle();
   }
@@ -310,6 +316,7 @@ class TestColumnCommands {
             "users",
             "name",
             "varchar(250)");
+    doReturn(mockUpdateDatatype).when(mockUpdateDatatype).validate();
     commandLine.handleCommandLine();
     verify(mockUpdateDatatype).handle();
   }
@@ -342,6 +349,7 @@ class TestColumnCommands {
             "users",
             "name",
             "first");
+    doReturn(mockUpdatePosition).when(mockUpdatePosition).validate();
     commandLine.handleCommandLine();
     verify(mockUpdatePosition).handle();
   }
@@ -373,6 +381,7 @@ class TestColumnCommands {
             "users",
             "name",
             true);
+    doReturn(mockUpdateNull).when(mockUpdateNull).validate();
     commandLine.handleCommandLine();
     verify(mockUpdateNull).handle();
   }
@@ -404,6 +413,7 @@ class TestColumnCommands {
             "users",
             "name",
             true);
+    doReturn(mockUpdateAuto).when(mockUpdateAuto).validate();
     commandLine.handleCommandLine();
     verify(mockUpdateAuto).handle();
   }
@@ -439,10 +449,33 @@ class TestColumnCommands {
             "name",
             "Fred Smith",
             "varchar(100)");
+    doReturn(mockUpdateDefault).when(mockUpdateDefault).validate();
     commandLine.handleCommandLine();
     verify(mockUpdateDefault).handle();
   }
 
+  @Test
+  void testUpdateColumnDefaultWithoutDataType() {
+    Main.useExit = false;
+    UpdateColumnDefault spyUpdate =
+        spy(
+            new UpdateColumnDefault(
+                GravitinoCommandLine.DEFAULT_URL,
+                false,
+                "metalake_demo",
+                "catalog",
+                "schema",
+                "user",
+                "name",
+                "",
+                null));
+
+    assertThrows(RuntimeException.class, spyUpdate::validate);
+    verify(spyUpdate, never()).handle();
+    String output = new String(errContent.toByteArray(), 
StandardCharsets.UTF_8).trim();
+    assertEquals(ErrorMessages.MISSING_DATATYPE, output);
+  }
+
   @Test
   @SuppressWarnings("DefaultCharset")
   void testDeleteColumnCommandWithoutCatalog() {
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java
index 8d475d3625..b83cc3c313 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestModelCommands.java
@@ -94,6 +94,7 @@ public class TestModelCommands {
             eq("metalake_demo"),
             eq("catalog"),
             eq("schema"));
+    doReturn(mockList).when(mockList).validate();
     commandLine.handleCommandLine();
     verify(mockList).handle();
   }
@@ -176,6 +177,7 @@ public class TestModelCommands {
             eq("catalog"),
             eq("schema"),
             eq("model"));
+    doReturn(mockList).when(mockList).validate();
     commandLine.handleCommandLine();
     verify(mockList).handle();
   }
@@ -291,6 +293,7 @@ public class TestModelCommands {
         .when(commandLine)
         .newModelAudit(
             GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo", 
"catalog", "schema", "model");
+    doReturn(mockAudit).when(mockAudit).validate();
     commandLine.handleCommandLine();
     verify(mockAudit).handle();
   }
@@ -320,6 +323,7 @@ public class TestModelCommands {
             eq("model"),
             isNull(),
             argThat(Map::isEmpty));
+    doReturn(mockCreate).when(mockCreate).validate();
     commandLine.handleCommandLine();
     verify(mockCreate).handle();
   }
@@ -349,6 +353,7 @@ public class TestModelCommands {
             eq("model"),
             eq("comment"),
             argThat(Map::isEmpty));
+    doReturn(mockCreate).when(mockCreate).validate();
     commandLine.handleCommandLine();
     verify(mockCreate).handle();
   }
@@ -384,6 +389,7 @@ public class TestModelCommands {
                     argument.size() == 2
                         && argument.containsKey("key1")
                         && argument.get("key1").equals("val1")));
+    doReturn(mockCreate).when(mockCreate).validate();
     commandLine.handleCommandLine();
     verify(mockCreate).handle();
   }
@@ -420,6 +426,7 @@ public class TestModelCommands {
                     argument.size() == 2
                         && argument.containsKey("key1")
                         && argument.get("key1").equals("val1")));
+    doReturn(mockCreate).when(mockCreate).validate();
     commandLine.handleCommandLine();
     verify(mockCreate).handle();
   }
@@ -446,6 +453,7 @@ public class TestModelCommands {
             "catalog",
             "schema",
             "model");
+    doReturn(mockDelete).when(mockDelete).validate();
     commandLine.handleCommandLine();
     verify(mockDelete).handle();
   }
@@ -478,6 +486,7 @@ public class TestModelCommands {
             isNull(),
             isNull(),
             argThat(Map::isEmpty));
+    doReturn(linkModelMock).when(linkModelMock).validate();
     commandLine.handleCommandLine();
     verify(linkModelMock).handle();
   }
@@ -516,6 +525,7 @@ public class TestModelCommands {
                         && "aliasB".equals(argument[1])),
             isNull(),
             argThat(Map::isEmpty));
+    doReturn(linkModelMock).when(linkModelMock).validate();
     commandLine.handleCommandLine();
     verify(linkModelMock).handle();
   }
@@ -523,30 +533,23 @@ public class TestModelCommands {
   @Test
   void testLinkModelCommandWithoutURI() {
     Main.useExit = false;
-    
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.URI)).thenReturn(false);
-    when(mockCommandLine.hasOption(GravitinoOptions.ALIAS)).thenReturn(false);
-    GravitinoCommandLine commandLine =
-        spy(
-            new GravitinoCommandLine(
-                mockCommandLine, mockOptions, CommandEntities.MODEL, 
CommandActions.UPDATE));
 
-    assertThrows(RuntimeException.class, commandLine::handleCommandLine);
-    verify(commandLine, never())
-        .newLinkModel(
-            eq(GravitinoCommandLine.DEFAULT_URL),
-            eq(false),
-            eq("metalake_demo"),
-            eq("catalog"),
-            eq("schema"),
-            eq("model"),
-            isNull(),
-            isNull(),
-            isNull(),
-            argThat(Map::isEmpty));
+    LinkModel spyLinkModel =
+        spy(
+            new LinkModel(
+                GravitinoCommandLine.DEFAULT_URL,
+                false,
+                "metalake_demo",
+                "catalog",
+                "schema",
+                "model",
+                null,
+                new String[] {"aliasA", "aliasB"},
+                "comment",
+                Collections.EMPTY_MAP));
+
+    assertThrows(RuntimeException.class, spyLinkModel::validate);
+    verify(spyLinkModel, never()).handle();
     String output = new String(errContent.toByteArray(), 
StandardCharsets.UTF_8).trim();
     assertEquals(ErrorMessages.MISSING_URI, output);
   }
@@ -596,6 +599,7 @@ public class TestModelCommands {
                         && argument.containsKey("key2")
                         && "val1".equals(argument.get("key1"))
                         && "val2".equals(argument.get("key2"))));
+    doReturn(linkModelMock).when(linkModelMock).validate();
     commandLine.handleCommandLine();
     verify(linkModelMock).handle();
   }
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestSchemaCommands.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestSchemaCommands.java
index 9059afeedb..6b8770d8ed 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestSchemaCommands.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestSchemaCommands.java
@@ -88,6 +88,7 @@ class TestSchemaCommands {
     doReturn(mockList)
         .when(commandLine)
         .newListSchema(GravitinoCommandLine.DEFAULT_URL, false, 
"metalake_demo", "catalog");
+    doReturn(mockList).when(mockList).validate();
     commandLine.handleCommandLine();
     verify(mockList).handle();
   }
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestTableCommands.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestTableCommands.java
index 0193c834a5..f068332045 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestTableCommands.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestTableCommands.java
@@ -95,6 +95,7 @@ class TestTableCommands {
         .when(commandLine)
         .newListTables(
             GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo", 
"catalog", "schema");
+    doReturn(mockList).when(mockList).validate();
     commandLine.handleCommandLine();
     verify(mockList).handle();
   }

Reply via email to