You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sk...@apache.org on 2022/06/27 09:34:19 UTC
[ignite-3] branch main updated: IGNITE-17162 Fix init cluster command options. Fixes #895
This is an automated email from the ASF dual-hosted git repository.
sk0x50 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git
The following commit(s) were added to refs/heads/main by this push:
new fd2bd2d51 IGNITE-17162 Fix init cluster command options. Fixes #895
fd2bd2d51 is described below
commit fd2bd2d51e6bfac3d7d91981e215952f876e575c
Author: Vadim Pakhnushev <86...@users.noreply.github.com>
AuthorDate: Mon Jun 27 12:34:01 2022 +0300
IGNITE-17162 Fix init cluster command options. Fixes #895
Signed-off-by: Slava Koptilin <sl...@gmail.com>
---
modules/cli/pom.xml | 6 +
.../cli/deprecated/ItClusterCommandTest.java | 6 +-
.../ignite/cli/call/cluster/ClusterInitCall.java | 58 +++
.../cli/call/cluster/ClusterInitCallInput.java | 124 ++++++
.../ignite/cli/commands/TopLevelCliCommand.java | 2 +-
.../cli/commands/TopLevelCliReplCommand.java | 2 +-
.../cluster/ClusterCommand.java | 12 +-
.../cluster/ClusterInitReplSubCommand.java | 107 +++++
.../commands/cluster/ClusterInitSubCommand.java | 93 ++++
.../cluster/ClusterReplCommand.java | 11 +-
.../builtins/cluster/ClusterApiClient.java | 119 -----
.../builtins/cluster/InitClusterRequest.java | 51 ---
.../builtins/config/HttpClientFactory.java | 41 --
.../deprecated/builtins/config/package-info.java | 22 -
.../cli/deprecated/spec/ClusterCommandSpec.java | 95 ----
.../deprecated/spec/ClusterReplCommandSpec.java | 114 -----
.../cli/deprecated/IgniteCliInterfaceTest.java | 489 ++++++++-------------
parent/pom.xml | 7 +
18 files changed, 585 insertions(+), 774 deletions(-)
diff --git a/modules/cli/pom.xml b/modules/cli/pom.xml
index e95d9fef3..20699e8d2 100644
--- a/modules/cli/pom.xml
+++ b/modules/cli/pom.xml
@@ -225,6 +225,12 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.mock-server</groupId>
+ <artifactId>mockserver-netty</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<profiles>
diff --git a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItClusterCommandTest.java b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItClusterCommandTest.java
index d8168cb83..54568781c 100644
--- a/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItClusterCommandTest.java
+++ b/modules/cli/src/integrationTest/java/org/apache/ignite/cli/deprecated/ItClusterCommandTest.java
@@ -152,7 +152,7 @@ class ItClusterCommandTest extends AbstractCliIntegrationTest {
/**
* Starts a cluster of 4 nodes and executes init command on it. First node is used to issue the command via REST endpoint,
- * second will host the meta-storage RAFT group, third will host the Cluster Management RAFT Group (CMG), fourth
+ * second will host the Meta Storage, third will host the Cluster Management Group (CMG), fourth
* will be just a node.
*
* @param testInfo test info (used to derive node names)
@@ -161,7 +161,7 @@ class ItClusterCommandTest extends AbstractCliIntegrationTest {
void initClusterWithNodesOfDifferentRoles(TestInfo testInfo) {
int exitCode = cmd(ctx).execute(
"cluster", "init",
- "--node-endpoint", FIRST_NODE.restHostPort(),
+ "--cluster-url", FIRST_NODE.restHostPort(),
"--meta-storage-node", SECOND_NODE.nodeName(testInfo),
"--cmg-node", THIRD_NODE.nodeName(testInfo),
"--cluster-name", "ignite-cluster"
@@ -196,7 +196,7 @@ class ItClusterCommandTest extends AbstractCliIntegrationTest {
}
String restHostPort() {
- return "localhost:" + restPort;
+ return "http://localhost:" + restPort;
}
}
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/cluster/ClusterInitCall.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/cluster/ClusterInitCall.java
new file mode 100644
index 000000000..ec0f86296
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/cluster/ClusterInitCall.java
@@ -0,0 +1,58 @@
+/*
+ * 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.cli.call.cluster;
+
+import jakarta.inject.Singleton;
+import org.apache.ignite.cli.core.call.Call;
+import org.apache.ignite.cli.core.call.DefaultCallOutput;
+import org.apache.ignite.cli.core.exception.IgniteCliApiException;
+import org.apache.ignite.rest.client.api.ClusterManagementApi;
+import org.apache.ignite.rest.client.invoker.ApiClient;
+import org.apache.ignite.rest.client.invoker.ApiException;
+import org.apache.ignite.rest.client.invoker.Configuration;
+import org.apache.ignite.rest.client.model.InitCommand;
+
+/**
+ * Inits cluster.
+ */
+@Singleton
+public class ClusterInitCall implements Call<ClusterInitCallInput, String> {
+
+ /** {@inheritDoc} */
+ @Override
+ public DefaultCallOutput<String> execute(ClusterInitCallInput input) {
+ ClusterManagementApi client = createApiClient(input);
+
+ try {
+ client.init(new InitCommand()
+ .metaStorageNodes(input.getMetaStorageNodes())
+ .cmgNodes(input.getCmgNodes())
+ .clusterName(input.getClusterName())
+ );
+ return DefaultCallOutput.success("Cluster was initialized successfully.");
+ } catch (ApiException | IllegalArgumentException e) {
+ return DefaultCallOutput.failure(new IgniteCliApiException(e, input.getClusterUrl()));
+ }
+ }
+
+ private ClusterManagementApi createApiClient(ClusterInitCallInput input) {
+ ApiClient client = Configuration.getDefaultApiClient();
+ client.setBasePath(input.getClusterUrl());
+ return new ClusterManagementApi(client);
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/call/cluster/ClusterInitCallInput.java b/modules/cli/src/main/java/org/apache/ignite/cli/call/cluster/ClusterInitCallInput.java
new file mode 100644
index 000000000..0ed1e13dc
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/call/cluster/ClusterInitCallInput.java
@@ -0,0 +1,124 @@
+/*
+ * 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.cli.call.cluster;
+
+import java.util.List;
+import org.apache.ignite.cli.core.call.CallInput;
+
+/**
+ * Input for {@link ClusterInitCall}.
+ */
+public class ClusterInitCallInput implements CallInput {
+ private final String clusterUrl;
+ private final List<String> metaStorageNodes;
+ private final List<String> cmgNodes;
+ private final String clusterName;
+
+ private ClusterInitCallInput(
+ String clusterUrl,
+ List<String> metaStorageNodes,
+ List<String> cmgNodes,
+ String clusterName
+ ) {
+ this.clusterUrl = clusterUrl;
+ this.metaStorageNodes = metaStorageNodes;
+ this.cmgNodes = cmgNodes;
+ this.clusterName = clusterName;
+ }
+
+ /**
+ * Builder for {@link ClusterInitCallInput}.
+ */
+ public static ClusterInitCallInputBuilder builder() {
+ return new ClusterInitCallInputBuilder();
+ }
+
+ /**
+ * Gets cluster URL.
+ *
+ * @return Cluster URL.
+ */
+ public String getClusterUrl() {
+ return clusterUrl;
+ }
+
+ /**
+ * Consistent IDs of the nodes that will host the Meta Storage.
+ *
+ * @return Meta storage node ids.
+ */
+ public List<String> getMetaStorageNodes() {
+ return metaStorageNodes;
+ }
+
+ /**
+ * Consistent IDs of the nodes that will host the Cluster Management Group; if empty,
+ * {@code metaStorageNodeIds} will be used to host the CMG as well.
+ *
+ * @return Cluster management node ids.
+ */
+ public List<String> getCmgNodes() {
+ return cmgNodes;
+ }
+
+ /**
+ * Human-readable name of the cluster.
+ *
+ * @return Cluster name.
+ */
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ /**
+ * Builder for {@link ClusterInitCallInput}.
+ */
+ public static class ClusterInitCallInputBuilder {
+ private String clusterUrl;
+
+ private List<String> metaStorageNodes;
+
+ private List<String> cmgNodes;
+
+ private String clusterName;
+
+ public ClusterInitCallInputBuilder clusterUrl(String clusterUrl) {
+ this.clusterUrl = clusterUrl;
+ return this;
+ }
+
+ public ClusterInitCallInputBuilder metaStorageNodes(List<String> metaStorageNodes) {
+ this.metaStorageNodes = metaStorageNodes;
+ return this;
+ }
+
+ public ClusterInitCallInputBuilder cmgNodes(List<String> cmgNodes) {
+ this.cmgNodes = cmgNodes;
+ return this;
+ }
+
+ public ClusterInitCallInputBuilder clusterName(String clusterName) {
+ this.clusterName = clusterName;
+ return this;
+ }
+
+ public ClusterInitCallInput build() {
+ return new ClusterInitCallInput(clusterUrl, metaStorageNodes, cmgNodes, clusterName);
+ }
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java
index 981ed9ced..0e1844372 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliCommand.java
@@ -20,7 +20,7 @@ package org.apache.ignite.cli.commands;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.VersionProvider;
import org.apache.ignite.cli.commands.cliconfig.CliCommand;
-import org.apache.ignite.cli.commands.configuration.cluster.ClusterCommand;
+import org.apache.ignite.cli.commands.cluster.ClusterCommand;
import org.apache.ignite.cli.commands.configuration.node.NodeCommand;
import org.apache.ignite.cli.commands.sql.SqlCommand;
import org.apache.ignite.cli.commands.status.StatusCommand;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java
index db4766553..3a3185712 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/TopLevelCliReplCommand.java
@@ -19,7 +19,7 @@ package org.apache.ignite.cli.commands;
import jakarta.inject.Singleton;
import org.apache.ignite.cli.commands.cliconfig.CliCommand;
-import org.apache.ignite.cli.commands.configuration.cluster.ClusterReplCommand;
+import org.apache.ignite.cli.commands.cluster.ClusterReplCommand;
import org.apache.ignite.cli.commands.configuration.node.NodeReplCommand;
import org.apache.ignite.cli.commands.connect.ConnectCommand;
import org.apache.ignite.cli.commands.connect.DisconnectCommand;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterCommand.java
similarity index 74%
rename from modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterCommand.java
rename to modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterCommand.java
index 5b4d0e19c..d34feb032 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterCommand.java
@@ -15,20 +15,16 @@
* limitations under the License.
*/
-package org.apache.ignite.cli.commands.configuration.cluster;
+package org.apache.ignite.cli.commands.cluster;
-import org.apache.ignite.cli.deprecated.spec.ClusterCommandSpec;
+import org.apache.ignite.cli.commands.configuration.cluster.ClusterConfigSubCommand;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
/**
* Node command.
*/
@Command(name = "cluster",
- subcommands = {ClusterConfigSubCommand.class},
- description = "Cluster config operations.")
+ subcommands = {ClusterConfigSubCommand.class, ClusterInitSubCommand.class},
+ description = "Manages an Ignite cluster.")
public class ClusterCommand {
-
- @Mixin
- ClusterCommandSpec clusterCommandSpec;
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterInitReplSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterInitReplSubCommand.java
new file mode 100644
index 000000000..94747b225
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterInitReplSubCommand.java
@@ -0,0 +1,107 @@
+/*
+ * 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.cli.commands.cluster;
+
+import static picocli.CommandLine.Command;
+
+import jakarta.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.ignite.cli.call.cluster.ClusterInitCall;
+import org.apache.ignite.cli.call.cluster.ClusterInitCallInput;
+import org.apache.ignite.cli.call.cluster.ClusterInitCallInput.ClusterInitCallInputBuilder;
+import org.apache.ignite.cli.commands.BaseCommand;
+import org.apache.ignite.cli.core.call.CallExecutionPipeline;
+import org.apache.ignite.cli.core.repl.Session;
+import picocli.CommandLine.Option;
+
+/**
+ * Initializes an Ignite cluster.
+ */
+@Command(name = "init", description = "Initializes an Ignite cluster.")
+public class ClusterInitReplSubCommand extends BaseCommand implements Runnable {
+
+ /**
+ * Node url option.
+ */
+ @Option(
+ names = {"--cluster-url"}, description = "Url to ignite node.",
+ descriptionKey = "ignite.cluster-url", defaultValue = "http://localhost:10300"
+ )
+ private String clusterUrl;
+
+ /**
+ * List of names of the nodes (each represented by a separate command line argument) that will host the Meta Storage. If the
+ * "--cmg-nodes" parameter is omitted, the same nodes will also host the Cluster Management Group.
+ */
+ @Option(names = "--meta-storage-node", required = true, description = {
+ "Name of the node (repeat like '--meta-storage-node node1 --meta-storage-node node2' to specify more than one node)",
+ "that will host the Meta Storage.",
+ "If the --cmg-node parameter is omitted, the same nodes will also host the Cluster Management Group."
+ })
+ private List<String> metaStorageNodes;
+
+ /**
+ * List of names of the nodes (each represented by a separate command line argument) that will host the Cluster Management Group.
+ */
+ @Option(names = "--cmg-node", description = {
+ "Name of the node (repeat like '--cmg-node node1 --cmg-node node2' to specify more than one node)",
+ "that will host the Cluster Management Group.",
+ "If omitted, then --meta-storage-node values will also supply the nodes for the Cluster Management Group."
+ })
+ private List<String> cmgNodes = new ArrayList<>();
+
+ /** Name of the cluster. */
+ @Option(names = "--cluster-name", required = true, description = "Human-readable name of the cluster")
+ private String clusterName;
+
+ @Inject
+ private ClusterInitCall call;
+
+ @Inject
+ private Session session;
+
+ /** {@inheritDoc} */
+ @Override
+ public void run() {
+ ClusterInitCallInputBuilder input = buildCallInput();
+
+ if (session.isConnectedToNode()) {
+ input.clusterUrl(session.getNodeUrl());
+ } else if (clusterUrl != null) {
+ input.clusterUrl(clusterUrl);
+ } else {
+ spec.commandLine().getErr().println("You are not connected to node. Run 'connect' command or use '--node-endpoint' option.");
+ return;
+ }
+
+ CallExecutionPipeline.builder(call)
+ .inputProvider(input::build)
+ .output(spec.commandLine().getOut())
+ .errOutput(spec.commandLine().getErr())
+ .build()
+ .runPipeline();
+ }
+
+ private ClusterInitCallInputBuilder buildCallInput() {
+ return ClusterInitCallInput.builder()
+ .metaStorageNodes(metaStorageNodes)
+ .cmgNodes(cmgNodes)
+ .clusterName(clusterName);
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterInitSubCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterInitSubCommand.java
new file mode 100644
index 000000000..39e53519c
--- /dev/null
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterInitSubCommand.java
@@ -0,0 +1,93 @@
+/*
+ * 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.cli.commands.cluster;
+
+import jakarta.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import org.apache.ignite.cli.call.cluster.ClusterInitCall;
+import org.apache.ignite.cli.call.cluster.ClusterInitCallInput;
+import org.apache.ignite.cli.commands.BaseCommand;
+import org.apache.ignite.cli.core.call.CallExecutionPipeline;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+
+/**
+ * Initializes an Ignite cluster.
+ */
+@Command(name = "init", description = "Initializes an Ignite cluster.")
+public class ClusterInitSubCommand extends BaseCommand implements Callable<Integer> {
+
+ /**
+ * Node url option.
+ */
+ @Option(
+ names = {"--cluster-url"}, description = "Url to ignite node.",
+ descriptionKey = "ignite.cluster-url", defaultValue = "http://localhost:10300"
+ )
+ private String clusterUrl;
+
+ /**
+ * List of names of the nodes (each represented by a separate command line argument) that will host the Meta Storage. If the
+ * "--cmg-nodes" parameter is omitted, the same nodes will also host the Cluster Management Group.
+ */
+ @Option(names = "--meta-storage-node", required = true, description = {
+ "Name of the node (repeat like '--meta-storage-node node1 --meta-storage-node node2' to specify more than one node)",
+ "that will host the Meta Storage.",
+ "If the --cmg-node parameter is omitted, the same nodes will also host the Cluster Management Group."
+ })
+ private List<String> metaStorageNodes;
+
+ /**
+ * List of names of the nodes (each represented by a separate command line argument) that will host the Cluster Management Group.
+ */
+ @Option(names = "--cmg-node", description = {
+ "Name of the node (repeat like '--cmg-node node1 --cmg-node node2' to specify more than one node)",
+ "that will host the Cluster Management Group.",
+ "If omitted, then --meta-storage-node values will also supply the nodes for the Cluster Management Group."
+ })
+ private List<String> cmgNodes = new ArrayList<>();
+
+ /** Name of the cluster. */
+ @Option(names = "--cluster-name", required = true, description = "Human-readable name of the cluster")
+ private String clusterName;
+
+ @Inject
+ private ClusterInitCall call;
+
+ /** {@inheritDoc} */
+ @Override
+ public Integer call() {
+ return CallExecutionPipeline.builder(call)
+ .inputProvider(this::buildCallInput)
+ .output(spec.commandLine().getOut())
+ .errOutput(spec.commandLine().getErr())
+ .build()
+ .runPipeline();
+ }
+
+ private ClusterInitCallInput buildCallInput() {
+ return ClusterInitCallInput.builder()
+ .clusterUrl(clusterUrl)
+ .metaStorageNodes(metaStorageNodes)
+ .cmgNodes(cmgNodes)
+ .clusterName(clusterName)
+ .build();
+ }
+}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterReplCommand.java b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterReplCommand.java
similarity index 73%
rename from modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterReplCommand.java
rename to modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterReplCommand.java
index 9b0e8d1ac..72ec227de 100644
--- a/modules/cli/src/main/java/org/apache/ignite/cli/commands/configuration/cluster/ClusterReplCommand.java
+++ b/modules/cli/src/main/java/org/apache/ignite/cli/commands/cluster/ClusterReplCommand.java
@@ -15,19 +15,16 @@
* limitations under the License.
*/
-package org.apache.ignite.cli.commands.configuration.cluster;
+package org.apache.ignite.cli.commands.cluster;
-import org.apache.ignite.cli.deprecated.spec.ClusterReplCommandSpec;
+import org.apache.ignite.cli.commands.configuration.cluster.ClusterConfigReplSubCommand;
import picocli.CommandLine.Command;
-import picocli.CommandLine.Mixin;
/**
* Cluster command in REPL mode.
*/
@Command(name = "cluster",
- subcommands = {ClusterConfigReplSubCommand.class},
- description = "Cluster config operations.")
+ subcommands = {ClusterConfigReplSubCommand.class, ClusterInitReplSubCommand.class},
+ description = "Manages an Ignite cluster.")
public class ClusterReplCommand {
- @Mixin
- ClusterReplCommandSpec clusterReplCommandSpec;
}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java
deleted file mode 100644
index 2a89e8707..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/ClusterApiClient.java
+++ /dev/null
@@ -1,119 +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.cli.deprecated.builtins.cluster;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import jakarta.inject.Inject;
-import jakarta.inject.Singleton;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.HttpURLConnection;
-import java.net.URI;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpRequest.BodyPublishers;
-import java.net.http.HttpResponse;
-import java.net.http.HttpResponse.BodyHandlers;
-import java.util.List;
-import org.apache.ignite.cli.core.exception.IgniteCliApiException;
-import org.apache.ignite.cli.deprecated.IgniteCliException;
-
-/**
- * Client for Ignite Cluster management API.
- */
-@Singleton
-public class ClusterApiClient {
- private static final String CLUSTER_INIT_URL = "/management/v1/cluster/init/";
-
- private final HttpClient httpClient;
-
- private final ObjectMapper objectMapper = new ObjectMapper();
-
- @Inject
- public ClusterApiClient(HttpClient httpClient) {
- this.httpClient = httpClient;
- }
-
- /**
- * Sends 'cluster init' command to the specified node.
- *
- * @param nodeEndpoint host:port on which REST API is listening
- * @param metaStorageNodeIds consistent IDs of the nodes that will host the Meta Storage Raft group
- * @param cmgNodeIds consistent IDs of the nodes that will host the Cluster Management Raft Group; if empty,
- * {@code metaStorageNodeIds} will be used to host the CMG as well
- * @param clusterName Human-readable name of the cluster
- * @param out {@link PrintWriter} to which to report about the command outcome
- */
- public void init(
- String nodeEndpoint,
- List<String> metaStorageNodeIds,
- List<String> cmgNodeIds,
- String clusterName,
- PrintWriter out
- ) {
- InitClusterRequest requestPayload = new InitClusterRequest(metaStorageNodeIds, cmgNodeIds, clusterName);
- String requestJson = toJson(requestPayload);
-
- var httpRequest = HttpRequest
- .newBuilder()
- .uri(URI.create("http://" + nodeEndpoint + CLUSTER_INIT_URL))
- .method("POST", BodyPublishers.ofString(requestJson))
- .header("Content-Type", "application/json")
- .build();
-
- HttpResponse<String> httpResponse;
- try {
- httpResponse = httpClient.send(httpRequest, BodyHandlers.ofString());
- } catch (IOException | InterruptedException e) {
- throw new IgniteCliApiException(e, nodeEndpoint);
- }
-
- if (httpResponse.statusCode() == HttpURLConnection.HTTP_OK) {
- out.println("Cluster was initialized successfully.");
- } else {
- throw error("Failed to initialize cluster", httpResponse);
- }
- }
-
- private String toJson(InitClusterRequest requestPayload) {
- try {
- return objectMapper.writeValueAsString(requestPayload);
- } catch (JsonProcessingException e) {
- throw new IllegalStateException("Cannot serialize JSON", e);
- }
- }
-
- private IgniteCliException error(String message, HttpResponse<String> httpResponse) {
- String errorPayload;
- try {
- errorPayload = prettifyJson(httpResponse);
- } catch (JsonProcessingException e) {
- // not a valid JSON probably
- errorPayload = httpResponse.body();
- }
-
- return new IgniteCliException(message + System.lineSeparator().repeat(2) + errorPayload);
- }
-
- private String prettifyJson(HttpResponse<String> httpResponse) throws JsonProcessingException {
- return objectMapper.writerWithDefaultPrettyPrinter()
- .writeValueAsString(objectMapper.readValue(httpResponse.body(), JsonNode.class));
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/InitClusterRequest.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/InitClusterRequest.java
deleted file mode 100644
index 656fdc5d5..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/cluster/InitClusterRequest.java
+++ /dev/null
@@ -1,51 +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.cli.deprecated.builtins.cluster;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import java.util.List;
-
-/**
- * A request to the Cluster Init REST API.
- */
-public class InitClusterRequest {
- @SuppressWarnings("unused")
- @JsonProperty
- private final List<String> metaStorageNodes;
-
- @SuppressWarnings("unused")
- @JsonProperty
- private final List<String> cmgNodes;
-
- @SuppressWarnings("unused")
- @JsonProperty
- private final String clusterName;
-
- /**
- * Creates a new request.
- *
- * @param metaStorageNodes Names of the nodes that host the Meta Storage.
- * @param cmgNodes Names of the nodes that host the CMG.
- * @param clusterName Human-readable name of the cluster.
- */
- public InitClusterRequest(List<String> metaStorageNodes, List<String> cmgNodes, String clusterName) {
- this.metaStorageNodes = List.copyOf(metaStorageNodes);
- this.cmgNodes = List.copyOf(cmgNodes);
- this.clusterName = clusterName;
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/config/HttpClientFactory.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/config/HttpClientFactory.java
deleted file mode 100644
index a9ba71ac9..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/config/HttpClientFactory.java
+++ /dev/null
@@ -1,41 +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.cli.deprecated.builtins.config;
-
-import io.micronaut.context.annotation.Factory;
-import jakarta.inject.Singleton;
-import java.net.http.HttpClient;
-
-/**
- * Factory for producing simple HTTP clients.
- */
-@Factory
-public class HttpClientFactory {
- /**
- * Creates new HTTP client.
- *
- * @return HttpClient
- */
- @Singleton
- HttpClient httpClient() {
- return HttpClient
- .newBuilder()
- .version(HttpClient.Version.HTTP_1_1)
- .build();
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/config/package-info.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/config/package-info.java
deleted file mode 100644
index 4a7268fe0..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/builtins/config/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-
-/**
- * Contains classes for node/cluster configuration related operation.
- */
-
-package org.apache.ignite.cli.deprecated.builtins.config;
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java
deleted file mode 100644
index b4389edca..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterCommandSpec.java
+++ /dev/null
@@ -1,95 +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.cli.deprecated.spec;
-
-import jakarta.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import org.apache.ignite.cli.commands.BaseCommand;
-import org.apache.ignite.cli.deprecated.builtins.cluster.ClusterApiClient;
-import picocli.CommandLine;
-import picocli.CommandLine.Option;
-
-/**
- * Commands for managing Ignite cluster as a whole.
- */
-@CommandLine.Command(
- name = "cluster",
- description = "Manages an Ignite cluster as a whole.",
- subcommands = {
- ClusterCommandSpec.InitClusterCommandSpec.class,
- }
-)
-public class ClusterCommandSpec {
- /**
- * Initializes an Ignite cluster.
- */
- @CommandLine.Command(name = "init", description = "Initializes an Ignite cluster.")
- public static class InitClusterCommandSpec extends BaseCommand implements Callable<Integer> {
-
- @Inject
- private ClusterApiClient clusterApiClient;
-
- /**
- * Address of the REST endpoint of the receiving node in host:port format.
- */
- @Option(names = "--node-endpoint", required = true,
- description = "Address of the REST endpoint of the receiving node in host:port format")
- private String nodeEndpoint;
-
- /**
- * List of names of the nodes (each represented by a separate command line argument) that will host the Metastorage Raft group.
- * If the "--cmg-nodes" parameter is omitted, the same nodes will also host the Cluster Management Raft group.
- */
- @Option(names = "--meta-storage-node", required = true, description = {
- "Name of the node (repeat like '--meta-storage-node node1 --meta-storage-node node2' to specify more than one node)",
- "that will host the Meta Storage Raft group.",
- "If the --cmg-node parameter is omitted, the same nodes will also host the Cluster Management Raft group."
- })
- private List<String> metaStorageNodes;
-
- /**
- * List of names of the nodes (each represented by a separate command line argument) that will host
- * the Cluster Management Raft group.
- */
- @Option(names = "--cmg-node", description = {
- "Name of the node (repeat like '--cmg-node node1 --cmg-node node2' to specify more than one node)",
- "that will host the Cluster Management Raft group.",
- "If omitted, then --meta-storage-node values will also supply the nodes for the Cluster Management Raft group."
- })
- private List<String> cmgNodes = new ArrayList<>();
-
- /** Name of the cluster. */
- @Option(names = "--cluster-name", required = true, description = "Human-readable name of the cluster")
- private String clusterName;
-
- /** {@inheritDoc} */
- @Override
- public Integer call() {
- clusterApiClient.init(
- nodeEndpoint,
- metaStorageNodes,
- cmgNodes,
- clusterName,
- spec.commandLine().getOut()
- );
- return 0;
- }
- }
-}
diff --git a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java b/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java
deleted file mode 100644
index 107f2d2f7..000000000
--- a/modules/cli/src/main/java/org/apache/ignite/cli/deprecated/spec/ClusterReplCommandSpec.java
+++ /dev/null
@@ -1,114 +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.cli.deprecated.spec;
-
-import jakarta.inject.Inject;
-import java.util.ArrayList;
-import java.util.List;
-import org.apache.ignite.cli.commands.BaseCommand;
-import org.apache.ignite.cli.core.repl.Session;
-import org.apache.ignite.cli.deprecated.builtins.cluster.ClusterApiClient;
-import picocli.CommandLine;
-import picocli.CommandLine.Option;
-
-/**
- * Commands for managing Ignite cluster as a whole.
- */
-@CommandLine.Command(
- name = "cluster",
- description = "Manages an Ignite cluster as a whole.",
- subcommands = {
- ClusterReplCommandSpec.InitClusterCommandSpec.class,
- }
-)
-public class ClusterReplCommandSpec {
- /**
- * Initializes an Ignite cluster.
- */
- @CommandLine.Command(name = "init", description = "Initializes an Ignite cluster.")
- public static class InitClusterCommandSpec extends BaseCommand implements Runnable {
-
- @Inject
- private ClusterApiClient clusterApiClient;
-
- /**
- * Address of the REST endpoint of the receiving node in host:port format.
- */
- @Option(names = "--node-endpoint",
- description = "Address of the REST endpoint of the receiving node in host:port format")
- private String nodeEndpoint;
-
- /**
- * List of names of the nodes (each represented by a separate command line argument) that will host the Metastorage Raft group.
- * If the "--cmg-nodes" parameter is omitted, the same nodes will also host the Cluster Management Raft group.
- */
- @Option(names = "--meta-storage-node", required = true, description = {
- "Name of the node (repeat like '--meta-storage-node node1 --meta-storage-node node2' to specify more than one node)",
- "that will host the Meta Storage Raft group.",
- "If the --cmg-node parameter is omitted, the same nodes will also host the Cluster Management Raft group."
- })
- private List<String> metaStorageNodes;
-
- /**
- * List of names of the nodes (each represented by a separate command line argument) that will host
- * the Cluster Management Raft group.
- */
- @Option(names = "--cmg-node", description = {
- "Name of the node (repeat like '--cmg-node node1 --cmg-node node2' to specify more than one node)",
- "that will host the Cluster Management Raft group.",
- "If omitted, then --meta-storage-node values will also supply the nodes for the Cluster Management Raft group."
- })
- private List<String> cmgNodes = new ArrayList<>();
-
- /** Name of the cluster. */
- @Option(names = "--cluster-name", required = true, description = "Human-readable name of the cluster")
- private String clusterName;
-
- @Inject
- private Session session;
-
- /** {@inheritDoc} */
- @Override
- public void run() {
- String endpoint = null;
-
- if (session.isConnectedToNode()) {
- endpoint = session.getNodeUrl();
- } else if (nodeEndpoint != null) {
- endpoint = nodeEndpoint;
- } else {
- spec.commandLine().getErr().println(
- "You are not connected to node. Run 'connect' command or use '--node-endpoint' option."
- );
- return;
- }
-
- if (endpoint.startsWith("http://")) {
- endpoint = endpoint.replace("http://", "");
- }
-
- clusterApiClient.init(
- endpoint,
- metaStorageNodes,
- cmgNodes,
- clusterName,
- spec.commandLine().getOut()
- );
- }
- }
-}
diff --git a/modules/cli/src/test/java/org/apache/ignite/cli/deprecated/IgniteCliInterfaceTest.java b/modules/cli/src/test/java/org/apache/ignite/cli/deprecated/IgniteCliInterfaceTest.java
index 6a7d9ac70..28c1b851d 100644
--- a/modules/cli/src/test/java/org/apache/ignite/cli/deprecated/IgniteCliInterfaceTest.java
+++ b/modules/cli/src/test/java/org/apache/ignite/cli/deprecated/IgniteCliInterfaceTest.java
@@ -17,45 +17,30 @@
package org.apache.ignite.cli.deprecated;
-import static com.github.npathai.hamcrestopt.OptionalMatchers.isPresentAnd;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.stream.Collectors.toList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.mockserver.model.HttpRequest.request;
+import static org.mockserver.model.HttpResponse.response;
+import static org.mockserver.model.HttpStatusCode.INTERNAL_SERVER_ERROR_500;
+import static org.mockserver.model.HttpStatusCode.OK_200;
import io.micronaut.context.ApplicationContext;
import io.micronaut.context.env.Environment;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-import java.net.HttpURLConnection;
-import java.net.http.HttpClient;
-import java.net.http.HttpRequest;
-import java.net.http.HttpRequest.BodyPublisher;
-import java.net.http.HttpResponse;
-import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
-import org.apache.ignite.cli.call.configuration.ClusterConfigShowCall;
-import org.apache.ignite.cli.call.configuration.ClusterConfigShowCallInput;
-import org.apache.ignite.cli.call.configuration.ClusterConfigUpdateCall;
-import org.apache.ignite.cli.call.configuration.ClusterConfigUpdateCallInput;
-import org.apache.ignite.cli.call.configuration.NodeConfigShowCall;
-import org.apache.ignite.cli.call.configuration.NodeConfigShowCallInput;
-import org.apache.ignite.cli.call.configuration.NodeConfigUpdateCall;
-import org.apache.ignite.cli.call.configuration.NodeConfigUpdateCallInput;
import org.apache.ignite.cli.commands.TopLevelCliCommand;
-import org.apache.ignite.cli.core.call.DefaultCallOutput;
import org.apache.ignite.cli.deprecated.builtins.init.InitIgniteCommand;
import org.apache.ignite.cli.deprecated.builtins.node.NodeManager;
import org.junit.jupiter.api.AfterEach;
@@ -64,12 +49,11 @@ import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockserver.integration.ClientAndServer;
+import org.mockserver.model.MediaType;
import picocli.CommandLine;
-import reactor.adapter.JdkFlowAdapter;
/**
* Smoke test for Ignite CLI features and its UI. Structure of tests should be self-documented and repeat the structure of Ignite CLI
@@ -99,8 +83,9 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
Path.of("log"),
"version");
- @Captor
- private ArgumentCaptor<HttpRequest> requestCaptor;
+ private ClientAndServer clientAndServer;
+
+ private String mockUrl;
/**
* Sets up environment before test execution.
@@ -113,6 +98,9 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
err = new ByteArrayOutputStream();
out = new ByteArrayOutputStream();
+
+ clientAndServer = ClientAndServer.startClientAndServer(0);
+ mockUrl = "http://localhost:" + clientAndServer.getPort();
}
/**
@@ -120,6 +108,7 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
*/
@AfterEach
void tearDown() {
+ clientAndServer.stop();
ctx.stop();
}
@@ -136,6 +125,10 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
.setOut(new PrintWriter(out, true));
}
+ private int execute(String cmdLine) {
+ return cmd(ctx).execute(cmdLine.split(" "));
+ }
+
/**
* Tests "bootstrap" command.
*/
@@ -207,8 +200,8 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
+ "| PID | 1 |\n"
+ "+-----------+---------+\n"
+ "| Log File | logfile |\n"
- + "+-----------+---------+\n",
- out.toString(UTF_8));
+ + "+-----------+---------+\n"
+ );
assertThatStderrIsEmpty();
}
@@ -232,8 +225,8 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertOutputEqual(
"Stopping locally running node with consistent ID "
+ cmd.getColorScheme().parameterText(nodeName)
- + cmd.getColorScheme().text("... @|bold,green Done!|@\n"),
- out.toString(UTF_8));
+ + cmd.getColorScheme().text("... @|bold,green Done!|@\n")
+ );
assertThatStderrIsEmpty();
}
@@ -257,8 +250,8 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertOutputEqual(
"Stopping locally running node with consistent ID "
+ cmd.getColorScheme().parameterText(nodeName)
- + cmd.getColorScheme().text("... @|bold,red Failed|@\n"),
- out.toString(UTF_8));
+ + cmd.getColorScheme().text("... @|bold,red Failed|@\n")
+ );
assertThatStderrIsEmpty();
}
@@ -281,14 +274,14 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertThatExitCodeMeansSuccess(exitCode);
verify(nodeMgr).getRunningNodes(ignitePaths.logDir, ignitePaths.cliPidsDir());
assertOutputEqual(cmd.getColorScheme().text("Number of running nodes: @|bold 2|@\n\n")
- + "+---------------+-----+----------+\n"
- + cmd.getColorScheme().text("| @|bold Consistent ID|@ | @|bold PID|@ | @|bold Log File|@ |\n")
- + "+---------------+-----+----------+\n"
- + "| new1 | 1 | logFile1 |\n"
- + "+---------------+-----+----------+\n"
- + "| new2 | 2 | logFile2 |\n"
- + "+---------------+-----+----------+\n",
- out.toString(UTF_8));
+ + "+---------------+-----+----------+\n"
+ + cmd.getColorScheme().text("| @|bold Consistent ID|@ | @|bold PID|@ | @|bold Log File|@ |\n")
+ + "+---------------+-----+----------+\n"
+ + "| new1 | 1 | logFile1 |\n"
+ + "+---------------+-----+----------+\n"
+ + "| new2 | 2 | logFile2 |\n"
+ + "+---------------+-----+----------+\n"
+ );
assertThatStderrIsEmpty();
}
@@ -308,8 +301,8 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertThatExitCodeMeansSuccess(exitCode);
verify(nodeMgr).getRunningNodes(ignitePaths.logDir, ignitePaths.cliPidsDir());
assertOutputEqual("Currently, there are no locally running nodes.\n\n"
- + "Use the " + cmd.getColorScheme().commandText("ignite node start") + " command to start a new node.\n",
- out.toString(UTF_8));
+ + "Use the " + cmd.getColorScheme().commandText("ignite node start") + " command to start a new node.\n"
+ );
assertThatStderrIsEmpty();
}
@@ -325,8 +318,8 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
verify(nodeMgr).classpathItems();
assertOutputEqual(
cmd.getColorScheme().text(
- "@|bold Current Ignite node classpath:|@\n item1\n item2\n").toString(),
- out.toString(UTF_8));
+ "@|bold Current Ignite node classpath:|@\n item1\n item2\n").toString()
+ );
assertThatStderrIsEmpty();
}
@@ -336,104 +329,68 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
@Nested
@DisplayName("config")
class Config {
- /** Http client that is used for communication purposes. */
- @Mock
- private HttpClient httpClient;
-
- /** HTTP response. */
- @Mock
- private HttpResponse<String> res;
-
- private NodeConfigShowCallInput capturedShowConfigurationInput;
-
- private NodeConfigUpdateCallInput capturedUpdateConfigurationInput;
-
- NodeConfigShowCall showConfigurationCall() {
- return new NodeConfigShowCall() {
- @Override
- public DefaultCallOutput<String> execute(NodeConfigShowCallInput readConfigurationInput) {
- capturedShowConfigurationInput = readConfigurationInput;
- return DefaultCallOutput.success("{\"autoAdjust\":{\"enabled\":true}}");
- }
- };
- }
-
- NodeConfigUpdateCall updateConfigurationCall() {
- return new NodeConfigUpdateCall() {
- @Override
- public DefaultCallOutput<String> execute(NodeConfigUpdateCallInput nodeConfigUpdateCallInput) {
- capturedUpdateConfigurationInput = nodeConfigUpdateCallInput;
- return DefaultCallOutput.success("Configuration was updated successfully.");
- }
- };
- }
-
- @BeforeEach
- void setUp() {
- ctx.registerSingleton(showConfigurationCall());
- ctx.registerSingleton(updateConfigurationCall());
- }
-
- //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("config show --node-url http://localhost:8081")
+ @DisplayName("show --node-url http://localhost:10300")
void show() {
- int exitCode =
- cmd(ctx).execute("node config show --node-url http://localhost:8081".split(" "));
+ clientAndServer
+ .when(request()
+ .withMethod("GET")
+ .withPath("/management/v1/configuration/node")
+ )
+ .respond(response("{\"autoAdjust\":{\"enabled\":true}}"));
- assertThatExitCodeMeansSuccess(exitCode);
+ int exitCode = execute("node config show --node-url " + mockUrl);
- assertThat(capturedShowConfigurationInput.getNodeUrl(), is("http://localhost:8081"));
- assertNull(capturedShowConfigurationInput.getSelector());
+ assertThatExitCodeMeansSuccess(exitCode);
assertOutputEqual("{\n"
+ " \"autoAdjust\" : {\n"
+ " \"enabled\" : true\n"
+ " }\n"
- + "}\n",
- out.toString(UTF_8)
+ + "}\n"
);
assertThatStderrIsEmpty();
}
- //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("config show --node-url http://localhost:8081 --selector local.baseline")
+ @DisplayName("show --node-url http://localhost:10300 --selector local.baseline")
void showSubtree() {
- int exitCode =
- cmd(ctx).execute(("node config show --node-url http://localhost:8081 "
- + "--selector local.baseline").split(" "));
+ clientAndServer
+ .when(request()
+ .withMethod("GET")
+ .withPath("/management/v1/configuration/node/local.baseline")
+ )
+ .respond(response("{\"autoAdjust\":{\"enabled\":true}}"));
- assertThatExitCodeMeansSuccess(exitCode);
+ int exitCode = execute("node config show --node-url " + mockUrl + " --selector local.baseline");
- assertThat(capturedShowConfigurationInput.getNodeUrl(), is("http://localhost:8081"));
- assertThat(capturedShowConfigurationInput.getSelector(), is("local.baseline"));
+ assertThatExitCodeMeansSuccess(exitCode);
assertOutputEqual("{\n"
+ " \"autoAdjust\" : {\n"
+ " \"enabled\" : true\n"
+ " }\n"
- + "}\n",
- out.toString(UTF_8)
+ + "}\n"
);
assertThatStderrIsEmpty();
}
- //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
@Test
- @DisplayName("config update --node-url http://localhost:8081 local.baseline.autoAdjust.enabled=true")
+ @DisplayName("update --node-url http://localhost:10300 local.baseline.autoAdjust.enabled=true")
void updateHocon() {
- CommandLine cmd = cmd(ctx);
- int exitCode =
- cmd.execute(("node config update --node-url http://localhost:8081 local.baseline.autoAdjust.enabled=true")
- .split(" "));
+ clientAndServer
+ .when(request()
+ .withMethod("PATCH")
+ .withPath("/management/v1/configuration/node")
+ .withBody("local.baseline.autoAdjust.enabled=true")
+ )
+ .respond(response(null));
- assertThatExitCodeMeansSuccess(exitCode);
+ int exitCode = execute("node config update --node-url " + mockUrl + " local.baseline.autoAdjust.enabled=true");
- assertThat(capturedUpdateConfigurationInput.getNodeUrl(), is("http://localhost:8081"));
- assertThat(capturedUpdateConfigurationInput.getConfig(), is("local.baseline.autoAdjust.enabled=true"));
+ assertThatExitCodeMeansSuccess(exitCode);
- assertOutputEqual("Configuration was updated successfully.", out.toString(UTF_8));
+ assertOutputEqual("Node configuration was updated successfully.");
assertThatStderrIsEmpty();
}
}
@@ -445,89 +402,27 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
@Nested
@DisplayName("cluster")
class Cluster {
- @Mock
- private HttpClient httpClient;
-
- @Mock
- private HttpResponse<String> response;
-
- private ClusterConfigShowCallInput capturedShowConfigurationInput;
-
- private ClusterConfigUpdateCallInput capturedUpdateConfigurationInput;
-
- ClusterConfigShowCall showConfigurationCall() {
- return new ClusterConfigShowCall() {
- @Override
- public DefaultCallOutput<String> execute(ClusterConfigShowCallInput input) {
- capturedShowConfigurationInput = input;
- return DefaultCallOutput.success("{\"autoAdjust\":{\"enabled\":true}}");
- }
- };
- }
-
- ClusterConfigUpdateCall updateConfigurationCall() {
- return new ClusterConfigUpdateCall() {
- @Override
- public DefaultCallOutput<String> execute(ClusterConfigUpdateCallInput input) {
- capturedUpdateConfigurationInput = input;
- return DefaultCallOutput.success("Configuration was updated successfully.");
- }
- };
- }
-
- @BeforeEach
- void setUp() {
- ctx.registerSingleton(httpClient);
- ctx.registerSingleton(showConfigurationCall());
- ctx.registerSingleton(updateConfigurationCall());
- }
-
@Test
- @DisplayName("init --node-endpoint=127.0.0.1:17300 --meta-storage-node node1ConsistentId --meta-storage-node node2ConsistentId "
- + "--cmg-node node2ConsistentId --cmg-node node3ConsistentId")
- void initSuccess() throws Exception {
- when(response.statusCode()).thenReturn(HttpURLConnection.HTTP_OK);
- when(httpClient.<String>send(any(), any())).thenReturn(response);
-
- var expSentContent = "{\"metaStorageNodes\":[\"node1ConsistentId\",\"node2ConsistentId\"],"
+ @DisplayName("init --cluster-url http://localhost:10300 --meta-storage-node node1ConsistentId --meta-storage-node node2ConsistentId "
+ + "--cmg-node node2ConsistentId --cmg-node node3ConsistentId --cluster-name cluster")
+ void initSuccess() {
+ var expectedSentContent = "{\"metaStorageNodes\":[\"node1ConsistentId\",\"node2ConsistentId\"],"
+ "\"cmgNodes\":[\"node2ConsistentId\",\"node3ConsistentId\"],"
+ "\"clusterName\":\"cluster\"}";
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
- "cluster", "init",
- "--node-endpoint", "127.0.0.1:8081",
- "--meta-storage-node", "node1ConsistentId",
- "--meta-storage-node", "node2ConsistentId",
- "--cmg-node", "node2ConsistentId",
- "--cmg-node", "node3ConsistentId",
- "--cluster-name", "cluster"
- );
-
- assertThatExitCodeMeansSuccess(exitCode);
-
- verify(httpClient).send(requestCaptor.capture(), any());
- HttpRequest capturedRequest = requestCaptor.getValue();
-
- assertThat(capturedRequest.uri().toString(), is("http://127.0.0.1:8081/management/v1/cluster/init/"));
- assertThat(capturedRequest.method(), is("POST"));
- assertThat(new String(requestBodyBytes(capturedRequest), UTF_8), is(expSentContent));
- assertThat(capturedRequest.headers().firstValue("Content-Type"), isPresentAnd(is("application/json")));
-
- assertThat(out.toString(UTF_8), is(platformizeNewLines("Cluster was initialized successfully.\n")));
- assertThatStderrIsEmpty();
- }
+ clientAndServer
+ .when(request()
+ .withMethod("POST")
+ .withPath("/management/v1/cluster/init")
+ .withBody(expectedSentContent)
+ .withContentType(MediaType.APPLICATION_JSON_UTF_8)
+ )
+ .respond(response(null));
- @Test
- void initErrorWithWellFormedJsonResponseDisplaysPrettifiedJson() throws Exception {
- when(response.statusCode()).thenReturn(HttpURLConnection.HTTP_INTERNAL_ERROR);
- when(response.body()).thenReturn("{\"error\":{\"type\":\"INTERNAL_ERROR\",\"message\":\"Cannot elect leaders\"}}");
- when(httpClient.<String>send(any(), any())).thenReturn(response);
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
+ int exitCode = cmd(ctx).execute(
"cluster", "init",
- "--node-endpoint", "127.0.0.1:8081",
+ "--cluster-url", mockUrl,
"--meta-storage-node", "node1ConsistentId",
"--meta-storage-node", "node2ConsistentId",
"--cmg-node", "node2ConsistentId",
@@ -535,30 +430,27 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
"--cluster-name", "cluster"
);
- assertThatExitCodeIs(1, exitCode);
+ assertThatExitCodeMeansSuccess(exitCode);
- assertThatStdoutIsEmpty();
- assertThat(err.toString(UTF_8), startsWith(platformizeNewLines(
- "org.apache.ignite.cli.deprecated.IgniteCliException: Failed to initialize cluster\n"
- + "\n"
- + "{\n"
- + " \"error\" : {\n"
- + " \"type\" : \"INTERNAL_ERROR\",\n"
- + " \"message\" : \"Cannot elect leaders\"\n"
- + " }\n"
- + "}")));
+ assertOutputEqual("Cluster was initialized successfully.");
+ assertThatStderrIsEmpty();
}
@Test
- void initErrorWithNonJsonResponse() throws Exception {
- when(response.statusCode()).thenReturn(HttpURLConnection.HTTP_INTERNAL_ERROR);
- when(response.body()).thenReturn("Oops");
- when(httpClient.<String>send(any(), any())).thenReturn(response);
-
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
+ void initError() {
+ clientAndServer
+ .when(request()
+ .withMethod("POST")
+ .withPath("/management/v1/cluster/init")
+ )
+ .respond(response()
+ .withStatusCode(INTERNAL_SERVER_ERROR_500.code())
+ .withBody("Oops")
+ );
+
+ int exitCode = cmd(ctx).execute(
"cluster", "init",
- "--node-endpoint=127.0.0.1:8081",
+ "--cluster-url", mockUrl,
"--meta-storage-node", "node1ConsistentId",
"--meta-storage-node", "node2ConsistentId",
"--cmg-node", "node2ConsistentId",
@@ -569,39 +461,15 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertThatExitCodeIs(1, exitCode);
assertThatStdoutIsEmpty();
- assertThat(err.toString(UTF_8), startsWith(platformizeNewLines(
- "org.apache.ignite.cli.deprecated.IgniteCliException: Failed to initialize cluster\n"
- + "\n"
- + "Oops")));
- }
-
- @Test
- @DisplayName("init --meta-storage-node node1ConsistentId --meta-storage-node node2ConsistentId "
- + "--cmg-node node2ConsistentId --cmg-node node3ConsistentId")
- void nodeEndpointIsMandatoryForInit() {
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
- "cluster", "init",
- "--meta-storage-node", "node1ConsistentId",
- "--meta-storage-node", "node2ConsistentId",
- "--cmg-node", "node2ConsistentId",
- "--cmg-node", "node3ConsistentId",
- "--cluster-name", "cluster"
- );
-
- assertThatExitCodeIs(2, exitCode);
-
- assertThatStdoutIsEmpty();
- assertThat(err.toString(UTF_8), startsWith("Missing required option: '--node-endpoint=<nodeEndpoint>'"));
+ assertErrOutputEqual("An error occurred, error code: 500, response: Oops");
}
@Test
- @DisplayName("init --node-endpoint=127.0.0.1:17300 --cmg-node node2ConsistentId --cmg-node node3ConsistentId")
+ @DisplayName("init --cluster-url http://localhost:10300 --cmg-node node2ConsistentId --cmg-node node3ConsistentId")
void metastorageNodesAreMandatoryForInit() {
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
+ int exitCode = cmd(ctx).execute(
"cluster", "init",
- "--node-endpoint", "127.0.0.1:8081",
+ "--cluster-url", mockUrl,
"--cmg-node", "node2ConsistentId",
"--cmg-node", "node3ConsistentId",
"--cluster-name", "cluster"
@@ -614,15 +482,18 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
}
@Test
- @DisplayName("init --node-endpoint=127.0.0.1:17300 --meta-storage-node node2ConsistentId --meta-storage-node node3ConsistentId")
- void cmgNodesAreNotMandatoryForInit() throws Exception {
- when(response.statusCode()).thenReturn(HttpURLConnection.HTTP_OK);
- when(httpClient.<String>send(any(), any())).thenReturn(response);
-
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
+ @DisplayName("init --cluster-url http://localhost:10300 --meta-storage-node node2ConsistentId --meta-storage-node node3ConsistentId")
+ void cmgNodesAreNotMandatoryForInit() {
+ clientAndServer
+ .when(request()
+ .withMethod("POST")
+ .withPath("/management/v1/cluster/init")
+ )
+ .respond(response().withStatusCode(OK_200.code()));
+
+ int exitCode = cmd(ctx).execute(
"cluster", "init",
- "--node-endpoint", "127.0.0.1:8081",
+ "--cluster-url", mockUrl,
"--meta-storage-node", "node1ConsistentId",
"--meta-storage-node", "node2ConsistentId",
"--cluster-name", "cluster"
@@ -630,17 +501,16 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertThatExitCodeMeansSuccess(exitCode);
- assertThat(out.toString(UTF_8), is(platformizeNewLines("Cluster was initialized successfully.\n")));
+ assertOutputEqual("Cluster was initialized successfully.");
assertThatStderrIsEmpty();
}
@Test
- @DisplayName("init --node-endpoint 127.0.0.1:8081 --meta-storage-node node1ConsistentId --cmg-node node2ConsistentId")
+ @DisplayName("init --cluster-url http://localhost:10300 --meta-storage-node node1ConsistentId --cmg-node node2ConsistentId")
void clusterNameIsMandatoryForInit() {
- CommandLine cmd = cmd(ctx);
- int exitCode = cmd.execute(
+ int exitCode = cmd(ctx).execute(
"cluster", "init",
- "--node-endpoint", "127.0.0.1:8081",
+ "--cluster-url", mockUrl,
"--meta-storage-node", "node1ConsistentId",
"--cmg-node", "node2ConsistentId"
);
@@ -651,74 +521,74 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
assertThat(err.toString(UTF_8), startsWith("Missing required option: '--cluster-name=<clusterName>'"));
}
- //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
- @Test
- @DisplayName("config show --cluster-url http://localhost:8081")
- void show() {
- int exitCode =
- cmd(ctx).execute("cluster config show --cluster-url http://localhost:8081".split(" "));
+ @Nested
+ @DisplayName("config")
+ class Config {
+ @Test
+ @DisplayName("show --cluster-url http://localhost:10300")
+ void show() {
+ clientAndServer
+ .when(request()
+ .withMethod("GET")
+ .withPath("/management/v1/configuration/cluster")
+ )
+ .respond(response("{\"autoAdjust\":{\"enabled\":true}}"));
- assertThatExitCodeMeansSuccess(exitCode);
+ int exitCode = execute("cluster config show --cluster-url " + mockUrl);
- assertThat(capturedShowConfigurationInput.getClusterUrl(), is("http://localhost:8081"));
- assertNull(capturedShowConfigurationInput.getSelector());
+ assertThatExitCodeMeansSuccess(exitCode);
- assertOutputEqual("{\n"
- + " \"autoAdjust\" : {\n"
- + " \"enabled\" : true\n"
- + " }\n"
- + "}\n",
- out.toString(UTF_8)
- );
- assertThatStderrIsEmpty();
- }
+ assertOutputEqual("{\n"
+ + " \"autoAdjust\" : {\n"
+ + " \"enabled\" : true\n"
+ + " }\n"
+ + "}\n");
+ assertThatStderrIsEmpty();
+ }
- //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
- @Test
- @DisplayName("config show --cluster-url http://localhost:8081 --selector local.baseline")
- void showSubtree() {
- int exitCode =
- cmd(ctx).execute(("cluster config show --cluster-url http://localhost:8081 "
- + "--selector local.baseline").split(" "));
+ @Test
+ @DisplayName("show --cluster-url http://localhost:10300 --selector local.baseline")
+ void showSubtree() {
+ clientAndServer
+ .when(request()
+ .withMethod("GET")
+ .withPath("/management/v1/configuration/cluster/local.baseline")
+ )
+ .respond(response("{\"autoAdjust\":{\"enabled\":true}}"));
- assertThatExitCodeMeansSuccess(exitCode);
+ int exitCode = execute("cluster config show --cluster-url " + mockUrl + " --selector local.baseline");
- assertThat(capturedShowConfigurationInput.getClusterUrl(), is("http://localhost:8081"));
- assertThat(capturedShowConfigurationInput.getSelector(), is("local.baseline"));
+ assertThatExitCodeMeansSuccess(exitCode);
- assertOutputEqual("{\n"
- + " \"autoAdjust\" : {\n"
- + " \"enabled\" : true\n"
- + " }\n"
- + "}\n",
- out.toString(UTF_8)
- );
- assertThatStderrIsEmpty();
- }
+ assertOutputEqual("{\n"
+ + " \"autoAdjust\" : {\n"
+ + " \"enabled\" : true\n"
+ + " }\n"
+ + "}\n");
+ assertThatStderrIsEmpty();
+ }
- //TODO: Fix in https://issues.apache.org/jira/browse/IGNITE-15306
- @Test
- @DisplayName("config update --cluster-url http://localhost:8081 local.baseline.autoAdjust.enabled=true")
- void updateHocon() {
- CommandLine cmd = cmd(ctx);
- int exitCode =
- cmd.execute(("cluster config update --cluster-url http://localhost:8081 local.baseline.autoAdjust.enabled=true")
- .split(" "));
+ @Test
+ @DisplayName("update --cluster-url http://localhost:10300 local.baseline.autoAdjust.enabled=true")
+ void updateHocon() {
+ clientAndServer
+ .when(request()
+ .withMethod("PATCH")
+ .withPath("/management/v1/configuration/cluster")
+ .withBody("local.baseline.autoAdjust.enabled=true")
+ )
+ .respond(response(null));
- assertThatExitCodeMeansSuccess(exitCode);
+ int exitCode = execute("cluster config update --cluster-url " + mockUrl + " local.baseline.autoAdjust.enabled=true");
- assertThat(capturedUpdateConfigurationInput.getClusterUrl(), is("http://localhost:8081"));
- assertThat(capturedUpdateConfigurationInput.getConfig(), is("local.baseline.autoAdjust.enabled=true"));
+ assertThatExitCodeMeansSuccess(exitCode);
- assertOutputEqual("Configuration was updated successfully.", out.toString(UTF_8));
- assertThatStderrIsEmpty();
+ assertOutputEqual("Cluster configuration was updated successfully.");
+ assertThatStderrIsEmpty();
+ }
}
}
- private String platformizeNewLines(String str) {
- return str.replace("\n", System.lineSeparator());
- }
-
private void assertThatStdoutIsEmpty() {
assertThat(out.toString(UTF_8), is(""));
}
@@ -739,19 +609,6 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
return "stdout:\n" + out.toString(UTF_8) + "\n" + "stderr:\n" + err.toString(UTF_8);
}
- private byte[] requestBodyBytes(HttpRequest capturedRequest) {
- assertTrue(capturedRequest.bodyPublisher().isPresent());
-
- BodyPublisher jdkBodyPublisher = capturedRequest.bodyPublisher().get();
- ByteBuffer requestBodyBuffer = JdkFlowAdapter.flowPublisherToFlux(jdkBodyPublisher).blockFirst();
- assertThat(requestBodyBuffer, is(notNullValue()));
-
- byte[] bytes = new byte[requestBodyBuffer.remaining()];
- requestBodyBuffer.get(bytes);
-
- return bytes;
- }
-
/**
* <em>Assert</em> that {@code expected} and {@code actual} are equal.
*
@@ -767,4 +624,12 @@ public class IgniteCliInterfaceTest extends AbstractCliTest {
actual.lines().collect(toList())
);
}
+
+ private void assertOutputEqual(String exp) {
+ assertOutputEqual(exp, out.toString(UTF_8));
+ }
+
+ private void assertErrOutputEqual(String exp) {
+ assertOutputEqual(exp, err.toString(UTF_8));
+ }
}
diff --git a/parent/pom.xml b/parent/pom.xml
index ab345f5e9..d69aea3a3 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -100,6 +100,7 @@
<fastutil.version>8.5.6</fastutil.version>
<kryo.version>4.0.1</kryo.version>
<bytebuddy.version>1.12.8</bytebuddy.version>
+ <mock-server.version>5.13.2</mock-server.version>
<!-- Plugins versions -->
<apache.rat.plugin.version>0.13</apache.rat.plugin.version>
@@ -897,6 +898,12 @@
<artifactId>byte-buddy</artifactId>
<version>${bytebuddy.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.mock-server</groupId>
+ <artifactId>mockserver-netty</artifactId>
+ <version>${mock-server.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>