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 */
017 package org.apache.camel.core.xml;
018
019 import java.util.ArrayList;
020 import java.util.HashSet;
021 import java.util.List;
022 import java.util.Map;
023 import java.util.Map.Entry;
024 import java.util.Set;
025 import javax.xml.bind.annotation.XmlAccessType;
026 import javax.xml.bind.annotation.XmlAccessorType;
027 import javax.xml.bind.annotation.XmlTransient;
028
029 import org.apache.camel.CamelContext;
030 import org.apache.camel.CamelException;
031 import org.apache.camel.RoutesBuilder;
032 import org.apache.camel.ShutdownRoute;
033 import org.apache.camel.ShutdownRunningTask;
034 import org.apache.camel.builder.ErrorHandlerBuilderRef;
035 import org.apache.camel.builder.RouteBuilder;
036 import org.apache.camel.component.properties.PropertiesComponent;
037 import org.apache.camel.component.properties.PropertiesParser;
038 import org.apache.camel.component.properties.PropertiesResolver;
039 import org.apache.camel.core.xml.scan.PatternBasedPackageScanFilter;
040 import org.apache.camel.management.DefaultManagementAgent;
041 import org.apache.camel.management.DefaultManagementLifecycleStrategy;
042 import org.apache.camel.management.DefaultManagementStrategy;
043 import org.apache.camel.management.ManagedManagementStrategy;
044 import org.apache.camel.model.ContextScanDefinition;
045 import org.apache.camel.model.IdentifiedType;
046 import org.apache.camel.model.InterceptDefinition;
047 import org.apache.camel.model.InterceptFromDefinition;
048 import org.apache.camel.model.InterceptSendToEndpointDefinition;
049 import org.apache.camel.model.OnCompletionDefinition;
050 import org.apache.camel.model.OnExceptionDefinition;
051 import org.apache.camel.model.PackageScanDefinition;
052 import org.apache.camel.model.RouteBuilderDefinition;
053 import org.apache.camel.model.RouteContainer;
054 import org.apache.camel.model.RouteContextRefDefinition;
055 import org.apache.camel.model.RouteDefinition;
056 import org.apache.camel.model.RouteDefinitionHelper;
057 import org.apache.camel.model.ThreadPoolProfileDefinition;
058 import org.apache.camel.model.config.PropertiesDefinition;
059 import org.apache.camel.model.dataformat.DataFormatsDefinition;
060 import org.apache.camel.processor.interceptor.Delayer;
061 import org.apache.camel.processor.interceptor.HandleFault;
062 import org.apache.camel.processor.interceptor.TraceFormatter;
063 import org.apache.camel.processor.interceptor.Tracer;
064 import org.apache.camel.spi.ClassResolver;
065 import org.apache.camel.spi.Debugger;
066 import org.apache.camel.spi.EndpointStrategy;
067 import org.apache.camel.spi.EventFactory;
068 import org.apache.camel.spi.EventNotifier;
069 import org.apache.camel.spi.ExecutorServiceStrategy;
070 import org.apache.camel.spi.FactoryFinderResolver;
071 import org.apache.camel.spi.InflightRepository;
072 import org.apache.camel.spi.InterceptStrategy;
073 import org.apache.camel.spi.LifecycleStrategy;
074 import org.apache.camel.spi.ManagementNamingStrategy;
075 import org.apache.camel.spi.ManagementStrategy;
076 import org.apache.camel.spi.PackageScanClassResolver;
077 import org.apache.camel.spi.PackageScanFilter;
078 import org.apache.camel.spi.ProcessorFactory;
079 import org.apache.camel.spi.ShutdownStrategy;
080 import org.apache.camel.spi.ThreadPoolProfile;
081 import org.apache.camel.spi.UuidGenerator;
082 import org.apache.camel.util.CamelContextHelper;
083 import org.apache.camel.util.ObjectHelper;
084 import org.slf4j.Logger;
085 import org.slf4j.LoggerFactory;
086
087 /**
088 * A factory to create and initialize a
089 * {@link CamelContext} and install routes either explicitly configured
090 * or found by searching the classpath for Java classes which extend
091 * {@link org.apache.camel.builder.RouteBuilder}.
092 *
093 * @version
094 */
095 @XmlAccessorType(XmlAccessType.FIELD)
096 public abstract class AbstractCamelContextFactoryBean<T extends CamelContext> extends IdentifiedType implements RouteContainer {
097 private static final Logger LOG = LoggerFactory.getLogger(AbstractCamelContextFactoryBean.class);
098
099 @XmlTransient
100 private List<RoutesBuilder> builders = new ArrayList<RoutesBuilder>();
101 @XmlTransient
102 private ClassLoader contextClassLoaderOnStart;
103
104 public AbstractCamelContextFactoryBean() {
105 // Lets keep track of the class loader for when we actually do start things up
106 contextClassLoaderOnStart = Thread.currentThread().getContextClassLoader();
107 }
108
109 public Object getObject() throws Exception {
110 return getContext();
111 }
112
113 public Class getObjectType() {
114 return CamelContext.class;
115 }
116
117 public boolean isSingleton() {
118 return true;
119 }
120
121 public ClassLoader getContextClassLoaderOnStart() {
122 return contextClassLoaderOnStart;
123 }
124
125 public void afterPropertiesSet() throws Exception {
126 if (ObjectHelper.isEmpty(getId())) {
127 throw new IllegalArgumentException("Id must be set");
128 }
129 if (getProperties() != null) {
130 getContext().setProperties(getProperties().asMap());
131 }
132
133 // set the type converter mode first
134 if (getLazyLoadTypeConverters() != null) {
135 getContext().setLazyLoadTypeConverters(getLazyLoadTypeConverters());
136 }
137
138 PackageScanClassResolver packageResolver = getBeanForType(PackageScanClassResolver.class);
139 if (packageResolver != null) {
140 LOG.info("Using custom PackageScanClassResolver: " + packageResolver);
141 getContext().setPackageScanClassResolver(packageResolver);
142 }
143 ClassResolver classResolver = getBeanForType(ClassResolver.class);
144 if (classResolver != null) {
145 LOG.info("Using custom ClassResolver: " + classResolver);
146 getContext().setClassResolver(classResolver);
147 }
148 FactoryFinderResolver factoryFinderResolver = getBeanForType(FactoryFinderResolver.class);
149 if (factoryFinderResolver != null) {
150 LOG.info("Using custom FactoryFinderResolver: " + factoryFinderResolver);
151 getContext().setFactoryFinderResolver(factoryFinderResolver);
152 }
153 ExecutorServiceStrategy executorServiceStrategy = getBeanForType(ExecutorServiceStrategy.class);
154 if (executorServiceStrategy != null) {
155 LOG.info("Using custom ExecutorServiceStrategy: " + executorServiceStrategy);
156 getContext().setExecutorServiceStrategy(executorServiceStrategy);
157 }
158 ProcessorFactory processorFactory = getBeanForType(ProcessorFactory.class);
159 if (processorFactory != null) {
160 LOG.info("Using custom ProcessorFactory: " + processorFactory);
161 getContext().setProcessorFactory(processorFactory);
162 }
163 Debugger debugger = getBeanForType(Debugger.class);
164 if (debugger != null) {
165 LOG.info("Using custom Debugger: " + debugger);
166 getContext().setDebugger(debugger);
167 }
168 UuidGenerator uuidGenerator = getBeanForType(UuidGenerator.class);
169 if (uuidGenerator != null) {
170 LOG.info("Using custom UuidGenerator: " + uuidGenerator);
171 getContext().setUuidGenerator(uuidGenerator);
172 }
173
174 // set the custom registry if defined
175 initCustomRegistry(getContext());
176
177 // setup property placeholder so we got it as early as possible
178 initPropertyPlaceholder();
179
180 // setup JMX agent at first
181 initJMXAgent();
182
183 Tracer tracer = getBeanForType(Tracer.class);
184 if (tracer != null) {
185 // use formatter if there is a TraceFormatter bean defined
186 TraceFormatter formatter = getBeanForType(TraceFormatter.class);
187 if (formatter != null) {
188 tracer.setFormatter(formatter);
189 }
190 LOG.info("Using custom Tracer: " + tracer);
191 getContext().addInterceptStrategy(tracer);
192 }
193 HandleFault handleFault = getBeanForType(HandleFault.class);
194 if (handleFault != null) {
195 LOG.info("Using custom HandleFault: " + handleFault);
196 getContext().addInterceptStrategy(handleFault);
197 }
198 Delayer delayer = getBeanForType(Delayer.class);
199 if (delayer != null) {
200 LOG.info("Using custom Delayer: " + delayer);
201 getContext().addInterceptStrategy(delayer);
202 }
203 InflightRepository inflightRepository = getBeanForType(InflightRepository.class);
204 if (delayer != null) {
205 LOG.info("Using custom InflightRepository: " + inflightRepository);
206 getContext().setInflightRepository(inflightRepository);
207 }
208 ManagementStrategy managementStrategy = getBeanForType(ManagementStrategy.class);
209 if (managementStrategy != null) {
210 LOG.info("Using custom ManagementStrategy: " + managementStrategy);
211 getContext().setManagementStrategy(managementStrategy);
212 }
213 ManagementNamingStrategy managementNamingStrategy = getBeanForType(ManagementNamingStrategy.class);
214 if (managementNamingStrategy != null) {
215 LOG.info("Using custom ManagementNamingStrategy: " + managementNamingStrategy);
216 getContext().getManagementStrategy().setManagementNamingStrategy(managementNamingStrategy);
217 }
218 EventFactory eventFactory = getBeanForType(EventFactory.class);
219 if (eventFactory != null) {
220 LOG.info("Using custom EventFactory: " + eventFactory);
221 getContext().getManagementStrategy().setEventFactory(eventFactory);
222 }
223 // set the event notifier strategies if defined
224 Map<String, EventNotifier> eventNotifiers = getContext().getRegistry().lookupByType(EventNotifier.class);
225 if (eventNotifiers != null && !eventNotifiers.isEmpty()) {
226 for (Entry<String, EventNotifier> entry : eventNotifiers.entrySet()) {
227 EventNotifier notifier = entry.getValue();
228 // do not add if already added, for instance a tracer that is also an InterceptStrategy class
229 if (!getContext().getManagementStrategy().getEventNotifiers().contains(notifier)) {
230 LOG.info("Using custom EventNotifier with id: " + entry.getKey() + " and implementation: " + notifier);
231 getContext().getManagementStrategy().addEventNotifier(notifier);
232 }
233 }
234 }
235 // set endpoint strategies if defined
236 Map<String, EndpointStrategy> endpointStrategies = getContext().getRegistry().lookupByType(EndpointStrategy.class);
237 if (endpointStrategies != null && !endpointStrategies.isEmpty()) {
238 for (Entry<String, EndpointStrategy> entry : endpointStrategies.entrySet()) {
239 EndpointStrategy strategy = entry.getValue();
240 LOG.info("Using custom EndpointStrategy with id: " + entry.getKey() + " and implementation: " + strategy);
241 getContext().addRegisterEndpointCallback(strategy);
242 }
243 }
244 // shutdown
245 ShutdownStrategy shutdownStrategy = getBeanForType(ShutdownStrategy.class);
246 if (shutdownStrategy != null) {
247 LOG.info("Using custom ShutdownStrategy: " + shutdownStrategy);
248 getContext().setShutdownStrategy(shutdownStrategy);
249 }
250 // add global interceptors
251 Map<String, InterceptStrategy> interceptStrategies = getContext().getRegistry().lookupByType(InterceptStrategy.class);
252 if (interceptStrategies != null && !interceptStrategies.isEmpty()) {
253 for (Entry<String, InterceptStrategy> entry : interceptStrategies.entrySet()) {
254 InterceptStrategy strategy = entry.getValue();
255 // do not add if already added, for instance a tracer that is also an InterceptStrategy class
256 if (!getContext().getInterceptStrategies().contains(strategy)) {
257 LOG.info("Using custom InterceptStrategy with id: " + entry.getKey() + " and implementation: " + strategy);
258 getContext().addInterceptStrategy(strategy);
259 }
260 }
261 }
262 // set the lifecycle strategy if defined
263 Map<String, LifecycleStrategy> lifecycleStrategies = getContext().getRegistry().lookupByType(LifecycleStrategy.class);
264 if (lifecycleStrategies != null && !lifecycleStrategies.isEmpty()) {
265 for (Entry<String, LifecycleStrategy> entry : lifecycleStrategies.entrySet()) {
266 LifecycleStrategy strategy = entry.getValue();
267 // do not add if already added, for instance a tracer that is also an InterceptStrategy class
268 if (!getContext().getLifecycleStrategies().contains(strategy)) {
269 LOG.info("Using custom LifecycleStrategy with id: " + entry.getKey() + " and implementation: " + strategy);
270 getContext().addLifecycleStrategy(strategy);
271 }
272 }
273 }
274
275 // set the default thread pool profile if defined
276 initThreadPoolProfiles(getContext());
277
278 // Set the application context and camelContext for the beanPostProcessor
279 initBeanPostProcessor(getContext());
280
281 // init camel context
282 initCamelContext(getContext());
283
284 // must init route refs before we prepare the routes below
285 initRouteRefs();
286
287 // do special preparation for some concepts such as interceptors and policies
288 // this is needed as JAXB does not build exactly the same model definition as Spring DSL would do
289 // using route builders. So we have here a little custom code to fix the JAXB gaps
290 prepareRoutes();
291
292 // and add the routes
293 getContext().addRouteDefinitions(getRoutes());
294
295 if (LOG.isDebugEnabled()) {
296 LOG.debug("Found JAXB created routes: " + getRoutes());
297 }
298 findRouteBuilders();
299 installRoutes();
300 }
301
302 /**
303 * Do special preparation for some concepts such as interceptors and policies
304 * this is needed as JAXB does not build exactly the same model definition as Spring DSL would do
305 * using route builders. So we have here a little custom code to fix the JAXB gaps
306 */
307 private void prepareRoutes() {
308 for (RouteDefinition route : getRoutes()) {
309 // leverage logic from route definition helper to prepare the route
310 RouteDefinitionHelper.prepareRoute(getContext(), route, getOnExceptions(), getIntercepts(), getInterceptFroms(),
311 getInterceptSendToEndpoints(), getOnCompletions());
312
313 // mark the route as prepared now
314 route.markPrepared();
315 }
316 }
317
318 protected abstract void initCustomRegistry(T context);
319
320 protected void initJMXAgent() throws Exception {
321 CamelJMXAgentDefinition camelJMXAgent = getCamelJMXAgent();
322
323 boolean disabled = false;
324 if (camelJMXAgent != null) {
325 disabled = CamelContextHelper.parseBoolean(getContext(), camelJMXAgent.getDisabled());
326 }
327
328 if (disabled) {
329 LOG.info("JMXAgent disabled");
330 // clear the existing lifecycle strategies define by the DefaultCamelContext constructor
331 getContext().getLifecycleStrategies().clear();
332 // no need to add a lifecycle strategy as we do not need one as JMX is disabled
333 getContext().setManagementStrategy(new DefaultManagementStrategy());
334 } else if (camelJMXAgent != null) {
335 LOG.info("JMXAgent enabled: " + camelJMXAgent);
336 DefaultManagementAgent agent = new DefaultManagementAgent(getContext());
337 agent.setConnectorPort(CamelContextHelper.parseInteger(getContext(), camelJMXAgent.getConnectorPort()));
338 agent.setCreateConnector(CamelContextHelper.parseBoolean(getContext(), camelJMXAgent.getCreateConnector()));
339 agent.setMBeanObjectDomainName(CamelContextHelper.parseText(getContext(), camelJMXAgent.getMbeanObjectDomainName()));
340 agent.setMBeanServerDefaultDomain(CamelContextHelper.parseText(getContext(), camelJMXAgent.getMbeanServerDefaultDomain()));
341 agent.setRegistryPort(CamelContextHelper.parseInteger(getContext(), camelJMXAgent.getRegistryPort()));
342 agent.setServiceUrlPath(CamelContextHelper.parseText(getContext(), camelJMXAgent.getServiceUrlPath()));
343 agent.setUsePlatformMBeanServer(CamelContextHelper.parseBoolean(getContext(), camelJMXAgent.getUsePlatformMBeanServer()));
344 agent.setOnlyRegisterProcessorWithCustomId(CamelContextHelper.parseBoolean(getContext(), camelJMXAgent.getOnlyRegisterProcessorWithCustomId()));
345 agent.setRegisterAlways(CamelContextHelper.parseBoolean(getContext(), camelJMXAgent.getRegisterAlways()));
346 agent.setRegisterNewRoutes(CamelContextHelper.parseBoolean(getContext(), camelJMXAgent.getRegisterNewRoutes()));
347
348 ManagementStrategy managementStrategy = new ManagedManagementStrategy(agent);
349 getContext().setManagementStrategy(managementStrategy);
350
351 // clear the existing lifecycle strategies define by the DefaultCamelContext constructor
352 getContext().getLifecycleStrategies().clear();
353 getContext().addLifecycleStrategy(new DefaultManagementLifecycleStrategy(getContext()));
354 // set additional configuration from camelJMXAgent
355 boolean onlyId = agent.getOnlyRegisterProcessorWithCustomId() != null && agent.getOnlyRegisterProcessorWithCustomId();
356 getContext().getManagementStrategy().onlyManageProcessorWithCustomId(onlyId);
357 getContext().getManagementStrategy().setStatisticsLevel(camelJMXAgent.getStatisticsLevel());
358 }
359 }
360
361 protected void initPropertyPlaceholder() throws Exception {
362 if (getCamelPropertyPlaceholder() != null) {
363 CamelPropertyPlaceholderDefinition def = getCamelPropertyPlaceholder();
364
365 PropertiesComponent pc = new PropertiesComponent();
366 pc.setLocation(def.getLocation());
367
368 // if using a custom resolver
369 if (ObjectHelper.isNotEmpty(def.getPropertiesResolverRef())) {
370 PropertiesResolver resolver = CamelContextHelper.mandatoryLookup(getContext(), def.getPropertiesResolverRef(),
371 PropertiesResolver.class);
372 pc.setPropertiesResolver(resolver);
373 }
374
375 // if using a custom parser
376 if (ObjectHelper.isNotEmpty(def.getPropertiesParserRef())) {
377 PropertiesParser parser = CamelContextHelper.mandatoryLookup(getContext(), def.getPropertiesParserRef(),
378 PropertiesParser.class);
379 pc.setPropertiesParser(parser);
380 }
381
382 // register the properties component
383 getContext().addComponent("properties", pc);
384 }
385 }
386
387 protected void initRouteRefs() throws Exception {
388 // add route refs to existing routes
389 if (getRouteRefs() != null) {
390 for (RouteContextRefDefinition ref : getRouteRefs()) {
391 List<RouteDefinition> defs = ref.lookupRoutes(getContext());
392 for (RouteDefinition def : defs) {
393 if (LOG.isDebugEnabled()) {
394 LOG.debug("Adding route from " + ref + " -> " + def);
395 }
396 // add in top as they are most likely to be common/shared
397 // which you may want to start first
398 getRoutes().add(0, def);
399 }
400 }
401 }
402 }
403
404 protected abstract <S> S getBeanForType(Class<S> clazz);
405
406 public void destroy() throws Exception {
407 getContext().stop();
408 }
409
410 // Properties
411 // -------------------------------------------------------------------------
412 public T getContext() {
413 return getContext(true);
414 }
415
416 public abstract T getContext(boolean create);
417
418 public abstract List<RouteDefinition> getRoutes();
419
420 public abstract List<? extends AbstractCamelEndpointFactoryBean> getEndpoints();
421
422 public abstract List<? extends AbstractCamelRedeliveryPolicyFactoryBean> getRedeliveryPolicies();
423
424 public abstract List<InterceptDefinition> getIntercepts();
425
426 public abstract List<InterceptFromDefinition> getInterceptFroms();
427
428 public abstract List<InterceptSendToEndpointDefinition> getInterceptSendToEndpoints();
429
430 public abstract PropertiesDefinition getProperties();
431
432 public abstract String[] getPackages();
433
434 public abstract PackageScanDefinition getPackageScan();
435
436 public abstract void setPackageScan(PackageScanDefinition packageScan);
437
438 public abstract ContextScanDefinition getContextScan();
439
440 public abstract void setContextScan(ContextScanDefinition contextScan);
441
442 public abstract CamelPropertyPlaceholderDefinition getCamelPropertyPlaceholder();
443
444 public abstract String getTrace();
445
446 public abstract String getStreamCache();
447
448 public abstract String getDelayer();
449
450 public abstract String getHandleFault();
451
452 public abstract String getAutoStartup();
453
454 public abstract String getUseMDCLogging();
455
456 public abstract Boolean getLazyLoadTypeConverters();
457
458 public abstract CamelJMXAgentDefinition getCamelJMXAgent();
459
460 public abstract List<RouteBuilderDefinition> getBuilderRefs();
461
462 public abstract List<RouteContextRefDefinition> getRouteRefs();
463
464 public abstract String getErrorHandlerRef();
465
466 public abstract DataFormatsDefinition getDataFormats();
467
468 public abstract List<OnExceptionDefinition> getOnExceptions();
469
470 public abstract List<OnCompletionDefinition> getOnCompletions();
471
472 public abstract ShutdownRoute getShutdownRoute();
473
474 public abstract ShutdownRunningTask getShutdownRunningTask();
475
476 public abstract List<ThreadPoolProfileDefinition> getThreadPoolProfiles();
477
478 public abstract String getDependsOn();
479
480 // Implementation methods
481 // -------------------------------------------------------------------------
482
483 /**
484 * Initializes the context
485 *
486 * @param ctx the context
487 * @throws Exception is thrown if error occurred
488 */
489 protected void initCamelContext(T ctx) throws Exception {
490 if (getStreamCache() != null) {
491 ctx.setStreamCaching(CamelContextHelper.parseBoolean(getContext(), getStreamCache()));
492 }
493 if (getTrace() != null) {
494 ctx.setTracing(CamelContextHelper.parseBoolean(getContext(), getTrace()));
495 }
496 if (getDelayer() != null) {
497 ctx.setDelayer(CamelContextHelper.parseLong(getContext(), getDelayer()));
498 }
499 if (getHandleFault() != null) {
500 ctx.setHandleFault(CamelContextHelper.parseBoolean(getContext(), getHandleFault()));
501 }
502 if (getErrorHandlerRef() != null) {
503 ctx.setErrorHandlerBuilder(new ErrorHandlerBuilderRef(getErrorHandlerRef()));
504 }
505 if (getAutoStartup() != null) {
506 ctx.setAutoStartup(CamelContextHelper.parseBoolean(getContext(), getAutoStartup()));
507 }
508 if (getUseMDCLogging() != null) {
509 ctx.setUseMDCLogging(CamelContextHelper.parseBoolean(getContext(), getUseMDCLogging()));
510 }
511 if (getShutdownRoute() != null) {
512 ctx.setShutdownRoute(getShutdownRoute());
513 }
514 if (getShutdownRunningTask() != null) {
515 ctx.setShutdownRunningTask(getShutdownRunningTask());
516 }
517 if (getDataFormats() != null) {
518 ctx.setDataFormats(getDataFormats().asMap());
519 }
520 }
521
522 protected void initThreadPoolProfiles(T context) throws Exception {
523 Set<String> defaultIds = new HashSet<String>();
524
525 // lookup and use custom profiles from the registry
526 Map<String, ThreadPoolProfile> profiles = context.getRegistry().lookupByType(ThreadPoolProfile.class);
527 if (profiles != null && !profiles.isEmpty()) {
528 for (Entry<String, ThreadPoolProfile> entry : profiles.entrySet()) {
529 ThreadPoolProfile profile = entry.getValue();
530 // do not add if already added, for instance a tracer that is also an InterceptStrategy class
531 if (profile.isDefaultProfile()) {
532 LOG.info("Using custom default ThreadPoolProfile with id: " + entry.getKey() + " and implementation: " + profile);
533 context.getExecutorServiceStrategy().setDefaultThreadPoolProfile(profile);
534 defaultIds.add(entry.getKey());
535 } else {
536 context.getExecutorServiceStrategy().registerThreadPoolProfile(profile);
537 }
538 }
539 }
540
541 // use custom profiles defined in the CamelContext
542 if (getThreadPoolProfiles() != null && !getThreadPoolProfiles().isEmpty()) {
543 for (ThreadPoolProfileDefinition profile : getThreadPoolProfiles()) {
544 if (profile.isDefaultProfile()) {
545 LOG.info("Using custom default ThreadPoolProfile with id: " + profile.getId() + " and implementation: " + profile);
546 context.getExecutorServiceStrategy().setDefaultThreadPoolProfile(profile.asThreadPoolProfile(context));
547 defaultIds.add(profile.getId());
548 } else {
549 context.getExecutorServiceStrategy().registerThreadPoolProfile(profile.asThreadPoolProfile(context));
550 }
551 }
552 }
553
554 // validate at most one is defined
555 if (defaultIds.size() > 1) {
556 throw new IllegalArgumentException("Only exactly one default ThreadPoolProfile is allowed, was " + defaultIds.size() + " ids: " + defaultIds);
557 }
558 }
559
560 protected abstract void initBeanPostProcessor(T context);
561
562 /**
563 * Strategy to install all available routes into the context
564 */
565 protected void installRoutes() throws Exception {
566 List<RouteBuilder> builders = new ArrayList<RouteBuilder>();
567
568 // lets add route builders added from references
569 if (getBuilderRefs() != null) {
570 for (RouteBuilderDefinition builderRef : getBuilderRefs()) {
571 RouteBuilder builder = builderRef.createRouteBuilder(getContext());
572 if (builder != null) {
573 builders.add(builder);
574 } else {
575 // support to get the route here
576 RoutesBuilder routes = builderRef.createRoutes(getContext());
577 if (routes != null) {
578 this.builders.add(routes);
579 } else {
580 // Throw the exception that we can't find any build here
581 throw new CamelException("Cannot find any routes with this RouteBuilder reference: " + builderRef);
582 }
583 }
584 }
585 }
586
587 // install already configured routes
588 for (RoutesBuilder routeBuilder : this.builders) {
589 getContext().addRoutes(routeBuilder);
590 }
591
592 // install builders
593 for (RouteBuilder builder : builders) {
594 // Inject the annotated resource
595 postProcessBeforeInit(builder);
596 getContext().addRoutes(builder);
597 }
598 }
599
600 protected abstract void postProcessBeforeInit(RouteBuilder builder);
601
602 /**
603 * Strategy method to try find {@link org.apache.camel.builder.RouteBuilder} instances on the classpath
604 */
605 protected void findRouteBuilders() throws Exception {
606 // package scan
607 addPackageElementContentsToScanDefinition();
608 PackageScanDefinition packageScanDef = getPackageScan();
609 if (packageScanDef != null && packageScanDef.getPackages().size() > 0) {
610 // use package scan filter
611 PatternBasedPackageScanFilter filter = new PatternBasedPackageScanFilter();
612 // support property placeholders in include and exclude
613 for (String include : packageScanDef.getIncludes()) {
614 include = getContext().resolvePropertyPlaceholders(include);
615 filter.addIncludePattern(include);
616 }
617 for (String exclude : packageScanDef.getExcludes()) {
618 exclude = getContext().resolvePropertyPlaceholders(exclude);
619 filter.addExcludePattern(exclude);
620 }
621
622 String[] normalized = normalizePackages(getContext(), packageScanDef.getPackages());
623 findRouteBuildersByPackageScan(normalized, filter, builders);
624 }
625
626 // context scan
627 ContextScanDefinition contextScanDef = getContextScan();
628 if (contextScanDef != null) {
629 // use package scan filter
630 PatternBasedPackageScanFilter filter = new PatternBasedPackageScanFilter();
631 // support property placeholders in include and exclude
632 for (String include : contextScanDef.getIncludes()) {
633 include = getContext().resolvePropertyPlaceholders(include);
634 filter.addIncludePattern(include);
635 }
636 for (String exclude : contextScanDef.getExcludes()) {
637 exclude = getContext().resolvePropertyPlaceholders(exclude);
638 filter.addExcludePattern(exclude);
639 }
640 findRouteBuildersByContextScan(filter, builders);
641 }
642 }
643
644 protected abstract void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception;
645
646 protected abstract void findRouteBuildersByContextScan(PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception;
647
648 private void addPackageElementContentsToScanDefinition() {
649 PackageScanDefinition packageScanDef = getPackageScan();
650
651 if (getPackages() != null && getPackages().length > 0) {
652 if (packageScanDef == null) {
653 packageScanDef = new PackageScanDefinition();
654 setPackageScan(packageScanDef);
655 }
656
657 for (String pkg : getPackages()) {
658 packageScanDef.getPackages().add(pkg);
659 }
660 }
661 }
662
663 private String[] normalizePackages(T context, List<String> unnormalized) throws Exception {
664 List<String> packages = new ArrayList<String>();
665 for (String name : unnormalized) {
666 // it may use property placeholders
667 name = context.resolvePropertyPlaceholders(name);
668 name = ObjectHelper.normalizeClassName(name);
669 if (ObjectHelper.isNotEmpty(name)) {
670 if (LOG.isTraceEnabled()) {
671 LOG.trace("Using package: " + name + " to scan for RouteBuilder classes");
672 }
673 packages.add(name);
674 }
675 }
676 return packages.toArray(new String[packages.size()]);
677 }
678
679 }