This is an automated email from the ASF dual-hosted git repository.
zixuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git
The following commit(s) were added to refs/heads/master by this push:
new 7644a027502 [improve][cli] PIP-343: Use picocli instead of jcommander
in bin/pulsar (#22288)
7644a027502 is described below
commit 7644a02750239af30ab707702d1a3f97596b08fd
Author: Zixuan Liu <[email protected]>
AuthorDate: Fri Mar 22 20:50:25 2024 +0800
[improve][cli] PIP-343: Use picocli instead of jcommander in bin/pulsar
(#22288)
Signed-off-by: Zixuan Liu <[email protected]>
---
pulsar-broker/pom.xml | 4 +-
.../org/apache/pulsar/PulsarBrokerStarter.java | 135 +++++++------
.../apache/pulsar/PulsarClusterMetadataSetup.java | 88 ++++-----
.../pulsar/PulsarClusterMetadataTeardown.java | 32 ++--
.../apache/pulsar/PulsarInitialNamespaceSetup.java | 33 ++--
.../java/org/apache/pulsar/PulsarStandalone.java | 39 ++--
.../org/apache/pulsar/PulsarStandaloneStarter.java | 18 +-
.../PulsarTransactionCoordinatorMetadataSetup.java | 32 ++--
.../org/apache/pulsar/PulsarVersionStarter.java | 22 ++-
.../org/apache/pulsar/broker/tools/BrokerTool.java | 34 ++--
.../pulsar/broker/tools/GenerateDocsCommand.java | 61 ++----
.../pulsar/broker/tools/LoadReportCommand.java | 78 +++-----
.../apache/pulsar/compaction/CompactorTool.java | 27 +--
.../pulsar/utils/auth/tokens/TokensCliUtils.java | 211 ++++++++++-----------
.../org/apache/pulsar/PulsarBrokerStarterTest.java | 109 +++++------
.../pulsar/PulsarClusterMetadataSetupTest.java | 12 +-
.../pulsar/PulsarClusterMetadataTeardownTest.java | 6 +-
.../pulsar/PulsarInitialNamespaceSetupTest.java | 6 +-
...sarTransactionCoordinatorMetadataSetupTest.java | 6 +-
.../apache/pulsar/PulsarVersionStarterTest.java | 6 +-
.../apache/pulsar/broker/tools/BrokerToolTest.java | 8 +-
.../pulsar/compaction/CompactorToolTest.java | 6 +-
.../utils/auth/tokens/TokensCliUtilsTest.java | 8 +-
pulsar-docs-tools/pom.xml | 4 +-
.../docs/tools/BaseGenerateDocumentation.java | 50 +++--
.../apache/pulsar/docs/tools/CmdGenerateDocs.java | 171 +++++++++--------
.../pulsar/docs/tools/CmdGenerateDocsTest.java | 96 ++++------
.../functions/worker/FunctionWorkerStarter.java | 25 +--
.../worker/FunctionWorkerStarterTest.java | 6 +-
pulsar-io/docs/pom.xml | 4 +-
pulsar-proxy/pom.xml | 4 +-
.../pulsar/proxy/server/ProxyServiceStarter.java | 34 ++--
.../websocket/service/WebSocketServiceStarter.java | 25 +--
.../service/WebSocketServiceStarterTest.java | 6 +-
34 files changed, 691 insertions(+), 715 deletions(-)
diff --git a/pulsar-broker/pom.xml b/pulsar-broker/pom.xml
index db839467ed2..8264459c6d9 100644
--- a/pulsar-broker/pom.xml
+++ b/pulsar-broker/pom.xml
@@ -322,8 +322,8 @@
</dependency>
<dependency>
- <groupId>com.beust</groupId>
- <artifactId>jcommander</artifactId>
+ <groupId>info.picocli</groupId>
+ <artifactId>picocli</artifactId>
</dependency>
<dependency>
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarBrokerStarter.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarBrokerStarter.java
index 1b24c806e62..bd5b5399b00 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarBrokerStarter.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarBrokerStarter.java
@@ -23,9 +23,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static
org.apache.pulsar.common.configuration.PulsarConfigurationLoader.create;
import static
org.apache.pulsar.common.configuration.PulsarConfigurationLoader.isComplete;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.Parameters;
import com.google.common.annotations.VisibleForTesting;
import java.io.File;
import java.io.FileInputStream;
@@ -34,10 +31,10 @@ import java.net.MalformedURLException;
import java.nio.file.Path;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.Optional;
+import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import org.apache.bookkeeper.common.component.ComponentStarter;
import org.apache.bookkeeper.common.component.LifecycleComponent;
@@ -63,7 +60,13 @@ import org.apache.pulsar.functions.worker.WorkerService;
import org.apache.pulsar.functions.worker.service.WorkerServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+import picocli.CommandLine.ArgGroup;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
+@Command(description = "broker", showDefaultValues = true, scope =
ScopeType.INHERIT)
public class PulsarBrokerStarter {
private static ServiceConfiguration loadConfig(String configFile) throws
Exception {
@@ -76,31 +79,30 @@ public class PulsarBrokerStarter {
}
@VisibleForTesting
- @Parameters(commandDescription = "Options")
private static class StarterArguments {
- @Parameter(names = {"-c", "--broker-conf"}, description =
"Configuration file for Broker")
+ @Option(names = {"-c", "--broker-conf"}, description = "Configuration
file for Broker")
private String brokerConfigFile = "conf/broker.conf";
- @Parameter(names = {"-rb", "--run-bookie"}, description = "Run Bookie
together with Broker")
+ @Option(names = {"-rb", "--run-bookie"}, description = "Run Bookie
together with Broker")
private boolean runBookie = false;
- @Parameter(names = {"-ra", "--run-bookie-autorecovery"},
+ @Option(names = {"-ra", "--run-bookie-autorecovery"},
description = "Run Bookie Autorecovery together with broker")
private boolean runBookieAutoRecovery = false;
- @Parameter(names = {"-bc", "--bookie-conf"}, description =
"Configuration file for Bookie")
+ @Option(names = {"-bc", "--bookie-conf"}, description = "Configuration
file for Bookie")
private String bookieConfigFile = "conf/bookkeeper.conf";
- @Parameter(names = {"-rfw", "--run-functions-worker"}, description =
"Run functions worker with Broker")
+ @Option(names = {"-rfw", "--run-functions-worker"}, description = "Run
functions worker with Broker")
private boolean runFunctionsWorker = false;
- @Parameter(names = {"-fwc", "--functions-worker-conf"}, description =
"Configuration file for Functions Worker")
+ @Option(names = {"-fwc", "--functions-worker-conf"}, description =
"Configuration file for Functions Worker")
private String fnWorkerConfigFile = "conf/functions_worker.yml";
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
@@ -125,43 +127,46 @@ public class PulsarBrokerStarter {
return bookieConf;
}
- private static boolean argsContains(String[] args, String arg) {
- return Arrays.asList(args).contains(arg);
- }
-
- private static class BrokerStarter {
- private final ServiceConfiguration brokerConfig;
- private final PulsarService pulsarService;
- private final LifecycleComponent bookieServer;
+ protected static class BrokerStarter implements Callable<Integer> {
+ private ServiceConfiguration brokerConfig;
+ private PulsarService pulsarService;
+ private LifecycleComponent bookieServer;
private volatile CompletableFuture<Void> bookieStartFuture;
- private final AutoRecoveryMain autoRecoveryMain;
- private final StatsProvider bookieStatsProvider;
- private final ServerConfiguration bookieConfig;
- private final WorkerService functionsWorkerService;
- private final WorkerConfig workerConfig;
-
- BrokerStarter(String[] args) throws Exception {
- StarterArguments starterArguments = new StarterArguments();
- JCommander jcommander = new JCommander(starterArguments);
- jcommander.setProgramName("PulsarBrokerStarter");
-
- // parse args by JCommander
- jcommander.parse(args);
+ private AutoRecoveryMain autoRecoveryMain;
+ private StatsProvider bookieStatsProvider;
+ private ServerConfiguration bookieConfig;
+ private WorkerService functionsWorkerService;
+ private WorkerConfig workerConfig;
+
+ private CommandLine commander;
+
+ @ArgGroup(exclusive = false)
+ private final StarterArguments starterArguments = new
StarterArguments();
+
+ BrokerStarter() {
+ commander = new CommandLine(this);
+ }
+
+ public int start(String[] args) {
+ return commander.execute(args);
+ }
+
+ public Integer call() throws Exception {
if (starterArguments.help) {
- jcommander.usage();
- System.exit(0);
+ commander.usage(commander.getOut());
+ return 0;
}
if (starterArguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("broker", starterArguments);
+ cmd.addCommand("broker", commander);
cmd.run(null);
- System.exit(0);
+ return 0;
}
// init broker config
if (isBlank(starterArguments.brokerConfigFile)) {
- jcommander.usage();
+ commander.usage(commander.getOut());
throw new IllegalArgumentException("Need to specify a
configuration file for broker");
} else {
final String filepath =
Path.of(starterArguments.brokerConfigFile)
@@ -209,20 +214,16 @@ public class PulsarBrokerStarter {
});
// if no argument to run bookie in cmd line, read from pulsar
config
- if (!argsContains(args, "-rb") && !argsContains(args,
"--run-bookie")) {
- checkState(!starterArguments.runBookie,
- "runBookie should be false if has no argument
specified");
+ if (!starterArguments.runBookie) {
starterArguments.runBookie =
brokerConfig.isEnableRunBookieTogether();
}
- if (!argsContains(args, "-ra") && !argsContains(args,
"--run-bookie-autorecovery")) {
- checkState(!starterArguments.runBookieAutoRecovery,
- "runBookieAutoRecovery should be false if has no
argument specified");
+ if (!starterArguments.runBookieAutoRecovery) {
starterArguments.runBookieAutoRecovery =
brokerConfig.isEnableRunBookieAutoRecoveryTogether();
}
if ((starterArguments.runBookie ||
starterArguments.runBookieAutoRecovery)
- && isBlank(starterArguments.bookieConfigFile)) {
- jcommander.usage();
+ && isBlank(starterArguments.bookieConfigFile)) {
+ commander.usage(commander.getOut());
throw new IllegalArgumentException("No configuration file for
Bookie");
}
@@ -257,9 +258,7 @@ public class PulsarBrokerStarter {
} else {
autoRecoveryMain = null;
}
- }
- public void start() throws Exception {
if (bookieStatsProvider != null) {
bookieStatsProvider.start(bookieConfig);
log.info("started bookieStatsProvider.");
@@ -275,15 +274,17 @@ public class PulsarBrokerStarter {
pulsarService.start();
log.info("PulsarService started.");
+ return 0;
}
public void join() throws InterruptedException {
- pulsarService.waitUntilClosed();
-
- try {
- pulsarService.close();
- } catch (PulsarServerException e) {
- throw new RuntimeException();
+ if (pulsarService != null) {
+ pulsarService.waitUntilClosed();
+ try {
+ pulsarService.close();
+ } catch (PulsarServerException e) {
+ throw new RuntimeException();
+ }
}
if (bookieStartFuture != null) {
@@ -301,8 +302,10 @@ public class PulsarBrokerStarter {
log.info("Shut down functions worker service successfully.");
}
- pulsarService.close();
- log.info("Shut down broker service successfully.");
+ if (pulsarService != null) {
+ pulsarService.close();
+ log.info("Shut down broker service successfully.");
+ }
if (bookieStatsProvider != null) {
bookieStatsProvider.stop();
@@ -317,6 +320,11 @@ public class PulsarBrokerStarter {
log.info("Shut down autoRecoveryMain successfully.");
}
}
+
+ @VisibleForTesting
+ CommandLine getCommander() {
+ return commander;
+ }
}
@@ -330,7 +338,7 @@ public class PulsarBrokerStarter {
exception.printStackTrace(System.out);
});
- BrokerStarter starter = new BrokerStarter(args);
+ BrokerStarter starter = new BrokerStarter();
Runtime.getRuntime().addShutdownHook(
new Thread(() -> {
try {
@@ -344,16 +352,21 @@ public class PulsarBrokerStarter {
);
PulsarByteBufAllocator.registerOOMListener(oomException -> {
- if (starter.brokerConfig.isSkipBrokerShutdownOnOOM()) {
+ if (starter.brokerConfig != null &&
starter.brokerConfig.isSkipBrokerShutdownOnOOM()) {
log.error("-- Received OOM exception: {}",
oomException.getMessage(), oomException);
} else {
log.error("-- Shutting down - Received OOM exception: {}",
oomException.getMessage(), oomException);
- starter.pulsarService.shutdownNow();
+ if (starter.pulsarService != null) {
+ starter.pulsarService.shutdownNow();
+ }
}
});
try {
- starter.start();
+ int start = starter.start(args);
+ if (start != 0) {
+ System.exit(start);
+ }
} catch (Throwable t) {
log.error("Failed to start pulsar service.", t);
ShutdownUtil.triggerImmediateForcefulShutdown();
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataSetup.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataSetup.java
index 96ebadb1ff4..854a5179161 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataSetup.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataSetup.java
@@ -19,8 +19,6 @@
package org.apache.pulsar;
import static org.apache.pulsar.common.policies.data.PoliciesUtil.getBundles;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import java.io.IOException;
import java.util.Collections;
import java.util.Optional;
@@ -58,6 +56,10 @@ import
org.apache.pulsar.metadata.impl.MetadataStoreFactoryImpl;
import org.apache.pulsar.metadata.impl.ZKMetadataStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* Setup the metadata for a new Pulsar cluster.
@@ -66,75 +68,76 @@ public class PulsarClusterMetadataSetup {
private static final int DEFAULT_BUNDLE_NUMBER = 16;
+ @Command(name = "initialize-cluster-metadata", showDefaultValues = true,
scope = ScopeType.INHERIT)
private static class Arguments {
- @Parameter(names = { "-c", "--cluster" }, description = "Cluster
name", required = true)
+ @Option(names = {"-c", "--cluster"}, description = "Cluster name",
required = true)
private String cluster;
- @Parameter(names = {"-bn",
+ @Option(names = {"-bn",
"--default-namespace-bundle-number"},
description = "The bundle numbers for the default
namespaces(public/default), default is 16",
required = false)
private int numberOfDefaultNamespaceBundles;
- @Parameter(names = { "-uw",
- "--web-service-url" }, description = "Web-service URL for new
cluster", required = true)
+ @Option(names = {"-uw",
+ "--web-service-url"}, description = "Web-service URL for new
cluster", required = true)
private String clusterWebServiceUrl;
- @Parameter(names = {"-tw",
+ @Option(names = {"-tw",
"--web-service-url-tls"},
description = "Web-service URL for new cluster with TLS
encryption", required = false)
private String clusterWebServiceUrlTls;
- @Parameter(names = { "-ub",
- "--broker-service-url" }, description = "Broker-service URL
for new cluster", required = false)
+ @Option(names = {"-ub",
+ "--broker-service-url"}, description = "Broker-service URL for
new cluster", required = false)
private String clusterBrokerServiceUrl;
- @Parameter(names = {"-tb",
+ @Option(names = {"-tb",
"--broker-service-url-tls"},
description = "Broker-service URL for new cluster with TLS
encryption", required = false)
private String clusterBrokerServiceUrlTls;
- @Parameter(names = { "-zk",
- "--zookeeper" }, description = "Local ZooKeeper quorum
connection string",
+ @Option(names = {"-zk",
+ "--zookeeper"}, description = "Local ZooKeeper quorum
connection string",
required = false,
hidden = true
- )
+ )
private String zookeeper;
- @Parameter(names = { "-md",
- "--metadata-store" }, description = "Metadata Store service
url. eg: zk:my-zk:2181", required = false)
+ @Option(names = {"-md",
+ "--metadata-store"}, description = "Metadata Store service
url. eg: zk:my-zk:2181", required = false)
private String metadataStoreUrl;
- @Parameter(names = {
- "--zookeeper-session-timeout-ms"
+ @Option(names = {
+ "--zookeeper-session-timeout-ms"
}, description = "Local zookeeper session timeout ms")
private int zkSessionTimeoutMillis = 30000;
- @Parameter(names = {"-gzk",
+ @Option(names = {"-gzk",
"--global-zookeeper"},
description = "Global ZooKeeper quorum connection string",
required = false, hidden = true)
private String globalZookeeper;
- @Parameter(names = {"-cs",
+ @Option(names = {"-cs",
"--configuration-store"}, description = "Configuration Store
connection string", hidden = true)
private String configurationStore;
- @Parameter(names = {"-cms",
+ @Option(names = {"-cms",
"--configuration-metadata-store"}, description =
"Configuration Metadata Store connection string",
hidden = false)
private String configurationMetadataStore;
- @Parameter(names = {
- "--initial-num-stream-storage-containers"
+ @Option(names = {
+ "--initial-num-stream-storage-containers"
}, description = "Num storage containers of BookKeeper stream storage")
private int numStreamStorageContainers = 16;
- @Parameter(names = {
+ @Option(names = {
"--initial-num-transaction-coordinators"
}, description = "Num transaction coordinators will assigned in
cluster")
private int numTransactionCoordinators = 16;
- @Parameter(names = {
+ @Option(names = {
"--existing-bk-metadata-service-uri"},
description = "The metadata service URI of the existing
BookKeeper cluster that you want to use")
private String existingBkMetadataServiceUri;
@@ -142,26 +145,26 @@ public class PulsarClusterMetadataSetup {
// Hide and marked as deprecated this flag because we use the new name
'--existing-bk-metadata-service-uri' to
// pass the service url. For compatibility of the command, we should
keep both to avoid the exceptions.
@Deprecated
- @Parameter(names = {
- "--bookkeeper-metadata-service-uri"},
- description = "The metadata service URI of the existing BookKeeper
cluster that you want to use",
- hidden = true)
+ @Option(names = {
+ "--bookkeeper-metadata-service-uri"},
+ description = "The metadata service URI of the existing
BookKeeper cluster that you want to use",
+ hidden = true)
private String bookieMetadataServiceUri;
- @Parameter(names = { "-pp",
- "--proxy-protocol" },
+ @Option(names = {"-pp",
+ "--proxy-protocol"},
description = "Proxy protocol to select type of routing at
proxy. Possible Values: [SNI]",
required = false)
private ProxyProtocol clusterProxyProtocol;
- @Parameter(names = { "-pu",
- "--proxy-url" }, description = "Proxy-server URL to which to
connect.", required = false)
+ @Option(names = {"-pu",
+ "--proxy-url"}, description = "Proxy-server URL to which to
connect.", required = false)
private String clusterProxyUrl;
- @Parameter(names = { "-h", "--help" }, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
@@ -197,28 +200,27 @@ public class PulsarClusterMetadataSetup {
System.setProperty("bookkeeper.metadata.client.drivers",
PulsarMetadataClientDriver.class.getName());
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(arguments);
try {
- jcommander.addObject(arguments);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
if (arguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("initialize-cluster-metadata", arguments);
+ cmd.addCommand("initialize-cluster-metadata", commander);
cmd.run(null);
return;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.getErr().println(e);
throw e;
}
if (arguments.metadataStoreUrl == null && arguments.zookeeper == null)
{
System.err.println("Metadata store address argument is required
(--metadata-store)");
- jcommander.usage();
+ commander.usage(commander.getOut());
System.exit(1);
}
@@ -226,7 +228,7 @@ public class PulsarClusterMetadataSetup {
&& arguments.globalZookeeper == null) {
System.err.println(
"Configuration metadata store address argument is required
(--configuration-metadata-store)");
- jcommander.usage();
+ commander.usage(commander.getOut());
System.exit(1);
}
@@ -234,7 +236,7 @@ public class PulsarClusterMetadataSetup {
|| arguments.globalZookeeper != null)) {
System.err.println("Configuration metadata store argument
(--configuration-metadata-store) "
+ "supersedes the deprecated (--global-zookeeper and
--configuration-store) argument");
- jcommander.usage();
+ commander.usage(commander.getOut());
System.exit(1);
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataTeardown.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataTeardown.java
index 01a9eedcca3..a2984a352b9 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataTeardown.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarClusterMetadataTeardown.java
@@ -18,8 +18,6 @@
*/
package org.apache.pulsar;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import com.google.protobuf.InvalidProtocolBufferException;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@@ -41,35 +39,40 @@ import org.apache.pulsar.metadata.api.MetadataStoreFactory;
import org.apache.pulsar.metadata.api.extended.MetadataStoreExtended;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* Teardown the metadata for a existed Pulsar cluster.
*/
public class PulsarClusterMetadataTeardown {
+ @Command(name = "delete-cluster-metadata", showDefaultValues = true, scope
= ScopeType.INHERIT)
private static class Arguments {
- @Parameter(names = { "-zk",
+ @Option(names = { "-zk",
"--zookeeper"}, description = "Local ZooKeeper quorum
connection string", required = true)
private String zookeeper;
- @Parameter(names = {
+ @Option(names = {
"--zookeeper-session-timeout-ms"
}, description = "Local zookeeper session timeout ms")
private int zkSessionTimeoutMillis = 30000;
- @Parameter(names = { "-c", "-cluster", "--cluster" }, description =
"Cluster name")
+ @Option(names = { "-c", "-cluster", "--cluster" }, description =
"Cluster name")
private String cluster;
- @Parameter(names = { "-cs", "--configuration-store" }, description =
"Configuration Store connection string")
+ @Option(names = { "-cs", "--configuration-store" }, description =
"Configuration Store connection string")
private String configurationStore;
- @Parameter(names = { "--bookkeeper-metadata-service-uri" },
description = "Metadata service uri of BookKeeper")
+ @Option(names = { "--bookkeeper-metadata-service-uri" }, description =
"Metadata service uri of BookKeeper")
private String bkMetadataServiceUri;
- @Parameter(names = { "-h", "--help" }, description = "Show this help
message")
+ @Option(names = { "-h", "--help" }, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
@@ -78,22 +81,21 @@ public class PulsarClusterMetadataTeardown {
public static void main(String[] args) throws Exception {
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(arguments);
try {
- jcommander.addObject(arguments);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
if (arguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("delete-cluster-metadata", arguments);
+ cmd.addCommand("delete-cluster-metadata", commander);
cmd.run(null);
return;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.getErr().println(e);
throw e;
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarInitialNamespaceSetup.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarInitialNamespaceSetup.java
index 22b38e59676..891aa1aa421 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarInitialNamespaceSetup.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarInitialNamespaceSetup.java
@@ -18,67 +18,70 @@
*/
package org.apache.pulsar;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import java.util.List;
import org.apache.pulsar.broker.resources.PulsarResources;
import org.apache.pulsar.common.naming.NamespaceName;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
import org.apache.pulsar.metadata.api.MetadataStore;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+import picocli.CommandLine.ScopeType;
/**
* Setup the initial namespace of the cluster without startup the Pulsar
broker.
*/
public class PulsarInitialNamespaceSetup {
+ @Command(name = "initialize-namespace", showDefaultValues = true, scope =
ScopeType.INHERIT)
private static class Arguments {
- @Parameter(names = { "-c", "--cluster" }, description = "Cluster
name", required = true)
+ @Option(names = { "-c", "--cluster" }, description = "Cluster name",
required = true)
private String cluster;
- @Parameter(names = { "-cs",
+ @Option(names = { "-cs",
"--configuration-store" }, description = "Configuration Store
connection string", required = true)
private String configurationStore;
- @Parameter(names = {
+ @Option(names = {
"--zookeeper-session-timeout-ms"
}, description = "Local zookeeper session timeout ms")
private int zkSessionTimeoutMillis = 30000;
- @Parameter(description = "tenant/namespace", required = true)
+ @Parameters(description = "tenant/namespace", arity = "1")
private List<String> namespaces;
- @Parameter(names = { "-h", "--help" }, description = "Show this help
message")
+ @Option(names = { "-h", "--help" }, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
public static int doMain(String[] args) throws Exception {
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(arguments);
try {
- jcommander.addObject(arguments);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return 0;
}
if (arguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("initialize-namespace", arguments);
+ cmd.addCommand("initialize-namespace", commander);
cmd.run(null);
return 0;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.getErr().println(e);
return 1;
}
if (arguments.configurationStore == null) {
System.err.println("Configuration store address argument is
required (--configuration-store)");
- jcommander.usage();
+ commander.usage(commander.getOut());
return 1;
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandalone.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandalone.java
index ba136e7c910..b785448cdac 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandalone.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandalone.java
@@ -20,7 +20,6 @@ package org.apache.pulsar;
import static org.apache.pulsar.common.naming.NamespaceName.SYSTEM_NAMESPACE;
import static
org.apache.pulsar.common.naming.SystemTopicNames.TRANSACTION_COORDINATOR_ASSIGN;
-import com.beust.jcommander.Parameter;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import io.netty.util.internal.PlatformDependent;
@@ -52,8 +51,12 @@ import org.apache.pulsar.metadata.bookkeeper.BKCluster;
import org.apache.pulsar.metadata.impl.ZKMetadataStore;
import
org.apache.pulsar.packages.management.storage.filesystem.FileSystemPackagesStorageProvider;
import org.apache.pulsar.zookeeper.LocalBookkeeperEnsemble;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
@Slf4j
+@Command(name = "standalone", showDefaultValues = true, scope =
ScopeType.INHERIT)
public class PulsarStandalone implements AutoCloseable {
private static final String PULSAR_STANDALONE_USE_ZOOKEEPER =
"PULSAR_STANDALONE_USE_ZOOKEEPER";
@@ -211,60 +214,60 @@ public class PulsarStandalone implements AutoCloseable {
return help;
}
- @Parameter(names = { "-c", "--config" }, description = "Configuration file
path")
+ @Option(names = { "-c", "--config" }, description = "Configuration file
path")
private String configFile;
- @Parameter(names = { "--wipe-data" }, description = "Clean up previous
ZK/BK data")
+ @Option(names = { "--wipe-data" }, description = "Clean up previous ZK/BK
data")
private boolean wipeData = false;
- @Parameter(names = { "--num-bookies" }, description = "Number of local
Bookies")
+ @Option(names = { "--num-bookies" }, description = "Number of local
Bookies")
private int numOfBk = 1;
- @Parameter(names = { "--metadata-dir" },
+ @Option(names = { "--metadata-dir" },
description = "Directory for storing metadata")
private String metadataDir = "data/metadata";
- @Parameter(names = { "--metadata-url" },
+ @Option(names = { "--metadata-url" },
description = "Metadata store url")
private String metadataStoreUrl = "";
- @Parameter(names = {"--zookeeper-port"}, description = "Local zookeeper's
port",
+ @Option(names = {"--zookeeper-port"}, description = "Local zookeeper's
port",
hidden = true)
private int zkPort = 2181;
- @Parameter(names = { "--bookkeeper-port" }, description = "Local bookies
base port")
+ @Option(names = { "--bookkeeper-port" }, description = "Local bookies base
port")
private int bkPort = 3181;
- @Parameter(names = { "--zookeeper-dir" },
+ @Option(names = { "--zookeeper-dir" },
description = "Local zooKeeper's data directory",
hidden = true)
private String zkDir = "data/standalone/zookeeper";
- @Parameter(names = { "--bookkeeper-dir" }, description = "Local bookies
base data directory")
+ @Option(names = { "--bookkeeper-dir" }, description = "Local bookies base
data directory")
private String bkDir = "data/standalone/bookkeeper";
- @Parameter(names = { "--no-broker" }, description = "Only start ZK and BK
services, no broker")
+ @Option(names = { "--no-broker" }, description = "Only start ZK and BK
services, no broker")
private boolean noBroker = false;
- @Parameter(names = { "--only-broker" }, description = "Only start Pulsar
broker service (no ZK, BK)")
+ @Option(names = { "--only-broker" }, description = "Only start Pulsar
broker service (no ZK, BK)")
private boolean onlyBroker = false;
- @Parameter(names = {"-nfw", "--no-functions-worker"}, description = "Run
functions worker with Broker")
+ @Option(names = {"-nfw", "--no-functions-worker"}, description = "Run
functions worker with Broker")
private boolean noFunctionsWorker = false;
- @Parameter(names = {"-fwc", "--functions-worker-conf"}, description =
"Configuration file for Functions Worker")
+ @Option(names = {"-fwc", "--functions-worker-conf"}, description =
"Configuration file for Functions Worker")
private String fnWorkerConfigFile = "conf/functions_worker.yml";
- @Parameter(names = {"-nss", "--no-stream-storage"}, description = "Disable
stream storage")
+ @Option(names = {"-nss", "--no-stream-storage"}, description = "Disable
stream storage")
private boolean noStreamStorage = false;
- @Parameter(names = { "--stream-storage-port" }, description = "Local
bookies stream storage port")
+ @Option(names = { "--stream-storage-port" }, description = "Local bookies
stream storage port")
private int streamStoragePort = 4181;
- @Parameter(names = { "-a", "--advertised-address" }, description =
"Standalone broker advertised address")
+ @Option(names = { "-a", "--advertised-address" }, description =
"Standalone broker advertised address")
private String advertisedAddress = null;
- @Parameter(names = { "-h", "--help" }, description = "Show this help
message")
+ @Option(names = { "-h", "--help" }, description = "Show this help message")
private boolean help = false;
private boolean usingNewDefaultsPIP117;
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandaloneStarter.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandaloneStarter.java
index e3a5e66d4b6..0ab731591da 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandaloneStarter.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarStandaloneStarter.java
@@ -19,8 +19,6 @@
package org.apache.pulsar;
import static org.apache.commons.lang3.StringUtils.isBlank;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import com.google.common.base.Strings;
import java.io.FileInputStream;
import java.util.Arrays;
@@ -30,23 +28,25 @@ import org.apache.logging.log4j.LogManager;
import org.apache.pulsar.broker.ServiceConfiguration;
import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
+import picocli.CommandLine;
+import picocli.CommandLine.Option;
@Slf4j
public class PulsarStandaloneStarter extends PulsarStandalone {
private static final String PULSAR_CONFIG_FILE = "pulsar.config.file";
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate docs")
private boolean generateDocs = false;
public PulsarStandaloneStarter(String[] args) throws Exception {
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(this);
+
try {
- jcommander.addObject(this);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (this.isHelp()) {
- jcommander.usage();
+ commander.usage(commander.getOut());
exit(0);
}
if (Strings.isNullOrEmpty(this.getConfigFile())) {
@@ -67,11 +67,11 @@ public class PulsarStandaloneStarter extends
PulsarStandalone {
if (this.isNoBroker() && this.isOnlyBroker()) {
log.error("Only one option is allowed between '--no-broker'
and '--only-broker'");
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.usage(commander.getOut());
log.error(e.getMessage());
exit(1);
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetup.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetup.java
index 6aedfe13a5b..57b67b01191 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetup.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetup.java
@@ -18,13 +18,15 @@
*/
package org.apache.pulsar;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import org.apache.pulsar.broker.resources.PulsarResources;
import org.apache.pulsar.common.naming.NamespaceName;
import org.apache.pulsar.common.naming.SystemTopicNames;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
import org.apache.pulsar.metadata.api.extended.MetadataStoreExtended;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* Set up the transaction coordinator metadata for a cluster, the setup will
create pulsar/system namespace and create
@@ -32,56 +34,56 @@ import
org.apache.pulsar.metadata.api.extended.MetadataStoreExtended;
*/
public class PulsarTransactionCoordinatorMetadataSetup {
+ @Command(name = "initialize-transaction-coordinator-metadata",
showDefaultValues = true, scope = ScopeType.INHERIT)
private static class Arguments {
- @Parameter(names = { "-c", "--cluster" }, description = "Cluster
name", required = true)
+ @Option(names = { "-c", "--cluster" }, description = "Cluster name",
required = true)
private String cluster;
- @Parameter(names = { "-cs",
+ @Option(names = { "-cs",
"--configuration-store" }, description = "Configuration Store
connection string", required = true)
private String configurationStore;
- @Parameter(names = {
+ @Option(names = {
"--zookeeper-session-timeout-ms"
}, description = "Local zookeeper session timeout ms")
private int zkSessionTimeoutMillis = 30000;
- @Parameter(names = {
+ @Option(names = {
"--initial-num-transaction-coordinators"
}, description = "Num transaction coordinators will assigned in
cluster")
private int numTransactionCoordinators = 16;
- @Parameter(names = { "-h", "--help" }, description = "Show this help
message")
+ @Option(names = { "-h", "--help" }, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
public static void main(String[] args) throws Exception {
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(arguments);
try {
- jcommander.addObject(arguments);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
if (arguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("initialize-transaction-coordinator-metadata",
arguments);
+ cmd.addCommand("initialize-transaction-coordinator-metadata",
commander);
cmd.run(null);
return;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.usage(commander.getOut());
throw e;
}
if (arguments.configurationStore == null) {
System.err.println("Configuration store address argument is
required (--configuration-store)");
- jcommander.usage();
+ commander.usage(commander.getOut());
System.exit(1);
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarVersionStarter.java
b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarVersionStarter.java
index 85a6c4156db..556b3ebfd84 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/PulsarVersionStarter.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/PulsarVersionStarter.java
@@ -18,41 +18,43 @@
*/
package org.apache.pulsar;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* Pulsar version entry point.
*/
public class PulsarVersionStarter {
+ @Command(name = "version", showDefaultValues = true, scope =
ScopeType.INHERIT)
private static class Arguments {
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
public static void main(String[] args) {
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(arguments);
try {
- jcommander.addObject(arguments);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
if (arguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("version", arguments);
+ cmd.addCommand("version", commander);
cmd.run(null);
return;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.getErr().println(e);
return;
}
System.out.println("Current version of pulsar is: " +
PulsarVersion.getVersion());
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/BrokerTool.java
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/BrokerTool.java
index 2a479ce4b90..980c92fee8a 100644
--- a/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/BrokerTool.java
+++ b/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/BrokerTool.java
@@ -18,30 +18,32 @@
*/
package org.apache.pulsar.broker.tools;
-import org.apache.bookkeeper.tools.framework.Cli;
-import org.apache.bookkeeper.tools.framework.CliFlags;
-import org.apache.bookkeeper.tools.framework.CliSpec;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* <b>broker-tool</b> is used for operations on a specific broker.
*/
+@Command(name = "broker-tool", description = "broker-tool is used for
operations on a specific broker",
+ showDefaultValues = true, scope = ScopeType.INHERIT)
public class BrokerTool {
- public static final String NAME = "broker-tool";
+ @Option(
+ names = {"-h", "--help"},
+ description = "Display help information",
+ usageHelp = true
+ )
+ public boolean help = false;
public static int run(String[] args) {
- CliSpec.Builder<CliFlags> specBuilder = CliSpec.newBuilder()
- .withName(NAME)
- .withUsage(NAME + " [flags] [commands]")
- .withDescription(NAME + " is used for operations on a specific
broker")
- .withFlags(new CliFlags())
- .withConsole(System.out)
- .addCommand(new LoadReportCommand())
- .addCommand(new GenerateDocsCommand());
-
- CliSpec<CliFlags> spec = specBuilder.build();
-
- return Cli.runCli(spec, args);
+ BrokerTool brokerTool = new BrokerTool();
+ CommandLine commander = new CommandLine(brokerTool);
+ GenerateDocsCommand generateDocsCommand = new
GenerateDocsCommand(commander);
+ commander.addSubcommand(LoadReportCommand.class)
+ .addSubcommand(generateDocsCommand);
+ return commander.execute(args);
}
public static void main(String[] args) {
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/GenerateDocsCommand.java
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/GenerateDocsCommand.java
index b020b4bfd8b..b0ed54bc53f 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/GenerateDocsCommand.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/GenerateDocsCommand.java
@@ -18,63 +18,42 @@
*/
package org.apache.pulsar.broker.tools;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import java.util.ArrayList;
import java.util.List;
-import org.apache.bookkeeper.tools.framework.Cli;
-import org.apache.bookkeeper.tools.framework.CliCommand;
-import org.apache.bookkeeper.tools.framework.CliFlags;
-import org.apache.bookkeeper.tools.framework.CliSpec;
+import java.util.concurrent.Callable;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
/**
* The command to generate documents of broker-tool.
*/
-public class GenerateDocsCommand extends CliCommand<CliFlags,
GenerateDocsCommand.GenDocFlags> {
+@Command(name = "gen-doc", description = "Generate documents of broker-tool")
+public class GenerateDocsCommand implements Callable<Integer> {
+ @Option(
+ names = {"-n", "--command-names"},
+ description = "List of command names",
+ arity = "0..1"
+ )
+ private List<String> commandNames = new ArrayList<>();
+ private final CommandLine rootCmd;
- private static final String NAME = "gen-doc";
- private static final String DESC = "Generate documents of broker-tool";
-
- /**
- * The CLI flags of gen docs command.
- */
- protected static class GenDocFlags extends CliFlags {
- @Parameter(
- names = {"-n", "--command-names"},
- description = "List of command names"
- )
- private List<String> commandNames = new ArrayList<>();
- }
-
- public GenerateDocsCommand() {
- super(CliSpec.<GenDocFlags>newBuilder()
- .withName(NAME)
- .withDescription(DESC)
- .withFlags(new GenDocFlags())
- .build());
+ public GenerateDocsCommand(CommandLine rootCmd) {
+ this.rootCmd = rootCmd;
}
@Override
- public Boolean apply(CliFlags globalFlags, String[] args) {
- CliSpec<GenDocFlags> newSpec = CliSpec.newBuilder(spec)
- .withRunFunc(cmdFlags -> apply(cmdFlags))
- .build();
- return 0 == Cli.runCli(newSpec, args);
- }
-
- private boolean apply(GenerateDocsCommand.GenDocFlags flags) {
+ public Integer call() throws Exception {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- JCommander commander = new JCommander();
- commander.addCommand("load-report", new LoadReportCommand.Flags());
- cmd.addCommand("broker-tool", commander);
- if (flags.commandNames.isEmpty()) {
+ cmd.addCommand("broker-tool", rootCmd);
+ if (commandNames.isEmpty()) {
cmd.run(null);
} else {
- ArrayList<String> args = new ArrayList(flags.commandNames);
+ ArrayList<String> args = new ArrayList(commandNames);
args.add(0, "-n");
cmd.run(args.toArray(new String[0]));
}
- return true;
+ return 0;
}
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/LoadReportCommand.java
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/LoadReportCommand.java
index 935e3a9f2fa..f1f4a917571 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/LoadReportCommand.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/broker/tools/LoadReportCommand.java
@@ -18,76 +18,48 @@
*/
package org.apache.pulsar.broker.tools;
-import com.beust.jcommander.Parameter;
import java.util.Optional;
+import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import org.apache.bookkeeper.tools.framework.Cli;
-import org.apache.bookkeeper.tools.framework.CliCommand;
-import org.apache.bookkeeper.tools.framework.CliFlags;
-import org.apache.bookkeeper.tools.framework.CliSpec;
import org.apache.commons.lang3.SystemUtils;
import org.apache.pulsar.broker.loadbalance.BrokerHostUsage;
import org.apache.pulsar.broker.loadbalance.impl.GenericBrokerHostUsageImpl;
import org.apache.pulsar.broker.loadbalance.impl.LinuxBrokerHostUsageImpl;
-import org.apache.pulsar.broker.tools.LoadReportCommand.Flags;
import org.apache.pulsar.client.util.ExecutorProvider;
import org.apache.pulsar.policies.data.loadbalancer.ResourceUsage;
import org.apache.pulsar.policies.data.loadbalancer.SystemResourceUsage;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Model.CommandSpec;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Spec;
/**
* The command to collect the load report of a specific broker.
*/
-public class LoadReportCommand extends CliCommand<CliFlags, Flags> {
+@Command(name = "load-report", description = "Collect the load report of a
specific broker")
+public class LoadReportCommand implements Callable<Integer> {
- private static final String NAME = "load-report";
- private static final String DESC = "Collect the load report of a specific
broker";
+ @Option(names = {"-i", "--interval-ms"}, description = "Interval to
collect load report, in milliseconds")
+ public int intervalMilliseconds = 100;
- /**
- * The CLI flags of load report command.
- */
- public static class Flags extends CliFlags {
-
- @Parameter(
- names = {
- "-i", "--interval-ms"
- },
- description = "Interval to collect load report, in milliseconds"
- )
- public int intervalMilliseconds = 100;
-
- }
-
- public LoadReportCommand() {
- super(CliSpec.<Flags>newBuilder()
- .withName(NAME)
- .withDescription(DESC)
- .withFlags(new Flags())
- .build());
- }
+ @Spec
+ CommandSpec spec;
@Override
- public Boolean apply(CliFlags globalFlags, String[] args) {
- CliSpec<Flags> newSpec = CliSpec.newBuilder(spec)
- .withRunFunc(cmdFlags -> apply(cmdFlags))
- .build();
- return 0 == Cli.runCli(newSpec, args);
- }
-
- private boolean apply(Flags flags) {
-
+ public Integer call() throws Exception {
boolean isLinux = SystemUtils.IS_OS_LINUX;
- spec.console().println("OS ARCH: " + SystemUtils.OS_ARCH);
- spec.console().println("OS NAME: " + SystemUtils.OS_NAME);
- spec.console().println("OS VERSION: " + SystemUtils.OS_VERSION);
- spec.console().println("Linux: " + isLinux);
- spec.console().println("--------------------------------------");
- spec.console().println();
- spec.console().println("Load Report Interval : " +
flags.intervalMilliseconds + " ms");
- spec.console().println();
- spec.console().println("--------------------------------------");
- spec.console().println();
+ spec.commandLine().getOut().println("OS ARCH: " + SystemUtils.OS_ARCH);
+ spec.commandLine().getOut().println("OS NAME: " + SystemUtils.OS_NAME);
+ spec.commandLine().getOut().println("OS VERSION: " +
SystemUtils.OS_VERSION);
+ spec.commandLine().getOut().println("Linux: " + isLinux);
+
spec.commandLine().getOut().println("--------------------------------------");
+ spec.commandLine().getOut().println();
+ spec.commandLine().getOut().println("Load Report Interval : " +
intervalMilliseconds + " ms");
+ spec.commandLine().getOut().println();
+
spec.commandLine().getOut().println("--------------------------------------");
+ spec.commandLine().getOut().println();
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor(
new ExecutorProvider.ExtendedThreadFactory("load-report"));
@@ -105,7 +77,7 @@ public class LoadReportCommand extends CliCommand<CliFlags,
Flags> {
hostUsage.calculateBrokerHostUsage();
try {
- TimeUnit.MILLISECONDS.sleep(flags.intervalMilliseconds);
+ TimeUnit.MILLISECONDS.sleep(intervalMilliseconds);
} catch (InterruptedException e) {
}
hostUsage.calculateBrokerHostUsage();
@@ -117,13 +89,13 @@ public class LoadReportCommand extends
CliCommand<CliFlags, Flags> {
printResourceUsage("Bandwidth In", usage.bandwidthIn);
printResourceUsage("Bandwidth Out", usage.bandwidthOut);
- return true;
+ return 0;
} finally {
scheduler.shutdown();
}
}
private void printResourceUsage(String name, ResourceUsage usage) {
- spec.console().println(name + " : usage = " + usage.usage + ", limit =
" + usage.limit);
+ spec.commandLine().getOut().println(name + " : usage = " + usage.usage
+ ", limit = " + usage.limit);
}
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/compaction/CompactorTool.java
b/pulsar-broker/src/main/java/org/apache/pulsar/compaction/CompactorTool.java
index 83ff7902281..f8cc95e6ac0 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/compaction/CompactorTool.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/compaction/CompactorTool.java
@@ -20,8 +20,6 @@ package org.apache.pulsar.compaction;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.netty.channel.EventLoopGroup;
import io.netty.util.concurrent.DefaultThreadFactory;
@@ -48,20 +46,25 @@ import
org.apache.pulsar.metadata.api.extended.MetadataStoreExtended;
import org.apache.pulsar.policies.data.loadbalancer.AdvertisedListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
+@Command(name = "compact-topic", showDefaultValues = true, scope =
ScopeType.INHERIT)
public class CompactorTool {
private static class Arguments {
- @Parameter(names = {"-c", "--broker-conf"}, description =
"Configuration file for Broker")
+ @Option(names = {"-c", "--broker-conf"}, description = "Configuration
file for Broker")
private String brokerConfigFile = "conf/broker.conf";
- @Parameter(names = {"-t", "--topic"}, description = "Topic to
compact", required = true)
+ @Option(names = {"-t", "--topic"}, description = "Topic to compact",
required = true)
private String topic;
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
@@ -107,13 +110,11 @@ public class CompactorTool {
public static void main(String[] args) throws Exception {
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander(arguments);
- jcommander.setProgramName("PulsarTopicCompactor");
-
- // parse args by JCommander
- jcommander.parse(args);
+ CommandLine commander = new CommandLine(arguments);
+ commander.setCommandName("PulsarTopicCompactor");
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
System.exit(0);
}
@@ -126,7 +127,7 @@ public class CompactorTool {
// init broker config
if (isBlank(arguments.brokerConfigFile)) {
- jcommander.usage();
+ commander.usage(commander.getOut());
throw new IllegalArgumentException("Need to specify a
configuration file for broker");
}
diff --git
a/pulsar-broker/src/main/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtils.java
b/pulsar-broker/src/main/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtils.java
index fa3a7bed8f6..4ae28b2c0bd 100644
---
a/pulsar-broker/src/main/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtils.java
+++
b/pulsar-broker/src/main/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtils.java
@@ -18,11 +18,7 @@
*/
package org.apache.pulsar.utils.auth.tokens;
-import com.beust.jcommander.DefaultUsageFormatter;
-import com.beust.jcommander.IUsageFormatter;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.Parameters;
+import com.google.common.annotations.VisibleForTesting;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwt;
import io.jsonwebtoken.Jwts;
@@ -31,7 +27,6 @@ import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import java.io.BufferedReader;
-import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -40,34 +35,42 @@ import java.security.Key;
import java.security.KeyPair;
import java.util.Date;
import java.util.Optional;
+import java.util.concurrent.Callable;
import javax.crypto.SecretKey;
import lombok.Cleanup;
import org.apache.pulsar.broker.authentication.utils.AuthTokenUtils;
-import org.apache.pulsar.cli.converters.TimeUnitToSecondsConverter;
+import org.apache.pulsar.cli.converters.picocli.TimeUnitToSecondsConverter;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+import picocli.CommandLine.ScopeType;
+@Command(name = "tokens", showDefaultValues = true, scope = ScopeType.INHERIT)
public class TokensCliUtils {
- public static class Arguments {
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
- private boolean help = false;
- }
+ private final CommandLine commander;
+
+ @Option(names = {"-h", "--help"}, usageHelp = true, description = "Show
this help message")
+ private boolean help;
- @Parameters(commandDescription = "Create a new secret key")
- public static class CommandCreateSecretKey {
- @Parameter(names = {"-a",
+ @Command(description = "Create a new secret key")
+ public static class CommandCreateSecretKey implements Callable<Integer> {
+ @Option(names = {"-a",
"--signature-algorithm"}, description = "The signature
algorithm for the new secret key.")
SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
- @Parameter(names = {"-o",
+ @Option(names = {"-o",
"--output"}, description = "Write the secret key to a file
instead of stdout")
String outputFile;
- @Parameter(names = {
+ @Option(names = {
"-b", "--base64"}, description = "Encode the key in base64")
boolean base64 = false;
- public void run() throws IOException {
+ @Override
+ public Integer call() throws Exception {
SecretKey secretKey = AuthTokenUtils.createSecretKey(algorithm);
byte[] encoded = secretKey.getEncoded();
@@ -80,67 +83,73 @@ public class TokensCliUtils {
} else {
System.out.write(encoded);
}
+
+ return 0;
}
}
- @Parameters(commandDescription = "Create a new or pair of keys
public/private")
- public static class CommandCreateKeyPair {
- @Parameter(names = {"-a",
+ @Command(description = "Create a new or pair of keys public/private")
+ public static class CommandCreateKeyPair implements Callable<Integer> {
+ @Option(names = {"-a",
"--signature-algorithm"}, description = "The signature
algorithm for the new key pair.")
SignatureAlgorithm algorithm = SignatureAlgorithm.RS256;
- @Parameter(names = {
+ @Option(names = {
"--output-private-key"}, description = "File where to write
the private key", required = true)
String privateKeyFile;
- @Parameter(names = {
+ @Option(names = {
"--output-public-key"}, description = "File where to write the
public key", required = true)
String publicKeyFile;
- public void run() throws IOException {
+ @Override
+ public Integer call() throws Exception {
KeyPair pair = Keys.keyPairFor(algorithm);
Files.write(Paths.get(publicKeyFile),
pair.getPublic().getEncoded());
Files.write(Paths.get(privateKeyFile),
pair.getPrivate().getEncoded());
+
+ return 0;
}
}
- @Parameters(commandDescription = "Create a new token")
- public static class CommandCreateToken {
- @Parameter(names = {"-a",
+ @Command(description = "Create a new token")
+ public static class CommandCreateToken implements Callable<Integer> {
+ @Option(names = {"-a",
"--signature-algorithm"}, description = "The signature
algorithm for the new key pair.")
SignatureAlgorithm algorithm = SignatureAlgorithm.RS256;
- @Parameter(names = {"-s",
+ @Option(names = {"-s",
"--subject"},
description = "Specify the 'subject' or 'principal' associate
with this token", required = true)
private String subject;
- @Parameter(names = {"-e",
+ @Option(names = {"-e",
"--expiry-time"},
description = "Relative expiry time for the token (eg: 1h, 3d,
10y)."
+ " (m=minutes) Default: no expiration",
- converter = TimeUnitToSecondsConverter.class)
+ converter = TimeUnitToSecondsConverter.class)
private Long expiryTime = null;
- @Parameter(names = {"-sk",
+ @Option(names = {"-sk",
"--secret-key"},
description = "Pass the secret key for signing the token. This
can either be: data:, file:, etc..")
private String secretKey;
- @Parameter(names = {"-pk",
+ @Option(names = {"-pk",
"--private-key"},
description = "Pass the private key for signing the token.
This can either be: data:, file:, etc..")
private String privateKey;
- public void run() throws Exception {
+ @Override
+ public Integer call() throws Exception {
if (secretKey == null && privateKey == null) {
System.err.println(
"Either --secret-key or --private-key needs to be
passed for signing a token");
- System.exit(1);
+ return 1;
} else if (secretKey != null && privateKey != null) {
System.err.println(
"Only one of --secret-key and --private-key needs to
be passed for signing a token");
- System.exit(1);
+ return 1;
}
Key signingKey;
@@ -159,27 +168,30 @@ public class TokensCliUtils {
String token = AuthTokenUtils.createToken(signingKey, subject,
optExpiryTime);
System.out.println(token);
+
+ return 0;
}
}
- @Parameters(commandDescription = "Show the content of token")
- public static class CommandShowToken {
+ @Command(description = "Show the content of token")
+ public static class CommandShowToken implements Callable<Integer> {
- @Parameter(description = "The token string", arity = 1)
- private java.util.List<String> args;
+ @Parameters(description = "The token string", arity = "0..1")
+ private String args;
- @Parameter(names = {"-i",
+ @Option(names = {"-i",
"--stdin"}, description = "Read token from standard input")
private Boolean stdin = false;
- @Parameter(names = {"-f",
+ @Option(names = {"-f",
"--token-file"}, description = "Read token from a file")
private String tokenFile;
- public void run() throws Exception {
+ @Override
+ public Integer call() throws Exception {
String token;
if (args != null) {
- token = args.get(0);
+ token = args;
} else if (stdin) {
@Cleanup
BufferedReader r = new BufferedReader(new
InputStreamReader(System.in));
@@ -192,59 +204,61 @@ public class TokensCliUtils {
System.err.println(
"Token needs to be either passed as an argument or
through `--stdin`,"
+ " `--token-file` or by the `TOKEN`
environment variable");
- System.exit(1);
- return;
+ return 1;
}
String[] parts = token.split("\\.");
System.out.println(new
String(Decoders.BASE64URL.decode(parts[0])));
System.out.println("---");
System.out.println(new
String(Decoders.BASE64URL.decode(parts[1])));
+
+ return 0;
}
}
- @Parameters(commandDescription = "Validate a token against a key")
- public static class CommandValidateToken {
+ @Command(description = "Validate a token against a key")
+ public static class CommandValidateToken implements Callable<Integer> {
- @Parameter(names = {"-a",
+ @Option(names = {"-a",
"--signature-algorithm"}, description = "The signature
algorithm for the key pair if using public key.")
SignatureAlgorithm algorithm = SignatureAlgorithm.RS256;
- @Parameter(description = "The token string", arity = 1)
- private java.util.List<String> args;
+ @Parameters(description = "The token string", arity = "0..1")
+ private String args;
- @Parameter(names = {"-i",
+ @Option(names = {"-i",
"--stdin"}, description = "Read token from standard input")
private Boolean stdin = false;
- @Parameter(names = {"-f",
+ @Option(names = {"-f",
"--token-file"}, description = "Read token from a file")
private String tokenFile;
- @Parameter(names = {"-sk",
+ @Option(names = {"-sk",
"--secret-key"},
description = "Pass the secret key for validating the token.
This can either be: data:, file:, etc..")
private String secretKey;
- @Parameter(names = {"-pk",
+ @Option(names = {"-pk",
"--public-key"},
description = "Pass the public key for validating the token.
This can either be: data:, file:, etc..")
private String publicKey;
- public void run() throws Exception {
+ @Override
+ public Integer call() throws Exception {
if (secretKey == null && publicKey == null) {
System.err.println(
"Either --secret-key or --public-key needs to be
passed for signing a token");
- System.exit(1);
+ return 1;
} else if (secretKey != null && publicKey != null) {
System.err.println(
"Only one of --secret-key and --public-key needs to be
passed for signing a token");
- System.exit(1);
+ return 1;
}
String token;
if (args != null) {
- token = args.get(0);
+ token = args;
} else if (stdin) {
@Cleanup
BufferedReader r = new BufferedReader(new
InputStreamReader(System.in));
@@ -257,8 +271,7 @@ public class TokensCliUtils {
System.err.println(
"Token needs to be either passed as an argument or
through `--stdin`,"
+ " `--token-file` or by the `TOKEN`
environment variable");
- System.exit(1);
- return;
+ return 1;
}
Key validationKey;
@@ -279,64 +292,46 @@ public class TokensCliUtils {
.parse(token);
System.out.println(jwt.getBody());
+ return 0;
}
}
- public static void main(String[] args) throws Exception {
- Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander(arguments);
- IUsageFormatter usageFormatter = new DefaultUsageFormatter(jcommander);
-
- CommandCreateSecretKey commandCreateSecretKey = new
CommandCreateSecretKey();
- jcommander.addCommand("create-secret-key", commandCreateSecretKey);
-
- CommandCreateKeyPair commandCreateKeyPair = new CommandCreateKeyPair();
- jcommander.addCommand("create-key-pair", commandCreateKeyPair);
-
- CommandCreateToken commandCreateToken = new CommandCreateToken();
- jcommander.addCommand("create", commandCreateToken);
-
- CommandShowToken commandShowToken = new CommandShowToken();
- jcommander.addCommand("show", commandShowToken);
+ @Command
+ static class GenDoc implements Callable<Integer> {
- CommandValidateToken commandValidateToken = new CommandValidateToken();
- jcommander.addCommand("validate", commandValidateToken);
+ private final CommandLine rootCmd;
- jcommander.addCommand("gen-doc", new Object());
-
- try {
- jcommander.parse(args);
-
- if (arguments.help || jcommander.getParsedCommand() == null) {
- jcommander.usage();
- System.exit(1);
- }
- } catch (Exception e) {
- System.err.println(e);
- String chosenCommand = jcommander.getParsedCommand();
- usageFormatter.usage(chosenCommand);
- System.exit(1);
+ public GenDoc(CommandLine rootCmd) {
+ this.rootCmd = rootCmd;
}
- String cmd = jcommander.getParsedCommand();
-
- if (cmd.equals("create-secret-key")) {
- commandCreateSecretKey.run();
- } else if (cmd.equals("create-key-pair")) {
- commandCreateKeyPair.run();
- } else if (cmd.equals("create")) {
- commandCreateToken.run();
- } else if (cmd.equals("show")) {
- commandShowToken.run();
- } else if (cmd.equals("validate")) {
- commandValidateToken.run();
- } else if (cmd.equals("gen-doc")) {
+ @Override
+ public Integer call() throws Exception {
CmdGenerateDocs genDocCmd = new CmdGenerateDocs("pulsar");
- genDocCmd.addCommand("tokens", jcommander);
+ genDocCmd.addCommand("tokens", rootCmd);
genDocCmd.run(null);
- } else {
- System.err.println("Invalid command: " + cmd);
- System.exit(1);
+
+ return 0;
}
}
+
+ TokensCliUtils() {
+ commander = new CommandLine(this);
+ commander.addSubcommand("create-secret-key",
CommandCreateSecretKey.class);
+ commander.addSubcommand("create-key-pair", CommandCreateKeyPair.class);
+ commander.addSubcommand("create", CommandCreateToken.class);
+ commander.addSubcommand("show", CommandShowToken.class);
+ commander.addSubcommand("validate", CommandValidateToken.class);
+ commander.addSubcommand("gen-doc", new GenDoc(commander));
+ }
+
+ @VisibleForTesting
+ int execute(String[] args) {
+ return commander.execute(args);
+ }
+
+ public static void main(String[] args) throws Exception {
+ TokensCliUtils tokensCliUtils = new TokensCliUtils();
+ System.exit(tokensCliUtils.execute(args));
+ }
}
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarBrokerStarterTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarBrokerStarterTest.java
index 1bc3bd26f12..4c05a991b7f 100644
--- a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarBrokerStarterTest.java
+++ b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarBrokerStarterTest.java
@@ -22,7 +22,6 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-import com.beust.jcommander.Parameter;
import com.google.common.collect.Sets;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -32,14 +31,16 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
+import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
+import lombok.Cleanup;
+import org.apache.pulsar.PulsarBrokerStarter.BrokerStarter;
import org.apache.pulsar.broker.ServiceConfiguration;
-import org.apache.pulsar.docs.tools.CmdGenerateDocs;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
@Test(groups = "broker")
public class PulsarBrokerStarterTest {
@@ -282,12 +283,14 @@ public class PulsarBrokerStarterTest {
*/
@Test
public void testMainWithNoArgument() throws Exception {
- try {
- PulsarBrokerStarter.main(new String[0]);
- fail("No argument to main should've raised FileNotFoundException
for no broker config!");
- } catch (FileNotFoundException e) {
- // code should reach here.
- }
+ BrokerStarter brokerStarter = new BrokerStarter();
+ @Cleanup
+ StringWriter err = new StringWriter();
+ @Cleanup
+ PrintWriter printWriter = new PrintWriter(err);
+ brokerStarter.getCommander().setErr(printWriter);
+ assertEquals(brokerStarter.start(new String[0]), 1);
+ assertTrue(err.toString().contains("FileNotFoundException"));
}
/**
@@ -296,16 +299,16 @@ public class PulsarBrokerStarterTest {
*/
@Test
public void testMainRunBookieAndAutoRecoveryNoConfig() throws Exception {
- try {
- File testConfigFile = createValidBrokerConfigFile();
- String[] args = {"-c", testConfigFile.getAbsolutePath(), "-rb",
"-ra", "-bc", ""};
- PulsarBrokerStarter.main(args);
- fail("No Config file for bookie auto recovery should've raised
IllegalArgumentException!");
- } catch (IllegalArgumentException e) {
- // code should reach here.
- e.printStackTrace();
- assertEquals(e.getMessage(), "No configuration file for Bookie");
- }
+ File testConfigFile = createValidBrokerConfigFile();
+ String[] args = {"-c", testConfigFile.getAbsolutePath(), "-rb", "-ra",
"-bc", ""};
+ BrokerStarter starter = new BrokerStarter();
+ @Cleanup
+ StringWriter err = new StringWriter();
+ @Cleanup
+ PrintWriter printWriter = new PrintWriter(err);
+ starter.getCommander().setErr(printWriter);
+ assertEquals(starter.start(args), 1);
+ assertTrue(err.toString().contains("No configuration file for
Bookie"));
}
/**
@@ -314,15 +317,16 @@ public class PulsarBrokerStarterTest {
*/
@Test
public void testMainRunBookieRecoveryNoConfig() throws Exception {
- try {
- File testConfigFile = createValidBrokerConfigFile();
- String[] args = {"-c", testConfigFile.getAbsolutePath(), "-ra",
"-bc", ""};
- PulsarBrokerStarter.main(args);
- fail("No Config file for bookie auto recovery should've raised
IllegalArgumentException!");
- } catch (IllegalArgumentException e) {
- // code should reach here.
- assertEquals(e.getMessage(), "No configuration file for Bookie");
- }
+ File testConfigFile = createValidBrokerConfigFile();
+ String[] args = {"-c", testConfigFile.getAbsolutePath(), "-ra", "-bc",
""};
+ BrokerStarter starter = new BrokerStarter();
+ @Cleanup
+ StringWriter err = new StringWriter();
+ @Cleanup
+ PrintWriter printWriter = new PrintWriter(err);
+ starter.getCommander().setErr(printWriter);
+ assertEquals(starter.start(args), 1);
+ assertTrue(err.toString().contains("No configuration file for
Bookie"));
}
/**
@@ -330,15 +334,16 @@ public class PulsarBrokerStarterTest {
*/
@Test
public void testMainRunBookieNoConfig() throws Exception {
- try {
- File testConfigFile = createValidBrokerConfigFile();
- String[] args = {"-c", testConfigFile.getAbsolutePath(), "-rb",
"-bc", ""};
- PulsarBrokerStarter.main(args);
- fail("No Config file for bookie should've raised
IllegalArgumentException!");
- } catch (IllegalArgumentException e) {
- // code should reach here
- assertEquals(e.getMessage(), "No configuration file for Bookie");
- }
+ File testConfigFile = createValidBrokerConfigFile();
+ String[] args = {"-c", testConfigFile.getAbsolutePath(), "-rb", "-bc",
""};
+ BrokerStarter starter = new BrokerStarter();
+ @Cleanup
+ StringWriter err = new StringWriter();
+ @Cleanup
+ PrintWriter printWriter = new PrintWriter(err);
+ starter.getCommander().setErr(printWriter);
+ assertEquals(starter.start(args), 1);
+ assertTrue(err.toString().contains("No configuration file for
Bookie"));
}
/**
@@ -346,14 +351,16 @@ public class PulsarBrokerStarterTest {
*/
@Test
public void testMainEnableRunBookieThroughBrokerConfig() throws Exception {
- try {
- File testConfigFile = createValidBrokerConfigFile();
- String[] args = {"-c", testConfigFile.getAbsolutePath()};
- PulsarBrokerStarter.main(args);
- fail("No argument to main should've raised
IllegalArgumentException for no bookie config!");
- } catch (IllegalArgumentException e) {
- // code should reach here.
- }
+ File testConfigFile = createValidBrokerConfigFile();
+ String[] args = {"-c", testConfigFile.getAbsolutePath()};
+ BrokerStarter starter = new BrokerStarter();
+ @Cleanup
+ StringWriter err = new StringWriter();
+ @Cleanup
+ PrintWriter printWriter = new PrintWriter(err);
+ starter.getCommander().setErr(printWriter);
+ assertEquals(starter.start(args), 1);
+ assertTrue(err.toString().contains("IllegalArgumentException"));
}
@Test
@@ -364,21 +371,15 @@ public class PulsarBrokerStarterTest {
System.setOut(new PrintStream(baoStream));
Class argumentsClass =
Class.forName("org.apache.pulsar.PulsarBrokerStarter$StarterArguments");
- Constructor constructor = argumentsClass.getDeclaredConstructor();
- constructor.setAccessible(true);
- Object obj = constructor.newInstance();
-
- CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("broker", obj);
- cmd.run(null);
+ PulsarBrokerStarter.main(new String[]{"-g"});
String message = baoStream.toString();
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
String nameStr = Arrays.asList(names).toString();
nameStr = nameStr.substring(1, nameStr.length() - 1);
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataSetupTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataSetupTest.java
index 6196f666988..710e040f8df 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataSetupTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataSetupTest.java
@@ -19,13 +19,15 @@
package org.apache.pulsar;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
+import lombok.extern.slf4j.Slf4j;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
+@Slf4j
public class PulsarClusterMetadataSetupTest {
@Test
public void testMainGenerateDocs() throws Exception {
@@ -43,16 +45,16 @@ public class PulsarClusterMetadataSetupTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
- if (names.length == 0) {
+ if (names.length == 0 || fieldAnno.hidden()) {
continue;
}
String nameStr = Arrays.asList(names).toString();
nameStr = nameStr.substring(1, nameStr.length() - 1);
- assertTrue(message.indexOf(nameStr) > 0);
+ assertTrue(message.indexOf(nameStr) > 0, nameStr);
}
}
} finally {
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataTeardownTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataTeardownTest.java
index f6a388dac76..95d12f378c5 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataTeardownTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarClusterMetadataTeardownTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
public class PulsarClusterMetadataTeardownTest {
@Test
@@ -43,9 +43,9 @@ public class PulsarClusterMetadataTeardownTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
if (names.length == 0) {
continue;
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarInitialNamespaceSetupTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarInitialNamespaceSetupTest.java
index c1ad8c621c4..0c6ba05b460 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarInitialNamespaceSetupTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarInitialNamespaceSetupTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
public class PulsarInitialNamespaceSetupTest {
@Test
@@ -43,9 +43,9 @@ public class PulsarInitialNamespaceSetupTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
if (names.length == 0) {
continue;
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetupTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetupTest.java
index 70c7c7bd62e..6ff055385b2 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetupTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarTransactionCoordinatorMetadataSetupTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
public class PulsarTransactionCoordinatorMetadataSetupTest {
@Test
@@ -43,9 +43,9 @@ public class PulsarTransactionCoordinatorMetadataSetupTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
if (names.length == 0) {
continue;
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarVersionStarterTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarVersionStarterTest.java
index 219e3b80cd3..b921c3d3843 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/PulsarVersionStarterTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/PulsarVersionStarterTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
public class PulsarVersionStarterTest {
@Test
@@ -43,9 +43,9 @@ public class PulsarVersionStarterTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
if (names.length == 0) {
continue;
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/tools/BrokerToolTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/tools/BrokerToolTest.java
index ad2cf7784eb..063c041f2e0 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/broker/tools/BrokerToolTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/broker/tools/BrokerToolTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar.broker.tools;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
/**
* Broker Tool Tests.
@@ -47,12 +47,12 @@ public class BrokerToolTest {
String message = baoStream.toString();
- Class argumentsClass =
Class.forName("org.apache.pulsar.broker.tools.LoadReportCommand$Flags");
+ Class argumentsClass =
Class.forName("org.apache.pulsar.broker.tools.LoadReportCommand");
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
String nameStr = Arrays.asList(names).toString();
nameStr = nameStr.substring(1, nameStr.length() - 1);
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/compaction/CompactorToolTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/compaction/CompactorToolTest.java
index fb8d6566d9a..72b8628caca 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/compaction/CompactorToolTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/compaction/CompactorToolTest.java
@@ -22,7 +22,6 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
@@ -37,6 +36,7 @@ import org.apache.pulsar.client.api.PulsarClient;
import org.apache.pulsar.client.api.PulsarClientException;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
/**
* CompactorTool Tests.
@@ -69,9 +69,9 @@ public class CompactorToolTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
String nameStr = Arrays.asList(names).toString();
nameStr = nameStr.substring(1, nameStr.length() - 1);
diff --git
a/pulsar-broker/src/test/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtilsTest.java
b/pulsar-broker/src/test/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtilsTest.java
index a488e4d9584..d5dc259438e 100644
---
a/pulsar-broker/src/test/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtilsTest.java
+++
b/pulsar-broker/src/test/java/org/apache/pulsar/utils/auth/tokens/TokensCliUtilsTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar.utils.auth.tokens;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
/**
* TokensCliUtils Tests.
@@ -43,7 +43,7 @@ public class TokensCliUtilsTest {
ByteArrayOutputStream baoStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(baoStream));
- TokensCliUtils.main(new String[]{"gen-doc"});
+ new TokensCliUtils().execute(new String[]{"gen-doc"});
String message = baoStream.toString();
@@ -68,9 +68,9 @@ public class TokensCliUtilsTest {
Class argumentsClass = Class.forName(className);
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno = field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
if (names.length < 1) {
continue;
diff --git a/pulsar-docs-tools/pom.xml b/pulsar-docs-tools/pom.xml
index 40bddfde532..e275d128fb0 100644
--- a/pulsar-docs-tools/pom.xml
+++ b/pulsar-docs-tools/pom.xml
@@ -43,8 +43,8 @@
<artifactId>swagger-core</artifactId>
</dependency>
<dependency>
- <groupId>com.beust</groupId>
- <artifactId>jcommander</artifactId>
+ <groupId>info.picocli</groupId>
+ <artifactId>picocli</artifactId>
</dependency>
</dependencies>
diff --git
a/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/BaseGenerateDocumentation.java
b/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/BaseGenerateDocumentation.java
index db6178a7fda..ff474d98edc 100644
---
a/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/BaseGenerateDocumentation.java
+++
b/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/BaseGenerateDocumentation.java
@@ -18,8 +18,6 @@
*/
package org.apache.pulsar.docs.tools;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.lang.annotation.Annotation;
@@ -28,6 +26,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
+import java.util.concurrent.Callable;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.SneakyThrows;
@@ -35,49 +34,44 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.commons.lang3.tuple.Pair;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
@Slf4j
-public abstract class BaseGenerateDocumentation {
+@Command(name = "gen-doc", showDefaultValues = true, scope = ScopeType.INHERIT)
+public abstract class BaseGenerateDocumentation implements Callable<Integer> {
- JCommander jcommander;
+ CommandLine commander;
- @Parameter(names = {"-c", "--class-names"}, description =
+ @Option(names = {"-c", "--class-names"}, description =
"List of class names, generate documentation based on the
annotations in the Class")
private List<String> classNames = new ArrayList<>();
- @Parameter(names = {"-h", "--help"}, help = true, description = "Show this
help.")
+ @Option(names = {"-h", "--help"}, usageHelp = true, description = "Show
this help.")
boolean help;
public BaseGenerateDocumentation() {
- jcommander = new JCommander();
- jcommander.setProgramName("pulsar-generateDocumentation");
- jcommander.addObject(this);
+ commander = new CommandLine(this);
}
- public boolean run(String[] args) throws Exception {
- if (args.length == 0) {
- jcommander.usage();
- return false;
- }
-
- if (help) {
- jcommander.usage();
- return true;
- }
-
- try {
- jcommander.parse(Arrays.copyOfRange(args, 0, args.length));
- } catch (Exception e) {
- System.err.println(e.getMessage());
- jcommander.usage();
- return false;
- }
+ @Override
+ public Integer call() throws Exception {
if (classNames != null) {
for (String className : classNames) {
System.out.println(generateDocumentByClassName(className));
}
}
- return true;
+ return 0;
+ }
+
+ public boolean run(String[] args) throws Exception {
+ if (args.length == 0) {
+ commander.usage(commander.getOut());
+ return false;
+ }
+ return commander.execute(args) == 0;
}
protected abstract String generateDocumentByClassName(String className)
throws Exception;
diff --git
a/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/CmdGenerateDocs.java
b/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/CmdGenerateDocs.java
index 8f784c1eca1..a66da9fd6c6 100644
---
a/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/CmdGenerateDocs.java
+++
b/pulsar-docs-tools/src/main/java/org/apache/pulsar/docs/tools/CmdGenerateDocs.java
@@ -18,144 +18,155 @@
*/
package org.apache.pulsar.docs.tools;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.ParameterDescription;
-import com.beust.jcommander.Parameters;
+import com.google.common.annotations.VisibleForTesting;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
-import java.util.Map;
+import java.util.concurrent.Callable;
import lombok.Getter;
import lombok.Setter;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Model.ArgSpec;
+import picocli.CommandLine.Model.OptionSpec;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
@Getter
@Setter
-@Parameters(commandDescription = "Generate documentation automatically.")
-public class CmdGenerateDocs {
+@Command(showDefaultValues = true, scope = ScopeType.INHERIT)
+public class CmdGenerateDocs implements Callable<Integer> {
- @Parameter(
+ @Option(
names = {"-h", "--help"},
- description = "Display help information"
+ description = "Display help information",
+ usageHelp = true
)
public boolean help;
- @Parameter(
+ @Option(
names = {"-n", "--command-names"},
description = "List of command names"
)
private List<String> commandNames = new ArrayList<>();
private static final String name = "gen-doc";
- private final JCommander jcommander;
+ private final CommandLine commander;
public CmdGenerateDocs(String cmdName) {
- jcommander = new JCommander(this);
- jcommander.setProgramName(cmdName);
+ commander = new CommandLine(this);
+ commander.setCommandName(cmdName);
}
public CmdGenerateDocs addCommand(String name, Object command) {
- jcommander.addCommand(name, command);
+ commander.addSubcommand(name, command);
return this;
}
public boolean run(String[] args) {
- JCommander tmpCmd = new JCommander(this);
- tmpCmd.setProgramName(jcommander.getProgramName() + " " + name);
- try {
- if (args == null) {
- args = new String[]{};
- }
- tmpCmd.parse(args);
- } catch (Exception e) {
- System.err.println(e.getMessage());
- System.err.println();
- tmpCmd.usage();
- return false;
+ if (args == null) {
+ args = new String[]{};
}
- if (help) {
- tmpCmd.usage();
- return true;
+ return commander.execute(args) == 0;
+ }
+
+ private static String getCommandDescription(CommandLine commandLine) {
+ String[] description =
commandLine.getCommandSpec().usageMessage().description();
+ if (description != null && description.length != 0) {
+ return description[0];
}
+ return "";
+ }
- if (commandNames.size() == 0) {
- for (Map.Entry<String, JCommander> cmd :
jcommander.getCommands().entrySet()) {
- if (cmd.getKey().equals(name)) {
- continue;
- }
- System.out.println(generateDocument(cmd.getKey(), jcommander));
- }
- } else {
- for (String commandName : commandNames) {
- if (commandName.equals(name)) {
- continue;
- }
- if (!jcommander.getCommands().keySet().contains(commandName)) {
- continue;
- }
- System.out.println(generateDocument(commandName, jcommander));
- }
+ private static String getArgDescription(ArgSpec argSpec) {
+ String[] description = argSpec.description();
+ if (description != null && description.length != 0) {
+ return description[0];
}
- return true;
+ return "";
}
- private String generateDocument(String module, JCommander commander) {
- JCommander cmd = commander.getCommands().get(module);
+ private String generateDocument(String module, CommandLine commander) {
StringBuilder sb = new StringBuilder();
sb.append("# ").append(module).append("\n\n");
- String desc =
commander.getUsageFormatter().getCommandDescription(module);
+ String desc = getCommandDescription(commander);
if (null != desc && !desc.isEmpty()) {
sb.append(desc).append("\n");
}
sb.append("\n\n```shell\n")
.append("$ ");
- if (null != jcommander.getProgramName() &&
!jcommander.getProgramName().isEmpty()) {
- sb.append(jcommander.getProgramName()).append(" ");
- }
- sb.append(module);
- if (cmd.getObjects().size() > 0
- &&
cmd.getObjects().get(0).getClass().getName().equals("com.beust.jcommander.JCommander"))
{
- JCommander cmdObj = (JCommander) cmd.getObjects().get(0);
+ String commandName = commander.getCommandName();
+ sb.append(this.commander.getCommandName() + " " + commandName);
+ if (!commander.getSubcommands().isEmpty()) {
sb.append(" subcommand").append("\n```").append("\n\n");
- cmdObj.getCommands().forEach((subK, subV) -> {
+ commander.getSubcommands().forEach((subK, subV) -> {
if (!subK.equals(name)) {
sb.append("\n\n## ").append(subK).append("\n\n");
- String subDesc =
cmdObj.getUsageFormatter().getCommandDescription(subK);
+ String subDesc = getCommandDescription(subV);
if (null != subDesc && !subDesc.isEmpty()) {
sb.append(subDesc).append("\n");
}
sb.append("```shell\n$ ");
- if (null != jcommander.getProgramName() &&
!jcommander.getProgramName().isEmpty()) {
- sb.append(jcommander.getProgramName()).append(" ");
- }
+ sb.append(this.commander.getCommandName()).append(" ");
sb.append(module).append(" ").append(subK).append("
options").append("\n```\n\n");
- List<ParameterDescription> options =
cmdObj.getCommands().get(subK).getParameters();
- if (options.size() > 0) {
+ List<ArgSpec> argSpecs = subV.getCommandSpec().args();
+ if (argSpecs.size() > 0) {
sb.append("|Flag|Description|Default|\n");
sb.append("|---|---|---|\n");
}
- options.forEach((option) ->
- sb.append("| `").append(option.getNames())
- .append("` |
").append(option.getDescription().replace("\n", " "))
-
.append("|").append(option.getDefault()).append("|\n")
- );
+
+ argSpecs.forEach(option -> {
+ if (option.hidden() || !(option instanceof
OptionSpec)) {
+ return;
+ }
+ sb.append("| `").append(String.join(", ",
((OptionSpec) option).names()))
+ .append("` |
").append(getArgDescription(option).replace("\n", " "))
+
.append("|").append(option.defaultValueString()).append("|\n");
+ });
}
});
} else {
sb.append(" options").append("\n```").append("\n\n");
sb.append("|Flag|Description|Default|\n");
sb.append("|---|---|---|\n");
- List<ParameterDescription> options = cmd.getParameters();
-
options.stream().sorted(Comparator.comparing(ParameterDescription::getLongestName))
- .forEach((option) ->
- sb.append("| `")
- .append(option.getNames())
- .append("` | ")
-
.append(option.getDescription().replace("\n", " "))
- .append("|")
- .append(option.getDefault()).append("|\n")
- );
+ List<ArgSpec> argSpecs = commander.getCommandSpec().args();
+ argSpecs.forEach(option -> {
+ if (option.hidden() || !(option instanceof OptionSpec)) {
+ return;
+ }
+ sb.append("| `")
+ .append(String.join(", ", ((OptionSpec)
option).names()))
+ .append("` | ")
+ .append(getArgDescription(option).replace("\n", " "))
+ .append("|")
+ .append(option.defaultValueString()).append("|\n");
+ });
}
return sb.toString();
}
+
+ @Override
+ public Integer call() throws Exception {
+ if (commandNames.size() == 0) {
+ commander.getSubcommands().forEach((name, cmd) -> {
+ commander.getOut().println(generateDocument(name, cmd));
+ });
+ } else {
+ for (String commandName : commandNames) {
+ if (commandName.equals(name)) {
+ continue;
+ }
+ CommandLine cmd = commander.getSubcommands().get(commandName);
+ if (cmd == null) {
+ continue;
+ }
+ commander.getOut().println(generateDocument(commandName, cmd));
+ }
+ }
+ return 0;
+ }
+
+ @VisibleForTesting
+ CommandLine getCommander() {
+ return commander;
+ }
}
diff --git
a/pulsar-docs-tools/src/test/java/org/apache/pulsar/docs/tools/CmdGenerateDocsTest.java
b/pulsar-docs-tools/src/test/java/org/apache/pulsar/docs/tools/CmdGenerateDocsTest.java
index 3f96ddaef59..0f0f96f80ec 100644
---
a/pulsar-docs-tools/src/test/java/org/apache/pulsar/docs/tools/CmdGenerateDocsTest.java
+++
b/pulsar-docs-tools/src/test/java/org/apache/pulsar/docs/tools/CmdGenerateDocsTest.java
@@ -19,79 +19,63 @@
package org.apache.pulsar.docs.tools;
import static org.testng.Assert.assertEquals;
-import com.beust.jcommander.Parameter;
-import com.beust.jcommander.Parameters;
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import org.testng.annotations.Test;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
public class CmdGenerateDocsTest {
- @Parameters(commandDescription = "Options")
+ @Command
public class Arguments {
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-n", "--name"}, description = "Name")
+ @Option(names = {"-n", "--name"}, description = "Name")
private String name;
}
@Test
public void testHelp() {
- PrintStream oldStream = System.out;
- try {
- ByteArrayOutputStream baoStream = new ByteArrayOutputStream(2048);
- PrintStream cacheStream = new PrintStream(baoStream);
- System.setOut(cacheStream);
+ CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
+ cmd.addCommand("test", new Arguments());
+ StringWriter stringWriter = new StringWriter();
+ cmd.getCommander().setOut(new PrintWriter(stringWriter));
+ cmd.run(new String[]{"-h"});
- CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("test", new Arguments());
- cmd.run(new String[]{"-h"});
-
- String message = baoStream.toString();
- String rightMsg = "Usage: pulsar gen-doc [options]\n"
- + " Options:\n"
- + " -n, --command-names\n"
- + " List of command names\n"
- + " Default: []\n"
- + " -h, --help\n"
- + " Display help information\n"
- + " Default: false\n"
- + System.lineSeparator();
- assertEquals(rightMsg, message);
- } finally {
- System.setOut(oldStream);
- }
+ String message = stringWriter.toString();
+ String rightMsg = "Usage: pulsar [-h] [-n=<commandNames>]...
[COMMAND]\n"
+ + " -h, --help Display help information\n"
+ + " -n, --command-names=<commandNames>\n"
+ + " List of command names\n"
+ + " Default: []\n"
+ + "Commands:\n"
+ + " test\n";
+ assertEquals(message, rightMsg);
}
@Test
public void testGenerateDocs() {
- PrintStream oldStream = System.out;
- try {
- ByteArrayOutputStream baoStream = new ByteArrayOutputStream(2048);
- PrintStream cacheStream = new PrintStream(baoStream);
- System.setOut(cacheStream);
-
- CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("test", new Arguments());
- cmd.run(null);
+ CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
+ cmd.addCommand("test", new Arguments());
+ StringWriter stringWriter = new StringWriter();
+ cmd.getCommander().setOut(new PrintWriter(stringWriter));
+ cmd.run(null);
- String message = baoStream.toString();
- String rightMsg = "# test\n\n"
- + "Options\n\n"
- + "\n"
- + "```shell\n"
- + "$ pulsar test options\n"
- + "```\n"
- + "\n"
- + "|Flag|Description|Default|\n"
- + "|---|---|---|\n"
- + "| `-h, --help` | Show this help message|false|\n"
- + "| `-n, --name` | Name|null|\n"
- + System.lineSeparator();
- assertEquals(rightMsg, message);
- } finally {
- System.setOut(oldStream);
- }
+ String message = stringWriter.toString();
+ String rightMsg = "# test\n\n"
+ + "\n"
+ + "\n"
+ + "```shell\n"
+ + "$ pulsar test options\n"
+ + "```\n"
+ + "\n"
+ + "|Flag|Description|Default|\n"
+ + "|---|---|---|\n"
+ + "| `-h, --help` | Show this help message|false|\n"
+ + "| `-n, --name` | Name|null|\n"
+ + System.lineSeparator();
+ assertEquals(message, rightMsg);
}
}
diff --git
a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionWorkerStarter.java
b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionWorkerStarter.java
index 679ce1db70d..c5fb552d9cc 100644
---
a/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionWorkerStarter.java
+++
b/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/FunctionWorkerStarter.java
@@ -19,11 +19,13 @@
package org.apache.pulsar.functions.worker;
import static org.apache.commons.lang3.StringUtils.isBlank;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.common.util.ShutdownUtil;
import org.apache.pulsar.docs.tools.CmdGenerateDocs;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* A starter to start function worker.
@@ -31,35 +33,36 @@ import org.apache.pulsar.docs.tools.CmdGenerateDocs;
@Slf4j
public class FunctionWorkerStarter {
+ @Command(name = "functions-worker", showDefaultValues = true, scope =
ScopeType.INHERIT)
private static class WorkerArguments {
- @Parameter(
+ @Option(
names = { "-c", "--conf" },
description = "Configuration File for Function Worker")
private String configFile;
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
+
public static void main(String[] args) throws Exception {
WorkerArguments workerArguments = new WorkerArguments();
- JCommander commander = new JCommander(workerArguments);
- commander.setProgramName("FunctionWorkerStarter");
+ CommandLine commander = new CommandLine(workerArguments);
+ commander.setCommandName("FunctionWorkerStarter");
- // parse args by commander
- commander.parse(args);
+ commander.parseArgs(args);
if (workerArguments.help) {
- commander.usage();
+ commander.usage(commander.getOut());
return;
}
if (workerArguments.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("functions-worker", workerArguments);
+ cmd.addCommand("functions-worker", commander);
cmd.run(null);
return;
}
diff --git
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/FunctionWorkerStarterTest.java
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/FunctionWorkerStarterTest.java
index 51bcd974f50..6fa0bec1b36 100644
---
a/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/FunctionWorkerStarterTest.java
+++
b/pulsar-functions/worker/src/test/java/org/apache/pulsar/functions/worker/FunctionWorkerStarterTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar.functions.worker;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
public class FunctionWorkerStarterTest {
@Test
@@ -43,9 +43,9 @@ public class FunctionWorkerStarterTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
String nameStr = Arrays.asList(names).toString();
nameStr = nameStr.substring(1, nameStr.length() - 1);
diff --git a/pulsar-io/docs/pom.xml b/pulsar-io/docs/pom.xml
index adbc2f4efad..0fd774aaafe 100644
--- a/pulsar-io/docs/pom.xml
+++ b/pulsar-io/docs/pom.xml
@@ -42,8 +42,8 @@
<artifactId>reflections</artifactId>
</dependency>
<dependency>
- <groupId>com.beust</groupId>
- <artifactId>jcommander</artifactId>
+ <groupId>info.picocli</groupId>
+ <artifactId>picocli</artifactId>
</dependency>
<!-- include connectors -->
diff --git a/pulsar-proxy/pom.xml b/pulsar-proxy/pom.xml
index 55dfd11e40e..64ca301facf 100644
--- a/pulsar-proxy/pom.xml
+++ b/pulsar-proxy/pom.xml
@@ -184,8 +184,8 @@
</dependency>
<dependency>
- <groupId>com.beust</groupId>
- <artifactId>jcommander</artifactId>
+ <groupId>info.picocli</groupId>
+ <artifactId>picocli</artifactId>
</dependency>
<dependency>
diff --git
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
index 1a98601f2a9..72d54601995 100644
---
a/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
+++
b/pulsar-proxy/src/main/java/org/apache/pulsar/proxy/server/ProxyServiceStarter.java
@@ -23,8 +23,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.pulsar.common.stats.JvmMetrics.getJvmDirectMemoryUsed;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import com.google.common.annotations.VisibleForTesting;
import io.prometheus.client.CollectorRegistry;
import io.prometheus.client.Gauge;
@@ -61,40 +59,45 @@ import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ScopeType;
/**
* Starts an instance of the Pulsar ProxyService.
*/
+@Command(name = "proxy", showDefaultValues = true, scope = ScopeType.INHERIT)
public class ProxyServiceStarter {
- @Parameter(names = { "-c", "--config" }, description = "Configuration file
path", required = true)
+ @Option(names = { "-c", "--config" }, description = "Configuration file
path", required = true)
private String configFile;
@Deprecated
- @Parameter(names = { "-zk", "--zookeeper-servers" },
+ @Option(names = { "-zk", "--zookeeper-servers" },
description = "Local zookeeper connection string, please use
--metadata-store instead")
private String zookeeperServers = "";
- @Parameter(names = { "-md", "--metadata-store" }, description = "Metadata
Store service url. eg: zk:my-zk:2181")
+ @Option(names = { "-md", "--metadata-store" }, description = "Metadata
Store service url. eg: zk:my-zk:2181")
private String metadataStoreUrl = "";
@Deprecated
- @Parameter(names = { "-gzk", "--global-zookeeper-servers" },
+ @Option(names = { "-gzk", "--global-zookeeper-servers" },
description = "Global zookeeper connection string, please use
--configuration-metadata-store instead")
private String globalZookeeperServers = "";
@Deprecated
- @Parameter(names = { "-cs", "--configuration-store-servers" },
+ @Option(names = { "-cs", "--configuration-store-servers" },
description = "Configuration store connection string, "
+ "please use --configuration-metadata-store
instead")
private String configurationStoreServers = "";
- @Parameter(names = { "-cms", "--configuration-metadata-store" },
+ @Option(names = { "-cms", "--configuration-metadata-store" },
description = "The metadata store URL for the configuration data")
private String configurationMetadataStoreUrl = "";
- @Parameter(names = { "-h", "--help" }, description = "Show this help
message")
+ @Option(names = { "-h", "--help" }, description = "Show this help message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate docs")
private boolean generateDocs = false;
private ProxyConfiguration config;
@@ -116,23 +119,22 @@ public class ProxyServiceStarter {
exception.printStackTrace(System.out);
});
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(this);
try {
- jcommander.addObject(this);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (help || isBlank(configFile)) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
if (this.generateDocs) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("proxy", this);
+ cmd.addCommand("proxy", commander);
cmd.run(null);
System.exit(0);
}
} catch (Exception e) {
- jcommander.usage();
+ commander.getErr().println(e);
System.exit(1);
}
diff --git
a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketServiceStarter.java
b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketServiceStarter.java
index fd38208323c..ed1a99b8133 100644
---
a/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketServiceStarter.java
+++
b/pulsar-websocket/src/main/java/org/apache/pulsar/websocket/service/WebSocketServiceStarter.java
@@ -22,8 +22,6 @@ import static
com.google.common.base.Preconditions.checkArgument;
import static
org.apache.pulsar.websocket.admin.WebSocketWebResource.ADMIN_PATH_V1;
import static
org.apache.pulsar.websocket.admin.WebSocketWebResource.ADMIN_PATH_V2;
import static
org.apache.pulsar.websocket.admin.WebSocketWebResource.ATTRIBUTE_PROXY_SERVICE_NAME;
-import com.beust.jcommander.JCommander;
-import com.beust.jcommander.Parameter;
import org.apache.pulsar.common.configuration.PulsarConfigurationLoader;
import org.apache.pulsar.common.configuration.VipStatus;
import org.apache.pulsar.common.util.ShutdownUtil;
@@ -37,37 +35,42 @@ import
org.apache.pulsar.websocket.admin.v1.WebSocketProxyStatsV1;
import org.apache.pulsar.websocket.admin.v2.WebSocketProxyStatsV2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+import picocli.CommandLine.ScopeType;
public class WebSocketServiceStarter {
+ @Command(name = "websocket", showDefaultValues = true, scope =
ScopeType.INHERIT)
private static class Arguments {
- @Parameter(description = "config file")
+ @Parameters(description = "config file", arity = "0..1")
private String configFile = "";
- @Parameter(names = {"-h", "--help"}, description = "Show this help
message")
+ @Option(names = {"-h", "--help"}, description = "Show this help
message")
private boolean help = false;
- @Parameter(names = {"-g", "--generate-docs"}, description = "Generate
docs")
+ @Option(names = {"-g", "--generate-docs"}, description = "Generate
docs")
private boolean generateDocs = false;
}
public static void main(String[] args) throws Exception {
Arguments arguments = new Arguments();
- JCommander jcommander = new JCommander();
+ CommandLine commander = new CommandLine(arguments);
try {
- jcommander.addObject(arguments);
- jcommander.parse(args);
+ commander.parseArgs(args);
if (arguments.help) {
- jcommander.usage();
+ commander.usage(commander.getOut());
return;
}
if (arguments.generateDocs && arguments.configFile != null) {
CmdGenerateDocs cmd = new CmdGenerateDocs("pulsar");
- cmd.addCommand("websocket", arguments);
+ cmd.addCommand("websocket", commander);
cmd.run(null);
return;
}
} catch (Exception e) {
- jcommander.usage();
+ commander.getErr().println(e);
return;
}
diff --git
a/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/service/WebSocketServiceStarterTest.java
b/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/service/WebSocketServiceStarterTest.java
index c898a07e228..f9a190cf866 100644
---
a/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/service/WebSocketServiceStarterTest.java
+++
b/pulsar-websocket/src/test/java/org/apache/pulsar/websocket/service/WebSocketServiceStarterTest.java
@@ -19,12 +19,12 @@
package org.apache.pulsar.websocket.service;
import static org.testng.Assert.assertTrue;
-import com.beust.jcommander.Parameter;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.Arrays;
import org.testng.annotations.Test;
+import picocli.CommandLine.Option;
public class WebSocketServiceStarterTest {
@Test
@@ -43,9 +43,9 @@ public class WebSocketServiceStarterTest {
Field[] fields = argumentsClass.getDeclaredFields();
for (Field field : fields) {
- boolean fieldHasAnno =
field.isAnnotationPresent(Parameter.class);
+ boolean fieldHasAnno = field.isAnnotationPresent(Option.class);
if (fieldHasAnno) {
- Parameter fieldAnno = field.getAnnotation(Parameter.class);
+ Option fieldAnno = field.getAnnotation(Option.class);
String[] names = fieldAnno.names();
if (names.length == 0) {
continue;