Search in sources :

Example 1 with ConnectionRequest

use of org.apache.nifi.cluster.protocol.ConnectionRequest 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)

Example 2 with ConnectionRequest

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

the class TestNodeClusterCoordinator method requestConnection.

private ProtocolMessage requestConnection(final NodeIdentifier requestedNodeId, final NodeClusterCoordinator coordinator) {
    final ConnectionRequest request = new ConnectionRequest(requestedNodeId, new StandardDataFlow(new byte[0], new byte[0], new byte[0], new HashSet<>()));
    final ConnectionRequestMessage requestMsg = new ConnectionRequestMessage();
    requestMsg.setConnectionRequest(request);
    return coordinator.handle(requestMsg);
}
Also used : ConnectionRequest(org.apache.nifi.cluster.protocol.ConnectionRequest) StandardDataFlow(org.apache.nifi.cluster.protocol.StandardDataFlow) ConnectionRequestMessage(org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage) HashSet(java.util.HashSet)

Example 3 with ConnectionRequest

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

the class TestNodeClusterCoordinator method testTryAgainIfNoFlowServiceSet.

@Test
public void testTryAgainIfNoFlowServiceSet() {
    final ClusterCoordinationProtocolSenderListener senderListener = Mockito.mock(ClusterCoordinationProtocolSenderListener.class);
    final EventReporter eventReporter = Mockito.mock(EventReporter.class);
    final RevisionManager revisionManager = Mockito.mock(RevisionManager.class);
    Mockito.when(revisionManager.getAllRevisions()).thenReturn(Collections.emptyList());
    final NodeClusterCoordinator coordinator = new NodeClusterCoordinator(senderListener, eventReporter, null, new FirstVoteWinsFlowElection(), null, revisionManager, createProperties(), null) {

        @Override
        void notifyOthersOfNodeStatusChange(NodeConnectionStatus updatedStatus, boolean notifyAllNodes, boolean waitForCoordinator) {
        }
    };
    final NodeIdentifier requestedNodeId = createNodeId(6);
    final ConnectionRequest request = new ConnectionRequest(requestedNodeId, new StandardDataFlow(new byte[0], new byte[0], new byte[0], new HashSet<>()));
    final ConnectionRequestMessage requestMsg = new ConnectionRequestMessage();
    requestMsg.setConnectionRequest(request);
    coordinator.setConnected(true);
    final ProtocolMessage protocolResponse = coordinator.handle(requestMsg);
    assertNotNull(protocolResponse);
    assertTrue(protocolResponse instanceof ConnectionResponseMessage);
    final ConnectionResponse response = ((ConnectionResponseMessage) protocolResponse).getConnectionResponse();
    assertNotNull(response);
    assertEquals(5, response.getTryLaterSeconds());
}
Also used : ConnectionRequestMessage(org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage) RevisionManager(org.apache.nifi.web.revision.RevisionManager) ConnectionResponse(org.apache.nifi.cluster.protocol.ConnectionResponse) ProtocolMessage(org.apache.nifi.cluster.protocol.message.ProtocolMessage) ConnectionRequest(org.apache.nifi.cluster.protocol.ConnectionRequest) StandardDataFlow(org.apache.nifi.cluster.protocol.StandardDataFlow) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) ConnectionResponseMessage(org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage) ClusterCoordinationProtocolSenderListener(org.apache.nifi.cluster.protocol.impl.ClusterCoordinationProtocolSenderListener) EventReporter(org.apache.nifi.events.EventReporter) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 4 with ConnectionRequest

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

the class StandardFlowService method connect.

private ConnectionResponse connect(final boolean retryOnCommsFailure, final boolean retryIndefinitely, final DataFlow dataFlow) throws ConnectionException {
    readLock.lock();
    try {
        logger.info("Connecting Node: " + nodeId);
        // create connection request message
        final ConnectionRequest request = new ConnectionRequest(nodeId, dataFlow);
        final ConnectionRequestMessage requestMsg = new ConnectionRequestMessage();
        requestMsg.setConnectionRequest(request);
        // send connection request to cluster manager
        /*
             * Try to get a current copy of the cluster's dataflow from the manager
             * for ten times, sleeping between attempts. Ten times should be
             * enough because the manager will register the node as connecting
             * and therefore, no other changes to the cluster flow can occur.
             *
             * However, the manager needs to obtain a current data flow within
             * maxAttempts * tryLaterSeconds or else the node will fail to startup.
             */
        final int maxAttempts = 10;
        ConnectionResponse response = null;
        for (int i = 0; i < maxAttempts || retryIndefinitely; i++) {
            try {
                response = senderListener.requestConnection(requestMsg).getConnectionResponse();
                if (response.shouldTryLater()) {
                    logger.info("Requested by cluster coordinator to retry connection in " + response.getTryLaterSeconds() + " seconds with explanation: " + response.getRejectionReason());
                    try {
                        Thread.sleep(response.getTryLaterSeconds() * 1000);
                    } catch (final InterruptedException ie) {
                        // we were interrupted, so finish quickly
                        Thread.currentThread().interrupt();
                        break;
                    }
                } else if (response.getRejectionReason() != null) {
                    logger.warn("Connection request was blocked by cluster coordinator with the explanation: " + response.getRejectionReason());
                    // set response to null and treat a firewall blockage the same as getting no response from manager
                    response = null;
                    break;
                } else {
                    // we received a successful connection response from manager
                    break;
                }
            } catch (final NoClusterCoordinatorException ncce) {
                logger.warn("There is currently no Cluster Coordinator. This often happens upon restart of NiFi when running an embedded ZooKeeper. Will register this node " + "to become the active Cluster Coordinator and will attempt to connect to cluster again");
                controller.registerForClusterCoordinator(true);
                try {
                    Thread.sleep(1000L);
                } catch (final InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    break;
                }
            } catch (final Exception pe) {
                // could not create a socket and communicate with manager
                logger.warn("Failed to connect to cluster due to: " + pe);
                if (logger.isDebugEnabled()) {
                    logger.warn("", pe);
                }
                if (retryOnCommsFailure) {
                    try {
                        Thread.sleep(response == null ? 5000 : response.getTryLaterSeconds());
                    } catch (final InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                } else {
                    break;
                }
            }
        }
        if (response == null) {
            // if response is null, then either we had IO problems or we were blocked by firewall or we couldn't determine manager's address
            return response;
        } else if (response.shouldTryLater()) {
            // if response indicates we should try later, then coordinator was unable to service our request. Just load local flow and move on.
            // when the cluster coordinator is able to service requests, this node's heartbeat will trigger the cluster coordinator to reach
            // out to this node and re-connect to the cluster.
            logger.info("Received a 'try again' response from Cluster Coordinator when attempting to connect to cluster with explanation '" + response.getRejectionReason() + "'. However, the maximum number of retries have already completed. Will load local flow and connect to the cluster when able.");
            return null;
        } else {
            // persist node uuid and index returned by NCM and return the response to the caller
            try {
                // Ensure that we have registered our 'cluster node configuration' state key
                final Map<String, String> map = Collections.singletonMap(NODE_UUID, response.getNodeIdentifier().getId());
                controller.getStateManagerProvider().getStateManager(CLUSTER_NODE_CONFIG).setState(map, Scope.LOCAL);
            } catch (final IOException ioe) {
                logger.warn("Received successful response from Cluster Manager but failed to persist state about the Node's Unique Identifier and the Node's Index. " + "This node may be assigned a different UUID when the node is restarted.", ioe);
            }
            return response;
        }
    } finally {
        readLock.unlock();
    }
}
Also used : ConnectionRequest(org.apache.nifi.cluster.protocol.ConnectionRequest) NoClusterCoordinatorException(org.apache.nifi.cluster.exception.NoClusterCoordinatorException) ConnectionRequestMessage(org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage) IOException(java.io.IOException) ConnectionResponse(org.apache.nifi.cluster.protocol.ConnectionResponse) Map(java.util.Map) FlowSerializationException(org.apache.nifi.controller.serialization.FlowSerializationException) ConnectionException(org.apache.nifi.cluster.ConnectionException) FlowSynchronizationException(org.apache.nifi.controller.serialization.FlowSynchronizationException) LifeCycleStartException(org.apache.nifi.lifecycle.LifeCycleStartException) NoClusterCoordinatorException(org.apache.nifi.cluster.exception.NoClusterCoordinatorException) IOException(java.io.IOException) ProtocolException(org.apache.nifi.cluster.protocol.ProtocolException)

Example 5 with ConnectionRequest

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

the class TestNodeClusterCoordinator method testProposedIdentifierResolvedIfConflict.

@Test
public void testProposedIdentifierResolvedIfConflict() {
    final NodeIdentifier id1 = new NodeIdentifier("1234", "localhost", 8000, "localhost", 9000, "localhost", 10000, 11000, false);
    final NodeIdentifier conflictingId = new NodeIdentifier("1234", "localhost", 8001, "localhost", 9000, "localhost", 10000, 11000, false);
    final ConnectionRequest connectionRequest = new ConnectionRequest(id1, new StandardDataFlow(new byte[0], new byte[0], new byte[0], new HashSet<>()));
    final ConnectionRequestMessage crm = new ConnectionRequestMessage();
    crm.setConnectionRequest(connectionRequest);
    final ProtocolMessage response = coordinator.handle(crm);
    assertNotNull(response);
    assertTrue(response instanceof ConnectionResponseMessage);
    final ConnectionResponseMessage responseMessage = (ConnectionResponseMessage) response;
    final NodeIdentifier resolvedNodeId = responseMessage.getConnectionResponse().getNodeIdentifier();
    assertEquals(id1, resolvedNodeId);
    final ConnectionRequest conRequest2 = new ConnectionRequest(conflictingId, new StandardDataFlow(new byte[0], new byte[0], new byte[0], new HashSet<>()));
    final ConnectionRequestMessage crm2 = new ConnectionRequestMessage();
    crm2.setConnectionRequest(conRequest2);
    final ProtocolMessage conflictingResponse = coordinator.handle(crm2);
    assertNotNull(conflictingResponse);
    assertTrue(conflictingResponse instanceof ConnectionResponseMessage);
    final ConnectionResponseMessage conflictingResponseMessage = (ConnectionResponseMessage) conflictingResponse;
    final NodeIdentifier conflictingNodeId = conflictingResponseMessage.getConnectionResponse().getNodeIdentifier();
    assertNotSame(id1.getId(), conflictingNodeId.getId());
    assertEquals(conflictingId.getApiAddress(), conflictingNodeId.getApiAddress());
    assertEquals(conflictingId.getApiPort(), conflictingNodeId.getApiPort());
    assertEquals(conflictingId.getSiteToSiteAddress(), conflictingNodeId.getSiteToSiteAddress());
    assertEquals(conflictingId.getSiteToSitePort(), conflictingNodeId.getSiteToSitePort());
    assertEquals(conflictingId.getSocketAddress(), conflictingNodeId.getSocketAddress());
    assertEquals(conflictingId.getSocketPort(), conflictingNodeId.getSocketPort());
}
Also used : ConnectionRequest(org.apache.nifi.cluster.protocol.ConnectionRequest) StandardDataFlow(org.apache.nifi.cluster.protocol.StandardDataFlow) ConnectionRequestMessage(org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage) NodeIdentifier(org.apache.nifi.cluster.protocol.NodeIdentifier) ConnectionResponseMessage(org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage) ProtocolMessage(org.apache.nifi.cluster.protocol.message.ProtocolMessage) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

ConnectionRequest (org.apache.nifi.cluster.protocol.ConnectionRequest)5 StandardDataFlow (org.apache.nifi.cluster.protocol.StandardDataFlow)4 ConnectionRequestMessage (org.apache.nifi.cluster.protocol.message.ConnectionRequestMessage)4 HashSet (java.util.HashSet)3 NodeIdentifier (org.apache.nifi.cluster.protocol.NodeIdentifier)3 ConnectionResponse (org.apache.nifi.cluster.protocol.ConnectionResponse)2 ConnectionResponseMessage (org.apache.nifi.cluster.protocol.message.ConnectionResponseMessage)2 ProtocolMessage (org.apache.nifi.cluster.protocol.message.ProtocolMessage)2 Test (org.junit.Test)2 IOException (java.io.IOException)1 Map (java.util.Map)1 ConnectionException (org.apache.nifi.cluster.ConnectionException)1 NoClusterCoordinatorException (org.apache.nifi.cluster.exception.NoClusterCoordinatorException)1 DataFlow (org.apache.nifi.cluster.protocol.DataFlow)1 ProtocolException (org.apache.nifi.cluster.protocol.ProtocolException)1 ClusterCoordinationProtocolSenderListener (org.apache.nifi.cluster.protocol.impl.ClusterCoordinationProtocolSenderListener)1 FlowSerializationException (org.apache.nifi.controller.serialization.FlowSerializationException)1 FlowSynchronizationException (org.apache.nifi.controller.serialization.FlowSynchronizationException)1 EventReporter (org.apache.nifi.events.EventReporter)1 LifeCycleStartException (org.apache.nifi.lifecycle.LifeCycleStartException)1