Skip to content

Commit 7f8f120

Browse files
Allow help flags to be specified for any Admin subcommand (apache#5220)
* Consolidates all subCommand Opts under Admin class Moves the Opts class from ServiceStatusCmd and into the `Admin` class. Removes the AdminOpts class * Make call to stop explicit in admin command Use `else if` instead of default `else` case as it will create a client.shutdown rpc call to the manager. * Update server/base/src/main/java/org/apache/accumulo/server/util/Admin.java Automatically find all subcommand help options instead of formal IF statement. Co-authored-by: Keith Turner <kturner@apache.org> --------- Co-authored-by: Keith Turner <kturner@apache.org>
1 parent 87deb3a commit 7f8f120

File tree

5 files changed

+75
-48
lines changed

5 files changed

+75
-48
lines changed

core/src/test/java/org/apache/accumulo/core/cli/TestHelp.java

+19
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@
1919
package org.apache.accumulo.core.cli;
2020

2121
import static org.junit.jupiter.api.Assertions.assertEquals;
22+
import static org.junit.jupiter.api.Assertions.assertTrue;
2223

2324
import org.junit.jupiter.api.Test;
2425

26+
import com.beust.jcommander.Parameter;
27+
2528
public class TestHelp {
2629
protected class HelpStub extends Help {
2730
@Override
@@ -46,4 +49,20 @@ public void testInvalidArgs() {
4649
}
4750
}
4851

52+
@Test
53+
public void testHelpCommand() {
54+
class TestHelpOpt extends HelpStub {
55+
@Parameter(names = {"--test"})
56+
boolean test = false;
57+
}
58+
59+
String[] args = {"--help", "--test"};
60+
TestHelpOpt opts = new TestHelpOpt();
61+
try {
62+
opts.parseArgs("program", args);
63+
assertTrue(opts.test);
64+
} catch (RuntimeException e) {
65+
assertEquals("0", e.getMessage());
66+
}
67+
}
4968
}

server/base/src/main/java/org/apache/accumulo/server/util/Admin.java

+50-31
Original file line numberDiff line numberDiff line change
@@ -96,26 +96,28 @@
9696
public class Admin implements KeywordExecutable {
9797
private static final Logger log = LoggerFactory.getLogger(Admin.class);
9898

99-
static class AdminOpts extends ServerUtilOpts {
100-
@Parameter(names = {"-f", "--force"},
101-
description = "force the given server to stop by removing its lock")
102-
boolean force = false;
99+
private static class SubCommandOpts {
100+
@Parameter(names = {"-h", "-?", "--help", "-help"}, help = true)
101+
public boolean help = false;
103102
}
104103

105104
@Parameters(commandDescription = "stop the tablet server on the given hosts")
106-
static class StopCommand {
105+
static class StopCommand extends SubCommandOpts {
106+
@Parameter(names = {"-f", "--force"},
107+
description = "force the given server to stop by removing its lock")
108+
boolean force = false;
107109
@Parameter(description = "<host> {<host> ... }")
108110
List<String> args = new ArrayList<>();
109111
}
110112

111113
@Parameters(commandDescription = "Ping tablet servers. If no arguments, pings all.")
112-
static class PingCommand {
114+
static class PingCommand extends SubCommandOpts {
113115
@Parameter(description = "{<host> ... }")
114116
List<String> args = new ArrayList<>();
115117
}
116118

117119
@Parameters(commandDescription = "print tablets that are offline in online tables")
118-
static class CheckTabletsCommand {
120+
static class CheckTabletsCommand extends SubCommandOpts {
119121
@Parameter(names = "--fixFiles", description = "Remove dangling file pointers")
120122
boolean fixFiles = false;
121123

@@ -125,17 +127,17 @@ static class CheckTabletsCommand {
125127
}
126128

127129
@Parameters(commandDescription = "stop the manager")
128-
static class StopManagerCommand {}
130+
static class StopManagerCommand extends SubCommandOpts {}
129131

130132
@Deprecated(since = "2.1.0")
131133
@Parameters(commandDescription = "stop the master (DEPRECATED -- use stopManager instead)")
132134
static class StopMasterCommand {}
133135

134136
@Parameters(commandDescription = "stop all tablet servers and the manager")
135-
static class StopAllCommand {}
137+
static class StopAllCommand extends SubCommandOpts {}
136138

137139
@Parameters(commandDescription = "list Accumulo instances in zookeeper")
138-
static class ListInstancesCommand {
140+
static class ListInstancesCommand extends SubCommandOpts {
139141
@Parameter(names = "--print-errors", description = "display errors while listing instances")
140142
boolean printErrors = false;
141143
@Parameter(names = "--print-all",
@@ -144,13 +146,13 @@ static class ListInstancesCommand {
144146
}
145147

146148
@Parameters(commandDescription = "Accumulo volume utility")
147-
static class VolumesCommand {
149+
static class VolumesCommand extends SubCommandOpts {
148150
@Parameter(names = {"-l", "--list"}, description = "list volumes currently in use")
149151
boolean printErrors = false;
150152
}
151153

152154
@Parameters(commandDescription = "print out non-default configuration settings")
153-
static class DumpConfigCommand {
155+
static class DumpConfigCommand extends SubCommandOpts {
154156
@Parameter(names = {"-a", "--all"},
155157
description = "print the system and all table configurations")
156158
boolean allConfiguration = false;
@@ -173,13 +175,13 @@ static class DumpConfigCommand {
173175
+ "necessary.";
174176

175177
@Parameters(commandDescription = RV_DEPRECATION_MSG)
176-
static class RandomizeVolumesCommand {
178+
static class RandomizeVolumesCommand extends SubCommandOpts {
177179
@Parameter(names = {"-t"}, description = "table to update", required = true)
178180
String tableName = null;
179181
}
180182

181183
@Parameters(commandDescription = "Verify all Tablets are assigned to tablet servers")
182-
static class VerifyTabletAssignmentsCommand {
184+
static class VerifyTabletAssignmentsCommand extends SubCommandOpts {
183185
@Parameter(names = {"-v", "--verbose"},
184186
description = "verbose mode (prints locations of tablets)")
185187
boolean verbose = false;
@@ -194,14 +196,14 @@ static class ChangeSecretCommand {}
194196

195197
@Parameters(
196198
commandDescription = "List or delete Tablet Server locks. Default with no arguments is to list the locks.")
197-
static class TabletServerLocksCommand {
199+
static class TabletServerLocksCommand extends SubCommandOpts {
198200
@Parameter(names = "-delete", description = "specify a tablet server lock to delete")
199201
String delete = null;
200202
}
201203

202204
@Parameters(
203205
commandDescription = "Deletes specific instance name or id from zookeeper or cleans up all old instances.")
204-
static class DeleteZooInstanceCommand {
206+
static class DeleteZooInstanceCommand extends SubCommandOpts {
205207
@Parameter(names = {"-i", "--instance"}, description = "the instance name or id to delete")
206208
String instance;
207209
@Parameter(names = {"-c", "--clean"},
@@ -214,7 +216,7 @@ static class DeleteZooInstanceCommand {
214216
}
215217

216218
@Parameters(commandDescription = "Restore Zookeeper data from a file.")
217-
static class RestoreZooCommand {
219+
static class RestoreZooCommand extends SubCommandOpts {
218220
@Parameter(names = "--overwrite")
219221
boolean overwrite = false;
220222

@@ -224,7 +226,7 @@ static class RestoreZooCommand {
224226

225227
@Parameters(commandNames = "fate",
226228
commandDescription = "Operations performed on the Manager FaTE system.")
227-
static class FateOpsCommand {
229+
static class FateOpsCommand extends SubCommandOpts {
228230
@Parameter(description = "[<txId>...]")
229231
List<String> txList = new ArrayList<>();
230232

@@ -255,6 +257,15 @@ static class FateOpsCommand {
255257
List<String> states = new ArrayList<>();
256258
}
257259

260+
@Parameters(commandDescription = "show service status")
261+
public static class ServiceStatusCmdOpts extends SubCommandOpts {
262+
@Parameter(names = "--json", description = "provide output in json format (--noHosts ignored)")
263+
boolean json = false;
264+
@Parameter(names = "--noHosts",
265+
description = "provide a summary of service counts without host details")
266+
boolean noHosts = false;
267+
}
268+
258269
public static void main(String[] args) {
259270
new Admin().execute(args);
260271
}
@@ -277,13 +288,12 @@ public String description() {
277288
@SuppressFBWarnings(value = "DM_EXIT", justification = "System.exit okay for CLI tool")
278289
@Override
279290
public void execute(final String[] args) {
280-
boolean everything;
281291

282-
AdminOpts opts = new AdminOpts();
292+
ServerUtilOpts opts = new ServerUtilOpts();
283293
JCommander cl = new JCommander(opts);
284294
cl.setProgramName("accumulo admin");
285295

286-
ServiceStatusCmd.Opts serviceStatusCommandOpts = new ServiceStatusCmd.Opts();
296+
ServiceStatusCmdOpts serviceStatusCommandOpts = new ServiceStatusCmdOpts();
287297
cl.addCommand("serviceStatus", serviceStatusCommandOpts);
288298

289299
ChangeSecretCommand changeSecretCommand = new ChangeSecretCommand();
@@ -337,11 +347,21 @@ public void execute(final String[] args) {
337347

338348
cl.parse(args);
339349

340-
if (opts.help || cl.getParsedCommand() == null) {
350+
if (cl.getParsedCommand() == null) {
341351
cl.usage();
342352
return;
343353
}
344354

355+
for (var command : cl.getCommands().entrySet()) {
356+
var objects = command.getValue().getObjects();
357+
for (var obj : objects) {
358+
if (obj instanceof SubCommandOpts && ((SubCommandOpts) obj).help) {
359+
command.getValue().usage();
360+
return;
361+
}
362+
}
363+
}
364+
345365
ServerContext context = opts.getServerContext();
346366

347367
AccumuloConfiguration conf = context.getConfiguration();
@@ -380,7 +400,7 @@ public void execute(final String[] args) {
380400
}
381401

382402
} else if (cl.getParsedCommand().equals("stop")) {
383-
stopTabletServer(context, stopOpts.args, opts.force);
403+
stopTabletServer(context, stopOpts.args, stopOpts.force);
384404
} else if (cl.getParsedCommand().equals("dumpConfig")) {
385405
printConfig(context, dumpConfigCommand);
386406
} else if (cl.getParsedCommand().equals("volumes")) {
@@ -402,15 +422,19 @@ public void execute(final String[] args) {
402422
} else if (cl.getParsedCommand().equals("fate")) {
403423
executeFateOpsCommand(context, fateOpsCommand);
404424
} else if (cl.getParsedCommand().equals("serviceStatus")) {
405-
printServiceStatus(context, serviceStatusCommandOpts);
406-
} else {
407-
everything = cl.getParsedCommand().equals("stopAll");
425+
ServiceStatusCmd ssc = new ServiceStatusCmd();
426+
ssc.execute(context, serviceStatusCommandOpts.json, serviceStatusCommandOpts.noHosts);
427+
} else if (cl.getParsedCommand().equals("stopManager")
428+
|| cl.getParsedCommand().equals("stopAll")) {
429+
boolean everything = cl.getParsedCommand().equals("stopAll");
408430

409431
if (everything) {
410432
flushAll(context);
411433
}
412434

413435
stopServer(context, everything);
436+
} else {
437+
cl.usage();
414438
}
415439

416440
if (rc != 0) {
@@ -430,11 +454,6 @@ public void execute(final String[] args) {
430454
}
431455
}
432456

433-
private static void printServiceStatus(ServerContext context, ServiceStatusCmd.Opts opts) {
434-
ServiceStatusCmd ssc = new ServiceStatusCmd();
435-
ssc.execute(context, opts);
436-
}
437-
438457
private static int ping(ClientContext context, List<String> args) {
439458

440459
InstanceOperations io = context.instanceOperations();

server/base/src/main/java/org/apache/accumulo/server/util/ServiceStatusCmd.java

+3-14
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@
3939
import org.slf4j.Logger;
4040
import org.slf4j.LoggerFactory;
4141

42-
import com.beust.jcommander.Parameter;
43-
import com.beust.jcommander.Parameters;
4442
import com.google.common.annotations.VisibleForTesting;
4543

4644
public class ServiceStatusCmd {
@@ -56,7 +54,7 @@ public ServiceStatusCmd() {}
5654
* Read the service statuses from ZooKeeper, build the status report and then output the report to
5755
* stdout.
5856
*/
59-
public void execute(final ServerContext context, final Opts opts) {
57+
public void execute(final ServerContext context, final boolean json, final boolean noHosts) {
6058

6159
ZooReader zooReader = context.getZooReader();
6260

@@ -74,9 +72,9 @@ public void execute(final ServerContext context, final Opts opts) {
7472
services.put(ServiceStatusReport.ReportKey.COMPACTOR, getCompactorStatus(zooReader, zooRoot));
7573
services.put(ServiceStatusReport.ReportKey.GC, getGcStatus(zooReader, zooRoot));
7674

77-
ServiceStatusReport report = new ServiceStatusReport(services, opts.noHosts);
75+
ServiceStatusReport report = new ServiceStatusReport(services, noHosts);
7876

79-
if (opts.json) {
77+
if (json) {
8078
System.out.println(report.toJson());
8179
} else {
8280
StringBuilder sb = new StringBuilder(8192);
@@ -336,15 +334,6 @@ Result<Set<String>> readAllNodesData(final ZooReader zooReader, final String pat
336334
return new Result<>(errorCount.get(), hosts);
337335
}
338336

339-
@Parameters(commandDescription = "show service status")
340-
public static class Opts {
341-
@Parameter(names = "--json", description = "provide output in json format (--noHosts ignored)")
342-
boolean json = false;
343-
@Parameter(names = "--noHosts",
344-
description = "provide a summary of service counts without host details")
345-
boolean noHosts = false;
346-
}
347-
348337
/**
349338
* Provides explicit method names instead of generic getFirst to get the error count and getSecond
350339
* hosts information

server/base/src/test/java/org/apache/accumulo/server/util/AdminCommandsTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ public void testDumpConfigCommand() {
8686

8787
// not a command, but easy enough to include here
8888
@Test
89-
public void testAdminOpts() {
90-
Admin.AdminOpts opts = new Admin.AdminOpts();
89+
public void testStopOpts() {
90+
Admin.StopCommand opts = new Admin.StopCommand();
9191
assertFalse(opts.force);
9292
}
9393
}

server/base/src/test/java/org/apache/accumulo/server/util/ServiceStatusCmdTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ void zkNodeDeletedTest() throws Exception {
398398
@Test
399399
public void testServiceStatusCommandOpts() {
400400
replay(zooReader); // needed for @AfterAll verify
401-
ServiceStatusCmd.Opts opts = new ServiceStatusCmd.Opts();
401+
Admin.ServiceStatusCmdOpts opts = new Admin.ServiceStatusCmdOpts();
402402
assertFalse(opts.json);
403403
assertFalse(opts.noHosts);
404404
}

0 commit comments

Comments
 (0)