rpuch commented on code in PR #795:
URL: https://github.com/apache/ignite-3/pull/795#discussion_r879554000


##########
modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java:
##########
@@ -214,27 +234,61 @@ private CompletableFuture<CmgRaftService> 
recoverLocalState() {
             throw new IgniteInternalException("Error while retrieving local 
CMG state", e);
         }
 
-        if (cmgNodes.isEmpty()) {
+        if (localState == null) {
             return null;
         }
 
         log.info("Local CMG state recovered, starting the CMG");
 
-        return startCmgRaftService(cmgNodes)
+        return startCmgRaftService(localState.cmgNodeNames())
                 .thenCompose(service -> service.isCurrentNodeLeader()
                         .thenCompose(isLeader -> {
-                            if (isLeader) {
-                                return service.readClusterState()
-                                        // Raft state might not have been 
initialized in case of leader failure during cluster init
-                                        // TODO: properly handle this case, 
see https://issues.apache.org/jira/browse/IGNITE-16819
-                                        .thenCompose(state -> state == null ? 
completedFuture(null) : onLeaderElected(service, state));
-                            } else {
+                            if (!isLeader) {
                                 return completedFuture(null);
                             }
+
+                            return service.readClusterState()
+                                    .thenCompose(state -> {
+                                        if (state == null) {
+                                            // Raft state might not have been 
initialized in case of leader failure during cluster init
+                                            // TODO: properly handle this 
case, see https://issues.apache.org/jira/browse/IGNITE-16819
+
+                                            return completedFuture(null);
+                                        } else {
+                                            // CMG leader must validate itself 
on start
+                                            validateSelf(state, localState);
+
+                                            return onLeaderElected(service, 
state);
+                                        }
+                                    });
                         })
                         .thenApply(v -> service));
     }
 
+    /**
+     * Validates this node against the CMG state.
+     *
+     * @param state CMG state.
+     * @param localState Local node state.
+     * @throws IgniteInternalException If the node does not pass the 
validation.
+     */
+    private static void validateSelf(ClusterState state, LocalState 
localState) {
+        if (!state.cmgNodes().equals(localState.cmgNodeNames())) {
+            throw new IgniteInternalException(String.format(
+                    "Local state and CMG state differs. CMG nodes: %s, nodes 
stored in CMG: %s",
+                    localState.cmgNodeNames(), state.cmgNodes()
+            ));
+        }
+
+        var validationInfo = new 
ValidationInfo(IgniteProductVersion.CURRENT_VERSION, localState.clusterTag());
+
+        ValidationError validationError = NodeValidator.validateNode(state, 
validationInfo);
+
+        if (validationError != null) {
+            throw new IgniteInternalException(validationError.rejectReason());

Review Comment:
   It could make diagnostics a bit easier by adding some context: not just 'why 
it failed', but 'what failed'.



##########
modules/cluster-management/src/main/java/org/apache/ignite/internal/cluster/management/ClusterManagementGroupManager.java:
##########
@@ -214,27 +234,61 @@ private CompletableFuture<CmgRaftService> 
recoverLocalState() {
             throw new IgniteInternalException("Error while retrieving local 
CMG state", e);
         }
 
-        if (cmgNodes.isEmpty()) {
+        if (localState == null) {
             return null;
         }
 
         log.info("Local CMG state recovered, starting the CMG");
 
-        return startCmgRaftService(cmgNodes)
+        return startCmgRaftService(localState.cmgNodeNames())
                 .thenCompose(service -> service.isCurrentNodeLeader()
                         .thenCompose(isLeader -> {
-                            if (isLeader) {
-                                return service.readClusterState()
-                                        // Raft state might not have been 
initialized in case of leader failure during cluster init
-                                        // TODO: properly handle this case, 
see https://issues.apache.org/jira/browse/IGNITE-16819
-                                        .thenCompose(state -> state == null ? 
completedFuture(null) : onLeaderElected(service, state));
-                            } else {
+                            if (!isLeader) {
                                 return completedFuture(null);
                             }
+
+                            return service.readClusterState()
+                                    .thenCompose(state -> {
+                                        if (state == null) {
+                                            // Raft state might not have been 
initialized in case of leader failure during cluster init
+                                            // TODO: properly handle this 
case, see https://issues.apache.org/jira/browse/IGNITE-16819
+
+                                            return completedFuture(null);
+                                        } else {
+                                            // CMG leader must validate itself 
on start
+                                            validateSelf(state, localState);
+
+                                            return onLeaderElected(service, 
state);
+                                        }
+                                    });
                         })
                         .thenApply(v -> service));
     }
 
+    /**
+     * Validates this node against the CMG state.
+     *
+     * @param state CMG state.
+     * @param localState Local node state.
+     * @throws IgniteInternalException If the node does not pass the 
validation.
+     */
+    private static void validateSelf(ClusterState state, LocalState 
localState) {
+        if (!state.cmgNodes().equals(localState.cmgNodeNames())) {
+            throw new IgniteInternalException(String.format(
+                    "Local state and CMG state differs. CMG nodes: %s, nodes 
stored in CMG: %s",
+                    localState.cmgNodeNames(), state.cmgNodes()
+            ));
+        }
+
+        var validationInfo = new 
ValidationInfo(IgniteProductVersion.CURRENT_VERSION, localState.clusterTag());
+
+        ValidationError validationError = NodeValidator.validateNode(state, 
validationInfo);
+
+        if (validationError != null) {
+            throw new IgniteInternalException(validationError.rejectReason());

Review Comment:
   It could make diagnostics a bit easier by adding some context: not just 'why 
it failed', but also 'what failed'.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to