This is an automated email from the ASF dual-hosted git repository.
alexpl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git
The following commit(s) were added to refs/heads/master by this push:
new 0f91ab211ae IGNITE-18945 Add an ability to extend control-utility with
the new commands - Fixes #10576.
0f91ab211ae is described below
commit 0f91ab211aeb92efcd57aa7586457cfab073d2f7
Author: Aleksey Plekhanov <[email protected]>
AuthorDate: Fri Mar 10 14:51:39 2023 +0300
IGNITE-18945 Add an ability to extend control-utility with the new commands
- Fixes #10576.
Signed-off-by: Aleksey Plekhanov <[email protected]>
---
assembly/dependencies-apache-ignite-lgpl.xml | 2 +-
assembly/dependencies-apache-ignite-slim.xml | 2 +-
assembly/dependencies-apache-ignite.xml | 2 +-
modules/bom/pom.xml | 7 +
modules/control-utility/pom.xml | 11 ++
.../ignite/internal/commandline/Command.java | 19 +++
.../internal/commandline/CommandArgIterator.java | 16 +-
.../internal/commandline/CommandHandler.java | 45 +++++-
.../ignite/internal/commandline/CommandList.java | 23 ++-
.../internal/commandline/CommandsProvider.java} | 22 ++-
.../internal/commandline/CommonArgParser.java | 21 ++-
.../commandline/cache/CacheCommandList.java | 166 ---------------------
.../internal/commandline/cache/CacheCommands.java | 2 +-
.../commandline/cache/CacheSubcommands.java | 34 ++---
.../commandline/CommandHandlerParsingTest.java | 2 +-
.../{logo => pluggable}/licenses/apache-2.0.txt | 0
modules/extdata/{logo => pluggable}/pom.xml | 15 +-
.../commandline/CommandsProviderExtImpl.java | 90 +++++++++++
.../commandline/ExtendedControlUtilityTest.java | 71 +++++++++
.../ignite/internal/plugin/ExtendedLogoTest.java} | 4 +-
.../plugin/IgniteExtLogInfoProviderImpl.java | 0
.../IgnitePluggableExtensionsTestSuite.java} | 10 +-
...he.ignite.internal.commandline.CommandsProvider | 1 +
...he.ignite.internal.plugin.IgniteLogInfoProvider | 0
pom.xml | 2 +-
25 files changed, 330 insertions(+), 237 deletions(-)
diff --git a/assembly/dependencies-apache-ignite-lgpl.xml
b/assembly/dependencies-apache-ignite-lgpl.xml
index 0e1ec42f4a8..cd273439857 100644
--- a/assembly/dependencies-apache-ignite-lgpl.xml
+++ b/assembly/dependencies-apache-ignite-lgpl.xml
@@ -120,7 +120,7 @@
<exclude>${project.groupId}:ignite-extdata-p2p</exclude>
<exclude>${project.groupId}:ignite-extdata-uri</exclude>
<exclude>${project.groupId}:ignite-extdata-uri-dep</exclude>
- <exclude>${project.groupId}:ignite-extdata-logo</exclude>
+ <exclude>${project.groupId}:ignite-extdata-pluggable</exclude>
<exclude>${project.groupId}:ignite-examples</exclude>
<exclude>${project.groupId}:ignite-indexing</exclude>
<exclude>${project.groupId}:ignite-codegen</exclude>
diff --git a/assembly/dependencies-apache-ignite-slim.xml
b/assembly/dependencies-apache-ignite-slim.xml
index eb81a4cdbcb..dbcd1efb2ff 100644
--- a/assembly/dependencies-apache-ignite-slim.xml
+++ b/assembly/dependencies-apache-ignite-slim.xml
@@ -120,7 +120,7 @@
<exclude>${project.groupId}:ignite-extdata-p2p</exclude>
<exclude>${project.groupId}:ignite-extdata-uri</exclude>
<exclude>${project.groupId}:ignite-extdata-uri-dep</exclude>
- <exclude>${project.groupId}:ignite-extdata-logo</exclude>
+ <exclude>${project.groupId}:ignite-extdata-pluggable</exclude>
<exclude>${project.groupId}:ignite-examples</exclude>
<exclude>${project.groupId}:ignite-indexing</exclude>
<exclude>${project.groupId}:ignite-hadoop</exclude>
diff --git a/assembly/dependencies-apache-ignite.xml
b/assembly/dependencies-apache-ignite.xml
index 695baee9108..ab81d967cc0 100644
--- a/assembly/dependencies-apache-ignite.xml
+++ b/assembly/dependencies-apache-ignite.xml
@@ -121,7 +121,7 @@
<exclude>${project.groupId}:ignite-extdata-p2p</exclude>
<exclude>${project.groupId}:ignite-extdata-uri</exclude>
<exclude>${project.groupId}:ignite-extdata-uri-dep</exclude>
- <exclude>${project.groupId}:ignite-extdata-logo</exclude>
+ <exclude>${project.groupId}:ignite-extdata-pluggable</exclude>
<exclude>${project.groupId}:ignite-examples</exclude>
<exclude>${project.groupId}:ignite-indexing</exclude>
<exclude>${project.groupId}:ignite-codegen</exclude>
diff --git a/modules/bom/pom.xml b/modules/bom/pom.xml
index 3ad77023ca2..7c82f120990 100644
--- a/modules/bom/pom.xml
+++ b/modules/bom/pom.xml
@@ -208,6 +208,13 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>ignite-control-utility</artifactId>
+ <version>${revision}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</dependencyManagement>
diff --git a/modules/control-utility/pom.xml b/modules/control-utility/pom.xml
index 42a50502f10..32d50b0ce0e 100644
--- a/modules/control-utility/pom.xml
+++ b/modules/control-utility/pom.xml
@@ -141,6 +141,17 @@
<build>
<plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>test-jar</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
index 87cc47441d1..b4b9209e637 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/Command.java
@@ -124,6 +124,25 @@ public interface Command<T> {
CommandList cmd,
@Nullable Map<String, String> paramsDesc,
String... args
+ ) {
+ usage(logger, desc, cmd.text(), paramsDesc, args);
+ }
+
+ /**
+ * Print command usage.
+ *
+ * @param logger Logger to use.
+ * @param desc Command description.
+ * @param cmd Command.
+ * @param paramsDesc Description of parameters (optional).
+ * @param args Arguments.
+ */
+ public default void usage(
+ IgniteLogger logger,
+ String desc,
+ String cmd,
+ @Nullable Map<String, String> paramsDesc,
+ String... args
) {
logger.info("");
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java
index 892f87e0166..3e7d94a2051 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandArgIterator.java
@@ -21,6 +21,7 @@ package org.apache.ignite.internal.commandline;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.ignite.internal.util.typedef.F;
@@ -31,7 +32,10 @@ import org.jetbrains.annotations.NotNull;
*/
public class CommandArgIterator {
/** */
- private Iterator<String> argsIt;
+ private final Iterator<String> argsIt;
+
+ /** */
+ private final Map<String, Command<?>> cmds;
/** */
private String peekedArg;
@@ -44,10 +48,16 @@ public class CommandArgIterator {
/**
* @param argsIt Raw argument iterator.
* @param commonArgumentsAndHighLevelCommandSet All known subcomands.
+ * @param cmds Supported commands.
*/
- public CommandArgIterator(Iterator<String> argsIt, Set<String>
commonArgumentsAndHighLevelCommandSet) {
+ public CommandArgIterator(
+ Iterator<String> argsIt,
+ Set<String> commonArgumentsAndHighLevelCommandSet,
+ Map<String, Command<?>> cmds
+ ) {
this.argsIt = argsIt;
this.commonArgumentsAndHighLevelCommandSet =
commonArgumentsAndHighLevelCommandSet;
+ this.cmds = cmds;
}
/**
@@ -61,7 +71,7 @@ public class CommandArgIterator {
* @return <code>true</code> if there's next argument for subcommand.
*/
public boolean hasNextSubArg() {
- return hasNextArg() && CommandList.of(peekNextArg()) == null &&
+ return hasNextArg() && !cmds.containsKey(peekNextArg().toLowerCase())
&&
!commonArgumentsAndHighLevelCommandSet.contains(peekNextArg());
}
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
index c1c4b12d213..967f0114cc5 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandHandler.java
@@ -22,7 +22,9 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Scanner;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -112,6 +114,9 @@ public class CommandHandler {
/** JULs logger. */
private final IgniteLogger logger;
+ /** Supported commands. */
+ private final Map<String, Command<?>> cmds;
+
/** Session. */
protected final String ses = U.id8(UUID.randomUUID());
@@ -155,7 +160,7 @@ public class CommandHandler {
*
*/
public CommandHandler() {
- logger = setupJavaLogger("control-utility", CommandHandler.class);
+ this(setupJavaLogger("control-utility", CommandHandler.class));
}
/**
@@ -163,6 +168,35 @@ public class CommandHandler {
*/
public CommandHandler(IgniteLogger logger) {
this.logger = logger;
+ Iterable<CommandsProvider> it = U.loadService(CommandsProvider.class);
+
+ Map<String, Command<?>> cmds = new LinkedHashMap<>();
+
+ CommandList.commands().forEach((k, v) -> cmds.put(k.toLowerCase(), v));
+
+ if (!F.isEmpty(it)) {
+ for (CommandsProvider provider : it) {
+ if (logger.isDebugEnabled())
+ logger.debug("Registering pluggable commands provider: " +
provider);
+
+ provider.commands().forEach((k, v) -> {
+ k = k.toLowerCase();
+
+ if (logger.isDebugEnabled())
+ logger.debug("Registering command: " + k);
+
+ if (cmds.containsKey(k)) {
+ throw new IllegalArgumentException("Found conflict for
command " + k + ". Provider " +
+ provider + " tries to register command " + v + ",
but this command has already been " +
+ "registered " + cmds.get(k));
+ }
+ else
+ cmds.put(k, v);
+ });
+ }
+ }
+
+ this.cmds = Collections.unmodifiableMap(cmds);
}
/**
@@ -195,7 +229,7 @@ public class CommandHandler {
verbose = F.exist(rawArgs, CMD_VERBOSE::equalsIgnoreCase);
- ConnectionAndSslParameters args = new
CommonArgParser(logger).parseAndValidate(rawArgs.iterator());
+ ConnectionAndSslParameters args = new CommonArgParser(logger,
cmds).parseAndValidate(rawArgs.iterator());
Command command = args.command();
commandName = command.name();
@@ -705,9 +739,10 @@ public class CommandHandler {
logger.info("This utility can do the following commands:");
- Arrays.stream(CommandList.values())
- .filter(c -> experimentalEnabled || !c.command().experimental())
- .forEach(c -> c.command().printUsage(logger));
+ cmds.values().forEach(c -> {
+ if (experimentalEnabled || !c.experimental())
+ c.printUsage(logger);
+ });
logger.info("");
logger.info("By default commands affecting the cluster require
interactive confirmation.");
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
index 2c7b78ce9bd..feabcdf3ac1 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandList.java
@@ -17,6 +17,10 @@
package org.apache.ignite.internal.commandline;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.stream.Collectors;
import org.apache.ignite.internal.commandline.cache.CacheCommands;
import org.apache.ignite.internal.commandline.cdc.CdcCommand;
import org.apache.ignite.internal.commandline.consistency.ConsistencyCommand;
@@ -116,28 +120,23 @@ public enum CommandList {
private final String text;
/** Command implementation. */
- private final Command command;
+ private final Command<?> command;
/**
* @param text Text.
* @param command Command implementation.
*/
- CommandList(String text, Command command) {
+ CommandList(String text, Command<?> command) {
this.text = text;
this.command = command;
}
/**
- * @param text Command text.
- * @return Command for the text.
+ * @return Map with commands.
*/
- public static CommandList of(String text) {
- for (CommandList cmd : VALUES) {
- if (cmd.text().equalsIgnoreCase(text))
- return cmd;
- }
-
- return null;
+ public static Map<String, Command<?>> commands() {
+ return Arrays.stream(VALUES).collect(
+ Collectors.toMap(CommandList::text, CommandList::command, (a, b)
-> a, LinkedHashMap::new));
}
/**
@@ -150,7 +149,7 @@ public enum CommandList {
/**
* @return Command implementation.
*/
- public Command command() {
+ public Command<?> command() {
return command;
}
diff --git
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/testsuites/IgniteLogoExtensionTestSuite.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java
similarity index 55%
copy from
modules/extdata/logo/src/test/java/org/apache/ignite/internal/testsuites/IgniteLogoExtensionTestSuite.java
copy to
modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java
index 36fea9f9d2f..f9ee95175c1 100644
---
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/testsuites/IgniteLogoExtensionTestSuite.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommandsProvider.java
@@ -1,12 +1,12 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
+ * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
+ * the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -15,18 +15,14 @@
* limitations under the License.
*/
-package org.apache.ignite.internal.testsuites;
+package org.apache.ignite.internal.commandline;
-import org.apache.ignite.internal.IgniteExtendedLogoTest;
-import org.junit.runner.RunWith;
-import org.junit.runners.Suite;
+import java.util.Map;
/**
- * Info provider test suite.
+ * Pluggable Ignite component that is responsible for providing list of
commands for control utility.
*/
-@RunWith(Suite.class)
[email protected]({
- IgniteExtendedLogoTest.class
-})
-public class IgniteLogoExtensionTestSuite {
+public interface CommandsProvider {
+ /** Gets all supported by this provider commands. */
+ public Map<String, Command<?>> commands();
}
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java
index 238a3a78046..91257db88ee 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/CommonArgParser.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.IgniteSystemProperties;
@@ -44,6 +45,9 @@ public class CommonArgParser {
/** */
private final IgniteLogger logger;
+ /** */
+ private final Map<String, Command<?>> cmds;
+
/** */
static final String CMD_HOST = "--host";
@@ -146,9 +150,11 @@ public class CommonArgParser {
/**
* @param logger Logger.
+ * @param cmds Supported commands.
*/
- public CommonArgParser(IgniteLogger logger) {
+ public CommonArgParser(IgniteLogger logger, Map<String, Command<?>> cmds) {
this.logger = logger;
+ this.cmds = cmds;
}
/**
@@ -224,26 +230,25 @@ public class CommonArgParser {
boolean experimentalEnabled =
IgniteSystemProperties.getBoolean(IGNITE_ENABLE_EXPERIMENTAL_COMMAND);
- CommandArgIterator argIter = new CommandArgIterator(rawArgIter,
AUX_COMMANDS);
+ CommandArgIterator argIter = new CommandArgIterator(rawArgIter,
AUX_COMMANDS, cmds);
- CommandList command = null;
+ Command<?> command = null;
while (argIter.hasNextArg()) {
String str = argIter.nextArg("").toLowerCase();
- CommandList cmd = CommandList.of(str);
+ Command<?> cmd = cmds.get(str);
if (cmd != null) {
if (command != null)
throw new IllegalArgumentException("Only one action can be
specified, but found at least two:" +
cmd.toString() + ", " + command.toString());
- cmd.command().parseArguments(argIter);
+ cmd.parseArguments(argIter);
command = cmd;
}
else {
-
switch (str) {
case CMD_HOST:
host = argIter.nextArg("Expected host name");
@@ -358,14 +363,14 @@ public class CommonArgParser {
if (command == null)
throw new IllegalArgumentException("No action was specified");
- if (!experimentalEnabled && command.command().experimental()) {
+ if (!experimentalEnabled && command.experimental()) {
logger.warning(String.format("To use experimental command add
--enable-experimental parameter for %s",
UTILITY_NAME));
throw new IllegalArgumentException("Experimental commands
disabled");
}
- return new ConnectionAndSslParameters(command.command(), host, port,
user, pwd,
+ return new ConnectionAndSslParameters(command, host, port, user, pwd,
pingTimeout, pingInterval, autoConfirmation, verbose,
sslProtocol, sslCipherSuites,
sslKeyAlgorithm, sslKeyStorePath, sslKeyStorePassword,
sslKeyStoreType,
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommandList.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommandList.java
deleted file mode 100644
index 9e0838627ed..00000000000
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommandList.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.ignite.internal.commandline.cache;
-
-import org.apache.ignite.internal.commandline.Command;
-import org.jetbrains.annotations.Nullable;
-
-/**
- *
- */
-public enum CacheCommandList {
- /**
- * Prints out help for the cache command.
- */
- HELP("help", null),
-
- /**
- * Checks consistency of primary and backup partitions assuming no
concurrent updates are happening in the cluster.
- */
- IDLE_VERIFY("idle_verify", new IdleVerify()),
-
- /**
- * Prints info regarding caches, groups or sequences.
- */
- LIST("list", new CacheViewer()),
-
- /**
- * Destroy caches.
- */
- DESTROY("destroy", new CacheDestroy()),
-
- /**
- * Clear caches.
- */
- CLEAR("clear", new CacheClear()),
-
- /**
- * Validates indexes attempting to read each indexed entry.
- */
- VALIDATE_INDEXES("validate_indexes", new CacheValidateIndexes()),
-
- /**
- * Check secondary indexes inline size.
- */
- CHECK_INDEX_INLINE_SIZES("check_index_inline_sizes", new
CheckIndexInlineSizes()),
-
- /**
- * Prints info about contended keys (the keys concurrently locked from
multiple transactions).
- */
- CONTENTION("contention", new CacheContention()),
-
- /**
- * Collect information on the distribution of partitions.
- */
- DISTRIBUTION("distribution", new CacheDistribution()),
-
- /**
- * Reset lost partitions
- */
- RESET_LOST_PARTITIONS("reset_lost_partitions", new ResetLostPartitions()),
-
- /**
- * Find and remove garbage.
- */
- FIND_AND_DELETE_GARBAGE("find_garbage", new FindAndDeleteGarbage()),
-
- /**
- * Index list.
- */
- INDEX_LIST("indexes_list", new CacheIndexesList()),
-
- /**
- * Index rebuild status.
- */
- INDEX_REBUILD_STATUS("indexes_rebuild_status", new
CacheIndexesRebuildStatus()),
-
- /**
- * Index force rebuild.
- */
- INDEX_FORCE_REBUILD("indexes_force_rebuild", new
CacheIndexesForceRebuild()),
-
- /**
- * Enable, disable or show status for cache metrics.
- */
- METRICS("metrics", new CacheMetrics()),
-
- /**
- * Schedule index rebuild via the maintenance mode.
- */
- INDEX_REBUILD("schedule_indexes_rebuild", new
CacheScheduleIndexesRebuild());
-
- /** Enumerated values. */
- private static final CacheCommandList[] VALS = values();
-
- /** Name. */
- private final String name;
-
- /** */
- private final Command command;
-
- /**
- * @param name Name.
- * @param command Command implementation.
- */
- CacheCommandList(String name, Command command) {
- this.name = name;
- this.command = command;
- }
-
- /**
- * @param text Command text.
- * @return Command for the text.
- */
- public static CacheCommandList of(String text) {
- for (CacheCommandList cmd : CacheCommandList.values()) {
- if (cmd.text().equalsIgnoreCase(text))
- return cmd;
- }
-
- return null;
- }
-
- /**
- * @return Name.
- */
- public String text() {
- return name;
- }
-
- /**
- * @return Cache subcommand implementation.
- */
- public Command subcommand() {
- return command;
- }
-
- /**
- * Efficiently gets enumerated value from its ordinal.
- *
- * @param ord Ordinal value.
- * @return Enumerated value or {@code null} if ordinal out of range.
- */
- @Nullable public static CacheCommandList fromOrdinal(int ord) {
- return ord >= 0 && ord < VALS.length ? VALS[ord] : null;
- }
-
- /** {@inheritDoc} */
- @Override public String toString() {
- return name;
- }
-}
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
index b4ae21be3a1..f94b9fc2cdd 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheCommands.java
@@ -115,7 +115,7 @@ public class CacheCommands extends
AbstractCommand<CacheSubcommands> {
logger.info("");
logger.info(INDENT + "Subcommands:");
- Arrays.stream(CacheCommandList.values()).forEach(c -> {
+ Arrays.stream(CacheSubcommands.values()).forEach(c -> {
if (c.subcommand() != null) c.subcommand().printUsage(logger);
});
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java
index 8b64f8f4727..571b8129229 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/cache/CacheSubcommands.java
@@ -49,11 +49,26 @@ public enum CacheSubcommands {
*/
LIST("list", ListCommandArg.class, new CacheViewer()),
+ /**
+ * Destroy caches.
+ */
+ DESTROY("destroy", null, new CacheDestroy()),
+
+ /**
+ * Clear caches.
+ */
+ CLEAR("clear", null, new CacheClear()),
+
/**
* Validates indexes attempting to read each indexed entry.
*/
VALIDATE_INDEXES("validate_indexes", ValidateIndexesCommandArg.class, new
CacheValidateIndexes()),
+ /**
+ * Check secondary indexes inline size.
+ */
+ CHECK_INDEX_INLINE_SIZES("check_index_inline_sizes", null, new
CheckIndexInlineSizes()),
+
/**
* Prints info about contended keys (the keys concurrently locked from
multiple transactions).
*/
@@ -89,30 +104,15 @@ public enum CacheSubcommands {
*/
INDEX_FORCE_REBUILD("indexes_force_rebuild",
IndexForceRebuildCommandArg.class, new CacheIndexesForceRebuild()),
- /**
- * Index rebuild via the maintenance mode.
- */
- INDEX_REBUILD("schedule_indexes_rebuild", IndexRebuildCommandArg.class,
new CacheScheduleIndexesRebuild()),
-
- /**
- * Check secondary indexes inline size.
- */
- CHECK_INDEX_INLINE_SIZES("check_index_inline_sizes", null, new
CheckIndexInlineSizes()),
-
- /**
- * Destroy caches.
- */
- DESTROY("destroy", null, new CacheDestroy()),
-
/**
* Enable / disable cache metrics collection or show metrics collection
status.
*/
METRICS("metrics", null, new CacheMetrics()),
/**
- * Clear caches.
+ * Index rebuild via the maintenance mode.
*/
- CLEAR("clear", null, new CacheClear());
+ INDEX_REBUILD("schedule_indexes_rebuild", IndexRebuildCommandArg.class,
new CacheScheduleIndexesRebuild());
/** Enumerated values. */
private static final CacheSubcommands[] VALS = values();
diff --git
a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
index c2ee56ce044..b06ac82fb4b 100644
---
a/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
+++
b/modules/control-utility/src/test/java/org/apache/ignite/internal/commandline/CommandHandlerParsingTest.java
@@ -1189,7 +1189,7 @@ public class CommandHandlerParsingTest {
* @return Common parameters container object.
*/
private ConnectionAndSslParameters parseArgs(List<String> args) {
- return new CommonArgParser(setupTestLogger()).
+ return new CommonArgParser(setupTestLogger(), CommandList.commands()).
parseAndValidate(args.iterator());
}
diff --git a/modules/extdata/logo/licenses/apache-2.0.txt
b/modules/extdata/pluggable/licenses/apache-2.0.txt
similarity index 100%
rename from modules/extdata/logo/licenses/apache-2.0.txt
rename to modules/extdata/pluggable/licenses/apache-2.0.txt
diff --git a/modules/extdata/logo/pom.xml b/modules/extdata/pluggable/pom.xml
similarity index 89%
rename from modules/extdata/logo/pom.xml
rename to modules/extdata/pluggable/pom.xml
index 3cddb24d8cc..fa93410f4bc 100644
--- a/modules/extdata/logo/pom.xml
+++ b/modules/extdata/pluggable/pom.xml
@@ -29,7 +29,7 @@
<relativePath>../../../parent-internal/pom.xml</relativePath>
</parent>
- <artifactId>ignite-extdata-logo</artifactId>
+ <artifactId>ignite-extdata-pluggable</artifactId>
<url>https://ignite.apache.org</url>
<dependencies>
@@ -78,6 +78,19 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>ignite-control-utility</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>ignite-control-utility</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
diff --git
a/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/commandline/CommandsProviderExtImpl.java
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/commandline/CommandsProviderExtImpl.java
new file mode 100644
index 00000000000..06282f7372a
--- /dev/null
+++
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/commandline/CommandsProviderExtImpl.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.commandline;
+
+import java.util.Collections;
+import java.util.Map;
+import org.apache.ignite.IgniteLogger;
+import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.util.typedef.F;
+
+/**
+ * Additional commands provider for control utility.
+ */
+public class CommandsProviderExtImpl implements CommandsProvider {
+ /** */
+ public static final Command<?> TEST_COMMAND = new TestCommand();
+
+ /** */
+ public static final String TEST_COMMAND_OUTPUT = "Test command executed";
+
+ /** */
+ public static final String TEST_COMMAND_USAGE = "Test command usage.";
+
+ /** */
+ public static final String TEST_COMMAND_ARG = "test-print";
+
+ /** {@inheritDoc} */
+ @Override public Map<String, Command<?>> commands() {
+ return Collections.singletonMap(TEST_COMMAND.name(), TEST_COMMAND);
+ }
+
+ /** */
+ public static class TestCommand extends AbstractCommand<Object> {
+ /** */
+ private String arg;
+
+ /** {@inheritDoc} */
+ @Override public Object execute(GridClientConfiguration clientCfg,
IgniteLogger log) {
+ log.info(TEST_COMMAND_OUTPUT + ": " + arg);
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void parseArguments(CommandArgIterator argIter) {
+ String cmdArg = argIter.nextArg("Required 1-st argument");
+
+ if (TEST_COMMAND_ARG.equals(cmdArg))
+ arg = argIter.nextArg("Required 2-nd argument");
+ else
+ throw new IllegalArgumentException("Invalid argument \"" +
cmdArg + "\".");
+
+ if (argIter.hasNextSubArg()) {
+ throw new IllegalArgumentException(
+ "Invalid argument \"" + argIter.peekNextArg() + "\", no
more arguments is expected.");
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public Object arg() {
+ return arg;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void printUsage(IgniteLogger log) {
+ usage(log, TEST_COMMAND_USAGE, TEST_COMMAND.name(),
F.asMap("value", "Value to print"),
+ TEST_COMMAND_ARG, "value");
+ }
+
+ /** {@inheritDoc} */
+ @Override public String name() {
+ return "--test-command";
+ }
+ }
+}
diff --git
a/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/commandline/ExtendedControlUtilityTest.java
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/commandline/ExtendedControlUtilityTest.java
new file mode 100644
index 00000000000..8631898b274
--- /dev/null
+++
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/commandline/ExtendedControlUtilityTest.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.commandline;
+
+import org.apache.ignite.util.GridCommandHandlerAbstractTest;
+import org.junit.Test;
+
+import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_INVALID_ARGUMENTS;
+import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+import static org.apache.ignite.testframework.GridTestUtils.assertContains;
+
+/**
+ * Tests control-utility extension.
+ */
+public class ExtendedControlUtilityTest extends GridCommandHandlerAbstractTest
{
+ /**
+ * Tests additional command for control-utility works.
+ */
+ @Test
+ public void testAdditionalCommand() {
+ autoConfirmation = false;
+
+ injectTestSystemOut();
+
+ String testVal = "test value";
+
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS,
execute(CommandsProviderExtImpl.TEST_COMMAND.name()));
+
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS,
execute(CommandsProviderExtImpl.TEST_COMMAND.name(),
+ CommandsProviderExtImpl.TEST_COMMAND_ARG));
+
+ assertEquals(EXIT_CODE_INVALID_ARGUMENTS,
execute(CommandsProviderExtImpl.TEST_COMMAND.name(),
+ "unknownSubcommand", testVal));
+
+ assertEquals(EXIT_CODE_OK,
execute(CommandsProviderExtImpl.TEST_COMMAND.name(),
+ CommandsProviderExtImpl.TEST_COMMAND_ARG, testVal));
+
+ assertContains(log, testOut.toString(),
CommandsProviderExtImpl.TEST_COMMAND_OUTPUT);
+ assertContains(log, testOut.toString(), testVal);
+ }
+
+ /**
+ * Tests usage help for additional commands.
+ */
+ @Test
+ public void testAdditionalCommandHelp() {
+ injectTestSystemOut();
+
+ assertEquals(EXIT_CODE_OK, execute("--help"));
+
+ String testOutStr = testOut.toString();
+
+ assertContains(log, testOutStr,
CommandsProviderExtImpl.TEST_COMMAND_USAGE);
+ assertContains(log, testOutStr,
CommandsProviderExtImpl.TEST_COMMAND_ARG);
+ }
+}
diff --git
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/IgniteExtendedLogoTest.java
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/plugin/ExtendedLogoTest.java
similarity index 93%
rename from
modules/extdata/logo/src/test/java/org/apache/ignite/internal/IgniteExtendedLogoTest.java
rename to
modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/plugin/ExtendedLogoTest.java
index 497d6202c3f..7bc7c7553d2 100644
---
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/IgniteExtendedLogoTest.java
+++
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/plugin/ExtendedLogoTest.java
@@ -15,7 +15,7 @@
* limitations under the License.
*/
-package org.apache.ignite.internal;
+package org.apache.ignite.internal.plugin;
import org.apache.ignite.testframework.ListeningTestLogger;
import org.apache.ignite.testframework.LogListener;
@@ -25,7 +25,7 @@ import org.junit.Test;
import static org.apache.ignite.testframework.GridTestUtils.waitForCondition;
/** */
-public class IgniteExtendedLogoTest extends GridCommonAbstractTest {
+public class ExtendedLogoTest extends GridCommonAbstractTest {
/** @throws Exception If fails. */
@Test
public void testExtendedLogo() throws Exception {
diff --git
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/plugin/IgniteExtLogInfoProviderImpl.java
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/plugin/IgniteExtLogInfoProviderImpl.java
similarity index 100%
rename from
modules/extdata/logo/src/test/java/org/apache/ignite/internal/plugin/IgniteExtLogInfoProviderImpl.java
rename to
modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/plugin/IgniteExtLogInfoProviderImpl.java
diff --git
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/testsuites/IgniteLogoExtensionTestSuite.java
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/testsuites/IgnitePluggableExtensionsTestSuite.java
similarity index 77%
rename from
modules/extdata/logo/src/test/java/org/apache/ignite/internal/testsuites/IgniteLogoExtensionTestSuite.java
rename to
modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/testsuites/IgnitePluggableExtensionsTestSuite.java
index 36fea9f9d2f..a22175e865c 100644
---
a/modules/extdata/logo/src/test/java/org/apache/ignite/internal/testsuites/IgniteLogoExtensionTestSuite.java
+++
b/modules/extdata/pluggable/src/test/java/org/apache/ignite/internal/testsuites/IgnitePluggableExtensionsTestSuite.java
@@ -17,16 +17,18 @@
package org.apache.ignite.internal.testsuites;
-import org.apache.ignite.internal.IgniteExtendedLogoTest;
+import org.apache.ignite.internal.commandline.ExtendedControlUtilityTest;
+import org.apache.ignite.internal.plugin.ExtendedLogoTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
/**
- * Info provider test suite.
+ * Pluggable extensions test suite.
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
- IgniteExtendedLogoTest.class
+ ExtendedLogoTest.class,
+ ExtendedControlUtilityTest.class,
})
-public class IgniteLogoExtensionTestSuite {
+public class IgnitePluggableExtensionsTestSuite {
}
diff --git
a/modules/extdata/pluggable/src/test/resources/META-INF/services/org.apache.ignite.internal.commandline.CommandsProvider
b/modules/extdata/pluggable/src/test/resources/META-INF/services/org.apache.ignite.internal.commandline.CommandsProvider
new file mode 100644
index 00000000000..a73af84557e
--- /dev/null
+++
b/modules/extdata/pluggable/src/test/resources/META-INF/services/org.apache.ignite.internal.commandline.CommandsProvider
@@ -0,0 +1 @@
+org.apache.ignite.internal.commandline.CommandsProviderExtImpl
diff --git
a/modules/extdata/logo/src/test/resources/META-INF/services/org.apache.ignite.internal.plugin.IgniteLogInfoProvider
b/modules/extdata/pluggable/src/test/resources/META-INF/services/org.apache.ignite.internal.plugin.IgniteLogInfoProvider
similarity index 100%
rename from
modules/extdata/logo/src/test/resources/META-INF/services/org.apache.ignite.internal.plugin.IgniteLogInfoProvider
rename to
modules/extdata/pluggable/src/test/resources/META-INF/services/org.apache.ignite.internal.plugin.IgniteLogInfoProvider
diff --git a/pom.xml b/pom.xml
index 7b1c60baec6..09611276dad 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
<module>modules/extdata/p2p</module>
<module>modules/extdata/uri</module>
<module>modules/extdata/platform</module>
- <module>modules/extdata/logo</module>
+ <module>modules/extdata/pluggable</module>
<module>modules/clients</module>
<module>modules/spring</module>
<module>modules/web</module>