Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* 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;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.Component;
import org.apache.camel.Consumer;
import org.apache.camel.ConsumerTemplate;
import org.apache.camel.Endpoint;
import org.apache.camel.ErrorHandlerFactory;
import org.apache.camel.ExtendedStartupListener;
import org.apache.camel.FailedToStartRouteException;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.IsSingleton;
import org.apache.camel.MultipleConsumersSupport;
import org.apache.camel.NamedNode;
import org.apache.camel.NoFactoryAvailableException;
import org.apache.camel.NoSuchEndpointException;
import org.apache.camel.PollingConsumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.ResolveEndpointFailedException;
import org.apache.camel.Route;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.Service;
import org.apache.camel.ServiceStatus;
import org.apache.camel.ShutdownRoute;
import org.apache.camel.ShutdownRunningTask;
import org.apache.camel.StartupListener;
import org.apache.camel.StatefulService;
import org.apache.camel.Suspendable;
import org.apache.camel.SuspendableService;
import org.apache.camel.TypeConverter;
import org.apache.camel.VetoCamelContextStartException;
import org.apache.camel.api.management.mbean.ManagedCamelContextMBean;
import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
import org.apache.camel.api.management.mbean.ManagedRouteMBean;
import org.apache.camel.builder.DefaultFluentProducerTemplate;
import org.apache.camel.builder.ErrorHandlerBuilder;
import org.apache.camel.builder.ErrorHandlerBuilderSupport;
import org.apache.camel.component.properties.PropertiesComponent;
import org.apache.camel.health.HealthCheckRegistry;
import org.apache.camel.impl.converter.BaseTypeConverterRegistry;
import org.apache.camel.impl.converter.DefaultTypeConverter;
import org.apache.camel.impl.converter.LazyLoadingTypeConverter;
import org.apache.camel.impl.health.DefaultHealthCheckRegistry;
import org.apache.camel.impl.transformer.TransformerKey;
import org.apache.camel.impl.validator.ValidatorKey;
import org.apache.camel.management.DefaultManagementMBeanAssembler;
import org.apache.camel.management.DefaultManagementStrategy;
import org.apache.camel.management.JmxSystemPropertyKeys;
import org.apache.camel.management.ManagementStrategyFactory;
import org.apache.camel.model.DataFormatDefinition;
import org.apache.camel.model.FromDefinition;
import org.apache.camel.model.HystrixConfigurationDefinition;
import org.apache.camel.model.ModelCamelContext;
import org.apache.camel.model.ModelHelper;
import org.apache.camel.model.ProcessorDefinition;
import org.apache.camel.model.ProcessorDefinitionHelper;
import org.apache.camel.model.RouteDefinition;
import org.apache.camel.model.RouteDefinitionHelper;
import org.apache.camel.model.RoutesDefinition;
import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
import org.apache.camel.model.rest.RestDefinition;
import org.apache.camel.model.rest.RestsDefinition;
import org.apache.camel.model.transformer.TransformerDefinition;
import org.apache.camel.model.validator.ValidatorDefinition;
import org.apache.camel.processor.interceptor.BacklogDebugger;
import org.apache.camel.processor.interceptor.BacklogTracer;
import org.apache.camel.processor.interceptor.Debug;
import org.apache.camel.processor.interceptor.Delayer;
import org.apache.camel.processor.interceptor.HandleFault;
import org.apache.camel.processor.interceptor.StreamCaching;
import org.apache.camel.processor.interceptor.Tracer;
import org.apache.camel.runtimecatalog.DefaultRuntimeCamelCatalog;
import org.apache.camel.runtimecatalog.RuntimeCamelCatalog;
import org.apache.camel.spi.AsyncProcessorAwaitManager;
import org.apache.camel.spi.CamelContextNameStrategy;
import org.apache.camel.spi.ClassResolver;
import org.apache.camel.spi.ComponentResolver;
import org.apache.camel.spi.Container;
import org.apache.camel.spi.DataFormat;
import org.apache.camel.spi.DataFormatResolver;
import org.apache.camel.spi.DataType;
import org.apache.camel.spi.Debugger;
import org.apache.camel.spi.EndpointRegistry;
import org.apache.camel.spi.EndpointStrategy;
import org.apache.camel.spi.EventNotifier;
import org.apache.camel.spi.ExecutorServiceManager;
import org.apache.camel.spi.FactoryFinder;
import org.apache.camel.spi.FactoryFinderResolver;
import org.apache.camel.spi.HeadersMapFactory;
import org.apache.camel.spi.InflightRepository;
import org.apache.camel.spi.Injector;
import org.apache.camel.spi.InterceptStrategy;
import org.apache.camel.spi.Language;
import org.apache.camel.spi.LanguageResolver;
import org.apache.camel.spi.LifecycleStrategy;
import org.apache.camel.spi.LogListener;
import org.apache.camel.spi.ManagementMBeanAssembler;
import org.apache.camel.spi.ManagementNameStrategy;
import org.apache.camel.spi.ManagementStrategy;
import org.apache.camel.spi.MessageHistoryFactory;
import org.apache.camel.spi.ModelJAXBContextFactory;
import org.apache.camel.spi.NodeIdFactory;
import org.apache.camel.spi.PackageScanClassResolver;
import org.apache.camel.spi.ProcessorFactory;
import org.apache.camel.spi.Registry;
import org.apache.camel.spi.ReloadStrategy;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.spi.RestRegistry;
import org.apache.camel.spi.RouteContext;
import org.apache.camel.spi.RouteController;
import org.apache.camel.spi.RouteError;
import org.apache.camel.spi.RoutePolicyFactory;
import org.apache.camel.spi.RouteStartupOrder;
import org.apache.camel.spi.RuntimeEndpointRegistry;
import org.apache.camel.spi.ServicePool;
import org.apache.camel.spi.ShutdownStrategy;
import org.apache.camel.spi.StreamCachingStrategy;
import org.apache.camel.spi.Transformer;
import org.apache.camel.spi.TransformerRegistry;
import org.apache.camel.spi.TypeConverterRegistry;
import org.apache.camel.spi.UnitOfWorkFactory;
import org.apache.camel.spi.UuidGenerator;
import org.apache.camel.spi.Validator;
import org.apache.camel.spi.ValidatorRegistry;
import org.apache.camel.support.ServiceSupport;
import org.apache.camel.util.CamelContextHelper;
import org.apache.camel.util.CollectionStringBuffer;
import org.apache.camel.util.EndpointHelper;
import org.apache.camel.util.EventHelper;
import org.apache.camel.util.IOHelper;
import org.apache.camel.util.IntrospectionSupport;
import org.apache.camel.util.JsonSchemaHelper;
import org.apache.camel.util.LoadPropertiesException;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.OrderedComparator;
import org.apache.camel.util.ServiceHelper;
import org.apache.camel.util.StopWatch;
import org.apache.camel.util.StringHelper;
import org.apache.camel.util.StringQuoteHelper;
import org.apache.camel.util.TimeUtils;
import org.apache.camel.util.URISupport;
import org.apache.camel.util.jsse.SSLContextParameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import static org.apache.camel.impl.MDCUnitOfWork.MDC_CAMEL_CONTEXT_ID;
/**
* Represents the context used to configure routes and the policies to use.
*
* @version
*/
@SuppressWarnings("deprecation")
public class DefaultCamelContext extends ServiceSupport implements ModelCamelContext, Suspendable {
private final Logger log = LoggerFactory.getLogger(getClass());
private final AtomicBoolean vetoStated = new AtomicBoolean();
private JAXBContext jaxbContext;
private CamelContextNameStrategy nameStrategy = createCamelContextNameStrategy();
private ManagementNameStrategy managementNameStrategy = createManagementNameStrategy();
private String managementName;
private ClassLoader applicationContextClassLoader;
private EndpointRegistry endpoints;
private final AtomicInteger endpointKeyCounter = new AtomicInteger();
private final List endpointStrategies = new ArrayList<>();
private final Map components = new ConcurrentHashMap<>();
private final Set routes = new LinkedHashSet<>();
private final List servicesToStop = new CopyOnWriteArrayList<>();
private final List startupListeners = new CopyOnWriteArrayList<>();
private final DeferServiceStartupListener deferStartupListener = new DeferServiceStartupListener();
private TypeConverter typeConverter;
private TypeConverterRegistry typeConverterRegistry;
private Injector injector;
private ComponentResolver componentResolver;
private boolean autoCreateComponents = true;
private LanguageResolver languageResolver;
private final Map languages = new HashMap<>();
private Registry registry;
private List lifecycleStrategies = new CopyOnWriteArrayList<>();
private ManagementStrategy managementStrategy;
private ManagementMBeanAssembler managementMBeanAssembler;
private final List routeDefinitions = new ArrayList<>();
private final List restDefinitions = new ArrayList<>();
private Map restConfigurations = new ConcurrentHashMap<>();
private Map serviceCallConfigurations = new ConcurrentHashMap<>();
private Map hystrixConfigurations = new ConcurrentHashMap<>();
private RestRegistry restRegistry = new DefaultRestRegistry();
private List interceptStrategies = new ArrayList<>();
private List routePolicyFactories = new ArrayList<>();
private Set logListeners = new LinkedHashSet<>();
private HeadersMapFactory headersMapFactory = createHeadersMapFactory();
// special flags to control the first startup which can are special
private volatile boolean firstStartDone;
private volatile boolean doNotStartRoutesOnFirstStart;
private final ThreadLocal isStartingRoutes = new ThreadLocal<>();
private final ThreadLocal isSetupRoutes = new ThreadLocal<>();
private Boolean autoStartup = Boolean.TRUE;
private Boolean trace = Boolean.FALSE;
private Boolean messageHistory = Boolean.TRUE;
private Boolean logMask = Boolean.FALSE;
private Boolean logExhaustedMessageBody = Boolean.FALSE;
private Boolean streamCache = Boolean.FALSE;
private Boolean handleFault = Boolean.FALSE;
private Boolean disableJMX = Boolean.FALSE;
private Boolean lazyLoadTypeConverters = Boolean.FALSE;
private Boolean loadTypeConverters = Boolean.TRUE;
private Boolean typeConverterStatisticsEnabled = Boolean.FALSE;
private Boolean useMDCLogging = Boolean.FALSE;
private Boolean useDataType = Boolean.FALSE;
private Boolean useBreadcrumb = Boolean.TRUE;
private Boolean allowUseOriginalMessage = Boolean.FALSE;
private Long delay;
private ErrorHandlerFactory errorHandlerBuilder;
private final Object errorHandlerExecutorServiceLock = new Object();
private ScheduledExecutorService errorHandlerExecutorService;
private Map dataFormats = new HashMap<>();
private DataFormatResolver dataFormatResolver;
private Map globalOptions = new HashMap<>();
private FactoryFinderResolver factoryFinderResolver;
private FactoryFinder defaultFactoryFinder;
private PropertiesComponent propertiesComponent;
private StreamCachingStrategy streamCachingStrategy;
private final Map factories = new HashMap<>();
private final Map routeServices = new LinkedHashMap<>();
private final Map suspendedRouteServices = new LinkedHashMap<>();
private ClassResolver classResolver = createClassResolver();
private PackageScanClassResolver packageScanClassResolver;
// we use a capacity of 100 per endpoint, so for the same endpoint we have at most 100 producers in the pool
// so if we have 6 endpoints in the pool, we can have 6 x 100 producers in total
private ServicePool producerServicePool = createProducerServicePool();
private ServicePool pollingConsumerServicePool = createPollingConsumerServicePool();
private NodeIdFactory nodeIdFactory = createNodeIdFactory();
private ProcessorFactory processorFactory = createProcessorFactory();
private MessageHistoryFactory messageHistoryFactory = createMessageHistoryFactory();
private InterceptStrategy defaultTracer;
private InterceptStrategy defaultBacklogTracer;
private InterceptStrategy defaultBacklogDebugger;
private InflightRepository inflightRepository = createInflightRepository();
private AsyncProcessorAwaitManager asyncProcessorAwaitManager = createAsyncProcessorAwaitManager();
private RuntimeEndpointRegistry runtimeEndpointRegistry;
private final List routeStartupOrder = new ArrayList<>();
// start auto assigning route ids using numbering 1000 and upwards
private int defaultRouteStartupOrder = 1000;
private ShutdownStrategy shutdownStrategy = createShutdownStrategy();
private ShutdownRoute shutdownRoute = ShutdownRoute.Default;
private ShutdownRunningTask shutdownRunningTask = ShutdownRunningTask.CompleteCurrentTaskOnly;
private ExecutorServiceManager executorServiceManager;
private Debugger debugger;
private UuidGenerator uuidGenerator = createDefaultUuidGenerator();
private UnitOfWorkFactory unitOfWorkFactory = createUnitOfWorkFactory();
private final StopWatch stopWatch = new StopWatch(false);
private Date startDate;
private ModelJAXBContextFactory modelJAXBContextFactory;
private List transformers = new ArrayList<>();
private TransformerRegistry transformerRegistry;
private List validators = new ArrayList<>();
private ValidatorRegistry validatorRegistry;
private ReloadStrategy reloadStrategy;
private final RuntimeCamelCatalog runtimeCamelCatalog = createRuntimeCamelCatalog();
private SSLContextParameters sslContextParameters;
private final ThreadLocal> componentsInCreation = new ThreadLocal>() {
@Override
public Set initialValue() {
return new HashSet<>();
}
};
private RouteController routeController = createRouteController();
private HealthCheckRegistry healthCheckRegistry = createHealthCheckRegistry();
/**
* Creates the {@link CamelContext} using {@link JndiRegistry} as registry,
* but will silently fallback and use {@link SimpleRegistry} if JNDI cannot be used.
*
* Use one of the other constructors to force use an explicit registry / JNDI.
*/
public DefaultCamelContext() {
this.executorServiceManager = createExecutorServiceManager();
// create a provisional (temporary) endpoint registry at first since end users may access endpoints before CamelContext is started
// we will later transfer the endpoints to the actual DefaultEndpointRegistry later, but we do this to starup Camel faster.
this.endpoints = new ProvisionalEndpointRegistry();
// add the defer service startup listener
this.startupListeners.add(deferStartupListener);
packageScanClassResolver = createPackageScanClassResolver();
// setup management strategy first since end users may use it to add event notifiers
// using the management strategy before the CamelContext has been started
this.managementStrategy = createManagementStrategy();
this.managementMBeanAssembler = createManagementMBeanAssembler();
// Call all registered trackers with this context
// Note, this may use a partially constructed object
CamelContextTrackerRegistry.INSTANCE.contextCreated(this);
}
/**
* Creates the {@link CamelContext} using the given JNDI context as the registry
*
* @param jndiContext the JNDI context
*/
public DefaultCamelContext(Context jndiContext) {
this();
setJndiContext(jndiContext);
}
/**
* Creates the {@link CamelContext} using the given registry
*
* @param registry the registry
*/
public DefaultCamelContext(Registry registry) {
this();
setRegistry(registry);
}
public T adapt(Class type) {
return type.cast(this);
}
public boolean isVetoStarted() {
return vetoStated.get();
}
public String getName() {
return getNameStrategy().getName();
}
/**
* Sets the name of the this context.
*
* @param name the name
*/
public void setName(String name) {
// use an explicit name strategy since an explicit name was provided to be used
this.nameStrategy = new ExplicitCamelContextNameStrategy(name);
}
public CamelContextNameStrategy getNameStrategy() {
return nameStrategy;
}
public void setNameStrategy(CamelContextNameStrategy nameStrategy) {
this.nameStrategy = nameStrategy;
}
public ManagementNameStrategy getManagementNameStrategy() {
return managementNameStrategy;
}
public void setManagementNameStrategy(ManagementNameStrategy managementNameStrategy) {
this.managementNameStrategy = managementNameStrategy;
}
public String getManagementName() {
return managementName;
}
public void setManagementName(String managementName) {
this.managementName = managementName;
}
public Component hasComponent(String componentName) {
return components.get(componentName);
}
public void addComponent(String componentName, final Component component) {
ObjectHelper.notNull(component, "component");
component.setCamelContext(this);
Component oldValue = components.putIfAbsent(componentName, component);
if (oldValue != null) {
throw new IllegalArgumentException("Cannot add component as its already previously added: " + componentName);
}
postInitComponent(componentName, component);
}
private void postInitComponent(String componentName, final Component component) {
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onComponentAdd(componentName, component);
}
// keep reference to properties component up to date
if (component instanceof PropertiesComponent && "properties".equals(componentName)) {
propertiesComponent = (PropertiesComponent) component;
}
}
public Component getComponent(String name) {
return getComponent(name, autoCreateComponents, true);
}
public Component getComponent(String name, boolean autoCreateComponents) {
return getComponent(name, autoCreateComponents, true);
}
public Component getComponent(String name, boolean autoCreateComponents, boolean autoStart) {
// Check if the named component is already being created, that would mean
// that the initComponent has triggered a new getComponent
if (componentsInCreation.get().contains(name)) {
throw new IllegalStateException("Circular dependency detected, the component " + name + " is already being created");
}
try {
// Flag used to mark a component of being created.
final AtomicBoolean created = new AtomicBoolean(false);
// atomic operation to get/create a component. Avoid global locks.
final Component component = components.computeIfAbsent(name, new Function() {
@Override
public Component apply(String comp) {
created.set(true);
return DefaultCamelContext.this.initComponent(name, autoCreateComponents);
}
});
// Start the component after its creation as if it is a component proxy
// that creates/start a delegated component, we may end up in a deadlock
if (component != null && created.get() && autoStart && (isStarted() || isStarting())) {
// If the component is looked up after the context is started,
// lets start it up.
if (component instanceof Service) {
startService((Service)component);
}
}
return component;
} catch (Exception e) {
throw new RuntimeCamelException("Cannot auto create component: " + name, e);
} finally {
// remove the reference to the component being created
componentsInCreation.get().remove(name);
}
}
/**
* Function to initialize a component and auto start. Returns null if the autoCreateComponents is disabled
*/
private Component initComponent(String name, boolean autoCreateComponents) {
Component component = null;
if (autoCreateComponents) {
try {
if (log.isDebugEnabled()) {
log.debug("Using ComponentResolver: {} to resolve component with name: {}", getComponentResolver(), name);
}
// Mark the component as being created so we can detect circular
// requests.
//
// In spring apps, the component resolver may trigger a new getComponent
// because of the underlying bean factory and as the endpoints are
// registered as singleton, the spring factory creates the bean
// and then check the type so the getComponent is always triggered.
//
// Simple circular dependency:
//
//
//
//
//
//
//
//
// Complex circular dependency:
//
//
//
//
//
//
//
//
// This would freeze the app (lock or infinite loop).
//
// See https://issues.apache.org/jira/browse/CAMEL-11225
componentsInCreation.get().add(name);
component = getComponentResolver().resolveComponent(name, this);
if (component != null) {
component.setCamelContext(this);
postInitComponent(name, component);
}
} catch (Exception e) {
throw new RuntimeCamelException("Cannot auto create component: " + name, e);
}
}
return component;
}
public T getComponent(String name, Class componentType) {
Component component = getComponent(name);
if (componentType.isInstance(component)) {
return componentType.cast(component);
} else {
String message;
if (component == null) {
message = "Did not find component given by the name: " + name;
} else {
message = "Found component of type: " + component.getClass() + " instead of expected: " + componentType;
}
throw new IllegalArgumentException(message);
}
}
public Component resolveComponent(String name) {
Component answer = hasComponent(name);
if (answer == null) {
try {
answer = getComponentResolver().resolveComponent(name, this);
} catch (Exception e) {
throw new RuntimeCamelException("Cannot resolve component: " + name, e);
}
}
return answer;
}
public Component removeComponent(String componentName) {
Component oldComponent = components.remove(componentName);
if (oldComponent != null) {
try {
stopServices(oldComponent);
} catch (Exception e) {
log.warn("Error stopping component " + oldComponent + ". This exception will be ignored.", e);
}
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onComponentRemove(componentName, oldComponent);
}
}
// keep reference to properties component up to date
if (oldComponent != null && "properties".equals(componentName)) {
propertiesComponent = null;
}
return oldComponent;
}
// Endpoint Management Methods
// -----------------------------------------------------------------------
public EndpointRegistry getEndpointRegistry() {
return endpoints;
}
public Collection getEndpoints() {
return new ArrayList<>(endpoints.values());
}
public Map getEndpointMap() {
Map answer = new TreeMap<>();
for (Map.Entry entry : endpoints.entrySet()) {
answer.put(entry.getKey().get(), entry.getValue());
}
return answer;
}
public Endpoint hasEndpoint(String uri) {
return endpoints.get(getEndpointKey(uri));
}
public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception {
Endpoint oldEndpoint;
startService(endpoint);
oldEndpoint = endpoints.remove(getEndpointKey(uri));
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onEndpointAdd(endpoint);
}
addEndpointToRegistry(uri, endpoint);
if (oldEndpoint != null) {
stopServices(oldEndpoint);
}
return oldEndpoint;
}
public void removeEndpoint(Endpoint endpoint) throws Exception {
removeEndpoints(endpoint.getEndpointUri());
}
public Collection removeEndpoints(String uri) throws Exception {
Collection answer = new ArrayList<>();
Endpoint oldEndpoint = endpoints.remove(getEndpointKey(uri));
if (oldEndpoint != null) {
answer.add(oldEndpoint);
stopServices(oldEndpoint);
} else {
for (Map.Entry entry : endpoints.entrySet()) {
oldEndpoint = entry.getValue();
if (EndpointHelper.matchEndpoint(this, oldEndpoint.getEndpointUri(), uri)) {
try {
stopServices(oldEndpoint);
} catch (Exception e) {
log.warn("Error stopping endpoint " + oldEndpoint + ". This exception will be ignored.", e);
}
answer.add(oldEndpoint);
endpoints.remove(entry.getKey());
}
}
}
// notify lifecycle its being removed
for (Endpoint endpoint : answer) {
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onEndpointRemove(endpoint);
}
}
return answer;
}
public Endpoint getEndpoint(String uri) {
StringHelper.notEmpty(uri, "uri");
log.trace("Getting endpoint with uri: {}", uri);
// in case path has property placeholders then try to let property component resolve those
try {
uri = resolvePropertyPlaceholders(uri);
} catch (Exception e) {
throw new ResolveEndpointFailedException(uri, e);
}
final String rawUri = uri;
// normalize uri so we can do endpoint hits with minor mistakes and parameters is not in the same order
uri = normalizeEndpointUri(uri);
log.trace("Getting endpoint with raw uri: {}, normalized uri: {}", rawUri, uri);
Endpoint answer;
String scheme = null;
// use optimized method to get the endpoint uri
EndpointKey key = getEndpointKeyPreNormalized(uri);
answer = endpoints.get(key);
if (answer == null) {
try {
// Use the URI prefix to find the component.
String splitURI[] = StringHelper.splitOnCharacter(uri, ":", 2);
if (splitURI[1] != null) {
scheme = splitURI[0];
log.trace("Endpoint uri: {} is from component with name: {}", uri, scheme);
Component component = getComponent(scheme);
// Ask the component to resolve the endpoint.
if (component != null) {
log.trace("Creating endpoint from uri: {} using component: {}", uri, component);
// Have the component create the endpoint if it can.
if (component.useRawUri()) {
answer = component.createEndpoint(rawUri);
} else {
answer = component.createEndpoint(uri);
}
if (answer != null && log.isDebugEnabled()) {
log.debug("{} converted to endpoint: {} by component: {}", URISupport.sanitizeUri(uri), answer, component);
}
}
}
if (answer == null) {
// no component then try in registry and elsewhere
answer = createEndpoint(uri);
log.trace("No component to create endpoint from uri: {} fallback lookup in registry -> {}", uri, answer);
}
if (answer == null && splitURI[1] == null) {
// the uri has no context-path which is rare and it was not referring to an endpoint in the registry
// so try to see if it can be created by a component
int pos = uri.indexOf('?');
String componentName = pos > 0 ? uri.substring(0, pos) : uri;
Component component = getComponent(componentName);
// Ask the component to resolve the endpoint.
if (component != null) {
log.trace("Creating endpoint from uri: {} using component: {}", uri, component);
// Have the component create the endpoint if it can.
if (component.useRawUri()) {
answer = component.createEndpoint(rawUri);
} else {
answer = component.createEndpoint(uri);
}
if (answer != null && log.isDebugEnabled()) {
log.debug("{} converted to endpoint: {} by component: {}", URISupport.sanitizeUri(uri), answer, component);
}
}
}
if (answer != null) {
addService(answer);
answer = addEndpointToRegistry(uri, answer);
}
} catch (Exception e) {
throw new ResolveEndpointFailedException(uri, e);
}
}
// unknown scheme
if (answer == null && scheme != null) {
throw new ResolveEndpointFailedException(uri, "No component found with scheme: " + scheme);
}
return answer;
}
public T getEndpoint(String name, Class endpointType) {
Endpoint endpoint = getEndpoint(name);
if (endpoint == null) {
throw new NoSuchEndpointException(name);
}
if (endpoint instanceof InterceptSendToEndpoint) {
endpoint = ((InterceptSendToEndpoint) endpoint).getDelegate();
}
if (endpointType.isInstance(endpoint)) {
return endpointType.cast(endpoint);
} else {
throw new IllegalArgumentException("The endpoint is not of type: " + endpointType
+ " but is: " + endpoint.getClass().getCanonicalName());
}
}
public void addRegisterEndpointCallback(EndpointStrategy strategy) {
if (!endpointStrategies.contains(strategy)) {
// let it be invoked for already registered endpoints so it can catch-up.
endpointStrategies.add(strategy);
for (Endpoint endpoint : getEndpoints()) {
Endpoint newEndpoint = strategy.registerEndpoint(endpoint.getEndpointUri(), endpoint);
if (newEndpoint != null) {
// put will replace existing endpoint with the new endpoint
endpoints.put(getEndpointKey(endpoint.getEndpointUri()), newEndpoint);
}
}
}
}
/**
* Strategy to add the given endpoint to the internal endpoint registry
*
* @param uri uri of the endpoint
* @param endpoint the endpoint to add
* @return the added endpoint
*/
protected Endpoint addEndpointToRegistry(String uri, Endpoint endpoint) {
StringHelper.notEmpty(uri, "uri");
ObjectHelper.notNull(endpoint, "endpoint");
// if there is endpoint strategies, then use the endpoints they return
// as this allows to intercept endpoints etc.
for (EndpointStrategy strategy : endpointStrategies) {
endpoint = strategy.registerEndpoint(uri, endpoint);
}
endpoints.put(getEndpointKey(uri, endpoint), endpoint);
return endpoint;
}
/**
* Normalize uri so we can do endpoint hits with minor mistakes and parameters is not in the same order.
*
* @param uri the uri
* @return normalized uri
* @throws ResolveEndpointFailedException if uri cannot be normalized
*/
protected static String normalizeEndpointUri(String uri) {
try {
uri = URISupport.normalizeUri(uri);
} catch (Exception e) {
throw new ResolveEndpointFailedException(uri, e);
}
return uri;
}
/**
* Gets the endpoint key to use for lookup or whe adding endpoints to the {@link DefaultEndpointRegistry}
*
* @param uri the endpoint uri
* @return the key
*/
protected EndpointKey getEndpointKey(String uri) {
return new EndpointKey(uri);
}
/**
* Gets the endpoint key to use for lookup or whe adding endpoints to the {@link DefaultEndpointRegistry}
*
* @param uri the endpoint uri which is pre normalized
* @return the key
*/
protected EndpointKey getEndpointKeyPreNormalized(String uri) {
return new EndpointKey(uri, true);
}
/**
* Gets the endpoint key to use for lookup or whe adding endpoints to the {@link DefaultEndpointRegistry}
*
* @param uri the endpoint uri
* @param endpoint the endpoint
* @return the key
*/
protected EndpointKey getEndpointKey(String uri, Endpoint endpoint) {
if (endpoint != null && !endpoint.isSingleton()) {
int counter = endpointKeyCounter.incrementAndGet();
return new EndpointKey(uri + ":" + counter);
} else {
return new EndpointKey(uri);
}
}
// Route Management Methods
// -----------------------------------------------------------------------
@Override
public void setRouteController(RouteController routeController) {
this.routeController = routeController;
this.routeController.setCamelContext(this);
}
@Override
public RouteController getRouteController() {
return routeController;
}
public List getRouteStartupOrder() {
return routeStartupOrder;
}
public List getRoutes() {
// lets return a copy of the collection as objects are removed later when services are stopped
if (routes.isEmpty()) {
return Collections.emptyList();
} else {
synchronized (routes) {
return new ArrayList<>(routes);
}
}
}
public Route getRoute(String id) {
if (id != null) {
for (Route route : getRoutes()) {
if (route.getId().equals(id)) {
return route;
}
}
}
return null;
}
public Processor getProcessor(String id) {
for (Route route : getRoutes()) {
List list = route.filter(id);
if (list.size() == 1) {
return list.get(0);
}
}
return null;
}
public T getProcessor(String id, Class type) {
Processor answer = getProcessor(id);
if (answer != null) {
return type.cast(answer);
}
return null;
}
public T getManagedProcessor(String id, Class type) {
// jmx must be enabled
if (getManagementStrategy().getManagementAgent() == null) {
return null;
}
Processor processor = getProcessor(id);
ProcessorDefinition def = getProcessorDefinition(id);
// processor may be null if its anonymous inner class or as lambda
if (def != null) {
try {
ObjectName on = getManagementStrategy().getManagementNamingStrategy().getObjectNameForProcessor(this, processor, def);
return getManagementStrategy().getManagementAgent().newProxyClient(on, type);
} catch (MalformedObjectNameException e) {
throw ObjectHelper.wrapRuntimeCamelException(e);
}
}
return null;
}
public T getManagedRoute(String routeId, Class type) {
// jmx must be enabled
if (getManagementStrategy().getManagementAgent() == null) {
return null;
}
Route route = getRoute(routeId);
if (route != null) {
try {
ObjectName on = getManagementStrategy().getManagementNamingStrategy().getObjectNameForRoute(route);
return getManagementStrategy().getManagementAgent().newProxyClient(on, type);
} catch (MalformedObjectNameException e) {
throw ObjectHelper.wrapRuntimeCamelException(e);
}
}
return null;
}
public ManagedCamelContextMBean getManagedCamelContext() {
// jmx must be enabled
if (getManagementStrategy().getManagementAgent() == null) {
return null;
}
try {
ObjectName on = getManagementStrategy().getManagementNamingStrategy().getObjectNameForCamelContext(this);
return getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedCamelContextMBean.class);
} catch (MalformedObjectNameException e) {
throw ObjectHelper.wrapRuntimeCamelException(e);
}
}
public ProcessorDefinition getProcessorDefinition(String id) {
for (RouteDefinition route : getRouteDefinitions()) {
Iterator it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class);
while (it.hasNext()) {
ProcessorDefinition proc = it.next();
if (id.equals(proc.getId())) {
return proc;
}
}
}
return null;
}
public T getProcessorDefinition(String id, Class type) {
ProcessorDefinition answer = getProcessorDefinition(id);
if (answer != null) {
return type.cast(answer);
}
return null;
}
@Deprecated
public void setRoutes(List routes) {
throw new UnsupportedOperationException("Overriding existing routes is not supported yet, use addRouteCollection instead");
}
void removeRouteCollection(Collection routes) {
synchronized (this.routes) {
this.routes.removeAll(routes);
}
}
void addRouteCollection(Collection routes) throws Exception {
synchronized (this.routes) {
this.routes.addAll(routes);
}
}
public void addRoutes(final RoutesBuilder builder) throws Exception {
log.debug("Adding routes from builder: {}", builder);
doWithDefinedClassLoader(new Callable() {
@Override
public Void call() throws Exception {
builder.addRoutesToCamelContext(DefaultCamelContext.this);
return null;
}
});
}
public synchronized RoutesDefinition loadRoutesDefinition(InputStream is) throws Exception {
return ModelHelper.loadRoutesDefinition(this, is);
}
public synchronized RestsDefinition loadRestsDefinition(InputStream is) throws Exception {
// load routes using JAXB
if (jaxbContext == null) {
// must use classloader from CamelContext to have JAXB working
jaxbContext = getModelJAXBContextFactory().newJAXBContext();
}
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Object result = unmarshaller.unmarshal(is);
if (result == null) {
throw new IOException("Cannot unmarshal to rests using JAXB from input stream: " + is);
}
// can either be routes or a single route
RestsDefinition answer;
if (result instanceof RestDefinition) {
RestDefinition rest = (RestDefinition) result;
answer = new RestsDefinition();
answer.getRests().add(rest);
} else if (result instanceof RestsDefinition) {
answer = (RestsDefinition) result;
} else {
throw new IllegalArgumentException("Unmarshalled object is an unsupported type: " + ObjectHelper.className(result) + " -> " + result);
}
return answer;
}
public synchronized void addRouteDefinitions(Collection routeDefinitions) throws Exception {
if (routeDefinitions == null || routeDefinitions.isEmpty()) {
return;
}
for (RouteDefinition routeDefinition : routeDefinitions) {
removeRouteDefinition(routeDefinition);
}
this.routeDefinitions.addAll(routeDefinitions);
if (shouldStartRoutes()) {
startRouteDefinitions(routeDefinitions);
}
}
public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception {
addRouteDefinitions(Arrays.asList(routeDefinition));
}
/**
* Removes the route definition with the given key.
*
* @return true if one or more routes was removed
*/
protected boolean removeRouteDefinition(String key) {
boolean answer = false;
Iterator iter = routeDefinitions.iterator();
while (iter.hasNext()) {
RouteDefinition route = iter.next();
if (route.idOrCreate(nodeIdFactory).equals(key)) {
iter.remove();
answer = true;
}
}
return answer;
}
public synchronized void removeRouteDefinitions(Collection routeDefinitions) throws Exception {
for (RouteDefinition routeDefinition : routeDefinitions) {
removeRouteDefinition(routeDefinition);
}
}
public synchronized void removeRouteDefinition(RouteDefinition routeDefinition) throws Exception {
RouteDefinition toBeRemoved = routeDefinition;
String id = routeDefinition.getId();
if (id != null) {
// remove existing route
stopRoute(id);
removeRoute(id);
toBeRemoved = getRouteDefinition(id);
}
this.routeDefinitions.remove(toBeRemoved);
}
public ServiceStatus getRouteStatus(String key) {
RouteService routeService = routeServices.get(key);
if (routeService != null) {
return routeService.getStatus();
}
return null;
}
public void startRoute(RouteDefinition route) throws Exception {
// assign ids to the routes and validate that the id's is all unique
RouteDefinitionHelper.forceAssignIds(this, routeDefinitions);
String duplicate = RouteDefinitionHelper.validateUniqueIds(route, routeDefinitions);
if (duplicate != null) {
throw new FailedToStartRouteException(route.getId(), "duplicate id detected: " + duplicate + ". Please correct ids to be unique among all your routes.");
}
// indicate we are staring the route using this thread so
// we are able to query this if needed
isStartingRoutes.set(true);
try {
// must ensure route is prepared, before we can start it
route.prepare(this);
List routes = new ArrayList<>();
List routeContexts = route.addRoutes(this, routes);
RouteService routeService = new RouteService(this, route, routeContexts, routes);
startRouteService(routeService, true);
} finally {
// we are done staring routes
isStartingRoutes.remove();
}
}
public boolean isStartingRoutes() {
Boolean answer = isStartingRoutes.get();
return answer != null && answer;
}
public boolean isSetupRoutes() {
Boolean answer = isSetupRoutes.get();
return answer != null && answer;
}
public void stopRoute(RouteDefinition route) throws Exception {
stopRoute(route.idOrCreate(nodeIdFactory));
}
public void startAllRoutes() throws Exception {
doStartOrResumeRoutes(routeServices, true, true, false, false);
}
public synchronized void startRoute(String routeId) throws Exception {
DefaultRouteError.reset(this, routeId);
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
try {
startRouteService(routeService, false);
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.START, e);
throw e;
}
}
}
public synchronized void resumeRoute(String routeId) throws Exception {
DefaultRouteError.reset(this, routeId);
try {
if (!routeSupportsSuspension(routeId)) {
// start route if suspension is not supported
startRoute(routeId);
return;
}
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
resumeRouteService(routeService);
// must resume the route as well
Route route = getRoute(routeId);
ServiceHelper.resumeService(route);
}
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.RESUME, e);
throw e;
}
}
public synchronized boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception {
DefaultRouteError.reset(this, routeId);
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
try {
RouteStartupOrder route = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
boolean completed = getShutdownStrategy().shutdown(this, route, timeout, timeUnit, abortAfterTimeout);
if (completed) {
// must stop route service as well
stopRouteService(routeService, false);
} else {
// shutdown was aborted, make sure route is re-started properly
startRouteService(routeService, false);
}
return completed;
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.STOP, e);
throw e;
}
}
return false;
}
public synchronized void stopRoute(String routeId) throws Exception {
DefaultRouteError.reset(this, routeId);
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
try {
List routes = new ArrayList<>(1);
RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
routes.add(order);
getShutdownStrategy().shutdown(this, routes);
// must stop route service as well
stopRouteService(routeService, false);
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.STOP, e);
throw e;
}
}
}
public synchronized void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
DefaultRouteError.reset(this, routeId);
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
try {
List routes = new ArrayList<>(1);
RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
routes.add(order);
getShutdownStrategy().shutdown(this, routes, timeout, timeUnit);
// must stop route service as well
stopRouteService(routeService, false);
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.STOP, e);
throw e;
}
}
}
public synchronized void shutdownRoute(String routeId) throws Exception {
DefaultRouteError.reset(this, routeId);
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
try {
List routes = new ArrayList<>(1);
RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
routes.add(order);
getShutdownStrategy().shutdown(this, routes);
// must stop route service as well (and remove the routes from management)
stopRouteService(routeService, true);
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.SHUTDOWN, e);
throw e;
}
}
}
public synchronized void shutdownRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
DefaultRouteError.reset(this, routeId);
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
try {
List routes = new ArrayList<>(1);
RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
routes.add(order);
getShutdownStrategy().shutdown(this, routes, timeout, timeUnit);
// must stop route service as well (and remove the routes from management)
stopRouteService(routeService, true);
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.SHUTDOWN, e);
throw e;
}
}
}
public synchronized boolean removeRoute(String routeId) throws Exception {
DefaultRouteError.reset(this, routeId);
// remove the route from ErrorHandlerBuilder if possible
if (getErrorHandlerBuilder() instanceof ErrorHandlerBuilderSupport) {
ErrorHandlerBuilderSupport builder = (ErrorHandlerBuilderSupport)getErrorHandlerBuilder();
builder.removeOnExceptionList(routeId);
}
// gather a map of all the endpoints in use by the routes, so we can known if a given endpoints is in use
// by one or more routes, when we remove the route
Map> endpointsInUse = new HashMap<>();
for (Map.Entry entry : routeServices.entrySet()) {
endpointsInUse.put(entry.getKey(), entry.getValue().gatherEndpoints());
}
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
if (getRouteStatus(routeId).isStopped()) {
try {
routeService.setRemovingRoutes(true);
shutdownRouteService(routeService);
removeRouteDefinition(routeId);
routeServices.remove(routeId);
// remove route from startup order as well, as it was removed
Iterator it = routeStartupOrder.iterator();
while (it.hasNext()) {
RouteStartupOrder order = it.next();
if (order.getRoute().getId().equals(routeId)) {
it.remove();
}
}
// from the route which we have removed, then remove all its private endpoints
// (eg the endpoints which are not in use by other routes)
Set toRemove = new LinkedHashSet<>();
for (Endpoint endpoint : endpointsInUse.get(routeId)) {
// how many times is the endpoint in use
int count = 0;
for (Set endpoints : endpointsInUse.values()) {
if (endpoints.contains(endpoint)) {
count++;
}
}
// notice we will count ourselves so if there is only 1 then its safe to remove
if (count <= 1) {
toRemove.add(endpoint);
}
}
for (Endpoint endpoint : toRemove) {
log.debug("Removing: {} which was only in use by route: {}", endpoint, routeId);
removeEndpoint(endpoint);
}
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.REMOVE, e);
throw e;
}
return true;
} else {
return false;
}
}
return false;
}
public synchronized void suspendRoute(String routeId) throws Exception {
try {
DefaultRouteError.reset(this, routeId);
if (!routeSupportsSuspension(routeId)) {
// stop if we suspend is not supported
stopRoute(routeId);
return;
}
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
List routes = new ArrayList<>(1);
Route route = routeService.getRoutes().iterator().next();
RouteStartupOrder order = new DefaultRouteStartupOrder(1, route, routeService);
routes.add(order);
getShutdownStrategy().suspend(this, routes);
// must suspend route service as well
suspendRouteService(routeService);
// must suspend the route as well
if (route instanceof SuspendableService) {
((SuspendableService) route).suspend();
}
}
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.SUSPEND, e);
throw e;
}
}
public synchronized void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
DefaultRouteError.reset(this, routeId);
try {
if (!routeSupportsSuspension(routeId)) {
stopRoute(routeId, timeout, timeUnit);
return;
}
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
List routes = new ArrayList<>(1);
Route route = routeService.getRoutes().iterator().next();
RouteStartupOrder order = new DefaultRouteStartupOrder(1, route, routeService);
routes.add(order);
getShutdownStrategy().suspend(this, routes, timeout, timeUnit);
// must suspend route service as well
suspendRouteService(routeService);
// must suspend the route as well
if (route instanceof SuspendableService) {
((SuspendableService) route).suspend();
}
}
} catch (Exception e) {
DefaultRouteError.set(this, routeId, RouteError.Phase.SUSPEND, e);
throw e;
}
}
public void addService(Object object) throws Exception {
addService(object, true);
}
public void addService(Object object, boolean stopOnShutdown) throws Exception {
doAddService(object, stopOnShutdown, false);
}
@Override
public void addService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception {
doAddService(object, stopOnShutdown, forceStart);
}
private void doAddService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception {
// inject CamelContext
if (object instanceof CamelContextAware) {
CamelContextAware aware = (CamelContextAware) object;
aware.setCamelContext(this);
}
if (object instanceof Service) {
Service service = (Service) object;
for (LifecycleStrategy strategy : lifecycleStrategies) {
if (service instanceof Endpoint) {
// use specialized endpoint add
strategy.onEndpointAdd((Endpoint) service);
} else {
strategy.onServiceAdd(this, service, null);
}
}
if (!forceStart) {
// now start the service (and defer starting if CamelContext is starting up itself)
deferStartService(object, stopOnShutdown);
} else {
// only add to services to close if its a singleton
// otherwise we could for example end up with a lot of prototype scope endpoints
boolean singleton = true; // assume singleton by default
if (object instanceof IsSingleton) {
singleton = ((IsSingleton) service).isSingleton();
}
// do not add endpoints as they have their own list
if (singleton && !(service instanceof Endpoint)) {
// only add to list of services to stop if its not already there
if (stopOnShutdown && !hasService(service)) {
servicesToStop.add(service);
}
}
ServiceHelper.startService(service);
}
}
}
public boolean removeService(Object object) throws Exception {
if (object instanceof Endpoint) {
removeEndpoint((Endpoint) object);
return true;
}
if (object instanceof Service) {
Service service = (Service) object;
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onServiceRemove(this, service, null);
}
return servicesToStop.remove(service);
}
return false;
}
public boolean hasService(Object object) {
if (object instanceof Service) {
Service service = (Service) object;
return servicesToStop.contains(service);
}
return false;
}
@Override
public T hasService(Class type) {
for (Service service : servicesToStop) {
if (type.isInstance(service)) {
return type.cast(service);
}
}
return null;
}
@Override
public Set hasServices(Class type) {
Set set = new HashSet<>();
for (Service service : servicesToStop) {
if (type.isInstance(service)) {
set.add((T) service);
}
}
return set;
}
public void deferStartService(Object object, boolean stopOnShutdown) throws Exception {
if (object instanceof Service) {
Service service = (Service) object;
// only add to services to close if its a singleton
// otherwise we could for example end up with a lot of prototype scope endpoints
boolean singleton = true; // assume singleton by default
if (object instanceof IsSingleton) {
singleton = ((IsSingleton) service).isSingleton();
}
// do not add endpoints as they have their own list
if (singleton && !(service instanceof Endpoint)) {
// only add to list of services to stop if its not already there
if (stopOnShutdown && !hasService(service)) {
servicesToStop.add(service);
}
}
// are we already started?
if (isStarted()) {
ServiceHelper.startService(service);
} else {
deferStartupListener.addService(service);
}
}
}
public void addStartupListener(StartupListener listener) throws Exception {
// either add to listener so we can invoke then later when CamelContext has been started
// or invoke the callback right now
if (isStarted()) {
listener.onCamelContextStarted(this, true);
} else {
startupListeners.add(listener);
}
}
public String resolveComponentDefaultName(String javaType) {
// special for some components
// TODO: ActiveMQ 5.11 will include this out of the box, so not needed when its released
if ("org.apache.activemq.camel.component.ActiveMQComponent".equals(javaType)) {
return "jms";
}
// try to find the component by its java type from the in-use components
if (javaType != null) {
// find all the components which will include the default component name
try {
Map all = CamelContextHelper.findComponents(this);
for (Map.Entry entry : all.entrySet()) {
String fqn = (String) entry.getValue().get("class");
if (javaType.equals(fqn)) {
// is there component docs for that name?
String name = entry.getKey();
String json = getComponentParameterJsonSchema(name);
if (json != null) {
return name;
}
}
}
} catch (Exception e) {
// ignore
return null;
}
}
// could not find a component with that name
return null;
}
public Map findComponents() throws LoadPropertiesException, IOException {
return CamelContextHelper.findComponents(this);
}
public Map findEips() throws LoadPropertiesException, IOException {
return CamelContextHelper.findEips(this);
}
public String getComponentDocumentation(String componentName) throws IOException {
return null;
}
public String getComponentParameterJsonSchema(String componentName) throws IOException {
// use the component factory finder to find the package name of the component class, which is the location
// where the documentation exists as well
FactoryFinder finder = getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH);
try {
Class clazz = null;
try {
clazz = finder.findClass(componentName);
} catch (NoFactoryAvailableException e) {
// ignore, i.e. if a component is an auto-configured spring-boot
// component
}
if (clazz == null) {
// fallback and find existing component
Component existing = hasComponent(componentName);
if (existing != null) {
clazz = existing.getClass();
} else {
return null;
}
}
String packageName = clazz.getPackage().getName();
packageName = packageName.replace('.', '/');
String path = packageName + "/" + componentName + ".json";
ClassResolver resolver = getClassResolver();
InputStream inputStream = resolver.loadResourceAsStream(path);
log.debug("Loading component JSON Schema for: {} using class resolver: {} -> {}", componentName, resolver, inputStream);
if (inputStream != null) {
try {
return IOHelper.loadText(inputStream);
} finally {
IOHelper.close(inputStream);
}
}
// special for ActiveMQ as it is really just JMS
if ("ActiveMQComponent".equals(clazz.getSimpleName())) {
return getComponentParameterJsonSchema("jms");
} else {
return null;
}
} catch (ClassNotFoundException e) {
return null;
}
}
public String getDataFormatParameterJsonSchema(String dataFormatName) throws IOException {
// use the dataformat factory finder to find the package name of the dataformat class, which is the location
// where the documentation exists as well
FactoryFinder finder = getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH);
try {
Class clazz = null;
try {
clazz = finder.findClass(dataFormatName);
} catch (NoFactoryAvailableException e) {
// ignore, i.e. if a component is an auto-configured spring-boot
// data-formats
}
if (clazz == null) {
return null;
}
String packageName = clazz.getPackage().getName();
packageName = packageName.replace('.', '/');
String path = packageName + "/" + dataFormatName + ".json";
ClassResolver resolver = getClassResolver();
InputStream inputStream = resolver.loadResourceAsStream(path);
log.debug("Loading dataformat JSON Schema for: {} using class resolver: {} -> {}", dataFormatName, resolver, inputStream);
if (inputStream != null) {
try {
return IOHelper.loadText(inputStream);
} finally {
IOHelper.close(inputStream);
}
}
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
public String getLanguageParameterJsonSchema(String languageName) throws IOException {
// use the language factory finder to find the package name of the language class, which is the location
// where the documentation exists as well
FactoryFinder finder = getFactoryFinder(DefaultLanguageResolver.LANGUAGE_RESOURCE_PATH);
try {
Class clazz = null;
try {
clazz = finder.findClass(languageName);
} catch (NoFactoryAvailableException e) {
// ignore, i.e. if a component is an auto-configured spring-boot
// languages
}
if (clazz == null) {
return null;
}
String packageName = clazz.getPackage().getName();
packageName = packageName.replace('.', '/');
String path = packageName + "/" + languageName + ".json";
ClassResolver resolver = getClassResolver();
InputStream inputStream = resolver.loadResourceAsStream(path);
log.debug("Loading language JSON Schema for: {} using class resolver: {} -> {}", languageName, resolver, inputStream);
if (inputStream != null) {
try {
return IOHelper.loadText(inputStream);
} finally {
IOHelper.close(inputStream);
}
}
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
public String getEipParameterJsonSchema(String eipName) throws IOException {
// the eip json schema may be in some of the sub-packages so look until we find it
String[] subPackages = new String[]{"", "/config", "/dataformat", "/language", "/loadbalancer", "/rest"};
for (String sub : subPackages) {
String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub + "/" + eipName + ".json";
ClassResolver resolver = getClassResolver();
InputStream inputStream = resolver.loadResourceAsStream(path);
if (inputStream != null) {
log.debug("Loading eip JSON Schema for: {} using class resolver: {} -> {}", eipName, resolver, inputStream);
try {
return IOHelper.loadText(inputStream);
} finally {
IOHelper.close(inputStream);
}
}
}
return null;
}
public String explainEipJson(String nameOrId, boolean includeAllOptions) {
try {
// try to find the id within all known routes and their eips
String eipName = nameOrId;
NamedNode target = null;
for (RouteDefinition route : getRouteDefinitions()) {
if (route.getId().equals(nameOrId)) {
target = route;
break;
}
for (FromDefinition from : route.getInputs()) {
if (nameOrId.equals(from.getId())) {
target = route;
break;
}
}
Iterator it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class);
while (it.hasNext()) {
ProcessorDefinition def = it.next();
if (nameOrId.equals(def.getId())) {
target = def;
break;
}
}
if (target != null) {
break;
}
}
if (target != null) {
eipName = target.getShortName();
}
String json = getEipParameterJsonSchema(eipName);
if (json == null) {
return null;
}
// overlay with runtime parameters that id uses at runtime
if (target != null) {
List