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 f197f51d7dd IGNITE-25753 enabledColocation validation on cluster init (#6118) f197f51d7dd is described below commit f197f51d7ddddfdf090b6afc9ce6b6b764335a62 Author: Alexander Lapin <lapin1...@gmail.com> AuthorDate: Tue Jul 15 15:04:05 2025 +0300 IGNITE-25753 enabledColocation validation on cluster init (#6118) --- .../cluster/management/ItClusterManagerTest.java | 48 ++++++++++++ .../cluster/management/ClusterInitializer.java | 73 ++++++++++-------- .../management/ClusterManagementGroupManager.java | 88 +++++++++++++++++++++- .../management/network/CmgMessageCallback.java | 6 ++ .../management/network/CmgMessageHandler.java | 3 + .../network/messages/CmgMessageGroup.java | 10 +++ .../network/messages/CmgPrepareInitMessage.java | 33 ++++++++ .../messages/PrepareInitCompleteMessage.java | 28 +++++++ .../cluster/management/ClusterInitializerTest.java | 75 +++++++++++++++++- .../internal/cluster/management/MockNode.java | 13 +++- .../rebalance/ItRebalanceDistributedTest.java | 3 +- .../ItMetaStorageMultipleNodesAbstractTest.java | 4 +- .../metastorage/impl/ItMetaStorageWatchTest.java | 4 +- .../partition/replicator/fixtures/Node.java | 4 +- .../ItDistributedConfigurationPropertiesTest.java | 4 +- .../ItDistributedConfigurationStorageTest.java | 4 +- .../runner/app/ItIgniteNodeRestartTest.java | 4 +- .../org/apache/ignite/internal/app/IgniteImpl.java | 6 +- 18 files changed, 363 insertions(+), 47 deletions(-) diff --git a/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/ItClusterManagerTest.java b/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/ItClusterManagerTest.java index 5bc44954b23..69e6931eecc 100644 --- a/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/ItClusterManagerTest.java +++ b/modules/cluster-management/src/integrationTest/java/org/apache/ignite/internal/cluster/management/ItClusterManagerTest.java @@ -17,6 +17,7 @@ package org.apache.ignite.internal.cluster.management; +import static org.apache.ignite.internal.lang.IgniteSystemProperties.COLOCATION_FEATURE_FLAG; import static org.apache.ignite.internal.testframework.IgniteTestUtils.assertThrowsWithCause; import static org.apache.ignite.internal.testframework.IgniteTestUtils.waitForCondition; import static org.apache.ignite.internal.testframework.matchers.CompletableFutureExceptionMatcher.willThrow; @@ -44,7 +45,10 @@ import org.apache.ignite.internal.util.IgniteUtils; import org.apache.ignite.network.ClusterNode; import org.jetbrains.annotations.Nullable; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Integration tests for {@link ClusterManagementGroupManager}. @@ -52,9 +56,22 @@ import org.junit.jupiter.api.Test; public class ItClusterManagerTest extends BaseItClusterManagementTest { private final List<MockNode> cluster = new ArrayList<>(); + private String commonColocationFeatureFlag; + + @BeforeEach + public void setUp() { + commonColocationFeatureFlag = System.getProperty(COLOCATION_FEATURE_FLAG); + } + @AfterEach void tearDown() throws Exception { stopCluster(); + + if (commonColocationFeatureFlag == null) { + System.clearProperty(COLOCATION_FEATURE_FLAG); + } else { + System.setProperty(COLOCATION_FEATURE_FLAG, commonColocationFeatureFlag); + } } private void startCluster(int numNodes) { @@ -63,6 +80,14 @@ public class ItClusterManagerTest extends BaseItClusterManagementTest { cluster.parallelStream().forEach(MockNode::startAndJoin); } + private void startNode(int idx, int clusterSize) { + MockNode node = createNode(idx, clusterSize); + + cluster.add(node); + + node.startAndJoin(); + } + private void stopCluster() throws Exception { stopNodes(cluster); @@ -204,6 +229,7 @@ public class ItClusterManagerTest extends BaseItClusterManagementTest { /** * Tests executing the init command with incorrect node names. */ + @SuppressWarnings("ThrowableNotThrown") @Test void testInitInvalidNodes() throws Exception { startCluster(2); @@ -534,4 +560,26 @@ public class ItClusterManagerTest extends BaseItClusterManagementTest { assertThat(node.startFuture(), willCompleteSuccessfully()); } } + + @SuppressWarnings("ThrowableNotThrown") + @ParameterizedTest + @ValueSource(booleans = {true, false}) + void testInitFailsOnDifferentEnabledColocationModesWithinCmgNodes(boolean colocationEnabled) { + System.setProperty(COLOCATION_FEATURE_FLAG, Boolean.toString(colocationEnabled)); + startNode(0, 2); + + System.setProperty(COLOCATION_FEATURE_FLAG, Boolean.toString(!colocationEnabled)); + startNode(1, 2); + + String[] cmgNodes = clusterNodeNames(); + + assertThrowsWithCause( + () -> initCluster(cmgNodes, cmgNodes), + InitException.class, + "Unable to initialize the cluster: org.apache.ignite.internal.cluster.management.InternalInitException: IGN-CMN-65535" + + " Got error response from node \"icmt_tifodecmwcn_10001\": Colocation modes do not match" + + " [initInitiatorNodeName=icmt_tifodecmwcn_10000, initInitiatorColocationMode=" + colocationEnabled + + ", recipientColocationMode=" + !colocationEnabled + "]." + ); + } } diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterInitializer.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterInitializer.java index 1af3d36b563..23a61bdc49a 100644 --- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterInitializer.java +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterInitializer.java @@ -37,8 +37,11 @@ import org.apache.ignite.configuration.validation.ValidationIssue; import org.apache.ignite.internal.cluster.management.network.messages.CancelInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory; +import org.apache.ignite.internal.cluster.management.network.messages.CmgPrepareInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.InitCompleteMessage; import org.apache.ignite.internal.cluster.management.network.messages.InitErrorMessage; +import org.apache.ignite.internal.cluster.management.network.messages.PrepareInitCompleteMessage; +import org.apache.ignite.internal.components.NodeProperties; import org.apache.ignite.internal.configuration.validation.ConfigurationDuplicatesValidator; import org.apache.ignite.internal.configuration.validation.ConfigurationValidator; import org.apache.ignite.internal.logger.IgniteLogger; @@ -66,15 +69,19 @@ public class ClusterInitializer { private final CmgMessagesFactory msgFactory = new CmgMessagesFactory(); + private final NodeProperties nodeProperties; + /** Constructor. */ public ClusterInitializer( ClusterService clusterService, ConfigurationDynamicDefaultsPatcher configurationDynamicDefaultsPatcher, - ConfigurationValidator clusterConfigurationValidator + ConfigurationValidator clusterConfigurationValidator, + NodeProperties nodeProperties ) { this.clusterService = clusterService; this.configurationDynamicDefaultsPatcher = configurationDynamicDefaultsPatcher; this.clusterConfigurationValidator = clusterConfigurationValidator; + this.nodeProperties = nodeProperties; } /** @@ -185,6 +192,10 @@ public class ClusterInitializer { validateConfiguration(patchedClusterConfiguration, clusterConfiguration); + CmgPrepareInitMessage prepareInitMessage = msgFactory.cmgPrepareInitMessage() + .initInitiatorColocationEnabled(nodeProperties.colocationEnabled()) + .build(); + CmgInitMessage initMessage = msgFactory.cmgInitMessage() .metaStorageNodes(msNodeNameSet) .cmgNodes(cmgNodeNameSet) @@ -193,34 +204,36 @@ public class ClusterInitializer { .initialClusterConfiguration(patchedClusterConfiguration) .build(); - return invokeMessage(cmgNodes, initMessage) - .handle((v, e) -> { - if (e == null) { - LOG.info( - "Cluster initialized [clusterName={}, cmgNodes={}, msNodes={}]", - initMessage.clusterName(), - initMessage.cmgNodes(), - initMessage.metaStorageNodes() - ); - - return CompletableFutures.<Void>nullCompletedFuture(); - } else { - if (e instanceof CompletionException) { - e = e.getCause(); - } - - LOG.info("Initialization failed [reason={}]", e, e.getMessage()); - - if (e instanceof InternalInitException && !((InternalInitException) e).shouldCancelInit()) { - return CompletableFuture.<Void>failedFuture(e); - } else { - LOG.debug("Critical error encountered, rolling back the init procedure"); - - return cancelInit(cmgNodes, e); - } - } - }) - .thenCompose(Function.identity()); + // Handler of prepareInitMessage validates that all CMG nodes have the same enabledColocation mode. + return invokeMessage(cmgNodes, prepareInitMessage) + .thenCompose(ignored -> invokeMessage(cmgNodes, initMessage) + .handle((v, e) -> { + if (e == null) { + LOG.info( + "Cluster initialized [clusterName={}, cmgNodes={}, msNodes={}]", + initMessage.clusterName(), + initMessage.cmgNodes(), + initMessage.metaStorageNodes() + ); + + return CompletableFutures.<Void>nullCompletedFuture(); + } else { + if (e instanceof CompletionException) { + e = e.getCause(); + } + + LOG.info("Initialization failed [reason={}]", e, e.getMessage()); + + if (e instanceof InternalInitException && !((InternalInitException) e).shouldCancelInit()) { + return CompletableFuture.<Void>failedFuture(e); + } else { + LOG.debug("Critical error encountered, rolling back the init procedure"); + + return cancelInit(cmgNodes, e); + } + } + }) + .thenCompose(Function.identity())); } catch (Exception e) { return failedFuture(e); } @@ -278,7 +291,7 @@ public class ClusterInitializer { String.format("Got error response from node \"%s\": %s", node.name(), errorResponse.cause()), errorResponse.shouldCancel() ); - } else if (!(response instanceof InitCompleteMessage)) { + } else if (!(response instanceof InitCompleteMessage || response instanceof PrepareInitCompleteMessage)) { throw new InternalInitException( String.format("Unexpected response from node \"%s\": %s", node.name(), response.getClass()), true diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java index d9cd9ba404b..6e6f3a917b3 100644 --- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java @@ -55,6 +55,7 @@ import org.apache.ignite.internal.cluster.management.network.messages.ClusterSta import org.apache.ignite.internal.cluster.management.network.messages.CmgInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgMessageGroup; import org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory; +import org.apache.ignite.internal.cluster.management.network.messages.CmgPrepareInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.InitErrorMessage; import org.apache.ignite.internal.cluster.management.network.messages.RefuseJoinMessage; import org.apache.ignite.internal.cluster.management.raft.ClusterStateStorage; @@ -68,6 +69,8 @@ import org.apache.ignite.internal.cluster.management.raft.commands.JoinReadyComm import org.apache.ignite.internal.cluster.management.topology.LogicalTopology; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.api.LogicalTopologySnapshot; +import org.apache.ignite.internal.components.NodeProperties; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.disaster.system.message.ResetClusterMessage; import org.apache.ignite.internal.disaster.system.storage.ClusterResetStorage; import org.apache.ignite.internal.event.AbstractEventProducer; @@ -75,6 +78,7 @@ import org.apache.ignite.internal.event.EventParameters; import org.apache.ignite.internal.failure.FailureContext; import org.apache.ignite.internal.failure.FailureProcessor; import org.apache.ignite.internal.lang.IgniteInternalException; +import org.apache.ignite.internal.lang.IgniteStringFormatter; import org.apache.ignite.internal.lang.NodeStoppingException; import org.apache.ignite.internal.logger.IgniteLogger; import org.apache.ignite.internal.logger.Loggers; @@ -178,6 +182,8 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster private final LocalTopologyMetricsSource localTopologyMetricsSource; + private final NodeProperties nodeProperties; + /** Constructor. */ public ClusterManagementGroupManager( VaultManager vault, @@ -192,7 +198,8 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster FailureProcessor failureProcessor, ClusterIdStore clusterIdStore, RaftGroupOptionsConfigurer raftGroupOptionsConfigurer, - MetricManager metricManager + MetricManager metricManager, + NodeProperties nodeProperties ) { this.clusterResetStorage = clusterResetStorage; this.clusterService = clusterService; @@ -226,6 +233,8 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster cmgMessageHandler = createMessageHandler(); clusterService.messagingService().addMessageHandler(CmgMessageGroup.class, message -> scheduledExecutor, cmgMessageHandler); + + this.nodeProperties = nodeProperties; } private CmgMessageHandler createMessageHandler() { @@ -253,6 +262,13 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster handleInit(message, sender, correlationId); } + + @Override + public void onCmgPrepareInitMessageReceived(CmgPrepareInitMessage message, ClusterNode sender, @Nullable Long correlationId) { + assert correlationId != null : sender; + + handlePrepareInit(message, sender, correlationId); + } }; return new CmgMessageHandler(busyLock, msgFactory, clusterService, failureProcessor, messageCallback); @@ -287,7 +303,43 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster failureProcessor, clusterIdStore, raftGroupOptionsConfigurer, - metricManager + metricManager, + new SystemPropertiesNodeProperties() + ); + } + + /** Constructor. */ + @TestOnly + public ClusterManagementGroupManager( + VaultManager vault, + ClusterResetStorage clusterResetStorage, + ClusterService clusterService, + ClusterInitializer clusterInitializer, + RaftManager raftManager, + ClusterStateStorage clusterStateStorage, + LogicalTopology logicalTopology, + NodeAttributes nodeAttributes, + FailureProcessor failureProcessor, + ClusterIdStore clusterIdStore, + RaftGroupOptionsConfigurer raftGroupOptionsConfigurer, + MetricManager metricManager, + NodeProperties nodeProperties + ) { + this( + vault, + clusterResetStorage, + clusterService, + clusterInitializer, + raftManager, + new ClusterStateStorageManager(clusterStateStorage), + logicalTopology, + new ValidationManager(new ClusterStateStorageManager(clusterStateStorage), logicalTopology), + nodeAttributes, + failureProcessor, + clusterIdStore, + raftGroupOptionsConfigurer, + metricManager, + nodeProperties ); } @@ -555,6 +607,31 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster } } + /** + * Handles the prepare init messages. + * + * <p>If both initiator node and recipient have the same colocation mode, a PrepareInitCompleteMessage is sent, + * otherwise an InitErrorMessage is sent. + */ + private void handlePrepareInit(CmgPrepareInitMessage msg, ClusterNode sender, long correlationId) { + NetworkMessage response; + if (nodeProperties.colocationEnabled() != msg.initInitiatorColocationEnabled()) { + String colocationEnabledMismatchResponseMessage = IgniteStringFormatter.format( + "Colocation modes do not match [initInitiatorNodeName={}, initInitiatorColocationMode={}, " + + "recipientColocationMode={}].", + sender.name(), + msg.initInitiatorColocationEnabled(), + nodeProperties.colocationEnabled() + ); + + response = preparePhaseInitErrorMessage(colocationEnabledMismatchResponseMessage); + } else { + response = msgFactory.prepareInitCompleteMessage().build(); + } + + clusterService.messagingService().respond(sender, response, correlationId); + } + private CompletableFuture<CmgRaftService> doInit(CmgRaftService service, CmgInitMessage msg, @Nullable List<UUID> formerClusterIds) { return service.initClusterState(createClusterState(msg, formerClusterIds)) .thenCompose(state -> { @@ -650,6 +727,13 @@ public class ClusterManagementGroupManager extends AbstractEventProducer<Cluster .build(); } + private InitErrorMessage preparePhaseInitErrorMessage(String responseMessage) { + return msgFactory.initErrorMessage() + .cause(responseMessage) + .shouldCancel(false) + .build(); + } + /** * This method must be executed upon CMG leader election in order to regain logical topology consistency in case some nodes left the * physical topology during the election. Newly appeared nodes will be added automatically after the new leader broadcasts the current diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageCallback.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageCallback.java index 55bf8fe2d37..fda2f539f28 100644 --- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageCallback.java +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageCallback.java @@ -20,6 +20,7 @@ package org.apache.ignite.internal.cluster.management.network; import org.apache.ignite.internal.cluster.management.network.messages.CancelInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.ClusterStateMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgInitMessage; +import org.apache.ignite.internal.cluster.management.network.messages.CmgPrepareInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.RefuseJoinMessage; import org.apache.ignite.network.ClusterNode; import org.jetbrains.annotations.Nullable; @@ -47,4 +48,9 @@ public interface CmgMessageCallback { * Notifies about an incoming {@link CmgInitMessage}. */ void onCmgInitMessageReceived(CmgInitMessage message, ClusterNode sender, @Nullable Long correlationId); + + /** + * Notifies about an incoming {@link CmgPrepareInitMessage}. + */ + void onCmgPrepareInitMessageReceived(CmgPrepareInitMessage message, ClusterNode sender, @Nullable Long correlationId); } diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageHandler.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageHandler.java index f1736b6311a..ee5a14af55b 100644 --- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageHandler.java +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/CmgMessageHandler.java @@ -23,6 +23,7 @@ import org.apache.ignite.internal.cluster.management.network.messages.CancelInit import org.apache.ignite.internal.cluster.management.network.messages.ClusterStateMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory; +import org.apache.ignite.internal.cluster.management.network.messages.CmgPrepareInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.RefuseJoinMessage; import org.apache.ignite.internal.failure.FailureContext; import org.apache.ignite.internal.failure.FailureProcessor; @@ -130,6 +131,8 @@ public class CmgMessageHandler implements NetworkMessageHandler { cmgMessageCallback.onRefuseJoinMessageReceived((RefuseJoinMessage) message, sender, correlationId); } else if (message instanceof CmgInitMessage) { cmgMessageCallback.onCmgInitMessageReceived((CmgInitMessage) message, sender, correlationId); + } else if (message instanceof CmgPrepareInitMessage) { + cmgMessageCallback.onCmgPrepareInitMessageReceived((CmgPrepareInitMessage) message, sender, correlationId); } } catch (Exception e) { failureProcessor.process(new FailureContext(e, "CMG message handling failed")); diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java index aa94f3ce43a..286f497417d 100644 --- a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgMessageGroup.java @@ -77,6 +77,16 @@ public class CmgMessageGroup { */ public static final short REFUSE_JOIN = 8; + /** + * Message type for {@link CmgPrepareInitMessage}. + */ + public static final short CMG_PREPARE_INIT = 9; + + /** + * Message type for {@link PrepareInitCompleteMessage}. + */ + public static final short PREPARE_INIT_COMPLETE = 10; + /** * Message types for RAFT commands. */ diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgPrepareInitMessage.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgPrepareInitMessage.java new file mode 100644 index 00000000000..8e5369d954b --- /dev/null +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/CmgPrepareInitMessage.java @@ -0,0 +1,33 @@ +/* + * 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.cluster.management.network.messages; + +import org.apache.ignite.internal.network.NetworkMessage; +import org.apache.ignite.internal.network.annotations.Transferable; + +/** + * Message for the Cluster Management Group initialization preparation. + */ +@Transferable(CmgMessageGroup.CMG_PREPARE_INIT) +public interface CmgPrepareInitMessage extends NetworkMessage { + /** + * Colocation enabled mode of the node that initiates the init procedure. All nodes in CMG group should have the same colocation enabled + * mode. + */ + boolean initInitiatorColocationEnabled(); +} diff --git a/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/PrepareInitCompleteMessage.java b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/PrepareInitCompleteMessage.java new file mode 100644 index 00000000000..5670a557fc8 --- /dev/null +++ b/modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/network/messages/PrepareInitCompleteMessage.java @@ -0,0 +1,28 @@ +/* + * 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.cluster.management.network.messages; + +import org.apache.ignite.internal.network.NetworkMessage; +import org.apache.ignite.internal.network.annotations.Transferable; + +/** + * Successful response for initializing a Raft group. + */ +@Transferable(CmgMessageGroup.PREPARE_INIT_COMPLETE) +public interface PrepareInitCompleteMessage extends NetworkMessage { +} diff --git a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/ClusterInitializerTest.java b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/ClusterInitializerTest.java index 383bb23ca35..5a39a259c7a 100644 --- a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/ClusterInitializerTest.java +++ b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/ClusterInitializerTest.java @@ -30,6 +30,7 @@ import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.assertArg; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -41,6 +42,8 @@ import java.util.stream.IntStream; import org.apache.ignite.internal.cluster.management.network.messages.CancelInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgInitMessage; import org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory; +import org.apache.ignite.internal.cluster.management.network.messages.CmgPrepareInitMessage; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.validation.TestConfigurationValidator; import org.apache.ignite.internal.network.ChannelType; import org.apache.ignite.internal.network.ClusterNodeImpl; @@ -85,7 +88,8 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); } @@ -101,6 +105,8 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { when(topologyService.getByConsistentId(cmgNode.name())).thenReturn(cmgNode); when(topologyService.allMembers()).thenReturn(List.of(metastorageNode, cmgNode)); + when(messagingService.invoke(any(ClusterNode.class), any(CmgPrepareInitMessage.class), anyLong())) + .thenReturn(prepareInitCompleteMessage()); when(messagingService.invoke(any(ClusterNode.class), any(CmgInitMessage.class), anyLong())) .thenReturn(initCompleteMessage()); @@ -111,6 +117,7 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { "cluster" ); + verify(messagingService).invoke(eq(cmgNode), any(CmgPrepareInitMessage.class), anyLong()); verify(messagingService).invoke(eq(cmgNode), any(CmgInitMessage.class), anyLong()); verify(messagingService, never()).invoke(eq(metastorageNode), any(CmgInitMessage.class), anyLong()); @@ -134,6 +141,9 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { } when(topologyService.allMembers()).thenReturn(allNodes); + when(messagingService.invoke(any(ClusterNode.class), any(CmgPrepareInitMessage.class), anyLong())) + .thenReturn(prepareInitCompleteMessage()); + when(messagingService.invoke(any(ClusterNode.class), any(CmgInitMessage.class), anyLong())) .thenReturn(initCompleteMessage()); @@ -157,9 +167,14 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { boolean shouldBeCmg = i <= 3 || (numNodes >= 5 && i <= 5); if (shouldBeCmg) { - verify(messagingService).invoke(eq(node), assertArg((CmgInitMessage msg) -> { - assertThat(msg.metaStorageNodes(), equalTo(cmgNodeNameSet)); - assertThat(msg.cmgNodes(), equalTo(cmgNodeNameSet)); + verify(messagingService).invoke(eq(node), any(CmgPrepareInitMessage.class), anyLong()); + verify(messagingService).invoke(eq(node), any(CmgInitMessage.class), anyLong()); + verify(messagingService, times(2)).invoke(eq(node), assertArg((NetworkMessage msg) -> { + if (msg instanceof CmgInitMessage) { + CmgInitMessage cmgInitMessage = (CmgInitMessage) msg; + assertThat(cmgInitMessage.metaStorageNodes(), equalTo(cmgNodeNameSet)); + assertThat(cmgInitMessage.cmgNodes(), equalTo(cmgNodeNameSet)); + } }), anyLong()); } else { verify(messagingService, never()).invoke(eq(node), any(CmgInitMessage.class), anyLong()); @@ -183,6 +198,8 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { when(topologyService.getByConsistentId(cmgNode.name())).thenReturn(cmgNode); when(topologyService.allMembers()).thenReturn(List.of(metastorageNode, cmgNode)); + when(messagingService.invoke(any(ClusterNode.class), any(CmgPrepareInitMessage.class), anyLong())) + .thenReturn(prepareInitCompleteMessage()); when(messagingService.invoke(any(ClusterNode.class), any(CmgInitMessage.class), anyLong())) .thenReturn(initCompleteMessage()); @@ -192,6 +209,7 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { "cluster" ); + verify(messagingService).invoke(eq(metastorageNode), any(CmgPrepareInitMessage.class), anyLong()); verify(messagingService).invoke(eq(metastorageNode), any(CmgInitMessage.class), anyLong()); verify(messagingService, never()).invoke(eq(cmgNode), any(CmgInitMessage.class), anyLong()); @@ -210,6 +228,8 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { when(topologyService.getByConsistentId(cmgNode.name())).thenReturn(cmgNode); when(topologyService.allMembers()).thenReturn(List.of(metastorageNode, cmgNode)); + when(messagingService.invoke(any(ClusterNode.class), any(CmgPrepareInitMessage.class), anyLong())) + .thenReturn(prepareInitCompleteMessage()); when(messagingService.invoke(eq(cmgNode), any(CmgInitMessage.class), anyLong())) .thenAnswer(invocation -> { NetworkMessage response = msgFactory.initErrorMessage().cause("foobar").shouldCancel(true).build(); @@ -229,6 +249,7 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { String errorMessageFragment = String.format("Got error response from node \"%s\": foobar", cmgNode.name()); assertThat(initFuture, willThrow(InternalInitException.class, errorMessageFragment)); + verify(messagingService).invoke(eq(cmgNode), any(CmgPrepareInitMessage.class), anyLong()); verify(messagingService).send(eq(cmgNode), any(CancelInitMessage.class)); verify(messagingService, never()).send(eq(metastorageNode), any(CancelInitMessage.class)); } @@ -245,6 +266,8 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { when(topologyService.getByConsistentId(cmgNode.name())).thenReturn(cmgNode); when(topologyService.allMembers()).thenReturn(List.of(metastorageNode, cmgNode)); + when(messagingService.invoke(any(ClusterNode.class), any(CmgPrepareInitMessage.class), anyLong())) + .thenReturn(prepareInitCompleteMessage()); when(messagingService.invoke(eq(cmgNode), any(CmgInitMessage.class), anyLong())) .thenAnswer(invocation -> { NetworkMessage response = msgFactory.initErrorMessage().cause("foobar").shouldCancel(false).build(); @@ -261,6 +284,7 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { String errorMessageFragment = String.format("Got error response from node \"%s\": foobar", cmgNode.name()); assertThat(initFuture, willThrow(InternalInitException.class, errorMessageFragment)); + verify(messagingService).invoke(eq(cmgNode), any(CmgPrepareInitMessage.class), anyLong()); verify(messagingService, never()).send(eq(cmgNode), any(CancelInitMessage.class)); verify(messagingService, never()).send(eq(metastorageNode), any(CancelInitMessage.class)); } @@ -271,6 +295,12 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { return CompletableFuture.completedFuture(msg); } + private CompletableFuture<NetworkMessage> prepareInitCompleteMessage() { + NetworkMessage msg = msgFactory.prepareInitCompleteMessage().build(); + + return CompletableFuture.completedFuture(msg); + } + /** * Tests that providing no nodes for the initialization throws an error. */ @@ -310,4 +340,41 @@ public class ClusterInitializerTest extends BaseIgniteAbstractTest { verify(messagingService, never()).invoke(any(String.class), any(NetworkMessage.class), anyLong()); verify(messagingService, never()).invoke(any(String.class), any(ChannelType.class), any(NetworkMessage.class), anyLong()); } + + /** + * Tests a situation when one of the nodes fail during initialization. + */ + @Test + void testInitOnHeterogeniusEnabledColocation() { + ClusterNode metastorageNode = new ClusterNodeImpl(randomUUID(), "metastore", new NetworkAddress("foo", 123)); + ClusterNode cmgNode = new ClusterNodeImpl(randomUUID(), "cmg", new NetworkAddress("bar", 456)); + + when(topologyService.getByConsistentId(metastorageNode.name())).thenReturn(metastorageNode); + when(topologyService.getByConsistentId(cmgNode.name())).thenReturn(cmgNode); + when(topologyService.allMembers()).thenReturn(List.of(metastorageNode, cmgNode)); + + when(messagingService.invoke(any(ClusterNode.class), any(CmgPrepareInitMessage.class), anyLong())) + .thenReturn(prepareInitCompleteMessage()); + when(messagingService.invoke(eq(cmgNode), any(CmgPrepareInitMessage.class), anyLong())) + .thenAnswer(invocation -> { + NetworkMessage response = msgFactory.initErrorMessage().cause("colocation modes do not match.").shouldCancel(false) + .build(); + + return CompletableFuture.completedFuture(response); + }); + + + CompletableFuture<Void> initFuture = clusterInitializer.initCluster( + List.of(metastorageNode.name()), + List.of(cmgNode.name()), + "cluster" + ); + + String errorMessageFragment = String.format("Got error response from node \"%s\": colocation modes do not match.", cmgNode.name()); + assertThat(initFuture, willThrow(InternalInitException.class, errorMessageFragment)); + + verify(messagingService, never()).invoke(eq(cmgNode), any(CmgInitMessage.class), anyLong()); + verify(messagingService, never()).send(eq(cmgNode), any(CancelInitMessage.class)); + verify(messagingService, never()).send(eq(metastorageNode), any(CancelInitMessage.class)); + } } diff --git a/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java b/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java index c5f0d0919af..38ab516d663 100644 --- a/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java +++ b/modules/cluster-management/src/testFixtures/java/org/apache/ignite/internal/cluster/management/MockNode.java @@ -42,6 +42,7 @@ import org.apache.ignite.internal.disaster.system.SystemDisasterRecoveryStorage; import org.apache.ignite.internal.failure.FailureManager; import org.apache.ignite.internal.failure.NoOpFailureManager; import org.apache.ignite.internal.hlc.HybridClockImpl; +import org.apache.ignite.internal.lang.IgniteSystemProperties; import org.apache.ignite.internal.manager.ComponentContext; import org.apache.ignite.internal.manager.IgniteComponent; import org.apache.ignite.internal.metrics.NoOpMetricManager; @@ -126,11 +127,18 @@ public class MockNode { RaftGroupOptionsConfigurer cmgRaftConfigurer = RaftGroupOptionsConfigHelper.configureProperties(cmgLogStorageFactory, this.workDir.resolve("cmg/meta")); + boolean colocationEnabled = IgniteSystemProperties.colocationEnabled(); + this.clusterManager = new ClusterManagementGroupManager( vaultManager, new SystemDisasterRecoveryStorage(vaultManager), clusterService, - new ClusterInitializer(clusterService, hocon -> hocon, new TestConfigurationValidator()), + new ClusterInitializer( + clusterService, + hocon -> hocon, + new TestConfigurationValidator(), + () -> colocationEnabled + ), raftManager, clusterStateStorage, new LogicalTopologyImpl(clusterStateStorage, failureManager), @@ -138,7 +146,8 @@ public class MockNode { failureManager, clusterIdHolder, cmgRaftConfigurer, - new NoOpMetricManager() + new NoOpMetricManager(), + () -> colocationEnabled ); components = List.of( diff --git a/modules/distribution-zones/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java b/modules/distribution-zones/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java index a06818c9273..2ceb1b26fb7 100644 --- a/modules/distribution-zones/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java +++ b/modules/distribution-zones/src/integrationTest/java/org/apache/ignite/internal/rebalance/ItRebalanceDistributedTest.java @@ -1346,7 +1346,8 @@ public class ItRebalanceDistributedTest extends BaseIgniteAbstractTest { var clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); ComponentWorkingDir cmgWorkDir = cmgPath(systemConfiguration, dir); diff --git a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java index 550894248e6..b3351960b70 100644 --- a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java +++ b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageMultipleNodesAbstractTest.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.cluster.management.raft.ClusterStateStorage; import org.apache.ignite.internal.cluster.management.raft.TestClusterStateStorage; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyServiceImpl; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.ComponentWorkingDir; import org.apache.ignite.internal.configuration.RaftGroupOptionsConfigHelper; import org.apache.ignite.internal.configuration.SystemDistributedConfiguration; @@ -171,7 +172,8 @@ abstract class ItMetaStorageMultipleNodesAbstractTest extends IgniteAbstractTest var clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); ComponentWorkingDir cmgWorkDir = new ComponentWorkingDir(basePath.resolve("cmg")); diff --git a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java index 41d6565a454..4047c63809c 100644 --- a/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java +++ b/modules/metastorage/src/integrationTest/java/org/apache/ignite/internal/metastorage/impl/ItMetaStorageWatchTest.java @@ -56,6 +56,7 @@ import org.apache.ignite.internal.cluster.management.configuration.NodeAttribute import org.apache.ignite.internal.cluster.management.raft.TestClusterStateStorage; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyServiceImpl; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.ComponentWorkingDir; import org.apache.ignite.internal.configuration.RaftGroupOptionsConfigHelper; import org.apache.ignite.internal.configuration.SystemDistributedConfiguration; @@ -177,7 +178,8 @@ public class ItMetaStorageWatchTest extends IgniteAbstractTest { var clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); components.add(failureManager); diff --git a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java index 45c81be29ef..d162150c090 100644 --- a/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java +++ b/modules/partition-replicator/src/integrationTest/java/org/apache/ignite/internal/partition/replicator/fixtures/Node.java @@ -69,6 +69,7 @@ import org.apache.ignite.internal.cluster.management.configuration.NodeAttribute import org.apache.ignite.internal.cluster.management.raft.TestClusterStateStorage; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyServiceImpl; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.ClusterConfiguration; import org.apache.ignite.internal.configuration.ComponentWorkingDir; import org.apache.ignite.internal.configuration.ConfigurationManager; @@ -416,7 +417,8 @@ public class Node { var clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); ComponentWorkingDir cmgWorkDir = new ComponentWorkingDir(dir.resolve("cmg")); diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java index 4c63e8d6426..d32cfe3f114 100644 --- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java +++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/ItDistributedConfigurationPropertiesTest.java @@ -48,6 +48,7 @@ import org.apache.ignite.internal.cluster.management.configuration.NodeAttribute import org.apache.ignite.internal.cluster.management.raft.TestClusterStateStorage; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyServiceImpl; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.storage.ConfigurationStorageListener; import org.apache.ignite.internal.configuration.storage.DistributedConfigurationStorage; import org.apache.ignite.internal.configuration.testframework.ConfigurationExtension; @@ -192,7 +193,8 @@ public class ItDistributedConfigurationPropertiesTest extends BaseIgniteAbstract var clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); ComponentWorkingDir cmgWorkDir = new ComponentWorkingDir(workDir.resolve("cmg")); diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java index 6b6989c4bf7..765daea938c 100644 --- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java +++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/configuration/storage/ItDistributedConfigurationStorageTest.java @@ -40,6 +40,7 @@ import org.apache.ignite.internal.cluster.management.configuration.NodeAttribute import org.apache.ignite.internal.cluster.management.raft.TestClusterStateStorage; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyServiceImpl; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.ComponentWorkingDir; import org.apache.ignite.internal.configuration.RaftGroupOptionsConfigHelper; import org.apache.ignite.internal.configuration.SystemDistributedConfiguration; @@ -166,7 +167,8 @@ public class ItDistributedConfigurationStorageTest extends BaseIgniteAbstractTes var clusterInitializer = new ClusterInitializer( clusterService, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); ComponentWorkingDir cmgWorkDir = new ComponentWorkingDir(workDir.resolve("cmg")); diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java index 26e675e1232..1df60705030 100644 --- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java +++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/ItIgniteNodeRestartTest.java @@ -108,6 +108,7 @@ import org.apache.ignite.internal.cluster.management.raft.RocksDbClusterStateSto import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyImpl; import org.apache.ignite.internal.cluster.management.topology.LogicalTopologyServiceImpl; import org.apache.ignite.internal.cluster.management.topology.api.LogicalNode; +import org.apache.ignite.internal.components.SystemPropertiesNodeProperties; import org.apache.ignite.internal.configuration.ComponentWorkingDir; import org.apache.ignite.internal.configuration.ConfigurationManager; import org.apache.ignite.internal.configuration.ConfigurationModules; @@ -437,7 +438,8 @@ public class ItIgniteNodeRestartTest extends BaseIgniteRestartTest { var clusterInitializer = new ClusterInitializer( clusterSvc, hocon -> hocon, - new TestConfigurationValidator() + new TestConfigurationValidator(), + new SystemPropertiesNodeProperties() ); ComponentWorkingDir cmgWorkDir = new ComponentWorkingDir(workDir.resolve("cmg")); diff --git a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java index aad2c730e9d..1bf76d2701a 100644 --- a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java +++ b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java @@ -712,7 +712,8 @@ public class IgniteImpl implements Ignite { clusterInitializer = new ClusterInitializer( clusterSvc, clusterCfgDynamicDefaultsPatcher, - distributedCfgValidator + distributedCfgValidator, + nodeProperties ); NodeAttributesCollector nodeAttributesCollector = @@ -740,7 +741,8 @@ public class IgniteImpl implements Ignite { failureManager, clusterIdService, cmgRaftConfigurer, - metricManager + metricManager, + nodeProperties ); logicalTopologyService = new LogicalTopologyServiceImpl(logicalTopology, cmgMgr);