Search in sources :

Example 11 with AsyncProcessor

use of org.apache.camel.AsyncProcessor in project camel by apache.

the class InterceptSendToEndpoint method createProducer.

public Producer createProducer() throws Exception {
    producer = delegate.createProducer();
    return new DefaultAsyncProducer(delegate) {

        public Endpoint getEndpoint() {
            return producer.getEndpoint();
        }

        public Exchange createExchange() {
            return producer.createExchange();
        }

        public Exchange createExchange(ExchangePattern pattern) {
            return producer.createExchange(pattern);
        }

        @Deprecated
        public Exchange createExchange(Exchange exchange) {
            return producer.createExchange(exchange);
        }

        @Override
        public boolean process(Exchange exchange, AsyncCallback callback) {
            // process the detour so we do the detour routing
            if (LOG.isDebugEnabled()) {
                LOG.debug("Sending to endpoint: {} is intercepted and detoured to: {} for exchange: {}", new Object[] { getEndpoint(), detour, exchange });
            }
            // add header with the real endpoint uri
            exchange.getIn().setHeader(Exchange.INTERCEPTED_ENDPOINT, delegate.getEndpointUri());
            // detour the exchange using synchronous processing
            try {
                detour.process(exchange);
            } catch (Exception e) {
                exchange.setException(e);
            }
            // check for error if so we should break out
            if (!continueProcessing(exchange, "skip sending to original intended destination: " + getEndpoint(), LOG)) {
                callback.done(true);
                return true;
            }
            // determine if we should skip or not
            boolean shouldSkip = skip;
            // if then interceptor had a when predicate, then we should only skip if it matched
            Boolean whenMatches = (Boolean) exchange.removeProperty(Exchange.INTERCEPT_SEND_TO_ENDPOINT_WHEN_MATCHED);
            if (whenMatches != null) {
                shouldSkip = skip && whenMatches;
            }
            if (!shouldSkip) {
                if (exchange.hasOut()) {
                    // replace OUT with IN as detour changed something
                    exchange.setIn(exchange.getOut());
                    exchange.setOut(null);
                }
                // route to original destination leveraging the asynchronous routing engine if possible
                if (producer instanceof AsyncProcessor) {
                    AsyncProcessor async = (AsyncProcessor) producer;
                    return async.process(exchange, callback);
                } else {
                    try {
                        producer.process(exchange);
                    } catch (Exception e) {
                        exchange.setException(e);
                    }
                    callback.done(true);
                    return true;
                }
            } else {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Stop() means skip sending exchange to original intended destination: {} for exchange: {}", getEndpoint(), exchange);
                }
                callback.done(true);
                return true;
            }
        }

        public boolean isSingleton() {
            return producer.isSingleton();
        }

        public void start() throws Exception {
            ServiceHelper.startService(detour);
            // here we also need to start the producer
            ServiceHelper.startService(producer);
        }

        public void stop() throws Exception {
            // do not stop detour as it should only be stopped when the interceptor stops
            // we should stop the producer here
            ServiceHelper.stopService(producer);
        }
    };
}
Also used : Exchange(org.apache.camel.Exchange) ExchangePattern(org.apache.camel.ExchangePattern) AsyncProcessor(org.apache.camel.AsyncProcessor) AsyncCallback(org.apache.camel.AsyncCallback)

Example 12 with AsyncProcessor

use of org.apache.camel.AsyncProcessor in project camel by apache.

the class Pipeline method process.

private boolean process(final Exchange original, final Exchange exchange, final AsyncCallback callback, final Iterator<Processor> processors, final AsyncProcessor asyncProcessor) {
    // this does the actual processing so log at trace level
    LOG.trace("Processing exchangeId: {} >>> {}", exchange.getExchangeId(), exchange);
    // implement asynchronous routing logic in callback so we can have the callback being
    // triggered and then continue routing where we left
    boolean sync = asyncProcessor.process(exchange, new AsyncCallback() {

        public void done(boolean doneSync) {
            // we only have to handle async completion of the pipeline
            if (doneSync) {
                return;
            }
            // continue processing the pipeline asynchronously
            Exchange nextExchange = exchange;
            while (continueRouting(processors, nextExchange)) {
                AsyncProcessor processor = AsyncProcessorConverterHelper.convert(processors.next());
                // check for error if so we should break out
                if (!continueProcessing(nextExchange, "so breaking out of pipeline", LOG)) {
                    break;
                }
                nextExchange = createNextExchange(nextExchange);
                doneSync = process(original, nextExchange, callback, processors, processor);
                if (!doneSync) {
                    LOG.trace("Processing exchangeId: {} is continued being processed asynchronously", exchange.getExchangeId());
                    return;
                }
            }
            ExchangeHelper.copyResults(original, nextExchange);
            LOG.trace("Processing complete for exchangeId: {} >>> {}", original.getExchangeId(), original);
            callback.done(false);
        }
    });
    return sync;
}
Also used : Exchange(org.apache.camel.Exchange) AsyncProcessor(org.apache.camel.AsyncProcessor) AsyncCallback(org.apache.camel.AsyncCallback)

Example 13 with AsyncProcessor

use of org.apache.camel.AsyncProcessor in project camel by apache.

the class Pipeline method process.

public boolean process(Exchange exchange, AsyncCallback callback) {
    Iterator<Processor> processors = getProcessors().iterator();
    Exchange nextExchange = exchange;
    boolean first = true;
    while (continueRouting(processors, nextExchange)) {
        if (first) {
            first = false;
        } else {
            // prepare for next run
            nextExchange = createNextExchange(nextExchange);
        }
        // get the next processor
        Processor processor = processors.next();
        AsyncProcessor async = AsyncProcessorConverterHelper.convert(processor);
        boolean sync = process(exchange, nextExchange, callback, processors, async);
        // continue as long its being processed synchronously
        if (!sync) {
            LOG.trace("Processing exchangeId: {} is continued being processed asynchronously", exchange.getExchangeId());
            // so we break out now, then the callback will be invoked which then continue routing from where we left here
            return false;
        }
        LOG.trace("Processing exchangeId: {} is continued being processed synchronously", exchange.getExchangeId());
        // check for error if so we should break out
        if (!continueProcessing(nextExchange, "so breaking out of pipeline", LOG)) {
            break;
        }
    }
    // logging nextExchange as it contains the exchange that might have altered the payload and since
    // we are logging the completion if will be confusing if we log the original instead
    // we could also consider logging the original and the nextExchange then we have *before* and *after* snapshots
    LOG.trace("Processing complete for exchangeId: {} >>> {}", exchange.getExchangeId(), nextExchange);
    // copy results back to the original exchange
    ExchangeHelper.copyResults(exchange, nextExchange);
    callback.done(true);
    return true;
}
Also used : Exchange(org.apache.camel.Exchange) Processor(org.apache.camel.Processor) AsyncProcessor(org.apache.camel.AsyncProcessor) AsyncProcessor(org.apache.camel.AsyncProcessor)

Example 14 with AsyncProcessor

use of org.apache.camel.AsyncProcessor in project camel by apache.

the class RedeliveryErrorHandler method deliverToFailureProcessor.

/**
     * All redelivery attempts failed so move the exchange to the dead letter queue
     */
protected boolean deliverToFailureProcessor(final Processor processor, final boolean isDeadLetterChannel, final Exchange exchange, final RedeliveryData data, final AsyncCallback callback) {
    boolean sync = true;
    Exception caught = exchange.getException();
    // we did not success with the redelivery so now we let the failure processor handle it
    // clear exception as we let the failure processor handle it
    exchange.setException(null);
    final boolean shouldHandle = shouldHandle(exchange, data);
    final boolean shouldContinue = shouldContinue(exchange, data);
    // regard both handled or continued as being handled
    boolean handled = false;
    // always handle if dead letter channel
    boolean handleOrContinue = isDeadLetterChannel || shouldHandle || shouldContinue;
    if (handleOrContinue) {
        // its handled then remove traces of redelivery attempted
        exchange.getIn().removeHeader(Exchange.REDELIVERED);
        exchange.getIn().removeHeader(Exchange.REDELIVERY_COUNTER);
        exchange.getIn().removeHeader(Exchange.REDELIVERY_MAX_COUNTER);
        exchange.removeProperty(Exchange.REDELIVERY_EXHAUSTED);
        // and remove traces of rollback only and uow exhausted markers
        exchange.removeProperty(Exchange.ROLLBACK_ONLY);
        exchange.removeProperty(Exchange.UNIT_OF_WORK_EXHAUSTED);
        handled = true;
    } else {
        // must decrement the redelivery counter as we didn't process the redelivery but is
        // handling by the failure handler. So we must -1 to not let the counter be out-of-sync
        decrementRedeliveryCounter(exchange);
    }
    // we should allow using the failure processor if we should not continue
    // or in case of continue then the failure processor is NOT a dead letter channel
    // because you can continue and still let the failure processor do some routing
    // before continue in the main route.
    boolean allowFailureProcessor = !shouldContinue || !isDeadLetterChannel;
    if (allowFailureProcessor && processor != null) {
        // prepare original IN body if it should be moved instead of current body
        if (data.useOriginalInMessage) {
            log.trace("Using the original IN message instead of current");
            Message original = ExchangeHelper.getOriginalInMessage(exchange);
            exchange.setIn(original);
            if (exchange.hasOut()) {
                log.trace("Removing the out message to avoid some uncertain behavior");
                exchange.setOut(null);
            }
        }
        // reset cached streams so they can be read again
        MessageHelper.resetStreamCache(exchange.getIn());
        // invoke custom on prepare
        if (onPrepareProcessor != null) {
            try {
                log.trace("OnPrepare processor {} is processing Exchange: {}", onPrepareProcessor, exchange);
                onPrepareProcessor.process(exchange);
            } catch (Exception e) {
                // a new exception was thrown during prepare
                exchange.setException(e);
            }
        }
        log.trace("Failure processor {} is processing Exchange: {}", processor, exchange);
        // store the last to endpoint as the failure endpoint
        exchange.setProperty(Exchange.FAILURE_ENDPOINT, exchange.getProperty(Exchange.TO_ENDPOINT));
        // and store the route id so we know in which route we failed
        UnitOfWork uow = exchange.getUnitOfWork();
        if (uow != null && uow.getRouteContext() != null) {
            exchange.setProperty(Exchange.FAILURE_ROUTE_ID, uow.getRouteContext().getRoute().getId());
        }
        // fire event as we had a failure processor to handle it, which there is a event for
        final boolean deadLetterChannel = processor == data.deadLetterProcessor;
        EventHelper.notifyExchangeFailureHandling(exchange.getContext(), exchange, processor, deadLetterChannel, deadLetterUri);
        // the failure processor could also be asynchronous
        AsyncProcessor afp = AsyncProcessorConverterHelper.convert(processor);
        sync = afp.process(exchange, new AsyncCallback() {

            public void done(boolean sync) {
                log.trace("Failure processor done: {} processing Exchange: {}", processor, exchange);
                try {
                    prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
                    // fire event as we had a failure processor to handle it, which there is a event for
                    EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel, deadLetterUri);
                } finally {
                    // if the fault was handled asynchronously, this should be reflected in the callback as well
                    data.sync &= sync;
                    callback.done(data.sync);
                }
            }
        });
    } else {
        try {
            // invoke custom on prepare
            if (onPrepareProcessor != null) {
                try {
                    log.trace("OnPrepare processor {} is processing Exchange: {}", onPrepareProcessor, exchange);
                    onPrepareProcessor.process(exchange);
                } catch (Exception e) {
                    // a new exception was thrown during prepare
                    exchange.setException(e);
                }
            }
            // no processor but we need to prepare after failure as well
            prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
        } finally {
            // callback we are done
            callback.done(data.sync);
        }
    }
    // create log message
    String msg = "Failed delivery for " + ExchangeHelper.logIds(exchange);
    msg = msg + ". Exhausted after delivery attempt: " + data.redeliveryCounter + " caught: " + caught;
    if (processor != null) {
        if (isDeadLetterChannel && deadLetterUri != null) {
            msg = msg + ". Handled by DeadLetterChannel: [" + URISupport.sanitizeUri(deadLetterUri) + "]";
        } else {
            msg = msg + ". Processed by failure processor: " + processor;
        }
    }
    // log that we failed delivery as we are exhausted
    logFailedDelivery(false, false, handled, false, isDeadLetterChannel, exchange, msg, data, null);
    return sync;
}
Also used : UnitOfWork(org.apache.camel.spi.UnitOfWork) Message(org.apache.camel.Message) AsyncProcessor(org.apache.camel.AsyncProcessor) AsyncCallback(org.apache.camel.AsyncCallback) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 15 with AsyncProcessor

use of org.apache.camel.AsyncProcessor in project camel by apache.

the class TryProcessor method process.

public boolean process(Exchange exchange, AsyncCallback callback) {
    Iterator<Processor> processors = next().iterator();
    Object lastHandled = exchange.getProperty(Exchange.EXCEPTION_HANDLED);
    exchange.setProperty(Exchange.EXCEPTION_HANDLED, null);
    while (continueRouting(processors, exchange)) {
        exchange.setProperty(Exchange.TRY_ROUTE_BLOCK, true);
        ExchangeHelper.prepareOutToIn(exchange);
        // process the next processor
        Processor processor = processors.next();
        AsyncProcessor async = AsyncProcessorConverterHelper.convert(processor);
        boolean sync = process(exchange, callback, processors, async, lastHandled);
        // continue as long its being processed synchronously
        if (!sync) {
            LOG.trace("Processing exchangeId: {} is continued being processed asynchronously", exchange.getExchangeId());
            // so we break out now, then the callback will be invoked which then continue routing from where we left here
            return false;
        }
        LOG.trace("Processing exchangeId: {} is continued being processed synchronously", exchange.getExchangeId());
    }
    ExchangeHelper.prepareOutToIn(exchange);
    exchange.removeProperty(Exchange.TRY_ROUTE_BLOCK);
    exchange.setProperty(Exchange.EXCEPTION_HANDLED, lastHandled);
    LOG.trace("Processing complete for exchangeId: {} >>> {}", exchange.getExchangeId(), exchange);
    callback.done(true);
    return true;
}
Also used : Processor(org.apache.camel.Processor) AsyncProcessor(org.apache.camel.AsyncProcessor) AsyncProcessor(org.apache.camel.AsyncProcessor)

Aggregations

AsyncProcessor (org.apache.camel.AsyncProcessor)23 AsyncCallback (org.apache.camel.AsyncCallback)11 Exchange (org.apache.camel.Exchange)11 Processor (org.apache.camel.Processor)10 Producer (org.apache.camel.Producer)7 Endpoint (org.apache.camel.Endpoint)5 StopWatch (org.apache.camel.util.StopWatch)5 ExchangePattern (org.apache.camel.ExchangePattern)4 FailedToCreateProducerException (org.apache.camel.FailedToCreateProducerException)4 AsyncProducerCallback (org.apache.camel.AsyncProducerCallback)3 CamelExchangeException (org.apache.camel.CamelExchangeException)3 DefaultExchange (org.apache.camel.impl.DefaultExchange)2 TracedRouteNodes (org.apache.camel.spi.TracedRouteNodes)2 AtomicExchange (org.apache.camel.util.concurrent.AtomicExchange)2 ByteBuf (io.netty.buffer.ByteBuf)1 InetSocketAddress (java.net.InetSocketAddress)1 ByteBuffer (java.nio.ByteBuffer)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1 CamelContextAware (org.apache.camel.CamelContextAware)1 ErrorHandlerFactory (org.apache.camel.ErrorHandlerFactory)1