use of org.apache.camel.model.OnCompletionDefinition in project camel by apache.
the class TraceInterceptor method process.
@Override
public boolean process(final Exchange exchange, final AsyncCallback callback) {
// do not trace if tracing is disabled
if (!tracer.isEnabled() || (routeContext != null && !routeContext.isTracing())) {
return processor.process(exchange, callback);
}
// logging TraceEvents to avoid infinite looping
if (exchange.getProperty(Exchange.TRACE_EVENT, false, Boolean.class)) {
// but we must still process to allow routing of TraceEvents to eg a JPA endpoint
return processor.process(exchange, callback);
}
final boolean shouldLog = shouldLogNode(node) && shouldLogExchange(exchange);
// whether we should trace it or not, some nodes should be skipped as they are abstract
// intermediate steps for instance related to on completion
boolean trace = true;
boolean sync = true;
// okay this is a regular exchange being routed we might need to log and trace
try {
// before
if (shouldLog) {
// traced holds the information about the current traced route path
if (exchange.getUnitOfWork() != null) {
TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
if (node instanceof OnCompletionDefinition || node instanceof OnExceptionDefinition) {
// skip any of these as its just a marker definition
trace = false;
} else if (ProcessorDefinitionHelper.isFirstChildOfType(OnCompletionDefinition.class, node)) {
// special for on completion tracing
traceOnCompletion(traced, exchange);
} else if (ProcessorDefinitionHelper.isFirstChildOfType(OnExceptionDefinition.class, node)) {
// special for on exception
traceOnException(traced, exchange);
} else if (ProcessorDefinitionHelper.isFirstChildOfType(CatchDefinition.class, node)) {
// special for do catch
traceDoCatch(traced, exchange);
} else if (ProcessorDefinitionHelper.isFirstChildOfType(FinallyDefinition.class, node)) {
// special for do finally
traceDoFinally(traced, exchange);
} else if (ProcessorDefinitionHelper.isFirstChildOfType(AggregateDefinition.class, node)) {
// special for aggregate
traceAggregate(traced, exchange);
} else {
// regular so just add it
traced.addTraced(new DefaultRouteNode(node, super.getProcessor()));
}
} else {
LOG.trace("Cannot trace as this Exchange does not have an UnitOfWork: {}", exchange);
}
}
// log and trace the processor
Object state = null;
if (shouldLog && trace) {
logExchange(exchange);
// either call the in or generic trace method depending on OUT has been enabled or not
if (tracer.isTraceOutExchanges()) {
state = traceExchangeIn(exchange);
} else {
traceExchange(exchange);
}
}
final Object traceState = state;
// special for interceptor where we need to keep booking how far we have routed in the intercepted processors
if (node.getParent() instanceof InterceptDefinition && exchange.getUnitOfWork() != null) {
TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
traceIntercept((InterceptDefinition) node.getParent(), traced, exchange);
}
// process the exchange
sync = processor.process(exchange, new AsyncCallback() {
@Override
public void done(boolean doneSync) {
try {
// after (trace out)
if (shouldLog && tracer.isTraceOutExchanges()) {
logExchange(exchange);
traceExchangeOut(exchange, traceState);
}
} catch (Throwable e) {
// some exception occurred in trace logic
if (shouldLogException(exchange)) {
logException(exchange, e);
}
exchange.setException(e);
} finally {
// ensure callback is always invoked
callback.done(doneSync);
}
}
});
} catch (Throwable e) {
// some exception occurred in trace logic
if (shouldLogException(exchange)) {
logException(exchange, e);
}
exchange.setException(e);
}
return sync;
}
Aggregations