use of org.apache.camel.spi.UnitOfWork in project camel by apache.
the class DefaultConsumer method createUoW.
/**
* If the consumer needs to defer done the {@link org.apache.camel.spi.UnitOfWork} on
* the processed {@link Exchange} then this method should be use to create and start
* the {@link UnitOfWork} on the exchange.
*
* @param exchange the exchange
* @return the created and started unit of work
* @throws Exception is thrown if error starting the unit of work
*
* @see #doneUoW(org.apache.camel.Exchange)
*/
public UnitOfWork createUoW(Exchange exchange) throws Exception {
// from this unit of work
if (route != null && exchange.getFromRouteId() == null) {
exchange.setFromRouteId(route.getId());
}
UnitOfWork uow = endpoint.getCamelContext().getUnitOfWorkFactory().createUnitOfWork(exchange);
exchange.setUnitOfWork(uow);
uow.start();
return uow;
}
use of org.apache.camel.spi.UnitOfWork 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.spi.UnitOfWork in project camel by apache.
the class DefaultRuntimeEndpointRegistry method getRouteId.
private String getRouteId(Exchange exchange) {
String answer = null;
UnitOfWork uow = exchange.getUnitOfWork();
RouteContext rc = uow != null ? uow.getRouteContext() : null;
if (rc != null) {
answer = rc.getRoute().getId();
}
if (answer == null) {
// fallback and get from route id on the exchange
answer = exchange.getFromRouteId();
}
return answer;
}
use of org.apache.camel.spi.UnitOfWork in project camel by apache.
the class DefaultUnitOfWork method createChildUnitOfWork.
public UnitOfWork createChildUnitOfWork(Exchange childExchange) {
// create a new child unit of work, and mark me as its parent
UnitOfWork answer = newInstance(childExchange);
answer.setParentUnitOfWork(this);
return answer;
}
use of org.apache.camel.spi.UnitOfWork 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;
}
Aggregations