Search in sources :

Example 11 with UnitOfWork

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;
}
Also used : UnitOfWork(org.apache.camel.spi.UnitOfWork)

Example 12 with UnitOfWork

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;
    }
}
Also used : UnitOfWork(org.apache.camel.spi.UnitOfWork) AsyncCallback(org.apache.camel.AsyncCallback) ArrayList(java.util.ArrayList)

Example 13 with UnitOfWork

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;
}
Also used : UnitOfWork(org.apache.camel.spi.UnitOfWork) RouteContext(org.apache.camel.spi.RouteContext)

Example 14 with UnitOfWork

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;
}
Also used : UnitOfWork(org.apache.camel.spi.UnitOfWork) SubUnitOfWork(org.apache.camel.spi.SubUnitOfWork)

Example 15 with UnitOfWork

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

Aggregations

UnitOfWork (org.apache.camel.spi.UnitOfWork)16 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)4 AsyncCallback (org.apache.camel.AsyncCallback)3 AsyncProcessor (org.apache.camel.AsyncProcessor)3 Processor (org.apache.camel.Processor)3 Exchange (org.apache.camel.Exchange)2 Message (org.apache.camel.Message)2 DefaultExchange (org.apache.camel.impl.DefaultExchange)2 ArrayList (java.util.ArrayList)1 Channel (org.apache.camel.Channel)1 Consumer (org.apache.camel.Consumer)1 NonManagedService (org.apache.camel.NonManagedService)1 Producer (org.apache.camel.Producer)1 RuntimeCamelCatalog (org.apache.camel.catalog.RuntimeCamelCatalog)1 ConsumerCache (org.apache.camel.impl.ConsumerCache)1 DefaultEndpointRegistry (org.apache.camel.impl.DefaultEndpointRegistry)1 DefaultTransformerRegistry (org.apache.camel.impl.DefaultTransformerRegistry)1 DefaultUnitOfWork (org.apache.camel.impl.DefaultUnitOfWork)1 DefaultValidatorRegistry (org.apache.camel.impl.DefaultValidatorRegistry)1 ProducerCache (org.apache.camel.impl.ProducerCache)1