001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.camel.impl; 018 019import java.io.IOException; 020import java.io.InputStream; 021import java.net.URI; 022import java.util.ArrayList; 023import java.util.Arrays; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.Comparator; 027import java.util.Date; 028import java.util.HashMap; 029import java.util.HashSet; 030import java.util.Iterator; 031import java.util.LinkedHashMap; 032import java.util.LinkedHashSet; 033import java.util.List; 034import java.util.Map; 035import java.util.Properties; 036import java.util.Set; 037import java.util.TreeMap; 038import java.util.concurrent.Callable; 039import java.util.concurrent.ConcurrentHashMap; 040import java.util.concurrent.CopyOnWriteArrayList; 041import java.util.concurrent.ScheduledExecutorService; 042import java.util.concurrent.TimeUnit; 043import java.util.concurrent.atomic.AtomicBoolean; 044import java.util.concurrent.atomic.AtomicInteger; 045import java.util.function.Function; 046 047import javax.management.MalformedObjectNameException; 048import javax.management.ObjectName; 049import javax.naming.Context; 050import javax.xml.bind.JAXBContext; 051import javax.xml.bind.Unmarshaller; 052 053import org.apache.camel.CamelContext; 054import org.apache.camel.CamelContextAware; 055import org.apache.camel.Component; 056import org.apache.camel.Consumer; 057import org.apache.camel.ConsumerTemplate; 058import org.apache.camel.Endpoint; 059import org.apache.camel.ErrorHandlerFactory; 060import org.apache.camel.ExtendedStartupListener; 061import org.apache.camel.FailedToStartRouteException; 062import org.apache.camel.FluentProducerTemplate; 063import org.apache.camel.IsSingleton; 064import org.apache.camel.MultipleConsumersSupport; 065import org.apache.camel.NamedNode; 066import org.apache.camel.NoFactoryAvailableException; 067import org.apache.camel.NoSuchEndpointException; 068import org.apache.camel.PollingConsumer; 069import org.apache.camel.Processor; 070import org.apache.camel.Producer; 071import org.apache.camel.ProducerTemplate; 072import org.apache.camel.ResolveEndpointFailedException; 073import org.apache.camel.Route; 074import org.apache.camel.RoutesBuilder; 075import org.apache.camel.RuntimeCamelException; 076import org.apache.camel.Service; 077import org.apache.camel.ServiceStatus; 078import org.apache.camel.ShutdownRoute; 079import org.apache.camel.ShutdownRunningTask; 080import org.apache.camel.StartupListener; 081import org.apache.camel.StatefulService; 082import org.apache.camel.Suspendable; 083import org.apache.camel.SuspendableService; 084import org.apache.camel.TypeConverter; 085import org.apache.camel.VetoCamelContextStartException; 086import org.apache.camel.api.management.mbean.ManagedCamelContextMBean; 087import org.apache.camel.api.management.mbean.ManagedProcessorMBean; 088import org.apache.camel.api.management.mbean.ManagedRouteMBean; 089import org.apache.camel.builder.DefaultFluentProducerTemplate; 090import org.apache.camel.builder.ErrorHandlerBuilder; 091import org.apache.camel.builder.ErrorHandlerBuilderSupport; 092import org.apache.camel.component.properties.PropertiesComponent; 093import org.apache.camel.health.HealthCheckRegistry; 094import org.apache.camel.impl.converter.BaseTypeConverterRegistry; 095import org.apache.camel.impl.converter.DefaultTypeConverter; 096import org.apache.camel.impl.converter.LazyLoadingTypeConverter; 097import org.apache.camel.impl.health.DefaultHealthCheckRegistry; 098import org.apache.camel.impl.transformer.TransformerKey; 099import org.apache.camel.impl.validator.ValidatorKey; 100import org.apache.camel.management.DefaultManagementMBeanAssembler; 101import org.apache.camel.management.DefaultManagementStrategy; 102import org.apache.camel.management.JmxSystemPropertyKeys; 103import org.apache.camel.management.ManagementStrategyFactory; 104import org.apache.camel.model.DataFormatDefinition; 105import org.apache.camel.model.FromDefinition; 106import org.apache.camel.model.HystrixConfigurationDefinition; 107import org.apache.camel.model.ModelCamelContext; 108import org.apache.camel.model.ModelHelper; 109import org.apache.camel.model.ProcessorDefinition; 110import org.apache.camel.model.ProcessorDefinitionHelper; 111import org.apache.camel.model.RouteDefinition; 112import org.apache.camel.model.RouteDefinitionHelper; 113import org.apache.camel.model.RoutesDefinition; 114import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; 115import org.apache.camel.model.rest.RestDefinition; 116import org.apache.camel.model.rest.RestsDefinition; 117import org.apache.camel.model.transformer.TransformerDefinition; 118import org.apache.camel.model.validator.ValidatorDefinition; 119import org.apache.camel.processor.interceptor.BacklogDebugger; 120import org.apache.camel.processor.interceptor.BacklogTracer; 121import org.apache.camel.processor.interceptor.Debug; 122import org.apache.camel.processor.interceptor.Delayer; 123import org.apache.camel.processor.interceptor.HandleFault; 124import org.apache.camel.processor.interceptor.StreamCaching; 125import org.apache.camel.processor.interceptor.Tracer; 126import org.apache.camel.runtimecatalog.DefaultRuntimeCamelCatalog; 127import org.apache.camel.runtimecatalog.RuntimeCamelCatalog; 128import org.apache.camel.spi.AsyncProcessorAwaitManager; 129import org.apache.camel.spi.CamelContextNameStrategy; 130import org.apache.camel.spi.ClassResolver; 131import org.apache.camel.spi.ComponentResolver; 132import org.apache.camel.spi.Container; 133import org.apache.camel.spi.DataFormat; 134import org.apache.camel.spi.DataFormatResolver; 135import org.apache.camel.spi.DataType; 136import org.apache.camel.spi.Debugger; 137import org.apache.camel.spi.EndpointRegistry; 138import org.apache.camel.spi.EndpointStrategy; 139import org.apache.camel.spi.EventNotifier; 140import org.apache.camel.spi.ExecutorServiceManager; 141import org.apache.camel.spi.FactoryFinder; 142import org.apache.camel.spi.FactoryFinderResolver; 143import org.apache.camel.spi.HeadersMapFactory; 144import org.apache.camel.spi.InflightRepository; 145import org.apache.camel.spi.Injector; 146import org.apache.camel.spi.InterceptStrategy; 147import org.apache.camel.spi.Language; 148import org.apache.camel.spi.LanguageResolver; 149import org.apache.camel.spi.LifecycleStrategy; 150import org.apache.camel.spi.LogListener; 151import org.apache.camel.spi.ManagementMBeanAssembler; 152import org.apache.camel.spi.ManagementNameStrategy; 153import org.apache.camel.spi.ManagementStrategy; 154import org.apache.camel.spi.MessageHistoryFactory; 155import org.apache.camel.spi.ModelJAXBContextFactory; 156import org.apache.camel.spi.NodeIdFactory; 157import org.apache.camel.spi.PackageScanClassResolver; 158import org.apache.camel.spi.ProcessorFactory; 159import org.apache.camel.spi.Registry; 160import org.apache.camel.spi.ReloadStrategy; 161import org.apache.camel.spi.RestConfiguration; 162import org.apache.camel.spi.RestRegistry; 163import org.apache.camel.spi.RouteContext; 164import org.apache.camel.spi.RouteController; 165import org.apache.camel.spi.RouteError; 166import org.apache.camel.spi.RoutePolicyFactory; 167import org.apache.camel.spi.RouteStartupOrder; 168import org.apache.camel.spi.RuntimeEndpointRegistry; 169import org.apache.camel.spi.ServicePool; 170import org.apache.camel.spi.ShutdownStrategy; 171import org.apache.camel.spi.StreamCachingStrategy; 172import org.apache.camel.spi.Transformer; 173import org.apache.camel.spi.TransformerRegistry; 174import org.apache.camel.spi.TypeConverterRegistry; 175import org.apache.camel.spi.UnitOfWorkFactory; 176import org.apache.camel.spi.UuidGenerator; 177import org.apache.camel.spi.Validator; 178import org.apache.camel.spi.ValidatorRegistry; 179import org.apache.camel.support.ServiceSupport; 180import org.apache.camel.util.CamelContextHelper; 181import org.apache.camel.util.CollectionStringBuffer; 182import org.apache.camel.util.EndpointHelper; 183import org.apache.camel.util.EventHelper; 184import org.apache.camel.util.IOHelper; 185import org.apache.camel.util.IntrospectionSupport; 186import org.apache.camel.util.JsonSchemaHelper; 187import org.apache.camel.util.LoadPropertiesException; 188import org.apache.camel.util.ObjectHelper; 189import org.apache.camel.util.OrderedComparator; 190import org.apache.camel.util.ServiceHelper; 191import org.apache.camel.util.StopWatch; 192import org.apache.camel.util.StringHelper; 193import org.apache.camel.util.StringQuoteHelper; 194import org.apache.camel.util.TimeUtils; 195import org.apache.camel.util.URISupport; 196import org.apache.camel.util.jsse.SSLContextParameters; 197import org.slf4j.Logger; 198import org.slf4j.LoggerFactory; 199import org.slf4j.MDC; 200 201import static org.apache.camel.impl.MDCUnitOfWork.MDC_CAMEL_CONTEXT_ID; 202 203/** 204 * Represents the context used to configure routes and the policies to use. 205 * 206 * @version 207 */ 208@SuppressWarnings("deprecation") 209public class DefaultCamelContext extends ServiceSupport implements ModelCamelContext, Suspendable { 210 private final Logger log = LoggerFactory.getLogger(getClass()); 211 private final AtomicBoolean vetoStated = new AtomicBoolean(); 212 private JAXBContext jaxbContext; 213 private CamelContextNameStrategy nameStrategy = createCamelContextNameStrategy(); 214 private ManagementNameStrategy managementNameStrategy = createManagementNameStrategy(); 215 private String managementName; 216 private ClassLoader applicationContextClassLoader; 217 private EndpointRegistry<EndpointKey> endpoints; 218 private final AtomicInteger endpointKeyCounter = new AtomicInteger(); 219 private final List<EndpointStrategy> endpointStrategies = new ArrayList<>(); 220 private final Map<String, Component> components = new ConcurrentHashMap<>(); 221 private final Set<Route> routes = new LinkedHashSet<>(); 222 private final List<Service> servicesToStop = new CopyOnWriteArrayList<>(); 223 private final List<StartupListener> startupListeners = new CopyOnWriteArrayList<>(); 224 private final DeferServiceStartupListener deferStartupListener = new DeferServiceStartupListener(); 225 private TypeConverter typeConverter; 226 private TypeConverterRegistry typeConverterRegistry; 227 private Injector injector; 228 private ComponentResolver componentResolver; 229 private boolean autoCreateComponents = true; 230 private LanguageResolver languageResolver; 231 private final Map<String, Language> languages = new HashMap<>(); 232 private Registry registry; 233 private List<LifecycleStrategy> lifecycleStrategies = new CopyOnWriteArrayList<>(); 234 private ManagementStrategy managementStrategy; 235 private ManagementMBeanAssembler managementMBeanAssembler; 236 private final List<RouteDefinition> routeDefinitions = new ArrayList<>(); 237 private final List<RestDefinition> restDefinitions = new ArrayList<>(); 238 private Map<String, RestConfiguration> restConfigurations = new ConcurrentHashMap<>(); 239 private Map<String, ServiceCallConfigurationDefinition> serviceCallConfigurations = new ConcurrentHashMap<>(); 240 private Map<String, HystrixConfigurationDefinition> hystrixConfigurations = new ConcurrentHashMap<>(); 241 private RestRegistry restRegistry = new DefaultRestRegistry(); 242 private List<InterceptStrategy> interceptStrategies = new ArrayList<>(); 243 private List<RoutePolicyFactory> routePolicyFactories = new ArrayList<>(); 244 private Set<LogListener> logListeners = new LinkedHashSet<>(); 245 private HeadersMapFactory headersMapFactory = createHeadersMapFactory(); 246 // special flags to control the first startup which can are special 247 private volatile boolean firstStartDone; 248 private volatile boolean doNotStartRoutesOnFirstStart; 249 private final ThreadLocal<Boolean> isStartingRoutes = new ThreadLocal<>(); 250 private final ThreadLocal<Boolean> isSetupRoutes = new ThreadLocal<>(); 251 private Boolean autoStartup = Boolean.TRUE; 252 private Boolean trace = Boolean.FALSE; 253 private Boolean messageHistory = Boolean.TRUE; 254 private Boolean logMask = Boolean.FALSE; 255 private Boolean logExhaustedMessageBody = Boolean.FALSE; 256 private Boolean streamCache = Boolean.FALSE; 257 private Boolean handleFault = Boolean.FALSE; 258 private Boolean disableJMX = Boolean.FALSE; 259 private Boolean lazyLoadTypeConverters = Boolean.FALSE; 260 private Boolean loadTypeConverters = Boolean.TRUE; 261 private Boolean typeConverterStatisticsEnabled = Boolean.FALSE; 262 private Boolean useMDCLogging = Boolean.FALSE; 263 private Boolean useDataType = Boolean.FALSE; 264 private Boolean useBreadcrumb = Boolean.TRUE; 265 private Boolean allowUseOriginalMessage = Boolean.FALSE; 266 private Long delay; 267 private ErrorHandlerFactory errorHandlerBuilder; 268 private final Object errorHandlerExecutorServiceLock = new Object(); 269 private ScheduledExecutorService errorHandlerExecutorService; 270 private Map<String, DataFormatDefinition> dataFormats = new HashMap<>(); 271 private DataFormatResolver dataFormatResolver; 272 private Map<String, String> globalOptions = new HashMap<>(); 273 private FactoryFinderResolver factoryFinderResolver; 274 private FactoryFinder defaultFactoryFinder; 275 private PropertiesComponent propertiesComponent; 276 private StreamCachingStrategy streamCachingStrategy; 277 private final Map<String, FactoryFinder> factories = new HashMap<>(); 278 private final Map<String, RouteService> routeServices = new LinkedHashMap<>(); 279 private final Map<String, RouteService> suspendedRouteServices = new LinkedHashMap<>(); 280 private ClassResolver classResolver = createClassResolver(); 281 private PackageScanClassResolver packageScanClassResolver; 282 // we use a capacity of 100 per endpoint, so for the same endpoint we have at most 100 producers in the pool 283 // so if we have 6 endpoints in the pool, we can have 6 x 100 producers in total 284 private ServicePool<Endpoint, Producer> producerServicePool = createProducerServicePool(); 285 private ServicePool<Endpoint, PollingConsumer> pollingConsumerServicePool = createPollingConsumerServicePool(); 286 private NodeIdFactory nodeIdFactory = createNodeIdFactory(); 287 private ProcessorFactory processorFactory = createProcessorFactory(); 288 private MessageHistoryFactory messageHistoryFactory = createMessageHistoryFactory(); 289 private InterceptStrategy defaultTracer; 290 private InterceptStrategy defaultBacklogTracer; 291 private InterceptStrategy defaultBacklogDebugger; 292 private InflightRepository inflightRepository = createInflightRepository(); 293 private AsyncProcessorAwaitManager asyncProcessorAwaitManager = createAsyncProcessorAwaitManager(); 294 private RuntimeEndpointRegistry runtimeEndpointRegistry; 295 private final List<RouteStartupOrder> routeStartupOrder = new ArrayList<>(); 296 // start auto assigning route ids using numbering 1000 and upwards 297 private int defaultRouteStartupOrder = 1000; 298 private ShutdownStrategy shutdownStrategy = createShutdownStrategy(); 299 private ShutdownRoute shutdownRoute = ShutdownRoute.Default; 300 private ShutdownRunningTask shutdownRunningTask = ShutdownRunningTask.CompleteCurrentTaskOnly; 301 private ExecutorServiceManager executorServiceManager; 302 private Debugger debugger; 303 private UuidGenerator uuidGenerator = createDefaultUuidGenerator(); 304 private UnitOfWorkFactory unitOfWorkFactory = createUnitOfWorkFactory(); 305 private final StopWatch stopWatch = new StopWatch(false); 306 private Date startDate; 307 private ModelJAXBContextFactory modelJAXBContextFactory; 308 private List<TransformerDefinition> transformers = new ArrayList<>(); 309 private TransformerRegistry<TransformerKey> transformerRegistry; 310 private List<ValidatorDefinition> validators = new ArrayList<>(); 311 private ValidatorRegistry<ValidatorKey> validatorRegistry; 312 private ReloadStrategy reloadStrategy; 313 private final RuntimeCamelCatalog runtimeCamelCatalog = createRuntimeCamelCatalog(); 314 private SSLContextParameters sslContextParameters; 315 private final ThreadLocal<Set<String>> componentsInCreation = new ThreadLocal<Set<String>>() { 316 @Override 317 public Set<String> initialValue() { 318 return new HashSet<>(); 319 } 320 }; 321 private RouteController routeController = createRouteController(); 322 private HealthCheckRegistry healthCheckRegistry = createHealthCheckRegistry(); 323 324 325 /** 326 * Creates the {@link CamelContext} using {@link JndiRegistry} as registry, 327 * but will silently fallback and use {@link SimpleRegistry} if JNDI cannot be used. 328 * <p/> 329 * Use one of the other constructors to force use an explicit registry / JNDI. 330 */ 331 public DefaultCamelContext() { 332 this.executorServiceManager = createExecutorServiceManager(); 333 334 // create a provisional (temporary) endpoint registry at first since end users may access endpoints before CamelContext is started 335 // we will later transfer the endpoints to the actual DefaultEndpointRegistry later, but we do this to starup Camel faster. 336 this.endpoints = new ProvisionalEndpointRegistry(); 337 338 // add the defer service startup listener 339 this.startupListeners.add(deferStartupListener); 340 341 packageScanClassResolver = createPackageScanClassResolver(); 342 343 // setup management strategy first since end users may use it to add event notifiers 344 // using the management strategy before the CamelContext has been started 345 this.managementStrategy = createManagementStrategy(); 346 this.managementMBeanAssembler = createManagementMBeanAssembler(); 347 348 // Call all registered trackers with this context 349 // Note, this may use a partially constructed object 350 CamelContextTrackerRegistry.INSTANCE.contextCreated(this); 351 } 352 353 /** 354 * Creates the {@link CamelContext} using the given JNDI context as the registry 355 * 356 * @param jndiContext the JNDI context 357 */ 358 public DefaultCamelContext(Context jndiContext) { 359 this(); 360 setJndiContext(jndiContext); 361 } 362 363 /** 364 * Creates the {@link CamelContext} using the given registry 365 * 366 * @param registry the registry 367 */ 368 public DefaultCamelContext(Registry registry) { 369 this(); 370 setRegistry(registry); 371 } 372 373 public <T extends CamelContext> T adapt(Class<T> type) { 374 return type.cast(this); 375 } 376 377 public boolean isVetoStarted() { 378 return vetoStated.get(); 379 } 380 381 public String getName() { 382 return getNameStrategy().getName(); 383 } 384 385 /** 386 * Sets the name of the this context. 387 * 388 * @param name the name 389 */ 390 public void setName(String name) { 391 // use an explicit name strategy since an explicit name was provided to be used 392 this.nameStrategy = new ExplicitCamelContextNameStrategy(name); 393 } 394 395 public CamelContextNameStrategy getNameStrategy() { 396 return nameStrategy; 397 } 398 399 public void setNameStrategy(CamelContextNameStrategy nameStrategy) { 400 this.nameStrategy = nameStrategy; 401 } 402 403 public ManagementNameStrategy getManagementNameStrategy() { 404 return managementNameStrategy; 405 } 406 407 public void setManagementNameStrategy(ManagementNameStrategy managementNameStrategy) { 408 this.managementNameStrategy = managementNameStrategy; 409 } 410 411 public String getManagementName() { 412 return managementName; 413 } 414 415 public void setManagementName(String managementName) { 416 this.managementName = managementName; 417 } 418 419 public Component hasComponent(String componentName) { 420 return components.get(componentName); 421 } 422 423 public void addComponent(String componentName, final Component component) { 424 ObjectHelper.notNull(component, "component"); 425 component.setCamelContext(this); 426 Component oldValue = components.putIfAbsent(componentName, component); 427 if (oldValue != null) { 428 throw new IllegalArgumentException("Cannot add component as its already previously added: " + componentName); 429 } 430 postInitComponent(componentName, component); 431 } 432 433 private void postInitComponent(String componentName, final Component component) { 434 for (LifecycleStrategy strategy : lifecycleStrategies) { 435 strategy.onComponentAdd(componentName, component); 436 } 437 438 // keep reference to properties component up to date 439 if (component instanceof PropertiesComponent && "properties".equals(componentName)) { 440 propertiesComponent = (PropertiesComponent) component; 441 } 442 } 443 444 public Component getComponent(String name) { 445 return getComponent(name, autoCreateComponents, true); 446 } 447 448 public Component getComponent(String name, boolean autoCreateComponents) { 449 return getComponent(name, autoCreateComponents, true); 450 } 451 452 public Component getComponent(String name, boolean autoCreateComponents, boolean autoStart) { 453 // Check if the named component is already being created, that would mean 454 // that the initComponent has triggered a new getComponent 455 if (componentsInCreation.get().contains(name)) { 456 throw new IllegalStateException("Circular dependency detected, the component " + name + " is already being created"); 457 } 458 459 try { 460 // Flag used to mark a component of being created. 461 final AtomicBoolean created = new AtomicBoolean(false); 462 463 // atomic operation to get/create a component. Avoid global locks. 464 final Component component = components.computeIfAbsent(name, new Function<String, Component>() { 465 @Override 466 public Component apply(String comp) { 467 created.set(true); 468 return DefaultCamelContext.this.initComponent(name, autoCreateComponents); 469 } 470 }); 471 472 // Start the component after its creation as if it is a component proxy 473 // that creates/start a delegated component, we may end up in a deadlock 474 if (component != null && created.get() && autoStart && (isStarted() || isStarting())) { 475 // If the component is looked up after the context is started, 476 // lets start it up. 477 if (component instanceof Service) { 478 startService((Service)component); 479 } 480 } 481 482 return component; 483 } catch (Exception e) { 484 throw new RuntimeCamelException("Cannot auto create component: " + name, e); 485 } finally { 486 // remove the reference to the component being created 487 componentsInCreation.get().remove(name); 488 } 489 } 490 491 /** 492 * Function to initialize a component and auto start. Returns null if the autoCreateComponents is disabled 493 */ 494 private Component initComponent(String name, boolean autoCreateComponents) { 495 Component component = null; 496 if (autoCreateComponents) { 497 try { 498 if (log.isDebugEnabled()) { 499 log.debug("Using ComponentResolver: {} to resolve component with name: {}", getComponentResolver(), name); 500 } 501 502 // Mark the component as being created so we can detect circular 503 // requests. 504 // 505 // In spring apps, the component resolver may trigger a new getComponent 506 // because of the underlying bean factory and as the endpoints are 507 // registered as singleton, the spring factory creates the bean 508 // and then check the type so the getComponent is always triggered. 509 // 510 // Simple circular dependency: 511 // 512 // <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> 513 // <route> 514 // <from id="twitter" uri="twitter://timeline/home?type=polling"/> 515 // <log message="Got ${body}"/> 516 // </route> 517 // </camelContext> 518 // 519 // Complex circular dependency: 520 // 521 // <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring"> 522 // <route> 523 // <from id="log" uri="seda:test"/> 524 // <to id="seda" uri="log:test"/> 525 // </route> 526 // </camelContext> 527 // 528 // This would freeze the app (lock or infinite loop). 529 // 530 // See https://issues.apache.org/jira/browse/CAMEL-11225 531 componentsInCreation.get().add(name); 532 533 component = getComponentResolver().resolveComponent(name, this); 534 if (component != null) { 535 component.setCamelContext(this); 536 postInitComponent(name, component); 537 } 538 } catch (Exception e) { 539 throw new RuntimeCamelException("Cannot auto create component: " + name, e); 540 } 541 } 542 return component; 543 } 544 545 public <T extends Component> T getComponent(String name, Class<T> componentType) { 546 Component component = getComponent(name); 547 if (componentType.isInstance(component)) { 548 return componentType.cast(component); 549 } else { 550 String message; 551 if (component == null) { 552 message = "Did not find component given by the name: " + name; 553 } else { 554 message = "Found component of type: " + component.getClass() + " instead of expected: " + componentType; 555 } 556 throw new IllegalArgumentException(message); 557 } 558 } 559 560 public Component resolveComponent(String name) { 561 Component answer = hasComponent(name); 562 if (answer == null) { 563 try { 564 answer = getComponentResolver().resolveComponent(name, this); 565 } catch (Exception e) { 566 throw new RuntimeCamelException("Cannot resolve component: " + name, e); 567 } 568 } 569 return answer; 570 } 571 572 public Component removeComponent(String componentName) { 573 Component oldComponent = components.remove(componentName); 574 if (oldComponent != null) { 575 try { 576 stopServices(oldComponent); 577 } catch (Exception e) { 578 log.warn("Error stopping component " + oldComponent + ". This exception will be ignored.", e); 579 } 580 for (LifecycleStrategy strategy : lifecycleStrategies) { 581 strategy.onComponentRemove(componentName, oldComponent); 582 } 583 } 584 // keep reference to properties component up to date 585 if (oldComponent != null && "properties".equals(componentName)) { 586 propertiesComponent = null; 587 } 588 return oldComponent; 589 } 590 591 // Endpoint Management Methods 592 // ----------------------------------------------------------------------- 593 594 public EndpointRegistry<EndpointKey> getEndpointRegistry() { 595 return endpoints; 596 } 597 598 public Collection<Endpoint> getEndpoints() { 599 return new ArrayList<>(endpoints.values()); 600 } 601 602 public Map<String, Endpoint> getEndpointMap() { 603 Map<String, Endpoint> answer = new TreeMap<>(); 604 for (Map.Entry<EndpointKey, Endpoint> entry : endpoints.entrySet()) { 605 answer.put(entry.getKey().get(), entry.getValue()); 606 } 607 return answer; 608 } 609 610 public Endpoint hasEndpoint(String uri) { 611 return endpoints.get(getEndpointKey(uri)); 612 } 613 614 public Endpoint addEndpoint(String uri, Endpoint endpoint) throws Exception { 615 Endpoint oldEndpoint; 616 617 startService(endpoint); 618 oldEndpoint = endpoints.remove(getEndpointKey(uri)); 619 for (LifecycleStrategy strategy : lifecycleStrategies) { 620 strategy.onEndpointAdd(endpoint); 621 } 622 addEndpointToRegistry(uri, endpoint); 623 if (oldEndpoint != null) { 624 stopServices(oldEndpoint); 625 } 626 627 return oldEndpoint; 628 } 629 630 public void removeEndpoint(Endpoint endpoint) throws Exception { 631 removeEndpoints(endpoint.getEndpointUri()); 632 } 633 634 public Collection<Endpoint> removeEndpoints(String uri) throws Exception { 635 Collection<Endpoint> answer = new ArrayList<>(); 636 Endpoint oldEndpoint = endpoints.remove(getEndpointKey(uri)); 637 if (oldEndpoint != null) { 638 answer.add(oldEndpoint); 639 stopServices(oldEndpoint); 640 } else { 641 for (Map.Entry<EndpointKey, Endpoint> entry : endpoints.entrySet()) { 642 oldEndpoint = entry.getValue(); 643 if (EndpointHelper.matchEndpoint(this, oldEndpoint.getEndpointUri(), uri)) { 644 try { 645 stopServices(oldEndpoint); 646 } catch (Exception e) { 647 log.warn("Error stopping endpoint " + oldEndpoint + ". This exception will be ignored.", e); 648 } 649 answer.add(oldEndpoint); 650 endpoints.remove(entry.getKey()); 651 } 652 } 653 } 654 655 // notify lifecycle its being removed 656 for (Endpoint endpoint : answer) { 657 for (LifecycleStrategy strategy : lifecycleStrategies) { 658 strategy.onEndpointRemove(endpoint); 659 } 660 } 661 662 return answer; 663 } 664 665 public Endpoint getEndpoint(String uri) { 666 StringHelper.notEmpty(uri, "uri"); 667 668 log.trace("Getting endpoint with uri: {}", uri); 669 670 // in case path has property placeholders then try to let property component resolve those 671 try { 672 uri = resolvePropertyPlaceholders(uri); 673 } catch (Exception e) { 674 throw new ResolveEndpointFailedException(uri, e); 675 } 676 677 final String rawUri = uri; 678 679 // normalize uri so we can do endpoint hits with minor mistakes and parameters is not in the same order 680 uri = normalizeEndpointUri(uri); 681 682 log.trace("Getting endpoint with raw uri: {}, normalized uri: {}", rawUri, uri); 683 684 Endpoint answer; 685 String scheme = null; 686 // use optimized method to get the endpoint uri 687 EndpointKey key = getEndpointKeyPreNormalized(uri); 688 answer = endpoints.get(key); 689 if (answer == null) { 690 try { 691 // Use the URI prefix to find the component. 692 String splitURI[] = StringHelper.splitOnCharacter(uri, ":", 2); 693 if (splitURI[1] != null) { 694 scheme = splitURI[0]; 695 log.trace("Endpoint uri: {} is from component with name: {}", uri, scheme); 696 Component component = getComponent(scheme); 697 698 // Ask the component to resolve the endpoint. 699 if (component != null) { 700 log.trace("Creating endpoint from uri: {} using component: {}", uri, component); 701 702 // Have the component create the endpoint if it can. 703 if (component.useRawUri()) { 704 answer = component.createEndpoint(rawUri); 705 } else { 706 answer = component.createEndpoint(uri); 707 } 708 709 if (answer != null && log.isDebugEnabled()) { 710 log.debug("{} converted to endpoint: {} by component: {}", URISupport.sanitizeUri(uri), answer, component); 711 } 712 } 713 } 714 715 if (answer == null) { 716 // no component then try in registry and elsewhere 717 answer = createEndpoint(uri); 718 log.trace("No component to create endpoint from uri: {} fallback lookup in registry -> {}", uri, answer); 719 } 720 721 if (answer == null && splitURI[1] == null) { 722 // the uri has no context-path which is rare and it was not referring to an endpoint in the registry 723 // so try to see if it can be created by a component 724 725 int pos = uri.indexOf('?'); 726 String componentName = pos > 0 ? uri.substring(0, pos) : uri; 727 728 Component component = getComponent(componentName); 729 730 // Ask the component to resolve the endpoint. 731 if (component != null) { 732 log.trace("Creating endpoint from uri: {} using component: {}", uri, component); 733 734 // Have the component create the endpoint if it can. 735 if (component.useRawUri()) { 736 answer = component.createEndpoint(rawUri); 737 } else { 738 answer = component.createEndpoint(uri); 739 } 740 741 if (answer != null && log.isDebugEnabled()) { 742 log.debug("{} converted to endpoint: {} by component: {}", URISupport.sanitizeUri(uri), answer, component); 743 } 744 } 745 746 } 747 748 if (answer != null) { 749 addService(answer); 750 answer = addEndpointToRegistry(uri, answer); 751 } 752 } catch (Exception e) { 753 throw new ResolveEndpointFailedException(uri, e); 754 } 755 } 756 757 // unknown scheme 758 if (answer == null && scheme != null) { 759 throw new ResolveEndpointFailedException(uri, "No component found with scheme: " + scheme); 760 } 761 762 return answer; 763 } 764 765 public <T extends Endpoint> T getEndpoint(String name, Class<T> endpointType) { 766 Endpoint endpoint = getEndpoint(name); 767 if (endpoint == null) { 768 throw new NoSuchEndpointException(name); 769 } 770 if (endpoint instanceof InterceptSendToEndpoint) { 771 endpoint = ((InterceptSendToEndpoint) endpoint).getDelegate(); 772 } 773 if (endpointType.isInstance(endpoint)) { 774 return endpointType.cast(endpoint); 775 } else { 776 throw new IllegalArgumentException("The endpoint is not of type: " + endpointType 777 + " but is: " + endpoint.getClass().getCanonicalName()); 778 } 779 } 780 781 public void addRegisterEndpointCallback(EndpointStrategy strategy) { 782 if (!endpointStrategies.contains(strategy)) { 783 // let it be invoked for already registered endpoints so it can catch-up. 784 endpointStrategies.add(strategy); 785 for (Endpoint endpoint : getEndpoints()) { 786 Endpoint newEndpoint = strategy.registerEndpoint(endpoint.getEndpointUri(), endpoint); 787 if (newEndpoint != null) { 788 // put will replace existing endpoint with the new endpoint 789 endpoints.put(getEndpointKey(endpoint.getEndpointUri()), newEndpoint); 790 } 791 } 792 } 793 } 794 795 /** 796 * Strategy to add the given endpoint to the internal endpoint registry 797 * 798 * @param uri uri of the endpoint 799 * @param endpoint the endpoint to add 800 * @return the added endpoint 801 */ 802 protected Endpoint addEndpointToRegistry(String uri, Endpoint endpoint) { 803 StringHelper.notEmpty(uri, "uri"); 804 ObjectHelper.notNull(endpoint, "endpoint"); 805 806 // if there is endpoint strategies, then use the endpoints they return 807 // as this allows to intercept endpoints etc. 808 for (EndpointStrategy strategy : endpointStrategies) { 809 endpoint = strategy.registerEndpoint(uri, endpoint); 810 } 811 endpoints.put(getEndpointKey(uri, endpoint), endpoint); 812 return endpoint; 813 } 814 815 /** 816 * Normalize uri so we can do endpoint hits with minor mistakes and parameters is not in the same order. 817 * 818 * @param uri the uri 819 * @return normalized uri 820 * @throws ResolveEndpointFailedException if uri cannot be normalized 821 */ 822 protected static String normalizeEndpointUri(String uri) { 823 try { 824 uri = URISupport.normalizeUri(uri); 825 } catch (Exception e) { 826 throw new ResolveEndpointFailedException(uri, e); 827 } 828 return uri; 829 } 830 831 /** 832 * Gets the endpoint key to use for lookup or whe adding endpoints to the {@link DefaultEndpointRegistry} 833 * 834 * @param uri the endpoint uri 835 * @return the key 836 */ 837 protected EndpointKey getEndpointKey(String uri) { 838 return new EndpointKey(uri); 839 } 840 841 /** 842 * Gets the endpoint key to use for lookup or whe adding endpoints to the {@link DefaultEndpointRegistry} 843 * 844 * @param uri the endpoint uri which is pre normalized 845 * @return the key 846 */ 847 protected EndpointKey getEndpointKeyPreNormalized(String uri) { 848 return new EndpointKey(uri, true); 849 } 850 851 /** 852 * Gets the endpoint key to use for lookup or whe adding endpoints to the {@link DefaultEndpointRegistry} 853 * 854 * @param uri the endpoint uri 855 * @param endpoint the endpoint 856 * @return the key 857 */ 858 protected EndpointKey getEndpointKey(String uri, Endpoint endpoint) { 859 if (endpoint != null && !endpoint.isSingleton()) { 860 int counter = endpointKeyCounter.incrementAndGet(); 861 return new EndpointKey(uri + ":" + counter); 862 } else { 863 return new EndpointKey(uri); 864 } 865 } 866 867 // Route Management Methods 868 // ----------------------------------------------------------------------- 869 870 @Override 871 public void setRouteController(RouteController routeController) { 872 this.routeController = routeController; 873 this.routeController.setCamelContext(this); 874 } 875 876 @Override 877 public RouteController getRouteController() { 878 return routeController; 879 } 880 881 public List<RouteStartupOrder> getRouteStartupOrder() { 882 return routeStartupOrder; 883 } 884 885 public List<Route> getRoutes() { 886 // lets return a copy of the collection as objects are removed later when services are stopped 887 if (routes.isEmpty()) { 888 return Collections.emptyList(); 889 } else { 890 synchronized (routes) { 891 return new ArrayList<>(routes); 892 } 893 } 894 } 895 896 public Route getRoute(String id) { 897 if (id != null) { 898 for (Route route : getRoutes()) { 899 if (route.getId().equals(id)) { 900 return route; 901 } 902 } 903 } 904 return null; 905 } 906 907 public Processor getProcessor(String id) { 908 for (Route route : getRoutes()) { 909 List<Processor> list = route.filter(id); 910 if (list.size() == 1) { 911 return list.get(0); 912 } 913 } 914 return null; 915 } 916 917 public <T extends Processor> T getProcessor(String id, Class<T> type) { 918 Processor answer = getProcessor(id); 919 if (answer != null) { 920 return type.cast(answer); 921 } 922 return null; 923 } 924 925 public <T extends ManagedProcessorMBean> T getManagedProcessor(String id, Class<T> type) { 926 // jmx must be enabled 927 if (getManagementStrategy().getManagementAgent() == null) { 928 return null; 929 } 930 931 Processor processor = getProcessor(id); 932 ProcessorDefinition def = getProcessorDefinition(id); 933 934 // processor may be null if its anonymous inner class or as lambda 935 if (def != null) { 936 try { 937 ObjectName on = getManagementStrategy().getManagementNamingStrategy().getObjectNameForProcessor(this, processor, def); 938 return getManagementStrategy().getManagementAgent().newProxyClient(on, type); 939 } catch (MalformedObjectNameException e) { 940 throw ObjectHelper.wrapRuntimeCamelException(e); 941 } 942 } 943 944 return null; 945 } 946 947 public <T extends ManagedRouteMBean> T getManagedRoute(String routeId, Class<T> type) { 948 // jmx must be enabled 949 if (getManagementStrategy().getManagementAgent() == null) { 950 return null; 951 } 952 953 Route route = getRoute(routeId); 954 955 if (route != null) { 956 try { 957 ObjectName on = getManagementStrategy().getManagementNamingStrategy().getObjectNameForRoute(route); 958 return getManagementStrategy().getManagementAgent().newProxyClient(on, type); 959 } catch (MalformedObjectNameException e) { 960 throw ObjectHelper.wrapRuntimeCamelException(e); 961 } 962 } 963 964 return null; 965 } 966 967 public ManagedCamelContextMBean getManagedCamelContext() { 968 // jmx must be enabled 969 if (getManagementStrategy().getManagementAgent() == null) { 970 return null; 971 } 972 973 try { 974 ObjectName on = getManagementStrategy().getManagementNamingStrategy().getObjectNameForCamelContext(this); 975 return getManagementStrategy().getManagementAgent().newProxyClient(on, ManagedCamelContextMBean.class); 976 } catch (MalformedObjectNameException e) { 977 throw ObjectHelper.wrapRuntimeCamelException(e); 978 } 979 } 980 981 public ProcessorDefinition getProcessorDefinition(String id) { 982 for (RouteDefinition route : getRouteDefinitions()) { 983 Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); 984 while (it.hasNext()) { 985 ProcessorDefinition proc = it.next(); 986 if (id.equals(proc.getId())) { 987 return proc; 988 } 989 } 990 } 991 return null; 992 } 993 994 public <T extends ProcessorDefinition> T getProcessorDefinition(String id, Class<T> type) { 995 ProcessorDefinition answer = getProcessorDefinition(id); 996 if (answer != null) { 997 return type.cast(answer); 998 } 999 return null; 1000 } 1001 1002 @Deprecated 1003 public void setRoutes(List<Route> routes) { 1004 throw new UnsupportedOperationException("Overriding existing routes is not supported yet, use addRouteCollection instead"); 1005 } 1006 1007 void removeRouteCollection(Collection<Route> routes) { 1008 synchronized (this.routes) { 1009 this.routes.removeAll(routes); 1010 } 1011 } 1012 1013 void addRouteCollection(Collection<Route> routes) throws Exception { 1014 synchronized (this.routes) { 1015 this.routes.addAll(routes); 1016 } 1017 } 1018 1019 public void addRoutes(final RoutesBuilder builder) throws Exception { 1020 log.debug("Adding routes from builder: {}", builder); 1021 doWithDefinedClassLoader(new Callable<Void>() { 1022 @Override 1023 public Void call() throws Exception { 1024 builder.addRoutesToCamelContext(DefaultCamelContext.this); 1025 return null; 1026 } 1027 }); 1028 } 1029 1030 public synchronized RoutesDefinition loadRoutesDefinition(InputStream is) throws Exception { 1031 return ModelHelper.loadRoutesDefinition(this, is); 1032 } 1033 1034 public synchronized RestsDefinition loadRestsDefinition(InputStream is) throws Exception { 1035 // load routes using JAXB 1036 if (jaxbContext == null) { 1037 // must use classloader from CamelContext to have JAXB working 1038 jaxbContext = getModelJAXBContextFactory().newJAXBContext(); 1039 } 1040 1041 Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 1042 Object result = unmarshaller.unmarshal(is); 1043 1044 if (result == null) { 1045 throw new IOException("Cannot unmarshal to rests using JAXB from input stream: " + is); 1046 } 1047 1048 // can either be routes or a single route 1049 RestsDefinition answer; 1050 if (result instanceof RestDefinition) { 1051 RestDefinition rest = (RestDefinition) result; 1052 answer = new RestsDefinition(); 1053 answer.getRests().add(rest); 1054 } else if (result instanceof RestsDefinition) { 1055 answer = (RestsDefinition) result; 1056 } else { 1057 throw new IllegalArgumentException("Unmarshalled object is an unsupported type: " + ObjectHelper.className(result) + " -> " + result); 1058 } 1059 1060 return answer; 1061 } 1062 1063 public synchronized void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { 1064 if (routeDefinitions == null || routeDefinitions.isEmpty()) { 1065 return; 1066 } 1067 for (RouteDefinition routeDefinition : routeDefinitions) { 1068 removeRouteDefinition(routeDefinition); 1069 } 1070 this.routeDefinitions.addAll(routeDefinitions); 1071 if (shouldStartRoutes()) { 1072 startRouteDefinitions(routeDefinitions); 1073 } 1074 } 1075 1076 public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception { 1077 addRouteDefinitions(Arrays.asList(routeDefinition)); 1078 } 1079 1080 /** 1081 * Removes the route definition with the given key. 1082 * 1083 * @return true if one or more routes was removed 1084 */ 1085 protected boolean removeRouteDefinition(String key) { 1086 boolean answer = false; 1087 Iterator<RouteDefinition> iter = routeDefinitions.iterator(); 1088 while (iter.hasNext()) { 1089 RouteDefinition route = iter.next(); 1090 if (route.idOrCreate(nodeIdFactory).equals(key)) { 1091 iter.remove(); 1092 answer = true; 1093 } 1094 } 1095 return answer; 1096 } 1097 1098 public synchronized void removeRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception { 1099 for (RouteDefinition routeDefinition : routeDefinitions) { 1100 removeRouteDefinition(routeDefinition); 1101 } 1102 } 1103 1104 public synchronized void removeRouteDefinition(RouteDefinition routeDefinition) throws Exception { 1105 RouteDefinition toBeRemoved = routeDefinition; 1106 String id = routeDefinition.getId(); 1107 if (id != null) { 1108 // remove existing route 1109 stopRoute(id); 1110 removeRoute(id); 1111 toBeRemoved = getRouteDefinition(id); 1112 } 1113 this.routeDefinitions.remove(toBeRemoved); 1114 } 1115 1116 public ServiceStatus getRouteStatus(String key) { 1117 RouteService routeService = routeServices.get(key); 1118 if (routeService != null) { 1119 return routeService.getStatus(); 1120 } 1121 return null; 1122 } 1123 1124 public void startRoute(RouteDefinition route) throws Exception { 1125 // assign ids to the routes and validate that the id's is all unique 1126 RouteDefinitionHelper.forceAssignIds(this, routeDefinitions); 1127 String duplicate = RouteDefinitionHelper.validateUniqueIds(route, routeDefinitions); 1128 if (duplicate != null) { 1129 throw new FailedToStartRouteException(route.getId(), "duplicate id detected: " + duplicate + ". Please correct ids to be unique among all your routes."); 1130 } 1131 1132 // indicate we are staring the route using this thread so 1133 // we are able to query this if needed 1134 isStartingRoutes.set(true); 1135 try { 1136 // must ensure route is prepared, before we can start it 1137 route.prepare(this); 1138 1139 List<Route> routes = new ArrayList<>(); 1140 List<RouteContext> routeContexts = route.addRoutes(this, routes); 1141 RouteService routeService = new RouteService(this, route, routeContexts, routes); 1142 startRouteService(routeService, true); 1143 } finally { 1144 // we are done staring routes 1145 isStartingRoutes.remove(); 1146 } 1147 } 1148 1149 public boolean isStartingRoutes() { 1150 Boolean answer = isStartingRoutes.get(); 1151 return answer != null && answer; 1152 } 1153 1154 public boolean isSetupRoutes() { 1155 Boolean answer = isSetupRoutes.get(); 1156 return answer != null && answer; 1157 } 1158 1159 public void stopRoute(RouteDefinition route) throws Exception { 1160 stopRoute(route.idOrCreate(nodeIdFactory)); 1161 } 1162 1163 public void startAllRoutes() throws Exception { 1164 doStartOrResumeRoutes(routeServices, true, true, false, false); 1165 } 1166 1167 public synchronized void startRoute(String routeId) throws Exception { 1168 DefaultRouteError.reset(this, routeId); 1169 1170 RouteService routeService = routeServices.get(routeId); 1171 if (routeService != null) { 1172 try { 1173 startRouteService(routeService, false); 1174 } catch (Exception e) { 1175 DefaultRouteError.set(this, routeId, RouteError.Phase.START, e); 1176 throw e; 1177 } 1178 } 1179 } 1180 1181 public synchronized void resumeRoute(String routeId) throws Exception { 1182 DefaultRouteError.reset(this, routeId); 1183 1184 try { 1185 if (!routeSupportsSuspension(routeId)) { 1186 // start route if suspension is not supported 1187 startRoute(routeId); 1188 return; 1189 } 1190 1191 RouteService routeService = routeServices.get(routeId); 1192 if (routeService != null) { 1193 resumeRouteService(routeService); 1194 // must resume the route as well 1195 Route route = getRoute(routeId); 1196 ServiceHelper.resumeService(route); 1197 } 1198 } catch (Exception e) { 1199 DefaultRouteError.set(this, routeId, RouteError.Phase.RESUME, e); 1200 throw e; 1201 } 1202 } 1203 1204 public synchronized boolean stopRoute(String routeId, long timeout, TimeUnit timeUnit, boolean abortAfterTimeout) throws Exception { 1205 DefaultRouteError.reset(this, routeId); 1206 1207 RouteService routeService = routeServices.get(routeId); 1208 if (routeService != null) { 1209 try { 1210 RouteStartupOrder route = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService); 1211 1212 boolean completed = getShutdownStrategy().shutdown(this, route, timeout, timeUnit, abortAfterTimeout); 1213 if (completed) { 1214 // must stop route service as well 1215 stopRouteService(routeService, false); 1216 } else { 1217 // shutdown was aborted, make sure route is re-started properly 1218 startRouteService(routeService, false); 1219 } 1220 return completed; 1221 } catch (Exception e) { 1222 DefaultRouteError.set(this, routeId, RouteError.Phase.STOP, e); 1223 throw e; 1224 } 1225 } 1226 1227 return false; 1228 } 1229 1230 public synchronized void stopRoute(String routeId) throws Exception { 1231 DefaultRouteError.reset(this, routeId); 1232 1233 RouteService routeService = routeServices.get(routeId); 1234 if (routeService != null) { 1235 try { 1236 List<RouteStartupOrder> routes = new ArrayList<>(1); 1237 RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService); 1238 routes.add(order); 1239 1240 getShutdownStrategy().shutdown(this, routes); 1241 // must stop route service as well 1242 stopRouteService(routeService, false); 1243 } catch (Exception e) { 1244 DefaultRouteError.set(this, routeId, RouteError.Phase.STOP, e); 1245 throw e; 1246 } 1247 } 1248 } 1249 1250 public synchronized void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception { 1251 DefaultRouteError.reset(this, routeId); 1252 1253 RouteService routeService = routeServices.get(routeId); 1254 if (routeService != null) { 1255 try { 1256 List<RouteStartupOrder> routes = new ArrayList<>(1); 1257 RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService); 1258 routes.add(order); 1259 1260 getShutdownStrategy().shutdown(this, routes, timeout, timeUnit); 1261 // must stop route service as well 1262 stopRouteService(routeService, false); 1263 } catch (Exception e) { 1264 DefaultRouteError.set(this, routeId, RouteError.Phase.STOP, e); 1265 throw e; 1266 } 1267 } 1268 } 1269 1270 public synchronized void shutdownRoute(String routeId) throws Exception { 1271 DefaultRouteError.reset(this, routeId); 1272 1273 RouteService routeService = routeServices.get(routeId); 1274 if (routeService != null) { 1275 try { 1276 List<RouteStartupOrder> routes = new ArrayList<>(1); 1277 RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService); 1278 routes.add(order); 1279 1280 getShutdownStrategy().shutdown(this, routes); 1281 // must stop route service as well (and remove the routes from management) 1282 stopRouteService(routeService, true); 1283 } catch (Exception e) { 1284 DefaultRouteError.set(this, routeId, RouteError.Phase.SHUTDOWN, e); 1285 throw e; 1286 } 1287 } 1288 } 1289 1290 public synchronized void shutdownRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception { 1291 DefaultRouteError.reset(this, routeId); 1292 1293 RouteService routeService = routeServices.get(routeId); 1294 if (routeService != null) { 1295 try { 1296 List<RouteStartupOrder> routes = new ArrayList<>(1); 1297 RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService); 1298 routes.add(order); 1299 1300 getShutdownStrategy().shutdown(this, routes, timeout, timeUnit); 1301 // must stop route service as well (and remove the routes from management) 1302 stopRouteService(routeService, true); 1303 } catch (Exception e) { 1304 DefaultRouteError.set(this, routeId, RouteError.Phase.SHUTDOWN, e); 1305 throw e; 1306 } 1307 } 1308 } 1309 1310 public synchronized boolean removeRoute(String routeId) throws Exception { 1311 DefaultRouteError.reset(this, routeId); 1312 1313 // remove the route from ErrorHandlerBuilder if possible 1314 if (getErrorHandlerBuilder() instanceof ErrorHandlerBuilderSupport) { 1315 ErrorHandlerBuilderSupport builder = (ErrorHandlerBuilderSupport)getErrorHandlerBuilder(); 1316 builder.removeOnExceptionList(routeId); 1317 } 1318 1319 // gather a map of all the endpoints in use by the routes, so we can known if a given endpoints is in use 1320 // by one or more routes, when we remove the route 1321 Map<String, Set<Endpoint>> endpointsInUse = new HashMap<>(); 1322 for (Map.Entry<String, RouteService> entry : routeServices.entrySet()) { 1323 endpointsInUse.put(entry.getKey(), entry.getValue().gatherEndpoints()); 1324 } 1325 1326 RouteService routeService = routeServices.get(routeId); 1327 if (routeService != null) { 1328 if (getRouteStatus(routeId).isStopped()) { 1329 try { 1330 routeService.setRemovingRoutes(true); 1331 shutdownRouteService(routeService); 1332 removeRouteDefinition(routeId); 1333 routeServices.remove(routeId); 1334 // remove route from startup order as well, as it was removed 1335 Iterator<RouteStartupOrder> it = routeStartupOrder.iterator(); 1336 while (it.hasNext()) { 1337 RouteStartupOrder order = it.next(); 1338 if (order.getRoute().getId().equals(routeId)) { 1339 it.remove(); 1340 } 1341 } 1342 1343 // from the route which we have removed, then remove all its private endpoints 1344 // (eg the endpoints which are not in use by other routes) 1345 Set<Endpoint> toRemove = new LinkedHashSet<>(); 1346 for (Endpoint endpoint : endpointsInUse.get(routeId)) { 1347 // how many times is the endpoint in use 1348 int count = 0; 1349 for (Set<Endpoint> endpoints : endpointsInUse.values()) { 1350 if (endpoints.contains(endpoint)) { 1351 count++; 1352 } 1353 } 1354 // notice we will count ourselves so if there is only 1 then its safe to remove 1355 if (count <= 1) { 1356 toRemove.add(endpoint); 1357 } 1358 } 1359 for (Endpoint endpoint : toRemove) { 1360 log.debug("Removing: {} which was only in use by route: {}", endpoint, routeId); 1361 removeEndpoint(endpoint); 1362 } 1363 } catch (Exception e) { 1364 DefaultRouteError.set(this, routeId, RouteError.Phase.REMOVE, e); 1365 throw e; 1366 } 1367 1368 return true; 1369 } else { 1370 return false; 1371 } 1372 } 1373 return false; 1374 } 1375 1376 public synchronized void suspendRoute(String routeId) throws Exception { 1377 try { 1378 DefaultRouteError.reset(this, routeId); 1379 1380 if (!routeSupportsSuspension(routeId)) { 1381 // stop if we suspend is not supported 1382 stopRoute(routeId); 1383 return; 1384 } 1385 1386 RouteService routeService = routeServices.get(routeId); 1387 if (routeService != null) { 1388 List<RouteStartupOrder> routes = new ArrayList<>(1); 1389 Route route = routeService.getRoutes().iterator().next(); 1390 RouteStartupOrder order = new DefaultRouteStartupOrder(1, route, routeService); 1391 routes.add(order); 1392 1393 getShutdownStrategy().suspend(this, routes); 1394 // must suspend route service as well 1395 suspendRouteService(routeService); 1396 // must suspend the route as well 1397 if (route instanceof SuspendableService) { 1398 ((SuspendableService) route).suspend(); 1399 } 1400 } 1401 } catch (Exception e) { 1402 DefaultRouteError.set(this, routeId, RouteError.Phase.SUSPEND, e); 1403 throw e; 1404 } 1405 } 1406 1407 public synchronized void suspendRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception { 1408 DefaultRouteError.reset(this, routeId); 1409 1410 try { 1411 if (!routeSupportsSuspension(routeId)) { 1412 stopRoute(routeId, timeout, timeUnit); 1413 return; 1414 } 1415 1416 RouteService routeService = routeServices.get(routeId); 1417 if (routeService != null) { 1418 List<RouteStartupOrder> routes = new ArrayList<>(1); 1419 Route route = routeService.getRoutes().iterator().next(); 1420 RouteStartupOrder order = new DefaultRouteStartupOrder(1, route, routeService); 1421 routes.add(order); 1422 1423 getShutdownStrategy().suspend(this, routes, timeout, timeUnit); 1424 // must suspend route service as well 1425 suspendRouteService(routeService); 1426 // must suspend the route as well 1427 if (route instanceof SuspendableService) { 1428 ((SuspendableService) route).suspend(); 1429 } 1430 } 1431 } catch (Exception e) { 1432 DefaultRouteError.set(this, routeId, RouteError.Phase.SUSPEND, e); 1433 throw e; 1434 } 1435 } 1436 1437 public void addService(Object object) throws Exception { 1438 addService(object, true); 1439 } 1440 1441 public void addService(Object object, boolean stopOnShutdown) throws Exception { 1442 doAddService(object, stopOnShutdown, false); 1443 } 1444 1445 @Override 1446 public void addService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception { 1447 doAddService(object, stopOnShutdown, forceStart); 1448 } 1449 1450 private void doAddService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception { 1451 1452 // inject CamelContext 1453 if (object instanceof CamelContextAware) { 1454 CamelContextAware aware = (CamelContextAware) object; 1455 aware.setCamelContext(this); 1456 } 1457 1458 if (object instanceof Service) { 1459 Service service = (Service) object; 1460 1461 for (LifecycleStrategy strategy : lifecycleStrategies) { 1462 if (service instanceof Endpoint) { 1463 // use specialized endpoint add 1464 strategy.onEndpointAdd((Endpoint) service); 1465 } else { 1466 strategy.onServiceAdd(this, service, null); 1467 } 1468 } 1469 1470 if (!forceStart) { 1471 // now start the service (and defer starting if CamelContext is starting up itself) 1472 deferStartService(object, stopOnShutdown); 1473 } else { 1474 // only add to services to close if its a singleton 1475 // otherwise we could for example end up with a lot of prototype scope endpoints 1476 boolean singleton = true; // assume singleton by default 1477 if (object instanceof IsSingleton) { 1478 singleton = ((IsSingleton) service).isSingleton(); 1479 } 1480 // do not add endpoints as they have their own list 1481 if (singleton && !(service instanceof Endpoint)) { 1482 // only add to list of services to stop if its not already there 1483 if (stopOnShutdown && !hasService(service)) { 1484 servicesToStop.add(service); 1485 } 1486 } 1487 ServiceHelper.startService(service); 1488 } 1489 } 1490 } 1491 1492 public boolean removeService(Object object) throws Exception { 1493 if (object instanceof Endpoint) { 1494 removeEndpoint((Endpoint) object); 1495 return true; 1496 } 1497 if (object instanceof Service) { 1498 Service service = (Service) object; 1499 for (LifecycleStrategy strategy : lifecycleStrategies) { 1500 strategy.onServiceRemove(this, service, null); 1501 } 1502 return servicesToStop.remove(service); 1503 } 1504 return false; 1505 } 1506 1507 public boolean hasService(Object object) { 1508 if (object instanceof Service) { 1509 Service service = (Service) object; 1510 return servicesToStop.contains(service); 1511 } 1512 return false; 1513 } 1514 1515 @Override 1516 public <T> T hasService(Class<T> type) { 1517 for (Service service : servicesToStop) { 1518 if (type.isInstance(service)) { 1519 return type.cast(service); 1520 } 1521 } 1522 return null; 1523 } 1524 1525 @Override 1526 public <T> Set<T> hasServices(Class<T> type) { 1527 Set<T> set = new HashSet<>(); 1528 for (Service service : servicesToStop) { 1529 if (type.isInstance(service)) { 1530 set.add((T) service); 1531 } 1532 } 1533 return set; 1534 } 1535 1536 public void deferStartService(Object object, boolean stopOnShutdown) throws Exception { 1537 if (object instanceof Service) { 1538 Service service = (Service) object; 1539 1540 // only add to services to close if its a singleton 1541 // otherwise we could for example end up with a lot of prototype scope endpoints 1542 boolean singleton = true; // assume singleton by default 1543 if (object instanceof IsSingleton) { 1544 singleton = ((IsSingleton) service).isSingleton(); 1545 } 1546 // do not add endpoints as they have their own list 1547 if (singleton && !(service instanceof Endpoint)) { 1548 // only add to list of services to stop if its not already there 1549 if (stopOnShutdown && !hasService(service)) { 1550 servicesToStop.add(service); 1551 } 1552 } 1553 // are we already started? 1554 if (isStarted()) { 1555 ServiceHelper.startService(service); 1556 } else { 1557 deferStartupListener.addService(service); 1558 } 1559 } 1560 } 1561 1562 public void addStartupListener(StartupListener listener) throws Exception { 1563 // either add to listener so we can invoke then later when CamelContext has been started 1564 // or invoke the callback right now 1565 if (isStarted()) { 1566 listener.onCamelContextStarted(this, true); 1567 } else { 1568 startupListeners.add(listener); 1569 } 1570 } 1571 1572 public String resolveComponentDefaultName(String javaType) { 1573 // special for some components 1574 // TODO: ActiveMQ 5.11 will include this out of the box, so not needed when its released 1575 if ("org.apache.activemq.camel.component.ActiveMQComponent".equals(javaType)) { 1576 return "jms"; 1577 } 1578 1579 // try to find the component by its java type from the in-use components 1580 if (javaType != null) { 1581 // find all the components which will include the default component name 1582 try { 1583 Map<String, Properties> all = CamelContextHelper.findComponents(this); 1584 for (Map.Entry<String, Properties> entry : all.entrySet()) { 1585 String fqn = (String) entry.getValue().get("class"); 1586 if (javaType.equals(fqn)) { 1587 // is there component docs for that name? 1588 String name = entry.getKey(); 1589 String json = getComponentParameterJsonSchema(name); 1590 if (json != null) { 1591 return name; 1592 } 1593 } 1594 } 1595 } catch (Exception e) { 1596 // ignore 1597 return null; 1598 } 1599 } 1600 1601 // could not find a component with that name 1602 return null; 1603 } 1604 1605 public Map<String, Properties> findComponents() throws LoadPropertiesException, IOException { 1606 return CamelContextHelper.findComponents(this); 1607 } 1608 1609 public Map<String, Properties> findEips() throws LoadPropertiesException, IOException { 1610 return CamelContextHelper.findEips(this); 1611 } 1612 1613 public String getComponentDocumentation(String componentName) throws IOException { 1614 return null; 1615 } 1616 1617 public String getComponentParameterJsonSchema(String componentName) throws IOException { 1618 // use the component factory finder to find the package name of the component class, which is the location 1619 // where the documentation exists as well 1620 FactoryFinder finder = getFactoryFinder(DefaultComponentResolver.RESOURCE_PATH); 1621 try { 1622 Class<?> clazz = null; 1623 try { 1624 clazz = finder.findClass(componentName); 1625 } catch (NoFactoryAvailableException e) { 1626 // ignore, i.e. if a component is an auto-configured spring-boot 1627 // component 1628 } 1629 1630 if (clazz == null) { 1631 // fallback and find existing component 1632 Component existing = hasComponent(componentName); 1633 if (existing != null) { 1634 clazz = existing.getClass(); 1635 } else { 1636 return null; 1637 } 1638 } 1639 1640 String packageName = clazz.getPackage().getName(); 1641 packageName = packageName.replace('.', '/'); 1642 String path = packageName + "/" + componentName + ".json"; 1643 1644 ClassResolver resolver = getClassResolver(); 1645 InputStream inputStream = resolver.loadResourceAsStream(path); 1646 log.debug("Loading component JSON Schema for: {} using class resolver: {} -> {}", componentName, resolver, inputStream); 1647 if (inputStream != null) { 1648 try { 1649 return IOHelper.loadText(inputStream); 1650 } finally { 1651 IOHelper.close(inputStream); 1652 } 1653 } 1654 // special for ActiveMQ as it is really just JMS 1655 if ("ActiveMQComponent".equals(clazz.getSimpleName())) { 1656 return getComponentParameterJsonSchema("jms"); 1657 } else { 1658 return null; 1659 } 1660 } catch (ClassNotFoundException e) { 1661 return null; 1662 } 1663 } 1664 1665 public String getDataFormatParameterJsonSchema(String dataFormatName) throws IOException { 1666 // use the dataformat factory finder to find the package name of the dataformat class, which is the location 1667 // where the documentation exists as well 1668 FactoryFinder finder = getFactoryFinder(DefaultDataFormatResolver.DATAFORMAT_RESOURCE_PATH); 1669 try { 1670 Class<?> clazz = null; 1671 try { 1672 clazz = finder.findClass(dataFormatName); 1673 } catch (NoFactoryAvailableException e) { 1674 // ignore, i.e. if a component is an auto-configured spring-boot 1675 // data-formats 1676 } 1677 1678 if (clazz == null) { 1679 return null; 1680 } 1681 1682 String packageName = clazz.getPackage().getName(); 1683 packageName = packageName.replace('.', '/'); 1684 String path = packageName + "/" + dataFormatName + ".json"; 1685 1686 ClassResolver resolver = getClassResolver(); 1687 InputStream inputStream = resolver.loadResourceAsStream(path); 1688 log.debug("Loading dataformat JSON Schema for: {} using class resolver: {} -> {}", dataFormatName, resolver, inputStream); 1689 if (inputStream != null) { 1690 try { 1691 return IOHelper.loadText(inputStream); 1692 } finally { 1693 IOHelper.close(inputStream); 1694 } 1695 } 1696 return null; 1697 1698 } catch (ClassNotFoundException e) { 1699 return null; 1700 } 1701 } 1702 1703 public String getLanguageParameterJsonSchema(String languageName) throws IOException { 1704 // use the language factory finder to find the package name of the language class, which is the location 1705 // where the documentation exists as well 1706 FactoryFinder finder = getFactoryFinder(DefaultLanguageResolver.LANGUAGE_RESOURCE_PATH); 1707 try { 1708 Class<?> clazz = null; 1709 try { 1710 clazz = finder.findClass(languageName); 1711 } catch (NoFactoryAvailableException e) { 1712 // ignore, i.e. if a component is an auto-configured spring-boot 1713 // languages 1714 } 1715 1716 if (clazz == null) { 1717 return null; 1718 } 1719 1720 String packageName = clazz.getPackage().getName(); 1721 packageName = packageName.replace('.', '/'); 1722 String path = packageName + "/" + languageName + ".json"; 1723 1724 ClassResolver resolver = getClassResolver(); 1725 InputStream inputStream = resolver.loadResourceAsStream(path); 1726 log.debug("Loading language JSON Schema for: {} using class resolver: {} -> {}", languageName, resolver, inputStream); 1727 if (inputStream != null) { 1728 try { 1729 return IOHelper.loadText(inputStream); 1730 } finally { 1731 IOHelper.close(inputStream); 1732 } 1733 } 1734 return null; 1735 1736 } catch (ClassNotFoundException e) { 1737 return null; 1738 } 1739 } 1740 1741 public String getEipParameterJsonSchema(String eipName) throws IOException { 1742 // the eip json schema may be in some of the sub-packages so look until we find it 1743 String[] subPackages = new String[]{"", "/config", "/dataformat", "/language", "/loadbalancer", "/rest"}; 1744 for (String sub : subPackages) { 1745 String path = CamelContextHelper.MODEL_DOCUMENTATION_PREFIX + sub + "/" + eipName + ".json"; 1746 ClassResolver resolver = getClassResolver(); 1747 InputStream inputStream = resolver.loadResourceAsStream(path); 1748 if (inputStream != null) { 1749 log.debug("Loading eip JSON Schema for: {} using class resolver: {} -> {}", eipName, resolver, inputStream); 1750 try { 1751 return IOHelper.loadText(inputStream); 1752 } finally { 1753 IOHelper.close(inputStream); 1754 } 1755 } 1756 } 1757 return null; 1758 } 1759 1760 public String explainEipJson(String nameOrId, boolean includeAllOptions) { 1761 try { 1762 // try to find the id within all known routes and their eips 1763 String eipName = nameOrId; 1764 NamedNode target = null; 1765 for (RouteDefinition route : getRouteDefinitions()) { 1766 if (route.getId().equals(nameOrId)) { 1767 target = route; 1768 break; 1769 } 1770 for (FromDefinition from : route.getInputs()) { 1771 if (nameOrId.equals(from.getId())) { 1772 target = route; 1773 break; 1774 } 1775 } 1776 Iterator<ProcessorDefinition> it = ProcessorDefinitionHelper.filterTypeInOutputs(route.getOutputs(), ProcessorDefinition.class); 1777 while (it.hasNext()) { 1778 ProcessorDefinition def = it.next(); 1779 if (nameOrId.equals(def.getId())) { 1780 target = def; 1781 break; 1782 } 1783 } 1784 if (target != null) { 1785 break; 1786 } 1787 } 1788 1789 if (target != null) { 1790 eipName = target.getShortName(); 1791 } 1792 1793 String json = getEipParameterJsonSchema(eipName); 1794 if (json == null) { 1795 return null; 1796 } 1797 1798 // overlay with runtime parameters that id uses at runtime 1799 if (target != null) { 1800 List<Map<String, String>> rows = JsonSchemaHelper.parseJsonSchema("properties", json, true); 1801 1802 // selected rows to use for answer 1803 Map<String, String[]> selected = new LinkedHashMap<>(); 1804 1805 // extract options from the node 1806 Map<String, Object> options = new LinkedHashMap<>(); 1807 IntrospectionSupport.getProperties(target, options, "", false); 1808 // remove outputs which we do not want to include 1809 options.remove("outputs"); 1810 1811 // include other rows 1812 for (Map<String, String> row : rows) { 1813 String name = row.get("name"); 1814 String kind = row.get("kind"); 1815 String label = row.get("label"); 1816 String required = row.get("required"); 1817 String value = row.get("value"); 1818 String defaultValue = row.get("defaultValue"); 1819 String type = row.get("type"); 1820 String javaType = row.get("javaType"); 1821 String deprecated = row.get("deprecated"); 1822 String description = row.get("description"); 1823 1824 // find the configured option 1825 Object o = options.get(name); 1826 if (o != null) { 1827 value = o.toString(); 1828 } 1829 1830 value = URISupport.sanitizePath(value); 1831 1832 if (includeAllOptions || o != null) { 1833 // add as selected row 1834 if (!selected.containsKey(name)) { 1835 selected.put(name, new String[]{name, kind, label, required, type, javaType, deprecated, value, defaultValue, description}); 1836 } 1837 } 1838 } 1839 1840 json = StringHelper.before(json, " \"properties\": {"); 1841 1842 StringBuilder buffer = new StringBuilder(" \"properties\": {"); 1843 1844 boolean first = true; 1845 for (String[] row : selected.values()) { 1846 if (first) { 1847 first = false; 1848 } else { 1849 buffer.append(","); 1850 } 1851 buffer.append("\n "); 1852 1853 String name = row[0]; 1854 String kind = row[1]; 1855 String label = row[2]; 1856 String required = row[3]; 1857 String type = row[4]; 1858 String javaType = row[5]; 1859 String deprecated = row[6]; 1860 String value = row[7]; 1861 String defaultValue = row[8]; 1862 String description = row[9]; 1863 1864 // add json of the option 1865 buffer.append(StringQuoteHelper.doubleQuote(name)).append(": { "); 1866 CollectionStringBuffer csb = new CollectionStringBuffer(); 1867 if (kind != null) { 1868 csb.append("\"kind\": \"" + kind + "\""); 1869 } 1870 if (label != null) { 1871 csb.append("\"label\": \"" + label + "\""); 1872 } 1873 if (required != null) { 1874 csb.append("\"required\": \"" + required + "\""); 1875 } 1876 if (type != null) { 1877 csb.append("\"type\": \"" + type + "\""); 1878 } 1879 if (javaType != null) { 1880 csb.append("\"javaType\": \"" + javaType + "\""); 1881 } 1882 if (deprecated != null) { 1883 csb.append("\"deprecated\": \"" + deprecated + "\""); 1884 } 1885 if (value != null) { 1886 csb.append("\"value\": \"" + value + "\""); 1887 } 1888 if (defaultValue != null) { 1889 csb.append("\"defaultValue\": \"" + defaultValue + "\""); 1890 } 1891 if (description != null) { 1892 csb.append("\"description\": \"" + description + "\""); 1893 } 1894 if (!csb.isEmpty()) { 1895 buffer.append(csb.toString()); 1896 } 1897 buffer.append(" }"); 1898 } 1899 1900 buffer.append("\n }\n}\n"); 1901 1902 // insert the original first part of the json into the start of the buffer 1903 buffer.insert(0, json); 1904 return buffer.toString(); 1905 } 1906 1907 return json; 1908 } catch (Exception e) { 1909 // ignore and return empty response 1910 return null; 1911 } 1912 } 1913 1914 public String explainDataFormatJson(String dataFormatName, DataFormat dataFormat, boolean includeAllOptions) { 1915 try { 1916 String json = getDataFormatParameterJsonSchema(dataFormatName); 1917 if (json == null) { 1918 // the model may be shared for multiple data formats such as bindy, json (xstream, jackson, gson) 1919 if (dataFormatName.contains("-")) { 1920 dataFormatName = StringHelper.before(dataFormatName, "-"); 1921 json = getDataFormatParameterJsonSchema(dataFormatName); 1922 } 1923 if (json == null) { 1924 return null; 1925 } 1926 } 1927 1928 List<Map<String, String>> rows = JsonSchemaHelper.parseJsonSchema("properties", json, true); 1929 1930 // selected rows to use for answer 1931 Map<String, String[]> selected = new LinkedHashMap<>(); 1932 Map<String, String[]> dataFormatOptions = new LinkedHashMap<>(); 1933 1934 // extract options from the data format 1935 Map<String, Object> options = new LinkedHashMap<>(); 1936 IntrospectionSupport.getProperties(dataFormat, options, "", false); 1937 1938 for (Map.Entry<String, Object> entry : options.entrySet()) { 1939 String name = entry.getKey(); 1940 String value = ""; 1941 if (entry.getValue() != null) { 1942 value = entry.getValue().toString(); 1943 } 1944 value = URISupport.sanitizePath(value); 1945 1946 // find type and description from the json schema 1947 String type = null; 1948 String kind = null; 1949 String label = null; 1950 String required = null; 1951 String javaType = null; 1952 String deprecated = null; 1953 String secret = null; 1954 String defaultValue = null; 1955 String description = null; 1956 for (Map<String, String> row : rows) { 1957 if (name.equals(row.get("name"))) { 1958 type = row.get("type"); 1959 kind = row.get("kind"); 1960 label = row.get("label"); 1961 required = row.get("required"); 1962 javaType = row.get("javaType"); 1963 deprecated = row.get("deprecated"); 1964 secret = row.get("secret"); 1965 defaultValue = row.get("defaultValue"); 1966 description = row.get("description"); 1967 break; 1968 } 1969 } 1970 1971 // remember this option from the uri 1972 dataFormatOptions.put(name, new String[]{name, kind, label, required, type, javaType, deprecated, secret, value, defaultValue, description}); 1973 } 1974 1975 // include other rows 1976 for (Map<String, String> row : rows) { 1977 String name = row.get("name"); 1978 String kind = row.get("kind"); 1979 String label = row.get("label"); 1980 String required = row.get("required"); 1981 String value = row.get("value"); 1982 String defaultValue = row.get("defaultValue"); 1983 String type = row.get("type"); 1984 String javaType = row.get("javaType"); 1985 String deprecated = row.get("deprecated"); 1986 String secret = row.get("secret"); 1987 value = URISupport.sanitizePath(value); 1988 String description = row.get("description"); 1989 1990 boolean isDataFormatOption = dataFormatOptions.containsKey(name); 1991 1992 // always include from uri or path options 1993 if (includeAllOptions || isDataFormatOption) { 1994 if (!selected.containsKey(name)) { 1995 // add as selected row, but take the value from uri options if it was from there 1996 if (isDataFormatOption) { 1997 selected.put(name, dataFormatOptions.get(name)); 1998 } else { 1999 selected.put(name, new String[]{name, kind, label, required, type, javaType, deprecated, secret, value, defaultValue, description}); 2000 } 2001 } 2002 } 2003 } 2004 2005 json = StringHelper.before(json, " \"properties\": {"); 2006 2007 StringBuilder buffer = new StringBuilder(" \"properties\": {"); 2008 2009 boolean first = true; 2010 for (String[] row : selected.values()) { 2011 if (first) { 2012 first = false; 2013 } else { 2014 buffer.append(","); 2015 } 2016 buffer.append("\n "); 2017 2018 String name = row[0]; 2019 String kind = row[1]; 2020 String label = row[2]; 2021 String required = row[3]; 2022 String type = row[4]; 2023 String javaType = row[5]; 2024 String deprecated = row[6]; 2025 String secret = row[7]; 2026 String value = row[8]; 2027 String defaultValue = row[9]; 2028 String description = row[10]; 2029 2030 // add json of the option 2031 buffer.append(StringQuoteHelper.doubleQuote(name)).append(": { "); 2032 CollectionStringBuffer csb = new CollectionStringBuffer(); 2033 if (kind != null) { 2034 csb.append("\"kind\": \"" + kind + "\""); 2035 } 2036 if (label != null) { 2037 csb.append("\"label\": \"" + label + "\""); 2038 } 2039 if (required != null) { 2040 csb.append("\"required\": \"" + required + "\""); 2041 } 2042 if (type != null) { 2043 csb.append("\"type\": \"" + type + "\""); 2044 } 2045 if (javaType != null) { 2046 csb.append("\"javaType\": \"" + javaType + "\""); 2047 } 2048 if (deprecated != null) { 2049 csb.append("\"deprecated\": \"" + deprecated + "\""); 2050 } 2051 if (secret != null) { 2052 csb.append("\"secret\": \"" + secret + "\""); 2053 } 2054 if (value != null) { 2055 csb.append("\"value\": \"" + value + "\""); 2056 } 2057 if (defaultValue != null) { 2058 csb.append("\"defaultValue\": \"" + defaultValue + "\""); 2059 } 2060 if (description != null) { 2061 csb.append("\"description\": \"" + description + "\""); 2062 } 2063 if (!csb.isEmpty()) { 2064 buffer.append(csb.toString()); 2065 } 2066 buffer.append(" }"); 2067 } 2068 2069 buffer.append("\n }\n}\n"); 2070 2071 // insert the original first part of the json into the start of the buffer 2072 buffer.insert(0, json); 2073 return buffer.toString(); 2074 2075 } catch (Exception e) { 2076 // ignore and return empty response 2077 return null; 2078 } 2079 } 2080 2081 public String explainComponentJson(String componentName, boolean includeAllOptions) { 2082 try { 2083 String json = getComponentParameterJsonSchema(componentName); 2084 if (json == null) { 2085 return null; 2086 } 2087 List<Map<String, String>> rows = JsonSchemaHelper.parseJsonSchema("componentProperties", json, true); 2088 2089 // selected rows to use for answer 2090 Map<String, String[]> selected = new LinkedHashMap<>(); 2091 2092 // insert values from component 2093 Component component = getComponent(componentName); 2094 Map<String, Object> options = new HashMap<>(); 2095 IntrospectionSupport.getProperties(component, options, null); 2096 2097 for (Map.Entry<String, Object> entry : options.entrySet()) { 2098 String name = entry.getKey(); 2099 // skip unwanted options which is default inherited from DefaultComponent 2100 if ("camelContext".equals(name) || "endpointClass".equals(name)) { 2101 continue; 2102 } 2103 String value = ""; 2104 if (entry.getValue() != null) { 2105 value = entry.getValue().toString(); 2106 } 2107 value = URISupport.sanitizePath(value); 2108 2109 // find type and description from the json schema 2110 String type = null; 2111 String kind = null; 2112 String group = null; 2113 String label = null; 2114 String required = null; 2115 String javaType = null; 2116 String deprecated = null; 2117 String secret = null; 2118 String defaultValue = null; 2119 String description = null; 2120 for (Map<String, String> row : rows) { 2121 if (name.equals(row.get("name"))) { 2122 type = row.get("type"); 2123 kind = row.get("kind"); 2124 group = row.get("group"); 2125 label = row.get("label"); 2126 required = row.get("required"); 2127 javaType = row.get("javaType"); 2128 deprecated = row.get("deprecated"); 2129 secret = row.get("secret"); 2130 defaultValue = row.get("defaultValue"); 2131 description = row.get("description"); 2132 break; 2133 } 2134 } 2135 // add as selected row 2136 selected.put(name, new String[]{name, kind, group, label, required, type, javaType, deprecated, secret, value, defaultValue, description}); 2137 } 2138 2139 // include other rows 2140 for (Map<String, String> row : rows) { 2141 String name = row.get("name"); 2142 String kind = row.get("kind"); 2143 String group = row.get("group"); 2144 String label = row.get("label"); 2145 String required = row.get("required"); 2146 String value = row.get("value"); 2147 String defaultValue = row.get("defaultValue"); 2148 String type = row.get("type"); 2149 String javaType = row.get("javaType"); 2150 String deprecated = row.get("deprecated"); 2151 String secret = row.get("secret"); 2152 value = URISupport.sanitizePath(value); 2153 String description = row.get("description"); 2154 // always include path options 2155 if (includeAllOptions) { 2156 // add as selected row 2157 if (!selected.containsKey(name)) { 2158 selected.put(name, new String[]{name, kind, group, label, required, type, javaType, deprecated, secret, value, defaultValue, description}); 2159 } 2160 } 2161 } 2162 2163 json = StringHelper.before(json, " \"componentProperties\": {"); 2164 StringBuilder buffer = new StringBuilder(" \"componentProperties\": {"); 2165 2166 boolean first = true; 2167 for (String[] row : selected.values()) { 2168 if (first) { 2169 first = false; 2170 } else { 2171 buffer.append(","); 2172 } 2173 buffer.append("\n "); 2174 2175 String name = row[0]; 2176 String kind = row[1]; 2177 String group = row[2]; 2178 String label = row[3]; 2179 String required = row[4]; 2180 String type = row[5]; 2181 String javaType = row[6]; 2182 String deprecated = row[7]; 2183 String secret = row[8]; 2184 String value = row[9]; 2185 String defaultValue = row[10]; 2186 String description = row[11]; 2187 2188 // add json of the option 2189 buffer.append(StringQuoteHelper.doubleQuote(name)).append(": { "); 2190 CollectionStringBuffer csb = new CollectionStringBuffer(); 2191 if (kind != null) { 2192 csb.append("\"kind\": \"" + kind + "\""); 2193 } 2194 if (group != null) { 2195 csb.append("\"group\": \"" + group + "\""); 2196 } 2197 if (label != null) { 2198 csb.append("\"label\": \"" + label + "\""); 2199 } 2200 if (required != null) { 2201 csb.append("\"required\": \"" + required + "\""); 2202 } 2203 if (type != null) { 2204 csb.append("\"type\": \"" + type + "\""); 2205 } 2206 if (javaType != null) { 2207 csb.append("\"javaType\": \"" + javaType + "\""); 2208 } 2209 if (deprecated != null) { 2210 csb.append("\"deprecated\": \"" + deprecated + "\""); 2211 } 2212 if (secret != null) { 2213 csb.append("\"secret\": \"" + secret + "\""); 2214 } 2215 if (value != null) { 2216 csb.append("\"value\": \"" + value + "\""); 2217 } 2218 if (defaultValue != null) { 2219 csb.append("\"defaultValue\": \"" + defaultValue + "\""); 2220 } 2221 if (description != null) { 2222 csb.append("\"description\": \"" + description + "\""); 2223 } 2224 if (!csb.isEmpty()) { 2225 buffer.append(csb.toString()); 2226 } 2227 buffer.append(" }"); 2228 } 2229 buffer.append("\n }\n}\n"); 2230 // insert the original first part of the json into the start of the buffer 2231 buffer.insert(0, json); 2232 return buffer.toString(); 2233 } catch (Exception e) { 2234 // ignore and return empty response 2235 return null; 2236 } 2237 } 2238 2239 // CHECKSTYLE:OFF 2240 public String explainEndpointJson(String uri, boolean includeAllOptions) { 2241 try { 2242 URI u = new URI(uri); 2243 String json = getComponentParameterJsonSchema(u.getScheme()); 2244 if (json == null) { 2245 return null; 2246 } 2247 List<Map<String, String>> rows = JsonSchemaHelper.parseJsonSchema("properties", json, true); 2248 2249 // selected rows to use for answer 2250 Map<String, String[]> selected = new LinkedHashMap<>(); 2251 Map<String, String[]> uriOptions = new LinkedHashMap<>(); 2252 2253 // insert values from uri 2254 Map<String, Object> options = EndpointHelper.endpointProperties(this, uri); 2255 2256 // extract consumer. prefix options 2257 Map<String, Object> consumerOptions = IntrospectionSupport.extractProperties(options, "consumer."); 2258 // and add back again without the consumer. prefix as that json schema omits that 2259 options.putAll(consumerOptions); 2260 2261 for (Map.Entry<String, Object> entry : options.entrySet()) { 2262 String name = entry.getKey(); 2263 String value = ""; 2264 if (entry.getValue() != null) { 2265 value = entry.getValue().toString(); 2266 } 2267 value = URISupport.sanitizePath(value); 2268 // find type and description from the json schema 2269 String type = null; 2270 String kind = null; 2271 String group = null; 2272 String label = null; 2273 String required = null; 2274 String javaType = null; 2275 String deprecated = null; 2276 String secret = null; 2277 String defaultValue = null; 2278 String description = null; 2279 for (Map<String, String> row : rows) { 2280 if (name.equals(row.get("name"))) { 2281 type = row.get("type"); 2282 kind = row.get("kind"); 2283 group = row.get("group"); 2284 label = row.get("label"); 2285 required = row.get("required"); 2286 javaType = row.get("javaType"); 2287 deprecated = row.get("deprecated"); 2288 secret = row.get("secret"); 2289 defaultValue = row.get("defaultValue"); 2290 description = row.get("description"); 2291 break; 2292 } 2293 } 2294 // remember this option from the uri 2295 uriOptions.put(name, new String[]{name, kind, group, label, required, type, javaType, deprecated, secret, value, defaultValue, description}); 2296 } 2297 2298 // include other rows 2299 for (Map<String, String> row : rows) { 2300 String name = row.get("name"); 2301 String kind = row.get("kind"); 2302 String group = row.get("group"); 2303 String label = row.get("label"); 2304 String required = row.get("required"); 2305 String value = row.get("value"); 2306 String defaultValue = row.get("defaultValue"); 2307 String type = row.get("type"); 2308 String javaType = row.get("javaType"); 2309 String deprecated = row.get("deprecated"); 2310 String secret = row.get("secret"); 2311 value = URISupport.sanitizePath(value); 2312 String description = row.get("description"); 2313 boolean isUriOption = uriOptions.containsKey(name); 2314 // always include from uri or path options 2315 if (includeAllOptions || isUriOption || "path".equals(kind)) { 2316 if (!selected.containsKey(name)) { 2317 // add as selected row, but take the value from uri options if it was from there 2318 if (isUriOption) { 2319 selected.put(name, uriOptions.get(name)); 2320 } else { 2321 selected.put(name, new String[]{name, kind, group, label, required, type, javaType, deprecated, secret, value, defaultValue, description}); 2322 } 2323 } 2324 } 2325 } 2326 2327 // skip component properties 2328 json = StringHelper.before(json, " \"componentProperties\": {"); 2329 // and rewrite properties 2330 StringBuilder buffer = new StringBuilder(" \"properties\": {"); 2331 2332 boolean first = true; 2333 for (String[] row : selected.values()) { 2334 if (first) { 2335 first = false; 2336 } else { 2337 buffer.append(","); 2338 } 2339 buffer.append("\n "); 2340 2341 String name = row[0]; 2342 String kind = row[1]; 2343 String group = row[2]; 2344 String label = row[3]; 2345 String required = row[4]; 2346 String type = row[5]; 2347 String javaType = row[6]; 2348 String deprecated = row[7]; 2349 String secret = row[8]; 2350 String value = row[9]; 2351 String defaultValue = row[10]; 2352 String description = row[11]; 2353 2354 // add json of the option 2355 buffer.append(StringQuoteHelper.doubleQuote(name)).append(": { "); 2356 CollectionStringBuffer csb = new CollectionStringBuffer(); 2357 if (kind != null) { 2358 csb.append("\"kind\": \"" + kind + "\""); 2359 } 2360 if (group != null) { 2361 csb.append("\"group\": \"" + group + "\""); 2362 } 2363 if (label != null) { 2364 csb.append("\"label\": \"" + label + "\""); 2365 } 2366 if (required != null) { 2367 csb.append("\"required\": \"" + required + "\""); 2368 } 2369 if (type != null) { 2370 csb.append("\"type\": \"" + type + "\""); 2371 } 2372 if (javaType != null) { 2373 csb.append("\"javaType\": \"" + javaType + "\""); 2374 } 2375 if (deprecated != null) { 2376 csb.append("\"deprecated\": \"" + deprecated + "\""); 2377 } 2378 if (secret != null) { 2379 csb.append("\"secret\": \"" + secret + "\""); 2380 } 2381 if (value != null) { 2382 csb.append("\"value\": \"" + value + "\""); 2383 } 2384 if (defaultValue != null) { 2385 csb.append("\"defaultValue\": \"" + defaultValue + "\""); 2386 } 2387 if (description != null) { 2388 csb.append("\"description\": \"" + description + "\""); 2389 } 2390 if (!csb.isEmpty()) { 2391 buffer.append(csb.toString()); 2392 } 2393 buffer.append(" }"); 2394 } 2395 buffer.append("\n }\n}\n"); 2396 // insert the original first part of the json into the start of the buffer 2397 buffer.insert(0, json); 2398 return buffer.toString(); 2399 } catch (Exception e) { 2400 // ignore and return empty response 2401 return null; 2402 } 2403 } 2404 // CHECKSTYLE:ON 2405 2406 public String createRouteStaticEndpointJson(String routeId) { 2407 // lets include dynamic as well as we want as much data as possible 2408 return createRouteStaticEndpointJson(routeId, true); 2409 } 2410 2411 public String createRouteStaticEndpointJson(String routeId, boolean includeDynamic) { 2412 List<RouteDefinition> routes = new ArrayList<>(); 2413 if (routeId != null) { 2414 RouteDefinition route = getRouteDefinition(routeId); 2415 if (route == null) { 2416 throw new IllegalArgumentException("Route with id " + routeId + " does not exist"); 2417 } 2418 routes.add(route); 2419 } else { 2420 routes.addAll(getRouteDefinitions()); 2421 } 2422 2423 StringBuilder buffer = new StringBuilder("{\n \"routes\": {"); 2424 boolean firstRoute = true; 2425 for (RouteDefinition route : routes) { 2426 if (!firstRoute) { 2427 buffer.append("\n },"); 2428 } else { 2429 firstRoute = false; 2430 } 2431 2432 String id = route.getId(); 2433 buffer.append("\n \"").append(id).append("\": {"); 2434 buffer.append("\n \"inputs\": ["); 2435 // for inputs we do not need to check dynamic as we have the data from the route definition 2436 Set<String> inputs = RouteDefinitionHelper.gatherAllStaticEndpointUris(this, route, true, false); 2437 boolean first = true; 2438 for (String input : inputs) { 2439 if (!first) { 2440 buffer.append(","); 2441 } else { 2442 first = false; 2443 } 2444 buffer.append("\n "); 2445 buffer.append(StringHelper.toJson("uri", input, true)); 2446 } 2447 buffer.append("\n ]"); 2448 2449 buffer.append(","); 2450 buffer.append("\n \"outputs\": ["); 2451 Set<String> outputs = RouteDefinitionHelper.gatherAllEndpointUris(this, route, false, true, includeDynamic); 2452 first = true; 2453 for (String output : outputs) { 2454 if (!first) { 2455 buffer.append(","); 2456 } else { 2457 first = false; 2458 } 2459 buffer.append("\n "); 2460 buffer.append(StringHelper.toJson("uri", output, true)); 2461 } 2462 buffer.append("\n ]"); 2463 } 2464 if (!firstRoute) { 2465 buffer.append("\n }"); 2466 } 2467 buffer.append("\n }\n}\n"); 2468 2469 return buffer.toString(); 2470 } 2471 2472 // Helper methods 2473 // ----------------------------------------------------------------------- 2474 2475 public Language resolveLanguage(String language) { 2476 Language answer; 2477 synchronized (languages) { 2478 answer = languages.get(language); 2479 2480 // check if the language is singleton, if so return the shared instance 2481 if (answer instanceof IsSingleton) { 2482 boolean singleton = ((IsSingleton) answer).isSingleton(); 2483 if (singleton) { 2484 return answer; 2485 } 2486 } 2487 2488 // language not known or not singleton, then use resolver 2489 answer = getLanguageResolver().resolveLanguage(language, this); 2490 2491 // inject CamelContext if aware 2492 if (answer != null) { 2493 if (answer instanceof CamelContextAware) { 2494 ((CamelContextAware) answer).setCamelContext(this); 2495 } 2496 if (answer instanceof Service) { 2497 try { 2498 startService((Service) answer); 2499 } catch (Exception e) { 2500 throw ObjectHelper.wrapRuntimeCamelException(e); 2501 } 2502 } 2503 2504 languages.put(language, answer); 2505 } 2506 } 2507 2508 return answer; 2509 } 2510 2511 public String getPropertyPrefixToken() { 2512 PropertiesComponent pc = getPropertiesComponent(); 2513 2514 if (pc != null) { 2515 return pc.getPrefixToken(); 2516 } else { 2517 return null; 2518 } 2519 } 2520 2521 public String getPropertySuffixToken() { 2522 PropertiesComponent pc = getPropertiesComponent(); 2523 2524 if (pc != null) { 2525 return pc.getSuffixToken(); 2526 } else { 2527 return null; 2528 } 2529 } 2530 2531 public String resolvePropertyPlaceholders(String text) throws Exception { 2532 // While it is more efficient to only do the lookup if we are sure we need the component, 2533 // with custom tokens, we cannot know if the URI contains a property or not without having 2534 // the component. We also lose fail-fast behavior for the missing component with this change. 2535 PropertiesComponent pc = getPropertiesComponent(); 2536 2537 // Do not parse uris that are designated for the properties component as it will handle that itself 2538 if (text != null && !text.startsWith("properties:")) { 2539 // No component, assume default tokens. 2540 if (pc == null && text.contains(PropertiesComponent.DEFAULT_PREFIX_TOKEN)) { 2541 // lookup existing properties component, or force create a new default component 2542 pc = (PropertiesComponent) CamelContextHelper.lookupPropertiesComponent(this, true); 2543 } 2544 2545 if (pc != null && text.contains(pc.getPrefixToken())) { 2546 // the parser will throw exception if property key was not found 2547 String answer = pc.parseUri(text); 2548 log.debug("Resolved text: {} -> {}", text, answer); 2549 return answer; 2550 } 2551 } 2552 2553 // return original text as is 2554 return text; 2555 } 2556 2557 // Properties 2558 // ----------------------------------------------------------------------- 2559 2560 public TypeConverter getTypeConverter() { 2561 if (typeConverter == null) { 2562 synchronized (this) { 2563 // we can synchronize on this as there is only one instance 2564 // of the camel context (its the container) 2565 typeConverter = createTypeConverter(); 2566 try { 2567 // must add service eager and force start it 2568 addService(typeConverter, true, true); 2569 } catch (Exception e) { 2570 throw ObjectHelper.wrapRuntimeCamelException(e); 2571 } 2572 } 2573 } 2574 return typeConverter; 2575 } 2576 2577 public void setTypeConverter(TypeConverter typeConverter) { 2578 this.typeConverter = typeConverter; 2579 try { 2580 // must add service eager and force start it 2581 addService(typeConverter, true, true); 2582 } catch (Exception e) { 2583 throw ObjectHelper.wrapRuntimeCamelException(e); 2584 } 2585 } 2586 2587 public TypeConverterRegistry getTypeConverterRegistry() { 2588 if (typeConverterRegistry == null) { 2589 // init type converter as its lazy 2590 if (typeConverter == null) { 2591 getTypeConverter(); 2592 } 2593 if (typeConverter instanceof TypeConverterRegistry) { 2594 typeConverterRegistry = (TypeConverterRegistry) typeConverter; 2595 } 2596 } 2597 return typeConverterRegistry; 2598 } 2599 2600 public void setTypeConverterRegistry(TypeConverterRegistry typeConverterRegistry) { 2601 this.typeConverterRegistry = typeConverterRegistry; 2602 } 2603 2604 public Injector getInjector() { 2605 if (injector == null) { 2606 injector = createInjector(); 2607 } 2608 return injector; 2609 } 2610 2611 public void setInjector(Injector injector) { 2612 this.injector = injector; 2613 } 2614 2615 public ManagementMBeanAssembler getManagementMBeanAssembler() { 2616 return managementMBeanAssembler; 2617 } 2618 2619 public void setManagementMBeanAssembler(ManagementMBeanAssembler managementMBeanAssembler) { 2620 this.managementMBeanAssembler = managementMBeanAssembler; 2621 } 2622 2623 public ComponentResolver getComponentResolver() { 2624 if (componentResolver == null) { 2625 componentResolver = createComponentResolver(); 2626 } 2627 return componentResolver; 2628 } 2629 2630 public void setComponentResolver(ComponentResolver componentResolver) { 2631 this.componentResolver = componentResolver; 2632 } 2633 2634 public LanguageResolver getLanguageResolver() { 2635 if (languageResolver == null) { 2636 languageResolver = createLanguageResolver(); 2637 } 2638 return languageResolver; 2639 } 2640 2641 public void setLanguageResolver(LanguageResolver languageResolver) { 2642 this.languageResolver = languageResolver; 2643 } 2644 2645 public boolean isAutoCreateComponents() { 2646 return autoCreateComponents; 2647 } 2648 2649 public void setAutoCreateComponents(boolean autoCreateComponents) { 2650 this.autoCreateComponents = autoCreateComponents; 2651 } 2652 2653 public Registry getRegistry() { 2654 if (registry == null) { 2655 registry = createRegistry(); 2656 setRegistry(registry); 2657 } 2658 return registry; 2659 } 2660 2661 public <T> T getRegistry(Class<T> type) { 2662 Registry reg = getRegistry(); 2663 2664 // unwrap the property placeholder delegate 2665 if (reg instanceof PropertyPlaceholderDelegateRegistry) { 2666 reg = ((PropertyPlaceholderDelegateRegistry) reg).getRegistry(); 2667 } 2668 2669 if (type.isAssignableFrom(reg.getClass())) { 2670 return type.cast(reg); 2671 } else if (reg instanceof CompositeRegistry) { 2672 List<Registry> list = ((CompositeRegistry) reg).getRegistryList(); 2673 for (Registry r : list) { 2674 if (type.isAssignableFrom(r.getClass())) { 2675 return type.cast(r); 2676 } 2677 } 2678 } 2679 return null; 2680 } 2681 2682 /** 2683 * Sets the registry to the given JNDI context 2684 * 2685 * @param jndiContext is the JNDI context to use as the registry 2686 * @see #setRegistry(org.apache.camel.spi.Registry) 2687 */ 2688 public void setJndiContext(Context jndiContext) { 2689 setRegistry(new JndiRegistry(jndiContext)); 2690 } 2691 2692 public void setRegistry(Registry registry) { 2693 // wrap the registry so we always do property placeholder lookups 2694 if (!(registry instanceof PropertyPlaceholderDelegateRegistry)) { 2695 registry = new PropertyPlaceholderDelegateRegistry(this, registry); 2696 } 2697 this.registry = registry; 2698 } 2699 2700 public List<LifecycleStrategy> getLifecycleStrategies() { 2701 return lifecycleStrategies; 2702 } 2703 2704 public void setLifecycleStrategies(List<LifecycleStrategy> lifecycleStrategies) { 2705 this.lifecycleStrategies = lifecycleStrategies; 2706 } 2707 2708 public void addLifecycleStrategy(LifecycleStrategy lifecycleStrategy) { 2709 this.lifecycleStrategies.add(lifecycleStrategy); 2710 } 2711 2712 public void setupRoutes(boolean done) { 2713 if (done) { 2714 isSetupRoutes.remove(); 2715 } else { 2716 isSetupRoutes.set(true); 2717 } 2718 } 2719 2720 public synchronized List<RouteDefinition> getRouteDefinitions() { 2721 return routeDefinitions; 2722 } 2723 2724 public synchronized RouteDefinition getRouteDefinition(String id) { 2725 for (RouteDefinition route : routeDefinitions) { 2726 if (route.idOrCreate(nodeIdFactory).equals(id)) { 2727 return route; 2728 } 2729 } 2730 return null; 2731 } 2732 2733 public synchronized List<RestDefinition> getRestDefinitions() { 2734 return restDefinitions; 2735 } 2736 2737 public void addRestDefinitions(Collection<RestDefinition> restDefinitions) throws Exception { 2738 if (restDefinitions == null || restDefinitions.isEmpty()) { 2739 return; 2740 } 2741 2742 this.restDefinitions.addAll(restDefinitions); 2743 } 2744 2745 public RestConfiguration getRestConfiguration() { 2746 return restConfigurations.get(""); 2747 } 2748 2749 public void setRestConfiguration(RestConfiguration restConfiguration) { 2750 restConfigurations.put("", restConfiguration); 2751 } 2752 2753 public Collection<RestConfiguration> getRestConfigurations() { 2754 return restConfigurations.values(); 2755 } 2756 2757 public void addRestConfiguration(RestConfiguration restConfiguration) { 2758 restConfigurations.put(restConfiguration.getComponent(), restConfiguration); 2759 } 2760 2761 public RestConfiguration getRestConfiguration(String component, boolean defaultIfNotExist) { 2762 if (component == null) { 2763 component = ""; 2764 } 2765 RestConfiguration config = restConfigurations.get(component); 2766 if (config == null && defaultIfNotExist) { 2767 // grab the default configuration 2768 config = getRestConfiguration(); 2769 if (config == null || (config.getComponent() != null && !config.getComponent().equals(component))) { 2770 config = new RestConfiguration(); 2771 restConfigurations.put(component, config); 2772 } 2773 } 2774 return config; 2775 } 2776 2777 @Override 2778 public ServiceCallConfigurationDefinition getServiceCallConfiguration(String serviceName) { 2779 if (serviceName == null) { 2780 serviceName = ""; 2781 } 2782 2783 return serviceCallConfigurations.get(serviceName); 2784 } 2785 2786 @Override 2787 public void setServiceCallConfiguration(ServiceCallConfigurationDefinition configuration) { 2788 serviceCallConfigurations.put("", configuration); 2789 } 2790 2791 @Override 2792 public void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> configurations) { 2793 if (configurations != null) { 2794 for (ServiceCallConfigurationDefinition configuration : configurations) { 2795 serviceCallConfigurations.put(configuration.getId(), configuration); 2796 } 2797 } 2798 } 2799 2800 @Override 2801 public void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration) { 2802 serviceCallConfigurations.put(serviceName, configuration); 2803 } 2804 2805 @Override 2806 public HystrixConfigurationDefinition getHystrixConfiguration(String id) { 2807 if (id == null) { 2808 id = ""; 2809 } 2810 2811 return hystrixConfigurations.get(id); 2812 } 2813 2814 @Override 2815 public void setHystrixConfiguration(HystrixConfigurationDefinition configuration) { 2816 hystrixConfigurations.put("", configuration); 2817 } 2818 2819 @Override 2820 public void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations) { 2821 if (configurations != null) { 2822 for (HystrixConfigurationDefinition configuration : configurations) { 2823 hystrixConfigurations.put(configuration.getId(), configuration); 2824 } 2825 } 2826 } 2827 2828 @Override 2829 public void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration) { 2830 hystrixConfigurations.put(id, configuration); 2831 } 2832 2833 public List<InterceptStrategy> getInterceptStrategies() { 2834 return interceptStrategies; 2835 } 2836 2837 public void setInterceptStrategies(List<InterceptStrategy> interceptStrategies) { 2838 this.interceptStrategies = interceptStrategies; 2839 } 2840 2841 public void addInterceptStrategy(InterceptStrategy interceptStrategy) { 2842 getInterceptStrategies().add(interceptStrategy); 2843 2844 // for backwards compatible or if user add them here instead of the setXXX methods 2845 2846 if (interceptStrategy instanceof Tracer) { 2847 setTracing(true); 2848 } else if (interceptStrategy instanceof HandleFault) { 2849 setHandleFault(true); 2850 } else if (interceptStrategy instanceof StreamCaching) { 2851 setStreamCaching(true); 2852 } else if (interceptStrategy instanceof Delayer) { 2853 setDelayer(((Delayer)interceptStrategy).getDelay()); 2854 } 2855 } 2856 2857 public List<RoutePolicyFactory> getRoutePolicyFactories() { 2858 return routePolicyFactories; 2859 } 2860 2861 public void setRoutePolicyFactories(List<RoutePolicyFactory> routePolicyFactories) { 2862 this.routePolicyFactories = routePolicyFactories; 2863 } 2864 2865 public void addRoutePolicyFactory(RoutePolicyFactory routePolicyFactory) { 2866 getRoutePolicyFactories().add(routePolicyFactory); 2867 } 2868 2869 public Set<LogListener> getLogListeners() { 2870 return logListeners; 2871 } 2872 2873 public void addLogListener(LogListener listener) { 2874 logListeners.add(listener); 2875 } 2876 2877 public void setStreamCaching(Boolean cache) { 2878 this.streamCache = cache; 2879 } 2880 2881 public Boolean isStreamCaching() { 2882 return streamCache; 2883 } 2884 2885 public void setTracing(Boolean tracing) { 2886 this.trace = tracing; 2887 } 2888 2889 public Boolean isTracing() { 2890 return trace; 2891 } 2892 2893 public Boolean isMessageHistory() { 2894 return messageHistory; 2895 } 2896 2897 public void setMessageHistory(Boolean messageHistory) { 2898 this.messageHistory = messageHistory; 2899 } 2900 2901 public void setLogMask(Boolean logMask) { 2902 this.logMask = logMask; 2903 } 2904 2905 public Boolean isLogMask() { 2906 return logMask != null && logMask; 2907 } 2908 2909 public Boolean isLogExhaustedMessageBody() { 2910 return logExhaustedMessageBody; 2911 } 2912 2913 public void setLogExhaustedMessageBody(Boolean logExhaustedMessageBody) { 2914 this.logExhaustedMessageBody = logExhaustedMessageBody; 2915 } 2916 2917 public Boolean isHandleFault() { 2918 return handleFault; 2919 } 2920 2921 public void setHandleFault(Boolean handleFault) { 2922 this.handleFault = handleFault; 2923 } 2924 2925 public Long getDelayer() { 2926 return delay; 2927 } 2928 2929 public void setDelayer(Long delay) { 2930 this.delay = delay; 2931 } 2932 2933 public ProducerTemplate createProducerTemplate() { 2934 int size = CamelContextHelper.getMaximumCachePoolSize(this); 2935 return createProducerTemplate(size); 2936 } 2937 2938 public ProducerTemplate createProducerTemplate(int maximumCacheSize) { 2939 DefaultProducerTemplate answer = new DefaultProducerTemplate(this); 2940 answer.setMaximumCacheSize(maximumCacheSize); 2941 // start it so its ready to use 2942 try { 2943 startService(answer); 2944 } catch (Exception e) { 2945 throw ObjectHelper.wrapRuntimeCamelException(e); 2946 } 2947 return answer; 2948 } 2949 2950 public FluentProducerTemplate createFluentProducerTemplate() { 2951 int size = CamelContextHelper.getMaximumCachePoolSize(this); 2952 return createFluentProducerTemplate(size); 2953 } 2954 2955 public FluentProducerTemplate createFluentProducerTemplate(int maximumCacheSize) { 2956 DefaultFluentProducerTemplate answer = new DefaultFluentProducerTemplate(this); 2957 answer.setMaximumCacheSize(maximumCacheSize); 2958 // start it so its ready to use 2959 try { 2960 startService(answer); 2961 } catch (Exception e) { 2962 throw ObjectHelper.wrapRuntimeCamelException(e); 2963 } 2964 return answer; 2965 } 2966 2967 public ConsumerTemplate createConsumerTemplate() { 2968 int size = CamelContextHelper.getMaximumCachePoolSize(this); 2969 return createConsumerTemplate(size); 2970 } 2971 2972 public ConsumerTemplate createConsumerTemplate(int maximumCacheSize) { 2973 DefaultConsumerTemplate answer = new DefaultConsumerTemplate(this); 2974 answer.setMaximumCacheSize(maximumCacheSize); 2975 // start it so its ready to use 2976 try { 2977 startService(answer); 2978 } catch (Exception e) { 2979 throw ObjectHelper.wrapRuntimeCamelException(e); 2980 } 2981 return answer; 2982 } 2983 2984 public ErrorHandlerBuilder getErrorHandlerBuilder() { 2985 return (ErrorHandlerBuilder)errorHandlerBuilder; 2986 } 2987 2988 public void setErrorHandlerBuilder(ErrorHandlerFactory errorHandlerBuilder) { 2989 this.errorHandlerBuilder = errorHandlerBuilder; 2990 } 2991 2992 public ScheduledExecutorService getErrorHandlerExecutorService() { 2993 synchronized (errorHandlerExecutorServiceLock) { 2994 if (errorHandlerExecutorService == null) { 2995 // setup default thread pool for error handler 2996 errorHandlerExecutorService = getExecutorServiceManager().newDefaultScheduledThreadPool("ErrorHandlerRedeliveryThreadPool", "ErrorHandlerRedeliveryTask"); 2997 } 2998 } 2999 return errorHandlerExecutorService; 3000 } 3001 3002 public void setProducerServicePool(ServicePool<Endpoint, Producer> producerServicePool) { 3003 this.producerServicePool = producerServicePool; 3004 } 3005 3006 public ServicePool<Endpoint, Producer> getProducerServicePool() { 3007 return producerServicePool; 3008 } 3009 3010 public ServicePool<Endpoint, PollingConsumer> getPollingConsumerServicePool() { 3011 return pollingConsumerServicePool; 3012 } 3013 3014 public void setPollingConsumerServicePool(ServicePool<Endpoint, PollingConsumer> pollingConsumerServicePool) { 3015 this.pollingConsumerServicePool = pollingConsumerServicePool; 3016 } 3017 3018 public UnitOfWorkFactory getUnitOfWorkFactory() { 3019 return unitOfWorkFactory; 3020 } 3021 3022 public void setUnitOfWorkFactory(UnitOfWorkFactory unitOfWorkFactory) { 3023 this.unitOfWorkFactory = unitOfWorkFactory; 3024 } 3025 3026 public RuntimeEndpointRegistry getRuntimeEndpointRegistry() { 3027 return runtimeEndpointRegistry; 3028 } 3029 3030 public void setRuntimeEndpointRegistry(RuntimeEndpointRegistry runtimeEndpointRegistry) { 3031 this.runtimeEndpointRegistry = runtimeEndpointRegistry; 3032 } 3033 3034 public String getUptime() { 3035 long delta = getUptimeMillis(); 3036 if (delta == 0) { 3037 return ""; 3038 } 3039 return TimeUtils.printDuration(delta); 3040 } 3041 3042 public long getUptimeMillis() { 3043 if (startDate == null) { 3044 return 0; 3045 } 3046 return new Date().getTime() - startDate.getTime(); 3047 } 3048 3049 @Override 3050 protected void doSuspend() throws Exception { 3051 EventHelper.notifyCamelContextSuspending(this); 3052 3053 log.info("Apache Camel {} (CamelContext: {}) is suspending", getVersion(), getName()); 3054 StopWatch watch = new StopWatch(); 3055 3056 // update list of started routes to be suspended 3057 // because we only want to suspend started routes 3058 // (so when we resume we only resume the routes which actually was suspended) 3059 for (Map.Entry<String, RouteService> entry : getRouteServices().entrySet()) { 3060 if (entry.getValue().getStatus().isStarted()) { 3061 suspendedRouteServices.put(entry.getKey(), entry.getValue()); 3062 } 3063 } 3064 3065 // assemble list of startup ordering so routes can be shutdown accordingly 3066 List<RouteStartupOrder> orders = new ArrayList<>(); 3067 for (Map.Entry<String, RouteService> entry : suspendedRouteServices.entrySet()) { 3068 Route route = entry.getValue().getRoutes().iterator().next(); 3069 Integer order = entry.getValue().getRouteDefinition().getStartupOrder(); 3070 if (order == null) { 3071 order = defaultRouteStartupOrder++; 3072 } 3073 orders.add(new DefaultRouteStartupOrder(order, route, entry.getValue())); 3074 } 3075 3076 // suspend routes using the shutdown strategy so it can shutdown in correct order 3077 // routes which doesn't support suspension will be stopped instead 3078 getShutdownStrategy().suspend(this, orders); 3079 3080 // mark the route services as suspended or stopped 3081 for (RouteService service : suspendedRouteServices.values()) { 3082 if (routeSupportsSuspension(service.getId())) { 3083 service.suspend(); 3084 } else { 3085 service.stop(); 3086 } 3087 } 3088 3089 watch.stop(); 3090 if (log.isInfoEnabled()) { 3091 log.info("Apache Camel {} (CamelContext: {}) is suspended in {}", getVersion(), getName(), TimeUtils.printDuration(watch.taken())); 3092 } 3093 3094 EventHelper.notifyCamelContextSuspended(this); 3095 } 3096 3097 @Override 3098 protected void doResume() throws Exception { 3099 try { 3100 EventHelper.notifyCamelContextResuming(this); 3101 3102 log.info("Apache Camel {} (CamelContext: {}) is resuming", getVersion(), getName()); 3103 StopWatch watch = new StopWatch(); 3104 3105 // start the suspended routes (do not check for route clashes, and indicate) 3106 doStartOrResumeRoutes(suspendedRouteServices, false, true, true, false); 3107 3108 // mark the route services as resumed (will be marked as started) as well 3109 for (RouteService service : suspendedRouteServices.values()) { 3110 if (routeSupportsSuspension(service.getId())) { 3111 service.resume(); 3112 } else { 3113 service.start(); 3114 } 3115 } 3116 3117 if (log.isInfoEnabled()) { 3118 log.info("Resumed {} routes", suspendedRouteServices.size()); 3119 log.info("Apache Camel {} (CamelContext: {}) resumed in {}", getVersion(), getName(), TimeUtils.printDuration(watch.taken())); 3120 } 3121 3122 // and clear the list as they have been resumed 3123 suspendedRouteServices.clear(); 3124 3125 EventHelper.notifyCamelContextResumed(this); 3126 } catch (Exception e) { 3127 EventHelper.notifyCamelContextResumeFailed(this, e); 3128 throw e; 3129 } 3130 } 3131 3132 @Override 3133 public void start() throws Exception { 3134 try (MDCHelper mdcHelper = new MDCHelper()) { 3135 vetoStated.set(false); 3136 startDate = new Date(); 3137 stopWatch.restart(); 3138 log.info("Apache Camel {} (CamelContext: {}) is starting", getVersion(), getName()); 3139 3140 // Note: This is done on context start as we want to avoid doing it during object construction 3141 // where we could be dealing with CDI proxied camel contexts which may never be started (CAMEL-9657) 3142 // [TODO] Remove in 3.0 3143 Container.Instance.manage(this); 3144 3145 // Start the route controller 3146 ServiceHelper.startServices(this.routeController); 3147 3148 doNotStartRoutesOnFirstStart = !firstStartDone && !isAutoStartup(); 3149 3150 // if the context was configured with auto startup = false, and we are already started, 3151 // then we may need to start the routes on the 2nd start call 3152 if (firstStartDone && !isAutoStartup() && isStarted()) { 3153 // invoke this logic to warm up the routes and if possible also start the routes 3154 doStartOrResumeRoutes(routeServices, true, true, false, true); 3155 } 3156 3157 // super will invoke doStart which will prepare internal services and start routes etc. 3158 try { 3159 firstStartDone = true; 3160 super.start(); 3161 } catch (VetoCamelContextStartException e) { 3162 // mark we veto against starting Camel 3163 vetoStated.set(true); 3164 if (e.isRethrowException()) { 3165 throw e; 3166 } else { 3167 log.info("CamelContext ({}) vetoed to not start due {}", getName(), e.getMessage()); 3168 // swallow exception and change state of this camel context to stopped 3169 stop(); 3170 return; 3171 } 3172 } 3173 3174 if (log.isInfoEnabled()) { 3175 // count how many routes are actually started 3176 int started = 0; 3177 for (Route route : getRoutes()) { 3178 ServiceStatus status = getRouteStatus(route.getId()); 3179 if (status != null && status.isStarted()) { 3180 started++; 3181 } 3182 } 3183 3184 final Collection<Route> controlledRoutes = getRouteController().getControlledRoutes(); 3185 if (controlledRoutes.isEmpty()) { 3186 log.info("Total {} routes, of which {} are started", 3187 getRoutes().size(), 3188 started); 3189 } else { 3190 log.info("Total {} routes, of which {} are started, and {} are managed by RouteController: {}", 3191 getRoutes().size(), 3192 started, 3193 controlledRoutes.size(), 3194 getRouteController().getClass().getName() 3195 ); 3196 } 3197 log.info("Apache Camel {} (CamelContext: {}) started in {}", getVersion(), getName(), TimeUtils.printDuration(stopWatch.taken())); 3198 } 3199 3200 // okay the routes has been started so emit event that CamelContext has started (here at the end) 3201 EventHelper.notifyCamelContextStarted(this); 3202 3203 // now call the startup listeners where the routes has been started 3204 for (StartupListener startup : startupListeners) { 3205 if (startup instanceof ExtendedStartupListener) { 3206 ((ExtendedStartupListener) startup).onCamelContextFullyStarted(this, isStarted()); 3207 } 3208 } 3209 } 3210 } 3211 3212 @Override 3213 public void stop() throws Exception { 3214 try (MDCHelper mdcHelper = new MDCHelper()) { 3215 super.stop(); 3216 } 3217 } 3218 3219 @Override 3220 public void suspend() throws Exception { 3221 try (MDCHelper mdcHelper = new MDCHelper()) { 3222 super.suspend(); 3223 } 3224 } 3225 3226 @Override 3227 public void resume() throws Exception { 3228 try (MDCHelper mdcHelper = new MDCHelper()) { 3229 super.resume(); 3230 } 3231 } 3232 3233 @Override 3234 public void shutdown() throws Exception { 3235 try (MDCHelper mdcHelper = new MDCHelper()) { 3236 super.shutdown(); 3237 } 3238 } 3239 3240 // Implementation methods 3241 // ----------------------------------------------------------------------- 3242 3243 protected synchronized void doStart() throws Exception { 3244 doWithDefinedClassLoader(new Callable<Void>() { 3245 @Override 3246 public Void call() throws Exception { 3247 try { 3248 doStartCamel(); 3249 return null; 3250 } catch (Exception e) { 3251 // fire event that we failed to start 3252 EventHelper.notifyCamelContextStartupFailed(DefaultCamelContext.this, e); 3253 // rethrow cause 3254 throw e; 3255 } 3256 } 3257 }); 3258 } 3259 3260 private <T> T doWithDefinedClassLoader(Callable<T> callable) throws Exception { 3261 ClassLoader tccl = Thread.currentThread().getContextClassLoader(); 3262 try { 3263 // Using the ApplicationClassLoader as the default for TCCL 3264 if (applicationContextClassLoader != null) { 3265 Thread.currentThread().setContextClassLoader(applicationContextClassLoader); 3266 } 3267 return callable.call(); 3268 } finally { 3269 Thread.currentThread().setContextClassLoader(tccl); 3270 } 3271 } 3272 3273 protected void doStartCamel() throws Exception { 3274 3275 // custom properties may use property placeholders so resolve those early on 3276 if (globalOptions != null && !globalOptions.isEmpty()) { 3277 for (Map.Entry<String, String> entry : globalOptions.entrySet()) { 3278 String key = entry.getKey(); 3279 String value = entry.getValue(); 3280 if (value != null) { 3281 String replaced = resolvePropertyPlaceholders(value); 3282 if (!value.equals(replaced)) { 3283 if (log.isDebugEnabled()) { 3284 log.debug("Camel property with key {} replaced value from {} -> {}", key, value, replaced); 3285 } 3286 entry.setValue(replaced); 3287 } 3288 } 3289 } 3290 } 3291 3292 if (classResolver instanceof CamelContextAware) { 3293 ((CamelContextAware) classResolver).setCamelContext(this); 3294 } 3295 3296 if (log.isDebugEnabled()) { 3297 log.debug("Using ClassResolver={}, PackageScanClassResolver={}, ApplicationContextClassLoader={}, RouteController={}", 3298 getClassResolver(), getPackageScanClassResolver(), getApplicationContextClassLoader(), getRouteController()); 3299 } 3300 3301 if (isStreamCaching()) { 3302 log.info("StreamCaching is enabled on CamelContext: {}", getName()); 3303 } 3304 3305 if (isTracing()) { 3306 // tracing is added in the DefaultChannel so we can enable it on the fly 3307 log.info("Tracing is enabled on CamelContext: {}", getName()); 3308 } 3309 3310 if (isUseMDCLogging()) { 3311 // log if MDC has been enabled 3312 log.info("MDC logging is enabled on CamelContext: {}", getName()); 3313 } 3314 3315 if (isHandleFault()) { 3316 // only add a new handle fault if not already configured 3317 if (HandleFault.getHandleFault(this) == null) { 3318 log.info("HandleFault is enabled on CamelContext: {}", getName()); 3319 addInterceptStrategy(new HandleFault()); 3320 } 3321 } 3322 3323 if (getDelayer() != null && getDelayer() > 0) { 3324 log.info("Delayer is enabled with: {} ms. on CamelContext: {}", getDelayer(), getName()); 3325 } 3326 3327 // register debugger 3328 if (getDebugger() != null) { 3329 log.info("Debugger: {} is enabled on CamelContext: {}", getDebugger(), getName()); 3330 // register this camel context on the debugger 3331 getDebugger().setCamelContext(this); 3332 startService(getDebugger()); 3333 addInterceptStrategy(new Debug(getDebugger())); 3334 } 3335 3336 // start management strategy before lifecycles are started 3337 ManagementStrategy managementStrategy = getManagementStrategy(); 3338 // inject CamelContext if aware 3339 if (managementStrategy instanceof CamelContextAware) { 3340 ((CamelContextAware) managementStrategy).setCamelContext(this); 3341 } 3342 ServiceHelper.startService(managementStrategy); 3343 3344 // start lifecycle strategies 3345 ServiceHelper.startServices(lifecycleStrategies); 3346 Iterator<LifecycleStrategy> it = lifecycleStrategies.iterator(); 3347 while (it.hasNext()) { 3348 LifecycleStrategy strategy = it.next(); 3349 try { 3350 strategy.onContextStart(this); 3351 } catch (VetoCamelContextStartException e) { 3352 // okay we should not start Camel since it was vetoed 3353 log.warn("Lifecycle strategy vetoed starting CamelContext ({}) due: {}", getName(), e.getMessage()); 3354 throw e; 3355 } catch (Exception e) { 3356 log.warn("Lifecycle strategy " + strategy + " failed starting CamelContext ({}) due: {}", getName(), e.getMessage()); 3357 throw e; 3358 } 3359 } 3360 3361 // start notifiers as services 3362 for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) { 3363 if (notifier instanceof Service) { 3364 Service service = (Service) notifier; 3365 for (LifecycleStrategy strategy : lifecycleStrategies) { 3366 strategy.onServiceAdd(this, service, null); 3367 } 3368 } 3369 if (notifier instanceof Service) { 3370 startService((Service)notifier); 3371 } 3372 } 3373 3374 // must let some bootstrap service be started before we can notify the starting event 3375 EventHelper.notifyCamelContextStarting(this); 3376 3377 forceLazyInitialization(); 3378 3379 // re-create endpoint registry as the cache size limit may be set after the constructor of this instance was called. 3380 // and we needed to create endpoints up-front as it may be accessed before this context is started 3381 endpoints = createEndpointRegistry(endpoints); 3382 // add this as service and force pre-start them 3383 addService(endpoints, true, true); 3384 // special for executorServiceManager as want to stop it manually so false in stopOnShutdown 3385 addService(executorServiceManager, false, true); 3386 addService(producerServicePool, true, true); 3387 addService(pollingConsumerServicePool, true, true); 3388 addService(inflightRepository, true, true); 3389 addService(asyncProcessorAwaitManager, true, true); 3390 addService(shutdownStrategy, true, true); 3391 addService(packageScanClassResolver, true, true); 3392 addService(restRegistry, true, true); 3393 addService(messageHistoryFactory, true, true); 3394 addService(runtimeCamelCatalog, true, true); 3395 if (reloadStrategy != null) { 3396 log.info("Using ReloadStrategy: {}", reloadStrategy); 3397 addService(reloadStrategy, true, true); 3398 } 3399 3400 // Initialize declarative transformer/validator registry 3401 transformerRegistry = createTransformerRegistry(transformers); 3402 addService(transformerRegistry, true, true); 3403 validatorRegistry = createValidatorRegistry(validators); 3404 addService(validatorRegistry, true, true); 3405 3406 // optimised to not include runtimeEndpointRegistry unlesstartServices its enabled or JMX statistics is in extended mode 3407 if (runtimeEndpointRegistry == null && getManagementStrategy() != null && getManagementStrategy().getManagementAgent() != null) { 3408 Boolean isEnabled = getManagementStrategy().getManagementAgent().getEndpointRuntimeStatisticsEnabled(); 3409 boolean isExtended = getManagementStrategy().getManagementAgent().getStatisticsLevel().isExtended(); 3410 // extended mode is either if we use Extended statistics level or the option is explicit enabled 3411 boolean extended = isExtended || isEnabled != null && isEnabled; 3412 if (extended) { 3413 runtimeEndpointRegistry = new DefaultRuntimeEndpointRegistry(); 3414 } 3415 } 3416 if (runtimeEndpointRegistry != null) { 3417 if (runtimeEndpointRegistry instanceof EventNotifier) { 3418 getManagementStrategy().addEventNotifier((EventNotifier) runtimeEndpointRegistry); 3419 } 3420 addService(runtimeEndpointRegistry, true, true); 3421 } 3422 3423 // eager lookup any configured properties component to avoid subsequent lookup attempts which may impact performance 3424 // due we use properties component for property placeholder resolution at runtime 3425 Component existing = CamelContextHelper.lookupPropertiesComponent(this, false); 3426 if (existing != null) { 3427 // store reference to the existing properties component 3428 if (existing instanceof PropertiesComponent) { 3429 propertiesComponent = (PropertiesComponent) existing; 3430 } else { 3431 // properties component must be expected type 3432 throw new IllegalArgumentException("Found properties component of type: " + existing.getClass() + " instead of expected: " + PropertiesComponent.class); 3433 } 3434 } 3435 3436 // start components 3437 startServices(components.values()); 3438 3439 // start the route definitions before the routes is started 3440 startRouteDefinitions(routeDefinitions); 3441 3442 // is there any stream caching enabled then log an info about this and its limit of spooling to disk, so people is aware of this 3443 boolean streamCachingInUse = isStreamCaching(); 3444 if (!streamCachingInUse) { 3445 for (RouteDefinition route : routeDefinitions) { 3446 Boolean routeCache = CamelContextHelper.parseBoolean(this, route.getStreamCache()); 3447 if (routeCache != null && routeCache) { 3448 streamCachingInUse = true; 3449 break; 3450 } 3451 } 3452 } 3453 3454 if (isUseDataType()) { 3455 // log if DataType has been enabled 3456 log.info("Message DataType is enabled on CamelContext: {}", getName()); 3457 } 3458 3459 if (streamCachingInUse) { 3460 // stream caching is in use so enable the strategy 3461 getStreamCachingStrategy().setEnabled(true); 3462 addService(getStreamCachingStrategy(), true, true); 3463 } else { 3464 // log if stream caching is not in use as this can help people to enable it if they use streams 3465 log.info("StreamCaching is not in use. If using streams then its recommended to enable stream caching." 3466 + " See more details at http://camel.apache.org/stream-caching.html"); 3467 } 3468 3469 if (isAllowUseOriginalMessage()) { 3470 log.debug("AllowUseOriginalMessage enabled because UseOriginalMessage is in use"); 3471 } 3472 3473 // use resolver to find the headers map factory to be used, if we are using the default 3474 if (headersMapFactory instanceof DefaultHeadersMapFactory) { 3475 headersMapFactory = new HeadersMapFactoryResolver().resolve(this); 3476 } 3477 3478 log.debug("Using HeadersMapFactory: {}", headersMapFactory); 3479 if (!headersMapFactory.isCaseInsensitive()) { 3480 log.info("HeadersMapFactory: {} is case-sensitive which can cause problems for protocols such as HTTP based, which rely on case-insensitive headers.", getHeadersMapFactory()); 3481 } 3482 3483 // start routes 3484 if (doNotStartRoutesOnFirstStart) { 3485 log.debug("Skip starting routes as CamelContext has been configured with autoStartup=false"); 3486 } 3487 3488 // invoke this logic to warmup the routes and if possible also start the routes 3489 doStartOrResumeRoutes(routeServices, true, !doNotStartRoutesOnFirstStart, false, true); 3490 3491 // starting will continue in the start method 3492 } 3493 3494 protected synchronized void doStop() throws Exception { 3495 stopWatch.restart(); 3496 log.info("Apache Camel {} (CamelContext: {}) is shutting down", getVersion(), getName()); 3497 EventHelper.notifyCamelContextStopping(this); 3498 3499 // Stop the route controller 3500 ServiceHelper.stopAndShutdownService(this.routeController); 3501 3502 // stop route inputs in the same order as they was started so we stop the very first inputs first 3503 try { 3504 // force shutting down routes as they may otherwise cause shutdown to hang 3505 shutdownStrategy.shutdownForced(this, getRouteStartupOrder()); 3506 } catch (Throwable e) { 3507 log.warn("Error occurred while shutting down routes. This exception will be ignored.", e); 3508 } 3509 3510 // shutdown await manager to trigger interrupt of blocked threads to attempt to free these threads graceful 3511 shutdownServices(asyncProcessorAwaitManager); 3512 3513 routeStartupOrder.sort(new Comparator<RouteStartupOrder>() { 3514 @Override 3515 public int compare(RouteStartupOrder o1, RouteStartupOrder o2) { 3516 // Reversed order 3517 return Integer.compare(o2.getStartupOrder(), o1.getStartupOrder()); 3518 } 3519 }); 3520 List<RouteService> list = new ArrayList<>(); 3521 for (RouteStartupOrder startupOrder : routeStartupOrder) { 3522 DefaultRouteStartupOrder order = (DefaultRouteStartupOrder) startupOrder; 3523 RouteService routeService = order.getRouteService(); 3524 list.add(routeService); 3525 } 3526 shutdownServices(list, false); 3527 // do not clear route services or startup listeners as we can start Camel again and get the route back as before 3528 routeStartupOrder.clear(); 3529 3530 // but clear any suspend routes 3531 suspendedRouteServices.clear(); 3532 3533 // stop consumers from the services to close first, such as POJO consumer (eg @Consumer) 3534 // which we need to stop after the routes, as a POJO consumer is essentially a route also 3535 for (Service service : servicesToStop) { 3536 if (service instanceof Consumer) { 3537 shutdownServices(service); 3538 } 3539 } 3540 3541 // the stop order is important 3542 3543 // shutdown default error handler thread pool 3544 if (errorHandlerExecutorService != null) { 3545 // force shutting down the thread pool 3546 getExecutorServiceManager().shutdownNow(errorHandlerExecutorService); 3547 errorHandlerExecutorService = null; 3548 } 3549 3550 // shutdown debugger 3551 ServiceHelper.stopAndShutdownService(getDebugger()); 3552 3553 shutdownServices(endpoints.values()); 3554 endpoints.clear(); 3555 3556 shutdownServices(components.values()); 3557 components.clear(); 3558 3559 shutdownServices(languages.values()); 3560 languages.clear(); 3561 3562 try { 3563 for (LifecycleStrategy strategy : lifecycleStrategies) { 3564 strategy.onContextStop(this); 3565 } 3566 } catch (Throwable e) { 3567 log.warn("Error occurred while stopping lifecycle strategies. This exception will be ignored.", e); 3568 } 3569 3570 // shutdown services as late as possible 3571 shutdownServices(servicesToStop); 3572 servicesToStop.clear(); 3573 3574 // must notify that we are stopped before stopping the management strategy 3575 EventHelper.notifyCamelContextStopped(this); 3576 3577 // stop the notifier service 3578 for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) { 3579 shutdownServices(notifier); 3580 } 3581 3582 // shutdown executor service and management as the last one 3583 shutdownServices(executorServiceManager); 3584 shutdownServices(managementStrategy); 3585 shutdownServices(managementMBeanAssembler); 3586 shutdownServices(lifecycleStrategies); 3587 // do not clear lifecycleStrategies as we can start Camel again and get the route back as before 3588 3589 // stop the lazy created so they can be re-created on restart 3590 forceStopLazyInitialization(); 3591 3592 // stop to clear introspection cache 3593 IntrospectionSupport.stop(); 3594 3595 if (log.isInfoEnabled()) { 3596 log.info("Apache Camel " + getVersion() + " (CamelContext: " + getName() + ") uptime {}", getUptime()); 3597 log.info("Apache Camel {} (CamelContext: {}) is shutdown in {}", getVersion(), getName(), TimeUtils.printDuration(stopWatch.taken())); 3598 } 3599 3600 // and clear start date 3601 startDate = null; 3602 3603 // [TODO] Remove in 3.0 3604 Container.Instance.unmanage(this); 3605 } 3606 3607 /** 3608 * Starts or resumes the routes 3609 * 3610 * @param routeServices the routes to start (will only start a route if its not already started) 3611 * @param checkClash whether to check for startup ordering clash 3612 * @param startConsumer whether the route consumer should be started. Can be used to warmup the route without starting the consumer. 3613 * @param resumeConsumer whether the route consumer should be resumed. 3614 * @param addingRoutes whether we are adding new routes 3615 * @throws Exception is thrown if error starting routes 3616 */ 3617 protected void doStartOrResumeRoutes(Map<String, RouteService> routeServices, boolean checkClash, 3618 boolean startConsumer, boolean resumeConsumer, boolean addingRoutes) throws Exception { 3619 isStartingRoutes.set(true); 3620 try { 3621 // filter out already started routes 3622 Map<String, RouteService> filtered = new LinkedHashMap<>(); 3623 for (Map.Entry<String, RouteService> entry : routeServices.entrySet()) { 3624 boolean startable = false; 3625 3626 Consumer consumer = entry.getValue().getRoutes().iterator().next().getConsumer(); 3627 if (consumer instanceof SuspendableService) { 3628 // consumer could be suspended, which is not reflected in the RouteService status 3629 startable = ((SuspendableService) consumer).isSuspended(); 3630 } 3631 3632 if (!startable && consumer instanceof StatefulService) { 3633 // consumer could be stopped, which is not reflected in the RouteService status 3634 startable = ((StatefulService) consumer).getStatus().isStartable(); 3635 } else if (!startable) { 3636 // no consumer so use state from route service 3637 startable = entry.getValue().getStatus().isStartable(); 3638 } 3639 3640 if (startable) { 3641 filtered.put(entry.getKey(), entry.getValue()); 3642 } 3643 } 3644 3645 // the context is in last phase of staring, so lets start the routes 3646 safelyStartRouteServices(checkClash, startConsumer, resumeConsumer, addingRoutes, filtered.values()); 3647 3648 } finally { 3649 isStartingRoutes.remove(); 3650 } 3651 } 3652 3653 protected boolean routeSupportsSuspension(String routeId) { 3654 RouteService routeService = routeServices.get(routeId); 3655 if (routeService != null) { 3656 return routeService.getRoutes().iterator().next().supportsSuspension(); 3657 } 3658 return false; 3659 } 3660 3661 private void shutdownServices(Object service) { 3662 // do not rethrow exception as we want to keep shutting down in case of problems 3663 3664 // allow us to do custom work before delegating to service helper 3665 try { 3666 if (service instanceof Service) { 3667 ServiceHelper.stopAndShutdownService(service); 3668 } else if (service instanceof Collection) { 3669 ServiceHelper.stopAndShutdownServices((Collection<?>)service); 3670 } 3671 } catch (Throwable e) { 3672 log.warn("Error occurred while shutting down service: " + service + ". This exception will be ignored.", e); 3673 // fire event 3674 EventHelper.notifyServiceStopFailure(this, service, e); 3675 } 3676 } 3677 3678 private void shutdownServices(Collection<?> services) { 3679 // reverse stopping by default 3680 shutdownServices(services, true); 3681 } 3682 3683 private void shutdownServices(Collection<?> services, boolean reverse) { 3684 Collection<?> list = services; 3685 if (reverse) { 3686 List<Object> reverseList = new ArrayList<>(services); 3687 Collections.reverse(reverseList); 3688 list = reverseList; 3689 } 3690 3691 for (Object service : list) { 3692 shutdownServices(service); 3693 } 3694 } 3695 3696 private void startService(Service service) throws Exception { 3697 // and register startup aware so they can be notified when 3698 // camel context has been started 3699 if (service instanceof StartupListener) { 3700 StartupListener listener = (StartupListener) service; 3701 addStartupListener(listener); 3702 } 3703 3704 if (service instanceof CamelContextAware) { 3705 CamelContextAware aware = (CamelContextAware) service; 3706 aware.setCamelContext(this); 3707 } 3708 3709 service.start(); 3710 } 3711 3712 private void startServices(Collection<?> services) throws Exception { 3713 for (Object element : services) { 3714 if (element instanceof Service) { 3715 startService((Service)element); 3716 } 3717 } 3718 } 3719 3720 private void stopServices(Object service) throws Exception { 3721 // allow us to do custom work before delegating to service helper 3722 try { 3723 ServiceHelper.stopService(service); 3724 } catch (Exception e) { 3725 // fire event 3726 EventHelper.notifyServiceStopFailure(this, service, e); 3727 // rethrow to signal error with stopping 3728 throw e; 3729 } 3730 } 3731 3732 protected void startRouteDefinitions(Collection<RouteDefinition> list) throws Exception { 3733 if (list != null) { 3734 for (RouteDefinition route : list) { 3735 startRoute(route); 3736 } 3737 } 3738 } 3739 3740 /** 3741 * Starts the given route service 3742 */ 3743 protected synchronized void startRouteService(RouteService routeService, boolean addingRoutes) throws Exception { 3744 // we may already be starting routes so remember this, so we can unset accordingly in finally block 3745 boolean alreadyStartingRoutes = isStartingRoutes(); 3746 if (!alreadyStartingRoutes) { 3747 isStartingRoutes.set(true); 3748 } 3749 3750 try { 3751 // the route service could have been suspended, and if so then resume it instead 3752 if (routeService.getStatus().isSuspended()) { 3753 resumeRouteService(routeService); 3754 } else { 3755 // start the route service 3756 routeServices.put(routeService.getId(), routeService); 3757 if (shouldStartRoutes()) { 3758 // this method will log the routes being started 3759 safelyStartRouteServices(true, true, true, false, addingRoutes, routeService); 3760 // start route services if it was configured to auto startup and we are not adding routes 3761 boolean autoStartup = routeService.getRouteDefinition().isAutoStartup(this) && this.isAutoStartup(); 3762 if (!addingRoutes || autoStartup) { 3763 // start the route since auto start is enabled or we are starting a route (not adding new routes) 3764 routeService.start(); 3765 } 3766 } 3767 } 3768 } finally { 3769 if (!alreadyStartingRoutes) { 3770 isStartingRoutes.remove(); 3771 } 3772 } 3773 } 3774 3775 /** 3776 * Resumes the given route service 3777 */ 3778 protected synchronized void resumeRouteService(RouteService routeService) throws Exception { 3779 // the route service could have been stopped, and if so then start it instead 3780 if (!routeService.getStatus().isSuspended()) { 3781 startRouteService(routeService, false); 3782 } else { 3783 // resume the route service 3784 if (shouldStartRoutes()) { 3785 // this method will log the routes being started 3786 safelyStartRouteServices(true, false, true, true, false, routeService); 3787 // must resume route service as well 3788 routeService.resume(); 3789 } 3790 } 3791 } 3792 3793 protected synchronized void stopRouteService(RouteService routeService, boolean removingRoutes) throws Exception { 3794 routeService.setRemovingRoutes(removingRoutes); 3795 stopRouteService(routeService); 3796 } 3797 3798 protected void logRouteState(Route route, String state) { 3799 if (log.isInfoEnabled()) { 3800 if (route.getConsumer() != null) { 3801 log.info("Route: {} is {}, was consuming from: {}", route.getId(), state, route.getConsumer().getEndpoint()); 3802 } else { 3803 log.info("Route: {} is {}.", route.getId(), state); 3804 } 3805 } 3806 } 3807 3808 protected synchronized void stopRouteService(RouteService routeService) throws Exception { 3809 routeService.stop(); 3810 for (Route route : routeService.getRoutes()) { 3811 logRouteState(route, "stopped"); 3812 } 3813 } 3814 3815 protected synchronized void shutdownRouteService(RouteService routeService) throws Exception { 3816 routeService.shutdown(); 3817 for (Route route : routeService.getRoutes()) { 3818 logRouteState(route, "shutdown and removed"); 3819 } 3820 } 3821 3822 protected synchronized void suspendRouteService(RouteService routeService) throws Exception { 3823 routeService.setRemovingRoutes(false); 3824 routeService.suspend(); 3825 for (Route route : routeService.getRoutes()) { 3826 logRouteState(route, "suspended"); 3827 } 3828 } 3829 3830 /** 3831 * Starts the routes services in a proper manner which ensures the routes will be started in correct order, 3832 * check for clash and that the routes will also be shutdown in correct order as well. 3833 * <p/> 3834 * This method <b>must</b> be used to start routes in a safe manner. 3835 * 3836 * @param checkClash whether to check for startup order clash 3837 * @param startConsumer whether the route consumer should be started. Can be used to warmup the route without starting the consumer. 3838 * @param resumeConsumer whether the route consumer should be resumed. 3839 * @param addingRoutes whether we are adding new routes 3840 * @param routeServices the routes 3841 * @throws Exception is thrown if error starting the routes 3842 */ 3843 protected synchronized void safelyStartRouteServices(boolean checkClash, boolean startConsumer, boolean resumeConsumer, 3844 boolean addingRoutes, Collection<RouteService> routeServices) throws Exception { 3845 // list of inputs to start when all the routes have been prepared for starting 3846 // we use a tree map so the routes will be ordered according to startup order defined on the route 3847 Map<Integer, DefaultRouteStartupOrder> inputs = new TreeMap<>(); 3848 3849 // figure out the order in which the routes should be started 3850 for (RouteService routeService : routeServices) { 3851 DefaultRouteStartupOrder order = doPrepareRouteToBeStarted(routeService); 3852 // check for clash before we add it as input 3853 if (checkClash) { 3854 doCheckStartupOrderClash(order, inputs); 3855 } 3856 inputs.put(order.getStartupOrder(), order); 3857 } 3858 3859 // warm up routes before we start them 3860 doWarmUpRoutes(inputs, startConsumer); 3861 3862 // sort the startup listeners so they are started in the right order 3863 startupListeners.sort(OrderedComparator.get()); 3864 // now call the startup listeners where the routes has been warmed up 3865 // (only the actual route consumer has not yet been started) 3866 for (StartupListener startup : startupListeners) { 3867 startup.onCamelContextStarted(this, isStarted()); 3868 } 3869 // because the consumers may also register startup listeners we need to reset 3870 // the already started listeners 3871 List<StartupListener> backup = new ArrayList<>(startupListeners); 3872 startupListeners.clear(); 3873 3874 // now start the consumers 3875 if (startConsumer) { 3876 if (resumeConsumer) { 3877 // and now resume the routes 3878 doResumeRouteConsumers(inputs, addingRoutes); 3879 } else { 3880 // and now start the routes 3881 // and check for clash with multiple consumers of the same endpoints which is not allowed 3882 doStartRouteConsumers(inputs, addingRoutes); 3883 } 3884 } 3885 3886 // sort the startup listeners so they are started in the right order 3887 startupListeners.sort(OrderedComparator.get()); 3888 // now the consumers that was just started may also add new StartupListeners (such as timer) 3889 // so we need to ensure they get started as well 3890 for (StartupListener startup : startupListeners) { 3891 startup.onCamelContextStarted(this, isStarted()); 3892 } 3893 // and add the previous started startup listeners to the list so we have them all 3894 startupListeners.addAll(0, backup); 3895 3896 // inputs no longer needed 3897 inputs.clear(); 3898 } 3899 3900 /** 3901 * @see #safelyStartRouteServices(boolean,boolean,boolean,boolean,java.util.Collection) 3902 */ 3903 protected synchronized void safelyStartRouteServices(boolean forceAutoStart, boolean checkClash, boolean startConsumer, 3904 boolean resumeConsumer, boolean addingRoutes, RouteService... routeServices) throws Exception { 3905 safelyStartRouteServices(checkClash, startConsumer, resumeConsumer, addingRoutes, Arrays.asList(routeServices)); 3906 } 3907 3908 private DefaultRouteStartupOrder doPrepareRouteToBeStarted(RouteService routeService) { 3909 // add the inputs from this route service to the list to start afterwards 3910 // should be ordered according to the startup number 3911 Integer startupOrder = routeService.getRouteDefinition().getStartupOrder(); 3912 if (startupOrder == null) { 3913 // auto assign a default startup order 3914 startupOrder = defaultRouteStartupOrder++; 3915 } 3916 3917 // create holder object that contains information about this route to be started 3918 Route route = routeService.getRoutes().iterator().next(); 3919 return new DefaultRouteStartupOrder(startupOrder, route, routeService); 3920 } 3921 3922 private boolean doCheckStartupOrderClash(DefaultRouteStartupOrder answer, Map<Integer, DefaultRouteStartupOrder> inputs) throws FailedToStartRouteException { 3923 // check for clash by startupOrder id 3924 DefaultRouteStartupOrder other = inputs.get(answer.getStartupOrder()); 3925 if (other != null && answer != other) { 3926 String otherId = other.getRoute().getId(); 3927 throw new FailedToStartRouteException(answer.getRoute().getId(), "startupOrder clash. Route " + otherId + " already has startupOrder " 3928 + answer.getStartupOrder() + " configured which this route have as well. Please correct startupOrder to be unique among all your routes."); 3929 } 3930 // check in existing already started as well 3931 for (RouteStartupOrder order : routeStartupOrder) { 3932 String otherId = order.getRoute().getId(); 3933 if (answer.getRoute().getId().equals(otherId)) { 3934 // its the same route id so skip clash check as its the same route (can happen when using suspend/resume) 3935 } else if (answer.getStartupOrder() == order.getStartupOrder()) { 3936 throw new FailedToStartRouteException(answer.getRoute().getId(), "startupOrder clash. Route " + otherId + " already has startupOrder " 3937 + answer.getStartupOrder() + " configured which this route have as well. Please correct startupOrder to be unique among all your routes."); 3938 } 3939 } 3940 return true; 3941 } 3942 3943 private void doWarmUpRoutes(Map<Integer, DefaultRouteStartupOrder> inputs, boolean autoStartup) throws Exception { 3944 // now prepare the routes by starting its services before we start the input 3945 for (Map.Entry<Integer, DefaultRouteStartupOrder> entry : inputs.entrySet()) { 3946 // defer starting inputs till later as we want to prepare the routes by starting 3947 // all their processors and child services etc. 3948 // then later we open the floods to Camel by starting the inputs 3949 // what this does is to ensure Camel is more robust on starting routes as all routes 3950 // will then be prepared in time before we start inputs which will consume messages to be routed 3951 RouteService routeService = entry.getValue().getRouteService(); 3952 log.debug("Warming up route id: {} having autoStartup={}", routeService.getId(), autoStartup); 3953 routeService.warmUp(); 3954 } 3955 } 3956 3957 private void doResumeRouteConsumers(Map<Integer, DefaultRouteStartupOrder> inputs, boolean addingRoutes) throws Exception { 3958 doStartOrResumeRouteConsumers(inputs, true, addingRoutes); 3959 } 3960 3961 private void doStartRouteConsumers(Map<Integer, DefaultRouteStartupOrder> inputs, boolean addingRoutes) throws Exception { 3962 doStartOrResumeRouteConsumers(inputs, false, addingRoutes); 3963 } 3964 3965 private void doStartOrResumeRouteConsumers(Map<Integer, DefaultRouteStartupOrder> inputs, boolean resumeOnly, boolean addingRoute) throws Exception { 3966 List<Endpoint> routeInputs = new ArrayList<>(); 3967 3968 for (Map.Entry<Integer, DefaultRouteStartupOrder> entry : inputs.entrySet()) { 3969 Integer order = entry.getKey(); 3970 Route route = entry.getValue().getRoute(); 3971 RouteService routeService = entry.getValue().getRouteService(); 3972 3973 // if we are starting camel, then skip routes which are configured to not be auto started 3974 boolean autoStartup = routeService.getRouteDefinition().isAutoStartup(this) && this.isAutoStartup(); 3975 if (addingRoute && !autoStartup) { 3976 log.info("Skipping starting of route {} as its configured with autoStartup=false", routeService.getId()); 3977 continue; 3978 } 3979 3980 // start the service 3981 for (Consumer consumer : routeService.getInputs().values()) { 3982 Endpoint endpoint = consumer.getEndpoint(); 3983 3984 // check multiple consumer violation, with the other routes to be started 3985 if (!doCheckMultipleConsumerSupportClash(endpoint, routeInputs)) { 3986 throw new FailedToStartRouteException(routeService.getId(), 3987 "Multiple consumers for the same endpoint is not allowed: " + endpoint); 3988 } 3989 3990 // check for multiple consumer violations with existing routes which 3991 // have already been started, or is currently starting 3992 List<Endpoint> existingEndpoints = new ArrayList<>(); 3993 for (Route existingRoute : getRoutes()) { 3994 if (route.getId().equals(existingRoute.getId())) { 3995 // skip ourselves 3996 continue; 3997 } 3998 Endpoint existing = existingRoute.getEndpoint(); 3999 ServiceStatus status = getRouteStatus(existingRoute.getId()); 4000 if (status != null && (status.isStarted() || status.isStarting())) { 4001 existingEndpoints.add(existing); 4002 } 4003 } 4004 if (!doCheckMultipleConsumerSupportClash(endpoint, existingEndpoints)) { 4005 throw new FailedToStartRouteException(routeService.getId(), 4006 "Multiple consumers for the same endpoint is not allowed: " + endpoint); 4007 } 4008 4009 // start the consumer on the route 4010 log.debug("Route: {} >>> {}", route.getId(), route); 4011 if (resumeOnly) { 4012 log.debug("Resuming consumer (order: {}) on route: {}", order, route.getId()); 4013 } else { 4014 log.debug("Starting consumer (order: {}) on route: {}", order, route.getId()); 4015 } 4016 4017 if (resumeOnly && route.supportsSuspension()) { 4018 // if we are resuming and the route can be resumed 4019 ServiceHelper.resumeService(consumer); 4020 log.info("Route: {} resumed and consuming from: {}", route.getId(), endpoint); 4021 } else { 4022 // when starting we should invoke the lifecycle strategies 4023 for (LifecycleStrategy strategy : lifecycleStrategies) { 4024 strategy.onServiceAdd(this, consumer, route); 4025 } 4026 try { 4027 startService(consumer); 4028 route.getProperties().remove("route.start.exception"); 4029 } catch (Exception e) { 4030 route.getProperties().put("route.start.exception", e); 4031 throw e; 4032 } 4033 4034 log.info("Route: {} started and consuming from: {}", route.getId(), endpoint); 4035 } 4036 4037 routeInputs.add(endpoint); 4038 4039 // add to the order which they was started, so we know how to stop them in reverse order 4040 // but only add if we haven't already registered it before (we dont want to double add when restarting) 4041 boolean found = false; 4042 for (RouteStartupOrder other : routeStartupOrder) { 4043 if (other.getRoute().getId().equals(route.getId())) { 4044 found = true; 4045 break; 4046 } 4047 } 4048 if (!found) { 4049 routeStartupOrder.add(entry.getValue()); 4050 } 4051 } 4052 4053 if (resumeOnly) { 4054 routeService.resume(); 4055 } else { 4056 // and start the route service (no need to start children as they are already warmed up) 4057 try { 4058 routeService.start(false); 4059 route.getProperties().remove("route.start.exception"); 4060 } catch (Exception e) { 4061 route.getProperties().put("route.start.exception", e); 4062 throw e; 4063 } 4064 } 4065 } 4066 } 4067 4068 private boolean doCheckMultipleConsumerSupportClash(Endpoint endpoint, List<Endpoint> routeInputs) { 4069 // is multiple consumers supported 4070 boolean multipleConsumersSupported = false; 4071 if (endpoint instanceof MultipleConsumersSupport) { 4072 multipleConsumersSupported = ((MultipleConsumersSupport) endpoint).isMultipleConsumersSupported(); 4073 } 4074 4075 if (multipleConsumersSupported) { 4076 // multiple consumer allowed, so return true 4077 return true; 4078 } 4079 4080 // check in progress list 4081 if (routeInputs.contains(endpoint)) { 4082 return false; 4083 } 4084 4085 return true; 4086 } 4087 4088 /** 4089 * Force some lazy initialization to occur upfront before we start any 4090 * components and create routes 4091 */ 4092 protected void forceLazyInitialization() { 4093 getRegistry(); 4094 getInjector(); 4095 getLanguageResolver(); 4096 getTypeConverterRegistry(); 4097 getTypeConverter(); 4098 4099 if (isTypeConverterStatisticsEnabled() != null) { 4100 getTypeConverterRegistry().getStatistics().setStatisticsEnabled(isTypeConverterStatisticsEnabled()); 4101 } 4102 4103 // resolve simple language to initialize it 4104 resolveLanguage("simple"); 4105 } 4106 4107 /** 4108 * Force clear lazy initialization so they can be re-created on restart 4109 */ 4110 protected void forceStopLazyInitialization() { 4111 injector = null; 4112 languageResolver = null; 4113 typeConverterRegistry = null; 4114 typeConverter = null; 4115 } 4116 4117 /** 4118 * Lazily create a default implementation 4119 */ 4120 protected TypeConverter createTypeConverter() { 4121 BaseTypeConverterRegistry answer; 4122 if (isLazyLoadTypeConverters()) { 4123 answer = new LazyLoadingTypeConverter(packageScanClassResolver, getInjector(), getDefaultFactoryFinder()); 4124 } else { 4125 answer = new DefaultTypeConverter(packageScanClassResolver, getInjector(), getDefaultFactoryFinder(), isLoadTypeConverters()); 4126 } 4127 answer.setCamelContext(this); 4128 setTypeConverterRegistry(answer); 4129 return answer; 4130 } 4131 4132 /** 4133 * Lazily create a default implementation 4134 */ 4135 protected Injector createInjector() { 4136 FactoryFinder finder = getDefaultFactoryFinder(); 4137 try { 4138 return (Injector) finder.newInstance("Injector"); 4139 } catch (NoFactoryAvailableException e) { 4140 // lets use the default injector 4141 return new DefaultInjector(this); 4142 } 4143 } 4144 4145 /** 4146 * Lazily create a default implementation 4147 */ 4148 protected ManagementMBeanAssembler createManagementMBeanAssembler() { 4149 return new DefaultManagementMBeanAssembler(this); 4150 } 4151 4152 /** 4153 * Lazily create a default implementation 4154 */ 4155 protected ComponentResolver createComponentResolver() { 4156 return new DefaultComponentResolver(); 4157 } 4158 4159 /** 4160 * Lazily create a default implementation 4161 */ 4162 protected Registry createRegistry() { 4163 JndiRegistry jndi = new JndiRegistry(); 4164 try { 4165 // getContext() will force setting up JNDI 4166 jndi.getContext(); 4167 return jndi; 4168 } catch (Throwable e) { 4169 log.debug("Cannot create javax.naming.InitialContext due " + e.getMessage() + ". Will fallback and use SimpleRegistry instead. This exception is ignored.", e); 4170 return new SimpleRegistry(); 4171 } 4172 } 4173 4174 /** 4175 * A pluggable strategy to allow an endpoint to be created without requiring 4176 * a component to be its factory, such as for looking up the URI inside some 4177 * {@link Registry} 4178 * 4179 * @param uri the uri for the endpoint to be created 4180 * @return the newly created endpoint or null if it could not be resolved 4181 */ 4182 protected Endpoint createEndpoint(String uri) { 4183 Object value = getRegistry().lookupByName(uri); 4184 if (value instanceof Endpoint) { 4185 return (Endpoint) value; 4186 } else if (value instanceof Processor) { 4187 return new ProcessorEndpoint(uri, this, (Processor) value); 4188 } else if (value != null) { 4189 return convertBeanToEndpoint(uri, value); 4190 } 4191 return null; 4192 } 4193 4194 /** 4195 * Strategy method for attempting to convert the bean from a {@link Registry} to an endpoint using 4196 * some kind of transformation or wrapper 4197 * 4198 * @param uri the uri for the endpoint (and name in the registry) 4199 * @param bean the bean to be converted to an endpoint, which will be not null 4200 * @return a new endpoint 4201 */ 4202 protected Endpoint convertBeanToEndpoint(String uri, Object bean) { 4203 throw new IllegalArgumentException("uri: " + uri + " bean: " + bean 4204 + " could not be converted to an Endpoint"); 4205 } 4206 4207 /** 4208 * Should we start newly added routes? 4209 */ 4210 protected boolean shouldStartRoutes() { 4211 return isStarted() && !isStarting(); 4212 } 4213 4214 /** 4215 * Gets the properties component in use. 4216 * Returns {@code null} if no properties component is in use. 4217 */ 4218 protected PropertiesComponent getPropertiesComponent() { 4219 return propertiesComponent; 4220 } 4221 4222 public void setDataFormats(Map<String, DataFormatDefinition> dataFormats) { 4223 this.dataFormats = dataFormats; 4224 } 4225 4226 public Map<String, DataFormatDefinition> getDataFormats() { 4227 return dataFormats; 4228 } 4229 4230 @Deprecated 4231 public Map<String, String> getProperties() { 4232 return getGlobalOptions(); 4233 } 4234 4235 @Override 4236 public Map<String, String> getGlobalOptions() { 4237 return globalOptions; 4238 } 4239 4240 @Deprecated 4241 public void setProperties(Map<String, String> properties) { 4242 this.setGlobalOptions(properties); 4243 } 4244 4245 @Override 4246 public void setGlobalOptions(Map<String, String> globalOptions) { 4247 this.globalOptions = globalOptions; 4248 } 4249 4250 public FactoryFinder getDefaultFactoryFinder() { 4251 if (defaultFactoryFinder == null) { 4252 defaultFactoryFinder = getFactoryFinderResolver().resolveDefaultFactoryFinder(getClassResolver()); 4253 } 4254 return defaultFactoryFinder; 4255 } 4256 4257 public FactoryFinderResolver getFactoryFinderResolver() { 4258 if (factoryFinderResolver == null) { 4259 factoryFinderResolver = createFactoryFinderResolver(); 4260 } 4261 return factoryFinderResolver; 4262 } 4263 4264 public void setFactoryFinderResolver(FactoryFinderResolver resolver) { 4265 this.factoryFinderResolver = resolver; 4266 } 4267 4268 public FactoryFinder getFactoryFinder(String path) throws NoFactoryAvailableException { 4269 synchronized (factories) { 4270 FactoryFinder answer = factories.get(path); 4271 if (answer == null) { 4272 answer = getFactoryFinderResolver().resolveFactoryFinder(getClassResolver(), path); 4273 factories.put(path, answer); 4274 } 4275 return answer; 4276 } 4277 } 4278 4279 public ClassResolver getClassResolver() { 4280 return classResolver; 4281 } 4282 4283 public void setClassResolver(ClassResolver classResolver) { 4284 this.classResolver = classResolver; 4285 } 4286 4287 public PackageScanClassResolver getPackageScanClassResolver() { 4288 return packageScanClassResolver; 4289 } 4290 4291 public void setPackageScanClassResolver(PackageScanClassResolver packageScanClassResolver) { 4292 this.packageScanClassResolver = packageScanClassResolver; 4293 } 4294 4295 public List<String> getComponentNames() { 4296 List<String> answer = new ArrayList<>(); 4297 for (String name : components.keySet()) { 4298 answer.add(name); 4299 } 4300 return answer; 4301 } 4302 4303 public List<String> getLanguageNames() { 4304 synchronized (languages) { 4305 List<String> answer = new ArrayList<>(); 4306 for (String name : languages.keySet()) { 4307 answer.add(name); 4308 } 4309 return answer; 4310 } 4311 } 4312 4313 public ModelJAXBContextFactory getModelJAXBContextFactory() { 4314 if (modelJAXBContextFactory == null) { 4315 modelJAXBContextFactory = createModelJAXBContextFactory(); 4316 } 4317 return modelJAXBContextFactory; 4318 } 4319 4320 public void setModelJAXBContextFactory(final ModelJAXBContextFactory modelJAXBContextFactory) { 4321 this.modelJAXBContextFactory = modelJAXBContextFactory; 4322 } 4323 4324 public NodeIdFactory getNodeIdFactory() { 4325 return nodeIdFactory; 4326 } 4327 4328 public void setNodeIdFactory(NodeIdFactory idFactory) { 4329 this.nodeIdFactory = idFactory; 4330 } 4331 4332 public ManagementStrategy getManagementStrategy() { 4333 return managementStrategy; 4334 } 4335 4336 public void setManagementStrategy(ManagementStrategy managementStrategy) { 4337 this.managementStrategy = managementStrategy; 4338 } 4339 4340 public InterceptStrategy getDefaultTracer() { 4341 if (defaultTracer == null) { 4342 defaultTracer = new Tracer(); 4343 } 4344 return defaultTracer; 4345 } 4346 4347 public void setDefaultTracer(InterceptStrategy tracer) { 4348 this.defaultTracer = tracer; 4349 } 4350 4351 public InterceptStrategy getDefaultBacklogTracer() { 4352 if (defaultBacklogTracer == null) { 4353 defaultBacklogTracer = BacklogTracer.createTracer(this); 4354 } 4355 return defaultBacklogTracer; 4356 } 4357 4358 public void setDefaultBacklogTracer(InterceptStrategy backlogTracer) { 4359 this.defaultBacklogTracer = backlogTracer; 4360 } 4361 4362 public InterceptStrategy getDefaultBacklogDebugger() { 4363 if (defaultBacklogDebugger == null) { 4364 defaultBacklogDebugger = new BacklogDebugger(this); 4365 } 4366 return defaultBacklogDebugger; 4367 } 4368 4369 public void setDefaultBacklogDebugger(InterceptStrategy defaultBacklogDebugger) { 4370 this.defaultBacklogDebugger = defaultBacklogDebugger; 4371 } 4372 4373 public void disableJMX() { 4374 if (isStarting() || isStarted()) { 4375 throw new IllegalStateException("Disabling JMX can only be done when CamelContext has not been started"); 4376 } 4377 managementStrategy = new DefaultManagementStrategy(this); 4378 // must clear lifecycle strategies as we add DefaultManagementLifecycleStrategy by default for JMX support 4379 lifecycleStrategies.clear(); 4380 } 4381 4382 public InflightRepository getInflightRepository() { 4383 return inflightRepository; 4384 } 4385 4386 public void setInflightRepository(InflightRepository repository) { 4387 this.inflightRepository = repository; 4388 } 4389 4390 public AsyncProcessorAwaitManager getAsyncProcessorAwaitManager() { 4391 return asyncProcessorAwaitManager; 4392 } 4393 4394 public void setAsyncProcessorAwaitManager(AsyncProcessorAwaitManager asyncProcessorAwaitManager) { 4395 this.asyncProcessorAwaitManager = asyncProcessorAwaitManager; 4396 } 4397 4398 public void setAutoStartup(Boolean autoStartup) { 4399 this.autoStartup = autoStartup; 4400 } 4401 4402 public Boolean isAutoStartup() { 4403 return autoStartup != null && autoStartup; 4404 } 4405 4406 @Deprecated 4407 public Boolean isLazyLoadTypeConverters() { 4408 return lazyLoadTypeConverters != null && lazyLoadTypeConverters; 4409 } 4410 4411 @Deprecated 4412 public void setLazyLoadTypeConverters(Boolean lazyLoadTypeConverters) { 4413 this.lazyLoadTypeConverters = lazyLoadTypeConverters; 4414 } 4415 4416 public Boolean isLoadTypeConverters() { 4417 return loadTypeConverters != null && loadTypeConverters; 4418 } 4419 4420 public void setLoadTypeConverters(Boolean loadTypeConverters) { 4421 this.loadTypeConverters = loadTypeConverters; 4422 } 4423 4424 public Boolean isTypeConverterStatisticsEnabled() { 4425 return typeConverterStatisticsEnabled != null && typeConverterStatisticsEnabled; 4426 } 4427 4428 public void setTypeConverterStatisticsEnabled(Boolean typeConverterStatisticsEnabled) { 4429 this.typeConverterStatisticsEnabled = typeConverterStatisticsEnabled; 4430 } 4431 4432 public Boolean isUseMDCLogging() { 4433 return useMDCLogging != null && useMDCLogging; 4434 } 4435 4436 public void setUseMDCLogging(Boolean useMDCLogging) { 4437 this.useMDCLogging = useMDCLogging; 4438 } 4439 4440 public Boolean isUseDataType() { 4441 return useDataType; 4442 } 4443 4444 @Override 4445 public void setUseDataType(Boolean useDataType) { 4446 this.useDataType = useDataType; 4447 } 4448 4449 public Boolean isUseBreadcrumb() { 4450 return useBreadcrumb != null && useBreadcrumb; 4451 } 4452 4453 public void setUseBreadcrumb(Boolean useBreadcrumb) { 4454 this.useBreadcrumb = useBreadcrumb; 4455 } 4456 4457 public ClassLoader getApplicationContextClassLoader() { 4458 return applicationContextClassLoader; 4459 } 4460 4461 public void setApplicationContextClassLoader(ClassLoader classLoader) { 4462 applicationContextClassLoader = classLoader; 4463 } 4464 4465 public DataFormatResolver getDataFormatResolver() { 4466 if (dataFormatResolver == null) { 4467 dataFormatResolver = createDataFormatResolver(); 4468 } 4469 return dataFormatResolver; 4470 } 4471 4472 public void setDataFormatResolver(DataFormatResolver dataFormatResolver) { 4473 this.dataFormatResolver = dataFormatResolver; 4474 } 4475 4476 public DataFormat resolveDataFormat(String name) { 4477 DataFormat answer = getDataFormatResolver().resolveDataFormat(name, this); 4478 4479 // inject CamelContext if aware 4480 if (answer instanceof CamelContextAware) { 4481 ((CamelContextAware) answer).setCamelContext(this); 4482 } 4483 4484 return answer; 4485 } 4486 4487 public DataFormat createDataFormat(String name) { 4488 DataFormat answer = getDataFormatResolver().createDataFormat(name, this); 4489 4490 // inject CamelContext if aware 4491 if (answer instanceof CamelContextAware) { 4492 ((CamelContextAware) answer).setCamelContext(this); 4493 } 4494 4495 return answer; 4496 } 4497 4498 public DataFormatDefinition resolveDataFormatDefinition(String name) { 4499 // lookup type and create the data format from it 4500 DataFormatDefinition type = lookup(this, name, DataFormatDefinition.class); 4501 if (type == null && getDataFormats() != null) { 4502 type = getDataFormats().get(name); 4503 } 4504 return type; 4505 } 4506 4507 private static <T> T lookup(CamelContext context, String ref, Class<T> type) { 4508 try { 4509 return context.getRegistry().lookupByNameAndType(ref, type); 4510 } catch (Exception e) { 4511 // need to ignore not same type and return it as null 4512 return null; 4513 } 4514 } 4515 4516 /** 4517 * @deprecated use {@link org.apache.camel.util.CamelContextHelper#lookupPropertiesComponent(org.apache.camel.CamelContext, boolean)} 4518 */ 4519 @Deprecated 4520 protected Component lookupPropertiesComponent() { 4521 return CamelContextHelper.lookupPropertiesComponent(this, false); 4522 } 4523 4524 public ShutdownStrategy getShutdownStrategy() { 4525 return shutdownStrategy; 4526 } 4527 4528 public void setShutdownStrategy(ShutdownStrategy shutdownStrategy) { 4529 this.shutdownStrategy = shutdownStrategy; 4530 } 4531 4532 public ShutdownRoute getShutdownRoute() { 4533 return shutdownRoute; 4534 } 4535 4536 public void setShutdownRoute(ShutdownRoute shutdownRoute) { 4537 this.shutdownRoute = shutdownRoute; 4538 } 4539 4540 public ShutdownRunningTask getShutdownRunningTask() { 4541 return shutdownRunningTask; 4542 } 4543 4544 public void setShutdownRunningTask(ShutdownRunningTask shutdownRunningTask) { 4545 this.shutdownRunningTask = shutdownRunningTask; 4546 } 4547 4548 public void setAllowUseOriginalMessage(Boolean allowUseOriginalMessage) { 4549 this.allowUseOriginalMessage = allowUseOriginalMessage; 4550 } 4551 4552 public Boolean isAllowUseOriginalMessage() { 4553 return allowUseOriginalMessage != null && allowUseOriginalMessage; 4554 } 4555 4556 public ExecutorServiceManager getExecutorServiceManager() { 4557 return this.executorServiceManager; 4558 } 4559 4560 @Deprecated 4561 public org.apache.camel.spi.ExecutorServiceStrategy getExecutorServiceStrategy() { 4562 // its okay to create a new instance as its stateless, and just delegate 4563 // ExecutorServiceManager which is the new API 4564 return new DefaultExecutorServiceStrategy(this); 4565 } 4566 4567 public void setExecutorServiceManager(ExecutorServiceManager executorServiceManager) { 4568 this.executorServiceManager = executorServiceManager; 4569 } 4570 4571 public ProcessorFactory getProcessorFactory() { 4572 return processorFactory; 4573 } 4574 4575 public void setProcessorFactory(ProcessorFactory processorFactory) { 4576 this.processorFactory = processorFactory; 4577 } 4578 4579 public MessageHistoryFactory getMessageHistoryFactory() { 4580 return messageHistoryFactory; 4581 } 4582 4583 public void setMessageHistoryFactory(MessageHistoryFactory messageHistoryFactory) { 4584 this.messageHistoryFactory = messageHistoryFactory; 4585 } 4586 4587 public Debugger getDebugger() { 4588 return debugger; 4589 } 4590 4591 public void setDebugger(Debugger debugger) { 4592 this.debugger = debugger; 4593 } 4594 4595 public UuidGenerator getUuidGenerator() { 4596 return uuidGenerator; 4597 } 4598 4599 public void setUuidGenerator(UuidGenerator uuidGenerator) { 4600 this.uuidGenerator = uuidGenerator; 4601 } 4602 4603 public StreamCachingStrategy getStreamCachingStrategy() { 4604 if (streamCachingStrategy == null) { 4605 streamCachingStrategy = new DefaultStreamCachingStrategy(); 4606 } 4607 return streamCachingStrategy; 4608 } 4609 4610 public void setStreamCachingStrategy(StreamCachingStrategy streamCachingStrategy) { 4611 this.streamCachingStrategy = streamCachingStrategy; 4612 } 4613 4614 public RestRegistry getRestRegistry() { 4615 return restRegistry; 4616 } 4617 4618 public void setRestRegistry(RestRegistry restRegistry) { 4619 this.restRegistry = restRegistry; 4620 } 4621 4622 @Deprecated 4623 @Override 4624 public String getProperty(String key) { 4625 return getGlobalOption(key); 4626 } 4627 4628 @Override 4629 public String getGlobalOption(String key) { 4630 String value = getGlobalOptions().get(key); 4631 if (ObjectHelper.isNotEmpty(value)) { 4632 try { 4633 value = resolvePropertyPlaceholders(value); 4634 } catch (Exception e) { 4635 throw new RuntimeCamelException("Error getting global option: " + key, e); 4636 } 4637 } 4638 return value; 4639 } 4640 4641 @Override 4642 public ReloadStrategy getReloadStrategy() { 4643 return reloadStrategy; 4644 } 4645 4646 @Override 4647 public void setReloadStrategy(ReloadStrategy reloadStrategy) { 4648 this.reloadStrategy = reloadStrategy; 4649 } 4650 4651 @Override 4652 public void setTransformers(List<TransformerDefinition> transformers) { 4653 this.transformers = transformers; 4654 } 4655 4656 @Override 4657 public List<TransformerDefinition> getTransformers() { 4658 return transformers; 4659 } 4660 4661 @Override 4662 public Transformer resolveTransformer(String scheme) { 4663 return transformerRegistry.resolveTransformer(new TransformerKey(scheme)); 4664 } 4665 4666 @Override 4667 public Transformer resolveTransformer(DataType from, DataType to) { 4668 return transformerRegistry.resolveTransformer(new TransformerKey(from, to)); 4669 } 4670 4671 @Override 4672 public TransformerRegistry<TransformerKey> getTransformerRegistry() { 4673 return transformerRegistry; 4674 } 4675 4676 @Override 4677 public void setValidators(List<ValidatorDefinition> validators) { 4678 this.validators = validators; 4679 } 4680 4681 @Override 4682 public List<ValidatorDefinition> getValidators() { 4683 return validators; 4684 } 4685 4686 @Override 4687 public Validator resolveValidator(DataType type) { 4688 return validatorRegistry.resolveValidator(new ValidatorKey(type)); 4689 } 4690 4691 @Override 4692 public ValidatorRegistry<ValidatorKey> getValidatorRegistry() { 4693 return validatorRegistry; 4694 } 4695 4696 @Override 4697 public RuntimeCamelCatalog getRuntimeCamelCatalog() { 4698 return runtimeCamelCatalog; 4699 } 4700 4701 @Override 4702 public void setSSLContextParameters(SSLContextParameters sslContextParameters) { 4703 this.sslContextParameters = sslContextParameters; 4704 } 4705 4706 @Override 4707 public SSLContextParameters getSSLContextParameters() { 4708 return this.sslContextParameters; 4709 } 4710 4711 @Override 4712 public HeadersMapFactory getHeadersMapFactory() { 4713 return headersMapFactory; 4714 } 4715 4716 @Override 4717 public void setHeadersMapFactory(HeadersMapFactory headersMapFactory) { 4718 this.headersMapFactory = headersMapFactory; 4719 } 4720 4721 protected Map<String, RouteService> getRouteServices() { 4722 return routeServices; 4723 } 4724 4725 protected ManagementStrategy createManagementStrategy() { 4726 return new ManagementStrategyFactory().create(this, disableJMX || Boolean.getBoolean(JmxSystemPropertyKeys.DISABLED)); 4727 } 4728 4729 /** 4730 * Reset context counter to a preset value. Mostly used for tests to ensure a predictable getName() 4731 * 4732 * @param value new value for the context counter 4733 */ 4734 public static void setContextCounter(int value) { 4735 DefaultCamelContextNameStrategy.setCounter(value); 4736 DefaultManagementNameStrategy.setCounter(value); 4737 } 4738 4739 protected UuidGenerator createDefaultUuidGenerator() { 4740 if (System.getProperty("com.google.appengine.runtime.environment") != null) { 4741 // either "Production" or "Development" 4742 return new JavaUuidGenerator(); 4743 } else { 4744 return new DefaultUuidGenerator(); 4745 } 4746 } 4747 4748 protected ModelJAXBContextFactory createModelJAXBContextFactory() { 4749 return new DefaultModelJAXBContextFactory(); 4750 } 4751 4752 @Override 4753 public String toString() { 4754 return "CamelContext(" + getName() + ")"; 4755 } 4756 4757 class MDCHelper implements AutoCloseable { 4758 final Map<String, String> originalContextMap; 4759 4760 MDCHelper() { 4761 if (isUseMDCLogging()) { 4762 originalContextMap = MDC.getCopyOfContextMap(); 4763 MDC.put(MDC_CAMEL_CONTEXT_ID, getName()); 4764 } else { 4765 originalContextMap = null; 4766 } 4767 } 4768 4769 @Override 4770 public void close() { 4771 if (isUseMDCLogging()) { 4772 if (originalContextMap != null) { 4773 MDC.setContextMap(originalContextMap); 4774 } else { 4775 MDC.clear(); 4776 } 4777 } 4778 } 4779 } 4780 4781 @Override 4782 public HealthCheckRegistry getHealthCheckRegistry() { 4783 return healthCheckRegistry; 4784 } 4785 4786 /** 4787 * Sets a {@link HealthCheckRegistry}. 4788 */ 4789 public void setHealthCheckRegistry(HealthCheckRegistry healthCheckRegistry) { 4790 this.healthCheckRegistry = ObjectHelper.notNull(healthCheckRegistry, "HealthCheckRegistry"); 4791 } 4792 4793 protected NodeIdFactory createNodeIdFactory() { 4794 return new DefaultNodeIdFactory(); 4795 } 4796 4797 protected FactoryFinderResolver createFactoryFinderResolver() { 4798 return new DefaultFactoryFinderResolver(); 4799 } 4800 4801 protected ClassResolver createClassResolver() { 4802 return new DefaultClassResolver(this); 4803 } 4804 4805 protected ProcessorFactory createProcessorFactory() { 4806 return new DefaultProcessorFactory(); 4807 } 4808 4809 protected DataFormatResolver createDataFormatResolver() { 4810 return new DefaultDataFormatResolver(); 4811 } 4812 4813 protected MessageHistoryFactory createMessageHistoryFactory() { 4814 return new DefaultMessageHistoryFactory(); 4815 } 4816 4817 protected InflightRepository createInflightRepository() { 4818 return new DefaultInflightRepository(); 4819 } 4820 4821 protected AsyncProcessorAwaitManager createAsyncProcessorAwaitManager() { 4822 return new DefaultAsyncProcessorAwaitManager(); 4823 } 4824 4825 protected RouteController createRouteController() { 4826 return new DefaultRouteController(this); 4827 } 4828 4829 protected HealthCheckRegistry createHealthCheckRegistry() { 4830 return new DefaultHealthCheckRegistry(this); 4831 } 4832 4833 4834 protected ShutdownStrategy createShutdownStrategy() { 4835 return new DefaultShutdownStrategy(this); 4836 } 4837 4838 protected PackageScanClassResolver createPackageScanClassResolver() { 4839 PackageScanClassResolver packageScanClassResolver; 4840 // use WebSphere specific resolver if running on WebSphere 4841 if (WebSpherePackageScanClassResolver.isWebSphereClassLoader(this.getClass().getClassLoader())) { 4842 log.info("Using WebSphere specific PackageScanClassResolver"); 4843 packageScanClassResolver = new WebSpherePackageScanClassResolver("META-INF/services/org/apache/camel/TypeConverter"); 4844 } else { 4845 packageScanClassResolver = new DefaultPackageScanClassResolver(); 4846 } 4847 return packageScanClassResolver; 4848 } 4849 4850 protected ExecutorServiceManager createExecutorServiceManager() { 4851 return new DefaultExecutorServiceManager(this); 4852 } 4853 4854 protected ServicePool<Endpoint, Producer> createProducerServicePool() { 4855 return new SharedProducerServicePool(100); 4856 } 4857 4858 protected ServicePool<Endpoint, PollingConsumer> createPollingConsumerServicePool() { 4859 return new SharedPollingConsumerServicePool(100); 4860 } 4861 4862 protected UnitOfWorkFactory createUnitOfWorkFactory() { 4863 return new DefaultUnitOfWorkFactory(); 4864 } 4865 4866 protected RuntimeCamelCatalog createRuntimeCamelCatalog() { 4867 return new DefaultRuntimeCamelCatalog(this, true); 4868 } 4869 4870 protected CamelContextNameStrategy createCamelContextNameStrategy() { 4871 return new DefaultCamelContextNameStrategy(); 4872 } 4873 4874 protected ManagementNameStrategy createManagementNameStrategy() { 4875 return new DefaultManagementNameStrategy(this); 4876 } 4877 4878 protected HeadersMapFactory createHeadersMapFactory() { 4879 return new DefaultHeadersMapFactory(); 4880 } 4881 4882 protected LanguageResolver createLanguageResolver() { 4883 return new DefaultLanguageResolver(); 4884 } 4885 4886 protected EndpointRegistry<EndpointKey> createEndpointRegistry(Map<EndpointKey, Endpoint> endpoints) { 4887 return new DefaultEndpointRegistry(this, endpoints); 4888 } 4889 4890 protected ValidatorRegistry<ValidatorKey> createValidatorRegistry(List<ValidatorDefinition> validators) throws Exception { 4891 return new DefaultValidatorRegistry(this, validators); 4892 } 4893 4894 protected TransformerRegistry<TransformerKey> createTransformerRegistry(List<TransformerDefinition> transformers) throws Exception { 4895 return new DefaultTransformerRegistry(this, transformers); 4896 } 4897 4898}