All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.camel.impl.engine.DefaultRouteContext Maven / Gradle / Ivy

There is a newer version: 4.9.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.camel.impl.engine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.ErrorHandlerFactory;
import org.apache.camel.NamedNode;
import org.apache.camel.NoSuchEndpointException;
import org.apache.camel.Processor;
import org.apache.camel.Route;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.ShutdownRoute;
import org.apache.camel.ShutdownRunningTask;
import org.apache.camel.processor.CamelInternalProcessor;
import org.apache.camel.processor.Pipeline;
import org.apache.camel.spi.CamelInternalProcessorAdvice;
import org.apache.camel.spi.InterceptStrategy;
import org.apache.camel.spi.ManagementInterceptStrategy;
import org.apache.camel.spi.RouteContext;
import org.apache.camel.spi.RouteController;
import org.apache.camel.spi.RouteError;
import org.apache.camel.spi.RoutePolicy;
import org.apache.camel.support.CamelContextHelper;
import org.apache.camel.util.ObjectHelper;

/**
 * The context used to activate new routing rules
 */
public class DefaultRouteContext implements RouteContext {
    private NamedNode route;
    private String routeId;
    private Route runtimeRoute;
    private Endpoint endpoint;
    private final List eventDrivenProcessors = new ArrayList<>();
    private CamelContext camelContext;
    private List interceptStrategies = new ArrayList<>();
    private ManagementInterceptStrategy managementInterceptStrategy;
    private boolean routeAdded;
    private Boolean trace;
    private Boolean backlogTrace;
    private Boolean debug;
    private Boolean messageHistory;
    private Boolean logMask;
    private Boolean logExhaustedMessageBody;
    private Boolean streamCache;
    private Long delay;
    private Boolean autoStartup = Boolean.TRUE;
    private List routePolicyList = new ArrayList<>();
    private ShutdownRoute shutdownRoute;
    private ShutdownRunningTask shutdownRunningTask;
    private RouteError routeError;
    private RouteController routeController;
    private final Map onCompletions = new HashMap<>();
    private final Map onExceptions = new HashMap<>();
    private final List> advices = new ArrayList<>();
    private final Map properties = new HashMap<>();
    private ErrorHandlerFactory errorHandlerFactory;
    private Integer startupOrder;
    private Map> errorHandlers = new HashMap<>();

    public DefaultRouteContext(CamelContext camelContext, NamedNode route, String routeId) {
        this.camelContext = camelContext;
        this.route = route;
        this.routeId = routeId;
    }

    @Override
    public Endpoint getEndpoint() {
        return endpoint;
    }

    @Override
    public void setEndpoint(Endpoint endpoint) {
        this.endpoint = endpoint;
    }

    @Override
    public NamedNode getRoute() {
        return route;
    }

    @Override
    public String getRouteId() {
        return routeId;
    }

    public Route getRuntimeRoute() {
        return runtimeRoute;
    }

    @Override
    public CamelContext getCamelContext() {
        return camelContext;
    }

    @Override
    public Endpoint resolveEndpoint(String uri) {
        return CamelContextHelper.getMandatoryEndpoint(camelContext, uri);
    }

    @Override
    public Endpoint resolveEndpoint(String uri, String ref) {
        Endpoint endpoint = null;
        if (uri != null) {
            endpoint = camelContext.getEndpoint(uri);
            if (endpoint == null) {
                throw new NoSuchEndpointException(uri);
            }
        }
        if (ref != null) {
            endpoint = lookup(ref, Endpoint.class);
            if (endpoint == null) {
                throw new NoSuchEndpointException("ref:" + ref, "check your camel registry with id " + ref);
            }
            // Check the endpoint has the right CamelContext 
            if (!this.getCamelContext().equals(endpoint.getCamelContext())) {
                throw new NoSuchEndpointException("ref:" + ref, "make sure the endpoint has the same camel context as the route does.");
            }
            try {
                // need add the endpoint into service
                getCamelContext().addService(endpoint);
            } catch (Exception ex) {
                throw new RuntimeCamelException(ex);
            }
        }
        if (endpoint == null) {
            throw new IllegalArgumentException("Either 'uri' or 'ref' must be specified on: " + this);
        } else {
            return endpoint;
        }
    }

    @Override
    public  T lookup(String name, Class type) {
        return getCamelContext().getRegistry().lookupByNameAndType(name, type);
    }

    @Override
    public  Map lookupByType(Class type) {
        return getCamelContext().getRegistry().findByTypeWithName(type);
    }

    @Override
    public  T mandatoryLookup(String name, Class type) {
        return CamelContextHelper.mandatoryLookup(getCamelContext(), name, type);
    }

    @Override
    public Route commit() {
        // now lets turn all of the event driven consumer processors into a single route
        if (!eventDrivenProcessors.isEmpty()) {
            // always use an pipeline even if there are only 1 processor as the pipeline
            // handles preparing the response from the exchange in regard to IN vs OUT messages etc
            Processor target = new Pipeline(getCamelContext(), eventDrivenProcessors);

            // and wrap it in a unit of work so the UoW is on the top, so the entire route will be in the same UoW
            CamelInternalProcessor internal = new CamelInternalProcessor(target);
            internal.addAdvice(new CamelInternalProcessor.UnitOfWorkProcessorAdvice(this));

            // and then optionally add route policy processor if a custom policy is set
            List routePolicyList = getRoutePolicyList();
            if (routePolicyList != null && !routePolicyList.isEmpty()) {
                for (RoutePolicy policy : routePolicyList) {
                    // add policy as service if we have not already done that (eg possible if two routes have the same service)
                    // this ensures Camel can control the lifecycle of the policy
                    if (!camelContext.hasService(policy)) {
                        try {
                            camelContext.addService(policy);
                        } catch (Exception e) {
                            throw RuntimeCamelException.wrapRuntimeCamelException(e);
                        }
                    }
                }

                internal.addAdvice(new CamelInternalProcessor.RoutePolicyAdvice(routePolicyList));
            }

            // wrap in route inflight processor to track number of inflight exchanges for the route
            internal.addAdvice(new CamelInternalProcessor.RouteInflightRepositoryAdvice(camelContext.getInflightRepository(), routeId));

            // wrap in JMX instrumentation processor that is used for performance stats
            if (managementInterceptStrategy != null) {
                internal.addAdvice(CamelInternalProcessor.wrap(managementInterceptStrategy.createProcessor("route")));
            }

            // wrap in route lifecycle
            internal.addAdvice(new CamelInternalProcessor.RouteLifecycleAdvice());

            // wrap in REST binding
            advices.forEach(internal::addAdvice);

            // and create the route that wraps the UoW
            Route edcr = new EventDrivenConsumerRoute(this, getEndpoint(), internal);
            edcr.getProperties().putAll(properties);

            // after the route is created then set the route on the policy processor so we get hold of it
            CamelInternalProcessor.RoutePolicyAdvice task = internal.getAdvice(CamelInternalProcessor.RoutePolicyAdvice.class);
            if (task != null) {
                task.setRoute(edcr);
            }
            CamelInternalProcessor.RouteLifecycleAdvice task2 = internal.getAdvice(CamelInternalProcessor.RouteLifecycleAdvice.class);
            if (task2 != null) {
                task2.setRoute(edcr);
            }

            // invoke init on route policy
            if (routePolicyList != null && !routePolicyList.isEmpty()) {
                for (RoutePolicy policy : routePolicyList) {
                    policy.onInit(edcr);
                }
            }

            runtimeRoute = edcr;
        }
        return runtimeRoute;
    }

    @Override
    public void addEventDrivenProcessor(Processor processor) {
        eventDrivenProcessors.add(processor);
    }

    @Override
    public List getInterceptStrategies() {
        return interceptStrategies;
    }

    @Override
    public void setInterceptStrategies(List interceptStrategies) {
        this.interceptStrategies = interceptStrategies;
    }

    @Override
    public void addInterceptStrategy(InterceptStrategy interceptStrategy) {
        getInterceptStrategies().add(interceptStrategy);
    }

    @Override
    public void setManagementInterceptStrategy(ManagementInterceptStrategy interceptStrategy) {
        this.managementInterceptStrategy = interceptStrategy;
    }

    @Override
    public ManagementInterceptStrategy getManagementInterceptStrategy() {
        return managementInterceptStrategy;
    }

    @Override
    public boolean isRouteAdded() {
        return routeAdded;
    }

    @Override
    public void setIsRouteAdded(boolean routeAdded) {
        this.routeAdded = routeAdded;
    }

    @Override
    public void setTracing(Boolean tracing) {
        this.trace = tracing;
    }

    @Override
    public Boolean isTracing() {
        if (trace != null) {
            return trace;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isTracing();
        }
    }

    @Override
    public String getTracingPattern() {
        // can only set this on context level
        return getCamelContext().getTracingPattern();
    }

    @Override
    public void setTracingPattern(String tracePattern) {
        // can only set this on context level
        getCamelContext().setTracingPattern(tracePattern);
    }

    @Override
    public void setBacklogTracing(Boolean backlogTrace) {
        this.backlogTrace = backlogTrace;
    }

    @Override
    public Boolean isBacklogTracing() {
        if (backlogTrace != null) {
            return backlogTrace;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isBacklogTracing();
        }
    }

    @Override
    public void setDebugging(Boolean debugging) {
        this.debug = debugging;
    }

    @Override
    public Boolean isDebugging() {
        if (debug != null) {
            return debug;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isDebugging();
        }
    }

    @Override
    public void setMessageHistory(Boolean messageHistory) {
        this.messageHistory = messageHistory;
    }

    @Override
    public Boolean isMessageHistory() {
        if (messageHistory != null) {
            return messageHistory;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isMessageHistory();
        }
    }

    @Override
    public void setLogMask(Boolean logMask) {
        this.logMask = logMask;
    }

    @Override
    public Boolean isLogMask() {
        if (logMask != null) {
            return logMask;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isLogMask();
        }
    }

    @Override
    public void setLogExhaustedMessageBody(Boolean logExhaustedMessageBody) {
        this.logExhaustedMessageBody = logExhaustedMessageBody;
    }

    @Override
    public Boolean isLogExhaustedMessageBody() {
        if (logExhaustedMessageBody != null) {
            return logExhaustedMessageBody;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isLogExhaustedMessageBody();
        }
    }

    @Override
    public void setStreamCaching(Boolean cache) {
        this.streamCache = cache;
    }

    @Override
    public Boolean isStreamCaching() {
        if (streamCache != null) {
            return streamCache;
        } else {
            // fallback to the option from camel context
            return getCamelContext().isStreamCaching();
        }
    }

    @Override
    public void setDelayer(Long delay) {
        this.delay = delay;
    }

    @Override
    public Long getDelayer() {
        if (delay != null) {
            return delay;
        } else {
            // fallback to the option from camel context
            return getCamelContext().getDelayer();
        }
    }

    @Override
    public void setAutoStartup(Boolean autoStartup) {
        this.autoStartup = autoStartup;
    }

    @Override
    public Boolean isAutoStartup() {
        if (autoStartup != null) {
            return autoStartup;
        }
        // default to true
        return true;
    }

    @Override
    public void setStartupOrder(Integer startupOrder) {
        this.startupOrder = startupOrder;
    }

    @Override
    public Integer getStartupOrder() {
        return startupOrder;
    }

    @Override
    public void setErrorHandlerFactory(ErrorHandlerFactory errorHandlerFactory) {
        this.errorHandlerFactory = errorHandlerFactory;
    }

    @Override
    public ErrorHandlerFactory getErrorHandlerFactory() {
        return errorHandlerFactory;
    }

    @Override
    public void setShutdownRoute(ShutdownRoute shutdownRoute) {
        this.shutdownRoute = shutdownRoute;
    }

    @Override
    public void setAllowUseOriginalMessage(Boolean allowUseOriginalMessage) {
        // can only be configured on CamelContext
        getCamelContext().setAllowUseOriginalMessage(allowUseOriginalMessage);
    }

    @Override
    public Boolean isAllowUseOriginalMessage() {
        // can only be configured on CamelContext
        return getCamelContext().isAllowUseOriginalMessage();
    }

    @Override
    public ShutdownRoute getShutdownRoute() {
        if (shutdownRoute != null) {
            return shutdownRoute;
        } else {
            // fallback to the option from camel context
            return getCamelContext().getShutdownRoute();
        }
    }

    @Override
    public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) {
        this.shutdownRunningTask = shutdownRunningTask;
    }

    @Override
    public ShutdownRunningTask getShutdownRunningTask() {
        if (shutdownRunningTask != null) {
            return shutdownRunningTask;
        } else {
            // fallback to the option from camel context
            return getCamelContext().getShutdownRunningTask();
        }
    }

    @Override
    public void setRoutePolicyList(List routePolicyList) {
        this.routePolicyList = routePolicyList;
    }

    @Override
    public List getRoutePolicyList() {
        return routePolicyList;
    }

    @Override
    public RouteError getLastError() {
        return routeError;
    }

    @Override
    public void setLastError(RouteError routeError) {
        this.routeError = routeError;
    }

    @Override
    public RouteController getRouteController() {
        return routeController;
    }

    @Override
    public void setRouteController(RouteController routeController) {
        this.routeController = routeController;
    }

    @Override
    public Processor getOnCompletion(String onCompletionId) {
        return onCompletions.get(onCompletionId);
    }

    @Override
    public void setOnCompletion(String onCompletionId, Processor processor) {
        onCompletions.put(onCompletionId, processor);
    }

    @Override
    public Processor getOnException(String onExceptionId) {
        return onExceptions.get(onExceptionId);
    }

    @Override
    public void setOnException(String onExceptionId, Processor processor) {
        onExceptions.put(onExceptionId, processor);
    }

    @Override
    public void addAdvice(CamelInternalProcessorAdvice advice) {
        advices.add(advice);
    }

    @Override
    public void addProperty(String key, Object value) {
        properties.put(key, value);
    }

    @Override
    public void addErrorHandler(ErrorHandlerFactory factory, NamedNode onException) {
        getErrorHandlers(factory).add(onException);
    }

    @Override
    public Set getErrorHandlers(ErrorHandlerFactory factory) {
        return errorHandlers.computeIfAbsent(factory, f -> new LinkedHashSet<>());
    }

    @Override
    public void addErrorHandlerFactoryReference(ErrorHandlerFactory source, ErrorHandlerFactory target) {
        Set list = getErrorHandlers(source);
        Set previous = errorHandlers.put(target, list);
        if (list != previous && ObjectHelper.isNotEmpty(previous) && ObjectHelper.isNotEmpty(list)) {
            throw new IllegalStateException("multiple references with different handlers");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy