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
}
});
}
}
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;
}
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;
}
}
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;
}
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;
}
Aggregations