This is an automated email from the ASF dual-hosted git repository. tejaskriya pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push: new 593c816f41 HDDS-13486. Exclusivity Between Node Selection and Sorting Options in ListInfoSubcommand (#8844) 593c816f41 is described below commit 593c816f4117e1b0907800f8b61128f377fc6353 Author: sreejasahithi <115860222+sreejasahi...@users.noreply.github.com> AuthorDate: Mon Jul 28 15:18:06 2025 +0530 HDDS-13486. Exclusivity Between Node Selection and Sorting Options in ListInfoSubcommand (#8844) --- .../hdds/scm/cli/datanode/ListInfoSubcommand.java | 23 +++++++------- .../scm/cli/datanode/TestListInfoSubcommand.java | 35 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java index 56c5045621..a30e91150e 100644 --- a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java +++ b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/datanode/ListInfoSubcommand.java @@ -66,17 +66,14 @@ public class ListInfoSubcommand extends ScmSubcommand { private boolean json; @CommandLine.ArgGroup(exclusive = true, multiplicity = "0..1") - private UsageSortingOptions usageSortingOptions; + private ExclusiveNodeOptions exclusiveNodeOptions; @CommandLine.Mixin private ListLimitOptions listLimitOptions; - @CommandLine.Mixin - private NodeSelectionMixin nodeSelectionMixin; - private List<Pipeline> pipelines; - static class UsageSortingOptions { + static class ExclusiveNodeOptions extends NodeSelectionMixin { @CommandLine.Option(names = {"--most-used"}, description = "Show datanodes sorted by Utilization (most to least).") private boolean mostUsed; @@ -89,8 +86,8 @@ static class UsageSortingOptions { @Override public void execute(ScmClient scmClient) throws IOException { pipelines = scmClient.listPipelines(); - if (!Strings.isNullOrEmpty(nodeSelectionMixin.getNodeId())) { - HddsProtos.Node node = scmClient.queryNode(UUID.fromString(nodeSelectionMixin.getNodeId())); + if (exclusiveNodeOptions != null && !Strings.isNullOrEmpty(exclusiveNodeOptions.getNodeId())) { + HddsProtos.Node node = scmClient.queryNode(UUID.fromString(exclusiveNodeOptions.getNodeId())); DatanodeWithAttributes dwa = new DatanodeWithAttributes(DatanodeDetails .getFromProtoBuf(node.getNodeID()), node.getNodeOperationalStates(0), @@ -105,13 +102,13 @@ public void execute(ScmClient scmClient) throws IOException { return; } Stream<DatanodeWithAttributes> allNodes = getAllNodes(scmClient).stream(); - if (!Strings.isNullOrEmpty(nodeSelectionMixin.getIp())) { + if (exclusiveNodeOptions != null && !Strings.isNullOrEmpty(exclusiveNodeOptions.getIp())) { allNodes = allNodes.filter(p -> p.getDatanodeDetails().getIpAddress() - .compareToIgnoreCase(nodeSelectionMixin.getIp()) == 0); + .compareToIgnoreCase(exclusiveNodeOptions.getIp()) == 0); } - if (!Strings.isNullOrEmpty(nodeSelectionMixin.getHostname())) { + if (exclusiveNodeOptions != null && !Strings.isNullOrEmpty(exclusiveNodeOptions.getHostname())) { allNodes = allNodes.filter(p -> p.getDatanodeDetails().getHostName() - .compareToIgnoreCase(nodeSelectionMixin.getHostname()) == 0); + .compareToIgnoreCase(exclusiveNodeOptions.getHostname()) == 0); } if (!Strings.isNullOrEmpty(nodeOperationalState)) { allNodes = allNodes.filter(p -> p.getOpState().toString() @@ -140,8 +137,8 @@ private List<DatanodeWithAttributes> getAllNodes(ScmClient scmClient) throws IOException { // If sorting is requested - if (usageSortingOptions != null && (usageSortingOptions.mostUsed || usageSortingOptions.leastUsed)) { - boolean sortByMostUsed = usageSortingOptions.mostUsed; + if (exclusiveNodeOptions != null && (exclusiveNodeOptions.mostUsed || exclusiveNodeOptions.leastUsed)) { + boolean sortByMostUsed = exclusiveNodeOptions.mostUsed; List<HddsProtos.DatanodeUsageInfoProto> usageInfos = scmClient.getDatanodeUsageInfo(sortByMostUsed, Integer.MAX_VALUE); diff --git a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java index f24fe6e1b2..a63d0c925f 100644 --- a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java +++ b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/scm/cli/datanode/TestListInfoSubcommand.java @@ -18,6 +18,7 @@ package org.apache.hadoop.hdds.scm.cli.datanode; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.Mockito.any; @@ -278,6 +279,40 @@ public void testUsedOrderingAndOutput( validateOrderingFromTextOutput(textOutput, orderDirection); } + @ParameterizedTest(name = "{0} and {1} should be mutually exclusive") + @CsvSource({ + "--most-used, --node-id", + "--most-used, --ip", + "--most-used, --hostname", + "--least-used, --node-id", + "--least-used, --ip", + "--least-used, --hostname" + }) + public void testNodeSelectionAndUsageSortingAreMutuallyExclusive(String sortingFlag, String selectionFlag) { + CommandLine c = new CommandLine(cmd); + + List<HddsProtos.Node> nodes = getNodeDetails(); + String nodeSelectionValue; + if ("--node-id".equals(selectionFlag)) { + nodeSelectionValue = nodes.get(0).getNodeID().getUuid(); + } else if ("--ip".equals(selectionFlag)) { + nodeSelectionValue = "192.168.1.100"; + } else { + nodeSelectionValue = "host-one"; + } + + CommandLine.MutuallyExclusiveArgsException thrown = assertThrows( + CommandLine.MutuallyExclusiveArgsException.class, + () -> c.parseArgs(sortingFlag, selectionFlag, nodeSelectionValue), + () -> String.format("Expected MutuallyExclusiveArgsException when combining %s and %s", + sortingFlag, selectionFlag) + ); + + String expectedErrorMessagePart = "mutually exclusive"; + assertTrue(thrown.getMessage().contains(expectedErrorMessagePart), + "Exception message should contain '" + expectedErrorMessagePart + "' but was: " + thrown.getMessage()); + } + private void validateOrdering(JsonNode root, String orderDirection) { for (int i = 0; i < root.size() - 1; i++) { long usedCurrent = root.get(i).get("used").asLong(); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@ozone.apache.org For additional commands, e-mail: commits-h...@ozone.apache.org