Search in sources :

Example 11 with NodeIdentifier

use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.

the class NodeClusterCoordinator method getElectedActiveCoordinatorNode.

private NodeIdentifier getElectedActiveCoordinatorNode(final boolean warnOnError) {
    final String electedNodeAddress;
    try {
        electedNodeAddress = getElectedActiveCoordinatorAddress();
    } catch (final NoClusterCoordinatorException ncce) {
        logger.debug("There is currently no elected active Cluster Coordinator");
        return null;
    } catch (final IOException ioe) {
        if (warnOnError) {
            logger.warn("Failed to determine which node is elected active Cluster Coordinator. There may be no coordinator currently: " + ioe);
            if (logger.isDebugEnabled()) {
                logger.warn("", ioe);
            }
        }
        return null;
    }
    if (electedNodeAddress == null) {
        logger.debug("There is currently no elected active Cluster Coordinator");
        return null;
    }
    final int colonLoc = electedNodeAddress.indexOf(':');
    if (colonLoc < 1) {
        if (warnOnError) {
            logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but this is not a valid address", electedNodeAddress);
        }
        return null;
    }
    final String electedNodeHostname = electedNodeAddress.substring(0, colonLoc);
    final String portString = electedNodeAddress.substring(colonLoc + 1);
    final int electedNodePort;
    try {
        electedNodePort = Integer.parseInt(portString);
    } catch (final NumberFormatException nfe) {
        if (warnOnError) {
            logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but this is not a valid address", electedNodeAddress);
        }
        return null;
    }
    final Set<NodeIdentifier> connectedNodeIds = getNodeIdentifiers();
    final NodeIdentifier electedNodeId = connectedNodeIds.stream().filter(nodeId -> nodeId.getSocketAddress().equals(electedNodeHostname) && nodeId.getSocketPort() == electedNodePort).findFirst().orElse(null);
    if (electedNodeId == null && warnOnError) {
        logger.debug("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}," + "but there is no node with this address. Will attempt to communicate with node to determine its information", electedNodeAddress);
        try {
            final NodeConnectionStatus connectionStatus = senderListener.requestNodeConnectionStatus(electedNodeHostname, electedNodePort);
            logger.debug("Received NodeConnectionStatus {}", connectionStatus);
            if (connectionStatus == null) {
                return null;
            }
            final NodeConnectionStatus existingStatus = this.nodeStatuses.putIfAbsent(connectionStatus.getNodeIdentifier(), connectionStatus);
            if (existingStatus == null) {
                return connectionStatus.getNodeIdentifier();
            } else {
                return existingStatus.getNodeIdentifier();
            }
        } catch (final Exception e) {
            logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but there is no node with this address. " + "Attempted to determine the node's information but failed to retrieve its information due to {}", electedNodeAddress, e.toString());
            if (logger.isDebugEnabled()) {
                logger.warn("", e);
            }
        }
    }
    return electedNodeId;
}
Also used : NoClusterCoordinatorException(org.apache.nifi.cluster.exception.NoClusterCoordinatorException) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) IOException(java.io.IOException) IllegalNodeDisconnectionException(org.apache.nifi.cluster.manager.exception.IllegalNodeDisconnectionException) NoClusterCoordinatorException(org.apache.nifi.cluster.exception.NoClusterCoordinatorException) IOException(java.io.IOException) ProtocolException(org.apache.nifi.cluster.protocol.ProtocolException)

Example 12 with NodeIdentifier

use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.

the class NodeClusterCoordinator method resetNodeStatuses.

@Override
public void resetNodeStatuses(final Map<NodeIdentifier, NodeConnectionStatus> statusMap) {
    logger.info("Resetting cluster node statuses from {} to {}", nodeStatuses, statusMap);
    // has a larger update id than the current value.
    for (final Map.Entry<NodeIdentifier, NodeConnectionStatus> entry : statusMap.entrySet()) {
        final NodeIdentifier nodeId = entry.getKey();
        final NodeConnectionStatus proposedStatus = entry.getValue();
        if (proposedStatus.getState() == NodeConnectionState.REMOVED) {
            nodeStatuses.remove(nodeId);
        } else {
            nodeStatuses.put(nodeId, proposedStatus);
        }
    }
}
Also used : NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 13 with NodeIdentifier

use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.

the class NodeClusterCoordinator method updateNodeStatus.

void updateNodeStatus(final NodeConnectionStatus status, final boolean waitForCoordinator) {
    final NodeIdentifier nodeId = status.getNodeIdentifier();
    // In this case, we are using nodeStatuses.put() instead of getting the current value and
    // comparing that to the new value and using the one with the largest update id. This is because
    // this method is called when something occurs that causes this node to change the status of the
    // node in question. We only use comparisons against the current value when we receive an update
    // about a node status from a different node, since those may be received out-of-order.
    final NodeConnectionStatus currentStatus = nodeStatuses.put(nodeId, status);
    final NodeConnectionState currentState = currentStatus == null ? null : currentStatus.getState();
    logger.info("Status of {} changed from {} to {}", nodeId, currentStatus, status);
    logger.debug("State of cluster nodes is now {}", nodeStatuses);
    latestUpdateId.updateAndGet(curVal -> Math.max(curVal, status.getUpdateIdentifier()));
    if (currentState == null || currentState != status.getState()) {
        final boolean notifyAllNodes = isActiveClusterCoordinator();
        if (notifyAllNodes) {
            logger.debug("Notifying all nodes that status changed from {} to {}", currentStatus, status);
        } else {
            logger.debug("Notifying cluster coordinator that node status changed from {} to {}", currentStatus, status);
        }
        notifyOthersOfNodeStatusChange(status, notifyAllNodes, waitForCoordinator);
    } else {
        logger.debug("Not notifying other nodes that status changed because previous state of {} is same as new state of {}", currentState, status.getState());
    }
}
Also used : NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier)

Example 14 with NodeIdentifier

use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.

the class NodeClusterCoordinator method resolveNodeId.

private NodeIdentifier resolveNodeId(final NodeIdentifier proposedIdentifier) {
    final NodeConnectionStatus proposedConnectionStatus = new NodeConnectionStatus(proposedIdentifier, DisconnectionCode.NOT_YET_CONNECTED);
    final NodeConnectionStatus existingStatus = nodeStatuses.putIfAbsent(proposedIdentifier, proposedConnectionStatus);
    NodeIdentifier resolvedNodeId = proposedIdentifier;
    if (existingStatus == null) {
        // there is no node with that ID
        resolvedNodeId = proposedIdentifier;
        logger.debug("No existing node with ID {}; resolved node ID is as-proposed", proposedIdentifier.getId());
    } else if (existingStatus.getNodeIdentifier().logicallyEquals(proposedIdentifier)) {
        // there is a node with that ID but it's the same node.
        resolvedNodeId = proposedIdentifier;
        logger.debug("No existing node with ID {}; resolved node ID is as-proposed", proposedIdentifier.getId());
    } else {
        // there is a node with that ID and it's a different node
        resolvedNodeId = new NodeIdentifier(UUID.randomUUID().toString(), proposedIdentifier.getApiAddress(), proposedIdentifier.getApiPort(), proposedIdentifier.getSocketAddress(), proposedIdentifier.getSocketPort(), proposedIdentifier.getSiteToSiteAddress(), proposedIdentifier.getSiteToSitePort(), proposedIdentifier.getSiteToSiteHttpApiPort(), proposedIdentifier.isSiteToSiteSecure());
        logger.debug("A node already exists with ID {}. Proposed Node Identifier was {}; existing Node Identifier is {}; Resolved Node Identifier is {}", proposedIdentifier.getId(), proposedIdentifier, getNodeIdentifier(proposedIdentifier.getId()), resolvedNodeId);
    }
    return resolvedNodeId;
}
Also used : NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier)

Example 15 with NodeIdentifier

use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.

the class NodeClusterCoordinator method handleConnectionRequest.

private ConnectionResponseMessage handleConnectionRequest(final ConnectionRequestMessage requestMessage) {
    final NodeIdentifier proposedIdentifier = requestMessage.getConnectionRequest().getProposedNodeIdentifier();
    final NodeIdentifier withRequestorDn = addRequestorDn(proposedIdentifier, requestMessage.getRequestorDN());
    final DataFlow dataFlow = requestMessage.getConnectionRequest().getDataFlow();
    final ConnectionRequest requestWithDn = new ConnectionRequest(withRequestorDn, dataFlow);
    // Resolve Node identifier.
    final NodeIdentifier resolvedNodeId = resolveNodeId(proposedIdentifier);
    if (requireElection) {
        final DataFlow electedDataFlow = flowElection.castVote(dataFlow, withRequestorDn);
        if (electedDataFlow == null) {
            logger.info("Received Connection Request from {}; responding with Flow Election In Progress message", withRequestorDn);
            return createFlowElectionInProgressResponse();
        } else {
            logger.info("Received Connection Request from {}; responding with DataFlow that was elected", withRequestorDn);
            return createConnectionResponse(requestWithDn, resolvedNodeId, electedDataFlow);
        }
    }
    logger.info("Received Connection Request from {}; responding with my DataFlow", withRequestorDn);
    return createConnectionResponse(requestWithDn, resolvedNodeId);
}
Also used : ConnectionRequest(org.apache.nifi.cluster.protocol.ConnectionRequest) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) StandardDataFlow(org.apache.nifi.cluster.protocol.StandardDataFlow) DataFlow(org.apache.nifi.cluster.protocol.DataFlow)

Aggregations

NodeIdentifier (org.apache.nifi.cluster.protocol.NodeIdentifier)141 HashMap (java.util.HashMap)72 Map (java.util.Map)71 NodeResponse (org.apache.nifi.cluster.manager.NodeResponse)42 Test (org.junit.Test)34 Set (java.util.Set)30 URI (java.net.URI)26 HashSet (java.util.HashSet)26 ArrayList (java.util.ArrayList)24 List (java.util.List)18 ClusterCoordinator (org.apache.nifi.cluster.coordination.ClusterCoordinator)15 ProcessorEntity (org.apache.nifi.web.api.entity.ProcessorEntity)15 NodeConnectionStatus (org.apache.nifi.cluster.coordination.node.NodeConnectionStatus)14 NiFiProperties (org.apache.nifi.util.NiFiProperties)11 Collections (java.util.Collections)10 Pattern (java.util.regex.Pattern)10 NiFiUserDetails (org.apache.nifi.authorization.user.NiFiUserDetails)10 NiFiAuthenticationToken (org.apache.nifi.web.security.token.NiFiAuthenticationToken)10 Authentication (org.springframework.security.core.Authentication)10 Response (javax.ws.rs.core.Response)9