Search in sources :

Example 56 with AsyncCallback

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

the class SedaConsumer method sendToConsumers.

/**
     * Send the given {@link Exchange} to the consumer(s).
     * <p/>
     * If multiple consumers then they will each receive a copy of the Exchange.
     * A multicast processor will send the exchange in parallel to the multiple consumers.
     * <p/>
     * If there is only a single consumer then its dispatched directly to it using same thread.
     * 
     * @param exchange the exchange
     * @throws Exception can be thrown if processing of the exchange failed
     */
protected void sendToConsumers(final Exchange exchange) throws Exception {
    // validate multiple consumers has been enabled
    int size = endpoint.getConsumers().size();
    if (size > 1 && !endpoint.isMultipleConsumersSupported()) {
        throw new IllegalStateException("Multiple consumers for the same endpoint is not allowed: " + endpoint);
    }
    // if there are multiple consumers then multicast to them
    if (endpoint.isMultipleConsumersSupported()) {
        if (LOG.isTraceEnabled()) {
            LOG.trace("Multicasting to {} consumers for Exchange: {}", size, exchange);
        }
        // handover completions, as we need to done this when the multicast is done
        final List<Synchronization> completions = exchange.handoverCompletions();
        // use a multicast processor to process it
        MulticastProcessor mp = endpoint.getConsumerMulticastProcessor();
        ObjectHelper.notNull(mp, "ConsumerMulticastProcessor", this);
        // and use the asynchronous routing engine to support it
        mp.process(exchange, new AsyncCallback() {

            public void done(boolean doneSync) {
                // done the uow on the completions
                UnitOfWorkHelper.doneSynchronizations(exchange, completions, LOG);
            }
        });
    } else {
        // use the regular processor and use the asynchronous routing engine to support it
        processor.process(exchange, new AsyncCallback() {

            public void done(boolean doneSync) {
            // noop
            }
        });
    }
}
Also used : AsyncCallback(org.apache.camel.AsyncCallback) MulticastProcessor(org.apache.camel.processor.MulticastProcessor) Synchronization(org.apache.camel.spi.Synchronization) Endpoint(org.apache.camel.Endpoint)

Example 57 with AsyncCallback

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

the class CxfRsInvoker method asyncInvoke.

private Object asyncInvoke(Exchange cxfExchange, final Object serviceObject, Method method, Object[] paramArray, final Continuation continuation, Object response) throws Exception {
    synchronized (continuation) {
        if (continuation.isNew()) {
            final org.apache.camel.Exchange camelExchange = prepareExchange(cxfExchange, method, paramArray, response);
            // we want to handle the UoW
            cxfRsConsumer.createUoW(camelExchange);
            // Now we don't set up the timeout value
            LOG.trace("Suspending continuation of exchangeId: {}", camelExchange.getExchangeId());
            // The continuation could be called before the suspend is called
            continuation.suspend(endpoint.getContinuationTimeout());
            cxfExchange.put(SUSPENED, Boolean.TRUE);
            continuation.setObject(camelExchange);
            cxfRsConsumer.getAsyncProcessor().process(camelExchange, new AsyncCallback() {

                public void done(boolean doneSync) {
                    // make sure the continuation resume will not be called before the suspend method in other thread
                    synchronized (continuation) {
                        LOG.trace("Resuming continuation of exchangeId: {}", camelExchange.getExchangeId());
                        // resume processing after both, sync and async callbacks
                        continuation.resume();
                    }
                }
            });
            return null;
        }
        if (continuation.isResumed()) {
            cxfExchange.put(SUSPENED, Boolean.FALSE);
            org.apache.camel.Exchange camelExchange = (org.apache.camel.Exchange) continuation.getObject();
            try {
                return returnResponse(cxfExchange, camelExchange);
            } finally {
                cxfRsConsumer.doneUoW(camelExchange);
            }
        } else {
            if (!continuation.isPending()) {
                cxfExchange.put(SUSPENED, Boolean.FALSE);
                org.apache.camel.Exchange camelExchange = (org.apache.camel.Exchange) continuation.getObject();
                camelExchange.setException(new ExchangeTimedOutException(camelExchange, endpoint.getContinuationTimeout()));
                try {
                    return returnResponse(cxfExchange, camelExchange);
                } finally {
                    cxfRsConsumer.doneUoW(camelExchange);
                }
            }
        }
    }
    return null;
}
Also used : Exchange(org.apache.cxf.message.Exchange) AsyncCallback(org.apache.camel.AsyncCallback) ExchangeTimedOutException(org.apache.camel.ExchangeTimedOutException)

Example 58 with AsyncCallback

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

the class CamelInternalProcessor method process.

@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
    if (processor == null || !continueProcessing(exchange)) {
        // no processor or we should not continue then we are done
        callback.done(true);
        return true;
    }
    final List<Object> states = new ArrayList<Object>(advices.size());
    for (CamelInternalProcessorAdvice task : advices) {
        try {
            Object state = task.before(exchange);
            states.add(state);
        } catch (Throwable e) {
            exchange.setException(e);
            callback.done(true);
            return true;
        }
    }
    // create internal callback which will execute the advices in reverse order when done
    callback = new InternalCallback(states, exchange, callback);
    // UNIT_OF_WORK_PROCESS_SYNC is @deprecated and we should remove it from Camel 3.0
    Object synchronous = exchange.removeProperty(Exchange.UNIT_OF_WORK_PROCESS_SYNC);
    if (exchange.isTransacted() || synchronous != null) {
        // must be synchronized for transacted exchanges
        if (LOG.isTraceEnabled()) {
            if (exchange.isTransacted()) {
                LOG.trace("Transacted Exchange must be routed synchronously for exchangeId: {} -> {}", exchange.getExchangeId(), exchange);
            } else {
                LOG.trace("Synchronous UnitOfWork Exchange must be routed synchronously for exchangeId: {} -> {}", exchange.getExchangeId(), exchange);
            }
        }
        // ----------------------------------------------------------
        try {
            processor.process(exchange);
        } catch (Throwable e) {
            exchange.setException(e);
        }
        // ----------------------------------------------------------
        // CAMEL END USER - DEBUG ME HERE +++ END +++
        // ----------------------------------------------------------
        callback.done(true);
        return true;
    } else {
        final UnitOfWork uow = exchange.getUnitOfWork();
        // allow unit of work to wrap callback in case it need to do some special work
        // for example the MDCUnitOfWork
        AsyncCallback async = callback;
        if (uow != null) {
            async = uow.beforeProcess(processor, exchange, callback);
        }
        // ----------------------------------------------------------
        if (LOG.isTraceEnabled()) {
            LOG.trace("Processing exchange for exchangeId: {} -> {}", exchange.getExchangeId(), exchange);
        }
        boolean sync = processor.process(exchange, async);
        // execute any after processor work (in current thread, not in the callback)
        if (uow != null) {
            uow.afterProcess(processor, exchange, callback, sync);
        }
        if (LOG.isTraceEnabled()) {
            LOG.trace("Exchange processed and is continued routed {} for exchangeId: {} -> {}", new Object[] { sync ? "synchronously" : "asynchronously", exchange.getExchangeId(), exchange });
        }
        return sync;
    }
}
Also used : UnitOfWork(org.apache.camel.spi.UnitOfWork) AsyncCallback(org.apache.camel.AsyncCallback) ArrayList(java.util.ArrayList)

Example 59 with AsyncCallback

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

the class MulticastProcessor method doProcessSequential.

private boolean doProcessSequential(final Exchange original, final AtomicExchange result, final Iterable<ProcessorExchangePair> pairs, final Iterator<ProcessorExchangePair> it, final ProcessorExchangePair pair, final AsyncCallback callback, final AtomicInteger total) {
    boolean sync = true;
    final Exchange exchange = pair.getExchange();
    Processor processor = pair.getProcessor();
    final Producer producer = pair.getProducer();
    TracedRouteNodes traced = exchange.getUnitOfWork() != null ? exchange.getUnitOfWork().getTracedRouteNodes() : null;
    // compute time taken if sending to another endpoint
    final StopWatch watch = producer != null ? new StopWatch() : null;
    try {
        // prepare tracing starting from a new block
        if (traced != null) {
            traced.pushBlock();
        }
        if (producer != null) {
            EventHelper.notifyExchangeSending(exchange.getContext(), exchange, producer.getEndpoint());
        }
        // let the prepared process it, remember to begin the exchange pair
        AsyncProcessor async = AsyncProcessorConverterHelper.convert(processor);
        pair.begin();
        sync = async.process(exchange, new AsyncCallback() {

            public void done(boolean doneSync) {
                // we are done with the exchange pair
                pair.done();
                // okay we are done, so notify the exchange was sent
                if (producer != null) {
                    long timeTaken = watch.stop();
                    Endpoint endpoint = producer.getEndpoint();
                    // emit event that the exchange was sent to the endpoint
                    EventHelper.notifyExchangeSent(exchange.getContext(), exchange, endpoint, timeTaken);
                }
                // we only have to handle async completion of the routing slip
                if (doneSync) {
                    return;
                }
                // continue processing the multicast asynchronously
                Exchange subExchange = exchange;
                // Decide whether to continue with the multicast or not; similar logic to the Pipeline
                // remember to test for stop on exception and aggregate before copying back results
                boolean continueProcessing = PipelineHelper.continueProcessing(subExchange, "Sequential processing failed for number " + total.get(), LOG);
                if (stopOnException && !continueProcessing) {
                    if (subExchange.getException() != null) {
                        // wrap in exception to explain where it failed
                        subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, subExchange.getException()));
                    } else {
                        // we want to stop on exception, and the exception was handled by the error handler
                        // this is similar to what the pipeline does, so we should do the same to not surprise end users
                        // so we should set the failed exchange as the result and be done
                        result.set(subExchange);
                    }
                    // and do the done work
                    doDone(original, subExchange, pairs, callback, false, true);
                    return;
                }
                try {
                    if (parallelAggregate) {
                        doAggregateInternal(getAggregationStrategy(subExchange), result, subExchange);
                    } else {
                        doAggregate(getAggregationStrategy(subExchange), result, subExchange);
                    }
                } catch (Throwable e) {
                    // wrap in exception to explain where it failed
                    subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, e));
                    // and do the done work
                    doDone(original, subExchange, pairs, callback, false, true);
                    return;
                }
                total.incrementAndGet();
                // maybe there are more processors to multicast
                while (it.hasNext()) {
                    // prepare and run the next
                    ProcessorExchangePair pair = it.next();
                    subExchange = pair.getExchange();
                    updateNewExchange(subExchange, total.get(), pairs, it);
                    boolean sync = doProcessSequential(original, result, pairs, it, pair, callback, total);
                    if (!sync) {
                        LOG.trace("Processing exchangeId: {} is continued being processed asynchronously", original.getExchangeId());
                        return;
                    }
                    // Decide whether to continue with the multicast or not; similar logic to the Pipeline
                    // remember to test for stop on exception and aggregate before copying back results
                    continueProcessing = PipelineHelper.continueProcessing(subExchange, "Sequential processing failed for number " + total.get(), LOG);
                    if (stopOnException && !continueProcessing) {
                        if (subExchange.getException() != null) {
                            // wrap in exception to explain where it failed
                            subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, subExchange.getException()));
                        } else {
                            // we want to stop on exception, and the exception was handled by the error handler
                            // this is similar to what the pipeline does, so we should do the same to not surprise end users
                            // so we should set the failed exchange as the result and be done
                            result.set(subExchange);
                        }
                        // and do the done work
                        doDone(original, subExchange, pairs, callback, false, true);
                        return;
                    }
                    // must catch any exceptions from aggregation
                    try {
                        if (parallelAggregate) {
                            doAggregateInternal(getAggregationStrategy(subExchange), result, subExchange);
                        } else {
                            doAggregate(getAggregationStrategy(subExchange), result, subExchange);
                        }
                    } catch (Throwable e) {
                        // wrap in exception to explain where it failed
                        subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, e));
                        // and do the done work
                        doDone(original, subExchange, pairs, callback, false, true);
                        return;
                    }
                    total.incrementAndGet();
                }
                // do the done work
                subExchange = result.get() != null ? result.get() : null;
                doDone(original, subExchange, pairs, callback, false, true);
            }
        });
    } finally {
        // pop the block so by next round we have the same staring point and thus the tracing looks accurate
        if (traced != null) {
            traced.popBlock();
        }
    }
    return sync;
}
Also used : CamelExchangeException(org.apache.camel.CamelExchangeException) AsyncProcessor(org.apache.camel.AsyncProcessor) Processor(org.apache.camel.Processor) AsyncCallback(org.apache.camel.AsyncCallback) StopWatch(org.apache.camel.util.StopWatch) AtomicExchange(org.apache.camel.util.concurrent.AtomicExchange) Exchange(org.apache.camel.Exchange) Producer(org.apache.camel.Producer) Endpoint(org.apache.camel.Endpoint) AsyncProcessor(org.apache.camel.AsyncProcessor) TracedRouteNodes(org.apache.camel.spi.TracedRouteNodes)

Example 60 with AsyncCallback

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

the class Enricher method process.

/**
     * Enriches the input data (<code>exchange</code>) by first obtaining
     * additional data from an endpoint represented by an endpoint
     * <code>producer</code> and second by aggregating input data and additional
     * data. Aggregation of input data and additional data is delegated to an
     * {@link AggregationStrategy} object set at construction time. If the
     * message exchange with the resource endpoint fails then no aggregation
     * will be done and the failed exchange content is copied over to the
     * original message exchange.
     *
     * @param exchange input data.
     */
public boolean process(final Exchange exchange, final AsyncCallback callback) {
    // which producer to use
    final Producer producer;
    final Endpoint endpoint;
    // use dynamic endpoint so calculate the endpoint to use
    Object recipient = null;
    try {
        recipient = expression.evaluate(exchange, Object.class);
        endpoint = resolveEndpoint(exchange, recipient);
        // acquire the consumer from the cache
        producer = producerCache.acquireProducer(endpoint);
    } catch (Throwable e) {
        if (isIgnoreInvalidEndpoint()) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Endpoint uri is invalid: " + recipient + ". This exception will be ignored.", e);
            }
        } else {
            exchange.setException(e);
        }
        callback.done(true);
        return true;
    }
    final Exchange resourceExchange = createResourceExchange(exchange, ExchangePattern.InOut);
    final Endpoint destination = producer.getEndpoint();
    EventHelper.notifyExchangeSending(exchange.getContext(), resourceExchange, destination);
    // record timing for sending the exchange using the producer
    final StopWatch watch = new StopWatch();
    AsyncProcessor ap = AsyncProcessorConverterHelper.convert(producer);
    boolean sync = ap.process(resourceExchange, new AsyncCallback() {

        public void done(boolean doneSync) {
            // we only have to handle async completion of the routing slip
            if (doneSync) {
                return;
            }
            // emit event that the exchange was sent to the endpoint
            long timeTaken = watch.stop();
            EventHelper.notifyExchangeSent(resourceExchange.getContext(), resourceExchange, destination, timeTaken);
            if (!isAggregateOnException() && resourceExchange.isFailed()) {
                // copy resource exchange onto original exchange (preserving pattern)
                copyResultsPreservePattern(exchange, resourceExchange);
            } else {
                prepareResult(exchange);
                try {
                    // prepare the exchanges for aggregation
                    ExchangeHelper.prepareAggregation(exchange, resourceExchange);
                    Exchange aggregatedExchange = aggregationStrategy.aggregate(exchange, resourceExchange);
                    if (aggregatedExchange != null) {
                        // copy aggregation result onto original exchange (preserving pattern)
                        copyResultsPreservePattern(exchange, aggregatedExchange);
                    }
                } catch (Throwable e) {
                    // if the aggregationStrategy threw an exception, set it on the original exchange
                    exchange.setException(new CamelExchangeException("Error occurred during aggregation", exchange, e));
                    callback.done(false);
                    // we failed so break out now
                    return;
                }
            }
            // set property with the uri of the endpoint enriched so we can use that for tracing etc
            exchange.setProperty(Exchange.TO_ENDPOINT, producer.getEndpoint().getEndpointUri());
            // return the producer back to the cache
            try {
                producerCache.releaseProducer(endpoint, producer);
            } catch (Exception e) {
            // ignore
            }
            callback.done(false);
        }
    });
    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());
    // emit event that the exchange was sent to the endpoint
    long timeTaken = watch.stop();
    EventHelper.notifyExchangeSent(resourceExchange.getContext(), resourceExchange, destination, timeTaken);
    if (!isAggregateOnException() && resourceExchange.isFailed()) {
        // copy resource exchange onto original exchange (preserving pattern)
        copyResultsPreservePattern(exchange, resourceExchange);
    } else {
        prepareResult(exchange);
        try {
            // prepare the exchanges for aggregation
            ExchangeHelper.prepareAggregation(exchange, resourceExchange);
            Exchange aggregatedExchange = aggregationStrategy.aggregate(exchange, resourceExchange);
            if (aggregatedExchange != null) {
                // copy aggregation result onto original exchange (preserving pattern)
                copyResultsPreservePattern(exchange, aggregatedExchange);
            }
        } catch (Throwable e) {
            // if the aggregationStrategy threw an exception, set it on the original exchange
            exchange.setException(new CamelExchangeException("Error occurred during aggregation", exchange, e));
            callback.done(true);
            // we failed so break out now
            return true;
        }
    }
    // set property with the uri of the endpoint enriched so we can use that for tracing etc
    exchange.setProperty(Exchange.TO_ENDPOINT, producer.getEndpoint().getEndpointUri());
    // return the producer back to the cache
    try {
        producerCache.releaseProducer(endpoint, producer);
    } catch (Exception e) {
    // ignore
    }
    callback.done(true);
    return true;
}
Also used : Exchange(org.apache.camel.Exchange) DefaultExchange(org.apache.camel.impl.DefaultExchange) CamelExchangeException(org.apache.camel.CamelExchangeException) Producer(org.apache.camel.Producer) Endpoint(org.apache.camel.Endpoint) AsyncProcessor(org.apache.camel.AsyncProcessor) AsyncCallback(org.apache.camel.AsyncCallback) CamelExchangeException(org.apache.camel.CamelExchangeException) StopWatch(org.apache.camel.util.StopWatch)

Aggregations

AsyncCallback (org.apache.camel.AsyncCallback)67 Exchange (org.apache.camel.Exchange)47 AsyncProcessor (org.apache.camel.AsyncProcessor)12 CamelExchangeException (org.apache.camel.CamelExchangeException)8 Message (org.apache.camel.Message)5 Processor (org.apache.camel.Processor)5 CountDownLatch (java.util.concurrent.CountDownLatch)4 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)4 Endpoint (org.apache.camel.Endpoint)4 Producer (org.apache.camel.Producer)4 Synchronization (org.apache.camel.spi.Synchronization)4 StopWatch (org.apache.camel.util.StopWatch)4 InetSocketAddress (java.net.InetSocketAddress)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ExchangePattern (org.apache.camel.ExchangePattern)3 ChannelHandler (io.netty.channel.ChannelHandler)2 IOException (java.io.IOException)2 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 ConnectException (java.net.ConnectException)2