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>