This is an automated email from the ASF dual-hosted git repository.
namelchev 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 d28bb13b862 IGNITE-18278 Add the ability to get a view from multiple
nodes in the control utility. (#10405)
d28bb13b862 is described below
commit d28bb13b8622913482548772e320fbd5ef17ef83
Author: Nikita Amelchev <[email protected]>
AuthorDate: Wed Nov 30 18:51:42 2022 +0300
IGNITE-18278 Add the ability to get a view from multiple nodes in the
control utility. (#10405)
---
.../ignite/internal/commandline/TaskExecutor.java | 2 +-
.../commandline/systemview/SystemViewCommand.java | 116 ++++++++++++-----
.../systemview/SystemViewCommandArg.java | 15 ++-
.../apache/ignite/util/SystemViewCommandTest.java | 142 +++++++++++++++++----
.../visor/systemview/VisorSystemViewTask.java | 33 ++++-
.../systemview/VisorSystemViewTaskResult.java | 29 ++---
...ridCommandHandlerClusterByClassTest_help.output | 8 +-
...andHandlerClusterByClassWithSSLTest_help.output | 8 +-
8 files changed, 269 insertions(+), 84 deletions(-)
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java
index c798d45fc63..b4f88cb4e84 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/TaskExecutor.java
@@ -187,7 +187,7 @@ public class TaskExecutor {
* @param compute instance
* @return balanced node
*/
- private static GridClientNode getBalancedNode(GridClientCompute compute)
throws GridClientException {
+ public static GridClientNode getBalancedNode(GridClientCompute compute)
throws GridClientException {
Collection<GridClientNode> nodes =
compute.nodes(GridClientNode::connectable);
if (F.isEmpty(nodes))
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommand.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommand.java
index 92f0e27e1e3..97ced5ecc86 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommand.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommand.java
@@ -19,8 +19,8 @@ package org.apache.ignite.internal.commandline.systemview;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
@@ -28,12 +28,17 @@ import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.ignite.IgniteLogger;
import org.apache.ignite.internal.client.GridClient;
+import org.apache.ignite.internal.client.GridClientCompute;
import org.apache.ignite.internal.client.GridClientConfiguration;
+import org.apache.ignite.internal.client.GridClientNode;
import org.apache.ignite.internal.commandline.AbstractCommand;
import org.apache.ignite.internal.commandline.Command;
import org.apache.ignite.internal.commandline.CommandArgIterator;
import org.apache.ignite.internal.commandline.CommandLogger;
import org.apache.ignite.internal.commandline.argument.CommandArgUtils;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.apache.ignite.internal.visor.VisorTaskArgument;
import org.apache.ignite.internal.visor.systemview.VisorSystemViewTask;
import
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType;
import org.apache.ignite.internal.visor.systemview.VisorSystemViewTaskArg;
@@ -41,10 +46,14 @@ import
org.apache.ignite.internal.visor.systemview.VisorSystemViewTaskResult;
import org.apache.ignite.spi.systemview.view.SystemView;
import static java.util.Collections.nCopies;
+import static java.util.Collections.singleton;
import static org.apache.ignite.internal.commandline.CommandList.SYSTEM_VIEW;
import static org.apache.ignite.internal.commandline.CommandLogger.optional;
-import static
org.apache.ignite.internal.commandline.TaskExecutor.executeTaskByNameOnNode;
+import static org.apache.ignite.internal.commandline.CommandLogger.or;
+import static
org.apache.ignite.internal.commandline.TaskExecutor.getBalancedNode;
+import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.ALL_NODES;
import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.NODE_ID;
+import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.NODE_IDS;
import static
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.DATE;
import static
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.NUMBER;
import static
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.STRING;
@@ -60,8 +69,11 @@ public class SystemViewCommand extends
AbstractCommand<VisorSystemViewTaskArg> {
*/
private VisorSystemViewTaskArg taskArg;
- /** ID of the node to get the system view content from. */
- private UUID nodeId;
+ /** ID of the nodes to get the system view content from. */
+ private Collection<UUID> nodeIds;
+
+ /** Flag to get the system view from all nodes. */
+ private boolean allNodes;
/** {@inheritDoc} */
@Override public Object execute(GridClientConfiguration clientCfg,
IgniteLogger log) throws Exception {
@@ -69,17 +81,42 @@ public class SystemViewCommand extends
AbstractCommand<VisorSystemViewTaskArg> {
VisorSystemViewTaskResult res;
try (GridClient client = Command.startClient(clientCfg)) {
- res = executeTaskByNameOnNode(
- client,
- VisorSystemViewTask.class.getName(),
- taskArg,
- nodeId,
- clientCfg
- );
+ GridClientCompute compute = client.compute();
+
+ Map<UUID, GridClientNode> clusterNodes =
compute.nodes().stream()
+ .collect(Collectors.toMap(GridClientNode::nodeId, n -> n));
+
+ if (allNodes)
+ nodeIds = clusterNodes.keySet();
+ else if (F.isEmpty(nodeIds))
+ nodeIds = singleton(getBalancedNode(compute).nodeId());
+ else {
+ for (UUID id : nodeIds) {
+ if (!clusterNodes.containsKey(id))
+ throw new IllegalArgumentException("Node with id="
+ id + " not found.");
+ }
+ }
+
+ Collection<GridClientNode> connectable =
F.viewReadOnly(nodeIds, clusterNodes::get,
+ id -> clusterNodes.get(id).connectable());
+
+ if (!F.isEmpty(connectable))
+ compute = compute.projection(connectable);
+
+ res = compute.execute(VisorSystemViewTask.class.getName(),
+ new VisorTaskArgument<>(nodeIds, taskArg, false));
}
- if (res != null)
- printTable(res.attributes(), res.types(), res.rows(), log);
+ if (res != null) {
+ res.rows().forEach((nodeId, rows) -> {
+ log.info("Results from node with ID: " + nodeId);
+ log.info("---");
+
+ printTable(res.attributes(), res.types(), rows, log);
+
+ log.info("---" + U.nl());
+ });
+ }
else
log.info("No system view with specified name was found [name="
+ taskArg.systemViewName() + "]");
@@ -161,7 +198,8 @@ public class SystemViewCommand extends
AbstractCommand<VisorSystemViewTaskArg> {
/** {@inheritDoc} */
@Override public void parseArguments(CommandArgIterator argIter) {
- nodeId = null;
+ nodeIds = null;
+ allNodes = false;
String sysViewName = null;
@@ -170,19 +208,27 @@ public class SystemViewCommand extends
AbstractCommand<VisorSystemViewTaskArg> {
SystemViewCommandArg cmdArg = CommandArgUtils.of(arg,
SystemViewCommandArg.class);
- if (cmdArg == NODE_ID) {
- String nodeIdArg = argIter.nextArg(
- "ID of the node from which system view content should be
obtained is expected.");
-
- try {
- nodeId = UUID.fromString(nodeIdArg);
- }
- catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Failed to parse " +
NODE_ID + " command argument." +
- " String representation of \"java.util.UUID\" is
exepected. For example:" +
- " 123e4567-e89b-42d3-a456-556642440000", e);
- }
+ if (cmdArg == NODE_ID || cmdArg == NODE_IDS) {
+ if (nodeIds != null)
+ throw new IllegalArgumentException("Only one of " +
NODE_ID + ", " + NODE_IDS + " commands is expected.");
+
+ String idsArg = argIter.nextArg(
+ cmdArg == NODE_ID ? "ID of the node from which system view
content should be obtained is expected." :
+ "Comma-separated list of node IDs from which system
view content should be obtained is expected.");
+
+ nodeIds = F.viewReadOnly(argIter.parseStringSet(idsArg), name
-> {
+ try {
+ return UUID.fromString(name);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Failed to parse "
+ (cmdArg == NODE_ID ? NODE_ID : NODE_IDS) +
+ " command argument. String representation of
\"java.util.UUID\" is exepected. For example:" +
+ " 123e4567-e89b-42d3-a456-556642440000", e);
+ }
+ });
}
+ else if (cmdArg == ALL_NODES)
+ allNodes = true;
else {
if (sysViewName != null)
throw new IllegalArgumentException("Multiple system view
names are not supported.");
@@ -191,6 +237,9 @@ public class SystemViewCommand extends
AbstractCommand<VisorSystemViewTaskArg> {
}
}
+ if (allNodes && !F.isEmpty(nodeIds))
+ throw new IllegalArgumentException("The " + ALL_NODES + "
parameter cannot be used with specified node IDs.");
+
if (sysViewName == null) {
throw new IllegalArgumentException(
"The name of the system view for which its content should be
printed is expected.");
@@ -206,15 +255,20 @@ public class SystemViewCommand extends
AbstractCommand<VisorSystemViewTaskArg> {
/** {@inheritDoc} */
@Override public void printUsage(IgniteLogger log) {
- Map<String, String> params = new HashMap<>();
+ Map<String, String> params = new LinkedHashMap<>();
- params.put("node_id", "ID of the node to get the system view from. If
not set, random node will be chosen.");
params.put("system_view_name", "Name of the system view which content
should be printed." +
" Both \"SQL\" and \"Java\" styles of system view name are
supported" +
" (e.g. SQL_TABLES and sql.tables will be handled similarly).");
-
- usage(log, "Print system view content:", SYSTEM_VIEW, params,
optional(NODE_ID, "node_id"),
- "system_view_name");
+ params.put(NODE_ID + " node_id", "ID of the node to get the system
view from (deprecated. Use " + NODE_IDS + " instead). " +
+ "If not set, random node will be chosen.");
+ params.put(NODE_IDS + " nodeId1,nodeId2,..",
+ "Comma-separated list of nodes IDs to get the system view from. If
not set, random node will be chosen.");
+ params.put(ALL_NODES.argName(),
+ "Get the system view from all nodes. If not set, random node will
be chosen.");
+
+ usage(log, "Print system view content:", SYSTEM_VIEW, params,
"system_view_name",
+ or(optional(NODE_ID, "node_id"), optional(NODE_IDS,
"nodeId1,nodeId2,.."), optional(ALL_NODES)));
}
/** {@inheritDoc} */
diff --git
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommandArg.java
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommandArg.java
index 1462eedca12..f712666f85b 100644
---
a/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommandArg.java
+++
b/modules/control-utility/src/main/java/org/apache/ignite/internal/commandline/systemview/SystemViewCommandArg.java
@@ -21,8 +21,19 @@ import
org.apache.ignite.internal.commandline.argument.CommandArg;
/** Represents all possible arguments for {@link SystemViewCommand}. */
public enum SystemViewCommandArg implements CommandArg {
- /** Id of the node to get the system view from. */
- NODE_ID("--node-id");
+ /**
+ * Id of the node to get the system view from.
+ *
+ * @deprecated Use {@link SystemViewCommandArg#NODE_IDS} instead.
+ */
+ @Deprecated
+ NODE_ID("--node-id"),
+
+ /** Node IDs to get the system view from. */
+ NODE_IDS("--node-ids"),
+
+ /** Get the system view from all nodes. */
+ ALL_NODES("--all-nodes");
/** Name of the argument. */
private final String name;
diff --git
a/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
b/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
index 5f621e27fe0..64b50216e8c 100644
---
a/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
+++
b/modules/control-utility/src/test/java/org/apache/ignite/util/SystemViewCommandTest.java
@@ -22,8 +22,12 @@ import java.net.InetSocketAddress;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;
@@ -32,6 +36,8 @@ import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
@@ -66,6 +72,8 @@ import
org.apache.ignite.internal.processors.cache.persistence.IgniteCacheDataba
import
org.apache.ignite.internal.processors.metastorage.DistributedMetaStorage;
import org.apache.ignite.internal.processors.service.DummyService;
import org.apache.ignite.internal.util.StripedExecutor;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.G;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.systemview.VisorSystemViewTask;
import org.apache.ignite.services.ServiceConfiguration;
@@ -85,7 +93,10 @@ import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_IN
import static
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
import static org.apache.ignite.internal.commandline.CommandList.SYSTEM_VIEW;
import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommand.COLUMN_SEPARATOR;
+import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.ALL_NODES;
import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.NODE_ID;
+import static
org.apache.ignite.internal.commandline.systemview.SystemViewCommandArg.NODE_IDS;
+import static
org.apache.ignite.internal.managers.discovery.GridDiscoveryManager.NODES_SYS_VIEW;
import static
org.apache.ignite.internal.managers.systemview.ScanQuerySystemView.SCAN_QRY_SYS_VIEW;
import static
org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_PREDICATE;
import static
org.apache.ignite.internal.metric.SystemViewSelfTest.TEST_TRANSFORMER;
@@ -203,6 +214,21 @@ public class SystemViewCommandTest extends
GridCommandHandlerClusterByClassAbstr
"Multiple system view names are not supported.");
}
+ /**
+ * Tests command error output in case {@link
SystemViewCommandArg#ALL_NODES} and
+ * {@link SystemViewCommandArg#NODE_IDS} are both specified.
+ */
+ @Test
+ public void testAllNodesAndNodeIds() {
+ assertContains(log, executeCommand(EXIT_CODE_INVALID_ARGUMENTS,
+ CMD_SYS_VIEW, SVCS_VIEW, ALL_NODES.argName(),
NODE_IDS.argName(), ignite0.localNode().id().toString()),
+ "The " + ALL_NODES.argName() + " parameter cannot be used with
specified node IDs.");
+
+ assertContains(log, executeCommand(EXIT_CODE_INVALID_ARGUMENTS,
+ CMD_SYS_VIEW, SVCS_VIEW, ALL_NODES.argName(),
NODE_ID.argName(), ignite0.localNode().id().toString()),
+ "The " + ALL_NODES.argName() + " parameter cannot be used with
specified node IDs.");
+ }
+
/**
* Tests command error output in case {@link SystemViewCommandArg#NODE_ID}
argument value refers to nonexistent
* node.
@@ -1125,6 +1151,36 @@ public class SystemViewCommandTest extends
GridCommandHandlerClusterByClassAbstr
assertEquals(srvCnt, systemView(ignite0, SNAPSHOT_SYS_VIEW).size());
}
+ /** */
+ @Test
+ public void testMultipleNodes() {
+ checkNodesResult(Collections.singleton(ignite0), NODE_IDS.argName());
+ checkNodesResult(Collections.singleton(client), NODE_IDS.argName());
+
+ checkNodesResult(F.asList(ignite0, ignite1), NODE_IDS.argName());
+ checkNodesResult(F.asList(ignite0, ignite1, client),
NODE_IDS.argName());
+
+ checkNodesResult(F.viewReadOnly(G.allGrids(), node -> (IgniteEx)node),
ALL_NODES.argName());
+ }
+
+ /** */
+ private void checkNodesResult(Collection<IgniteEx> nodes, String nodesArg)
{
+ Map<UUID, List<List<String>>> map = systemView(nodes, NODES_SYS_VIEW,
nodesArg);
+
+ assertEquals(nodes.size(), map.size());
+
+ map.forEach((nodeId, rows) -> {
+ assertEquals(ignite0.cluster().nodes().size(), rows.size());
+
+ for (List<String> row : rows) {
+ UUID rowNodeId = UUID.fromString(row.get(0));
+ boolean isLocal = Boolean.parseBoolean(row.get(8));
+
+ assertEquals(nodeId.equals(rowNodeId), isLocal);
+ }
+ });
+ }
+
/**
* Execute query on given node.
*
@@ -1148,9 +1204,26 @@ public class SystemViewCommandTest extends
GridCommandHandlerClusterByClassAbstr
* @return Content of the requested system view.
*/
private List<List<String>> systemView(IgniteEx node, String sysViewName) {
+ Map<UUID, List<List<String>>> map =
systemView(Collections.singleton(node), sysViewName, NODE_ID.argName());
+
+ assertEquals(1, map.size());
+
+ return map.get(node.localNode().id());
+ }
+
+ /**
+ * Gets system view content via control utility from specified nodes. Here
we also check if attributes names
+ * returned by the command match the real ones. And that both "SQL" and
"Java" command names styles are supported.
+ *
+ * @param nodes Nodes to obtain system view from.
+ * @param sysViewName Name of the system view which content is required.
+ * @param nodesArg Argument to specify nodes.
+ * @return Content of the requested system view.
+ */
+ private Map<UUID, List<List<String>>> systemView(Collection<IgniteEx>
nodes, String sysViewName, String nodesArg) {
List<String> attrNames = new ArrayList<>();
- SystemView<?> sysView = node.context().systemView().view(sysViewName);
+ SystemView<?> sysView =
nodes.iterator().next().context().systemView().view(sysViewName);
sysView.walker().visitAll(new AttributeVisitor() {
@Override public <T> void accept(int idx, String name, Class<T>
clazz) {
@@ -1158,28 +1231,29 @@ public class SystemViewCommandTest extends
GridCommandHandlerClusterByClassAbstr
}
});
- String nodeId = node.context().discovery().localNode().id().toString();
-
- List<List<String>> rows = parseSystemViewCommandOutput(
- executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW, toSqlName(sysViewName),
NODE_ID.argName(), nodeId));
+ int attrsCnt = sysView.walker().count();
- assertEquals(attrNames, rows.get(0));
+ Map<UUID, List<List<String>>> map = null;
- rows = parseSystemViewCommandOutput(
- executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW,
toSqlName(sysViewName).toLowerCase(), NODE_ID.argName(), nodeId));
+ for (String nameArg : F.asList(toSqlName(sysViewName),
toSqlName(sysViewName).toLowerCase(), sysViewName)) {
+ String[] args;
- assertEquals(attrNames, rows.get(0));
+ if (ALL_NODES.argName().equals(nodesArg))
+ args = new String[] {CMD_SYS_VIEW, nameArg,
ALL_NODES.argName()};
+ else {
+ String nodeIds = String.join(",", F.viewReadOnly(nodes, n ->
n.localNode().id().toString()));
- rows = parseSystemViewCommandOutput(
- executeCommand(EXIT_CODE_OK, CMD_SYS_VIEW, sysViewName,
NODE_ID.argName(), nodeId));
+ args = new String[] {CMD_SYS_VIEW, nameArg, nodesArg, nodeIds};
+ }
- assertEquals(attrNames, rows.remove(0));
+ map = parseSystemViewCommandOutput(executeCommand(EXIT_CODE_OK,
args));
- int attrsCnt = sysView.walker().count();
+ map.values().forEach(rows -> rows.forEach(row ->
assertEquals(attrsCnt, row.size())));
- rows.forEach(row -> assertEquals(attrsCnt, row.size()));
+ map.values().forEach(rows -> assertEquals(attrNames,
rows.remove(0)));
+ }
- return rows;
+ return map;
}
/**
@@ -1188,22 +1262,46 @@ public class SystemViewCommandTest extends
GridCommandHandlerClusterByClassAbstr
* @param out Command output to parse.
* @return System view values.
*/
- private List<List<String>> parseSystemViewCommandOutput(String out) {
+ private Map<UUID, List<List<String>>> parseSystemViewCommandOutput(String
out) {
String outStart =
"--------------------------------------------------------------------------------";
String outEnd = "Command [" + SYSTEM_VIEW.toCommandName() + "]
finished with code: " + EXIT_CODE_OK;
- List<String> rows = Arrays.asList(out.substring(
+ String[] rows = out.substring(
out.indexOf(outStart) + outStart.length() + 1,
out.indexOf(outEnd) - 1
- ).split(U.nl()));
+ ).split(U.nl());
+
+ Pattern nodePtrn = Pattern.compile("Results from node with ID: (.*)");
+ String tableDelim = "---";
- return rows.stream().map(row ->
- Arrays.stream(row.split(quote(COLUMN_SEPARATOR)))
+ Map<UUID, List<List<String>>> res = new HashMap<>();
+
+ UUID currNodeId = null;
+
+ for (String rowStr : rows) {
+ Matcher nodeMatcher = nodePtrn.matcher(rowStr);
+
+ if (nodeMatcher.matches()) {
+ currNodeId = UUID.fromString(nodeMatcher.group(1));
+
+ continue;
+ }
+
+ if (tableDelim.equals(rowStr) || rowStr.isEmpty())
+ continue;
+
+ assertNotNull("Expected node ID: " + out, currNodeId);
+
+ List<String> row =
Arrays.stream(rowStr.split(quote(COLUMN_SEPARATOR)))
.map(String::trim)
.filter(str -> !str.isEmpty())
- .collect(Collectors.toList()))
- .collect(Collectors.toList());
+ .collect(Collectors.toList());
+
+ res.computeIfAbsent(currNodeId, id -> new ArrayList<>()).add(row);
+ }
+
+ return res;
}
/**
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTask.java
b/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTask.java
index 6f6e0154553..b4b86691a40 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTask.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTask.java
@@ -21,20 +21,24 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import java.util.UUID;
import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
import org.apache.ignite.internal.managers.systemview.GridSystemViewManager;
import org.apache.ignite.internal.processors.task.GridInternal;
import org.apache.ignite.internal.processors.task.GridVisorManagementTask;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.internal.visor.VisorJob;
-import org.apache.ignite.internal.visor.VisorOneNodeTask;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
import org.apache.ignite.lang.IgniteUuid;
import org.apache.ignite.spi.systemview.view.SystemView;
import org.apache.ignite.spi.systemview.view.SystemViewRowAttributeWalker;
import
org.apache.ignite.spi.systemview.view.SystemViewRowAttributeWalker.AttributeWithValueVisitor;
import org.jetbrains.annotations.Nullable;
+import static java.util.Collections.singletonMap;
import static
org.apache.ignite.internal.processors.metric.impl.MetricUtils.toSqlName;
import static
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.DATE;
import static
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType.NUMBER;
@@ -43,7 +47,8 @@ import static
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.Si
/** Reperesents visor task for obtaining system view content. */
@GridInternal
@GridVisorManagementTask
-public class VisorSystemViewTask extends
VisorOneNodeTask<VisorSystemViewTaskArg, VisorSystemViewTaskResult> {
+public class VisorSystemViewTask extends
VisorMultiNodeTask<VisorSystemViewTaskArg, VisorSystemViewTaskResult,
+ VisorSystemViewTaskResult> {
/** */
private static final long serialVersionUID = 0L;
@@ -52,6 +57,28 @@ public class VisorSystemViewTask extends
VisorOneNodeTask<VisorSystemViewTaskArg
return new VisorSystemViewJob(arg, false);
}
+ /** {@inheritDoc} */
+ @Override protected @Nullable VisorSystemViewTaskResult
reduce0(List<ComputeJobResult> results)
+ throws IgniteException {
+ VisorSystemViewTaskResult res = null;
+
+ Map<UUID, List<List<?>>> merged = new TreeMap<>();
+
+ for (ComputeJobResult r : results) {
+ if (r.getException() != null)
+ throw new IgniteException("Failed to execute job [nodeId=" +
r.getNode().id() + ']', r.getException());
+
+ res = r.getData();
+
+ if (res == null)
+ return null;
+
+ merged.putAll(res.rows());
+ }
+
+ return new VisorSystemViewTaskResult(res.attributes(), res.types(),
merged);
+ }
+
/** */
private static class VisorSystemViewJob extends
VisorJob<VisorSystemViewTaskArg, VisorSystemViewTaskResult> {
/** */
@@ -149,7 +176,7 @@ public class VisorSystemViewTask extends
VisorOneNodeTask<VisorSystemViewTaskArg
rows.add(attrVals);
}
- return new VisorSystemViewTaskResult(attrNames, attrTypes, rows);
+ return new VisorSystemViewTaskResult(attrNames, attrTypes,
singletonMap(ignite.localNode().id(), rows));
}
/**
diff --git
a/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTaskResult.java
b/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTaskResult.java
index 313ccf45538..91522d1099b 100644
---
a/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTaskResult.java
+++
b/modules/core/src/main/java/org/apache/ignite/internal/visor/systemview/VisorSystemViewTaskResult.java
@@ -20,8 +20,9 @@ package org.apache.ignite.internal.visor.systemview;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
-import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.UUID;
import org.apache.ignite.internal.dto.IgniteDataTransferObject;
import org.apache.ignite.internal.util.typedef.internal.U;
import
org.apache.ignite.internal.visor.systemview.VisorSystemViewTask.SimpleType;
@@ -31,8 +32,8 @@ public class VisorSystemViewTaskResult extends
IgniteDataTransferObject {
/** */
private static final long serialVersionUID = 0L;
- /** Attribute values for each row of the system view. */
- private List<List<?>> rows;
+ /** Attribute values for each row of the system view per node ID. */
+ private Map<UUID, List<List<?>>> rows;
/** Names of the system view attributes. */
private List<String> attrs;
@@ -48,9 +49,9 @@ public class VisorSystemViewTaskResult extends
IgniteDataTransferObject {
/**
* @param attrs Names of system view attributes.
* @param types Types of the system view attributes.
- * @param rows Attribute values for each row of the system view.
+ * @param rows Attribute values for each row of the system view per node
ID.
*/
- public VisorSystemViewTaskResult(List<String> attrs, List<SimpleType>
types, List<List<?>> rows) {
+ public VisorSystemViewTaskResult(List<String> attrs, List<SimpleType>
types, Map<UUID, List<List<?>>> rows) {
this.attrs = attrs;
this.types = types;
this.rows = rows;
@@ -61,8 +62,8 @@ public class VisorSystemViewTaskResult extends
IgniteDataTransferObject {
return attrs;
}
- /** @return Attribute values for each row of the system view. */
- public List<List<?>> rows() {
+ /** @return Attribute values for each row of the system view per node ID.
*/
+ public Map<UUID, List<List<?>>> rows() {
return rows;
}
@@ -77,10 +78,7 @@ public class VisorSystemViewTaskResult extends
IgniteDataTransferObject {
U.writeCollection(out, types);
- out.writeInt(rows.size());
-
- for (List<?> row : rows)
- U.writeCollection(out, row);
+ U.writeMap(out, rows);
}
/** {@inheritDoc} */
@@ -89,13 +87,6 @@ public class VisorSystemViewTaskResult extends
IgniteDataTransferObject {
types = U.readList(in);
- int rowsCnt = in.readInt();
-
- List<List<?>> rows = new ArrayList<>(rowsCnt);
-
- for (int i = 0; i < rowsCnt; i++)
- rows.add(U.readList(in));
-
- this.rows = rows;
+ rows = U.readTreeMap(in);
}
}
diff --git
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index c1b37a48c3c..2b9eba75a01 100644
---
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -252,11 +252,13 @@ If the file name isn't specified the output file name is:
'<typeId>.bin'
control.(sh|bat) --property set --name <property_name> --val
<property_value>
Print system view content:
- control.(sh|bat) --system-view [--node-id node_id] system_view_name
+ control.(sh|bat) --system-view system_view_name [--node-id
node_id]|[--node-ids nodeId1,nodeId2,..]|[--all-nodes]
Parameters:
- system_view_name - Name of the system view which content should be
printed. Both "SQL" and "Java" styles of system view name are supported (e.g.
SQL_TABLES and sql.tables will be handled similarly).
- node_id - ID of the node to get the system view from. If not
set, random node will be chosen.
+ system_view_name - Name of the system view which content
should be printed. Both "SQL" and "Java" styles of system view name are
supported (e.g. SQL_TABLES and sql.tables will be handled similarly).
+ --node-id node_id - ID of the node to get the system view
from (deprecated. Use --node-ids instead). If not set, random node will be
chosen.
+ --node-ids nodeId1,nodeId2,.. - Comma-separated list of nodes IDs to
get the system view from. If not set, random node will be chosen.
+ --all-nodes - Get the system view from all nodes. If
not set, random node will be chosen.
Print metric value:
control.(sh|bat) --metric [--node-id node_id] name
diff --git
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index c1b37a48c3c..2b9eba75a01 100644
---
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -252,11 +252,13 @@ If the file name isn't specified the output file name is:
'<typeId>.bin'
control.(sh|bat) --property set --name <property_name> --val
<property_value>
Print system view content:
- control.(sh|bat) --system-view [--node-id node_id] system_view_name
+ control.(sh|bat) --system-view system_view_name [--node-id
node_id]|[--node-ids nodeId1,nodeId2,..]|[--all-nodes]
Parameters:
- system_view_name - Name of the system view which content should be
printed. Both "SQL" and "Java" styles of system view name are supported (e.g.
SQL_TABLES and sql.tables will be handled similarly).
- node_id - ID of the node to get the system view from. If not
set, random node will be chosen.
+ system_view_name - Name of the system view which content
should be printed. Both "SQL" and "Java" styles of system view name are
supported (e.g. SQL_TABLES and sql.tables will be handled similarly).
+ --node-id node_id - ID of the node to get the system view
from (deprecated. Use --node-ids instead). If not set, random node will be
chosen.
+ --node-ids nodeId1,nodeId2,.. - Comma-separated list of nodes IDs to
get the system view from. If not set, random node will be chosen.
+ --all-nodes - Get the system view from all nodes. If
not set, random node will be chosen.
Print metric value:
control.(sh|bat) --metric [--node-id node_id] name