@Override public void requestNodeConnect(final NodeIdentifier nodeId, final String userDn) { if (requireElection && !flowElection.isElectionComplete() && flowElection.isVoteCounted(nodeId)) { // If we receive a heartbeat from a node that we already know, we don't want to request that it reconnect // to the cluster because no flow has yet been elected. However, if the node has not yet voted, we want to send // a reconnect request because we want this node to cast its vote for the flow, and this happens on connection logger.debug("Received heartbeat for {} and node is not connected. Will not request node connect to cluster, " + "though, because the Flow Election is still in progress", nodeId); return; } if (userDn == null) { reportEvent(nodeId, Severity.INFO, "Requesting that node connect to cluster"); } else { reportEvent(nodeId, Severity.INFO, "Requesting that node connect to cluster on behalf of " + userDn); } updateNodeStatus(new NodeConnectionStatus(nodeId, NodeConnectionState.CONNECTING, null, null, null, System.currentTimeMillis())); // create the request final ReconnectionRequestMessage request = new ReconnectionRequestMessage(); request.setNodeId(nodeId); request.setInstanceId(instanceId); // If we still are requiring that an election take place, we do not want to include our local dataflow, because we don't // yet know what the cluster's dataflow looks like. However, if we don't require election, then we've connected to the // cluster, which means that our flow is correct. final boolean includeDataFlow = !requireElection; requestReconnectionAsynchronously(request, 10, 5, includeDataFlow); }
} catch (final InterruptedException ie) { logger.info("Could not send Reconnection request to {} because thread was " + "interrupted before FlowService was made available", request.getNodeId()); Thread.currentThread().interrupt(); return; if (NodeConnectionState.CONNECTING != getConnectionState(request.getNodeId())) { request.setDataFlow(new StandardDataFlow(flowService.createDataFlowFromController())); request.setNodeConnectionStatuses(getConnectionStatuses()); request.setComponentRevisions(revisionManager.getAllRevisions().stream().map(rev -> ComponentRevision.fromRevision(rev)).collect(Collectors.toList())); logger.info("Successfully requested that {} join the cluster", request.getNodeId()); logger.warn("Problem encountered issuing reconnection request to node " + request.getNodeId(), e); eventReporter.reportEvent(Severity.WARNING, EVENT_CATEGORY, "Problem encountered issuing reconnection request to node " + request.getNodeId() + " due to: " + e); if (NodeConnectionState.CONNECTING == getConnectionState(request.getNodeId())) { requestNodeDisconnect(request.getNodeId(), DisconnectionCode.UNABLE_TO_COMMUNICATE, "Attempted to request that node reconnect to cluster but could not communicate with node");
private void handleReconnectionRequest(final ReconnectionRequestMessage request) { try { logger.info("Processing reconnection request from cluster coordinator."); // reconnect ConnectionResponse connectionResponse = new ConnectionResponse(getNodeId(), request.getDataFlow(), request.getInstanceId(), request.getNodeConnectionStatuses(), request.getComponentRevisions()); if (connectionResponse.getDataFlow() == null) { logger.info("Received a Reconnection Request that contained no DataFlow. Will attempt to connect to cluster using local flow."); connectionResponse = connect(false, false, createDataFlowFromController()); } loadFromConnectionResponse(connectionResponse); clusterCoordinator.resetNodeStatuses(connectionResponse.getNodeConnectionStatuses().stream() .collect(Collectors.toMap(NodeConnectionStatus::getNodeIdentifier, status -> status))); // reconnected, this node needs to explicitly write the inherited flow to disk, and resume heartbeats saveFlowChanges(); controller.resumeHeartbeats(); logger.info("Node reconnected."); } catch (final Exception ex) { // disconnect controller if (controller.isClustered()) { disconnect("Failed to properly handle Reconnection request due to " + ex.toString()); } logger.error("Handling reconnection request failed due to: " + ex, ex); handleConnectionFailure(ex); } }
}, "Reconnect " + request.getNodeId());
public ReconnectionRequestMessage createReconnectionRequestMessage() { return new ReconnectionRequestMessage(); }
private NodeIdentifier getNodeIdentifier(final ProtocolMessage message) { if (message == null) { return null; } switch (message.getType()) { case CONNECTION_REQUEST: return ((ConnectionRequestMessage) message).getConnectionRequest().getProposedNodeIdentifier(); case HEARTBEAT: return ((HeartbeatMessage) message).getHeartbeat().getNodeIdentifier(); case OFFLOAD_REQUEST: return ((OffloadMessage) message).getNodeId(); case DISCONNECTION_REQUEST: return ((DisconnectMessage) message).getNodeId(); case FLOW_REQUEST: return ((FlowRequestMessage) message).getNodeId(); case RECONNECTION_REQUEST: return ((ReconnectionRequestMessage) message).getNodeId(); default: return null; } }
public ReconnectionRequestMessage createReconnectionRequestMessage() { return new ReconnectionRequestMessage(); }
private NodeIdentifier getNodeIdentifier(final ProtocolMessage message) { if (message == null) { return null; } switch (message.getType()) { case CONNECTION_REQUEST: return ((ConnectionRequestMessage) message).getConnectionRequest().getProposedNodeIdentifier(); case HEARTBEAT: return ((HeartbeatMessage) message).getHeartbeat().getNodeIdentifier(); case OFFLOAD_REQUEST: return ((OffloadMessage) message).getNodeId(); case DISCONNECTION_REQUEST: return ((DisconnectMessage) message).getNodeId(); case FLOW_REQUEST: return ((FlowRequestMessage) message).getNodeId(); case RECONNECTION_REQUEST: return ((ReconnectionRequestMessage) message).getNodeId(); default: return null; } }