This is an automated email from the ASF dual-hosted git repository.
rpuch 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 6935ca8cc4 IGNITE-22897 Add CLI for initiating MG repair (#4611)
6935ca8cc4 is described below
commit 6935ca8cc4751595be067dcae91789835198fd7f
Author: Phillippko <[email protected]>
AuthorDate: Sat Oct 26 01:26:57 2024 +0900
IGNITE-22897 Add CLI for initiating MG repair (#4611)
---
.../call/recovery/cluster/ResetClusterCall.java | 1 +
.../recovery/cluster/ResetClusterCallInput.java | 33 ++++--
.../ignite/internal/cli/commands/Options.java | 5 +
.../recovery/cluster/reset/ResetClusterMixin.java | 25 +++-
.../cluster/reset/ResetClusterCommandTest.java | 130 +++++++++++++++++++++
.../disaster/system/ItCmgDisasterRecoveryTest.java | 4 +-
.../ItMetastorageGroupDisasterRecoveryTest.java | 26 ++---
.../system/SystemDisasterRecoveryClient.java | 34 ++++--
8 files changed, 220 insertions(+), 38 deletions(-)
diff --git
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCall.java
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCall.java
index c6566044f4..c8d7da5e90 100644
---
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCall.java
+++
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCall.java
@@ -43,6 +43,7 @@ public class ResetClusterCall implements
Call<ResetClusterCallInput, String> {
ResetClusterRequest command = new ResetClusterRequest();
command.setCmgNodeNames(input.cmgNodeNames());
+
command.setMetastorageReplicationFactor(input.metastorageReplicationFactor());
try {
client.resetCluster(command);
diff --git
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCallInput.java
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCallInput.java
index b5767c1690..8f4d562350 100644
---
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCallInput.java
+++
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/cluster/ResetClusterCallInput.java
@@ -18,37 +18,46 @@
package org.apache.ignite.internal.cli.call.recovery.cluster;
import java.util.List;
-import java.util.Objects;
import
org.apache.ignite.internal.cli.commands.recovery.cluster.reset.ResetClusterMixin;
import org.apache.ignite.internal.cli.core.call.CallInput;
+import org.jetbrains.annotations.Nullable;
/** Input for the {@link ResetClusterCall} call. */
public class ResetClusterCallInput implements CallInput {
private final String clusterUrl;
+ @Nullable
private final List<String> cmgNodeNames;
+ @Nullable
+ private final Integer metastorageReplicationFactor;
+
/** Cluster url. */
public String clusterUrl() {
return clusterUrl;
}
/** Returns names of the proposed CMG nodes. */
- public List<String> cmgNodeNames() {
+ public @Nullable List<String> cmgNodeNames() {
return cmgNodeNames;
}
- private ResetClusterCallInput(String clusterUrl, List<String>
cmgNodeNames) {
- Objects.requireNonNull(cmgNodeNames);
+ /** Returns metastorage replication factor. */
+ public @Nullable Integer metastorageReplicationFactor() {
+ return metastorageReplicationFactor;
+ }
+ private ResetClusterCallInput(String clusterUrl, @Nullable List<String>
cmgNodeNames, @Nullable Integer metastorageReplicationFactor) {
this.clusterUrl = clusterUrl;
- this.cmgNodeNames = List.copyOf(cmgNodeNames);
+ this.cmgNodeNames = cmgNodeNames == null ? null :
List.copyOf(cmgNodeNames);
+ this.metastorageReplicationFactor = metastorageReplicationFactor;
}
/** Returns {@link ResetClusterCallInput} with specified arguments. */
public static ResetClusterCallInput of(ResetClusterMixin statesArgs,
String clusterUrl) {
return builder()
.cmgNodeNames(statesArgs.cmgNodeNames())
+
.metastorageReplicationFactor(statesArgs.metastorageReplicationFactor())
.clusterUrl(clusterUrl)
.build();
}
@@ -66,8 +75,12 @@ public class ResetClusterCallInput implements CallInput {
private static class ResetClusterCallInputBuilder {
private String clusterUrl;
+ @Nullable
private List<String> cmgNodeNames;
+ @Nullable
+ private Integer metastorageReplicationFactor;
+
/** Set cluster URL. */
ResetClusterCallInputBuilder clusterUrl(String clusterUrl) {
this.clusterUrl = clusterUrl;
@@ -75,14 +88,20 @@ public class ResetClusterCallInput implements CallInput {
}
/** Names of the proposed CMG nodes. */
- ResetClusterCallInputBuilder cmgNodeNames(List<String> cmgNodeNames) {
+ ResetClusterCallInputBuilder cmgNodeNames(@Nullable List<String>
cmgNodeNames) {
this.cmgNodeNames = cmgNodeNames;
return this;
}
+ /** Metastorage replication factor. */
+ ResetClusterCallInputBuilder metastorageReplicationFactor(@Nullable
Integer metastorageReplicationFactor) {
+ this.metastorageReplicationFactor = metastorageReplicationFactor;
+ return this;
+ }
+
/** Build {@link ResetClusterCallInput}. */
ResetClusterCallInput build() {
- return new ResetClusterCallInput(clusterUrl, cmgNodeNames);
+ return new ResetClusterCallInput(clusterUrl, cmgNodeNames,
metastorageReplicationFactor);
}
}
}
diff --git
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/Options.java
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/Options.java
index 68b27cf92f..6f76b70ff7 100644
---
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/Options.java
+++
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/Options.java
@@ -292,6 +292,11 @@ public enum Options {
public static final String RECOVERY_NODE_NAMES_OPTION_DESC = "Names
specifying nodes to get partition states from. "
+ "Case-sensitive, without quotes, all nodes if not set";
+ public static final String RECOVERY_METASTORAGE_REPLICATION_OPTION =
"--metastorage-replication-factor";
+
+ public static final String RECOVERY_METASTORAGE_REPLICATION_DESC =
"Number of nodes in the voting member set of the Metastorage "
+ + "RAFT group.";
+
public static final String RECOVERY_CMG_NODES_OPTION =
"--cluster-management-group";
public static final String RECOVERY_CMG_NODES_OPTION_DESC = "Names of
nodes (use comma-separated list of node names "
diff --git
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterMixin.java
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterMixin.java
index 65dd687c1b..caca6b84ce 100644
---
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterMixin.java
+++
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterMixin.java
@@ -19,17 +19,34 @@ package
org.apache.ignite.internal.cli.commands.recovery.cluster.reset;
import static
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_CMG_NODES_OPTION;
import static
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_CMG_NODES_OPTION_DESC;
+import static
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_METASTORAGE_REPLICATION_DESC;
+import static
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_METASTORAGE_REPLICATION_OPTION;
import java.util.List;
+import org.jetbrains.annotations.Nullable;
+import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Option;
/** Arguments for 'recovery cluster reset' command. */
public class ResetClusterMixin {
- @Option(names = RECOVERY_CMG_NODES_OPTION, description =
RECOVERY_CMG_NODES_OPTION_DESC, split = ",", required = true)
- private List<String> cmgNodeNames;
+ @ArgGroup(multiplicity = "1", exclusive = false)
+ private Options options;
/** Returns names of the proposed CMG nodes. */
- public List<String> cmgNodeNames() {
- return cmgNodeNames;
+ public @Nullable List<String> cmgNodeNames() {
+ return options.cmgNodeNames;
+ }
+
+ /** Returns metastorage replication factor. */
+ public @Nullable Integer metastorageReplicationFactor() {
+ return options.metastorageReplicationFactor;
+ }
+
+ private static class Options {
+ @Option(names = RECOVERY_CMG_NODES_OPTION, description =
RECOVERY_CMG_NODES_OPTION_DESC, split = ",")
+ private List<String> cmgNodeNames;
+
+ @Option(names = RECOVERY_METASTORAGE_REPLICATION_OPTION, description =
RECOVERY_METASTORAGE_REPLICATION_DESC)
+ private Integer metastorageReplicationFactor;
}
}
diff --git
a/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterCommandTest.java
b/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterCommandTest.java
new file mode 100644
index 0000000000..24a1a81891
--- /dev/null
+++
b/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/cluster/reset/ResetClusterCommandTest.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.cli.commands.recovery.cluster.reset;
+
+import static
org.apache.ignite.internal.cli.commands.Options.Constants.CLUSTER_URL_OPTION;
+import static
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_CMG_NODES_OPTION;
+import static
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_METASTORAGE_REPLICATION_OPTION;
+import static org.mockserver.model.HttpRequest.request;
+import static org.mockserver.model.HttpResponse.response;
+import static org.mockserver.model.JsonBody.json;
+
+import org.apache.ignite.internal.cli.commands.IgniteCliInterfaceTestBase;
+import org.apache.ignite.internal.util.ArrayUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.mockserver.model.MediaType;
+
+/** Unit tests for {@link ResetClusterCommand}. */
+public class ResetClusterCommandTest extends IgniteCliInterfaceTestBase {
+ @Test
+ @DisplayName("Reset cluster with CMG nodes specified")
+ void resetWithCmgNodesSpecified() {
+ String nodeNames = "node1,node2";
+
+ String expectedSentContent = "{"
+ + " \"cmgNodeNames\": [\"node1\", \"node2\"],"
+ + "}";
+
+ clientAndServer
+ .when(request()
+ .withMethod("POST")
+ .withPath("/management/v1/recovery/cluster/reset")
+ .withBody(json(expectedSentContent))
+ .withContentType(MediaType.APPLICATION_JSON_UTF_8)
+ )
+ .respond(response(null));
+
+ execute(CLUSTER_URL_OPTION, mockUrl,
+ RECOVERY_CMG_NODES_OPTION, nodeNames
+ );
+
+ assertErrOutputIsEmpty();
+ assertOutputIs("Successfully initiated cluster repair.");
+ }
+
+ @Test
+ @DisplayName("Reset cluster with replication factor specified")
+ void resetWithReplicationFactorSpecified() {
+ String replicationFactor = "5";
+
+ String expectedSentContent = "{"
+ + " \"metastorageReplicationFactor\" : 5"
+ + "}";
+
+ clientAndServer
+ .when(request()
+ .withMethod("POST")
+ .withPath("/management/v1/recovery/cluster/reset")
+ .withBody(json(expectedSentContent))
+ .withContentType(MediaType.APPLICATION_JSON_UTF_8)
+ )
+ .respond(response(null));
+
+ execute(CLUSTER_URL_OPTION, mockUrl,
+ RECOVERY_METASTORAGE_REPLICATION_OPTION, replicationFactor
+ );
+
+ assertErrOutputIsEmpty();
+ assertOutputIs("Successfully initiated cluster repair.");
+ }
+
+ @Test
+ @DisplayName("Reset cluster with cmg node names and replication factor
specified")
+ void resetWithCmgNodeNamesAndReplicationFactorSpecified() {
+ String replicationFactor = "5";
+ String nodeNames = "node1,node2";
+
+ String expectedSentContent = "{"
+ + " \"cmgNodeNames\": [\"node1\", \"node2\"],"
+ + " \"metastorageReplicationFactor\" : 5"
+ + "}";
+
+ clientAndServer
+ .when(request()
+ .withMethod("POST")
+ .withPath("/management/v1/recovery/cluster/reset")
+ .withBody(json(expectedSentContent))
+ .withContentType(MediaType.APPLICATION_JSON_UTF_8)
+ )
+ .respond(response(null));
+
+ execute(CLUSTER_URL_OPTION, mockUrl,
+ RECOVERY_CMG_NODES_OPTION, nodeNames,
+ RECOVERY_METASTORAGE_REPLICATION_OPTION, replicationFactor
+ );
+
+ assertErrOutputIsEmpty();
+ assertOutputIs("Successfully initiated cluster repair.");
+ }
+
+ @Test
+ @DisplayName("Reset cluster fails with args not specified")
+ void resetFailsArgsNotSpecified() {
+ execute(CLUSTER_URL_OPTION, mockUrl);
+
+ assertErrOutputContains("Missing required argument(s): ");
+ }
+
+ @Override
+ protected void execute(String... args) {
+ String[] fullArgs = ArrayUtils.concat(new String[] {"recovery",
"cluster", "reset"}, args);
+
+ super.execute(fullArgs);
+ }
+}
diff --git
a/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItCmgDisasterRecoveryTest.java
b/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItCmgDisasterRecoveryTest.java
index 3365bf12e3..a22c15f97a 100644
---
a/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItCmgDisasterRecoveryTest.java
+++
b/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItCmgDisasterRecoveryTest.java
@@ -80,8 +80,8 @@ class ItCmgDisasterRecoveryTest extends
ItSystemGroupDisasterRecoveryTest {
assertThat(ignite.logicalTopologyService().logicalTopologyOnLeader(),
willCompleteSuccessfully());
}
- private void initiateCmgRepairVia(int condictorIndex, int...
newCmgIndexes) throws InterruptedException {
- recoveryClient.initiateCmgRepair("localhost",
cluster.httpPort(condictorIndex), nodeNames(newCmgIndexes));
+ private void initiateCmgRepairVia(int conductorIndex, int...
newCmgIndexes) throws InterruptedException {
+ recoveryClient.initiateClusterReset("localhost",
cluster.httpPort(conductorIndex), null, nodeNames(newCmgIndexes));
}
@Test
diff --git
a/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItMetastorageGroupDisasterRecoveryTest.java
b/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItMetastorageGroupDisasterRecoveryTest.java
index 77dd33c3c6..2226b4123a 100644
---
a/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItMetastorageGroupDisasterRecoveryTest.java
+++
b/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/ItMetastorageGroupDisasterRecoveryTest.java
@@ -29,14 +29,12 @@ import static org.hamcrest.Matchers.notNullValue;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.stream.IntStream;
import org.apache.ignite.internal.app.IgniteImpl;
-import org.apache.ignite.internal.app.IgniteServerImpl;
import org.apache.ignite.internal.hlc.HybridTimestamp;
import org.apache.ignite.internal.lang.ByteArray;
import org.apache.ignite.internal.lang.NodeStoppingException;
@@ -63,7 +61,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
assertThatMgHasNoMajority(node0BeforeRestart);
- initiateMgRepairVia(node0BeforeRestart, 1, 0);
+ initiateMgRepairVia(0, 1, 0);
IgniteImpl restartedNode0 = waitTillNodeRestartsInternally(0);
waitTillMgHasMajority(restartedNode0);
@@ -83,12 +81,8 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
assertThat(ignite.metaStorageManager().get(new ByteArray("abc")),
willCompleteSuccessfully());
}
- private void initiateMgRepairVia(IgniteImpl conductor, int
mgReplicationFactor, int... newCmgIndexes) {
- // TODO: IGNITE-22897 - initiate repair via CLI.
-
- CompletableFuture<Void> initiationFuture =
conductor.systemDisasterRecoveryManager()
-
.resetClusterRepairingMetastorage(List.of(nodeNames(newCmgIndexes)),
mgReplicationFactor);
- assertThat(initiationFuture, willCompleteSuccessfully());
+ private void initiateMgRepairVia(int conductorIndex, int
mgReplicationFactor, int... newCmgIndexes) throws InterruptedException {
+ recoveryClient.initiateClusterReset("localhost",
cluster.httpPort(conductorIndex), mgReplicationFactor,
nodeNames(newCmgIndexes));
}
@Test
@@ -99,9 +93,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
// This makes the MG majority go away.
cluster.stopNode(1);
- IgniteImpl igniteImpl0BeforeRestart = igniteImpl(0);
-
- initiateMgRepairVia(igniteImpl0BeforeRestart, 1, 0);
+ initiateMgRepairVia(0, 1, 0);
IgniteImpl restartedIgniteImpl0 = waitTillNodeRestartsInternally(0);
waitTillMgHasMajority(restartedIgniteImpl0);
@@ -125,7 +117,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
assertThatMgHasNoMajority(igniteImpl2BeforeRestart);
- initiateMgRepairVia(igniteImpl2BeforeRestart, 3, 0, 1, 2);
+ initiateMgRepairVia(2, 3, 0, 1, 2);
IgniteImpl restartedIgniteImpl2 = waitTillNodeRestartsInternally(2);
waitTillMgHasMajority(restartedIgniteImpl2);
@@ -146,7 +138,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
cluster.stopNode(1);
- initiateMgRepairVia(igniteImpl(0), 1, 0);
+ initiateMgRepairVia(0, 1, 0);
// Doing this wait to make sure that blank node will be able to
connect at least someone. If we don't do this, the new node
// will still be able to connect, but this will happen on Scalecube's
initial sync retry, and we don't want to wait for it
@@ -179,7 +171,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
IntStream.of(0, 2).parallel().forEach(this::restartPartially);
- initiateMgRepairVia(((IgniteServerImpl)
cluster.server(0)).igniteImpl(), 1, 0);
+ initiateMgRepairVia(0, 1, 0);
IgniteImpl restartedIgniteImpl0 = waitTillNodeRestartsInternally(0);
waitTillMgHasMajority(restartedIgniteImpl0);
@@ -196,7 +188,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
IgniteImpl igniteImpl0BeforeRestart = igniteImpl(0);
- initiateMgRepairVia(igniteImpl0BeforeRestart, 1, 0);
+ initiateMgRepairVia(0, 1, 0);
IgniteImpl restartedIgniteImpl0 = waitTillNodeRestartsInternally(0);
waitTillMgHasMajority(restartedIgniteImpl0);
@@ -217,7 +209,7 @@ class ItMetastorageGroupDisasterRecoveryTest extends
ItSystemGroupDisasterRecove
assertThatMgHasNoMajority(igniteImpl0BeforeRestart);
- initiateMgRepairVia(igniteImpl0BeforeRestart, 1, 0);
+ initiateMgRepairVia(0, 1, 0);
IgniteImpl restartedIgniteImpl0 = waitTillNodeRestartsInternally(0);
waitTillMgHasMajority(restartedIgniteImpl0);
diff --git
a/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/SystemDisasterRecoveryClient.java
b/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/SystemDisasterRecoveryClient.java
index 3041882eb5..7d0f49ef4d 100644
---
a/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/SystemDisasterRecoveryClient.java
+++
b/modules/system-disaster-recovery/src/integrationTest/java/org/apache/ignite/internal/disaster/system/SystemDisasterRecoveryClient.java
@@ -19,6 +19,7 @@ package org.apache.ignite.internal.disaster.system;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.apache.ignite.internal.util.ArrayUtils.concat;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -29,6 +30,7 @@ import java.util.stream.Stream;
import org.apache.ignite.internal.cli.Main;
import org.apache.ignite.internal.logger.IgniteLogger;
import org.apache.ignite.internal.logger.Loggers;
+import org.jetbrains.annotations.Nullable;
/**
* Used to run system disaster recovery CLI commands.
@@ -37,15 +39,31 @@ import org.apache.ignite.internal.logger.Loggers;
class SystemDisasterRecoveryClient {
private static final IgniteLogger LOG =
Loggers.forClass(SystemDisasterRecoveryClient.class);
- void initiateCmgRepair(String httpHost, int httpPort, String...
newCmgNodeNames) throws InterruptedException {
- LOG.info("Initiating CMG repair via {}:{}, new CMG {}", httpHost,
httpPort, List.of(newCmgNodeNames));
-
- executeWithSameJavaBinaryAndClasspath(
- Main.class.getName(),
- "recovery", "cluster", "reset",
- "--url", "http://" + httpHost + ":" + httpPort,
- "--cluster-management-group", String.join(",", newCmgNodeNames)
+ void initiateClusterReset(
+ String httpHost,
+ int httpPort,
+ @Nullable Integer metastorageReplicationFactor,
+ String... newCmgNodeNames
+ ) throws InterruptedException {
+ LOG.info(
+ "Initiating cluster reset via {}:{}, new CMG {}, metastorage
replication Factor {}",
+ httpHost,
+ httpPort,
+ List.of(newCmgNodeNames),
+ metastorageReplicationFactor
);
+
+ String[] args = {Main.class.getName(), "recovery", "cluster", "reset",
"--url", "http://" + httpHost + ":" + httpPort};
+
+ if (newCmgNodeNames.length > 0) {
+ args = concat(args, "--cluster-management-group", String.join(",",
newCmgNodeNames));
+ }
+
+ if (metastorageReplicationFactor != null) {
+ args = concat(args, "--metastorage-replication-factor",
String.valueOf(metastorageReplicationFactor));
+ }
+
+ executeWithSameJavaBinaryAndClasspath(args);
}
private static void executeWithSameJavaBinaryAndClasspath(String... args)
throws InterruptedException {