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 09ad370429 [#6087] fix(CLI): Refactor the validation logic of catalog
(#6104)
09ad370429 is described below
commit 09ad370429b51333b0d1ae70b6dd939ee5f29424
Author: Lord of Abyss <[email protected]>
AuthorDate: Mon Jan 6 13:30:14 2025 +0800
[#6087] fix(CLI): Refactor the validation logic of catalog (#6104)
### What changes were proposed in this pull request?
Add `validate` method to Command, and refactor the validation code of
catalog.
### Why are the changes needed?
Fix: #6087
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
ut + local test
```bash
gcli catalog create -m demo_metalake --name test_catalog
# Missing --provider option.
gcli catalog set -m demo_metalake --name Hive_catalog
# Missing --property and --value options.
gcli catalog set -m demo_metalake --name Hive_catalog --property propertyA
# Missing --value option.
gcli catalog set -m demo_metalake --name Hive_catalog --value valA
# Missing --property option.
gcli catalog remove -m demo_metalake --name Hive_catalog
# Missing --property option.
```
---------
Co-authored-by: Justin Mclean <[email protected]>
---
.../org/apache/gravitino/cli/ErrorMessages.java | 2 +
.../apache/gravitino/cli/GravitinoCommandLine.java | 26 +++---
.../org/apache/gravitino/cli/commands/Command.java | 12 +++
.../gravitino/cli/commands/CreateCatalog.java | 6 ++
.../cli/commands/RemoveCatalogProperty.java | 6 ++
.../gravitino/cli/commands/SetCatalogProperty.java | 6 ++
.../cli/commands/SetMetalakeProperty.java | 4 +-
.../apache/gravitino/cli/TestCatalogCommands.java | 94 ++++++++++++++++++++++
8 files changed, 142 insertions(+), 14 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 10b1e9579a..c6c2a8d981 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
@@ -62,6 +62,8 @@ public class ErrorMessages {
public static final String MULTIPLE_TAG_COMMAND_ERROR =
"This command only supports one --tag option.";
+ public static final String MISSING_PROPERTY_AND_VALUE = "Missing --property
and --value options.";
+ public static final String MISSING_PROVIDER = "Missing --provider option.";
public static final String REGISTER_FAILED = "Failed to register model: ";
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 e19cc733f2..b3917c4f06 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
@@ -268,9 +268,9 @@ public class GravitinoCommandLine extends
TestableCommandLine {
switch (command) {
case CommandActions.DETAILS:
if (line.hasOption(GravitinoOptions.AUDIT)) {
- newCatalogAudit(url, ignore, metalake, catalog).handle();
+ newCatalogAudit(url, ignore, metalake, catalog).validate().handle();
} else {
- newCatalogDetails(url, ignore, outputFormat, metalake,
catalog).handle();
+ newCatalogDetails(url, ignore, outputFormat, metalake,
catalog).validate().handle();
}
break;
@@ -279,27 +279,29 @@ public class GravitinoCommandLine extends
TestableCommandLine {
String provider = line.getOptionValue(GravitinoOptions.PROVIDER);
String[] properties = line.getOptionValues(CommandActions.PROPERTIES);
Map<String, String> propertyMap = new Properties().parse(properties);
- newCreateCatalog(url, ignore, metalake, catalog, provider, comment,
propertyMap).handle();
+ newCreateCatalog(url, ignore, metalake, catalog, provider, comment,
propertyMap)
+ .validate()
+ .handle();
break;
case CommandActions.DELETE:
boolean force = line.hasOption(GravitinoOptions.FORCE);
- newDeleteCatalog(url, ignore, force, metalake, catalog).handle();
+ newDeleteCatalog(url, ignore, force, metalake,
catalog).validate().handle();
break;
case CommandActions.SET:
String property = line.getOptionValue(GravitinoOptions.PROPERTY);
String value = line.getOptionValue(GravitinoOptions.VALUE);
- newSetCatalogProperty(url, ignore, metalake, catalog, property,
value).handle();
+ newSetCatalogProperty(url, ignore, metalake, catalog, property,
value).validate().handle();
break;
case CommandActions.REMOVE:
property = line.getOptionValue(GravitinoOptions.PROPERTY);
- newRemoveCatalogProperty(url, ignore, metalake, catalog,
property).handle();
+ newRemoveCatalogProperty(url, ignore, metalake, catalog,
property).validate().handle();
break;
case CommandActions.PROPERTIES:
- newListCatalogProperties(url, ignore, metalake, catalog).handle();
+ newListCatalogProperties(url, ignore, metalake,
catalog).validate().handle();
break;
case CommandActions.UPDATE:
@@ -309,19 +311,21 @@ public class GravitinoCommandLine extends
TestableCommandLine {
}
if (line.hasOption(GravitinoOptions.ENABLE)) {
boolean enableMetalake = line.hasOption(GravitinoOptions.ALL);
- newCatalogEnable(url, ignore, metalake, catalog,
enableMetalake).handle();
+ newCatalogEnable(url, ignore, metalake, catalog,
enableMetalake).validate().handle();
}
if (line.hasOption(GravitinoOptions.DISABLE)) {
- newCatalogDisable(url, ignore, metalake, catalog).handle();
+ newCatalogDisable(url, ignore, metalake,
catalog).validate().handle();
}
if (line.hasOption(GravitinoOptions.COMMENT)) {
String updateComment = line.getOptionValue(GravitinoOptions.COMMENT);
- newUpdateCatalogComment(url, ignore, metalake, catalog,
updateComment).handle();
+ newUpdateCatalogComment(url, ignore, metalake, catalog,
updateComment)
+ .validate()
+ .handle();
}
if (line.hasOption(GravitinoOptions.RENAME)) {
String newName = line.getOptionValue(GravitinoOptions.RENAME);
- newUpdateCatalogName(url, ignore, metalake, catalog,
newName).handle();
+ newUpdateCatalogName(url, ignore, metalake, catalog,
newName).validate().handle();
}
break;
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/Command.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/Command.java
index d881a1dbcd..98c4096cb0 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/Command.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/Command.java
@@ -111,6 +111,18 @@ public abstract class Command {
return this;
}
+ /**
+ * Validates that both property and value parameters are not null.
+ *
+ * @param property The property name to check
+ * @param value The value associated with the property
+ */
+ protected void checkProperty(String property, String value) {
+ if (property == null && value == null)
exitWithError(ErrorMessages.MISSING_PROPERTY_AND_VALUE);
+ if (property == null) exitWithError(ErrorMessages.MISSING_PROPERTY);
+ if (value == null) exitWithError(ErrorMessages.MISSING_VALUE);
+ }
+
/**
* Builds a {@link GravitinoClient} instance with the provided server URL
and metalake.
*
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateCatalog.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateCatalog.java
index e0c11c1e04..2870dd7103 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateCatalog.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateCatalog.java
@@ -81,4 +81,10 @@ public class CreateCatalog extends Command {
System.out.println(catalog + " catalog created");
}
+
+ @Override
+ public Command validate() {
+ if (provider == null) exitWithError(ErrorMessages.MISSING_PROVIDER);
+ return super.validate();
+ }
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RemoveCatalogProperty.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RemoveCatalogProperty.java
index a460d91b2f..c777ba1628 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RemoveCatalogProperty.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RemoveCatalogProperty.java
@@ -66,4 +66,10 @@ public class RemoveCatalogProperty extends Command {
System.out.println(property + " property removed.");
}
+
+ @Override
+ public Command validate() {
+ if (property == null) exitWithError(ErrorMessages.MISSING_PROPERTY);
+ return super.validate();
+ }
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetCatalogProperty.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetCatalogProperty.java
index 21b1a6f1c9..8b511d7458 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetCatalogProperty.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetCatalogProperty.java
@@ -74,4 +74,10 @@ public class SetCatalogProperty extends Command {
System.out.println(catalog + " property set.");
}
+
+ @Override
+ public Command validate() {
+ checkProperty(property, value);
+ return this;
+ }
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetMetalakeProperty.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetMetalakeProperty.java
index 71e5b55898..ff945cf742 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetMetalakeProperty.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetMetalakeProperty.java
@@ -66,9 +66,7 @@ public class SetMetalakeProperty extends Command {
@Override
public Command validate() {
- if (property == null && value == null) exitWithError("Missing --property
and --value options.");
- if (property == null) exitWithError(ErrorMessages.MISSING_PROPERTY);
- if (value == null) exitWithError(ErrorMessages.MISSING_VALUE);
+ checkProperty(property, value);
return this;
}
}
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 bd8f30b5ad..04c0dacc13 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
@@ -112,6 +112,7 @@ class TestCatalogCommands {
.when(commandLine)
.newCatalogDetails(
GravitinoCommandLine.DEFAULT_URL, false, null, "metalake_demo",
"catalog");
+ doReturn(mockDetails).when(mockDetails).validate();
commandLine.handleCommandLine();
verify(mockDetails).handle();
}
@@ -131,6 +132,7 @@ class TestCatalogCommands {
doReturn(mockAudit)
.when(commandLine)
.newCatalogAudit(GravitinoCommandLine.DEFAULT_URL, false,
"metalake_demo", "catalog");
+ doReturn(mockAudit).when(mockAudit).validate();
commandLine.handleCommandLine();
verify(mockAudit).handle();
}
@@ -167,10 +169,30 @@ class TestCatalogCommands {
"postgres",
"comment",
map);
+ doReturn(mockCreate).when(mockCreate).validate();
commandLine.handleCommandLine();
verify(mockCreate).handle();
}
+ @Test
+ void testCreateCatalogCommandWithoutProvider() {
+ Main.useExit = false;
+ CreateCatalog mockCreateCatalog =
+ spy(
+ new CreateCatalog(
+ GravitinoCommandLine.DEFAULT_URL,
+ false,
+ "metalake_demo",
+ "catalog",
+ null,
+ "comment",
+ null));
+
+ assertThrows(RuntimeException.class, mockCreateCatalog::validate);
+ String errOutput = new String(errContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ assertEquals(ErrorMessages.MISSING_PROVIDER, errOutput);
+ }
+
@Test
void testDeleteCatalogCommand() {
DeleteCatalog mockDelete = mock(DeleteCatalog.class);
@@ -186,6 +208,7 @@ class TestCatalogCommands {
.when(commandLine)
.newDeleteCatalog(
GravitinoCommandLine.DEFAULT_URL, false, false, "metalake_demo",
"catalog");
+ doReturn(mockDelete).when(mockDelete).validate();
commandLine.handleCommandLine();
verify(mockDelete).handle();
}
@@ -206,6 +229,7 @@ class TestCatalogCommands {
.when(commandLine)
.newDeleteCatalog(
GravitinoCommandLine.DEFAULT_URL, false, true, "metalake_demo",
"catalog");
+ doReturn(mockDelete).when(mockDelete).validate();
commandLine.handleCommandLine();
verify(mockDelete).handle();
}
@@ -234,10 +258,60 @@ class TestCatalogCommands {
"catalog",
"property",
"value");
+ doReturn(mockSetProperty).when(mockSetProperty).validate();
commandLine.handleCommandLine();
verify(mockSetProperty).handle();
}
+ @Test
+ void testSetCatalogPropertyCommandWithoutPropertyAndValue() {
+ Main.useExit = false;
+ SetCatalogProperty mockSetProperty =
+ spy(
+ new SetCatalogProperty(
+ GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", null, null));
+
+ assertThrows(RuntimeException.class, mockSetProperty::validate);
+ String errOutput = new String(errContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ assertEquals("Missing --property and --value options.", errOutput);
+ }
+
+ @Test
+ void testSetCatalogPropertyCommandWithoutProperty() {
+ Main.useExit = false;
+ SetCatalogProperty mockSetProperty =
+ spy(
+ new SetCatalogProperty(
+ GravitinoCommandLine.DEFAULT_URL,
+ false,
+ "metalake_demo",
+ "catalog",
+ null,
+ "value"));
+
+ assertThrows(RuntimeException.class, mockSetProperty::validate);
+ String errOutput = new String(errContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ assertEquals(ErrorMessages.MISSING_PROPERTY, errOutput);
+ }
+
+ @Test
+ void testSetCatalogPropertyCommandWithoutValue() {
+ Main.useExit = false;
+ SetCatalogProperty mockSetProperty =
+ spy(
+ new SetCatalogProperty(
+ GravitinoCommandLine.DEFAULT_URL,
+ false,
+ "metalake_demo",
+ "catalog",
+ "property",
+ null));
+
+ assertThrows(RuntimeException.class, mockSetProperty::validate);
+ String errOutput = new String(errContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ assertEquals(ErrorMessages.MISSING_VALUE, errOutput);
+ }
+
@Test
void testRemoveCatalogPropertyCommand() {
RemoveCatalogProperty mockRemoveProperty =
mock(RemoveCatalogProperty.class);
@@ -255,10 +329,24 @@ class TestCatalogCommands {
.when(commandLine)
.newRemoveCatalogProperty(
GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", "property");
+ doReturn(mockRemoveProperty).when(mockRemoveProperty).validate();
commandLine.handleCommandLine();
verify(mockRemoveProperty).handle();
}
+ @Test
+ void testRemoveCatalogPropertyCommandWithoutProperty() {
+ Main.useExit = false;
+ RemoveCatalogProperty mockRemoveProperty =
+ spy(
+ new RemoveCatalogProperty(
+ GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", null));
+
+ assertThrows(RuntimeException.class, mockRemoveProperty::validate);
+ String errOutput = new String(errContent.toByteArray(),
StandardCharsets.UTF_8).trim();
+ assertEquals(ErrorMessages.MISSING_PROPERTY, errOutput);
+ }
+
@Test
void testListCatalogPropertiesCommand() {
ListCatalogProperties mockListProperties =
mock(ListCatalogProperties.class);
@@ -274,6 +362,7 @@ class TestCatalogCommands {
.when(commandLine)
.newListCatalogProperties(
GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog");
+ doReturn(mockListProperties).when(mockListProperties).validate();
commandLine.handleCommandLine();
verify(mockListProperties).handle();
}
@@ -295,6 +384,7 @@ class TestCatalogCommands {
.when(commandLine)
.newUpdateCatalogComment(
GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", "new comment");
+ doReturn(mockUpdateComment).when(mockUpdateComment).validate();
commandLine.handleCommandLine();
verify(mockUpdateComment).handle();
}
@@ -317,6 +407,7 @@ class TestCatalogCommands {
.when(commandLine)
.newUpdateCatalogName(
GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", "new_name");
+ doReturn(mockUpdateName).when(mockUpdateName).validate();
commandLine.handleCommandLine();
verify(mockUpdateName).handle();
}
@@ -368,6 +459,7 @@ class TestCatalogCommands {
.when(commandLine)
.newCatalogEnable(
GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", false);
+ doReturn(mockEnable).when(mockEnable).validate();
commandLine.handleCommandLine();
verify(mockEnable).handle();
}
@@ -390,6 +482,7 @@ class TestCatalogCommands {
.when(commandLine)
.newCatalogEnable(
GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"catalog", true);
+ doReturn(mockEnable).when(mockEnable).validate();
commandLine.handleCommandLine();
verify(mockEnable).handle();
}
@@ -410,6 +503,7 @@ class TestCatalogCommands {
doReturn(mockDisable)
.when(commandLine)
.newCatalogDisable(GravitinoCommandLine.DEFAULT_URL, false,
"metalake_demo", "catalog");
+ doReturn(mockDisable).when(mockDisable).validate();
commandLine.handleCommandLine();
verify(mockDisable).handle();
}