This is an automated email from the ASF dual-hosted git repository. zstan pushed a commit to branch ignite-2.18 in repository https://gitbox.apache.org/repos/asf/ignite.git
commit 0a126f8d717c65491b821798d14f0ed999ce28c3 Author: Maksim Timonin <[email protected]> AuthorDate: Thu Feb 12 11:46:54 2026 +0300 IGNITE-27457 Add output for enable/disable WAL commands (#12711) (cherry picked from commit 38ab8cf87368ae3632f2c177b4b37196bc2a919f) --- .../ignite/util/GridCommandHandlerWalTest.java | 80 +++++++++++++++++---- .../internal/management/wal/WalDisableCommand.java | 8 ++- .../internal/management/wal/WalEnableCommand.java | 8 ++- .../internal/management/wal/WalSetStateTask.java | 52 ++++++++------ .../management/wal/WalSetStateTaskResult.java | 81 ++++++++++++++++++++++ 5 files changed, 195 insertions(+), 34 deletions(-) diff --git a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java index 4417847b18d..615d0bde022 100644 --- a/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java +++ b/modules/control-utility/src/test/java/org/apache/ignite/util/GridCommandHandlerWalTest.java @@ -184,22 +184,78 @@ public class GridCommandHandlerWalTest extends GridCommandHandlerAbstractTest { srv.cluster().state(ClusterState.ACTIVE); srv.createCache(new CacheConfiguration<>("cache1") - .setGroupName("testGroup")); + .setGroupName("group1")); srv.createCache(new CacheConfiguration<>("cache2") - .setGroupName("testGroup")); + .setGroupName("group1")); + srv.createCache(new CacheConfiguration<>("cache3") + .setGroupName("group2")); + srv.createCache("cache4"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "group1,group2,cache4")); + outputContains(".*group1.*true.*true.*true.*true.*false"); + outputContains(".*group2.*true.*true.*true.*true.*false"); + outputContains(".*cache4.*true.*true.*true.*true.*false"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups", "group1")); + outputContains("Successfully disabled WAL for groups:"); + outputContains("group1"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "group1")); + outputContains(".*group1.*true.*false.*true.*true.*false"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups", "group1,group2")); + outputContains("Successfully disabled WAL for groups:"); + outputContains("group1"); + outputContains("group2"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "group1,group2")); + outputContains(".*group1.*true.*false.*true.*true.*false"); + outputContains(".*group2.*true.*false.*true.*true.*false"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups", "cache4,nonExistentGroup")); + outputContains("Successfully disabled WAL for groups:"); + outputContains("cache4"); + outputContains("Failed to disable WAL for groups:"); + outputContains("nonExistentGroup - Cache group not found"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "cache4")); + outputContains(".*cache4.*true.*false.*true.*true.*false"); + + // Error when using cache name instead of group name. + assertEquals(EXIT_CODE_OK, execute("--wal", "enable", "--groups", "cache3")); + outputContains("Failed to enable WAL for groups:"); + outputContains("cache3 - Cache group not found"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "enable", "--groups", "group2,cache4")); + outputContains("Successfully enabled WAL for groups:"); + outputContains("group2"); + outputContains("cache4"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "group2,cache4")); + outputContains(".*group2.*true.*true.*true.*true.*false"); + outputContains(".*cache4.*true.*true.*true.*true.*false"); + + assertEquals(EXIT_CODE_OK, execute("--wal", "disable")); + outputContains("Successfully disabled WAL for groups:"); + outputContains("group1"); + outputContains("group2"); + outputContains("cache4"); - assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "testGroup")); - outputContains(".*testGroup.*true.*true.*true.*true.*false"); - - assertEquals(EXIT_CODE_OK, execute("--wal", "disable", "--groups", "testGroup")); - - assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "testGroup")); - outputContains(".*testGroup.*true.*false.*true.*true.*false"); + assertEquals(EXIT_CODE_OK, execute("--wal", "state")); + outputContains(".*group1.*true.*false.*true.*true.*false"); + outputContains(".*group2.*true.*false.*true.*true.*false"); + outputContains(".*cache4.*true.*false.*true.*true.*false"); - assertEquals(EXIT_CODE_OK, execute("--wal", "enable", "--groups", "testGroup")); + assertEquals(EXIT_CODE_OK, execute("--wal", "enable")); + outputContains("Successfully enabled WAL for groups:"); + outputContains("group1"); + outputContains("group2"); + outputContains("cache4"); - assertEquals(EXIT_CODE_OK, execute("--wal", "state", "--groups", "testGroup")); - outputContains(".*testGroup.*true.*true.*true.*true.*false"); + assertEquals(EXIT_CODE_OK, execute("--wal", "state")); + outputContains(".*group1.*true.*true.*true.*true.*false"); + outputContains(".*group2.*true.*true.*true.*true.*false"); + outputContains(".*cache4.*true.*true.*true.*true.*false"); } /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java index 9802dc31864..3e3208d93bb 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalDisableCommand.java @@ -17,10 +17,11 @@ package org.apache.ignite.internal.management.wal; +import java.util.function.Consumer; import org.apache.ignite.internal.management.api.ComputeCommand; /** */ -public class WalDisableCommand implements ComputeCommand<WalDisableCommand.WalDisableCommandArg, Void> { +public class WalDisableCommand implements ComputeCommand<WalDisableCommand.WalDisableCommandArg, WalSetStateTaskResult> { /** {@inheritDoc} */ @Override public Class<WalSetStateTask> taskClass() { return WalSetStateTask.class; @@ -41,6 +42,11 @@ public class WalDisableCommand implements ComputeCommand<WalDisableCommand.WalDi return "Are you sure? Any node failure without WAL can lead to the loss of all PDS data. CDC events will be lost without WAL."; } + /** {@inheritDoc} */ + @Override public void printResult(WalDisableCommandArg arg, WalSetStateTaskResult res, Consumer<String> printer) { + res.print(false, printer); + } + /** */ public static class WalDisableCommandArg extends WalStateCommandArg { /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java index 950f416e54a..96f8284c72e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalEnableCommand.java @@ -17,11 +17,12 @@ package org.apache.ignite.internal.management.wal; +import java.util.function.Consumer; import org.apache.ignite.internal.management.api.ComputeCommand; import org.apache.ignite.internal.management.wal.WalDisableCommand.WalDisableCommandArg; /** */ -public class WalEnableCommand implements ComputeCommand<WalDisableCommandArg, Void> { +public class WalEnableCommand implements ComputeCommand<WalDisableCommandArg, WalSetStateTaskResult> { /** {@inheritDoc} */ @Override public Class<WalSetStateTask> taskClass() { return WalSetStateTask.class; @@ -37,6 +38,11 @@ public class WalEnableCommand implements ComputeCommand<WalDisableCommandArg, Vo return WalEnableCommandArg.class; } + /** {@inheritDoc} */ + @Override public void printResult(WalDisableCommandArg arg, WalSetStateTaskResult res, Consumer<String> printer) { + res.print(true, printer); + } + /** */ public static class WalEnableCommandArg extends WalDisableCommandArg { /** */ diff --git a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java index 017dd729bb5..af71cb07e78 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTask.java @@ -17,37 +17,34 @@ package org.apache.ignite.internal.management.wal; +import java.util.ArrayList; import java.util.Arrays; -import java.util.HashSet; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.apache.ignite.IgniteException; -import org.apache.ignite.compute.ComputeJobResult; import org.apache.ignite.internal.management.wal.WalDisableCommand.WalDisableCommandArg; import org.apache.ignite.internal.management.wal.WalEnableCommand.WalEnableCommandArg; import org.apache.ignite.internal.processors.cache.CacheGroupContext; import org.apache.ignite.internal.util.typedef.F; import org.apache.ignite.internal.visor.VisorJob; -import org.apache.ignite.internal.visor.VisorMultiNodeTask; +import org.apache.ignite.internal.visor.VisorOneNodeTask; import org.jetbrains.annotations.Nullable; /** */ -public class WalSetStateTask extends VisorMultiNodeTask<WalDisableCommandArg, Void, Void> { +public class WalSetStateTask extends VisorOneNodeTask<WalDisableCommandArg, WalSetStateTaskResult> { /** */ private static final long serialVersionUID = 0; /** {@inheritDoc} */ - @Override protected VisorJob<WalDisableCommandArg, Void> job(WalDisableCommandArg arg) { - return new WalDisableJob(arg, false); - } - - /** {@inheritDoc} */ - @Override protected @Nullable Void reduce0(List<ComputeJobResult> res) throws IgniteException { - return null; + @Override protected VisorJob<WalDisableCommandArg, WalSetStateTaskResult> job(WalDisableCommandArg arg) { + return new WalDisableJob(arg, debug); } /** */ - private static class WalDisableJob extends VisorJob<WalDisableCommandArg, Void> { + private static class WalDisableJob extends VisorJob<WalDisableCommandArg, WalSetStateTaskResult> { /** */ private static final long serialVersionUID = 0; @@ -57,22 +54,37 @@ public class WalSetStateTask extends VisorMultiNodeTask<WalDisableCommandArg, Vo } /** {@inheritDoc} */ - @Override protected Void run(@Nullable WalDisableCommandArg arg) throws IgniteException { - Set<String> grps = F.isEmpty(arg.groups()) ? null : new HashSet<>(Arrays.asList(arg.groups())); + @Override protected WalSetStateTaskResult run(@Nullable WalDisableCommandArg arg) throws IgniteException { + Set<String> grps = arg.groups == null ? null : Arrays.stream(arg.groups).collect(Collectors.toSet()); + + List<String> successGrps = new ArrayList<>(); + Map<String, String> failedGrps = new HashMap<>(); for (CacheGroupContext gctx : ignite.context().cache().cacheGroups()) { String grpName = gctx.cacheOrGroupName(); - if (grps != null && !grps.contains(grpName)) + if (grps != null && !grps.remove(grpName)) continue; - if (arg instanceof WalEnableCommandArg) - ignite.cluster().enableWal(grpName); - else - ignite.cluster().disableWal(grpName); + try { + if (arg instanceof WalEnableCommandArg) + ignite.cluster().enableWal(grpName); + else + ignite.cluster().disableWal(grpName); + + successGrps.add(grpName); + } + catch (IgniteException e) { + failedGrps.put(grpName, e.getMessage()); + } + } + + if (!F.isEmpty(grps)) { + for (String grp: grps) + failedGrps.put(grp, "Cache group not found"); } - return null; + return new WalSetStateTaskResult(successGrps, failedGrps); } } } diff --git a/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTaskResult.java b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTaskResult.java new file mode 100644 index 00000000000..53e0f8baad9 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/management/wal/WalSetStateTaskResult.java @@ -0,0 +1,81 @@ +/* + * 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.wal; + +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import org.apache.ignite.internal.Order; +import org.apache.ignite.internal.dto.IgniteDataTransferObject; +import org.apache.ignite.internal.util.typedef.F; + +/** + * Result of WAL enable/disable operation. + */ +public class WalSetStateTaskResult extends IgniteDataTransferObject { + /** */ + private static final long serialVersionUID = 0L; + + /** Successfully processed groups. */ + @Order(0) + List<String> successGrps; + + /** Errors by group name. */ + @Order(1) + Map<String, String> errorsByGrp; + + /** Default constructor. */ + public WalSetStateTaskResult() { + // No-op. + } + + /** + * Constructor. + * + * @param successGrps Successfully processed groups. + * @param errorsByGrp Error messages. + */ + public WalSetStateTaskResult(List<String> successGrps, Map<String, String> errorsByGrp) { + this.successGrps = successGrps; + this.errorsByGrp = errorsByGrp; + } + + /** + * Print WAL disable/enable command result. + * + * @param enable If {@code true} then "enable" operation, otherwise "disable". + * @param printer Output consumer. + */ + void print(boolean enable, Consumer<String> printer) { + String op = enable ? "enable" : "disable"; + + if (!successGrps.isEmpty()) { + printer.accept("Successfully " + op + "d WAL for groups:"); + + for (String grp : successGrps) + printer.accept(" " + grp); + } + + if (!F.isEmpty(errorsByGrp)) { + printer.accept("Failed to " + op + " WAL for groups:"); + + for (Map.Entry<String, String> entry : errorsByGrp.entrySet()) + printer.accept(" " + entry.getKey() + " - " + entry.getValue()); + } + } +}
