use of org.apache.camel.Processor in project camel by apache.
the class MulticastProcessor method createProcessorExchangePair.
/**
* Creates the {@link ProcessorExchangePair} which holds the processor and exchange to be send out.
* <p/>
* You <b>must</b> use this method to create the instances of {@link ProcessorExchangePair} as they
* need to be specially prepared before use.
*
* @param index the index
* @param processor the processor
* @param exchange the exchange
* @param routeContext the route context
* @return prepared for use
*/
protected ProcessorExchangePair createProcessorExchangePair(int index, Processor processor, Exchange exchange, RouteContext routeContext) {
Processor prepared = processor;
// set property which endpoint we send to
setToEndpoint(exchange, prepared);
// rework error handling to support fine grained error handling
prepared = createErrorHandler(routeContext, exchange, prepared);
// invoke on prepare on the exchange if specified
if (onPrepare != null) {
try {
onPrepare.process(exchange);
} catch (Exception e) {
exchange.setException(e);
}
}
return new DefaultProcessorExchangePair(index, processor, prepared, exchange);
}
use of org.apache.camel.Processor in project camel by apache.
the class MulticastProcessor method createErrorHandler.
protected Processor createErrorHandler(RouteContext routeContext, Exchange exchange, Processor processor) {
Processor answer;
boolean tryBlock = exchange.getProperty(Exchange.TRY_ROUTE_BLOCK, false, boolean.class);
// do not wrap in error handler if we are inside a try block
if (!tryBlock && routeContext != null) {
// wrap the producer in error handler so we have fine grained error handling on
// the output side instead of the input side
// this is needed to support redelivery on that output alone and not doing redelivery
// for the entire multicast block again which will start from scratch again
// create key for cache
final PreparedErrorHandler key = new PreparedErrorHandler(routeContext, processor);
// lookup cached first to reuse and preserve memory
answer = errorHandlers.get(key);
if (answer != null) {
LOG.trace("Using existing error handler for: {}", processor);
return answer;
}
LOG.trace("Creating error handler for: {}", processor);
ErrorHandlerFactory builder = routeContext.getRoute().getErrorHandlerBuilder();
// instead of using ProcessorDefinition.wrapInErrorHandler)
try {
processor = builder.createErrorHandler(routeContext, processor);
// and wrap in unit of work processor so the copy exchange also can run under UoW
answer = createUnitOfWorkProcessor(routeContext, processor, exchange);
boolean child = exchange.getProperty(Exchange.PARENT_UNIT_OF_WORK, UnitOfWork.class) != null;
// must start the error handler
ServiceHelper.startServices(answer);
// here we don't cache the child unit of work
if (!child) {
// add to cache
errorHandlers.putIfAbsent(key, answer);
}
} catch (Exception e) {
throw ObjectHelper.wrapRuntimeCamelException(e);
}
} else {
// and wrap in unit of work processor so the copy exchange also can run under UoW
answer = createUnitOfWorkProcessor(routeContext, processor, exchange);
}
return answer;
}
use of org.apache.camel.Processor in project camel by apache.
the class MulticastProcessor method doProcessParallel.
private void doProcessParallel(final ProcessorExchangePair pair) throws Exception {
final Exchange exchange = pair.getExchange();
Processor processor = pair.getProcessor();
Producer producer = pair.getProducer();
TracedRouteNodes traced = exchange.getUnitOfWork() != null ? exchange.getUnitOfWork().getTracedRouteNodes() : null;
// compute time taken if sending to another endpoint
StopWatch watch = null;
if (producer != null) {
watch = new StopWatch();
}
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();
// we invoke it synchronously as parallel async routing is too hard
AsyncProcessorHelper.process(async, exchange);
} finally {
pair.done();
// pop the block so by next round we have the same staring point and thus the tracing looks accurate
if (traced != null) {
traced.popBlock();
}
if (producer != null) {
long timeTaken = watch.stop();
Endpoint endpoint = producer.getEndpoint();
// emit event that the exchange was sent to the endpoint
// this is okay to do here in the finally block, as the processing is not using the async routing engine
//( we invoke it synchronously as parallel async routing is too hard)
EventHelper.notifyExchangeSent(exchange.getContext(), exchange, endpoint, timeTaken);
}
}
}
use of org.apache.camel.Processor in project camel by apache.
the class RecipientListProcessor method createProcessorExchangePair.
/**
* This logic is similar to MulticastProcessor but we have to return a RecipientProcessorExchangePair instead
*/
protected ProcessorExchangePair createProcessorExchangePair(int index, Endpoint endpoint, Producer producer, Exchange exchange, ExchangePattern pattern) {
Processor prepared = producer;
// copy exchange, and do not share the unit of work
Exchange copy = ExchangeHelper.createCorrelatedCopy(exchange, false);
// if we share unit of work, we need to prepare the child exchange
if (isShareUnitOfWork()) {
prepareSharedUnitOfWork(copy, exchange);
}
// set property which endpoint we send to
setToEndpoint(copy, prepared);
// rework error handling to support fine grained error handling
RouteContext routeContext = exchange.getUnitOfWork() != null ? exchange.getUnitOfWork().getRouteContext() : null;
prepared = createErrorHandler(routeContext, copy, prepared);
// invoke on prepare on the exchange if specified
if (onPrepare != null) {
try {
onPrepare.process(copy);
} catch (Exception e) {
copy.setException(e);
}
}
// and create the pair
return new RecipientProcessorExchangePair(index, producerCache, endpoint, producer, prepared, copy, pattern);
}
use of org.apache.camel.Processor in project camel by apache.
the class RedeliveryErrorHandler method handleException.
protected void handleException(Exchange exchange, RedeliveryData data, boolean isDeadLetterChannel) {
Exception e = exchange.getException();
// store the original caused exception in a property, so we can restore it later
exchange.setProperty(Exchange.EXCEPTION_CAUGHT, e);
// find the error handler to use (if any)
OnExceptionDefinition exceptionPolicy = getExceptionPolicy(exchange, e);
if (exceptionPolicy != null) {
data.currentRedeliveryPolicy = exceptionPolicy.createRedeliveryPolicy(exchange.getContext(), data.currentRedeliveryPolicy);
data.handledPredicate = exceptionPolicy.getHandledPolicy();
data.continuedPredicate = exceptionPolicy.getContinuedPolicy();
data.retryWhilePredicate = exceptionPolicy.getRetryWhilePolicy();
data.useOriginalInMessage = exceptionPolicy.getUseOriginalMessagePolicy() != null && exceptionPolicy.getUseOriginalMessagePolicy();
// route specific failure handler?
Processor processor = null;
UnitOfWork uow = exchange.getUnitOfWork();
if (uow != null && uow.getRouteContext() != null) {
String routeId = uow.getRouteContext().getRoute().getId();
processor = exceptionPolicy.getErrorHandler(routeId);
} else if (!exceptionPolicy.getErrorHandlers().isEmpty()) {
// note this should really not happen, but we have this code as a fail safe
// to be backwards compatible with the old behavior
log.warn("Cannot determine current route from Exchange with id: {}, will fallback and use first error handler.", exchange.getExchangeId());
processor = exceptionPolicy.getErrorHandlers().iterator().next();
}
if (processor != null) {
data.failureProcessor = processor;
}
// route specific on redelivery?
processor = exceptionPolicy.getOnRedelivery();
if (processor != null) {
data.onRedeliveryProcessor = processor;
}
// route specific on exception occurred?
processor = exceptionPolicy.getOnExceptionOccurred();
if (processor != null) {
data.onExceptionProcessor = processor;
}
}
// only log if not failure handled or not an exhausted unit of work
if (!ExchangeHelper.isFailureHandled(exchange) && !ExchangeHelper.isUnitOfWorkExhausted(exchange)) {
String msg = "Failed delivery for " + ExchangeHelper.logIds(exchange) + ". On delivery attempt: " + data.redeliveryCounter + " caught: " + e;
logFailedDelivery(true, false, false, false, isDeadLetterChannel, exchange, msg, data, e);
}
data.redeliveryCounter = incrementRedeliveryCounter(exchange, e, data);
}
Aggregations