use of org.apache.camel.spi.InterceptStrategy in project camel by apache.
the class ProcessorDefinition method addInterceptStrategies.
/**
* Adds the given list of interceptors to the channel.
*
* @param routeContext the route context
* @param channel the channel to add strategies
* @param strategies list of strategies to add.
*/
protected void addInterceptStrategies(RouteContext routeContext, Channel channel, List<InterceptStrategy> strategies) {
for (InterceptStrategy strategy : strategies) {
if (!routeContext.isStreamCaching() && strategy instanceof StreamCaching) {
// stream cache is disabled so we should not add it
continue;
}
if (!routeContext.isHandleFault() && strategy instanceof HandleFault) {
// handle fault is disabled so we should not add it
continue;
}
if (strategy instanceof Delayer) {
if (routeContext.getDelayer() == null || routeContext.getDelayer() <= 0) {
// delayer is disabled so we should not add it
continue;
} else {
// replace existing delayer as delayer have individual configuration
Iterator<InterceptStrategy> it = channel.getInterceptStrategies().iterator();
while (it.hasNext()) {
InterceptStrategy existing = it.next();
if (existing instanceof Delayer) {
it.remove();
}
}
// add the new correct delayer
channel.addInterceptStrategy(strategy);
continue;
}
}
// add strategy
channel.addInterceptStrategy(strategy);
}
}
use of org.apache.camel.spi.InterceptStrategy in project camel by apache.
the class DefaultChannel method initChannel.
@SuppressWarnings("deprecation")
public void initChannel(ProcessorDefinition<?> outputDefinition, RouteContext routeContext) throws Exception {
this.routeContext = routeContext;
this.definition = outputDefinition;
this.camelContext = routeContext.getCamelContext();
Processor target = nextProcessor;
Processor next;
// init CamelContextAware as early as possible on target
if (target instanceof CamelContextAware) {
((CamelContextAware) target).setCamelContext(camelContext);
}
// the definition to wrap should be the fine grained,
// so if a child is set then use it, if not then its the original output used
ProcessorDefinition<?> targetOutputDef = childDefinition != null ? childDefinition : outputDefinition;
LOG.debug("Initialize channel for target: '{}'", targetOutputDef);
// ideally we need the design time route -> runtime route to be a 2-phase pass (scheduled work for Camel 3.0)
if (childDefinition != null && outputDefinition != childDefinition) {
childDefinition.setParent(outputDefinition);
}
// force the creation of an id
RouteDefinitionHelper.forceAssignIds(routeContext.getCamelContext(), definition);
// first wrap the output with the managed strategy if any
InterceptStrategy managed = routeContext.getManagedInterceptStrategy();
if (managed != null) {
next = target == nextProcessor ? null : nextProcessor;
target = managed.wrapProcessorInInterceptors(routeContext.getCamelContext(), targetOutputDef, target, next);
}
// then wrap the output with the backlog and tracer (backlog first, as we do not want regular tracer to tracer the backlog)
InterceptStrategy tracer = getOrCreateBacklogTracer();
camelContext.addService(tracer);
if (tracer instanceof BacklogTracer) {
BacklogTracer backlogTracer = (BacklogTracer) tracer;
RouteDefinition route = ProcessorDefinitionHelper.getRoute(definition);
boolean first = false;
if (route != null && !route.getOutputs().isEmpty()) {
first = route.getOutputs().get(0) == definition;
}
addAdvice(new BacklogTracerAdvice(backlogTracer, targetOutputDef, route, first));
// add debugger as well so we have both tracing and debugging out of the box
InterceptStrategy debugger = getOrCreateBacklogDebugger();
camelContext.addService(debugger);
if (debugger instanceof BacklogDebugger) {
BacklogDebugger backlogDebugger = (BacklogDebugger) debugger;
addAdvice(new BacklogDebuggerAdvice(backlogDebugger, target, targetOutputDef));
}
}
if (routeContext.isMessageHistory()) {
// add message history advice
MessageHistoryFactory factory = camelContext.getMessageHistoryFactory();
addAdvice(new MessageHistoryAdvice(factory, targetOutputDef));
}
// the regular tracer is not a task on internalProcessor as this is not really needed
// end users have to explicit enable the tracer to use it, and then its okay if we wrap
// the processors (but by default tracer is disabled, and therefore we do not wrap processors)
tracer = getOrCreateTracer();
camelContext.addService(tracer);
if (tracer != null) {
TraceInterceptor trace = (TraceInterceptor) tracer.wrapProcessorInInterceptors(routeContext.getCamelContext(), targetOutputDef, target, null);
// trace interceptor need to have a reference to route context so we at runtime can enable/disable tracing on-the-fly
trace.setRouteContext(routeContext);
target = trace;
}
// sort interceptors according to ordered
interceptors.sort(new OrderedComparator());
// then reverse list so the first will be wrapped last, as it would then be first being invoked
Collections.reverse(interceptors);
// wrap the output with the configured interceptors
for (InterceptStrategy strategy : interceptors) {
next = target == nextProcessor ? null : nextProcessor;
// skip tracer as we did the specially beforehand and it could potentially be added as an interceptor strategy
if (strategy instanceof Tracer) {
continue;
}
// skip stream caching as it must be wrapped as outer most, which we do later
if (strategy instanceof StreamCaching) {
continue;
}
// use the fine grained definition (eg the child if available). Its always possible to get back to the parent
Processor wrapped = strategy.wrapProcessorInInterceptors(routeContext.getCamelContext(), targetOutputDef, target, next);
if (!(wrapped instanceof AsyncProcessor)) {
LOG.warn("Interceptor: " + strategy + " at: " + outputDefinition + " does not return an AsyncProcessor instance." + " This causes the asynchronous routing engine to not work as optimal as possible." + " See more details at the InterceptStrategy javadoc." + " Camel will use a bridge to adapt the interceptor to the asynchronous routing engine," + " but its not the most optimal solution. Please consider changing your interceptor to comply.");
// use a bridge and wrap again which allows us to adapt and leverage the asynchronous routing engine anyway
// however its not the most optimal solution, but we can still run.
InterceptorToAsyncProcessorBridge bridge = new InterceptorToAsyncProcessorBridge(target);
wrapped = strategy.wrapProcessorInInterceptors(routeContext.getCamelContext(), targetOutputDef, bridge, next);
// Avoid the stack overflow
if (!wrapped.equals(bridge)) {
bridge.setTarget(wrapped);
} else {
// Just skip the wrapped processor
bridge.setTarget(null);
}
wrapped = bridge;
}
if (!(wrapped instanceof WrapProcessor)) {
// wrap the target so it becomes a service and we can manage its lifecycle
wrapped = new WrapProcessor(wrapped, target);
}
target = wrapped;
}
if (routeContext.isStreamCaching()) {
addAdvice(new StreamCachingAdvice(camelContext.getStreamCachingStrategy()));
}
if (routeContext.getDelayer() != null && routeContext.getDelayer() > 0) {
addAdvice(new DelayerAdvice(routeContext.getDelayer()));
}
// sets the delegate to our wrapped output
output = target;
}
use of org.apache.camel.spi.InterceptStrategy in project camel by apache.
the class DefaultChannel method getOrCreateTracer.
private InterceptStrategy getOrCreateTracer() {
// only use tracer if explicit enabled
if (camelContext.isTracing() != null && !camelContext.isTracing()) {
return null;
}
InterceptStrategy tracer = Tracer.getTracer(camelContext);
if (tracer == null) {
if (camelContext.getRegistry() != null) {
// lookup in registry
Map<String, Tracer> map = camelContext.getRegistry().findByTypeWithName(Tracer.class);
if (map.size() == 1) {
tracer = map.values().iterator().next();
}
}
if (tracer == null) {
// fallback to use the default tracer
tracer = camelContext.getDefaultTracer();
// configure and use any trace formatter if any exists
Map<String, TraceFormatter> formatters = camelContext.getRegistry().findByTypeWithName(TraceFormatter.class);
if (formatters.size() == 1) {
TraceFormatter formatter = formatters.values().iterator().next();
if (tracer instanceof Tracer) {
((Tracer) tracer).setFormatter(formatter);
}
}
}
}
return tracer;
}
use of org.apache.camel.spi.InterceptStrategy in project camel by apache.
the class AbstractCamelContextFactoryBean method afterPropertiesSet.
public void afterPropertiesSet() throws Exception {
if (ObjectHelper.isEmpty(getId())) {
throw new IllegalArgumentException("Id must be set");
}
// set the package scan resolver as soon as possible
PackageScanClassResolver packageResolver = getBeanForType(PackageScanClassResolver.class);
if (packageResolver != null) {
LOG.info("Using custom PackageScanClassResolver: {}", packageResolver);
getContext().setPackageScanClassResolver(packageResolver);
}
// then set custom properties
Map<String, String> mergedOptions = new HashMap<>();
if (getProperties() != null) {
mergedOptions.putAll(getProperties().asMap());
}
if (getGlobalOptions() != null) {
mergedOptions.putAll(getGlobalOptions().asMap());
}
getContext().setGlobalOptions(mergedOptions);
// and enable lazy loading of type converters if applicable
initLazyLoadTypeConverters();
setupCustomServices();
// set the custom registry if defined
initCustomRegistry(getContext());
// setup property placeholder so we got it as early as possible
initPropertyPlaceholder();
// setup JMX agent at first
initJMXAgent();
Tracer tracer = getBeanForType(Tracer.class);
if (tracer != null) {
// use formatter if there is a TraceFormatter bean defined
TraceFormatter formatter = getBeanForType(TraceFormatter.class);
if (formatter != null) {
tracer.setFormatter(formatter);
}
LOG.info("Using custom Tracer: {}", tracer);
getContext().addInterceptStrategy(tracer);
}
BacklogTracer backlogTracer = getBeanForType(BacklogTracer.class);
if (backlogTracer != null) {
LOG.info("Using custom BacklogTracer: {}", backlogTracer);
getContext().addInterceptStrategy(backlogTracer);
}
HandleFault handleFault = getBeanForType(HandleFault.class);
if (handleFault != null) {
LOG.info("Using custom HandleFault: {}", handleFault);
getContext().addInterceptStrategy(handleFault);
}
@SuppressWarnings("deprecation") org.apache.camel.processor.interceptor.Delayer delayer = getBeanForType(org.apache.camel.processor.interceptor.Delayer.class);
if (delayer != null) {
LOG.info("Using custom Delayer: {}", delayer);
getContext().addInterceptStrategy(delayer);
}
InflightRepository inflightRepository = getBeanForType(InflightRepository.class);
if (inflightRepository != null) {
LOG.info("Using custom InflightRepository: {}", inflightRepository);
getContext().setInflightRepository(inflightRepository);
}
AsyncProcessorAwaitManager asyncProcessorAwaitManager = getBeanForType(AsyncProcessorAwaitManager.class);
if (asyncProcessorAwaitManager != null) {
LOG.info("Using custom AsyncProcessorAwaitManager: {}", asyncProcessorAwaitManager);
getContext().setAsyncProcessorAwaitManager(asyncProcessorAwaitManager);
}
ManagementStrategy managementStrategy = getBeanForType(ManagementStrategy.class);
if (managementStrategy != null) {
LOG.info("Using custom ManagementStrategy: {}", managementStrategy);
getContext().setManagementStrategy(managementStrategy);
}
ManagementNamingStrategy managementNamingStrategy = getBeanForType(ManagementNamingStrategy.class);
if (managementNamingStrategy != null) {
LOG.info("Using custom ManagementNamingStrategy: {}", managementNamingStrategy);
getContext().getManagementStrategy().setManagementNamingStrategy(managementNamingStrategy);
}
EventFactory eventFactory = getBeanForType(EventFactory.class);
if (eventFactory != null) {
LOG.info("Using custom EventFactory: {}", eventFactory);
getContext().getManagementStrategy().setEventFactory(eventFactory);
}
UnitOfWorkFactory unitOfWorkFactory = getBeanForType(UnitOfWorkFactory.class);
if (unitOfWorkFactory != null) {
LOG.info("Using custom UnitOfWorkFactory: {}", unitOfWorkFactory);
getContext().setUnitOfWorkFactory(unitOfWorkFactory);
}
RuntimeEndpointRegistry runtimeEndpointRegistry = getBeanForType(RuntimeEndpointRegistry.class);
if (runtimeEndpointRegistry != null) {
LOG.info("Using custom RuntimeEndpointRegistry: {}", runtimeEndpointRegistry);
getContext().setRuntimeEndpointRegistry(runtimeEndpointRegistry);
}
// custom type converters defined as <bean>s
Map<String, TypeConverters> typeConverters = getContext().getRegistry().findByTypeWithName(TypeConverters.class);
if (typeConverters != null && !typeConverters.isEmpty()) {
for (Entry<String, TypeConverters> entry : typeConverters.entrySet()) {
TypeConverters converter = entry.getValue();
LOG.info("Adding custom TypeConverters with id: {} and implementation: {}", entry.getKey(), converter);
getContext().getTypeConverterRegistry().addTypeConverters(converter);
}
}
// set the event notifier strategies if defined
Map<String, EventNotifier> eventNotifiers = getContext().getRegistry().findByTypeWithName(EventNotifier.class);
if (eventNotifiers != null && !eventNotifiers.isEmpty()) {
for (Entry<String, EventNotifier> entry : eventNotifiers.entrySet()) {
EventNotifier notifier = entry.getValue();
// do not add if already added, for instance a tracer that is also an InterceptStrategy class
if (!getContext().getManagementStrategy().getEventNotifiers().contains(notifier)) {
LOG.info("Using custom EventNotifier with id: {} and implementation: {}", entry.getKey(), notifier);
getContext().getManagementStrategy().addEventNotifier(notifier);
}
}
}
// set endpoint strategies if defined
Map<String, EndpointStrategy> endpointStrategies = getContext().getRegistry().findByTypeWithName(EndpointStrategy.class);
if (endpointStrategies != null && !endpointStrategies.isEmpty()) {
for (Entry<String, EndpointStrategy> entry : endpointStrategies.entrySet()) {
EndpointStrategy strategy = entry.getValue();
LOG.info("Using custom EndpointStrategy with id: {} and implementation: {}", entry.getKey(), strategy);
getContext().addRegisterEndpointCallback(strategy);
}
}
// shutdown
ShutdownStrategy shutdownStrategy = getBeanForType(ShutdownStrategy.class);
if (shutdownStrategy != null) {
LOG.info("Using custom ShutdownStrategy: " + shutdownStrategy);
getContext().setShutdownStrategy(shutdownStrategy);
}
// add global interceptors
Map<String, InterceptStrategy> interceptStrategies = getContext().getRegistry().findByTypeWithName(InterceptStrategy.class);
if (interceptStrategies != null && !interceptStrategies.isEmpty()) {
for (Entry<String, InterceptStrategy> entry : interceptStrategies.entrySet()) {
InterceptStrategy strategy = entry.getValue();
// do not add if already added, for instance a tracer that is also an InterceptStrategy class
if (!getContext().getInterceptStrategies().contains(strategy)) {
LOG.info("Using custom InterceptStrategy with id: {} and implementation: {}", entry.getKey(), strategy);
getContext().addInterceptStrategy(strategy);
}
}
}
// set the lifecycle strategy if defined
Map<String, LifecycleStrategy> lifecycleStrategies = getContext().getRegistry().findByTypeWithName(LifecycleStrategy.class);
if (lifecycleStrategies != null && !lifecycleStrategies.isEmpty()) {
for (Entry<String, LifecycleStrategy> entry : lifecycleStrategies.entrySet()) {
LifecycleStrategy strategy = entry.getValue();
// do not add if already added, for instance a tracer that is also an InterceptStrategy class
if (!getContext().getLifecycleStrategies().contains(strategy)) {
LOG.info("Using custom LifecycleStrategy with id: {} and implementation: {}", entry.getKey(), strategy);
getContext().addLifecycleStrategy(strategy);
}
}
}
// add route policy factories
Map<String, RoutePolicyFactory> routePolicyFactories = getContext().getRegistry().findByTypeWithName(RoutePolicyFactory.class);
if (routePolicyFactories != null && !routePolicyFactories.isEmpty()) {
for (Entry<String, RoutePolicyFactory> entry : routePolicyFactories.entrySet()) {
RoutePolicyFactory factory = entry.getValue();
LOG.info("Using custom RoutePolicyFactory with id: {} and implementation: {}", entry.getKey(), factory);
getContext().addRoutePolicyFactory(factory);
}
}
// set the default thread pool profile if defined
initThreadPoolProfiles(getContext());
// Set the application context and camelContext for the beanPostProcessor
initBeanPostProcessor(getContext());
// init camel context
initCamelContext(getContext());
// init stream caching strategy
initStreamCachingStrategy();
}
use of org.apache.camel.spi.InterceptStrategy in project camel by apache.
the class InterceptDefinition method createProcessor.
@Override
public Processor createProcessor(final RouteContext routeContext) throws Exception {
// create the output processor
output = this.createChildProcessor(routeContext, true);
// add the output as a intercept strategy to the route context so its invoked on each processing step
routeContext.getInterceptStrategies().add(new InterceptStrategy() {
private Processor interceptedTarget;
public Processor wrapProcessorInInterceptors(CamelContext context, ProcessorDefinition<?> definition, Processor target, Processor nextTarget) throws Exception {
// store the target we are intercepting
this.interceptedTarget = target;
// remember the target that was intercepted
intercepted.add(interceptedTarget);
if (interceptedTarget != null) {
// wrap in a pipeline so we continue routing to the next
List<Processor> list = new ArrayList<Processor>(2);
list.add(output);
list.add(interceptedTarget);
return new Pipeline(context, list);
} else {
return output;
}
}
@Override
public String toString() {
return "intercept[" + (interceptedTarget != null ? interceptedTarget : output) + "]";
}
});
// remove me from the route so I am not invoked in a regular route path
routeContext.getRoute().getOutputs().remove(this);
// and return no processor to invoke next from me
return null;
}
Aggregations