Search in sources :

Example 1 with PortNotRunningException

use of org.apache.nifi.remote.exception.PortNotRunningException in project nifi by apache.

the class StandardRemoteGroupPort method onTrigger.

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
    if (!remoteGroup.isTransmitting()) {
        logger.debug("{} {} is not transmitting; will not send/receive", this, remoteGroup);
        return;
    }
    if (getConnectableType() == ConnectableType.REMOTE_INPUT_PORT && session.getQueueSize().getObjectCount() == 0) {
        logger.debug("{} No data to send", this);
        return;
    }
    final String url = getRemoteProcessGroup().getTargetUri();
    // If we are sending data, we need to ensure that we have at least 1 FlowFile to send. Otherwise,
    // we don't want to create a transaction at all.
    final FlowFile firstFlowFile;
    if (getConnectableType() == ConnectableType.REMOTE_INPUT_PORT) {
        firstFlowFile = session.get();
        if (firstFlowFile == null) {
            return;
        }
    } else {
        firstFlowFile = null;
    }
    final SiteToSiteClient client = getSiteToSiteClient();
    final Transaction transaction;
    try {
        transaction = client.createTransaction(transferDirection);
    } catch (final PortNotRunningException e) {
        context.yield();
        this.targetRunning.set(false);
        final String message = String.format("%s failed to communicate with %s because the remote instance indicates that the port is not in a valid state", this, url);
        logger.error(message);
        session.rollback();
        remoteGroup.getEventReporter().reportEvent(Severity.ERROR, CATEGORY, message);
        return;
    } catch (final UnknownPortException e) {
        context.yield();
        this.targetExists.set(false);
        final String message = String.format("%s failed to communicate with %s because the remote instance indicates that the port no longer exists", this, url);
        logger.error(message);
        session.rollback();
        remoteGroup.getEventReporter().reportEvent(Severity.ERROR, CATEGORY, message);
        return;
    } catch (final UnreachableClusterException e) {
        context.yield();
        final String message = String.format("%s failed to communicate with %s due to %s", this, url, e.toString());
        logger.error(message);
        session.rollback();
        remoteGroup.getEventReporter().reportEvent(Severity.ERROR, CATEGORY, message);
        return;
    } catch (final IOException e) {
        // we do not yield here because the 'peer' will be penalized, and we won't communicate with that particular nifi instance
        // for a while due to penalization, but we can continue to talk to other nifi instances
        final String message = String.format("%s failed to communicate with %s due to %s", this, url, e.toString());
        logger.error(message);
        if (logger.isDebugEnabled()) {
            logger.error("", e);
        }
        session.rollback();
        remoteGroup.getEventReporter().reportEvent(Severity.ERROR, CATEGORY, message);
        return;
    }
    if (transaction == null) {
        logger.debug("{} Unable to create transaction to communicate with; all peers must be penalized, so yielding context", this);
        session.rollback();
        context.yield();
        return;
    }
    try {
        if (getConnectableType() == ConnectableType.REMOTE_INPUT_PORT) {
            transferFlowFiles(transaction, context, session, firstFlowFile);
        } else {
            final int numReceived = receiveFlowFiles(transaction, context, session);
            if (numReceived == 0) {
                context.yield();
            }
        }
        session.commit();
    } catch (final Throwable t) {
        final String message = String.format("%s failed to communicate with remote NiFi instance due to %s", this, t.toString());
        logger.error("{} failed to communicate with remote NiFi instance due to {}", this, t.toString());
        if (logger.isDebugEnabled()) {
            logger.error("", t);
        }
        remoteGroup.getEventReporter().reportEvent(Severity.ERROR, CATEGORY, message);
        transaction.error();
        session.rollback();
    }
}
Also used : SiteToSiteClient(org.apache.nifi.remote.client.SiteToSiteClient) FlowFile(org.apache.nifi.flowfile.FlowFile) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) IOException(java.io.IOException) UnreachableClusterException(org.apache.nifi.remote.exception.UnreachableClusterException)

Example 2 with PortNotRunningException

use of org.apache.nifi.remote.exception.PortNotRunningException in project nifi by apache.

the class HttpClient method createTransaction.

@Override
public Transaction createTransaction(final TransferDirection direction) throws HandshakeException, PortNotRunningException, ProtocolException, UnknownPortException, IOException {
    final int timeoutMillis = (int) config.getTimeout(TimeUnit.MILLISECONDS);
    PeerStatus peerStatus;
    while ((peerStatus = peerSelector.getNextPeerStatus(direction)) != null) {
        logger.debug("peerStatus={}", peerStatus);
        final CommunicationsSession commSession = new HttpCommunicationsSession();
        final String nodeApiUrl = resolveNodeApiUrl(peerStatus.getPeerDescription());
        final StringBuilder clusterUrls = new StringBuilder();
        config.getUrls().forEach(url -> {
            if (clusterUrls.length() > 0) {
                clusterUrls.append(",");
                clusterUrls.append(url);
            }
        });
        final Peer peer = new Peer(peerStatus.getPeerDescription(), commSession, nodeApiUrl, clusterUrls.toString());
        final int penaltyMillis = (int) config.getPenalizationPeriod(TimeUnit.MILLISECONDS);
        String portId = config.getPortIdentifier();
        if (StringUtils.isEmpty(portId)) {
            portId = siteInfoProvider.getPortIdentifier(config.getPortName(), direction);
            if (StringUtils.isEmpty(portId)) {
                peer.close();
                throw new IOException("Failed to determine the identifier of port " + config.getPortName());
            }
        }
        final SiteToSiteRestApiClient apiClient = new SiteToSiteRestApiClient(config.getSslContext(), config.getHttpProxy(), config.getEventReporter());
        apiClient.setBaseUrl(peer.getUrl());
        apiClient.setConnectTimeoutMillis(timeoutMillis);
        apiClient.setReadTimeoutMillis(timeoutMillis);
        apiClient.setCacheExpirationMillis(config.getCacheExpiration(TimeUnit.MILLISECONDS));
        apiClient.setLocalAddress(config.getLocalAddress());
        apiClient.setCompress(config.isUseCompression());
        apiClient.setRequestExpirationMillis(config.getIdleConnectionExpiration(TimeUnit.MILLISECONDS));
        apiClient.setBatchCount(config.getPreferredBatchCount());
        apiClient.setBatchSize(config.getPreferredBatchSize());
        apiClient.setBatchDurationMillis(config.getPreferredBatchDuration(TimeUnit.MILLISECONDS));
        final String transactionUrl;
        try {
            transactionUrl = apiClient.initiateTransaction(direction, portId);
            commSession.setUserDn(apiClient.getTrustedPeerDn());
        } catch (final Exception e) {
            apiClient.close();
            logger.warn("Penalizing a peer {} due to {}", peer, e.toString());
            peerSelector.penalize(peer, penaltyMillis);
            // Following exceptions will be thrown even if we tried other peers, so throw it.
            if (e instanceof UnknownPortException || e instanceof PortNotRunningException || e instanceof HandshakeException) {
                throw e;
            }
            logger.debug("Continue trying other peers...");
            continue;
        }
        // We found a valid peer to communicate with.
        final Integer transactionProtocolVersion = apiClient.getTransactionProtocolVersion();
        final HttpClientTransaction transaction = new HttpClientTransaction(transactionProtocolVersion, peer, direction, config.isUseCompression(), portId, penaltyMillis, config.getEventReporter()) {

            @Override
            protected void close() throws IOException {
                try {
                    super.close();
                } finally {
                    activeTransactions.remove(this);
                }
            }
        };
        try {
            transaction.initialize(apiClient, transactionUrl);
        } catch (final Exception e) {
            transaction.error();
            throw e;
        }
        activeTransactions.add(transaction);
        return transaction;
    }
    logger.info("Couldn't find a valid peer to communicate with.");
    return null;
}
Also used : HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) Peer(org.apache.nifi.remote.Peer) SiteToSiteRestApiClient(org.apache.nifi.remote.util.SiteToSiteRestApiClient) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) IOException(java.io.IOException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) IOException(java.io.IOException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) PeerStatus(org.apache.nifi.remote.PeerStatus) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) HttpClientTransaction(org.apache.nifi.remote.protocol.http.HttpClientTransaction)

Example 3 with PortNotRunningException

use of org.apache.nifi.remote.exception.PortNotRunningException in project nifi by apache.

the class SiteToSiteRestApiClient method handleErrResponse.

private IOException handleErrResponse(final int responseCode, final InputStream in) throws IOException {
    if (in == null) {
        return new IOException("Unexpected response code: " + responseCode);
    }
    final TransactionResultEntity errEntity = readResponse(in);
    final ResponseCode errCode = ResponseCode.fromCode(errEntity.getResponseCode());
    switch(errCode) {
        case UNKNOWN_PORT:
            return new UnknownPortException(errEntity.getMessage());
        case PORT_NOT_IN_VALID_STATE:
            return new PortNotRunningException(errEntity.getMessage());
        default:
            switch(responseCode) {
                case RESPONSE_CODE_FORBIDDEN:
                    return new HandshakeException(errEntity.getMessage());
                default:
                    return new IOException("Unexpected response code: " + responseCode + " errCode:" + errCode + " errMessage:" + errEntity.getMessage());
            }
    }
}
Also used : TransactionResultEntity(org.apache.nifi.web.api.entity.TransactionResultEntity) ResponseCode(org.apache.nifi.remote.protocol.ResponseCode) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) IOException(java.io.IOException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException)

Example 4 with PortNotRunningException

use of org.apache.nifi.remote.exception.PortNotRunningException in project nifi by apache.

the class EndpointConnectionPool method getEndpointConnection.

public EndpointConnection getEndpointConnection(final TransferDirection direction, final SiteToSiteClientConfig config) throws IOException {
    // 
    // Attempt to get a connection state that already exists for this URL.
    // 
    FlowFileCodec codec = null;
    CommunicationsSession commsSession = null;
    SocketClientProtocol protocol = null;
    EndpointConnection connection;
    Peer peer = null;
    final URI clusterUrl;
    try {
        clusterUrl = siteInfoProvider.getActiveClusterUrl();
    } catch (final IOException ioe) {
        throw new UnreachableClusterException("Unable to refresh details from any of the configured remote instances.", ioe);
    }
    do {
        final List<EndpointConnection> addBack = new ArrayList<>();
        logger.debug("{} getting next peer status", this);
        final PeerStatus peerStatus = peerSelector.getNextPeerStatus(direction);
        logger.debug("{} next peer status = {}", this, peerStatus);
        if (peerStatus == null) {
            return null;
        }
        final PeerDescription peerDescription = peerStatus.getPeerDescription();
        BlockingQueue<EndpointConnection> connectionQueue = connectionQueueMap.get(peerDescription);
        if (connectionQueue == null) {
            connectionQueue = new LinkedBlockingQueue<>();
            BlockingQueue<EndpointConnection> existing = connectionQueueMap.putIfAbsent(peerDescription, connectionQueue);
            if (existing != null) {
                connectionQueue = existing;
            }
        }
        try {
            connection = connectionQueue.poll();
            logger.debug("{} Connection State for {} = {}", this, clusterUrl, connection);
            final String portId = getPortIdentifier(direction);
            if (connection == null && !addBack.isEmpty()) {
                // all available connections have been penalized.
                logger.debug("{} all Connections for {} are penalized; returning no Connection", this, portId);
                return null;
            }
            if (connection != null && connection.getPeer().isPenalized(portId)) {
                // we have a connection, but it's penalized. We want to add it back to the queue
                // when we've found one to use.
                addBack.add(connection);
                continue;
            }
            // if we can't get an existing Connection, create one
            if (connection == null) {
                logger.debug("{} No Connection available for Port {}; creating new Connection", this, portId);
                protocol = new SocketClientProtocol();
                protocol.setDestination(new IdEnrichedRemoteDestination(remoteDestination, portId));
                protocol.setEventReporter(eventReporter);
                final long penalizationMillis = remoteDestination.getYieldPeriod(TimeUnit.MILLISECONDS);
                try {
                    logger.debug("{} Establishing site-to-site connection with {}", this, peerStatus);
                    commsSession = establishSiteToSiteConnection(peerStatus);
                } catch (final IOException ioe) {
                    peerSelector.penalize(peerStatus.getPeerDescription(), penalizationMillis);
                    throw ioe;
                }
                final DataInputStream dis = new DataInputStream(commsSession.getInput().getInputStream());
                final DataOutputStream dos = new DataOutputStream(commsSession.getOutput().getOutputStream());
                try {
                    logger.debug("{} Negotiating protocol", this);
                    RemoteResourceInitiator.initiateResourceNegotiation(protocol, dis, dos);
                } catch (final HandshakeException e) {
                    try {
                        commsSession.close();
                    } catch (final IOException ioe) {
                        throw e;
                    }
                }
                final String peerUrl = "nifi://" + peerDescription.getHostname() + ":" + peerDescription.getPort();
                peer = new Peer(peerDescription, commsSession, peerUrl, clusterUrl.toString());
                // set properties based on config
                if (config != null) {
                    protocol.setTimeout((int) config.getTimeout(TimeUnit.MILLISECONDS));
                    protocol.setPreferredBatchCount(config.getPreferredBatchCount());
                    protocol.setPreferredBatchSize(config.getPreferredBatchSize());
                    protocol.setPreferredBatchDuration(config.getPreferredBatchDuration(TimeUnit.MILLISECONDS));
                }
                // perform handshake
                try {
                    logger.debug("{} performing handshake", this);
                    protocol.handshake(peer);
                    // handle error cases
                    if (protocol.isDestinationFull()) {
                        logger.warn("{} {} indicates that port {}'s destination is full; penalizing peer", this, peer, config.getPortName() == null ? config.getPortIdentifier() : config.getPortName());
                        peerSelector.penalize(peer, penalizationMillis);
                        try {
                            peer.close();
                        } catch (final IOException ioe) {
                        }
                        continue;
                    } else if (protocol.isPortInvalid()) {
                        peerSelector.penalize(peer, penalizationMillis);
                        cleanup(protocol, peer);
                        throw new PortNotRunningException(peer.toString() + " indicates that port " + portId + " is not running");
                    } else if (protocol.isPortUnknown()) {
                        peerSelector.penalize(peer, penalizationMillis);
                        cleanup(protocol, peer);
                        throw new UnknownPortException(peer.toString() + " indicates that port " + portId + " is not known");
                    }
                    // negotiate the FlowFileCodec to use
                    logger.debug("{} negotiating codec", this);
                    codec = protocol.negotiateCodec(peer);
                    logger.debug("{} negotiated codec is {}", this, codec);
                } catch (final PortNotRunningException | UnknownPortException e) {
                    throw e;
                } catch (final Exception e) {
                    peerSelector.penalize(peer, penalizationMillis);
                    cleanup(protocol, peer);
                    final String message = String.format("%s failed to communicate with %s due to %s", this, peer == null ? clusterUrl : peer, e.toString());
                    error(logger, eventReporter, message);
                    if (logger.isDebugEnabled()) {
                        logger.error("", e);
                    }
                    throw e;
                }
                connection = new EndpointConnection(peer, protocol, codec);
            } else {
                final long lastTimeUsed = connection.getLastTimeUsed();
                final long millisSinceLastUse = System.currentTimeMillis() - lastTimeUsed;
                if (commsTimeout > 0L && millisSinceLastUse >= commsTimeout) {
                    cleanup(connection.getSocketClientProtocol(), connection.getPeer());
                    connection = null;
                } else {
                    codec = connection.getCodec();
                    peer = connection.getPeer();
                    commsSession = peer.getCommunicationsSession();
                    protocol = connection.getSocketClientProtocol();
                }
            }
        } catch (final Throwable t) {
            if (commsSession != null) {
                try {
                    commsSession.close();
                } catch (final IOException ioe) {
                }
            }
            throw t;
        } finally {
            if (!addBack.isEmpty()) {
                connectionQueue.addAll(addBack);
                addBack.clear();
            }
        }
    } while (connection == null || codec == null || commsSession == null || protocol == null);
    activeConnections.add(connection);
    return connection;
}
Also used : DataOutputStream(java.io.DataOutputStream) ArrayList(java.util.ArrayList) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) SocketChannelCommunicationsSession(org.apache.nifi.remote.io.socket.SocketChannelCommunicationsSession) SSLSocketChannelCommunicationsSession(org.apache.nifi.remote.io.socket.ssl.SSLSocketChannelCommunicationsSession) URI(java.net.URI) FlowFileCodec(org.apache.nifi.remote.codec.FlowFileCodec) PeerStatus(org.apache.nifi.remote.PeerStatus) UnreachableClusterException(org.apache.nifi.remote.exception.UnreachableClusterException) PeerDescription(org.apache.nifi.remote.PeerDescription) Peer(org.apache.nifi.remote.Peer) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) SocketClientProtocol(org.apache.nifi.remote.protocol.socket.SocketClientProtocol) UnreachableClusterException(org.apache.nifi.remote.exception.UnreachableClusterException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) TransmissionDisabledException(org.apache.nifi.remote.exception.TransmissionDisabledException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) IOException(java.io.IOException) CertificateException(java.security.cert.CertificateException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) HandshakeException(org.apache.nifi.remote.exception.HandshakeException)

Aggregations

IOException (java.io.IOException)4 PortNotRunningException (org.apache.nifi.remote.exception.PortNotRunningException)4 UnknownPortException (org.apache.nifi.remote.exception.UnknownPortException)4 HandshakeException (org.apache.nifi.remote.exception.HandshakeException)3 Peer (org.apache.nifi.remote.Peer)2 PeerStatus (org.apache.nifi.remote.PeerStatus)2 UnreachableClusterException (org.apache.nifi.remote.exception.UnreachableClusterException)2 CommunicationsSession (org.apache.nifi.remote.protocol.CommunicationsSession)2 DataInputStream (java.io.DataInputStream)1 DataOutputStream (java.io.DataOutputStream)1 URI (java.net.URI)1 CertificateException (java.security.cert.CertificateException)1 ArrayList (java.util.ArrayList)1 FlowFile (org.apache.nifi.flowfile.FlowFile)1 PeerDescription (org.apache.nifi.remote.PeerDescription)1 SiteToSiteClient (org.apache.nifi.remote.client.SiteToSiteClient)1 FlowFileCodec (org.apache.nifi.remote.codec.FlowFileCodec)1 ProtocolException (org.apache.nifi.remote.exception.ProtocolException)1 TransmissionDisabledException (org.apache.nifi.remote.exception.TransmissionDisabledException)1 HttpCommunicationsSession (org.apache.nifi.remote.io.http.HttpCommunicationsSession)1