This is an automated email from the ASF dual-hosted git repository.

sanpwc 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 938e09d0306 IGNITE-25987 Add public CLI API for partition restart with 
cleanup functionality (#6513)
938e09d0306 is described below

commit 938e09d0306be3f0d87d88f1714f55102e102840
Author: Cyrill <cyrill.si...@gmail.com>
AuthorDate: Tue Sep 2 10:00:36 2025 +0300

    IGNITE-25987 Add public CLI API for partition restart with cleanup 
functionality (#6513)
---
 .../restart/ItRestartPartitionsTest.java           | 71 +++++++++++++++++++++-
 .../recovery/restart/RestartPartitionsCall.java    | 12 +++-
 .../restart/RestartPartitionsCallInput.java        | 22 ++++++-
 .../ignite/internal/cli/commands/Options.java      |  5 ++
 .../partitions/restart/RestartPartitionsMixin.java | 10 +++
 .../partitions/restart/RestartPartitionsTest.java  | 64 +++++++++++++++++++
 6 files changed, 179 insertions(+), 5 deletions(-)

diff --git 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/ItRestartPartitionsTest.java
 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/ItRestartPartitionsTest.java
index 487abd5975f..f795455d85d 100644
--- 
a/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/ItRestartPartitionsTest.java
+++ 
b/modules/cli/src/integrationTest/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/ItRestartPartitionsTest.java
@@ -23,12 +23,14 @@ import static 
org.apache.ignite.internal.cli.commands.Options.Constants.CLUSTER_
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_NODE_NAMES_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_PARTITION_IDS_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_TABLE_NAME_OPTION;
+import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_WITH_CLEANUP_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_ZONE_NAME_OPTION;
 import static org.apache.ignite.lang.util.IgniteNameUtils.canonicalName;
 
 import org.apache.ignite.Ignite;
 import org.apache.ignite.internal.cli.CliIntegrationTest;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.DisabledIf;
 
@@ -44,10 +46,11 @@ public abstract class ItRestartPartitionsTest extends 
CliIntegrationTest {
 
     @BeforeAll
     public void createTables() {
-        sql(String.format("CREATE ZONE \"%s\" storage profiles ['%s']", ZONE, 
DEFAULT_AIPERSIST_PROFILE_NAME));
+        sql(String.format("CREATE ZONE \"%s\" (REPLICAS %s) storage profiles 
['%s']", ZONE, 3, DEFAULT_AIPERSIST_PROFILE_NAME));
         sql(String.format("CREATE TABLE PUBLIC.\"%s\" (id INT PRIMARY KEY, val 
INT) ZONE \"%s\"", TABLE_NAME, ZONE));
     }
 
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26337";)
     @Test
     public void testRestartAllPartitions() {
         execute(CLUSTER_URL_OPTION, NODE_URL,
@@ -161,4 +164,70 @@ public abstract class ItRestartPartitionsTest extends 
CliIntegrationTest {
                 DEFAULT_PARTITION_COUNT
         ));
     }
+
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26337";)
+    @Test
+    public void testRestartAllPartitionsWithCleanup() {
+        execute(CLUSTER_URL_OPTION, NODE_URL,
+                RECOVERY_TABLE_NAME_OPTION, QUALIFIED_TABLE_NAME,
+                RECOVERY_ZONE_NAME_OPTION, ZONE,
+                RECOVERY_WITH_CLEANUP_OPTION
+        );
+
+        assertErrOutputIsEmpty();
+        assertOutputContains("Successfully restarted partitions.");
+    }
+
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26337";)
+    @Test
+    public void testRestartSpecifiedPartitionsWithCleanup() {
+        execute(CLUSTER_URL_OPTION, NODE_URL,
+                RECOVERY_TABLE_NAME_OPTION, QUALIFIED_TABLE_NAME,
+                RECOVERY_ZONE_NAME_OPTION, ZONE,
+                RECOVERY_PARTITION_IDS_OPTION, "1,2",
+                RECOVERY_WITH_CLEANUP_OPTION
+        );
+
+        assertErrOutputIsEmpty();
+        assertOutputContains("Successfully restarted partitions.");
+    }
+
+    @Disabled("https://issues.apache.org/jira/browse/IGNITE-26337";)
+    @Test
+    public void testRestartPartitionsByNodesWithCleanup() {
+        String nodeNames = CLUSTER.runningNodes()
+                .limit(initialNodes() - 1)
+                .map(Ignite::name)
+                .collect(joining(","));
+
+        execute(CLUSTER_URL_OPTION, NODE_URL,
+                RECOVERY_TABLE_NAME_OPTION, QUALIFIED_TABLE_NAME,
+                RECOVERY_ZONE_NAME_OPTION, ZONE,
+                RECOVERY_PARTITION_IDS_OPTION, "1,2",
+                RECOVERY_NODE_NAMES_OPTION, nodeNames,
+                RECOVERY_WITH_CLEANUP_OPTION
+        );
+
+        assertErrOutputIsEmpty();
+        assertOutputContains("Successfully restarted partitions.");
+    }
+
+    @Test
+    public void testRestartPartitionsByNodesWithCleanupNoExecutorInNodes() {
+        String nodeNames = CLUSTER.runningNodes()
+                .skip(1)
+                .map(Ignite::name)
+                .collect(joining(","));
+
+        execute(CLUSTER_URL_OPTION, NODE_URL,
+                RECOVERY_TABLE_NAME_OPTION, QUALIFIED_TABLE_NAME,
+                RECOVERY_ZONE_NAME_OPTION, ZONE,
+                RECOVERY_PARTITION_IDS_OPTION, "1,2",
+                RECOVERY_NODE_NAMES_OPTION, nodeNames,
+                RECOVERY_WITH_CLEANUP_OPTION
+        );
+
+        assertErrOutputIsEmpty();
+        assertOutputContains("Successfully restarted partitions.");
+    }
 }
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCall.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCall.java
index 5c0b1f82b23..c45b98a5016 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCall.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCall.java
@@ -50,7 +50,11 @@ public class RestartPartitionsCall implements 
Call<RestartPartitionsCallInput, S
                 command.setNodeNames(input.nodeNames());
                 command.setZoneName(input.zoneName());
 
-                client.restartZonePartitions(command);
+                if (input.withCleanup()) {
+                    client.restartZonePartitionsWithCleanup(command);
+                } else {
+                    client.restartZonePartitions(command);
+                }
             } else {
                 RestartPartitionsRequest command = new 
RestartPartitionsRequest();
 
@@ -59,7 +63,11 @@ public class RestartPartitionsCall implements 
Call<RestartPartitionsCallInput, S
                 command.setTableName(input.tableName());
                 command.setZoneName(input.zoneName());
 
-                client.restartPartitions(command);
+                if (input.withCleanup()) {
+                    client.restartPartitionsWithCleanup(command);
+                } else {
+                    client.restartPartitions(command);
+                }
             }
 
             return DefaultCallOutput.success(
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCallInput.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCallInput.java
index e541bef10c5..495a87fad70 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCallInput.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/call/recovery/restart/RestartPartitionsCallInput.java
@@ -34,6 +34,8 @@ public class RestartPartitionsCallInput implements CallInput {
 
     private final List<Integer> partitionIds;
 
+    private final boolean withCleanup;
+
     /** Cluster url. */
     public String clusterUrl() {
         return clusterUrl;
@@ -59,18 +61,25 @@ public class RestartPartitionsCallInput implements 
CallInput {
         return nodeNames;
     }
 
+    /** Whether to restart partitions with cleanup. */
+    public boolean withCleanup() {
+        return withCleanup;
+    }
+
     private RestartPartitionsCallInput(
             String clusterUrl,
             String zoneName,
             String tableName,
             @Nullable List<Integer> partitionIds,
-            @Nullable List<String> nodeNames
+            @Nullable List<String> nodeNames,
+            boolean withCleanup
     ) {
         this.clusterUrl = clusterUrl;
         this.zoneName = zoneName;
         this.tableName = tableName;
         this.partitionIds = partitionIds == null ? List.of() : 
List.copyOf(partitionIds);
         this.nodeNames = nodeNames == null ? List.of() : 
List.copyOf(nodeNames);
+        this.withCleanup = withCleanup;
     }
 
     /** Returns {@link RestartPartitionsCallInput} with specified arguments. */
@@ -80,6 +89,7 @@ public class RestartPartitionsCallInput implements CallInput {
                 .tableName(restartArgs.tableName())
                 .partitionIds(restartArgs.partitionIds())
                 .nodeNames(restartArgs.nodeNames())
+                .withCleanup(restartArgs.withCleanup())
                 .clusterUrl(clusterUrl)
                 .build();
     }
@@ -107,6 +117,8 @@ public class RestartPartitionsCallInput implements 
CallInput {
         @Nullable
         private List<String> nodeNames;
 
+        private boolean withCleanup;
+
         /** Set cluster URL. */
         RestartPartitionsCallInputBuilder clusterUrl(String clusterUrl) {
             this.clusterUrl = clusterUrl;
@@ -137,9 +149,15 @@ public class RestartPartitionsCallInput implements 
CallInput {
             return this;
         }
 
+        /** Set whether to restart partitions with cleanup. */
+        RestartPartitionsCallInputBuilder withCleanup(boolean withCleanup) {
+            this.withCleanup = withCleanup;
+            return this;
+        }
+
         /** Build {@link RestartPartitionsCallInput}. */
         RestartPartitionsCallInput build() {
-            return new RestartPartitionsCallInput(clusterUrl, zoneName, 
tableName, partitionIds, nodeNames);
+            return new RestartPartitionsCallInput(clusterUrl, zoneName, 
tableName, partitionIds, nodeNames, withCleanup);
         }
     }
 }
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 e225a3e536c..a64ebf215fc 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
@@ -307,6 +307,11 @@ public enum Options {
                 + "'--cluster-management-group node1, node2' "
                 + "to specify more than one node) that will host the Cluster 
Management Group.";
 
+        public static final String RECOVERY_WITH_CLEANUP_OPTION = 
"--with-cleanup";
+
+        public static final String RECOVERY_WITH_CLEANUP_OPTION_DESC = 
"Restarts partitions, preceded by a storage cleanup. "
+                + "This will remove all data from the partition storages 
before restart.";
+
         /** Old cluster endpoint URL option long name. */
         public static final String RECOVERY_OLD_CLUSTER_URL_OPTION = 
"--old-cluster-url";
 
diff --git 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsMixin.java
 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsMixin.java
index 6527418d881..5ec51ebc23f 100644
--- 
a/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsMixin.java
+++ 
b/modules/cli/src/main/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsMixin.java
@@ -23,6 +23,8 @@ import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_PARTITION_IDS_OPTION_DESC;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_TABLE_NAME_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_TABLE_NAME_OPTION_DESC;
+import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_WITH_CLEANUP_OPTION;
+import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_WITH_CLEANUP_OPTION_DESC;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_ZONE_NAME_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_ZONE_NAME_OPTION_DESC;
 
@@ -44,6 +46,9 @@ public class RestartPartitionsMixin {
     @Option(names = RECOVERY_TABLE_NAME_OPTION, description = 
RECOVERY_TABLE_NAME_OPTION_DESC, required = true)
     private String tableName;
 
+    @Option(names = RECOVERY_WITH_CLEANUP_OPTION, description = 
RECOVERY_WITH_CLEANUP_OPTION_DESC)
+    private boolean withCleanup;
+
     /** Returns name of the zone to restart partitions of. */
     public String zoneName() {
         return zoneName;
@@ -65,4 +70,9 @@ public class RestartPartitionsMixin {
     public List<String> nodeNames() {
         return nodeNames;
     }
+
+    /** Returns whether to restart partitions with cleanup. */
+    public boolean withCleanup() {
+        return withCleanup;
+    }
 }
diff --git 
a/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsTest.java
 
b/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsTest.java
index bf69f75af2c..cc5a9f2d689 100644
--- 
a/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsTest.java
+++ 
b/modules/cli/src/test/java/org/apache/ignite/internal/cli/commands/recovery/partitions/restart/RestartPartitionsTest.java
@@ -21,6 +21,7 @@ import static 
org.apache.ignite.internal.cli.commands.Options.Constants.CLUSTER_
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_NODE_NAMES_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_PARTITION_IDS_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_TABLE_NAME_OPTION;
+import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_WITH_CLEANUP_OPTION;
 import static 
org.apache.ignite.internal.cli.commands.Options.Constants.RECOVERY_ZONE_NAME_OPTION;
 import static 
org.apache.ignite.internal.lang.IgniteSystemProperties.colocationEnabled;
 import static org.mockserver.matchers.MatchType.ONLY_MATCHING_FIELDS;
@@ -38,10 +39,12 @@ import org.mockserver.model.MediaType;
 /** Unit tests for {@link RestartPartitionsCommand}. */
 public class RestartPartitionsTest extends IgniteCliInterfaceTestBase {
     private static String PARTITIONS_RESTART_ENDPOINT;
+    private static String PARTITIONS_RESTART_ENDPOINT_WITH_CLEANUP;
 
     @BeforeAll
     public static void beforeAll() {
         PARTITIONS_RESTART_ENDPOINT = "partitions/restart";
+        PARTITIONS_RESTART_ENDPOINT_WITH_CLEANUP = 
"partitions/restartWithCleanup";
     }
 
     @Test
@@ -127,6 +130,67 @@ public class RestartPartitionsTest extends 
IgniteCliInterfaceTestBase {
         assertOutputIs("Successfully restarted partitions.");
     }
 
+    @Test
+    @DisplayName("Restart all partitions with cleanup")
+    void restartAllPartitionsWithCleanup() {
+        String expectedSentContent;
+
+        if (colocationEnabled()) {
+            expectedSentContent = "{"
+                    + "     \"zoneName\" : \"zone_NAME\""
+                    + "}";
+
+        } else {
+            expectedSentContent = "{"
+                    + "     \"tableName\" : \"table_NAME\","
+                    + "     \"zoneName\" : \"zone_NAME\""
+                    + "}";
+        }
+
+        clientAndServer
+                .when(request()
+                        .withMethod("POST")
+                        .withPath("/management/v1/recovery/" + 
PARTITIONS_RESTART_ENDPOINT_WITH_CLEANUP)
+                        .withBody(json(expectedSentContent))
+                        .withContentType(MediaType.APPLICATION_JSON_UTF_8)
+                )
+                .respond(response(null));
+
+        execute(CLUSTER_URL_OPTION, mockUrl,
+                RECOVERY_TABLE_NAME_OPTION, "table_NAME",
+                RECOVERY_ZONE_NAME_OPTION, "zone_NAME",
+                RECOVERY_WITH_CLEANUP_OPTION
+        );
+
+        assertErrOutputIsEmpty();
+        assertOutputIs("Successfully restarted partitions.");
+    }
+
+    @Test
+    @DisplayName("Restart specified partitions with cleanup")
+    void restartSpecifiedPartitionsWithCleanup() {
+        String expectedSentContent = "{\"partitionIds\" : [1,2]}";
+
+        clientAndServer
+                .when(request()
+                        .withMethod("POST")
+                        .withPath("/management/v1/recovery/" + 
PARTITIONS_RESTART_ENDPOINT_WITH_CLEANUP)
+                        .withBody(json(expectedSentContent, 
ONLY_MATCHING_FIELDS))
+                        .withContentType(MediaType.APPLICATION_JSON_UTF_8)
+                )
+                .respond(response(null));
+
+        execute(CLUSTER_URL_OPTION, mockUrl,
+                RECOVERY_TABLE_NAME_OPTION, "table_NAME",
+                RECOVERY_ZONE_NAME_OPTION, "zone_NAME",
+                RECOVERY_PARTITION_IDS_OPTION, "1,2",
+                RECOVERY_WITH_CLEANUP_OPTION
+        );
+
+        assertErrOutputIsEmpty();
+        assertOutputIs("Successfully restarted partitions.");
+    }
+
     @Override
     protected void execute(String... args) {
         String[] fullArgs = ArrayUtils.concat(new String[] {"recovery", 
"partitions", "restart"}, args);

Reply via email to