Skip to content

Commit

Permalink
[apache#5528]Improvement[cli] Add and delete multiple tags at once in…
Browse files Browse the repository at this point in the history
… the Gravitino CLI (apache#5641)

### What changes were proposed in this pull request?

Add and delete multiple tags at once in the Gravitino CLI 

### Why are the changes needed?

Close: [(apache#5528)](apache#5528)
  • Loading branch information
sunxiaojian authored Nov 25, 2024
1 parent dbeb017 commit e62c6d3
Show file tree
Hide file tree
Showing 10 changed files with 357 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ public class ErrorMessages {
public static final String UNKNOWN_GROUP = "Unknown group.";
public static final String GROUP_EXISTS = "Group already exists.";
public static final String UNKNOWN_TAG = "Unknown tag.";
public static final String MULTIPLE_TAG_COMMAND_ERROR =
"Error: The current command only supports one --tag option.";
public static final String TAG_EXISTS = "Tag already exists.";
public static final String TAG_EMPTY = "Error: Must configure --tag option.";
public static final String UNKNOWN_ROLE = "Unknown role.";
public static final String ROLE_EXISTS = "Role already exists.";
public static final String INVALID_SET_COMMAND =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

package org.apache.gravitino.cli;

import com.google.common.base.Preconditions;
import java.util.Arrays;
import java.util.Map;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
Expand Down Expand Up @@ -366,10 +368,11 @@ protected void handleTagCommand() {
String url = getUrl();
FullName name = new FullName(line);
String metalake = name.getMetalakeName();
String tag = line.getOptionValue(GravitinoOptions.TAG);

String[] tags = line.getOptionValues(GravitinoOptions.TAG);
tags = tags != null ? Arrays.stream(tags).distinct().toArray(String[]::new) : null;
if (CommandActions.DETAILS.equals(command)) {
newTagDetails(url, ignore, metalake, tag).handle();
newTagDetails(url, ignore, metalake, getOneTag(tags)).handle();
} else if (CommandActions.LIST.equals(command)) {
if (!name.hasCatalogName()) {
newListTags(url, ignore, metalake).handle();
Expand All @@ -378,40 +381,44 @@ protected void handleTagCommand() {
}
} else if (CommandActions.CREATE.equals(command)) {
String comment = line.getOptionValue(GravitinoOptions.COMMENT);
newCreateTag(url, ignore, metalake, tag, comment).handle();
newCreateTags(url, ignore, metalake, tags, comment).handle();
} else if (CommandActions.DELETE.equals(command)) {
boolean force = line.hasOption(GravitinoOptions.FORCE);
newDeleteTag(url, ignore, force, metalake, tag).handle();
newDeleteTag(url, ignore, force, metalake, tags).handle();
} else if (CommandActions.SET.equals(command)) {
String property = line.getOptionValue(GravitinoOptions.PROPERTY);
String value = line.getOptionValue(GravitinoOptions.VALUE);

if (property != null && value != null) {
newSetTagProperty(url, ignore, metalake, tag, property, value).handle();
newSetTagProperty(url, ignore, metalake, getOneTag(tags), property, value).handle();
} else if (name != null && property == null && value == null) {
newTagEntity(url, ignore, metalake, name, tag).handle();
newTagEntity(url, ignore, metalake, name, tags).handle();
}
} else if (CommandActions.REMOVE.equals(command)) {
String property = line.getOptionValue(GravitinoOptions.PROPERTY);
if (property != null) {
newRemoveTagProperty(url, ignore, metalake, tag, property).handle();
newRemoveTagProperty(url, ignore, metalake, getOneTag(tags), property).handle();
} else {
newUntagEntity(url, ignore, metalake, name, tag).handle();
newUntagEntity(url, ignore, metalake, name, tags).handle();
}
} else if (CommandActions.PROPERTIES.equals(command)) {
newListTagProperties(url, ignore, metalake, tag).handle();
newListTagProperties(url, ignore, metalake, getOneTag(tags)).handle();
} else if (CommandActions.UPDATE.equals(command)) {
if (line.hasOption(GravitinoOptions.COMMENT)) {
String comment = line.getOptionValue(GravitinoOptions.COMMENT);
newUpdateTagComment(url, ignore, metalake, tag, comment).handle();
newUpdateTagComment(url, ignore, metalake, getOneTag(tags), comment).handle();
}
if (line.hasOption(GravitinoOptions.RENAME)) {
String newName = line.getOptionValue(GravitinoOptions.RENAME);
newUpdateTagName(url, ignore, metalake, tag, newName).handle();
newUpdateTagName(url, ignore, metalake, getOneTag(tags), newName).handle();
}
}
}

private String getOneTag(String[] tags) {
Preconditions.checkArgument(tags.length <= 1, ErrorMessages.MULTIPLE_TAG_COMMAND_ERROR);
return tags[0];
}

/** Handles the command execution for Roles based on command type and the command line options. */
protected void handleRoleCommand() {
String url = getUrl();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public Options options() {
"z", PROVIDER, "provider one of hadoop, hive, mysql, postgres, iceberg, kafka"));
options.addOption(createArgOption("l", USER, "user name"));
options.addOption(createArgOption("g", GROUP, "group name"));
options.addOption(createArgOption("t", TAG, "tag name"));
options.addOption(createArgsOption("t", TAG, "tag name"));
options.addOption(createArgOption("r", ROLE, "role name"));

// Properties option can have multiple values
Expand Down Expand Up @@ -115,4 +115,9 @@ public Option createSimpleOption(String shortName, String longName, String descr
public Option createArgOption(String shortName, String longName, String description) {
return new Option(shortName, longName, true, description);
}

public Option createArgsOption(String shortName, String longName, String description) {
// Support multiple arguments
return Option.builder().option(shortName).longOpt(longName).hasArgs().desc(description).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -370,14 +370,14 @@ protected ListAllTags newListTags(String url, boolean ignore, String metalake) {
return new ListAllTags(url, ignore, metalake);
}

protected CreateTag newCreateTag(
String url, boolean ignore, String metalake, String tag, String comment) {
return new CreateTag(url, ignore, metalake, tag, comment);
protected CreateTag newCreateTags(
String url, boolean ignore, String metalake, String[] tags, String comment) {
return new CreateTag(url, ignore, metalake, tags, comment);
}

protected DeleteTag newDeleteTag(
String url, boolean ignore, boolean force, String metalake, String tag) {
return new DeleteTag(url, ignore, force, metalake, tag);
String url, boolean ignore, boolean force, String metalake, String[] tags) {
return new DeleteTag(url, ignore, force, metalake, tags);
}

protected SetTagProperty newSetTagProperty(
Expand Down Expand Up @@ -411,13 +411,13 @@ protected ListEntityTags newListEntityTags(
}

protected TagEntity newTagEntity(
String url, boolean ignore, String metalake, FullName name, String tag) {
return new TagEntity(url, ignore, metalake, name, tag);
String url, boolean ignore, String metalake, FullName name, String[] tags) {
return new TagEntity(url, ignore, metalake, name, tags);
}

protected UntagEntity newUntagEntity(
String url, boolean ignore, String metalake, FullName name, String tag) {
return new UntagEntity(url, ignore, metalake, name, tag);
String url, boolean ignore, String metalake, FullName name, String[] tags) {
return new UntagEntity(url, ignore, metalake, name, tags);
}

protected ListColumns newListColumns(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,51 @@

package org.apache.gravitino.cli.commands;

import java.util.ArrayList;
import java.util.Arrays;
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.TagAlreadyExistsException;

public class CreateTag extends Command {
protected final String metalake;
protected final String tag;
protected final String[] tags;
protected final String comment;

/**
* Create a new tag.
* Create tags.
*
* @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 tag The name of the tag.
* @param tags The names of the tags.
* @param comment The comment of the tag.
*/
public CreateTag(
String url, boolean ignoreVersions, String metalake, String tag, String comment) {
String url, boolean ignoreVersions, String metalake, String[] tags, String comment) {
super(url, ignoreVersions);
this.metalake = metalake;
this.tag = tag;
this.tags = tags;
this.comment = comment;
}

/** Create a new tag. */
/** Create tags. */
@Override
public void handle() {
boolean hasOnlyOneTag = tags.length == 1;
if (hasOnlyOneTag) {
handleOnlyOneTag();
} else {
handleMultipleTags();
}
}

private void handleOnlyOneTag() {
try {
GravitinoClient client = buildClient(metalake);
client.createTag(tag, comment, null);
client.createTag(tags[0], comment, null);
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
Expand All @@ -63,6 +75,34 @@ public void handle() {
return;
}

System.out.println(tag + " created");
System.out.println(tags[0] + " created");
}

private void handleMultipleTags() {
List<String> created = new ArrayList<>();
try {
GravitinoClient client = buildClient(metalake);
for (String tag : tags) {
client.createTag(tag, comment, null);
created.add(tag);
}
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
} catch (TagAlreadyExistsException err) {
System.err.println(ErrorMessages.TAG_EXISTS);
return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
if (!created.isEmpty()) {
System.out.println("Tags " + String.join(",", created) + " created");
}
if (created.size() < tags.length) {
List<String> remaining = Arrays.asList(tags);
remaining.removeAll(created);
System.out.println("Tags " + String.join(",", remaining) + " not created");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@

package org.apache.gravitino.cli.commands;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.gravitino.cli.AreYouSure;
import org.apache.gravitino.cli.ErrorMessages;
import org.apache.gravitino.client.GravitinoClient;
Expand All @@ -28,28 +31,70 @@
public class DeleteTag extends Command {

protected final String metalake;
protected final String tag;
protected final String[] tags;
protected final boolean force;

/**
* Delete a tag.
* Delete tags.
*
* @param url The URL of the Gravitino server.
* @param ignoreVersions If true don't check the client/server versions match.
* @param force Force operation.
* @param metalake The name of the metalake.
* @param tag The name of the tag.
* @param tags The names of the tags.
*/
public DeleteTag(String url, boolean ignoreVersions, boolean force, String metalake, String tag) {
public DeleteTag(
String url, boolean ignoreVersions, boolean force, String metalake, String[] tags) {
super(url, ignoreVersions);
this.force = force;
this.metalake = metalake;
this.tag = tag;
this.tags = tags;
}

/** Delete a tag. */
/** Delete tags. */
@Override
public void handle() {
if (!AreYouSure.really(force)) {
return;
}
boolean hasOnlyOneTag = tags.length == 1;
if (hasOnlyOneTag) {
handleOnlyOneTag();
} else {
handleMultipleTags();
}
}

private void handleMultipleTags() {
List<String> deleted = new ArrayList<>();
try {
GravitinoClient client = buildClient(metalake);
for (String tag : tags) {
if (client.deleteTag(tag)) {
deleted.add(tag);
}
}
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
} catch (NoSuchTagException err) {
System.err.println(ErrorMessages.UNKNOWN_TAG);
return;
} catch (Exception exp) {
System.err.println(exp.getMessage());
return;
}
if (!deleted.isEmpty()) {
System.out.println("Tags " + String.join(",", deleted) + " deleted.");
}
if (deleted.size() < tags.length) {
List<String> remaining = Arrays.asList(tags);
remaining.removeAll(deleted);
System.out.println("Tags " + String.join(",", deleted) + " not deleted.");
}
}

private void handleOnlyOneTag() {
boolean deleted = false;

if (!AreYouSure.really(force)) {
Expand All @@ -58,7 +103,7 @@ public void handle() {

try {
GravitinoClient client = buildClient(metalake);
deleted = client.deleteTag(tag);
deleted = client.deleteTag(tags[0]);
} catch (NoSuchMetalakeException err) {
System.err.println(ErrorMessages.UNKNOWN_METALAKE);
return;
Expand All @@ -71,9 +116,9 @@ public void handle() {
}

if (deleted) {
System.out.println(tag + " deleted.");
System.out.println(tags[0] + " deleted.");
} else {
System.out.println(tag + " not deleted.");
System.out.println(tags[0] + " not deleted.");
}
}
}
Loading

0 comments on commit e62c6d3

Please sign in to comment.