This is an automated email from the ASF dual-hosted git repository.
adoroszlai 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 175e2934fe1 HDDS-7957. Deprecate multi-char short options (#10494)
175e2934fe1 is described below
commit 175e2934fe1b92d250f6c59f9bf5106a1d6559f4
Author: hani-fouladgar <[email protected]>
AuthorDate: Sun Jun 14 02:09:16 2026 -0500
HDDS-7957. Deprecate multi-char short options (#10494)
---
.../hadoop/hdds/cli/DeprecatedCliOption.java | 78 ++++++++++++++++++
.../org/apache/hadoop/hdds/cli/GenericCli.java | 33 +++++++-
.../hdds/cli/TestGenericCliConfiguration.java | 78 ++++++++++++++++++
.../org/apache/hadoop/hdds/scm/cli/ScmOption.java | 20 ++++-
.../scm/cli/pipeline/FilterPipelineOptions.java | 20 ++++-
.../scm/cli/pipeline/ListPipelinesSubcommand.java | 24 +++++-
.../ozone/admin/om/DecommissionOMSubcommand.java | 78 +++++++++++++-----
.../hadoop/ozone/admin/om/PrepareSubCommand.java | 92 ++++++++++++++++++----
.../ozone/admin/scm/DecommissionScmSubcommand.java | 33 ++++++--
.../hadoop/hdds/cli/TestDeprecatedCliOption.java | 77 ++++++++++++++++++
.../java/org/apache/hadoop/ozone/shell/Shell.java | 2 +
.../apache/hadoop/ozone/shell/acl/AclOption.java | 47 +++++++----
12 files changed, 510 insertions(+), 72 deletions(-)
diff --git
a/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/DeprecatedCliOption.java
b/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/DeprecatedCliOption.java
new file mode 100644
index 00000000000..d455c29ece7
--- /dev/null
+++
b/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/DeprecatedCliOption.java
@@ -0,0 +1,78 @@
+/*
+ * 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.hadoop.hdds.cli;
+
+import java.io.PrintWriter;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import picocli.CommandLine;
+
+/**
+ * Emits warnings when deprecated multi-character short CLI options are used.
+ */
+public final class DeprecatedCliOption {
+
+ private static final Map<String, String> DEPRECATED_OPTIONS =
buildDeprecatedOptions();
+
+ private DeprecatedCliOption() {
+ // no instances
+ }
+
+ private static Map<String, String> buildDeprecatedOptions() {
+ Map<String, String> options = new LinkedHashMap<>();
+ options.put("-conf", "--conf");
+ options.put("-id", "--service-id");
+ options.put("-host", "--service-host");
+ options.put("-nodeid", "--nodeid");
+ options.put("-hostname", "--node-host-address");
+ options.put("-al", "--acls");
+ options.put("-ffc", "--filter-by-factor");
+ options.put("-fst", "--filter-by-state");
+ options.put("-tawt", "--transaction-apply-wait-timeout");
+ options.put("-tact", "--transaction-apply-check-interval");
+ options.put("-pct", "--prepare-check-interval");
+ options.put("-pt", "--prepare-timeout");
+ return options;
+ }
+
+ /**
+ * Print a warning to stderr for each deprecated option present on the
command line.
+ */
+ public static void warnIfMatched(CommandLine.ParseResult parseResult) {
+ if (parseResult == null) {
+ return;
+ }
+
+ for (CommandLine cli : parseResult.asCommandLineList()) {
+ CommandLine.ParseResult subcommandResult = cli.getParseResult();
+ if (subcommandResult.matchedOptions().isEmpty()) {
+ continue;
+ }
+ for (Map.Entry<String, String> entry : DEPRECATED_OPTIONS.entrySet()) {
+ if (subcommandResult.hasMatchedOption(entry.getKey())) {
+ warn(cli.getErr(), entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
+
+ private static void warn(PrintWriter err, String deprecated, String
replacement) {
+ err.printf("WARNING: Option '%s' is deprecated. Use '%s' instead.%n",
+ deprecated, replacement);
+ }
+}
diff --git
a/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java
b/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java
index b12330ab2d0..6fcdd686219 100644
---
a/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java
+++
b/hadoop-hdds/cli-common/src/main/java/org/apache/hadoop/hdds/cli/GenericCli.java
@@ -46,6 +46,10 @@ public abstract class GenericCli implements
GenericParentCommand {
private UserGroupInformation user;
+ private String configurationPath;
+ private String deprecatedConfigurationPath;
+ private boolean isConfigurationPathAdded = false;
+
@Option(names = {"--verbose"},
scope = CommandLine.ScopeType.INHERIT,
description = "More verbose output. Show the stack trace of the errors.")
@@ -56,9 +60,25 @@ public void setConfigurationOverrides(Map<String, String>
configOverrides) {
configOverrides.forEach(config::set);
}
- @Option(names = {"-conf"})
+ @Option(names = {"--conf"},
+ description = "Path to custom configuration file.")
public void setConfigurationPath(String configPath) {
- config.addResource(new Path(configPath));
+ configurationPath = configPath;
+ }
+
+ /** For backward compatibility. */
+ @Option(names = {"-conf"}, hidden = true)
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ public void setDeprecatedConfigurationPath(String configPath) {
+ deprecatedConfigurationPath = configPath;
+ }
+
+ private String getConfigurationPath() {
+ if (configurationPath != null) {
+ return configurationPath;
+ }
+ return deprecatedConfigurationPath;
}
public GenericCli() {
@@ -71,6 +91,10 @@ public GenericCli(CommandLine.IFactory factory) {
printError(ex);
return EXECUTION_ERROR_EXIT_CODE;
});
+ cmd.setExecutionStrategy(parseResult -> {
+ DeprecatedCliOption.warnIfMatched(parseResult);
+ return new CommandLine.RunLast().execute(parseResult);
+ });
ExtensibleParentCommand.addSubcommands(cmd);
}
@@ -111,6 +135,11 @@ public void printError(Throwable error) {
@Override
public OzoneConfiguration getOzoneConf() {
+ String path = getConfigurationPath();
+ if (path != null && !isConfigurationPathAdded) {
+ config.addResource(new Path(path));
+ isConfigurationPathAdded = true;
+ }
return config;
}
diff --git
a/hadoop-hdds/cli-common/src/test/java/org/apache/hadoop/hdds/cli/TestGenericCliConfiguration.java
b/hadoop-hdds/cli-common/src/test/java/org/apache/hadoop/hdds/cli/TestGenericCliConfiguration.java
new file mode 100644
index 00000000000..5334d4b86c3
--- /dev/null
+++
b/hadoop-hdds/cli-common/src/test/java/org/apache/hadoop/hdds/cli/TestGenericCliConfiguration.java
@@ -0,0 +1,78 @@
+/*
+ * 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.hadoop.hdds.cli;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for {@link GenericCli} configuration option handling.
+ */
+public class TestGenericCliConfiguration {
+
+ private static final class TestGenericCli extends GenericCli {
+ }
+
+ @Test
+ public void nonDeprecatedConfWinsWhenBothAreProvided() throws IOException {
+ Path deprecatedConf = writeConf("deprecated");
+ Path preferredConf = writeConf("preferred");
+
+ TestGenericCli cli = new TestGenericCli();
+ cli.getCmd().parseArgs("-conf", deprecatedConf.toString(), "--conf",
+ preferredConf.toString());
+
+ assertThat(cli.getOzoneConf().get("test.key")).isEqualTo("preferred");
+ }
+
+ @Test
+ public void nonDeprecatedConfWinsRegardlessOfOrder() throws IOException {
+ Path deprecatedConf = writeConf("deprecated");
+ Path preferredConf = writeConf("preferred");
+
+ TestGenericCli cli = new TestGenericCli();
+ cli.getCmd().parseArgs("--conf", preferredConf.toString(), "-conf",
+ deprecatedConf.toString());
+
+ assertThat(cli.getOzoneConf().get("test.key")).isEqualTo("preferred");
+ }
+
+ @Test
+ public void deprecatedConfIsUsedWhenNonDeprecatedIsAbsent() throws
IOException {
+ Path deprecatedConf = writeConf("deprecated");
+
+ TestGenericCli cli = new TestGenericCli();
+ cli.getCmd().parseArgs("-conf", deprecatedConf.toString());
+
+ assertThat(cli.getOzoneConf().get("test.key")).isEqualTo("deprecated");
+ }
+
+ private static Path writeConf(String value) throws IOException {
+ Path conf = Files.createTempFile("ozone-conf-", ".xml");
+ Files.write(conf,
+ ("<configuration><property><name>test.key</name><value>" + value
+ +
"</value></property></configuration>").getBytes(StandardCharsets.UTF_8));
+ conf.toFile().deleteOnExit();
+ return conf;
+ }
+}
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ScmOption.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ScmOption.java
index f82b2be6c88..acb7a4424b9 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ScmOption.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/ScmOption.java
@@ -42,10 +42,16 @@ public class ScmOption extends AbstractMixin {
description = "The destination scm (host:port)")
private String scm;
- @CommandLine.Option(names = {"--service-id", "-id"}, description =
+ @CommandLine.Option(names = {"--service-id"}, description =
"ServiceId of SCM HA Cluster")
private String scmServiceId;
+ /** For backward compatibility. */
+ @CommandLine.Option(names = {"-id"}, hidden = true)
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private String deprecatedScmServiceId;
+
public ScmClient createScmClient() throws IOException {
OzoneConfiguration conf = getOzoneConf();
checkAndSetSCMAddressArg(conf);
@@ -70,8 +76,9 @@ private void
checkAndSetSCMAddressArg(MutableConfigurationSource conf) {
// Use the scm service Id passed from the client.
- if (StringUtils.isNotEmpty(scmServiceId)) {
- conf.set(ScmConfigKeys.OZONE_SCM_DEFAULT_SERVICE_ID, scmServiceId);
+ String serviceId = getScmServiceId();
+ if (StringUtils.isNotEmpty(serviceId)) {
+ conf.set(ScmConfigKeys.OZONE_SCM_DEFAULT_SERVICE_ID, serviceId);
} else if (StringUtils.isBlank(HddsUtils.getScmServiceId(conf))) {
// Scm service id is not passed, and scm service id is not defined in
// the config, assuming it should be non-HA cluster.
@@ -98,4 +105,11 @@ public SCMSecurityProtocol createScmSecurityClient() {
public String getScm() {
return scm;
}
+
+ public String getScmServiceId() {
+ if (StringUtils.isNotEmpty(scmServiceId)) {
+ return scmServiceId;
+ }
+ return deprecatedScmServiceId;
+ }
}
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/FilterPipelineOptions.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/FilterPipelineOptions.java
index 64e6ad0f390..b30f2c45071 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/FilterPipelineOptions.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/FilterPipelineOptions.java
@@ -45,20 +45,30 @@ public class FilterPipelineOptions {
private String replication;
@CommandLine.Option(
- names = {"-ffc", "--filterByFactor", "--filter-by-factor"},
+ names = {"--filterByFactor", "--filter-by-factor"},
description = "[deprecated] Filter pipelines by factor (e.g. ONE, THREE)
(implies RATIS replication type)")
private ReplicationFactor factor;
+ /** For backward compatibility. */
+ @CommandLine.Option(
+ names = {"-ffc"},
+ hidden = true
+ )
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private ReplicationFactor deprecatedFactor;
+
Optional<Predicate<? super Pipeline>> getReplicationFilter() {
+ ReplicationFactor effectiveFactor = getFactor();
boolean hasReplication = !Strings.isNullOrEmpty(replication);
- boolean hasFactor = factor != null;
+ boolean hasFactor = effectiveFactor != null;
boolean hasReplicationType = !Strings.isNullOrEmpty(replicationType);
if (hasFactor) {
if (hasReplication) {
throw new IllegalArgumentException("Factor and replication are
mutually exclusive");
}
- ReplicationConfig replicationConfig =
RatisReplicationConfig.getInstance(factor.toProto());
+ ReplicationConfig replicationConfig =
RatisReplicationConfig.getInstance(effectiveFactor.toProto());
return Optional.of(p ->
replicationConfig.equals(p.getReplicationConfig()));
}
@@ -81,4 +91,8 @@ Optional<Predicate<? super Pipeline>> getReplicationFilter() {
return Optional.empty();
}
+
+ private ReplicationFactor getFactor() {
+ return factor != null ? factor : deprecatedFactor;
+ }
}
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/ListPipelinesSubcommand.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/ListPipelinesSubcommand.java
index 53c70a657f4..b1e5ec6d3ae 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/ListPipelinesSubcommand.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/hdds/scm/cli/pipeline/ListPipelinesSubcommand.java
@@ -44,11 +44,21 @@ public class ListPipelinesSubcommand extends ScmSubcommand {
private final FilterPipelineOptions filterOptions = new
FilterPipelineOptions();
@CommandLine.Option(
- names = {"-s", "--state", "-fst", "--filterByState",
"--filter-by-state"},
+ names = {"-s", "--state", "--filterByState", "--filter-by-state"},
description = "Filter listed pipelines by State, eg OPEN, CLOSED",
defaultValue = "")
private String state;
+ /** For backward compatibility. */
+ @CommandLine.Option(
+ names = {"-fst"},
+ hidden = true,
+ defaultValue = ""
+ )
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private String deprecatedState;
+
@CommandLine.Option(
names = {"--json"},
defaultValue = "false",
@@ -63,9 +73,10 @@ public void execute(ScmClient scmClient) throws IOException {
if (replicationFilter.isPresent()) {
stream = stream.filter(replicationFilter.get());
}
- if (!Strings.isNullOrEmpty(state)) {
+ String effectiveState = getState();
+ if (!Strings.isNullOrEmpty(effectiveState)) {
stream = stream.filter(p -> p.getPipelineState().toString()
- .compareToIgnoreCase(state) == 0);
+ .compareToIgnoreCase(effectiveState) == 0);
}
if (json) {
@@ -76,4 +87,11 @@ public void execute(ScmClient scmClient) throws IOException {
stream.forEach(System.out::println);
}
}
+
+ private String getState() {
+ if (!Strings.isNullOrEmpty(state)) {
+ return state;
+ }
+ return deprecatedState;
+ }
}
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/DecommissionOMSubcommand.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/DecommissionOMSubcommand.java
index 5e17e1f6f81..1b1a46f6654 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/DecommissionOMSubcommand.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/DecommissionOMSubcommand.java
@@ -43,8 +43,8 @@
@CommandLine.Command(
name = "decommission",
customSynopsis = "ozone admin om decommission --service-id=<om-service-id>
" +
- "-nodeid=<decommission-om-node-id> " +
- "-hostname=<decommission-om-node-address> [options]",
+ "--nodeid=<decommission-om-node-id> " +
+ "--node-host-address=<decommission-om-node-address> [options]",
description = "Decommission an OzoneManager. Ensure that the node being " +
"decommissioned is shutdown first." +
"%nNote - Add the node to be decommissioned to " +
@@ -67,15 +67,11 @@ public class DecommissionOMSubcommand implements
Callable<Void> {
@CommandLine.Mixin
private OmAddressOptions.MandatoryServiceIdMixin omServiceOption;
- @CommandLine.Option(names = {"-nodeid", "--nodeid"},
- description = "NodeID of the OM to be decommissioned.",
- required = true)
- private String decommNodeId;
+ @CommandLine.ArgGroup(multiplicity = "1")
+ private NodeIdOptions nodeIdOptions;
- @CommandLine.Option(names = {"-hostname", "--node-host-address"},
- description = "Host name/address of the OM to be decommissioned.",
- required = true)
- private String hostname;
+ @CommandLine.ArgGroup(multiplicity = "1")
+ private HostnameOptions hostnameOptions;
private InetAddress hostInetAddress;
@@ -106,14 +102,14 @@ public Void call() throws IOException {
OMAdminProtocolClientSideImpl.createProxyForOMHA(ozoneConf, user,
omServiceOption.getServiceID())) {
OMNodeDetails decommNodeDetails = new OMNodeDetails.Builder()
- .setOMNodeId(decommNodeId)
+ .setOMNodeId(nodeIdOptions.getNodeId())
.setHostAddress(hostInetAddress.getHostAddress())
.build();
omAdminProtocolClient.decommission(decommNodeDetails);
- System.out.println("Successfully decommissioned OM " + decommNodeId);
+ System.out.println("Successfully decommissioned OM " +
nodeIdOptions.getNodeId());
} catch (IOException e) {
- System.out.println("Failed to decommission OM " + decommNodeId);
+ System.out.println("Failed to decommission OM " +
nodeIdOptions.getNodeId());
throw e;
}
return null;
@@ -125,19 +121,19 @@ public Void call() throws IOException {
*/
private void verifyNodeIdAndHostAddress() throws IOException {
String rpcAddrKey = ConfUtils.addKeySuffixes(OZONE_OM_ADDRESS_KEY,
- omServiceOption.getServiceID(), decommNodeId);
+ omServiceOption.getServiceID(), nodeIdOptions.getNodeId());
String rpcAddrStr = OmUtils.getOmRpcAddress(ozoneConf, rpcAddrKey);
if (rpcAddrStr == null || rpcAddrStr.isEmpty()) {
- throw new IOException("There is no OM corresponding to " + decommNodeId
+ throw new IOException("There is no OM corresponding to " +
nodeIdOptions.getNodeId()
+ "in the configuration.");
}
- hostInetAddress = InetAddress.getByName(hostname);
+ hostInetAddress = InetAddress.getByName(hostnameOptions.getHostname());
InetAddress rpcAddressFromConfig = InetAddress.getByName(
rpcAddrStr.split(":")[0]);
if (!hostInetAddress.equals(rpcAddressFromConfig)) {
- throw new IOException("OM " + decommNodeId + "'s host address in " +
+ throw new IOException("OM " + nodeIdOptions.getNodeId() + "'s host
address in " +
"config - " + rpcAddressFromConfig.getHostAddress() + " does not " +
"match the provided host address " + hostInetAddress);
}
@@ -153,9 +149,9 @@ private void verifyConfigUpdatedOnAllOMs() throws
IOException {
OZONE_OM_DECOMMISSIONED_NODES_KEY, omServiceOption.getServiceID());
Collection<String> decommNodes =
OmUtils.getDecommissionedNodeIds(ozoneConf, decommNodesKey);
- if (!decommNodes.contains(decommNodeId)) {
+ if (!decommNodes.contains(nodeIdOptions.getNodeId())) {
throw new IOException("Please add the to be decommissioned OM "
- + decommNodeId + " to the " + decommNodesKey + " config in " +
+ + nodeIdOptions.getNodeId() + " to the " + decommNodesKey + " config
in " +
"ozone-site.xml of all nodes.");
}
@@ -165,7 +161,7 @@ private void verifyConfigUpdatedOnAllOMs() throws
IOException {
List<OMNodeDetails> activeOMNodeDetails = OmUtils.getAllOMHAAddresses(
ozoneConf, omServiceOption.getServiceID(), false);
if (activeOMNodeDetails.isEmpty()) {
- throw new IOException("Cannot decommission OM " + decommNodeId + " as " +
+ throw new IOException("Cannot decommission OM " +
nodeIdOptions.getNodeId() + " as " +
"it is the only node in the ring.");
}
@@ -194,7 +190,7 @@ private boolean checkOMConfig(OMNodeDetails omNodeDetails)
user, omNodeDetails)) {
OMConfiguration omConfig = omAdminProtocolClient.getOMConfiguration();
OMNodeDetails decommNodeDetails = omConfig
- .getDecommissionedNodesInNewConf().get(decommNodeId);
+ .getDecommissionedNodesInNewConf().get(nodeIdOptions.getNodeId());
if (decommNodeDetails == null) {
return false;
}
@@ -205,4 +201,44 @@ private boolean checkOMConfig(OMNodeDetails omNodeDetails)
}
return true;
}
+
+ /** Options for OM node ID. */
+ static class NodeIdOptions {
+ @CommandLine.Option(names = {"--nodeid"},
+ description = "NodeID of the OM to be decommissioned.",
+ required = true)
+ private String nodeId;
+
+ /** For backward compatibility. */
+ @CommandLine.Option(names = {"-nodeid"},
+ hidden = true,
+ required = true)
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private String deprecatedNodeId;
+
+ String getNodeId() {
+ return nodeId != null ? nodeId : deprecatedNodeId;
+ }
+ }
+
+ /** Options for OM host name/address. */
+ static class HostnameOptions {
+ @CommandLine.Option(names = {"--node-host-address"},
+ description = "Host name/address of the OM to be decommissioned.",
+ required = true)
+ private String hostname;
+
+ /** For backward compatibility. */
+ @CommandLine.Option(names = {"-hostname"},
+ hidden = true,
+ required = true)
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private String deprecatedHostname;
+
+ String getHostname() {
+ return hostname != null ? hostname : deprecatedHostname;
+ }
+ }
}
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/PrepareSubCommand.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/PrepareSubCommand.java
index a0eabd4b7d1..4dad5f979e7 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/PrepareSubCommand.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/om/PrepareSubCommand.java
@@ -57,39 +57,71 @@ public class PrepareSubCommand implements Callable<Void> {
private OmAddressOptions.MandatoryServiceIdMixin omServiceOption;
@CommandLine.Option(
- names = {"-tawt", "--transaction-apply-wait-timeout"},
+ names = {"--transaction-apply-wait-timeout"},
description = "Max time in SECONDS to wait for all transactions before" +
"the prepare request to be applied to the OM DB.",
- defaultValue = "120",
hidden = true
)
- private long txnApplyWaitTimeSeconds;
+ private Long txnApplyWaitTimeSeconds;
+ /** For backward compatibility. */
@CommandLine.Option(
- names = {"-tact", "--transaction-apply-check-interval"},
+ names = {"-tawt"},
+ hidden = true
+ )
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private Long deprecatedTxnApplyWaitTimeSeconds;
+
+ @CommandLine.Option(
+ names = {"--transaction-apply-check-interval"},
description = "Time in SECONDS to wait between successive checks for " +
"all transactions to be applied to the OM DB.",
- defaultValue = "5",
hidden = true
)
- private long txnApplyCheckIntervalSeconds;
+ private Long txnApplyCheckIntervalSeconds;
+
+ /** For backward compatibility. */
+ @CommandLine.Option(
+ names = {"-tact"},
+ hidden = true
+ )
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private Long deprecatedTxnApplyCheckIntervalSeconds;
@CommandLine.Option(
- names = {"-pct", "--prepare-check-interval"},
+ names = {"--prepare-check-interval"},
description = "Time in SECONDS to wait between successive checks for OM"
+
" preparation.",
- defaultValue = "10",
hidden = true
)
- private long prepareCheckInterval;
+ private Long prepareCheckInterval;
+ /** For backward compatibility. */
@CommandLine.Option(
- names = {"-pt", "--prepare-timeout"},
+ names = {"-pct"},
+ hidden = true
+ )
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private Long deprecatedPrepareCheckInterval;
+
+ @CommandLine.Option(
+ names = {"--prepare-timeout"},
description = "Max time in SECONDS to wait for all OMs to be prepared",
- defaultValue = "300",
hidden = true
)
- private long prepareTimeOut;
+ private Long prepareTimeOut;
+
+ /** For backward compatibility. */
+ @CommandLine.Option(
+ names = {"-pt"},
+ hidden = true
+ )
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private Long deprecatedPrepareTimeOut;
@Override
public Void call() throws Exception {
@@ -100,8 +132,8 @@ public Void call() throws Exception {
}
private void execute(OzoneManagerProtocol client) throws Exception {
- long prepareTxnId = client.prepareOzoneManager(txnApplyWaitTimeSeconds,
- txnApplyCheckIntervalSeconds);
+ long prepareTxnId =
client.prepareOzoneManager(getTxnApplyWaitTimeSeconds(),
+ getTxnApplyCheckIntervalSeconds());
System.out.println("Ozone Manager Prepare Request successfully returned " +
"with Transaction Id : [" + prepareTxnId + "].");
@@ -109,8 +141,8 @@ private void execute(OzoneManagerProtocol client) throws
Exception {
Set<String> omHosts = getOmHostsFromConfig(
parent.getParent().getOzoneConf(), omServiceOption.getServiceID());
omHosts.forEach(h -> omPreparedStatusMap.put(h, false));
- Duration pTimeout = Duration.of(prepareTimeOut, ChronoUnit.SECONDS);
- Duration pInterval = Duration.of(prepareCheckInterval, ChronoUnit.SECONDS);
+ Duration pTimeout = Duration.of(getPrepareTimeOut(), ChronoUnit.SECONDS);
+ Duration pInterval = Duration.of(getPrepareCheckInterval(),
ChronoUnit.SECONDS);
System.out.println();
System.out.println("Checking individual OM instances for prepare request "
+
@@ -143,7 +175,7 @@ private void execute(OzoneManagerProtocol client) throws
Exception {
}
}
if (currentNumPreparedOms < expectedNumPreparedOms) {
- System.out.println("Waiting for " + prepareCheckInterval +
+ System.out.println("Waiting for " + getPrepareCheckInterval() +
" seconds before retrying...");
Thread.sleep(pInterval.toMillis());
}
@@ -169,4 +201,30 @@ private void execute(OzoneManagerProtocol client) throws
Exception {
}
}
+ private long getTxnApplyWaitTimeSeconds() {
+ return resolveOption(txnApplyWaitTimeSeconds,
deprecatedTxnApplyWaitTimeSeconds, 120L);
+ }
+
+ private long getTxnApplyCheckIntervalSeconds() {
+ return resolveOption(txnApplyCheckIntervalSeconds,
deprecatedTxnApplyCheckIntervalSeconds, 5L);
+ }
+
+ private long getPrepareCheckInterval() {
+ return resolveOption(prepareCheckInterval, deprecatedPrepareCheckInterval,
10L);
+ }
+
+ private long getPrepareTimeOut() {
+ return resolveOption(prepareTimeOut, deprecatedPrepareTimeOut, 300L);
+ }
+
+ private static long resolveOption(Long value, Long deprecatedValue, long
defaultValue) {
+ if (value != null) {
+ return value;
+ }
+ if (deprecatedValue != null) {
+ return deprecatedValue;
+ }
+ return defaultValue;
+ }
+
}
diff --git
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java
index eb09b246ccd..cb0f5634736 100644
---
a/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java
+++
b/hadoop-ozone/cli-admin/src/main/java/org/apache/hadoop/ozone/admin/scm/DecommissionScmSubcommand.java
@@ -39,23 +39,42 @@ public class DecommissionScmSubcommand extends
ScmSubcommand {
@CommandLine.ParentCommand
private ScmAdmin parent;
- @CommandLine.Option(names = {"-nodeid", "--nodeid"},
- description = "NodeID of the SCM to be decommissioned.",
- required = true)
- private String nodeId;
+ @CommandLine.ArgGroup(multiplicity = "1")
+ private NodeIdOptions nodeIdOptions;
@Override
public void execute(ScmClient scmClient) throws IOException {
- DecommissionScmResponseProto response = scmClient.decommissionScm(nodeId);
+ DecommissionScmResponseProto response = scmClient.decommissionScm(
+ nodeIdOptions.getNodeId());
if (!response.getSuccess()) {
- String errorMsg = "Error decommissioning Scm " + nodeId;
+ String errorMsg = "Error decommissioning Scm " +
nodeIdOptions.getNodeId();
if (response.hasErrorMsg()) {
errorMsg = errorMsg + ", " + response.getErrorMsg();
}
// Throwing exception to create non-zero exit code in case of failure.
throw new IOException(errorMsg);
} else {
- System.out.println("Decommissioned Scm " + nodeId);
+ System.out.println("Decommissioned Scm " + nodeIdOptions.getNodeId());
+ }
+ }
+
+ /** Options for SCM node ID. */
+ static class NodeIdOptions {
+ @CommandLine.Option(names = {"--nodeid"},
+ description = "NodeID of the SCM to be decommissioned.",
+ required = true)
+ private String nodeId;
+
+ /** For backward compatibility. */
+ @CommandLine.Option(names = {"-nodeid"},
+ hidden = true,
+ required = true)
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private String deprecatedNodeId;
+
+ String getNodeId() {
+ return nodeId != null ? nodeId : deprecatedNodeId;
}
}
}
diff --git
a/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/cli/TestDeprecatedCliOption.java
b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/cli/TestDeprecatedCliOption.java
new file mode 100644
index 00000000000..85e00cf8f46
--- /dev/null
+++
b/hadoop-ozone/cli-admin/src/test/java/org/apache/hadoop/hdds/cli/TestDeprecatedCliOption.java
@@ -0,0 +1,77 @@
+/*
+ * 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.hadoop.hdds.cli;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import org.apache.hadoop.hdds.scm.cli.pipeline.ListPipelinesSubcommand;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import picocli.CommandLine;
+
+/**
+ * Tests for deprecated CLI option warnings.
+ */
+public class TestDeprecatedCliOption {
+ private StringWriter err;
+
+ @BeforeEach
+ public void setup() {
+ err = new StringWriter();
+ }
+
+ private CommandLine createCommandLine(Object command) {
+ CommandLine cli = new CommandLine(command);
+ cli.setErr(new PrintWriter(err, true));
+ cli.setExecutionStrategy(parseResult -> {
+ DeprecatedCliOption.warnIfMatched(parseResult);
+ return CommandLine.ExitCode.OK;
+ });
+ return cli;
+ }
+
+ @Test
+ public void warnsForDeprecatedOption() {
+ createCommandLine(new ListPipelinesSubcommand())
+ .execute("-ffc", "THREE");
+
+ assertThat(err.toString())
+ .contains("WARNING: Option '-ffc' is deprecated")
+ .contains("--filter-by-factor");
+ }
+
+ @Test
+ public void warnsForMultipleDeprecatedOptions() {
+ createCommandLine(new ListPipelinesSubcommand())
+ .execute("-ffc", "THREE", "-fst", "OPEN");
+
+ assertThat(err.toString())
+ .contains("WARNING: Option '-ffc' is deprecated")
+ .contains("WARNING: Option '-fst' is deprecated");
+ }
+
+ @Test
+ public void doesNotWarnForLongOption() {
+ createCommandLine(new ListPipelinesSubcommand())
+ .execute("--filter-by-factor", "THREE");
+
+ assertThat(err.toString()).isEmpty();
+ }
+}
diff --git
a/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/Shell.java
b/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/Shell.java
index 5106497a8d1..267bf4eedba 100644
---
a/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/Shell.java
+++
b/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/Shell.java
@@ -19,6 +19,7 @@
import java.util.Collections;
import java.util.List;
+import org.apache.hadoop.hdds.cli.DeprecatedCliOption;
import org.apache.hadoop.hdds.cli.GenericCli;
import org.apache.hadoop.hdds.tracing.TracingUtil;
import org.apache.hadoop.ozone.om.exceptions.OMException;
@@ -89,6 +90,7 @@ protected List<String> interactiveWelcomeLines() {
}
private int execute(CommandLine.ParseResult parseResult) {
+ DeprecatedCliOption.warnIfMatched(parseResult);
name = spec.name();
if (parseResult.hasMatchedOption("--interactive") ||
parseResult.hasMatchedOption("--execute")) {
diff --git
a/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/acl/AclOption.java
b/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/acl/AclOption.java
index 5986c114ede..e15980ff805 100644
---
a/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/acl/AclOption.java
+++
b/hadoop-ozone/cli-shell/src/main/java/org/apache/hadoop/ozone/shell/acl/AclOption.java
@@ -31,24 +31,39 @@
*/
public class AclOption implements CommandLine.ITypeConverter<OzoneAcl> {
- @CommandLine.Option(names = {"--acls", "--acl", "-al", "-a"}, split = ",",
- required = true,
- converter = AclOption.class,
- description = "Comma separated ACL list:%n" +
- "Example: user:user2:a OR user:user1:rw,group:hadoop:a%n" +
- "r = READ, " +
- "w = WRITE, " +
- "c = CREATE, " +
- "d = DELETE, " +
- "l = LIST, " +
- "a = ALL, " +
- "n = NONE, " +
- "x = READ_ACL, " +
- "y = WRITE_ACL.")
- private OzoneAcl[] values;
+ @CommandLine.ArgGroup(multiplicity = "1")
+ private Exclusive exclusive = new Exclusive();
+
+ private static final class Exclusive {
+ @CommandLine.Option(names = {"--acls", "--acl", "-a"}, split = ",",
+ required = true,
+ converter = AclOption.class,
+ description = "Comma separated ACL list:%n" +
+ "Example: user:user2:a OR user:user1:rw,group:hadoop:a%n" +
+ "r = READ, " +
+ "w = WRITE, " +
+ "c = CREATE, " +
+ "d = DELETE, " +
+ "l = LIST, " +
+ "a = ALL, " +
+ "n = NONE, " +
+ "x = READ_ACL, " +
+ "y = WRITE_ACL.")
+ private OzoneAcl[] values;
+
+ /** For backward compatibility. */
+ @CommandLine.Option(names = {"-al"}, split = ",", hidden = true,
+ required = true, converter = AclOption.class)
+ @Deprecated
+ @SuppressWarnings("DeprecatedIsStillUsed")
+ private OzoneAcl[] deprecatedValues;
+ }
private List<OzoneAcl> getAclList() {
- return ImmutableList.copyOf(values);
+ OzoneAcl[] acls = exclusive.values != null
+ ? exclusive.values
+ : exclusive.deprecatedValues;
+ return ImmutableList.copyOf(acls);
}
public void addTo(OzoneObj obj, ObjectStore objectStore, PrintWriter out)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]