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

nizhikov pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 93394abdada IGNITE-27033: Сheckpoint command added (#12547)
93394abdada is described below

commit 93394abdada537af66b769d8f5409bec0fed82c4
Author: DEADripER <[email protected]>
AuthorDate: Tue Dec 30 15:04:01 2025 +0300

    IGNITE-27033: Сheckpoint command added (#12547)
---
 .../testsuites/IgniteControlUtilityTestSuite.java  |   4 +-
 .../util/GridCommandHandlerCheckpointTest.java     | 278 +++++++++++++++++++++
 .../internal/management/IgniteCommandRegistry.java |   2 +
 .../management/checkpoint/CheckpointCommand.java   |  53 ++++
 .../checkpoint/CheckpointCommandArg.java           |  87 +++++++
 .../management/checkpoint/CheckpointTask.java      | 111 ++++++++
 ...ridCommandHandlerClusterByClassTest_help.output |   8 +
 ...andHandlerClusterByClassWithSSLTest_help.output |   8 +
 8 files changed, 550 insertions(+), 1 deletion(-)

diff --git 
a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
 
b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
index 175540df381..ae32372c0b2 100644
--- 
a/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
+++ 
b/modules/control-utility/src/test/java/org/apache/ignite/testsuites/IgniteControlUtilityTestSuite.java
@@ -24,6 +24,7 @@ import 
org.apache.ignite.internal.processors.security.GridCommandHandlerSslWithS
 import org.apache.ignite.util.GridCommandHandlerBrokenIndexTest;
 import org.apache.ignite.util.GridCommandHandlerCheckIncrementalSnapshotTest;
 import org.apache.ignite.util.GridCommandHandlerCheckIndexesInlineSizeTest;
+import org.apache.ignite.util.GridCommandHandlerCheckpointTest;
 import org.apache.ignite.util.GridCommandHandlerClusterByClassTest;
 import org.apache.ignite.util.GridCommandHandlerClusterByClassWithSSLTest;
 import 
org.apache.ignite.util.GridCommandHandlerConsistencyRepairCorrectnessTransactionalTest;
@@ -80,7 +81,8 @@ import org.junit.runners.Suite;
     BaselineEventsRemoteTest.class,
 
     GridCommandHandlerConsistencyRepairCorrectnessTransactionalTest.class,
-    GridCommandHandlerWalTest.class
+    GridCommandHandlerWalTest.class,
+    GridCommandHandlerCheckpointTest.class
 })
 public class IgniteControlUtilityTestSuite {
 }
diff --git 
a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckpointTest.java
 
b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckpointTest.java
new file mode 100644
index 00000000000..57d384afe79
--- /dev/null
+++ 
b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerCheckpointTest.java
@@ -0,0 +1,278 @@
+/*
+ * 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.util;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.regex.Pattern;
+import org.apache.ignite.IgniteCache;
+import org.apache.ignite.cluster.ClusterState;
+import org.apache.ignite.configuration.DataRegionConfiguration;
+import org.apache.ignite.configuration.DataStorageConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.IgniteEx;
+import 
org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
+import 
org.apache.ignite.internal.processors.cache.persistence.checkpoint.CheckpointListener;
+import org.apache.ignite.testframework.GridTestUtils;
+import org.apache.ignite.testframework.ListeningTestLogger;
+import org.apache.ignite.testframework.LogListener;
+import org.junit.Test;
+
+import static 
org.apache.ignite.internal.commandline.CommandHandler.EXIT_CODE_OK;
+
+/** Test for checkpoint in control.sh command. */
+public class GridCommandHandlerCheckpointTest extends 
GridCommandHandlerAbstractTest {
+    /** */
+    private static final String PERSISTENT_REGION_NAME = "pds-reg";
+
+    /** */
+    private final ListeningTestLogger listeningLog = new 
ListeningTestLogger(log);
+
+    /** */
+    private final LogListener checkpointFinishedLsnr = 
LogListener.matches("Checkpoint finished").build();
+
+    /** */
+    private boolean mixedConfig;
+
+    /** Latch for blocking checkpoint in timeout test. */
+    private CountDownLatch blockCheckpointLatch;
+
+    /** */
+    @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        listeningLog.registerListener(checkpointFinishedLsnr);
+
+        cfg.setGridLogger(listeningLog);
+
+        if (mixedConfig) {
+            DataStorageConfiguration storageCfg = new 
DataStorageConfiguration();
+
+            storageCfg.setDefaultDataRegionConfiguration(new 
DataRegionConfiguration().setName("default_in_memory_region")
+                                                                               
       .setPersistenceEnabled(false));
+
+            if (igniteInstanceName.contains("persistent_instance")) {
+                DataRegionConfiguration persistentRegionCfg = new 
DataRegionConfiguration();
+
+                
storageCfg.setDataRegionConfigurations(persistentRegionCfg.setName(PERSISTENT_REGION_NAME)
+                                                                          
.setPersistenceEnabled(true));
+            }
+
+            cfg.setDataStorageConfiguration(storageCfg);
+        }
+        else if (!persistenceEnable()) {
+            cfg.setDataStorageConfiguration(null);
+        }
+
+        return cfg;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void beforeTest() throws Exception {
+        super.beforeTest();
+
+        stopAllGrids();
+        cleanPersistenceDir();
+        injectTestSystemOut();
+
+        checkpointFinishedLsnr.reset();
+        blockCheckpointLatch = null;
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void afterTest() throws Exception {
+        if (blockCheckpointLatch != null) {
+            blockCheckpointLatch.countDown();
+        }
+
+        stopAllGrids();
+        cleanPersistenceDir();
+
+        super.afterTest();
+    }
+
+    /** Test checkpoint command with persistence enabled. */
+    @Test
+    public void testCheckpointPersistenceCluster() throws Exception {
+        persistenceEnable(true);
+
+        IgniteEx srv = startGrids(2);
+        IgniteEx cli = startClientGrid("client");
+
+        srv.cluster().state(ClusterState.ACTIVE);
+
+        IgniteCache<Integer, Integer> cacheCli = 
cli.getOrCreateCache(DEFAULT_CACHE_NAME);
+
+        cacheCli.put(1, 1);
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint"));
+        
assertTrue(GridTestUtils.waitForCondition(checkpointFinishedLsnr::check, 
10_000));
+        assertFalse(testOut.toString().contains("persistence disabled"));
+
+        outputContains(": Checkpoint started");
+
+        testOut.reset();
+
+        checkpointFinishedLsnr.reset();
+
+        cacheCli.put(2, 2);
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint", "--reason", 
"test_reason"));
+
+        LogListener checkpointReasonLsnr = 
LogListener.matches("reason='test_reason'").build();
+
+        listeningLog.registerListener(checkpointReasonLsnr);
+
+        
assertTrue(GridTestUtils.waitForCondition(checkpointFinishedLsnr::check, 
10_000));
+        assertTrue(GridTestUtils.waitForCondition(checkpointReasonLsnr::check, 
10_000));
+        assertFalse(testOut.toString().contains("persistence disabled"));
+
+        outputContains(": Checkpoint started");
+
+        testOut.reset();
+
+        checkpointFinishedLsnr.reset();
+
+        cacheCli.put(3, 3);
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint", 
"--wait-for-finish"));
+        assertTrue(checkpointFinishedLsnr.check());
+        assertFalse(testOut.toString().contains("persistence disabled"));
+    }
+
+    /** Test checkpoint command with in-memory cluster. */
+    @Test
+    public void testCheckpointInMemoryCluster() throws Exception {
+        persistenceEnable(false);
+
+        IgniteEx srv = startGrids(2);
+
+        startClientGrid("client");
+
+        srv.cluster().state(ClusterState.ACTIVE);
+
+        srv.createCache("testCache");
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint"));
+        assertFalse(checkpointFinishedLsnr.check());
+
+        outputContains("persistence disabled");
+    }
+
+    /** Test checkpoint with timeout when checkpoint completes within timeout. 
*/
+    @Test
+    public void testCheckpointTimeout() throws Exception {
+        persistenceEnable(true);
+
+        IgniteEx srv = startGrids(1);
+
+        srv.cluster().state(ClusterState.ACTIVE);
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint", 
"--wait-for-finish", "--timeout", "1000"));
+
+        assertTrue(checkpointFinishedLsnr.check());
+
+        assertFalse(testOut.toString().contains("persistence disabled"));
+    }
+
+    /** Test checkpoint timeout when checkpoint doesn't complete within 
timeout. */
+    @Test
+    public void testCheckpointTimeoutExceeded() throws Exception {
+        persistenceEnable(true);
+
+        IgniteEx srv = startGrids(1);
+
+        srv.cluster().state(ClusterState.ACTIVE);
+
+        blockCheckpointLatch = new CountDownLatch(1);
+
+        GridCacheDatabaseSharedManager dbMgr = 
(GridCacheDatabaseSharedManager)srv.context().cache().context().database();
+
+        dbMgr.addCheckpointListener(new CheckpointListener() {
+            @Override public void onMarkCheckpointBegin(Context ctx) {
+                try {
+                    blockCheckpointLatch.await();
+                }
+                catch (InterruptedException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+
+            @Override public void onCheckpointBegin(Context ctx) {
+                // No-op
+            }
+
+            @Override public void beforeCheckpointBegin(Context ctx) {
+                // No-op
+            }
+        });
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint", 
"--wait-for-finish", "--timeout", "500"));
+
+        outputContains("Checkpoint started but not finished within timeout 500 
ms");
+
+        blockCheckpointLatch.countDown();
+
+        
assertTrue(GridTestUtils.waitForCondition(checkpointFinishedLsnr::check, 
10_000));
+    }
+
+    /** Mixed cluster test. */
+    @Test
+    public void testMixedCluster() throws Exception {
+        mixedConfig = true;
+
+        IgniteEx node0 = startGrid("in-memory_instance");
+
+        node0.cluster().baselineAutoAdjustEnabled(false);
+
+        IgniteEx node1 = startGrid("persistent_instance");
+
+        node0.cluster().state(ClusterState.ACTIVE);
+
+        assertEquals(2, node0.cluster().nodes().size());
+
+        DataStorageConfiguration node0Storage = 
node0.configuration().getDataStorageConfiguration();
+        DataStorageConfiguration node1Storage = 
node1.configuration().getDataStorageConfiguration();
+
+        DataRegionConfiguration node0Dflt = 
node0Storage.getDefaultDataRegionConfiguration();
+        DataRegionConfiguration node1Dflt = 
node1Storage.getDefaultDataRegionConfiguration();
+
+        assertEquals(node0Dflt.getName(), node1Dflt.getName());
+        assertEquals(node0Dflt.isPersistenceEnabled(), 
node1Dflt.isPersistenceEnabled());
+        assertEquals(node0Dflt.getMaxSize(), node1Dflt.getMaxSize());
+
+        DataRegionConfiguration[] node1Regions = 
node1Storage.getDataRegionConfigurations();
+        assertEquals(1, node1Regions.length);
+
+        DataRegionConfiguration persistentRegion = node1Regions[0];
+
+        assertEquals(PERSISTENT_REGION_NAME, persistentRegion.getName());
+        assertEquals(true, persistentRegion.isPersistenceEnabled());
+
+        assertEquals(EXIT_CODE_OK, execute("--checkpoint", 
"--wait-for-finish"));
+
+        assertTrue(checkpointFinishedLsnr.check());
+
+        outputContains("persistence disabled");
+        outputContains("Checkpoint finished");
+    }
+
+    /** */
+    private void outputContains(String regexp) {
+        assertTrue(Pattern.compile(regexp).matcher(testOut.toString()).find());
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/management/IgniteCommandRegistry.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/management/IgniteCommandRegistry.java
index 4388486148a..1f28f1cfbd2 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/internal/management/IgniteCommandRegistry.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/management/IgniteCommandRegistry.java
@@ -24,6 +24,7 @@ import org.apache.ignite.internal.management.api.NoArg;
 import org.apache.ignite.internal.management.baseline.BaselineCommand;
 import org.apache.ignite.internal.management.cache.CacheCommand;
 import org.apache.ignite.internal.management.cdc.CdcCommand;
+import org.apache.ignite.internal.management.checkpoint.CheckpointCommand;
 import org.apache.ignite.internal.management.consistency.ConsistencyCommand;
 import 
org.apache.ignite.internal.management.defragmentation.DefragmentationCommand;
 import org.apache.ignite.internal.management.diagnostic.DiagnosticCommand;
@@ -58,6 +59,7 @@ public class IgniteCommandRegistry extends 
CommandRegistryImpl<NoArg, Void> {
             new TxCommand(),
             new CacheCommand(),
             new WalCommand(),
+            new CheckpointCommand(),
             new DiagnosticCommand(),
             new EncryptionCommand(),
             new KillCommand(),
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointCommand.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointCommand.java
new file mode 100644
index 00000000000..9129c8e0820
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointCommand.java
@@ -0,0 +1,53 @@
+/*
+ * 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.management.checkpoint;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+import org.apache.ignite.cluster.ClusterNode;
+import org.apache.ignite.internal.management.api.CommandUtils;
+import org.apache.ignite.internal.management.api.ComputeCommand;
+import org.jetbrains.annotations.Nullable;
+
+/** Checkpoint command. */
+public class CheckpointCommand implements ComputeCommand<CheckpointCommandArg, 
String> {
+    /** {@inheritDoc} */
+    @Override public Class<CheckpointTask> taskClass() {
+        return CheckpointTask.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override public String description() {
+        return "Trigger checkpoint";
+    }
+
+    /** {@inheritDoc} */
+    @Override public Class<CheckpointCommandArg> argClass() {
+        return CheckpointCommandArg.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override public @Nullable Collection<ClusterNode> 
nodes(Collection<ClusterNode> nodes, CheckpointCommandArg arg) {
+        return CommandUtils.servers(nodes);
+    }
+
+    /** {@inheritDoc} */
+    @Override public void printResult(CheckpointCommandArg arg, String res, 
Consumer<String> printer) {
+        printer.accept(res);
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointCommandArg.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointCommandArg.java
new file mode 100644
index 00000000000..f5f40c9a549
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointCommandArg.java
@@ -0,0 +1,87 @@
+/*
+ * 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.management.checkpoint;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import org.apache.ignite.internal.dto.IgniteDataTransferObject;
+import org.apache.ignite.internal.management.api.Argument;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/** Checkpoint command arguments. */
+public class CheckpointCommandArg extends IgniteDataTransferObject {
+    /** */
+    private static final long serialVersionUID = 0;
+
+    /** */
+    @Argument(description = "Reason (visible in logs)", optional = true)
+    private String reason;
+
+    /** */
+    @Argument(description = "Wait for checkpoint to finish", optional = true)
+    private boolean waitForFinish;
+
+    /** */
+    @Argument(description = "Timeout in milliseconds", optional = true)
+    private long timeout = -1;
+
+    /** {@inheritDoc} */
+    @Override protected void writeExternalData(ObjectOutput out) throws 
IOException {
+        U.writeString(out, reason);
+        out.writeBoolean(waitForFinish);
+        out.writeLong(timeout);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected void readExternalData(ObjectInput in) throws 
IOException, ClassNotFoundException {
+        reason = U.readString(in);
+        waitForFinish = in.readBoolean();
+        timeout = in.readLong();
+    }
+
+    /** */
+    public String reason() {
+        return reason;
+    }
+
+    /** */
+    public void reason(String reason) {
+        this.reason = reason;
+    }
+
+    /** */
+    public boolean waitForFinish() {
+        return waitForFinish;
+    }
+
+    /** */
+    public void waitForFinish(boolean waitForFinish) {
+        this.waitForFinish = waitForFinish;
+    }
+
+    /** */
+    public long timeout() {
+        return timeout;
+    }
+
+    /** */
+    public void timeout(long timeout) {
+        this.timeout = timeout;
+    }
+}
diff --git 
a/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointTask.java
 
b/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointTask.java
new file mode 100644
index 00000000000..1b5f95b13fa
--- /dev/null
+++ 
b/modules/core/src/main/java/org/apache/ignite/internal/management/checkpoint/CheckpointTask.java
@@ -0,0 +1,111 @@
+/*
+ * 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.management.checkpoint;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.IgniteException;
+import org.apache.ignite.compute.ComputeJobResult;
+import org.apache.ignite.internal.IgniteFutureTimeoutCheckedException;
+import org.apache.ignite.internal.processors.cache.persistence.CheckpointState;
+import 
org.apache.ignite.internal.processors.cache.persistence.GridCacheDatabaseSharedManager;
+import 
org.apache.ignite.internal.processors.cache.persistence.checkpoint.CheckpointProgress;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.visor.VisorJob;
+import org.apache.ignite.internal.visor.VisorMultiNodeTask;
+import org.jetbrains.annotations.Nullable;
+
+/** Checkpoint task. */
+public class CheckpointTask extends VisorMultiNodeTask<CheckpointCommandArg, 
String, String> {
+    /** */
+    private static final long serialVersionUID = 0;
+
+    /** {@inheritDoc} */
+    @Override protected VisorJob<CheckpointCommandArg, String> 
job(CheckpointCommandArg arg) {
+        return new CheckpointJob(arg, false);
+    }
+
+    /** {@inheritDoc} */
+    @Override protected @Nullable String reduce0(List<ComputeJobResult> 
results) throws IgniteException {
+        StringBuilder result = new StringBuilder();
+
+        for (ComputeJobResult res : results) {
+            if (res.getException() != null)
+                throw res.getException();
+
+            result.append(res.getData().toString()).append('\n');
+        }
+
+        return result.toString();
+    }
+
+    /** Checkpoint job. */
+    private static class CheckpointJob extends VisorJob<CheckpointCommandArg, 
String> {
+        /** */
+        private static final long serialVersionUID = 0;
+
+        /** */
+        protected CheckpointJob(CheckpointCommandArg arg, boolean debug) {
+            super(arg, debug);
+        }
+
+        /** {@inheritDoc} */
+        @Override protected String run(CheckpointCommandArg arg) throws 
IgniteException {
+            if (!CU.isPersistenceEnabled(ignite.configuration()))
+                  return result("persistence disabled, checkpoint skipped");
+
+            try {
+                GridCacheDatabaseSharedManager dbMgr = 
(GridCacheDatabaseSharedManager)ignite.context().cache().context().database();
+
+                CheckpointProgress checkpointfut = 
dbMgr.forceCheckpoint(arg.reason());
+
+                if (arg.waitForFinish()) {
+                    long timeout = arg.timeout();
+
+                    if (timeout > 0) {
+                        try {
+                            
checkpointfut.futureFor(CheckpointState.FINISHED).get(timeout, 
TimeUnit.MILLISECONDS);
+                        }
+                        catch (IgniteFutureTimeoutCheckedException e) {
+                            return result("Checkpoint started but not finished 
within timeout " + timeout + " ms");
+                        }
+                    }
+                    else
+                        
checkpointfut.futureFor(CheckpointState.FINISHED).get();
+
+                    return result("Checkpoint finished");
+                }
+
+                return result("Checkpoint started");
+            }
+            catch (IgniteCheckedException e) {
+                throw new IgniteException(result("Failed to force checkpoint 
on node"), e);
+            }
+        }
+
+        /**
+         * Create result string with node id and given description
+         *
+         * @param desc info about node to be put in result.
+         */
+        private String result(String desc) {
+            return ignite.localNode().id() + ": " + desc;
+        }
+    }
+}
diff --git 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
index a456cc42598..06ed1dbb83b 100644
--- 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
+++ 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassTest_help.output
@@ -109,6 +109,14 @@ This utility can do the following commands:
     Parameters:
       --groups group1[,group2,....,groupN]  - Comma-separated list of cache 
groups. If not set action applied to all groups.
 
+  Trigger checkpoint:
+    control.(sh|bat) --checkpoint [--reason reason] [--wait-for-finish] 
[--timeout timeout]
+
+    Parameters:
+      --reason reason    - Reason (visible in logs).
+      --wait-for-finish  - Wait for checkpoint to finish.
+      --timeout timeout  - Timeout in milliseconds.
+
   Print diagnostic command help:
     control.(sh|bat) --diagnostic
 
diff --git 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
index bdd83c95836..20bf8167824 100644
--- 
a/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
+++ 
b/modules/core/src/test/resources/org.apache.ignite.util/GridCommandHandlerClusterByClassWithSSLTest_help.output
@@ -109,6 +109,14 @@ This utility can do the following commands:
     Parameters:
       --groups group1[,group2,....,groupN]  - Comma-separated list of cache 
groups. If not set action applied to all groups.
 
+  Trigger checkpoint:
+    control.(sh|bat) --checkpoint [--reason reason] [--wait-for-finish] 
[--timeout timeout]
+
+    Parameters:
+      --reason reason    - Reason (visible in logs).
+      --wait-for-finish  - Wait for checkpoint to finish.
+      --timeout timeout  - Timeout in milliseconds.
+
   Print diagnostic command help:
     control.(sh|bat) --diagnostic
 

Reply via email to