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 7f59b5ace [#6143] improve(CLI): Refactor catalog commands in Gavitino CLI (#6159) 7f59b5ace is described below commit 7f59b5ace132bcbe0008c38399dbeef8b9392d29 Author: Lord of Abyss <103809695+abyss-l...@users.noreply.github.com> AuthorDate: Fri Jan 10 05:08:28 2025 +0800 [#6143] improve(CLI): Refactor catalog commands in Gavitino CLI (#6159) ### What changes were proposed in this pull request? 1. Refactor catalog commands and Base class in Gavitino CLI. 2. Add test case. ### Why are the changes needed? Fix: #6143 ### Does this PR introduce _any_ user-facing change? No ### How was this patch tested? local test. --- .../gravitino/cli/CatalogCommandHandler.java | 224 +++++++++++++++++++++ .../org/apache/gravitino/cli/CommandHandler.java | 120 +++++++++++ .../apache/gravitino/cli/GravitinoCommandLine.java | 97 +-------- 3 files changed, 345 insertions(+), 96 deletions(-) diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/CatalogCommandHandler.java b/clients/cli/src/main/java/org/apache/gravitino/cli/CatalogCommandHandler.java new file mode 100644 index 000000000..8e2384068 --- /dev/null +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/CatalogCommandHandler.java @@ -0,0 +1,224 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.cli; + +import com.google.common.collect.Lists; +import java.util.List; +import java.util.Map; +import org.apache.commons.cli.CommandLine; +import org.apache.gravitino.cli.commands.Command; + +/** + * Handles the command execution for Catalogs based on command type and the command line options. + */ +public class CatalogCommandHandler extends CommandHandler { + + private final GravitinoCommandLine gravitinoCommandLine; + private final CommandLine line; + private final String command; + private final boolean ignore; + private final String url; + private final FullName name; + private final String metalake; + private String catalog; + private final String outputFormat; + + /** + * Constructs a {@link CatalogCommandHandler} instance. + * + * @param gravitinoCommandLine The Gravitino command line instance. + * @param line The command line arguments. + * @param command The command to execute. + * @param ignore Ignore server version mismatch. + */ + public CatalogCommandHandler( + GravitinoCommandLine gravitinoCommandLine, CommandLine line, String command, boolean ignore) { + this.gravitinoCommandLine = gravitinoCommandLine; + this.line = line; + this.command = command; + this.ignore = ignore; + + this.url = getUrl(line); + this.name = new FullName(line); + this.metalake = name.getMetalakeName(); + this.outputFormat = line.getOptionValue(GravitinoOptions.OUTPUT); + } + + /** Handles the command execution logic based on the provided command. */ + @Override + protected void handle() { + String userName = line.getOptionValue(GravitinoOptions.LOGIN); + Command.setAuthenticationMode(getAuth(line), userName); + List<String> missingEntities = Lists.newArrayList(); + + if (CommandActions.LIST.equals(command)) { + handleListCommand(); + return; + } + + this.catalog = name.getCatalogName(); + if (catalog == null) missingEntities.add(CommandEntities.CATALOG); + checkEntities(missingEntities); + + if (!executeCommand()) { + System.err.println(ErrorMessages.UNSUPPORTED_COMMAND); + Main.exit(-1); + } + } + + /** + * Executes the specific command based on the command type. + * + * @return true if the command is supported, false otherwise + */ + private boolean executeCommand() { + switch (command) { + case CommandActions.DETAILS: + handleDetailsCommand(); + return true; + + case CommandActions.CREATE: + handleCreateCommand(); + return true; + + case CommandActions.DELETE: + handleDeleteCommand(); + return true; + + case CommandActions.SET: + handleSetCommand(); + return true; + + case CommandActions.REMOVE: + handleRemoveCommand(); + return true; + + case CommandActions.PROPERTIES: + handlePropertiesCommand(); + return true; + + case CommandActions.UPDATE: + handleUpdateCommand(); + return true; + + default: + return false; + } + } + + /** Handles the "DETAILS" command. */ + private void handleDetailsCommand() { + if (line.hasOption(GravitinoOptions.AUDIT)) { + gravitinoCommandLine.newCatalogAudit(url, ignore, metalake, catalog).validate().handle(); + } else { + gravitinoCommandLine + .newCatalogDetails(url, ignore, outputFormat, metalake, catalog) + .validate() + .handle(); + } + } + + /** Handles the "CREATE" command. */ + private void handleCreateCommand() { + String comment = line.getOptionValue(GravitinoOptions.COMMENT); + String provider = line.getOptionValue(GravitinoOptions.PROVIDER); + String[] properties = line.getOptionValues(CommandActions.PROPERTIES); + + Map<String, String> propertyMap = new Properties().parse(properties); + gravitinoCommandLine + .newCreateCatalog(url, ignore, metalake, catalog, provider, comment, propertyMap) + .validate() + .handle(); + } + + /** Handles the "DELETE" command. */ + private void handleDeleteCommand() { + boolean force = line.hasOption(GravitinoOptions.FORCE); + gravitinoCommandLine + .newDeleteCatalog(url, ignore, force, metalake, catalog) + .validate() + .handle(); + } + + /** Handles the "SET" command. */ + private void handleSetCommand() { + String property = line.getOptionValue(GravitinoOptions.PROPERTY); + String value = line.getOptionValue(GravitinoOptions.VALUE); + gravitinoCommandLine + .newSetCatalogProperty(url, ignore, metalake, catalog, property, value) + .validate() + .handle(); + } + + /** Handles the "REMOVE" command. */ + private void handleRemoveCommand() { + String property = line.getOptionValue(GravitinoOptions.PROPERTY); + gravitinoCommandLine + .newRemoveCatalogProperty(url, ignore, metalake, catalog, property) + .validate() + .handle(); + } + + /** Handles the "PROPERTIES" command. */ + private void handlePropertiesCommand() { + gravitinoCommandLine + .newListCatalogProperties(url, ignore, metalake, catalog) + .validate() + .handle(); + } + + /** Handles the "UPDATE" command. */ + private void handleUpdateCommand() { + if (line.hasOption(GravitinoOptions.ENABLE) && line.hasOption(GravitinoOptions.DISABLE)) { + System.err.println(ErrorMessages.INVALID_ENABLE_DISABLE); + Main.exit(-1); + } + if (line.hasOption(GravitinoOptions.ENABLE)) { + boolean enableMetalake = line.hasOption(GravitinoOptions.ALL); + gravitinoCommandLine + .newCatalogEnable(url, ignore, metalake, catalog, enableMetalake) + .validate() + .handle(); + } + if (line.hasOption(GravitinoOptions.DISABLE)) { + gravitinoCommandLine.newCatalogDisable(url, ignore, metalake, catalog).validate().handle(); + } + + if (line.hasOption(GravitinoOptions.COMMENT)) { + String updateComment = line.getOptionValue(GravitinoOptions.COMMENT); + gravitinoCommandLine + .newUpdateCatalogComment(url, ignore, metalake, catalog, updateComment) + .validate() + .handle(); + } + if (line.hasOption(GravitinoOptions.RENAME)) { + String newName = line.getOptionValue(GravitinoOptions.RENAME); + gravitinoCommandLine + .newUpdateCatalogName(url, ignore, metalake, catalog, newName) + .validate() + .handle(); + } + } + + /** Handles the "LIST" command. */ + private void handleListCommand() { + gravitinoCommandLine.newListCatalogs(url, ignore, outputFormat, metalake).validate().handle(); + } +} diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/CommandHandler.java b/clients/cli/src/main/java/org/apache/gravitino/cli/CommandHandler.java new file mode 100644 index 000000000..2b058b07a --- /dev/null +++ b/clients/cli/src/main/java/org/apache/gravitino/cli/CommandHandler.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.gravitino.cli; + +import com.google.common.base.Joiner; +import java.util.List; +import org.apache.commons.cli.CommandLine; + +public abstract class CommandHandler { + public static final Joiner COMMA_JOINER = Joiner.on(", ").skipNulls(); + + public static final String DEFAULT_URL = "http://localhost:8090"; + + private String urlEnv; + private boolean urlSet = false; + private String authEnv; + private boolean authSet = false; + + /** + * Retrieves the Gravitinno URL from the command line options or the GRAVITINO_URL environment + * variable or the Gravitio config file. + * + * @param line The command line instance. + * @return The Gravitinno URL, or null if not found. + */ + public String getUrl(CommandLine line) { + GravitinoConfig config = new GravitinoConfig(null); + + // If specified on the command line use that + if (line.hasOption(GravitinoOptions.URL)) { + return line.getOptionValue(GravitinoOptions.URL); + } + + // Cache the Gravitino URL environment variable + if (urlEnv == null && !urlSet) { + urlEnv = System.getenv("GRAVITINO_URL"); + urlSet = true; + } + + // If set return the Gravitino URL environment variable + if (urlEnv != null) { + return urlEnv; + } + + // Check if the Gravitino URL is specified in the configuration file + if (config.fileExists()) { + config.read(); + String configURL = config.getGravitinoURL(); + if (configURL != null) { + return configURL; + } + } + + // Return the default localhost URL + return DEFAULT_URL; + } + + /** + * Retrieves the Gravitinno authentication from the command line options or the GRAVITINO_AUTH + * environment variable or the Gravitio config file. + * + * @param line The command line instance. + * @return The Gravitinno authentication, or null if not found. + */ + public String getAuth(CommandLine line) { + // If specified on the command line use that + if (line.hasOption(GravitinoOptions.SIMPLE)) { + return GravitinoOptions.SIMPLE; + } + + // Cache the Gravitino authentication type environment variable + if (authEnv == null && !authSet) { + authEnv = System.getenv("GRAVITINO_AUTH"); + authSet = true; + } + + // If set return the Gravitino authentication type environment variable + if (authEnv != null) { + return authEnv; + } + + // Check if the authentication type is specified in the configuration file + GravitinoConfig config = new GravitinoConfig(null); + if (config.fileExists()) { + config.read(); + String configAuthType = config.getGravitinoAuthType(); + if (configAuthType != null) { + return configAuthType; + } + } + + return null; + } + + protected abstract void handle(); + + protected void checkEntities(List<String> entities) { + if (!entities.isEmpty()) { + System.err.println(ErrorMessages.MISSING_ENTITIES + COMMA_JOINER.join(entities)); + Main.exit(-1); + } + } +} 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 442ec2d1c..06b0c25e8 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 @@ -135,7 +135,7 @@ public class GravitinoCommandLine extends TestableCommandLine { } else if (entity.equals(CommandEntities.SCHEMA)) { handleSchemaCommand(); } else if (entity.equals(CommandEntities.CATALOG)) { - handleCatalogCommand(); + new CatalogCommandHandler(this, line, command, ignore).handle(); } else if (entity.equals(CommandEntities.METALAKE)) { handleMetalakeCommand(); } else if (entity.equals(CommandEntities.TOPIC)) { @@ -240,101 +240,6 @@ public class GravitinoCommandLine extends TestableCommandLine { } } - /** - * Handles the command execution for Catalogs based on command type and the command line options. - */ - private void handleCatalogCommand() { - String url = getUrl(); - String auth = getAuth(); - String userName = line.getOptionValue(GravitinoOptions.LOGIN); - FullName name = new FullName(line); - String metalake = name.getMetalakeName(); - String outputFormat = line.getOptionValue(GravitinoOptions.OUTPUT); - - Command.setAuthenticationMode(auth, userName); - List<String> missingEntities = Lists.newArrayList(); - - // Handle the CommandActions.LIST action separately as it doesn't use `catalog` - if (CommandActions.LIST.equals(command)) { - newListCatalogs(url, ignore, outputFormat, metalake).validate().handle(); - return; - } - - String catalog = name.getCatalogName(); - if (catalog == null) missingEntities.add(CommandEntities.CATALOG); - checkEntities(missingEntities); - - switch (command) { - case CommandActions.DETAILS: - if (line.hasOption(GravitinoOptions.AUDIT)) { - newCatalogAudit(url, ignore, metalake, catalog).validate().handle(); - } else { - newCatalogDetails(url, ignore, outputFormat, metalake, catalog).validate().handle(); - } - break; - - case CommandActions.CREATE: - String comment = line.getOptionValue(GravitinoOptions.COMMENT); - 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) - .validate() - .handle(); - break; - - case CommandActions.DELETE: - boolean force = line.hasOption(GravitinoOptions.FORCE); - 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).validate().handle(); - break; - - case CommandActions.REMOVE: - property = line.getOptionValue(GravitinoOptions.PROPERTY); - newRemoveCatalogProperty(url, ignore, metalake, catalog, property).validate().handle(); - break; - - case CommandActions.PROPERTIES: - newListCatalogProperties(url, ignore, metalake, catalog).validate().handle(); - break; - - case CommandActions.UPDATE: - if (line.hasOption(GravitinoOptions.ENABLE) && line.hasOption(GravitinoOptions.DISABLE)) { - System.err.println(ErrorMessages.INVALID_ENABLE_DISABLE); - Main.exit(-1); - } - if (line.hasOption(GravitinoOptions.ENABLE)) { - boolean enableMetalake = line.hasOption(GravitinoOptions.ALL); - newCatalogEnable(url, ignore, metalake, catalog, enableMetalake).validate().handle(); - } - if (line.hasOption(GravitinoOptions.DISABLE)) { - newCatalogDisable(url, ignore, metalake, catalog).validate().handle(); - } - - if (line.hasOption(GravitinoOptions.COMMENT)) { - String updateComment = line.getOptionValue(GravitinoOptions.COMMENT); - 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).validate().handle(); - } - break; - - default: - System.err.println(ErrorMessages.UNSUPPORTED_COMMAND); - Main.exit(-1); - break; - } - } - /** * Handles the command execution for Schemas based on command type and the command line options. */