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 db8a14abe [#6177] improve(CLI): Refactor ownership commands in 
Gravitino CLI (#6188)
db8a14abe is described below

commit db8a14abef75fdc73d303b7bd417e6e69a355cba
Author: Lord of Abyss <103809695+abyss-l...@users.noreply.github.com>
AuthorDate: Mon Jan 13 05:52:30 2025 +0800

    [#6177] improve(CLI): Refactor ownership commands in Gravitino CLI (#6188)
    
    ### What changes were proposed in this pull request?
    
    Refactor ownership commands in Gravitino CLI.
    
    ### Why are the changes needed?
    
    Fix: #6177
    
    ### Does this PR introduce _any_ user-facing change?
    
    No
    
    ### How was this patch tested?
    
    local test.
---
 .../apache/gravitino/cli/GravitinoCommandLine.java |  41 +------
 .../apache/gravitino/cli/OwnerCommandHandler.java  | 128 +++++++++++++++++++++
 .../apache/gravitino/cli/TestOwnerCommands.java    |  79 +++++++++++++
 3 files changed, 208 insertions(+), 40 deletions(-)

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 675a96d36..9c9ce6810 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
@@ -127,7 +127,7 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     if (CommandActions.HELP.equals(command)) {
       handleHelpCommand();
     } else if (line.hasOption(GravitinoOptions.OWNER)) {
-      handleOwnerCommand();
+      new OwnerCommandHandler(this, line, command, ignore, entity).handle();
     } else if (entity.equals(CommandEntities.COLUMN)) {
       handleColumnCommand();
     } else if (entity.equals(CommandEntities.TABLE)) {
@@ -554,45 +554,6 @@ public class GravitinoCommandLine extends 
TestableCommandLine {
     }
   }
 
-  /**
-   * Handles the command execution for Objects based on command type and the 
command line options.
-   */
-  private void handleOwnerCommand() {
-    String url = getUrl();
-    String auth = getAuth();
-    String userName = line.getOptionValue(GravitinoOptions.LOGIN);
-    FullName name = new FullName(line);
-    String metalake = name.getMetalakeName();
-    String entityName = line.getOptionValue(GravitinoOptions.NAME);
-
-    Command.setAuthenticationMode(auth, userName);
-
-    switch (command) {
-      case CommandActions.DETAILS:
-        newOwnerDetails(url, ignore, metalake, entityName, entity).handle();
-        break;
-
-      case CommandActions.SET:
-        {
-          String owner = line.getOptionValue(GravitinoOptions.USER);
-          String group = line.getOptionValue(GravitinoOptions.GROUP);
-
-          if (owner != null && group == null) {
-            newSetOwner(url, ignore, metalake, entityName, entity, owner, 
false).handle();
-          } else if (owner == null && group != null) {
-            newSetOwner(url, ignore, metalake, entityName, entity, group, 
true).handle();
-          } else {
-            System.err.println(ErrorMessages.INVALID_SET_COMMAND);
-          }
-          break;
-        }
-
-      default:
-        System.err.println(ErrorMessages.UNSUPPORTED_ACTION);
-        break;
-    }
-  }
-
   /**
    * Handles the command execution for filesets based on command type and the 
command line options.
    */
diff --git 
a/clients/cli/src/main/java/org/apache/gravitino/cli/OwnerCommandHandler.java 
b/clients/cli/src/main/java/org/apache/gravitino/cli/OwnerCommandHandler.java
new file mode 100644
index 000000000..7e41fb478
--- /dev/null
+++ 
b/clients/cli/src/main/java/org/apache/gravitino/cli/OwnerCommandHandler.java
@@ -0,0 +1,128 @@
+/*
+ * 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 org.apache.commons.cli.CommandLine;
+import org.apache.gravitino.cli.commands.Command;
+
+/** Handles the command execution for Owner based on command type and the 
command line options. */
+public class OwnerCommandHandler 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 final String entityName;
+  private final String owner;
+  private final String group;
+  private final String entity;
+
+  /**
+   * Constructs a {@link OwnerCommandHandler} 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.
+   * @param entity The entity to execute the command on.
+   */
+  public OwnerCommandHandler(
+      GravitinoCommandLine gravitinoCommandLine,
+      CommandLine line,
+      String command,
+      boolean ignore,
+      String entity) {
+    this.gravitinoCommandLine = gravitinoCommandLine;
+    this.line = line;
+    this.command = command;
+    this.ignore = ignore;
+
+    this.url = getUrl(line);
+    this.owner = line.getOptionValue(GravitinoOptions.USER);
+    this.group = line.getOptionValue(GravitinoOptions.GROUP);
+    this.name = new FullName(line);
+    this.metalake = name.getMetalakeName();
+    this.entityName = name.getName();
+    this.entity = entity;
+  }
+  /** 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);
+
+    if (entityName == null && !CommandEntities.METALAKE.equals(entity)) {
+      System.err.println(ErrorMessages.MISSING_NAME);
+      Main.exit(-1);
+    }
+    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.SET:
+        handleSetCommand();
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
+  /** Handles the "DETAILS" command. */
+  private void handleDetailsCommand() {
+    gravitinoCommandLine
+        .newOwnerDetails(url, ignore, metalake, entityName, entity)
+        .validate()
+        .handle();
+  }
+
+  /** Handles the "SET" command. */
+  private void handleSetCommand() {
+    if (owner != null && group == null) {
+      gravitinoCommandLine
+          .newSetOwner(url, ignore, metalake, entityName, entity, owner, false)
+          .validate()
+          .handle();
+    } else if (owner == null && group != null) {
+      gravitinoCommandLine
+          .newSetOwner(url, ignore, metalake, entityName, entity, group, true)
+          .validate()
+          .handle();
+    } else {
+      System.err.println(ErrorMessages.INVALID_SET_COMMAND);
+      Main.exit(-1);
+    }
+  }
+}
diff --git 
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java 
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java
index 0c2b2cf91..12f617380 100644
--- a/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java
@@ -19,16 +19,25 @@
 
 package org.apache.gravitino.cli;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
 import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.Options;
 import org.apache.gravitino.cli.commands.OwnerDetails;
 import org.apache.gravitino.cli.commands.SetOwner;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -36,10 +45,23 @@ class TestOwnerCommands {
   private CommandLine mockCommandLine;
   private Options mockOptions;
 
+  private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+  private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
+  private final PrintStream originalOut = System.out;
+  private final PrintStream originalErr = System.err;
+
   @BeforeEach
   void setUp() {
     mockCommandLine = mock(CommandLine.class);
     mockOptions = mock(Options.class);
+    System.setOut(new PrintStream(outContent));
+    System.setErr(new PrintStream(errContent));
+  }
+
+  @AfterEach
+  public void restoreStreams() {
+    System.setOut(originalOut);
+    System.setErr(originalErr);
   }
 
   @Test
@@ -67,6 +89,7 @@ class TestOwnerCommands {
             "catalog",
             "admin",
             false);
+    doReturn(mockSetOwner).when(mockSetOwner).validate();
     commandLine.handleCommandLine();
     verify(mockSetOwner).handle();
   }
@@ -96,6 +119,7 @@ class TestOwnerCommands {
             "catalog",
             "ITdept",
             true);
+    doReturn(mockSetOwner).when(mockSetOwner).validate();
     commandLine.handleCommandLine();
     verify(mockSetOwner).handle();
   }
@@ -116,7 +140,62 @@ class TestOwnerCommands {
         .when(commandLine)
         .newOwnerDetails(
             GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo", 
"postgres", "catalog");
+    doReturn(mockOwnerDetails).when(mockOwnerDetails).validate();
     commandLine.handleCommandLine();
     verify(mockOwnerDetails).handle();
   }
+
+  @Test
+  void testOwnerDetailsCommandWithoutName() {
+    Main.useExit = false;
+    
when(mockCommandLine.hasOption(GravitinoOptions.METALAKE)).thenReturn(true);
+    
when(mockCommandLine.getOptionValue(GravitinoOptions.METALAKE)).thenReturn("metalake_demo");
+    when(mockCommandLine.hasOption(GravitinoOptions.NAME)).thenReturn(false);
+    when(mockCommandLine.hasOption(GravitinoOptions.OWNER)).thenReturn(true);
+    GravitinoCommandLine commandLine =
+        spy(
+            new GravitinoCommandLine(
+                mockCommandLine, mockOptions, CommandEntities.CATALOG, 
CommandActions.DETAILS));
+
+    assertThrows(RuntimeException.class, commandLine::handleCommandLine);
+    verify(commandLine, never())
+        .newOwnerDetails(
+            eq(GravitinoCommandLine.DEFAULT_URL),
+            eq(false),
+            eq("metalake_demo"),
+            eq(null),
+            eq(CommandEntities.CATALOG));
+
+    String errOutput = new String(errContent.toByteArray(), 
StandardCharsets.UTF_8).trim();
+    assertEquals(ErrorMessages.MISSING_NAME, errOutput);
+  }
+
+  @Test
+  void testSetOwnerUserCommandWithoutUserAndGroup() {
+    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("postgres");
+    when(mockCommandLine.hasOption(GravitinoOptions.USER)).thenReturn(false);
+    when(mockCommandLine.hasOption(GravitinoOptions.GROUP)).thenReturn(false);
+    when(mockCommandLine.hasOption(GravitinoOptions.OWNER)).thenReturn(true);
+    GravitinoCommandLine commandLine =
+        spy(
+            new GravitinoCommandLine(
+                mockCommandLine, mockOptions, CommandEntities.CATALOG, 
CommandActions.SET));
+
+    assertThrows(RuntimeException.class, commandLine::handleCommandLine);
+    verify(commandLine, never())
+        .newSetOwner(
+            eq(GravitinoCommandLine.DEFAULT_URL),
+            eq(false),
+            eq("metalake_demo"),
+            eq("postgres"),
+            eq(CommandEntities.CATALOG),
+            isNull(),
+            eq(false));
+    String errOutput = new String(errContent.toByteArray(), 
StandardCharsets.UTF_8).trim();
+    assertEquals(ErrorMessages.INVALID_SET_COMMAND, errOutput);
+  }
 }

Reply via email to