This is an automated email from the ASF dual-hosted git repository.
shaofengshi 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 3a21ce46c [#5061] Basic user and group CLI (#5133)
3a21ce46c is described below
commit 3a21ce46c1bca1b741db65abada371a98ee1a5e5
Author: Justin Mclean <[email protected]>
AuthorDate: Fri Nov 8 13:38:01 2024 +1100
[#5061] Basic user and group CLI (#5133)
### What changes were proposed in this pull request?
Added basic user and group commands.
### Why are the changes needed?
For the CLI to support users and groups.
Fix: #5061
### Does this PR introduce _any_ user-facing change?
No, but extends CLI support.
### How was this patch tested?
Tested locally.
---
.../org/apache/gravitino/cli/CommandEntities.java | 4 +
.../org/apache/gravitino/cli/ErrorMessages.java | 4 +
.../apache/gravitino/cli/GravitinoCommandLine.java | 50 ++++++++++++-
.../org/apache/gravitino/cli/GravitinoOptions.java | 9 ++-
.../java/org/apache/gravitino/cli/Properties.java | 20 ++---
.../{MetalakeAuditInfo.java => CreateGroup.java} | 37 ++++------
.../{MetalakeAuditInfo.java => CreateUser.java} | 37 ++++------
.../{MetalakeAuditInfo.java => DeleteGroup.java} | 44 +++++------
.../{MetalakeAuditInfo.java => DeleteUser.java} | 44 +++++------
.../{MetalakeAuditInfo.java => GroupDetails.java} | 41 ++++++-----
.../{MetalakeAuditInfo.java => ListGroups.java} | 33 ++++-----
.../{MetalakeAuditInfo.java => ListUsers.java} | 33 ++++-----
.../gravitino/cli/commands/MetalakeAuditInfo.java | 1 +
.../{MetalakeAuditInfo.java => UserDetails.java} | 41 ++++++-----
.../org/apache/gravitino/cli/PropertiesTest.java | 86 ++++++++++++++++++++--
.../apache/gravitino/cli/TestCommandEntities.java | 2 -
docs/cli.md | 76 +++++++++++++++++--
17 files changed, 370 insertions(+), 192 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 66e679304..a7703b157 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
@@ -31,6 +31,8 @@ public class CommandEntities {
public static final String SCHEMA = "schema";
public static final String TABLE = "table";
public static final String COLUMN = "column";
+ public static final String USER = "user";
+ public static final String GROUP = "group";
private static final HashSet<String> VALID_ENTITIES = new HashSet<>();
@@ -40,6 +42,8 @@ public class CommandEntities {
VALID_ENTITIES.add(SCHEMA);
VALID_ENTITIES.add(TABLE);
VALID_ENTITIES.add(COLUMN);
+ VALID_ENTITIES.add(USER);
+ VALID_ENTITIES.add(GROUP);
}
/**
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 0e7816ae4..c3da72ce8 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
@@ -33,4 +33,8 @@ public class ErrorMessages {
public static final String METALAKE_EXISTS = "Metalake already exists.";
public static final String CATALOG_EXISTS = "Catalog already exists.";
public static final String SCHEMA_EXISTS = "Schema already exists.";
+ public static final String UNKNOWN_USER = "Unknown user.";
+ public static final String USER_EXISTS = "User already exists.";
+ public static final String UNKNOWN_GROUP = "Unknown group.";
+ public static final String GROUP_EXISTS = "Group already exists.";
}
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 356956387..566ff88e9 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
@@ -26,20 +26,27 @@ import org.apache.commons.cli.Options;
import org.apache.gravitino.cli.commands.CatalogDetails;
import org.apache.gravitino.cli.commands.ClientVersion;
import org.apache.gravitino.cli.commands.CreateCatalog;
+import org.apache.gravitino.cli.commands.CreateGroup;
import org.apache.gravitino.cli.commands.CreateMetalake;
import org.apache.gravitino.cli.commands.CreateSchema;
+import org.apache.gravitino.cli.commands.CreateUser;
import org.apache.gravitino.cli.commands.DeleteCatalog;
+import org.apache.gravitino.cli.commands.DeleteGroup;
import org.apache.gravitino.cli.commands.DeleteMetalake;
import org.apache.gravitino.cli.commands.DeleteSchema;
import org.apache.gravitino.cli.commands.DeleteTable;
+import org.apache.gravitino.cli.commands.DeleteUser;
+import org.apache.gravitino.cli.commands.GroupDetails;
import org.apache.gravitino.cli.commands.ListCatalogProperties;
import org.apache.gravitino.cli.commands.ListCatalogs;
import org.apache.gravitino.cli.commands.ListColumns;
+import org.apache.gravitino.cli.commands.ListGroups;
import org.apache.gravitino.cli.commands.ListMetalakeProperties;
import org.apache.gravitino.cli.commands.ListMetalakes;
import org.apache.gravitino.cli.commands.ListSchema;
import org.apache.gravitino.cli.commands.ListSchemaProperties;
import org.apache.gravitino.cli.commands.ListTables;
+import org.apache.gravitino.cli.commands.ListUsers;
import org.apache.gravitino.cli.commands.MetalakeAuditInfo;
import org.apache.gravitino.cli.commands.MetalakeDetails;
import org.apache.gravitino.cli.commands.RemoveCatalogProperty;
@@ -55,6 +62,7 @@ import org.apache.gravitino.cli.commands.UpdateCatalogComment;
import org.apache.gravitino.cli.commands.UpdateCatalogName;
import org.apache.gravitino.cli.commands.UpdateMetalakeComment;
import org.apache.gravitino.cli.commands.UpdateMetalakeName;
+import org.apache.gravitino.cli.commands.UserDetails;
/* Gravitino Command line */
public class GravitinoCommandLine {
@@ -152,6 +160,10 @@ public class GravitinoCommandLine {
handleCatalogCommand();
} else if (entity.equals(CommandEntities.METALAKE)) {
handleMetalakeCommand();
+ } else if (entity.equals(CommandEntities.USER)) {
+ handleUserCommand();
+ } else if (entity.equals(CommandEntities.GROUP)) {
+ handleGroupCommand();
}
}
@@ -217,7 +229,7 @@ public class GravitinoCommandLine {
} else if (CommandActions.CREATE.equals(command)) {
String comment = line.getOptionValue(GravitinoOptions.COMMENT);
String provider = line.getOptionValue(GravitinoOptions.PROVIDER);
- String properties = line.getOptionValue(GravitinoOptions.PROPERTIES);
+ String[] properties = line.getOptionValues(GravitinoOptions.PROPERTIES);
Map<String, String> propertyMap = new Properties().parse(properties);
new CreateCatalog(url, ignore, metalake, catalog, provider, comment,
propertyMap).handle();
} else if (CommandActions.DELETE.equals(command)) {
@@ -304,6 +316,42 @@ public class GravitinoCommandLine {
}
}
+ /** Handles the command execution for Users based on command type and the
command line options. */
+ protected void handleUserCommand() {
+ String url = getUrl();
+ FullName name = new FullName(line);
+ String metalake = name.getMetalakeName();
+ String user = line.getOptionValue(GravitinoOptions.USER);
+
+ if (CommandActions.DETAILS.equals(command)) {
+ new UserDetails(url, ignore, metalake, user).handle();
+ } else if (CommandActions.LIST.equals(command)) {
+ new ListUsers(url, ignore, metalake).handle();
+ } else if (CommandActions.CREATE.equals(command)) {
+ new CreateUser(url, ignore, metalake, user).handle();
+ } else if (CommandActions.DELETE.equals(command)) {
+ new DeleteUser(url, ignore, metalake, user).handle();
+ }
+ }
+
+ /** Handles the command execution for Group based on command type and the
command line options. */
+ protected void handleGroupCommand() {
+ String url = getUrl();
+ FullName name = new FullName(line);
+ String metalake = name.getMetalakeName();
+ String group = line.getOptionValue(GravitinoOptions.GROUP);
+
+ if (CommandActions.DETAILS.equals(command)) {
+ new GroupDetails(url, ignore, metalake, group).handle();
+ } else if (CommandActions.LIST.equals(command)) {
+ new ListGroups(url, ignore, metalake).handle();
+ } else if (CommandActions.CREATE.equals(command)) {
+ new CreateGroup(url, ignore, metalake, group).handle();
+ } else if (CommandActions.DELETE.equals(command)) {
+ new DeleteGroup(url, ignore, metalake, group).handle();
+ }
+ }
+
/**
* Handles the command execution for Columns based on command type and the
command line options.
*/
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
index 53b9fa2eb..d9ccbb4ad 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
@@ -37,6 +37,8 @@ public class GravitinoOptions {
public static final String VALUE = "value";
public static final String PROVIDER = "provider";
public static final String PROPERTIES = "properties";
+ public static final String USER = "user";
+ public static final String GROUP = "group";
public static final String AUDIT = "audit";
/**
@@ -64,12 +66,13 @@ public class GravitinoOptions {
options.addOption(createArgOption("V", VALUE, "property value"));
options.addOption(
createArgOption(
- "g", PROVIDER, "provider one of hadoop, hive, mysql, postgres,
iceberg, kafka"));
+ "t", PROVIDER, "provider one of hadoop, hive, mysql, postgres,
iceberg, kafka"));
+ options.addOption(createArgOption("l", USER, "user name"));
+ options.addOption(createArgOption("g", GROUP, "group name"));
// Properties option can have multiple values
Option properties =
- createArgOption("p", PROPERTIES, "comma separated property name/value
pairs");
- properties.hasArgs();
+ Option.builder("p").longOpt(PROPERTIES).desc("property name/value
pairs").hasArgs().build();
options.addOption(properties);
return options;
diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/Properties.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/Properties.java
index f9985f235..1c166102f 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/Properties.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/Properties.java
@@ -55,19 +55,21 @@ public class Properties {
* <p>Each pair in the input string is split by the specified delimiter, and
then each pair is
* further split by the key-value separator.
*
- * @param input The input string containing name-value pairs.
+ * @param inputs An arrays of input strings containing name-value pairs.
* @return A map of entries, where each entry represents a key-value pair
from the input string.
*/
- public Map<String, String> parse(String input) {
+ public Map<String, String> parse(String[] inputs) {
HashMap<String, String> map = new HashMap<>();
- // Split the input by the delimiter into key-value pairs
- String[] pairs = input.split(delimiter);
- for (String pair : pairs) {
- // Split each key-value pair by the separator
- String[] keyValue = pair.split(keyValueSeparator, 2);
- if (keyValue.length == 2) {
- map.put(keyValue[0].trim(), keyValue[1].trim());
+ for (String input : inputs) {
+ // Split the input by the delimiter into key-value pairs
+ String[] pairs = input.split(delimiter);
+ for (String pair : pairs) {
+ // Split each key-value pair by the separator
+ String[] keyValue = pair.split(keyValueSeparator, 2);
+ if (keyValue.length == 2) {
+ map.put(keyValue[0].trim(), keyValue[1].trim());
+ }
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateGroup.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateGroup.java
index 6c1d49a20..8f9fa985d 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateGroup.java
@@ -19,51 +19,46 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.GroupAlreadyExistsException;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
+public class CreateGroup extends Command {
protected final String metalake;
+ protected final String group;
/**
- * Displays metalake audit information.
+ * Create a new group.
*
* @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 group The name of the group.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public CreateGroup(String url, boolean ignoreVersions, String metalake,
String group) {
super(url, ignoreVersions);
this.metalake = metalake;
+ this.group = group;
}
- /** Displays the audit information of a metalake. */
+ /** Create a new group. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ try {
+ GravitinoClient client = buildClient(metalake);
+ client.addGroup(group);
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
+ } catch (GroupAlreadyExistsException err) {
+ System.err.println(ErrorMessages.GROUP_EXISTS);
+ return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
-
- System.out.println(auditInfo);
+ System.out.println(group + " created");
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateUser.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateUser.java
index 6c1d49a20..150bf64ce 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateUser.java
@@ -19,51 +19,46 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.UserAlreadyExistsException;
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
+public class CreateUser extends Command {
protected final String metalake;
+ protected final String user;
/**
- * Displays metalake audit information.
+ * Create a new User.
*
* @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 user The name of the user.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public CreateUser(String url, boolean ignoreVersions, String metalake,
String user) {
super(url, ignoreVersions);
this.metalake = metalake;
+ this.user = user;
}
- /** Displays the audit information of a metalake. */
+ /** Create a new user. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ try {
+ GravitinoClient client = buildClient(metalake);
+ client.addUser(user);
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
+ } catch (UserAlreadyExistsException err) {
+ System.err.println(ErrorMessages.USER_EXISTS);
+ return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
-
- System.out.println(auditInfo);
+ System.out.println(user + " created");
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteGroup.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteGroup.java
index 6c1d49a20..e13713752 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteGroup.java
@@ -19,51 +19,53 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchGroupException;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
+public class DeleteGroup extends Command {
+
protected final String metalake;
+ protected final String group;
/**
- * Displays metalake audit information.
+ * Delete a group.
*
* @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 group The name of the group.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public DeleteGroup(String url, boolean ignoreVersions, String metalake,
String group) {
super(url, ignoreVersions);
this.metalake = metalake;
+ this.group = group;
}
- /** Displays the audit information of a metalake. */
+ /** Delete a group. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ boolean deleted = false;
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ deleted = client.removeGroup(group);
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
+ } catch (NoSuchGroupException err) {
+ System.err.println(ErrorMessages.UNKNOWN_GROUP);
+ return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
-
- System.out.println(auditInfo);
+ if (deleted) {
+ System.out.println(group + " deleted.");
+ } else {
+ System.out.println(group + " not deleted.");
+ }
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteUser.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteUser.java
index 6c1d49a20..ae43866a1 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteUser.java
@@ -19,51 +19,53 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchUserException;
+
+public class DeleteUser extends Command {
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
protected final String metalake;
+ protected final String user;
/**
- * Displays metalake audit information.
+ * Deletes a user.
*
* @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 user The name of the user.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public DeleteUser(String url, boolean ignoreVersions, String metalake,
String user) {
super(url, ignoreVersions);
this.metalake = metalake;
+ this.user = user;
}
- /** Displays the audit information of a metalake. */
+ /** Delete a user. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ boolean deleted = false;
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ deleted = client.removeUser(user);
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
+ } catch (NoSuchUserException err) {
+ System.err.println(ErrorMessages.UNKNOWN_USER);
+ return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
-
- System.out.println(auditInfo);
+ if (deleted) {
+ System.out.println(user + " deleted.");
+ } else {
+ System.out.println(user + " not deleted.");
+ }
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/GroupDetails.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/GroupDetails.java
index 6c1d49a20..d21806ef2 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/GroupDetails.java
@@ -19,51 +19,52 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
+import java.util.List;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchUserException;
+
+public class GroupDetails extends Command {
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
protected final String metalake;
+ protected final String group;
/**
- * Displays metalake audit information.
+ * Displays the roles in a group.
*
* @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 group The name of the group.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public GroupDetails(String url, boolean ignoreVersions, String metalake,
String group) {
super(url, ignoreVersions);
this.metalake = metalake;
+ this.group = group;
}
- /** Displays the audit information of a metalake. */
+ /** Displays the roles of a specified group. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ List<String> roles = null;
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ roles = client.getGroup(group).roles();
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
+ } catch (NoSuchUserException err) {
+ System.err.println(ErrorMessages.UNKNOWN_GROUP);
+ return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
+ String all = String.join(",", roles);
- System.out.println(auditInfo);
+ System.out.println(all.toString());
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListGroups.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListGroups.java
index 6c1d49a20..d529b5147 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListGroups.java
@@ -19,32 +19,34 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
+/* Lists all groups in a metalake. */
+public class ListGroups extends Command {
+
protected final String metalake;
/**
- * Displays metalake audit information.
+ * Lists all groups in a metalake.
*
* @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.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public ListGroups(String url, boolean ignoreVersions, String metalake) {
super(url, ignoreVersions);
this.metalake = metalake;
}
- /** Displays the audit information of a metalake. */
+ /** Lists all groups in a metalake. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ String[] groups = new String[0];
+ try {
+ GravitinoClient client = buildClient(metalake);
+ groups = client.listGroupNames();
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
@@ -53,17 +55,8 @@ public class MetalakeAuditInfo extends Command {
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
+ String all = String.join(",", groups);
- System.out.println(auditInfo);
+ System.out.println(all.toString());
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListUsers.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListUsers.java
index 6c1d49a20..465075a97 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListUsers.java
@@ -19,32 +19,34 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
+/* Lists all users in a metalake. */
+public class ListUsers extends Command {
+
protected final String metalake;
/**
- * Displays metalake audit information.
+ * Lists all users in a metalake.
*
* @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.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public ListUsers(String url, boolean ignoreVersions, String metalake) {
super(url, ignoreVersions);
this.metalake = metalake;
}
- /** Displays the audit information of a metalake. */
+ /** Lists all users in a metalake. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ String[] users = new String[0];
+ try {
+ GravitinoClient client = buildClient(metalake);
+ users = client.listUserNames();
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
@@ -53,17 +55,8 @@ public class MetalakeAuditInfo extends Command {
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
+ String all = String.join(",", users);
- System.out.println(auditInfo);
+ System.out.println(all.toString());
}
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
index 6c1d49a20..de3807839 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
@@ -41,6 +41,7 @@ public class MetalakeAuditInfo extends Command {
}
/** Displays the audit information of a metalake. */
+ @Override
public void handle() {
Audit audit;
try (GravitinoClient client = buildClient(metalake)) {
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UserDetails.java
similarity index 66%
copy from
clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
copy to
clients/cli/src/main/java/org/apache/gravitino/cli/commands/UserDetails.java
index 6c1d49a20..43ebb65e8 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/MetalakeAuditInfo.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/UserDetails.java
@@ -19,51 +19,52 @@
package org.apache.gravitino.cli.commands;
-import org.apache.gravitino.Audit;
+import java.util.List;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchUserException;
+
+public class UserDetails extends Command {
-/** Displays the audit information of a metalake. */
-public class MetalakeAuditInfo extends Command {
protected final String metalake;
+ protected final String user;
/**
- * Displays metalake audit information.
+ * Displays the roles of a user.
*
* @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 user The name of the user.
*/
- public MetalakeAuditInfo(String url, boolean ignoreVersions, String
metalake) {
+ public UserDetails(String url, boolean ignoreVersions, String metalake,
String user) {
super(url, ignoreVersions);
this.metalake = metalake;
+ this.user = user;
}
- /** Displays the audit information of a metalake. */
+ /** Displays the roles of a specified user. */
+ @Override
public void handle() {
- Audit audit;
- try (GravitinoClient client = buildClient(metalake)) {
- audit = client.loadMetalake(metalake).auditInfo();
+ List<String> roles = null;
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ roles = client.getUser(user).roles();
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
+ } catch (NoSuchUserException err) {
+ System.err.println(ErrorMessages.UNKNOWN_USER);
+ return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
- String auditInfo =
- "creator,createTime,lastModifier,lastModifiedTime"
- + System.lineSeparator()
- + audit.creator()
- + ","
- + audit.createTime()
- + ","
- + audit.lastModifier()
- + ","
- + audit.lastModifiedTime();
+ String all = String.join(",", roles);
- System.out.println(auditInfo);
+ System.out.println(all.toString());
}
}
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/PropertiesTest.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/PropertiesTest.java
index cdf08a59d..17af8c21a 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/PropertiesTest.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/PropertiesTest.java
@@ -30,7 +30,20 @@ public class PropertiesTest {
@Test
public void testDefaultDelimiterAndSeparator() {
Properties properties = new Properties();
- String input = "key1=value1,key2=value2,key3=value3";
+ String[] input = {"key1=value1,key2=value2,key3=value3"};
+
+ Map<String, String> result = properties.parse(input);
+
+ assertEquals(3, result.size());
+ assertEquals("value1", result.get("key1"));
+ assertEquals("value2", result.get("key2"));
+ assertEquals("value3", result.get("key3"));
+ }
+
+ @Test
+ public void testDefaultDelimiterAndSeparatorArray() {
+ Properties properties = new Properties();
+ String[] input = {"key1=value1", "key2=value2", "key3=value3"};
Map<String, String> result = properties.parse(input);
@@ -43,7 +56,20 @@ public class PropertiesTest {
@Test
public void testCustomDelimiterAndSeparator() {
Properties properties = new Properties(";", ":");
- String input = "key1:value1;key2:value2;key3:value3";
+ String[] input = {"key1:value1;key2:value2;key3:value3"};
+
+ Map<String, String> result = properties.parse(input);
+
+ assertEquals(3, result.size());
+ assertEquals("value1", result.get("key1"));
+ assertEquals("value2", result.get("key2"));
+ assertEquals("value3", result.get("key3"));
+ }
+
+ @Test
+ public void testCustomDelimiterAndSeparatorArray() {
+ Properties properties = new Properties(";", ":");
+ String[] input = {"key1:value1;key2:value2", "key3:value3"};
Map<String, String> result = properties.parse(input);
@@ -56,17 +82,27 @@ public class PropertiesTest {
@Test
public void testEmptyInput() {
Properties properties = new Properties();
- String input = "";
+ String input[] = {""};
Map<String, String> result = properties.parse(input);
assertTrue(result.isEmpty(), "Result should be empty for empty input");
}
+ @Test
+ public void testEmptyArray() {
+ Properties properties = new Properties();
+ String input[] = {};
+
+ Map<String, String> result = properties.parse(input);
+
+ assertTrue(result.isEmpty(), "Result should be empty for empty array");
+ }
+
@Test
public void testSinglePair() {
Properties properties = new Properties();
- String input = "key1=value1";
+ String[] input = {"key1=value1"};
Map<String, String> result = properties.parse(input);
@@ -77,7 +113,19 @@ public class PropertiesTest {
@Test
public void testMalformedPair() {
Properties properties = new Properties();
- String input = "key1=value1,key2,key3=value3";
+ String[] input = {"key1=value1,key2,key3=value3"};
+
+ Map<String, String> result = properties.parse(input);
+
+ assertEquals(2, result.size());
+ assertEquals("value1", result.get("key1"));
+ assertEquals("value3", result.get("key3"));
+ }
+
+ @Test
+ public void testMalformedPairArray() {
+ Properties properties = new Properties();
+ String[] input = {"key1=value1", "key2", "key3=value3"};
Map<String, String> result = properties.parse(input);
@@ -89,7 +137,19 @@ public class PropertiesTest {
@Test
public void testWhitespaceHandling() {
Properties properties = new Properties();
- String input = " key1 = value1 , key2 = value2 ";
+ String[] input = {" key1 = value1 , key2 = value2 "};
+
+ Map<String, String> result = properties.parse(input);
+
+ assertEquals(2, result.size());
+ assertEquals("value1", result.get("key1"));
+ assertEquals("value2", result.get("key2"));
+ }
+
+ @Test
+ public void testWhitespaceHandlingArray() {
+ Properties properties = new Properties();
+ String[] input = {" key1 = value1 ", " key2 = value2 "};
Map<String, String> result = properties.parse(input);
@@ -101,7 +161,19 @@ public class PropertiesTest {
@Test
public void testDuplicateKeys() {
Properties properties = new Properties();
- String input = "key1=value1,key1=value2,key2=value3";
+ String[] input = {"key1=value1,key1=value2,key2=value3"};
+
+ Map<String, String> result = properties.parse(input);
+
+ assertEquals(2, result.size());
+ assertEquals("value2", result.get("key1"), "Last value should overwrite
previous ones");
+ assertEquals("value3", result.get("key2"));
+ }
+
+ @Test
+ public void testDuplicateKeysArray() {
+ Properties properties = new Properties();
+ String[] input = {"key1=value1", "key1=value2", "key2=value3"};
Map<String, String> result = properties.parse(input);
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
index 49ee9770b..2ca43d060 100644
---
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
+++
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
@@ -37,8 +37,6 @@ public class TestCommandEntities {
CommandEntities.isValidEntity(CommandEntities.SCHEMA), "SCHEMA should
be a valid entity");
assertTrue(
CommandEntities.isValidEntity(CommandEntities.TABLE), "TABLE should be
a valid entity");
- assertTrue(
- CommandEntities.isValidEntity(CommandEntities.COLUMN), "COLUMN should
be a valid entity");
}
@Test
diff --git a/docs/cli.md b/docs/cli.md
index 589129815..d54ba2c33 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -30,16 +30,18 @@ The general structure for running commands with the
Gravitino CLI is `gcli entit
usage: gcli [metalake|catalog|schema|table|column]
[list|details|create|delete|update|set|remove|properties] [options]
Options
-c,--comment <arg> entity comment
- -g,--provider <arg> provider one of hadoop, hive, mysql, postgres,
- iceberg, kafka
+ -g,--group <arg> group name
-h,--help command help information
-i,--ignore Ignore client/sever version check
+ -l,--user <arg> user name
-m,--metalake <arg> Metalake name
-n,--name <arg> full entity name (dot separated)
-P,--property <arg> property name
- -p,--properties <arg> comma separated property name/value pairs
+ -p,--properties <arg> property name/value pairs
-r,--rename <arg> new entity name
-s,--server Gravitino server version
+ -t,--provider <arg> provider one of hadoop, hive, mysql, postgres,
+ iceberg, kafka
-u,--url <arg> Gravitino URL (default: http://localhost:8090)
-v,--version Gravitino client version
-V,--value <arg> property value
@@ -134,6 +136,16 @@ If the client and server are running different versions of
the Gravitino softwar
2. Set via the `GRAVITINO_IGNORE` environment variable.
3. Stored in the Gravitino CLI configuration file.
+### Multiple properties
+
+For commands that accept multiple properties they can be specified in a couple
of different ways:
+
+1. gcli --properties n1=v1,n2=v2,n3=v3
+
+2. gcli --properties n1=v1 n2=v2 n3=v3
+
+3. gcli --properties n1=v1 --properties n2=v2 --properties n3=v3
+
### Metalake commands
#### Show all metalakes
@@ -190,7 +202,7 @@ gcli metalake set --metalake metalake_demo --property test
--value value
gcli metalake remove --metalake metalake_demo --property test
```
-### Catalog
+### Catalog commands
#### Show all catalogs in a metalake
@@ -274,7 +286,7 @@ gcli catalog set --metalake metalake_demo --name
catalog_mysql --property test -
gcli catalog remove --metalake metalake_demo --name catalog_mysql --property
test
```
-### Schema
+### Schema commands
#### Show all schemas in a catalog
@@ -302,7 +314,7 @@ gcli schema properties --metalake metalake_demo --name
catalog_postgres.hr -i
Setting and removing schema properties is not currently supported by the Java
API or the Gravitino CLI.
-### Table
+### Table commands
#### Show all tables
@@ -321,3 +333,55 @@ gcli column list --metalake metalake_demo --name
catalog_postgres.hr.departments
```bash
gcli table delete --metalake metalake_demo --name catalog_postgres.hr.salaries
```
+
+### User commands
+
+#### Create a user
+
+```bash
+gcli user create --metalake metalake_demo --user new_user
+```
+
+#### Show a user's details
+
+```bash
+gcli user details --metalake metalake_demo --user new_user
+```
+
+#### List all users
+
+```bash
+gcli user list --metalake metalake_demo
+```
+
+#### Delete a user
+
+```bash
+gcli user delete --metalake metalake_demo --user new_user
+```
+
+### Group commands
+
+#### Create a group
+
+```bash
+gcli group create --metalake metalake_demo --group new_group
+```
+
+#### Display a group's details
+
+```bash
+gcli group details --metalake metalake_demo --group new_group
+```
+
+#### List all groups
+
+```bash
+gcli group list --metalake metalake_demo
+```
+
+#### Delete a group
+
+```bash
+gcli group delete --metalake metalake_demo --group new_group
+```