Search in sources :

Example 6 with ChannelSender

use of org.apache.nifi.processor.util.put.sender.ChannelSender in project nifi by apache.

the class PutTCP method onTrigger.

/**
 * event handler method to handle the FlowFile being forwarded to the Processor by the framework. The FlowFile contents is sent out over a TCP connection using an acquired ChannelSender object. If
 * the FlowFile contents was sent out successfully then the FlowFile is forwarded to the success relationship. If an error occurred then the FlowFile is forwarded to the failure relationship.
 *
 * @param context
 *            - the current process context.
 *
 * @param sessionFactory
 *            - a factory object to obtain a process session.
 */
@Override
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
    final ProcessSession session = sessionFactory.createSession();
    final FlowFile flowFile = session.get();
    if (flowFile == null) {
        final PruneResult result = pruneIdleSenders(context.getProperty(IDLE_EXPIRATION).asTimePeriod(TimeUnit.MILLISECONDS).longValue());
        // yield if we closed an idle connection, or if there were no connections in the first place
        if (result.getNumClosed() > 0 || (result.getNumClosed() == 0 && result.getNumConsidered() == 0)) {
            context.yield();
        }
        return;
    }
    ChannelSender sender = acquireSender(context, session, flowFile);
    if (sender == null) {
        return;
    }
    // can cast to a SocketChannelSender later in order to obtain the OutputStream
    if (!(sender instanceof SocketChannelSender)) {
        getLogger().error("Processor can only be used with a SocketChannelSender, but obtained: " + sender.getClass().getCanonicalName());
        context.yield();
        return;
    }
    boolean closeSender = isConnectionPerFlowFile(context);
    try {
        // We might keep the connection open across invocations of the processor so don't auto-close this
        final OutputStream out = ((SocketChannelSender) sender).getOutputStream();
        final String delimiter = getOutgoingMessageDelimiter(context, flowFile);
        final StopWatch stopWatch = new StopWatch(true);
        try (final InputStream rawIn = session.read(flowFile);
            final BufferedInputStream in = new BufferedInputStream(rawIn)) {
            IOUtils.copy(in, out);
            if (delimiter != null) {
                final Charset charSet = Charset.forName(context.getProperty(CHARSET).getValue());
                out.write(delimiter.getBytes(charSet), 0, delimiter.length());
            }
            out.flush();
        } catch (final Exception e) {
            closeSender = true;
            throw e;
        }
        session.getProvenanceReporter().send(flowFile, transitUri, stopWatch.getElapsed(TimeUnit.MILLISECONDS));
        session.transfer(flowFile, REL_SUCCESS);
        session.commit();
    } catch (Exception e) {
        onFailure(context, session, flowFile);
        getLogger().error("Exception while handling a process session, transferring {} to failure.", new Object[] { flowFile }, e);
    } finally {
        if (closeSender) {
            getLogger().debug("Closing sender");
            sender.close();
        } else {
            getLogger().debug("Relinquishing sender");
            relinquishSender(sender);
        }
    }
}
Also used : ProcessSession(org.apache.nifi.processor.ProcessSession) FlowFile(org.apache.nifi.flowfile.FlowFile) BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) ChannelSender(org.apache.nifi.processor.util.put.sender.ChannelSender) SocketChannelSender(org.apache.nifi.processor.util.put.sender.SocketChannelSender) Charset(java.nio.charset.Charset) SocketChannelSender(org.apache.nifi.processor.util.put.sender.SocketChannelSender) ProcessException(org.apache.nifi.processor.exception.ProcessException) IOException(java.io.IOException) StopWatch(org.apache.nifi.util.StopWatch) BufferedInputStream(java.io.BufferedInputStream)

Example 7 with ChannelSender

use of org.apache.nifi.processor.util.put.sender.ChannelSender in project nifi by apache.

the class PutSplunk method onTrigger.

@Override
public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
    // first complete any batches from previous executions
    FlowFileMessageBatch batch;
    while ((batch = completeBatches.poll()) != null) {
        batch.completeSession();
    }
    // create a session and try to get a FlowFile, if none available then close any idle senders
    final ProcessSession session = sessionFactory.createSession();
    final FlowFile flowFile = session.get();
    if (flowFile == null) {
        final PruneResult result = pruneIdleSenders(context.getProperty(IDLE_EXPIRATION).asTimePeriod(TimeUnit.MILLISECONDS).longValue());
        // yield if we closed an idle connection, or if there were no connections in the first place
        if (result.getNumClosed() > 0 || (result.getNumClosed() == 0 && result.getNumConsidered() == 0)) {
            context.yield();
        }
        return;
    }
    // get a sender from the pool, or create a new one if the pool is empty
    // if we can't create a new connection then route flow files to failure and yield
    // acquireSender will handle the routing to failure and yielding
    ChannelSender sender = acquireSender(context, session, flowFile);
    if (sender == null) {
        return;
    }
    try {
        String delimiter = context.getProperty(MESSAGE_DELIMITER).evaluateAttributeExpressions(flowFile).getValue();
        if (delimiter != null) {
            delimiter = delimiter.replace("\\n", "\n").replace("\\r", "\r").replace("\\t", "\t");
        }
        // if no delimiter then treat the whole FlowFile as a single message
        if (delimiter == null) {
            processSingleMessage(context, session, flowFile, sender);
        } else {
            processDelimitedMessages(context, session, flowFile, sender, delimiter);
        }
    } finally {
        relinquishSender(sender);
    }
}
Also used : ProcessSession(org.apache.nifi.processor.ProcessSession) FlowFile(org.apache.nifi.flowfile.FlowFile) ChannelSender(org.apache.nifi.processor.util.put.sender.ChannelSender)

Example 8 with ChannelSender

use of org.apache.nifi.processor.util.put.sender.ChannelSender in project nifi by apache.

the class AbstractPutEventProcessor method createSender.

/**
 * Helper for sub-classes to create a sender.
 *
 * @param protocol the protocol for the sender
 * @param host the host to send to
 * @param port the port to send to
 * @param timeout the timeout for connecting and communicating over the channel
 * @param maxSendBufferSize the maximum size of the socket send buffer
 * @param sslContext an SSLContext, or null if not using SSL
 *
 * @return a ChannelSender based on the given properties
 *
 * @throws IOException if an error occurs creating the sender
 */
protected ChannelSender createSender(final String protocol, final String host, final int port, final int timeout, final int maxSendBufferSize, final SSLContext sslContext) throws IOException {
    ChannelSender sender;
    if (protocol.equals(UDP_VALUE.getValue())) {
        sender = new DatagramChannelSender(host, port, maxSendBufferSize, getLogger());
    } else {
        // if an SSLContextService is provided then we make a secure sender
        if (sslContext != null) {
            sender = new SSLSocketChannelSender(host, port, maxSendBufferSize, sslContext, getLogger());
        } else {
            sender = new SocketChannelSender(host, port, maxSendBufferSize, getLogger());
        }
    }
    sender.setTimeout(timeout);
    sender.open();
    return sender;
}
Also used : DatagramChannelSender(org.apache.nifi.processor.util.put.sender.DatagramChannelSender) SSLSocketChannelSender(org.apache.nifi.processor.util.put.sender.SSLSocketChannelSender) ChannelSender(org.apache.nifi.processor.util.put.sender.ChannelSender) SocketChannelSender(org.apache.nifi.processor.util.put.sender.SocketChannelSender) DatagramChannelSender(org.apache.nifi.processor.util.put.sender.DatagramChannelSender) SSLSocketChannelSender(org.apache.nifi.processor.util.put.sender.SSLSocketChannelSender) SocketChannelSender(org.apache.nifi.processor.util.put.sender.SocketChannelSender) SSLSocketChannelSender(org.apache.nifi.processor.util.put.sender.SSLSocketChannelSender)

Example 9 with ChannelSender

use of org.apache.nifi.processor.util.put.sender.ChannelSender in project nifi by apache.

the class PutSyslog method onTrigger.

@Override
public void onTrigger(ProcessContext context, ProcessSession session) throws ProcessException {
    final String protocol = context.getProperty(PROTOCOL).getValue();
    final int batchSize = context.getProperty(BATCH_SIZE).evaluateAttributeExpressions().asInteger();
    final List<FlowFile> flowFiles = session.get(batchSize);
    if (flowFiles == null || flowFiles.isEmpty()) {
        final PruneResult result = pruneIdleSenders(context.getProperty(IDLE_EXPIRATION).evaluateAttributeExpressions().asTimePeriod(TimeUnit.MILLISECONDS).longValue());
        // yield if we closed an idle connection, or if there were no connections in the first place
        if (result.getNumClosed() > 0 || (result.getNumClosed() == 0 && result.getNumConsidered() == 0)) {
            context.yield();
        }
        return;
    }
    // get a sender from the pool, or create a new one if the pool is empty
    // if we can't create a new connection then route flow files to failure and yield
    ChannelSender sender = senderPool.poll();
    if (sender == null) {
        try {
            getLogger().debug("No available connections, creating a new one...");
            sender = createSender(context);
        } catch (IOException e) {
            for (final FlowFile flowFile : flowFiles) {
                getLogger().error("No available connections, and unable to create a new one, transferring {} to failure", new Object[] { flowFile }, e);
                session.transfer(flowFile, REL_FAILURE);
            }
            context.yield();
            return;
        }
    }
    final String port = context.getProperty(PORT).evaluateAttributeExpressions().getValue();
    final String host = context.getProperty(HOSTNAME).evaluateAttributeExpressions().getValue();
    final String transitUri = new StringBuilder().append(protocol).append("://").append(host).append(":").append(port).toString();
    final AtomicReference<IOException> exceptionHolder = new AtomicReference<>(null);
    final Charset charSet = Charset.forName(context.getProperty(CHARSET).evaluateAttributeExpressions().getValue());
    try {
        for (FlowFile flowFile : flowFiles) {
            final StopWatch timer = new StopWatch(true);
            final String priority = context.getProperty(MSG_PRIORITY).evaluateAttributeExpressions(flowFile).getValue();
            final String version = context.getProperty(MSG_VERSION).evaluateAttributeExpressions(flowFile).getValue();
            final String timestamp = context.getProperty(MSG_TIMESTAMP).evaluateAttributeExpressions(flowFile).getValue();
            final String hostname = context.getProperty(MSG_HOSTNAME).evaluateAttributeExpressions(flowFile).getValue();
            final String body = context.getProperty(MSG_BODY).evaluateAttributeExpressions(flowFile).getValue();
            final StringBuilder messageBuilder = new StringBuilder();
            messageBuilder.append("<").append(priority).append(">");
            if (version != null) {
                messageBuilder.append(version).append(" ");
            }
            messageBuilder.append(timestamp).append(" ").append(hostname).append(" ").append(body);
            final String fullMessage = messageBuilder.toString();
            getLogger().debug(fullMessage);
            if (isValid(fullMessage)) {
                try {
                    // now that we validated, add a new line if doing TCP
                    if (protocol.equals(TCP_VALUE.getValue())) {
                        messageBuilder.append('\n');
                    }
                    sender.send(messageBuilder.toString(), charSet);
                    timer.stop();
                    final long duration = timer.getDuration(TimeUnit.MILLISECONDS);
                    session.getProvenanceReporter().send(flowFile, transitUri, duration, true);
                    getLogger().info("Transferring {} to success", new Object[] { flowFile });
                    session.transfer(flowFile, REL_SUCCESS);
                } catch (IOException e) {
                    getLogger().error("Transferring {} to failure", new Object[] { flowFile }, e);
                    session.transfer(flowFile, REL_FAILURE);
                    exceptionHolder.set(e);
                }
            } else {
                getLogger().info("Transferring {} to invalid", new Object[] { flowFile });
                session.transfer(flowFile, REL_INVALID);
            }
        }
    } finally {
        // if the connection is still open and no IO errors happened then try to return, if pool is full then close
        if (sender.isConnected() && exceptionHolder.get() == null) {
            boolean returned = senderPool.offer(sender);
            if (!returned) {
                sender.close();
            }
        } else {
            // probably already closed here, but quietly close anyway to be safe
            sender.close();
        }
    }
}
Also used : FlowFile(org.apache.nifi.flowfile.FlowFile) DatagramChannelSender(org.apache.nifi.processor.util.put.sender.DatagramChannelSender) SSLSocketChannelSender(org.apache.nifi.processor.util.put.sender.SSLSocketChannelSender) ChannelSender(org.apache.nifi.processor.util.put.sender.ChannelSender) SocketChannelSender(org.apache.nifi.processor.util.put.sender.SocketChannelSender) Charset(java.nio.charset.Charset) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) StopWatch(org.apache.nifi.util.StopWatch)

Example 10 with ChannelSender

use of org.apache.nifi.processor.util.put.sender.ChannelSender in project nifi by apache.

the class PutSyslog method onStopped.

@OnStopped
public void onStopped() {
    if (senderPool != null) {
        ChannelSender sender = senderPool.poll();
        while (sender != null) {
            sender.close();
            sender = senderPool.poll();
        }
    }
}
Also used : DatagramChannelSender(org.apache.nifi.processor.util.put.sender.DatagramChannelSender) SSLSocketChannelSender(org.apache.nifi.processor.util.put.sender.SSLSocketChannelSender) ChannelSender(org.apache.nifi.processor.util.put.sender.ChannelSender) SocketChannelSender(org.apache.nifi.processor.util.put.sender.SocketChannelSender) OnStopped(org.apache.nifi.annotation.lifecycle.OnStopped)

Aggregations

ChannelSender (org.apache.nifi.processor.util.put.sender.ChannelSender)11 SocketChannelSender (org.apache.nifi.processor.util.put.sender.SocketChannelSender)9 DatagramChannelSender (org.apache.nifi.processor.util.put.sender.DatagramChannelSender)8 SSLSocketChannelSender (org.apache.nifi.processor.util.put.sender.SSLSocketChannelSender)8 IOException (java.io.IOException)4 FlowFile (org.apache.nifi.flowfile.FlowFile)4 ProcessSession (org.apache.nifi.processor.ProcessSession)3 StopWatch (org.apache.nifi.util.StopWatch)3 Charset (java.nio.charset.Charset)2 ArrayList (java.util.ArrayList)2 OnStopped (org.apache.nifi.annotation.lifecycle.OnStopped)2 ProcessException (org.apache.nifi.processor.exception.ProcessException)2 BufferedInputStream (java.io.BufferedInputStream)1 InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 SSLContext (javax.net.ssl.SSLContext)1