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 <[email protected]>
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();
}