You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by gn...@apache.org on 2020/03/25 15:22:58 UTC

[camel] branch master updated (a8a13e2 -> c4f4d24)

This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from a8a13e2  Move the generated configurer into the o.a.c.main package
     new 7616492  Move Route.createErrorHandler to ExtendedCamelContext to get rid of the DefaultModelRoute class
     new cb507a0  Isolate org.apache.camel.reifier.* packages from model
     new 1449f6e  Move the clearModelReferences / clearReifiers logic into the ImmutableCamelContext and Main.lightweight property
     new 7afcecd  Add an init method to Expression / Predicate
     new f08ef3d  Fix simple builder predicate
     new 7d70ad8  Support for the splitter eip in lightweight mode
     new 7391593  Rename immutable -> lightweight to be more coherent and descriptive
     new 8a30982  Support lightweight mode in enrichers
     new bef4f8e  Add an init method to Expression / Predicate (fix)
     new be547c1  [CAMEL-14786] Move as much initialisation code from start() to init() phase
     new c4f4d24  [CAMEL-14786][CAMEL-14712] Lightweight context + init phase

The 11 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../apache/camel/language/bean/BeanExpression.java |   4 +
 .../camel/blueprint/BlueprintCamelContext.java     |   6 +-
 .../blueprint/handler/CamelNamespaceHandler.java   |   2 +-
 .../apache/camel/component/cron/CronComponent.java |   2 +-
 .../camel/component/mock/MockExpressionClause.java |  34 +-
 .../camel/component/mock/MockValueBuilder.java     |   6 +
 .../camel/component/xquery/XQueryBuilder.java      |   4 +
 .../spring/javaconfig/CamelConfiguration.java      |   2 +-
 .../main/java/org/apache/camel/spring/Main.java    |   9 +-
 .../camel/spring/CamelContextFactoryBean.java      |   2 +-
 .../apache/camel/spring/SpringCamelContext.java    |   2 +-
 .../spring/remoting/CamelServiceExporter.java      |   4 +-
 .../apache/camel/language/xpath/XPathBuilder.java  |   4 +
 .../org/apache/camel/CamelContextLifecycle.java    |   2 +
 .../src/main/java/org/apache/camel/Expression.java |   7 +
 .../org/apache/camel/ExtendedCamelContext.java     |  39 +--
 .../src/main/java/org/apache/camel/Predicate.java  |   6 +
 .../main/java/org/apache/camel/ServiceStatus.java  |  12 +-
 .../java/org/apache/camel/spi/EventFactory.java    |  16 +
 .../org/apache/camel/spi/LifecycleStrategy.java    |  10 +
 .../apache/camel/support/service/BaseService.java  |  41 ++-
 .../camel/support/service/ServiceHelper.java       |  14 +
 .../AbstractLocationPropertiesSource.java          |  10 -
 .../component/properties/PropertiesComponent.java  |  56 ++--
 .../impl/converter/BaseTypeConverterRegistry.java  |   2 +-
 .../impl/converter/CoreTypeConverterRegistry.java  |   3 -
 .../camel/impl/converter/DefaultTypeConverter.java |   9 +-
 .../TypeConvertersPackageScanClassResolver.java    |   9 -
 .../camel/impl/engine/AbstractCamelContext.java    | 328 ++++++++++----------
 .../impl/engine/BaseExecutorServiceManager.java    |   8 +-
 .../engine/DefaultAsyncProcessorAwaitManager.java  |   5 -
 .../impl/engine/DefaultBeanIntrospection.java      |   2 +-
 .../camel/impl/engine/DefaultConsumerCache.java    |  18 +-
 .../camel/impl/engine/DefaultConsumerTemplate.java |  12 +-
 .../impl/engine/DefaultFluentProducerTemplate.java |  41 +--
 .../impl/engine/DefaultInflightRepository.java     |   4 -
 .../impl/engine/DefaultManagementStrategy.java     |  48 ++-
 .../impl/engine/DefaultMessageHistoryFactory.java  |   9 -
 .../engine/DefaultPackageScanClassResolver.java    |   5 -
 .../engine/DefaultPackageScanResourceResolver.java |   2 +-
 .../camel/impl/engine/DefaultProducerCache.java    |  20 +-
 .../camel/impl/engine/DefaultProducerTemplate.java |  47 ++-
 .../camel/impl/engine/DefaultReactiveExecutor.java |   5 -
 .../org/apache/camel/impl/engine/DefaultRoute.java |   5 +-
 .../camel/impl/engine/DefaultRouteController.java  |  14 -
 .../engine/DefaultRuntimeEndpointRegistry.java     |   7 +-
 .../camel/impl/engine/SimpleCamelContext.java      |   8 +-
 .../impl/event/CamelContextInitializedEvent.java}  |  21 +-
 .../impl/event/CamelContextInitializingEvent.java} |  24 +-
 .../camel/impl/event/DefaultEventFactory.java      |  10 +
 .../java/org/apache/camel/processor/Enricher.java  |   2 +-
 .../apache/camel/processor/FilterProcessor.java    |  11 +-
 .../apache/camel/processor/MulticastProcessor.java |  31 +-
 .../org/apache/camel/processor/PollEnricher.java   |  43 ++-
 .../org/apache/camel/processor/RecipientList.java  |   2 +-
 .../camel/processor/RecipientListProcessor.java    |  12 +-
 .../camel/processor/RemovePropertiesProcessor.java |   9 -
 .../java/org/apache/camel/processor/Splitter.java  |  16 +-
 .../processor/interceptor/DefaultDebugger.java     |  10 +-
 .../loadbalancer/LoadBalancerSupport.java          |   5 +
 .../camel/builder/AdviceWithRouteBuilder.java      |   3 +-
 .../camel/builder/ErrorHandlerBuilderRef.java      |   3 +
 .../org/apache/camel/builder/ExpressionClause.java |  34 +-
 .../org/apache/camel/builder/NotifyBuilder.java    |   3 +-
 .../org/apache/camel/builder/RouteBuilder.java     |  30 --
 .../org/apache/camel/builder/SimpleBuilder.java    |  84 +++--
 .../apache/camel/builder/TransformerBuilder.java   |   4 +-
 .../org/apache/camel/builder/ValidatorBuilder.java |   4 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |  92 +++---
 ...elContext.java => LightweightCamelContext.java} | 104 +++++--
 ...xt.java => LightweightRuntimeCamelContext.java} |  42 ++-
 .../org/apache/camel/model/ExpressionNode.java     |  20 +-
 .../org/apache/camel/model/ModelCamelContext.java  |  15 +
 .../org/apache/camel/model/RouteDefinition.java    |   3 +-
 .../camel/model/language/ExpressionDefinition.java |  20 +-
 .../apache/camel/reifier/ExpressionReifier.java    |   2 +-
 .../org/apache/camel/reifier/FilterReifier.java    |   2 +-
 .../org/apache/camel/reifier/MulticastReifier.java |   2 +-
 .../apache/camel/reifier/PollEnrichReifier.java    |  15 +-
 .../org/apache/camel/reifier/RouteReifier.java     |   3 +-
 .../org/apache/camel/reifier/SplitReifier.java     |   2 +-
 .../reifier/errorhandler/ErrorHandlerReifier.java  |   3 +-
 .../camel/reifier/language/ExpressionReifier.java  |   2 +
 .../reifier/language/SimpleExpressionReifier.java  |  37 ++-
 .../core/xml/AbstractCamelContextFactoryBean.java  |   2 -
 .../java/org/apache/camel/ContextTestSupport.java  |  45 +--
 .../test/java/org/apache/camel/TestSupport.java    |  10 +-
 .../camel/builder/BuilderWithScopesTest.java       |   2 +-
 .../apache/camel/builder/NotifyBuilderTest.java    |   2 +-
 .../camel/impl/MultipleLifecycleStrategyTest.java  |   6 +-
 .../lw/EnricherLightweightTest.java}               |  41 ++-
 ...ontextTest.java => LightweightContextTest.java} |   4 +-
 .../camel/impl/lw/PollEnricherLightweightTest.java | 152 +++++++++
 .../camel/impl/lw/SplitterLightweightTest.java     | 319 +++++++++++++++++++
 .../issues/SentExchangeEventNotifierIssueTest.java |   1 -
 .../SentExchangeEventNotifierTwoIssueTest.java     |   1 -
 .../apache/camel/model/ChoiceDefinitionTest.java   |   2 +-
 .../EventNotifierExchangeSentExampleTest.java      |   1 -
 .../ProducerTemplateDisableEventNotifierTest.java  |   1 -
 ...litterUseOriginalNotPropagateExceptionTest.java |   1 -
 .../apache/camel/processor/TryProcessorTest.java   |   5 +
 .../apache/camel/processor/ValidateSimpleTest.java |   4 +-
 .../EnricherAsyncUnhandledExceptionTest.java       |   1 -
 .../processor/enricher/EnricherSendEventTest.java  |   1 -
 .../DynamicRouterEventNotifierTest.java            |   1 -
 .../RecipientListEventNotifierTest.java            |   1 -
 .../routingslip/RoutingSlipEventNotifierTest.java  |   1 -
 .../camel/main/ExtendedCamelContextConfigurer.java |   4 -
 .../MainConfigurationPropertiesConfigurer.java     |   6 +-
 .../camel-main-configuration-metadata.json         |   3 +-
 .../org/apache/camel/main/BaseMainSupport.java     |   2 +-
 .../camel/main/DefaultConfigurationConfigurer.java |   2 -
 .../camel/main/DefaultConfigurationProperties.java |  75 ++---
 .../src/main/java/org/apache/camel/main/Main.java  |   7 +-
 .../camel/management/DefaultManagementAgent.java   |  18 +-
 .../DefaultManagementObjectNameStrategy.java       |   2 +-
 .../management/JmxManagementLifecycleStrategy.java |  94 +++---
 .../camel/management/JmxManagementStrategy.java    |  23 +-
 .../management/JmxManagementStrategyFactory.java   |   4 +-
 ...ationOnlyRegisterProcessorWithCustomIdTest.java |   1 -
 .../ManagedCamelContextPropertiesTest.java         |   1 -
 .../camel/management/ManagedCamelContextTest.java  |   3 +-
 .../camel/management/ManagedDynamicRouterTest.java |   1 -
 .../ManagedEndpointUtilizationStatisticsTest.java  |   1 -
 .../camel/management/ManagedEnricherTest.java      |   1 -
 .../management/ManagedNamePatternFixedTest.java    |   1 -
 .../ManagedNamePatternIncludeHostNameTest.java     |   2 +-
 .../camel/management/ManagedNamePatternTest.java   |   1 -
 .../management/ManagedNonManagedServiceTest.java   |   2 +-
 .../camel/management/ManagedPollEnricherTest.java  |   1 -
 ...gedProducerRecipientListRegisterAlwaysTest.java |   1 -
 ...edProducerRouteAddRemoveRegisterAlwaysTest.java |   3 +-
 .../camel/management/ManagedRecipientListTest.java |   1 -
 .../management/ManagedRouteAddRemoveTest.java      |   2 +-
 .../camel/management/ManagedRoutingSlipTest.java   |   1 -
 .../camel/management/ManagedSanitizeTest.java      |   1 -
 .../ManagedSendDynamicProcessorTest.java           |   1 -
 .../camel/management/ManagedStartupFailedTest.java |   3 +-
 .../management/ManagedStatisticsLevelOffTest.java  |   1 -
 .../ManagedStatisticsLevelRoutesOnlyTest.java      |   1 -
 .../camel/management/ManagedWireTapTest.java       |   1 -
 .../apache/camel/support/ChildServiceSupport.java  |  25 +-
 .../java/org/apache/camel/support/EventHelper.java | 200 ++----------
 .../org/apache/camel/support/ExchangeHelper.java   |  36 ++-
 .../apache/camel/support/ExpressionSupport.java    |   5 +
 .../support/ExpressionToPredicateAdapter.java      |   5 +
 .../org/apache/camel/support/ScriptHelper.java     |  10 +
 .../support/builder/BinaryPredicateSupport.java    |   7 +
 .../camel/support/builder/ExpressionBuilder.java   | 342 +++++++++++++++++----
 .../apache/camel/support/builder/ValueBuilder.java |   6 +
 docs/components/modules/ROOT/pages/index.adoc      | 145 +++++++++
 151 files changed, 2144 insertions(+), 1142 deletions(-)
 rename core/{camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelRoute.java => camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializedEvent.java} (53%)
 copy core/{camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java => camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializingEvent.java} (63%)
 rename core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/{ImmutableCamelContext.java => LightweightCamelContext.java} (94%)
 rename core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/{RuntimeImmutableCamelContext.java => LightweightRuntimeCamelContext.java} (98%)
 copy core/camel-core/src/test/java/org/apache/camel/{processor/EventNotifierExchangeSentExampleTest.java => impl/lw/EnricherLightweightTest.java} (54%)
 rename core/camel-core/src/test/java/org/apache/camel/impl/lw/{ImmutableContextTest.java => LightweightContextTest.java} (96%)
 create mode 100644 core/camel-core/src/test/java/org/apache/camel/impl/lw/PollEnricherLightweightTest.java
 create mode 100644 core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java


[camel] 06/11: Support for the splitter eip in lightweight mode

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 7d70ad80c7dd81c872132e21e3f8dc581a10e74c
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 18 18:35:44 2020 +0100

    Support for the splitter eip in lightweight mode
---
 .../camel/impl/engine/SimpleCamelContext.java      |   2 +-
 .../apache/camel/processor/MulticastProcessor.java |  31 +-
 .../org/apache/camel/processor/RecipientList.java  |   2 +-
 .../camel/processor/RecipientListProcessor.java    |  12 +-
 .../java/org/apache/camel/processor/Splitter.java  |  16 +-
 .../impl/lw/RuntimeImmutableCamelContext.java      |   4 +-
 .../org/apache/camel/reifier/MulticastReifier.java |   2 +-
 .../org/apache/camel/reifier/SplitReifier.java     |   2 +-
 .../camel/reifier/language/ExpressionReifier.java  |   2 +
 .../test/java/org/apache/camel/TestSupport.java    |  10 +-
 .../apache/camel/builder/NotifyBuilderTest.java    |   2 +-
 .../camel/impl/lw/SplitterLightweightTest.java     | 320 +++++++++++++++++++++
 .../apache/camel/model/ChoiceDefinitionTest.java   |   2 +-
 13 files changed, 381 insertions(+), 26 deletions(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index 04f71cd..3f959c7 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -372,7 +372,7 @@ public class SimpleCamelContext extends AbstractCamelContext {
 
     @Override
     public AsyncProcessor createMulticast(Collection<Processor> processors, ExecutorService executor, boolean shutdownExecutorService) {
-        return new MulticastProcessor(getCamelContextReference(), processors, null, true, executor, shutdownExecutorService, false, false, 0, null, false, false);
+        return new MulticastProcessor(getCamelContextReference(), null, processors, null, true, executor, shutdownExecutorService, false, false, 0, null, false, false);
     }
 
     @Override
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/MulticastProcessor.java b/core/camel-base/src/main/java/org/apache/camel/processor/MulticastProcessor.java
index 3f8bf40..1a3c9de 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/MulticastProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/MulticastProcessor.java
@@ -57,12 +57,14 @@ import org.apache.camel.spi.RouteIdAware;
 import org.apache.camel.spi.UnitOfWork;
 import org.apache.camel.support.AsyncProcessorConverterHelper;
 import org.apache.camel.support.AsyncProcessorSupport;
+import org.apache.camel.support.DefaultExchange;
 import org.apache.camel.support.EventHelper;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.service.ServiceHelper;
 import org.apache.camel.util.CastUtils;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.KeyValueHolder;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StopWatch;
 import org.apache.camel.util.concurrent.AsyncCompletionService;
 import org.slf4j.Logger;
@@ -146,6 +148,7 @@ public class MulticastProcessor extends AsyncProcessorSupport implements Navigat
 
     protected final Processor onPrepare;
     private final CamelContext camelContext;
+    private final Route route;
     private final ReactiveExecutor reactiveExecutor;
     private String id;
     private String routeId;
@@ -164,27 +167,28 @@ public class MulticastProcessor extends AsyncProcessorSupport implements Navigat
     private final ConcurrentMap<ErrorHandlerKey, Processor> errorHandlers = new ConcurrentHashMap<>();
     private final boolean shareUnitOfWork;
 
-    public MulticastProcessor(CamelContext camelContext, Collection<Processor> processors) {
-        this(camelContext, processors, null);
+    public MulticastProcessor(CamelContext camelContext, Route route, Collection<Processor> processors) {
+        this(camelContext, route, processors, null);
     }
 
-    public MulticastProcessor(CamelContext camelContext, Collection<Processor> processors, AggregationStrategy aggregationStrategy) {
-        this(camelContext, processors, aggregationStrategy, false, null, false, false, false, 0, null, false, false);
+    public MulticastProcessor(CamelContext camelContext, Route route, Collection<Processor> processors, AggregationStrategy aggregationStrategy) {
+        this(camelContext, route, processors, aggregationStrategy, false, null, false, false, false, 0, null, false, false);
     }
 
-    public MulticastProcessor(CamelContext camelContext, Collection<Processor> processors, AggregationStrategy aggregationStrategy, boolean parallelProcessing,
+    public MulticastProcessor(CamelContext camelContext, Route route, Collection<Processor> processors, AggregationStrategy aggregationStrategy, boolean parallelProcessing,
                               ExecutorService executorService, boolean shutdownExecutorService, boolean streaming, boolean stopOnException, long timeout, Processor onPrepare,
                               boolean shareUnitOfWork, boolean parallelAggregate) {
-        this(camelContext, processors, aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException, timeout, onPrepare,
+        this(camelContext, route, processors, aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException, timeout, onPrepare,
              shareUnitOfWork, parallelAggregate, false);
     }
     
-    public MulticastProcessor(CamelContext camelContext, Collection<Processor> processors, AggregationStrategy aggregationStrategy,
+    public MulticastProcessor(CamelContext camelContext, Route route, Collection<Processor> processors, AggregationStrategy aggregationStrategy,
                               boolean parallelProcessing, ExecutorService executorService, boolean shutdownExecutorService, boolean streaming,
                               boolean stopOnException, long timeout, Processor onPrepare, boolean shareUnitOfWork,
                               boolean parallelAggregate, boolean stopOnAggregateException) {
         notNull(camelContext, "camelContext");
         this.camelContext = camelContext;
+        this.route = route;
         this.reactiveExecutor = camelContext.adapt(ExtendedCamelContext.class).getReactiveExecutor();
         this.processors = processors;
         this.aggregationStrategy = aggregationStrategy;
@@ -236,6 +240,16 @@ public class MulticastProcessor extends AsyncProcessorSupport implements Navigat
     }
 
     @Override
+    protected void doInit() throws Exception {
+        if (route != null) {
+            Exchange exchange = new DefaultExchange(getCamelContext());
+            for (Processor processor : getProcessors()) {
+                createErrorHandler(route, exchange, processor);
+            }
+        }
+    }
+
+    @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
         Iterable<ProcessorExchangePair> pairs;
         try {
@@ -710,6 +724,9 @@ public class MulticastProcessor extends AsyncProcessorSupport implements Navigat
     protected Processor createErrorHandler(Route route, Exchange exchange, Processor processor) {
         Processor answer;
 
+        if (route != this.route && this.route != null) {
+            throw new UnsupportedOperationException("Is this really correct ?");
+        }
         boolean tryBlock = exchange.getProperty(Exchange.TRY_ROUTE_BLOCK, false, boolean.class);
 
         // do not wrap in error handler if we are inside a try block
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/RecipientList.java b/core/camel-base/src/main/java/org/apache/camel/processor/RecipientList.java
index 43d58c6..2f3802c 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/RecipientList.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/RecipientList.java
@@ -186,7 +186,7 @@ public class RecipientList extends AsyncProcessorSupport implements IdAware, Rou
             iter = ObjectHelper.createIterator(recipientList, delimiter);
         }
 
-        RecipientListProcessor rlp = new RecipientListProcessor(exchange.getContext(), producerCache, iter, getAggregationStrategy(),
+        RecipientListProcessor rlp = new RecipientListProcessor(exchange.getContext(), null, producerCache, iter, getAggregationStrategy(),
                 isParallelProcessing(), getExecutorService(), isShutdownExecutorService(),
                 isStreaming(), isStopOnException(), getTimeout(), getOnPrepare(), isShareUnitOfWork(), isParallelAggregate(),
                 isStopOnAggregateException());
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/RecipientListProcessor.java b/core/camel-base/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
index c78f13d..8114541 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/RecipientListProcessor.java
@@ -153,22 +153,22 @@ public class RecipientListProcessor extends MulticastProcessor {
 
     // TODO: camel-bean @RecipientList cacheSize
 
-    public RecipientListProcessor(CamelContext camelContext, ProducerCache producerCache, Iterator<?> iter) {
-        super(camelContext, null);
+    public RecipientListProcessor(CamelContext camelContext, Route route, ProducerCache producerCache, Iterator<?> iter) {
+        super(camelContext, route, null);
         this.producerCache = producerCache;
         this.iter = iter;
     }
 
-    public RecipientListProcessor(CamelContext camelContext, ProducerCache producerCache, Iterator<?> iter, AggregationStrategy aggregationStrategy) {
-        super(camelContext, null, aggregationStrategy);
+    public RecipientListProcessor(CamelContext camelContext, Route route, ProducerCache producerCache, Iterator<?> iter, AggregationStrategy aggregationStrategy) {
+        super(camelContext, route, null, aggregationStrategy);
         this.producerCache = producerCache;
         this.iter = iter;
     }
 
-    public RecipientListProcessor(CamelContext camelContext, ProducerCache producerCache, Iterator<?> iter, AggregationStrategy aggregationStrategy,
+    public RecipientListProcessor(CamelContext camelContext, Route route, ProducerCache producerCache, Iterator<?> iter, AggregationStrategy aggregationStrategy,
                                   boolean parallelProcessing, ExecutorService executorService, boolean shutdownExecutorService, boolean streaming, boolean stopOnException,
                                   long timeout, Processor onPrepare, boolean shareUnitOfWork, boolean parallelAggregate, boolean stopOnAggregateException) {
-        super(camelContext, null, aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException, timeout, onPrepare,
+        super(camelContext, route, null, aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException, timeout, onPrepare,
               shareUnitOfWork, parallelAggregate, stopOnAggregateException);
         this.producerCache = producerCache;
         this.iter = iter;
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/Splitter.java b/core/camel-base/src/main/java/org/apache/camel/processor/Splitter.java
index f3463db..3618c71 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/Splitter.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/Splitter.java
@@ -55,17 +55,17 @@ public class Splitter extends MulticastProcessor implements AsyncProcessor, Trac
 
     private final Expression expression;
 
-    public Splitter(CamelContext camelContext, Expression expression, Processor destination, AggregationStrategy aggregationStrategy, boolean parallelProcessing,
+    public Splitter(CamelContext camelContext, Route route, Expression expression, Processor destination, AggregationStrategy aggregationStrategy, boolean parallelProcessing,
                     ExecutorService executorService, boolean shutdownExecutorService, boolean streaming, boolean stopOnException, long timeout, Processor onPrepare,
                     boolean useSubUnitOfWork, boolean parallelAggregate) {
-        this(camelContext, expression, destination, aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException, timeout,
-             onPrepare, useSubUnitOfWork, false, false);
+        this(camelContext, route, expression, destination, aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException, timeout,
+             onPrepare, useSubUnitOfWork, parallelAggregate, false);
     }
 
-    public Splitter(CamelContext camelContext, Expression expression, Processor destination, AggregationStrategy aggregationStrategy, boolean parallelProcessing,
+    public Splitter(CamelContext camelContext, Route route, Expression expression, Processor destination, AggregationStrategy aggregationStrategy, boolean parallelProcessing,
                     ExecutorService executorService, boolean shutdownExecutorService, boolean streaming, boolean stopOnException, long timeout, Processor onPrepare,
                     boolean useSubUnitOfWork, boolean parallelAggregate, boolean stopOnAggregateException) {
-        super(camelContext, Collections.singleton(destination), aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException,
+        super(camelContext, route, Collections.singleton(destination), aggregationStrategy, parallelProcessing, executorService, shutdownExecutorService, streaming, stopOnException,
               timeout, onPrepare, useSubUnitOfWork, parallelAggregate, stopOnAggregateException);
         this.expression = expression;
         notNull(expression, "expression");
@@ -78,6 +78,12 @@ public class Splitter extends MulticastProcessor implements AsyncProcessor, Trac
     }
 
     @Override
+    protected void doInit() throws Exception {
+        super.doInit();
+        expression.init(getCamelContext());
+    }
+
+    @Override
     public boolean process(Exchange exchange, final AsyncCallback callback) {
         AggregationStrategy strategy = getAggregationStrategy();
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
index e7ed47d..3de7132 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
@@ -176,6 +176,7 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
     private final List<Route> routes;
     private final boolean messageHistory;
     private final boolean allowUseOriginalMessage;
+    private final boolean logExhaustedMessageBody;
     private final String version;
     private Date startDate;
 
@@ -218,6 +219,7 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
         useMDCLogging = context.isUseMDCLogging();
         messageHistory = context.isMessageHistory();
         allowUseOriginalMessage = context.isAllowUseOriginalMessage();
+        logExhaustedMessageBody = context.isLogExhaustedMessageBody();
         version = context.getVersion();
     }
 
@@ -350,7 +352,7 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
 
     @Override
     public Boolean isLogExhaustedMessageBody() {
-        throw new UnsupportedOperationException();
+        return logExhaustedMessageBody;
     }
 
     @Override
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/MulticastReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/MulticastReifier.java
index 50b0d23..8d7a4d0 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/MulticastReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/MulticastReifier.java
@@ -73,7 +73,7 @@ public class MulticastReifier extends ProcessorReifier<MulticastDefinition> {
             definition.setOnPrepare(mandatoryLookup(definition.getOnPrepareRef(), Processor.class));
         }
 
-        MulticastProcessor answer = new MulticastProcessor(camelContext, list, strategy, isParallelProcessing, threadPool, shutdownThreadPool, isStreaming,
+        MulticastProcessor answer = new MulticastProcessor(camelContext, route, list, strategy, isParallelProcessing, threadPool, shutdownThreadPool, isStreaming,
                                                            isStopOnException, timeout, definition.getOnPrepare(), isShareUnitOfWork, isParallelAggregate,
                                                            isStopOnAggregateException);
         return answer;
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/SplitReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/SplitReifier.java
index a34a2e8..2191831 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/SplitReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/SplitReifier.java
@@ -59,7 +59,7 @@ public class SplitReifier extends ExpressionReifier<SplitDefinition> {
 
         Expression exp = createExpression(definition.getExpression());
 
-        Splitter answer = new Splitter(camelContext, exp, childProcessor, definition.getAggregationStrategy(), isParallelProcessing, threadPool,
+        Splitter answer = new Splitter(camelContext, route, exp, childProcessor, definition.getAggregationStrategy(), isParallelProcessing, threadPool,
                                        shutdownThreadPool, isStreaming, isStopOnException, timeout, definition.getOnPrepare(), isShareUnitOfWork, isParallelAggregate,
                                        isStopOnAggregateException);
         return answer;
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
index 8831b6e..e0d420b 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/ExpressionReifier.java
@@ -136,6 +136,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
         if (expression instanceof CamelContextAware) {
             ((CamelContextAware) expression).setCamelContext(camelContext);
         }
+        expression.init(camelContext);
         return expression;
     }
 
@@ -171,6 +172,7 @@ public class ExpressionReifier<T extends ExpressionDefinition> extends AbstractR
         if (predicate instanceof CamelContextAware) {
             ((CamelContextAware) predicate).setCamelContext(camelContext);
         }
+        predicate.init(camelContext);
         return predicate;
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/TestSupport.java b/core/camel-core/src/test/java/org/apache/camel/TestSupport.java
index f1eab1c..19a1bf0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/TestSupport.java
+++ b/core/camel-core/src/test/java/org/apache/camel/TestSupport.java
@@ -100,7 +100,7 @@ public abstract class TestSupport extends Assert {
      * Returns a predicate and value builder for the inbound body on an exchange
      */
     public static ValueBuilder body() {
-        return Builder.body();
+        return init(Builder.body());
     }
 
     /**
@@ -570,4 +570,12 @@ public abstract class TestSupport extends Assert {
             }
         }
     }
+
+    private static ValueBuilder init(ValueBuilder builder) {
+        Expression exp = builder.getExpression();
+        if (exp != null) {
+            exp.init(new DefaultCamelContext());
+        }
+        return builder;
+    }
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/builder/NotifyBuilderTest.java b/core/camel-core/src/test/java/org/apache/camel/builder/NotifyBuilderTest.java
index 858e6b4..0922883 100644
--- a/core/camel-core/src/test/java/org/apache/camel/builder/NotifyBuilderTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/builder/NotifyBuilderTest.java
@@ -355,7 +355,7 @@ public class NotifyBuilderTest extends ContextTestSupport {
     public void testFilterWhenExchangeDone() throws Exception {
         NotifyBuilder notify = new NotifyBuilder(context).filter(body().contains("World")).whenDone(3).create();
 
-        assertEquals("filter(simple{${body}} contains World).whenDone(3)", notify.toString());
+        assertEquals("filter(${body} contains World).whenDone(3)", notify.toString());
 
         assertEquals(false, notify.matches());
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java
new file mode 100644
index 0000000..d458707
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java
@@ -0,0 +1,320 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.lw;
+
+import java.io.File;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.MyAggregationStrategy;
+import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class SplitterLightweightTest extends ContextTestSupport {
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        setUseImmutableContext(true);
+        super.setUp();
+    }
+
+    @Test
+    public void testSendingAMessageUsingMulticastReceivesItsOwnExchange() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedBodiesReceived("James", "Guillaume", "Hiram", "Rob");
+
+        // InOnly
+        template.send("direct:seqential", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+
+        Set<String> ids = new HashSet<>();
+        Set<String> ids2 = new HashSet<>();
+
+        List<Exchange> list = resultEndpoint.getReceivedExchanges();
+        for (int i = 0; i < 4; i++) {
+            Exchange exchange = list.get(i);
+            Message in = exchange.getIn();
+            ids.add(in.getMessageId());
+            ids2.add(exchange.getExchangeId());
+            assertNotNull("The in message should not be null.", in);
+            assertProperty(exchange, Exchange.SPLIT_INDEX, i);
+            assertProperty(exchange, Exchange.SPLIT_SIZE, 4);
+        }
+
+        assertEquals("The sub messages should have unique message ids", 4, ids.size());
+        assertEquals("The sub messages should have unique exchange ids", 4, ids2.size());
+    }
+
+    @Test
+    public void testSplitterWithAggregationStrategy() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedBodiesReceived("James", "Guillaume", "Hiram", "Rob", "Roman");
+
+        Exchange result = template.request("direct:seqential", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob,Roman");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        Message out = result.getMessage();
+        assertEquals("Roman", out.getBody());
+        assertMessageHeader(out, "foo", "bar");
+        assertProperty(result, Exchange.SPLIT_INDEX, 4);
+    }
+
+    @Test
+    public void testEmptyBody() {
+        Exchange result = template.request("direct:seqential", new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader("foo", "bar");
+            }
+        });
+
+        assertFalse("Should not have out", result.hasOut());
+    }
+
+    @Test
+    public void testSendingAMessageUsingMulticastReceivesItsOwnExchangeParallel() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+
+        resultEndpoint.expectsNoDuplicates(body());
+        resultEndpoint.expectedMessageCount(4);
+
+        // InOnly
+        template.send("direct:parallel", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+
+        List<Exchange> list = resultEndpoint.getReceivedExchanges();
+        Set<Integer> numbersFound = new TreeSet<>();
+        final String[] names = {"James", "Guillaume", "Hiram", "Rob"};
+
+        for (int i = 0; i < 4; i++) {
+            Exchange exchange = list.get(i);
+            Message in = exchange.getIn();
+            Integer splitCounter = exchange.getProperty(Exchange.SPLIT_INDEX, Integer.class);
+            numbersFound.add(splitCounter);
+            assertEquals(names[splitCounter], in.getBody());
+            assertProperty(exchange, Exchange.SPLIT_SIZE, 4);
+        }
+
+        assertEquals(4, numbersFound.size());
+    }
+
+    @Test
+    public void testSplitterWithAggregationStrategyParallel() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(5);
+
+        Exchange result = template.request("direct:parallel", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob,Roman");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        Message out = result.getMessage();
+
+        assertMessageHeader(out, "foo", "bar");
+        assertEquals((Integer)5, result.getProperty("aggregated", Integer.class));
+    }
+
+    @Test
+    public void testSplitterWithAggregationStrategyParallelStreaming() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(5);
+        resultEndpoint.expectedBodiesReceivedInAnyOrder("James", "Guillaume", "Hiram", "Rob", "Roman");
+
+        Exchange result = template.request("direct:parallel-streaming", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob,Roman");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        Message out = result.getMessage();
+
+        assertMessageHeader(out, "foo", "bar");
+        assertEquals((Integer)5, result.getProperty("aggregated", Integer.class));
+    }
+
+    @Test
+    public void testSplitterParallelAggregate() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(5);
+        resultEndpoint.expectedBodiesReceivedInAnyOrder("James", "Guillaume", "Hiram", "Rob", "Roman");
+
+        Exchange result = template.request("direct:parallelAggregate", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob,Roman");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+        Message out = result.getMessage();
+
+        assertMessageHeader(out, "foo", "bar");
+        // we aggregate parallel and therefore its not thread-safe when setting
+        // values
+    }
+
+    @Test
+    public void testSplitterWithStreamingAndFileBody() throws Exception {
+        URL url = this.getClass().getResource("/org/apache/camel/processor/simple.txt");
+        assertNotNull("We should find this simple file here.", url);
+        File file = new File(url.getFile());
+        sendToSplitterWithStreaming(file);
+    }
+
+    @Test
+    public void testSplitterWithStreamingAndStringBody() throws Exception {
+        sendToSplitterWithStreaming("James,Guillaume,Hiram,Rob,Roman");
+    }
+
+    public void sendToSplitterWithStreaming(final Object body) throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(5);
+        resultEndpoint.expectedHeaderReceived("foo", "bar");
+
+        template.request("direct:streaming", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody(body);
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertMockEndpointsSatisfied();
+
+        // check properties with split details is correct
+        int size = resultEndpoint.getReceivedExchanges().size();
+        for (int i = 0; i < size; i++) {
+            Exchange exchange = resultEndpoint.getReceivedExchanges().get(i);
+            assertEquals(i, exchange.getProperty(Exchange.SPLIT_INDEX));
+            if (i < (size - 1)) {
+                assertEquals(Boolean.FALSE, exchange.getProperty(Exchange.SPLIT_COMPLETE));
+                // this header cannot be set when streaming is used, except for
+                // the last exchange
+                assertNull(exchange.getProperty(Exchange.SPLIT_SIZE));
+            } else {
+                assertEquals(Boolean.TRUE, exchange.getProperty(Exchange.SPLIT_COMPLETE));
+                // when we are complete the size is set
+                assertEquals(size, exchange.getProperty(Exchange.SPLIT_SIZE));
+            }
+        }
+    }
+
+    @Test
+    public void testSplitterWithException() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(4);
+        resultEndpoint.expectedHeaderReceived("foo", "bar");
+
+        MockEndpoint failedEndpoint = getMockEndpoint("mock:failed");
+        failedEndpoint.expectedMessageCount(1);
+        failedEndpoint.expectedHeaderReceived("foo", "bar");
+
+        Exchange result = template.request("direct:exception", new Processor() {
+            public void process(Exchange exchange) {
+                Message in = exchange.getIn();
+                in.setBody("James,Guillaume,Hiram,Rob,Exception");
+                in.setHeader("foo", "bar");
+            }
+        });
+
+        assertTrue("The result exchange should have a camel exception", result.getException() instanceof CamelException);
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Test
+    public void testSplitterWithIterable() throws Exception {
+        MockEndpoint resultEndpoint = getMockEndpoint("mock:result");
+        resultEndpoint.expectedMessageCount(4);
+        resultEndpoint.expectedBodiesReceived("A", "B", "C", "D");
+        final List<String> data = Arrays.asList("A", "B", "C", "D");
+        Iterable<String> itb = new Iterable<String>() {
+            public Iterator<String> iterator() {
+                return data.iterator();
+            }
+        };
+        sendBody("direct:simple", itb);
+        resultEndpoint.assertIsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                onException(CamelException.class).to("mock:failed");
+
+                from("direct:seqential").split(body().tokenize(","), new UseLatestAggregationStrategy()).to("mock:result");
+                from("direct:parallel").split(body().tokenize(","), new MyAggregationStrategy()).parallelProcessing().to("mock:result");
+                from("direct:parallelAggregate").split(body().tokenize(","), new MyAggregationStrategy()).parallelProcessing().parallelAggregate().to("mock:result");
+                from("direct:streaming").split(body().tokenize(",")).streaming().to("mock:result");
+                from("direct:parallel-streaming").split(body().tokenize(","), new MyAggregationStrategy()).parallelProcessing().streaming().to("mock:result");
+                from("direct:exception").split(body().tokenize(",")).aggregationStrategy(new MyAggregationStrategy()).parallelProcessing().process(new Processor() {
+                    public void process(Exchange exchange) throws Exception {
+                        String string = exchange.getIn().getBody(String.class);
+                        if ("Exception".equals(string)) {
+                            throw new CamelException("Just want to throw exception here");
+                        }
+
+                    }
+                }).to("mock:result");
+                from("direct:simple").split(body()).to("mock:result");
+            }
+        };
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/model/ChoiceDefinitionTest.java b/core/camel-core/src/test/java/org/apache/camel/model/ChoiceDefinitionTest.java
index 8df50e4..c5d738b 100644
--- a/core/camel-core/src/test/java/org/apache/camel/model/ChoiceDefinitionTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/model/ChoiceDefinitionTest.java
@@ -39,7 +39,7 @@ public class ChoiceDefinitionTest extends TestSupport {
         assertEquals(when1, choice.getOutputs().get(0));
         assertEquals(when2, choice.getOutputs().get(1));
         assertEquals(other, choice.getOutputs().get(2));
-        assertEquals("choice[when[{simple{${body}} contains Camel}],when[{simple{${body}} contains Donkey}],otherwise[]]", choice.getLabel());
+        assertEquals("choice[when[{${body} contains Camel}],when[{${body} contains Donkey}],otherwise[]]", choice.getLabel());
     }
 
     @Test


[camel] 09/11: Add an init method to Expression / Predicate (fix)

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit bef4f8e8c071c2776d3e17ce0ba9e377a82c34ba
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Thu Mar 19 17:13:57 2020 +0100

    Add an init method to Expression / Predicate (fix)
---
 .../main/java/org/apache/camel/component/xquery/XQueryBuilder.java    | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
index f4420d2..31733d1 100644
--- a/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
+++ b/components/camel-saxon/src/main/java/org/apache/camel/component/xquery/XQueryBuilder.java
@@ -133,6 +133,10 @@ public abstract class XQueryBuilder implements Expression, Predicate, NamespaceA
     }
 
     @Override
+    public void init(CamelContext context) {
+    }
+
+    @Override
     public <T> T evaluate(Exchange exchange, Class<T> type) {
         Object result = evaluate(exchange);
         return exchange.getContext().getTypeConverter().convertTo(type, result);


[camel] 11/11: [CAMEL-14786][CAMEL-14712] Lightweight context + init phase

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c4f4d2425f659f2a37b40f2e00a775ba1336b4d1
Merge: a8a13e2 be547c1
Author: gnodet <gn...@gmail.com>
AuthorDate: Wed Mar 25 16:22:27 2020 +0100

    [CAMEL-14786][CAMEL-14712] Lightweight context + init phase

 .../apache/camel/language/bean/BeanExpression.java |   4 +
 .../camel/blueprint/BlueprintCamelContext.java     |   6 +-
 .../blueprint/handler/CamelNamespaceHandler.java   |   2 +-
 .../apache/camel/component/cron/CronComponent.java |   2 +-
 .../camel/component/mock/MockExpressionClause.java |  34 +-
 .../camel/component/mock/MockValueBuilder.java     |   6 +
 .../camel/component/xquery/XQueryBuilder.java      |   4 +
 .../spring/javaconfig/CamelConfiguration.java      |   2 +-
 .../main/java/org/apache/camel/spring/Main.java    |   9 +-
 .../camel/spring/CamelContextFactoryBean.java      |   2 +-
 .../apache/camel/spring/SpringCamelContext.java    |   2 +-
 .../spring/remoting/CamelServiceExporter.java      |   4 +-
 .../apache/camel/language/xpath/XPathBuilder.java  |   4 +
 .../org/apache/camel/CamelContextLifecycle.java    |   2 +
 .../src/main/java/org/apache/camel/Expression.java |   7 +
 .../org/apache/camel/ExtendedCamelContext.java     |  39 +--
 .../src/main/java/org/apache/camel/Predicate.java  |   6 +
 .../main/java/org/apache/camel/ServiceStatus.java  |  12 +-
 .../java/org/apache/camel/spi/EventFactory.java    |  16 +
 .../org/apache/camel/spi/LifecycleStrategy.java    |  10 +
 .../apache/camel/support/service/BaseService.java  |  41 ++-
 .../camel/support/service/ServiceHelper.java       |  14 +
 .../AbstractLocationPropertiesSource.java          |  10 -
 .../component/properties/PropertiesComponent.java  |  56 ++--
 .../impl/converter/BaseTypeConverterRegistry.java  |   2 +-
 .../impl/converter/CoreTypeConverterRegistry.java  |   3 -
 .../camel/impl/converter/DefaultTypeConverter.java |   9 +-
 .../TypeConvertersPackageScanClassResolver.java    |   9 -
 .../camel/impl/engine/AbstractCamelContext.java    | 328 ++++++++++----------
 .../impl/engine/BaseExecutorServiceManager.java    |   8 +-
 .../engine/DefaultAsyncProcessorAwaitManager.java  |   5 -
 .../impl/engine/DefaultBeanIntrospection.java      |   2 +-
 .../camel/impl/engine/DefaultConsumerCache.java    |  18 +-
 .../camel/impl/engine/DefaultConsumerTemplate.java |  12 +-
 .../impl/engine/DefaultFluentProducerTemplate.java |  41 +--
 .../impl/engine/DefaultInflightRepository.java     |   4 -
 .../impl/engine/DefaultManagementStrategy.java     |  48 ++-
 .../impl/engine/DefaultMessageHistoryFactory.java  |   9 -
 .../engine/DefaultPackageScanClassResolver.java    |   5 -
 .../engine/DefaultPackageScanResourceResolver.java |   2 +-
 .../camel/impl/engine/DefaultProducerCache.java    |  20 +-
 .../camel/impl/engine/DefaultProducerTemplate.java |  47 ++-
 .../camel/impl/engine/DefaultReactiveExecutor.java |   5 -
 .../org/apache/camel/impl/engine/DefaultRoute.java |   5 +-
 .../camel/impl/engine/DefaultRouteController.java  |  14 -
 .../engine/DefaultRuntimeEndpointRegistry.java     |   7 +-
 .../camel/impl/engine/SimpleCamelContext.java      |   8 +-
 .../impl/event/CamelContextInitializedEvent.java}  |  21 +-
 .../impl/event/CamelContextInitializingEvent.java} |  24 +-
 .../camel/impl/event/DefaultEventFactory.java      |  10 +
 .../java/org/apache/camel/processor/Enricher.java  |   2 +-
 .../apache/camel/processor/FilterProcessor.java    |  11 +-
 .../apache/camel/processor/MulticastProcessor.java |  31 +-
 .../org/apache/camel/processor/PollEnricher.java   |  43 ++-
 .../org/apache/camel/processor/RecipientList.java  |   2 +-
 .../camel/processor/RecipientListProcessor.java    |  12 +-
 .../camel/processor/RemovePropertiesProcessor.java |   9 -
 .../java/org/apache/camel/processor/Splitter.java  |  16 +-
 .../processor/interceptor/DefaultDebugger.java     |  10 +-
 .../loadbalancer/LoadBalancerSupport.java          |   5 +
 .../camel/builder/AdviceWithRouteBuilder.java      |   3 +-
 .../camel/builder/ErrorHandlerBuilderRef.java      |   3 +
 .../org/apache/camel/builder/ExpressionClause.java |  34 +-
 .../org/apache/camel/builder/NotifyBuilder.java    |   3 +-
 .../org/apache/camel/builder/RouteBuilder.java     |  30 --
 .../org/apache/camel/builder/SimpleBuilder.java    |  84 +++--
 .../apache/camel/builder/TransformerBuilder.java   |   4 +-
 .../org/apache/camel/builder/ValidatorBuilder.java |   4 +-
 .../org/apache/camel/impl/DefaultCamelContext.java |  92 +++---
 ...elContext.java => LightweightCamelContext.java} | 104 +++++--
 ...xt.java => LightweightRuntimeCamelContext.java} |  42 ++-
 .../org/apache/camel/model/ExpressionNode.java     |  20 +-
 .../org/apache/camel/model/ModelCamelContext.java  |  15 +
 .../org/apache/camel/model/RouteDefinition.java    |   3 +-
 .../camel/model/language/ExpressionDefinition.java |  20 +-
 .../apache/camel/reifier/ExpressionReifier.java    |   2 +-
 .../org/apache/camel/reifier/FilterReifier.java    |   2 +-
 .../org/apache/camel/reifier/MulticastReifier.java |   2 +-
 .../apache/camel/reifier/PollEnrichReifier.java    |  15 +-
 .../org/apache/camel/reifier/RouteReifier.java     |   3 +-
 .../org/apache/camel/reifier/SplitReifier.java     |   2 +-
 .../reifier/errorhandler/ErrorHandlerReifier.java  |   3 +-
 .../camel/reifier/language/ExpressionReifier.java  |   2 +
 .../reifier/language/SimpleExpressionReifier.java  |  37 ++-
 .../core/xml/AbstractCamelContextFactoryBean.java  |   2 -
 .../java/org/apache/camel/ContextTestSupport.java  |  45 +--
 .../test/java/org/apache/camel/TestSupport.java    |  10 +-
 .../camel/builder/BuilderWithScopesTest.java       |   2 +-
 .../apache/camel/builder/NotifyBuilderTest.java    |   2 +-
 .../camel/impl/MultipleLifecycleStrategyTest.java  |   6 +-
 .../lw/EnricherLightweightTest.java}               |  41 ++-
 ...ontextTest.java => LightweightContextTest.java} |   4 +-
 .../camel/impl/lw/PollEnricherLightweightTest.java | 152 +++++++++
 .../camel/impl/lw/SplitterLightweightTest.java     | 319 +++++++++++++++++++
 .../issues/SentExchangeEventNotifierIssueTest.java |   1 -
 .../SentExchangeEventNotifierTwoIssueTest.java     |   1 -
 .../apache/camel/model/ChoiceDefinitionTest.java   |   2 +-
 .../EventNotifierExchangeSentExampleTest.java      |   1 -
 .../ProducerTemplateDisableEventNotifierTest.java  |   1 -
 ...litterUseOriginalNotPropagateExceptionTest.java |   1 -
 .../apache/camel/processor/TryProcessorTest.java   |   5 +
 .../apache/camel/processor/ValidateSimpleTest.java |   4 +-
 .../EnricherAsyncUnhandledExceptionTest.java       |   1 -
 .../processor/enricher/EnricherSendEventTest.java  |   1 -
 .../DynamicRouterEventNotifierTest.java            |   1 -
 .../RecipientListEventNotifierTest.java            |   1 -
 .../routingslip/RoutingSlipEventNotifierTest.java  |   1 -
 .../camel/main/ExtendedCamelContextConfigurer.java |   4 -
 .../MainConfigurationPropertiesConfigurer.java     |   6 +-
 .../camel-main-configuration-metadata.json         |   3 +-
 .../org/apache/camel/main/BaseMainSupport.java     |   2 +-
 .../camel/main/DefaultConfigurationConfigurer.java |   2 -
 .../camel/main/DefaultConfigurationProperties.java |  75 ++---
 .../src/main/java/org/apache/camel/main/Main.java  |   7 +-
 .../camel/management/DefaultManagementAgent.java   |  18 +-
 .../DefaultManagementObjectNameStrategy.java       |   2 +-
 .../management/JmxManagementLifecycleStrategy.java |  94 +++---
 .../camel/management/JmxManagementStrategy.java    |  23 +-
 .../management/JmxManagementStrategyFactory.java   |   4 +-
 ...ationOnlyRegisterProcessorWithCustomIdTest.java |   1 -
 .../ManagedCamelContextPropertiesTest.java         |   1 -
 .../camel/management/ManagedCamelContextTest.java  |   3 +-
 .../camel/management/ManagedDynamicRouterTest.java |   1 -
 .../ManagedEndpointUtilizationStatisticsTest.java  |   1 -
 .../camel/management/ManagedEnricherTest.java      |   1 -
 .../management/ManagedNamePatternFixedTest.java    |   1 -
 .../ManagedNamePatternIncludeHostNameTest.java     |   2 +-
 .../camel/management/ManagedNamePatternTest.java   |   1 -
 .../management/ManagedNonManagedServiceTest.java   |   2 +-
 .../camel/management/ManagedPollEnricherTest.java  |   1 -
 ...gedProducerRecipientListRegisterAlwaysTest.java |   1 -
 ...edProducerRouteAddRemoveRegisterAlwaysTest.java |   3 +-
 .../camel/management/ManagedRecipientListTest.java |   1 -
 .../management/ManagedRouteAddRemoveTest.java      |   2 +-
 .../camel/management/ManagedRoutingSlipTest.java   |   1 -
 .../camel/management/ManagedSanitizeTest.java      |   1 -
 .../ManagedSendDynamicProcessorTest.java           |   1 -
 .../camel/management/ManagedStartupFailedTest.java |   3 +-
 .../management/ManagedStatisticsLevelOffTest.java  |   1 -
 .../ManagedStatisticsLevelRoutesOnlyTest.java      |   1 -
 .../camel/management/ManagedWireTapTest.java       |   1 -
 .../apache/camel/support/ChildServiceSupport.java  |  25 +-
 .../java/org/apache/camel/support/EventHelper.java | 200 ++----------
 .../org/apache/camel/support/ExchangeHelper.java   |  36 ++-
 .../apache/camel/support/ExpressionSupport.java    |   5 +
 .../support/ExpressionToPredicateAdapter.java      |   5 +
 .../org/apache/camel/support/ScriptHelper.java     |  10 +
 .../support/builder/BinaryPredicateSupport.java    |   7 +
 .../camel/support/builder/ExpressionBuilder.java   | 342 +++++++++++++++++----
 .../apache/camel/support/builder/ValueBuilder.java |   6 +
 docs/components/modules/ROOT/pages/index.adoc      | 145 +++++++++
 151 files changed, 2144 insertions(+), 1142 deletions(-)



[camel] 05/11: Fix simple builder predicate

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit f08ef3d121b31fea7af83bd7b3a8ed92cd76f24c
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 18 16:00:52 2020 +0100

    Fix simple builder predicate
---
 .../src/main/java/org/apache/camel/builder/SimpleBuilder.java     | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
index d252920..1d36ff8 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
@@ -104,15 +104,13 @@ public class SimpleBuilder implements Predicate, Expression, ExpressionResultTyp
 
     @Override
     public void init(CamelContext context) {
-        if (predicate == null) {
-            predicate = createPredicate(context);
-        }
-        predicate.init(context);
     }
 
     @Override
     public boolean matches(Exchange exchange) {
-        init(exchange.getContext());
+        if (predicate == null) {
+            predicate = createPredicate(exchange.getContext());
+        }
         return predicate.matches(exchange);
     }
 


[camel] 10/11: [CAMEL-14786] Move as much initialisation code from start() to init() phase

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit be547c1d177aaec8c8520ac1970ef9b055b1deb7
Author: gnodet <gn...@gmail.com>
AuthorDate: Mon Mar 23 16:56:58 2020 +0100

    [CAMEL-14786] Move as much initialisation code from start() to init() phase
---
 .../camel/blueprint/BlueprintCamelContext.java     |   6 +-
 .../blueprint/handler/CamelNamespaceHandler.java   |   2 +-
 .../apache/camel/component/cron/CronComponent.java |   2 +-
 .../spring/javaconfig/CamelConfiguration.java      |   2 +-
 .../main/java/org/apache/camel/spring/Main.java    |   9 +-
 .../camel/spring/CamelContextFactoryBean.java      |   2 +-
 .../apache/camel/spring/SpringCamelContext.java    |   2 +-
 .../spring/remoting/CamelServiceExporter.java      |   4 +-
 .../org/apache/camel/CamelContextLifecycle.java    |   2 +
 .../main/java/org/apache/camel/ServiceStatus.java  |  12 +-
 .../java/org/apache/camel/spi/EventFactory.java    |  16 ++
 .../org/apache/camel/spi/LifecycleStrategy.java    |  10 +
 .../apache/camel/support/service/BaseService.java  |  41 +--
 .../camel/support/service/ServiceHelper.java       |  14 ++
 .../AbstractLocationPropertiesSource.java          |  10 -
 .../component/properties/PropertiesComponent.java  |  56 +++--
 .../impl/converter/BaseTypeConverterRegistry.java  |   2 +-
 .../impl/converter/CoreTypeConverterRegistry.java  |   3 -
 .../camel/impl/converter/DefaultTypeConverter.java |   9 +-
 .../TypeConvertersPackageScanClassResolver.java    |   9 -
 .../camel/impl/engine/AbstractCamelContext.java    | 280 +++++++++++++--------
 .../impl/engine/BaseExecutorServiceManager.java    |   8 +-
 .../engine/DefaultAsyncProcessorAwaitManager.java  |   5 -
 .../impl/engine/DefaultBeanIntrospection.java      |   2 +-
 .../camel/impl/engine/DefaultConsumerCache.java    |  18 +-
 .../camel/impl/engine/DefaultConsumerTemplate.java |  12 +-
 .../impl/engine/DefaultFluentProducerTemplate.java |  41 +--
 .../impl/engine/DefaultInflightRepository.java     |   4 -
 .../impl/engine/DefaultManagementStrategy.java     |  48 ++--
 .../impl/engine/DefaultMessageHistoryFactory.java  |   9 -
 .../engine/DefaultPackageScanClassResolver.java    |   5 -
 .../engine/DefaultPackageScanResourceResolver.java |   2 +-
 .../camel/impl/engine/DefaultProducerCache.java    |  20 +-
 .../camel/impl/engine/DefaultProducerTemplate.java |  47 ++--
 .../camel/impl/engine/DefaultReactiveExecutor.java |   5 -
 .../org/apache/camel/impl/engine/DefaultRoute.java |   2 -
 .../camel/impl/engine/DefaultRouteController.java  |  14 --
 .../engine/DefaultRuntimeEndpointRegistry.java     |   7 +-
 .../impl/event/CamelContextInitializedEvent.java   |  33 +++
 .../impl/event/CamelContextInitializingEvent.java  |  33 +++
 .../camel/impl/event/DefaultEventFactory.java      |  10 +
 .../camel/processor/RemovePropertiesProcessor.java |   9 -
 .../processor/interceptor/DefaultDebugger.java     |  10 +-
 .../loadbalancer/LoadBalancerSupport.java          |   5 +
 .../camel/builder/AdviceWithRouteBuilder.java      |   1 +
 .../org/apache/camel/builder/NotifyBuilder.java    |   3 +-
 .../camel/impl/lw/LightweightCamelContext.java     |   9 +-
 .../impl/lw/LightweightRuntimeCamelContext.java    |  10 +
 .../core/xml/AbstractCamelContextFactoryBean.java  |   2 -
 .../java/org/apache/camel/ContextTestSupport.java  |  25 +-
 .../camel/builder/BuilderWithScopesTest.java       |   2 +-
 .../camel/impl/MultipleLifecycleStrategyTest.java  |   6 +-
 .../issues/SentExchangeEventNotifierIssueTest.java |   1 -
 .../SentExchangeEventNotifierTwoIssueTest.java     |   1 -
 .../EventNotifierExchangeSentExampleTest.java      |   1 -
 .../ProducerTemplateDisableEventNotifierTest.java  |   1 -
 ...litterUseOriginalNotPropagateExceptionTest.java |   1 -
 .../EnricherAsyncUnhandledExceptionTest.java       |   1 -
 .../processor/enricher/EnricherSendEventTest.java  |   1 -
 .../DynamicRouterEventNotifierTest.java            |   1 -
 .../RecipientListEventNotifierTest.java            |   1 -
 .../routingslip/RoutingSlipEventNotifierTest.java  |   1 -
 .../org/apache/camel/main/BaseMainSupport.java     |   2 +-
 .../camel/management/DefaultManagementAgent.java   |  18 +-
 .../management/JmxManagementLifecycleStrategy.java |  94 +++----
 .../camel/management/JmxManagementStrategy.java    |  23 +-
 .../management/JmxManagementStrategyFactory.java   |   4 +-
 ...ationOnlyRegisterProcessorWithCustomIdTest.java |   1 -
 .../ManagedCamelContextPropertiesTest.java         |   1 -
 .../camel/management/ManagedCamelContextTest.java  |   3 +-
 .../camel/management/ManagedDynamicRouterTest.java |   1 -
 .../ManagedEndpointUtilizationStatisticsTest.java  |   1 -
 .../camel/management/ManagedEnricherTest.java      |   1 -
 .../management/ManagedNamePatternFixedTest.java    |   1 -
 .../ManagedNamePatternIncludeHostNameTest.java     |   2 +-
 .../camel/management/ManagedNamePatternTest.java   |   1 -
 .../management/ManagedNonManagedServiceTest.java   |   2 +-
 .../camel/management/ManagedPollEnricherTest.java  |   1 -
 ...gedProducerRecipientListRegisterAlwaysTest.java |   1 -
 ...edProducerRouteAddRemoveRegisterAlwaysTest.java |   3 +-
 .../camel/management/ManagedRecipientListTest.java |   1 -
 .../management/ManagedRouteAddRemoveTest.java      |   2 +-
 .../camel/management/ManagedRoutingSlipTest.java   |   1 -
 .../camel/management/ManagedSanitizeTest.java      |   1 -
 .../ManagedSendDynamicProcessorTest.java           |   1 -
 .../camel/management/ManagedStartupFailedTest.java |   3 +-
 .../management/ManagedStatisticsLevelOffTest.java  |   1 -
 .../ManagedStatisticsLevelRoutesOnlyTest.java      |   1 -
 .../camel/management/ManagedWireTapTest.java       |   1 -
 .../apache/camel/support/ChildServiceSupport.java  |  25 +-
 .../java/org/apache/camel/support/EventHelper.java | 200 ++-------------
 docs/components/modules/ROOT/pages/index.adoc      | 145 +++++++++++
 92 files changed, 815 insertions(+), 637 deletions(-)

diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java
index e9fcf46..8733ab0 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/BlueprintCamelContext.java
@@ -76,7 +76,7 @@ public class BlueprintCamelContext extends DefaultCamelContext implements Servic
         setLanguageResolver(new BlueprintLanguageResolver(bundleContext));
         setDataFormatResolver(new BlueprintDataFormatResolver(bundleContext));
         setApplicationContextClassLoader(new BundleDelegatingClassLoader(bundleContext.getBundle()));
-        init();
+        build();
     }
 
     @Override
@@ -110,7 +110,7 @@ public class BlueprintCamelContext extends DefaultCamelContext implements Servic
     }
 
     @Override
-    public void doInit() throws Exception {
+    public void doBuild() throws Exception {
         LOG.trace("init {}", this);
         // add service listener so we can be notified when blueprint container is done
         // and we would be ready to start CamelContext
@@ -119,7 +119,7 @@ public class BlueprintCamelContext extends DefaultCamelContext implements Servic
         // to support change events when it changes states
         registration = bundleContext.registerService(BlueprintListener.class, this, null);
         // call super
-        super.doInit();
+        super.doBuild();
     }
 
     public void destroy() throws Exception {
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
index f4c8173..3d71208 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java
@@ -283,7 +283,7 @@ public class CamelNamespaceHandler implements NamespaceHandler {
         ctx.setFactoryComponent(factory2);
         ctx.setFactoryMethod("getContext");
         ctx.addProperty("bundleStateService", createRef(context, ".camelBlueprint.bundleStateService"));
-        ctx.setInitMethod("init");
+        ctx.setInitMethod("build");
         ctx.setDestroyMethod("destroy");
 
         // Register factory beans
diff --git a/components/camel-cron/src/main/java/org/apache/camel/component/cron/CronComponent.java b/components/camel-cron/src/main/java/org/apache/camel/component/cron/CronComponent.java
index 0a112a4..c48356c 100644
--- a/components/camel-cron/src/main/java/org/apache/camel/component/cron/CronComponent.java
+++ b/components/camel-cron/src/main/java/org/apache/camel/component/cron/CronComponent.java
@@ -60,7 +60,7 @@ public class CronComponent extends DefaultComponent {
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         initCamelCronService();
     }
 
diff --git a/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
index adbfe6a..e98dbcc 100644
--- a/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
+++ b/components/camel-spring-javaconfig/src/main/java/org/apache/camel/spring/javaconfig/CamelConfiguration.java
@@ -161,7 +161,7 @@ public abstract class CamelConfiguration implements BeanFactoryAware, Applicatio
     public CamelContext camelContext() throws Exception {
         CamelContext camelContext = createCamelContext();
         setupCamelContext(camelContext);
-        camelContext.init();
+        camelContext.build();
         return camelContext;
     }
 
diff --git a/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java b/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java
index 92df8b0..940652a 100644
--- a/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java
+++ b/components/camel-spring-main/src/main/java/org/apache/camel/spring/Main.java
@@ -30,7 +30,9 @@ import java.util.Set;
 import org.apache.camel.CamelContext;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.main.MainCommandLineSupport;
+import org.apache.camel.VetoCamelContextStartException;
 import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 import org.springframework.context.support.AbstractApplicationContext;
@@ -177,10 +179,13 @@ public class Main extends MainCommandLineSupport {
             applicationContext.start();
 
             initCamelContext();
-        } finally {
+        } catch (Exception e) {
             // if we were veto started then mark as completed
-            if (getCamelContext() != null && getCamelContext().isVetoStarted()) {
+            VetoCamelContextStartException veto = ObjectHelper.getException(VetoCamelContextStartException.class, e);
+            if (veto != null) {
                 completed();
+            } else {
+                throw e;
             }
         }
     }
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
index 3429e9d..364fcb7 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java
@@ -483,7 +483,7 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
         if (context == null && create) {
             context = createContext();
             configure(context);
-            context.init();
+            context.build();
         }
         return context;
     }
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java b/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java
index c4e344a..100f857 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java
@@ -100,7 +100,7 @@ public class SpringCamelContext extends DefaultCamelContext implements Lifecycle
         }
         SpringCamelContext answer = new SpringCamelContext();
         answer.setApplicationContext(applicationContext);
-        answer.init();
+        answer.build();
         if (maybeStart) {
             answer.start();
         }
diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelServiceExporter.java b/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelServiceExporter.java
index ceed311..a7d3f85 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelServiceExporter.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/remoting/CamelServiceExporter.java
@@ -114,12 +114,12 @@ public class CamelServiceExporter extends RemoteExporter implements Initializing
 
         try {
             // need to start endpoint before we create consumer
-            ServiceHelper.startService(endpoint);
+            ServiceHelper.initService(endpoint);
             BeanProcessor processor = new BeanProcessor(proxy, camelContext);
             processor.setMethod(method);
             consumer = endpoint.createConsumer(processor);
             // add and start consumer
-            camelContext.addService(consumer, true, true);
+            camelContext.addService(consumer, true, false);
         } catch (Exception e) {
             throw new FailedToCreateConsumerException(endpoint, e);
         }
diff --git a/core/camel-api/src/main/java/org/apache/camel/CamelContextLifecycle.java b/core/camel-api/src/main/java/org/apache/camel/CamelContextLifecycle.java
index 7c4b327..152290b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/CamelContextLifecycle.java
+++ b/core/camel-api/src/main/java/org/apache/camel/CamelContextLifecycle.java
@@ -90,6 +90,8 @@ public interface CamelContextLifecycle extends AutoCloseable {
      */
     boolean isRunAllowed();
 
+    void build();
+
     void init();
 
     /**
diff --git a/core/camel-api/src/main/java/org/apache/camel/ServiceStatus.java b/core/camel-api/src/main/java/org/apache/camel/ServiceStatus.java
index 312a42c..6f4d941 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ServiceStatus.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ServiceStatus.java
@@ -22,10 +22,10 @@ import java.io.Serializable;
  * Represents the status of a {@link Service} instance
  */
 public enum ServiceStatus implements Serializable {
-    Starting, Started, Stopping, Stopped, Suspending, Suspended;
+    Initializing, Initialized, Starting, Started, Stopping, Stopped, Suspending, Suspended;
 
     public boolean isStartable() {
-        return this == Stopped || this == Suspended;
+        return this == Initialized || this == Stopped || this == Suspended;
     }
 
     public boolean isStoppable() {
@@ -36,6 +36,14 @@ public enum ServiceStatus implements Serializable {
         return this == Started;
     }
 
+    public boolean isInitializing() {
+        return this == Initializing;
+    }
+
+    public boolean isInitialized() {
+        return this == Initialized;
+    }
+
     public boolean isStarting() {
         return this == Starting;
     }
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/EventFactory.java b/core/camel-api/src/main/java/org/apache/camel/spi/EventFactory.java
index 41754e7..b9de47f 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/EventFactory.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/EventFactory.java
@@ -30,6 +30,22 @@ import org.apache.camel.Route;
 public interface EventFactory {
 
     /**
+     * Creates an {@link CamelEvent} for Camel is initializing.
+     *
+     * @param context camel context
+     * @return the created event
+     */
+    CamelEvent createCamelContextInitializingEvent(CamelContext context);
+
+    /**
+     * Creates an {@link CamelEvent} for Camel has been initialized successfully.
+     *
+     * @param context camel context
+     * @return the created event
+     */
+    CamelEvent createCamelContextInitializedEvent(CamelContext context);
+
+    /**
      * Creates an {@link CamelEvent} for Camel is starting.
      *
      * @param context camel context
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/LifecycleStrategy.java b/core/camel-api/src/main/java/org/apache/camel/spi/LifecycleStrategy.java
index 20ddeaa..cf74794 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/LifecycleStrategy.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/LifecycleStrategy.java
@@ -34,6 +34,16 @@ import org.apache.camel.VetoCamelContextStartException;
 public interface LifecycleStrategy {
 
     /**
+     * Notification on initializing a {@link CamelContext}.
+     *
+     * @param context the camel context
+     * @throws VetoCamelContextStartException can be thrown to veto starting {@link CamelContext}.
+     *                                        Any other runtime exceptions will be logged at <tt>WARN</tt> level by Camel will continue starting itself.
+     */
+    default void onContextInitialized(CamelContext context) throws VetoCamelContextStartException {
+    }
+
+    /**
      * Notification on starting a {@link CamelContext}.
      *
      * @param context the camel context
diff --git a/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java b/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
index d408b10..054235b 100644
--- a/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
+++ b/core/camel-api/src/main/java/org/apache/camel/support/service/BaseService.java
@@ -37,16 +37,17 @@ public abstract class BaseService {
 
     protected static final byte NEW = 0;
     protected static final byte BUILDED = 1;
-    protected static final byte INITIALIZED = 2;
-    protected static final byte STARTING = 3;
-    protected static final byte STARTED = 4;
-    protected static final byte SUSPENDING = 5;
-    protected static final byte SUSPENDED = 6;
-    protected static final byte STOPPING = 7;
-    protected static final byte STOPPED = 8;
-    protected static final byte SHUTTINGDOWN = 9;
-    protected static final byte SHUTDOWN = 10;
-    protected static final byte FAILED = 11;
+    protected static final byte INITIALIZING = 2;
+    protected static final byte INITIALIZED = 3;
+    protected static final byte STARTING = 4;
+    protected static final byte STARTED = 5;
+    protected static final byte SUSPENDING = 6;
+    protected static final byte SUSPENDED = 7;
+    protected static final byte STOPPING = 8;
+    protected static final byte STOPPED = 9;
+    protected static final byte SHUTTINGDOWN = 10;
+    protected static final byte SHUTDOWN = 11;
+    protected static final byte FAILED = 12;
 
     private static final Logger LOG = LoggerFactory.getLogger(BaseService.class);
 
@@ -75,15 +76,17 @@ public abstract class BaseService {
         if (status <= BUILDED || status >= STOPPED) {
             synchronized (lock) {
                 if (status <= BUILDED || status >= STOPPED) {
+                    build();
                     LOG.trace("Initializing service: {}", this);
                     try (AutoCloseable ignored = doLifecycleChange()) {
+                        status = INITIALIZING;
                         doInit();
+                        status = INITIALIZED;
+                        LOG.trace("Initialized service: {}", this);
                     } catch (Exception e) {
                         LOG.trace("Error while initializing service: " + this, e);
                         fail(e);
                     }
-                    status = INITIALIZED;
-                    LOG.trace("Initialized service: {}", this);
                 }
             }
         }
@@ -245,6 +248,10 @@ public abstract class BaseService {
 
     public ServiceStatus getStatus() {
         switch (status) {
+            case INITIALIZING:
+                return ServiceStatus.Initializing;
+            case INITIALIZED:
+                return ServiceStatus.Initialized;
             case STARTING:
                 return ServiceStatus.Starting;
             case STARTED:
@@ -338,6 +345,7 @@ public abstract class BaseService {
      * This method will only be called by frameworks which supports pre-building projects such as camel-quarkus.
      */
     protected void doBuild() throws Exception {
+        // noop
     }
 
     /**
@@ -345,6 +353,7 @@ public abstract class BaseService {
      * This method will only be called once before starting.
      */
     protected void doInit() throws Exception {
+        // noop
     }
 
     /**
@@ -354,7 +363,9 @@ public abstract class BaseService {
      *
      * @see #doStop()
      */
-    protected abstract void doStart() throws Exception;
+    protected void doStart() throws Exception {
+        // noop
+    }
 
     /**
      * Implementations override this method to support customized start/stop.
@@ -368,7 +379,9 @@ public abstract class BaseService {
      *
      * @see #doStart()
      */
-    protected abstract void doStop() throws Exception;
+    protected void doStop() throws Exception {
+        // noop
+    }
 
     /**
      * Implementations override this method to support customized suspend/resume.
diff --git a/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceHelper.java b/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceHelper.java
index 6ecfdc7..6ae854a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceHelper.java
+++ b/core/camel-api/src/main/java/org/apache/camel/support/service/ServiceHelper.java
@@ -61,6 +61,20 @@ public final class ServiceHelper {
     }
 
     /**
+     * Initializes each element of the given {@code services} if {@code services} itself is
+     * not {@code null}, otherwise this method would return immediately.
+     *
+     * @see #initService(Object)
+     */
+    public static void initService(Object... services) {
+        if (services != null) {
+            for (Object o : services) {
+                initService(o);
+            }
+        }
+    }
+
+    /**
      * Starts the given {@code value} if it's a {@link Service} or a collection of it.
      * <p/>
      * Calling this method has no effect if {@code value} is {@code null}.
diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/AbstractLocationPropertiesSource.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/AbstractLocationPropertiesSource.java
index 1e08cb5..306ef8a 100644
--- a/core/camel-base/src/main/java/org/apache/camel/component/properties/AbstractLocationPropertiesSource.java
+++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/AbstractLocationPropertiesSource.java
@@ -79,16 +79,6 @@ public abstract class AbstractLocationPropertiesSource extends ServiceSupport im
         }
     }
 
-    @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        // noop
-    }
-
     /**
      * Strategy to prepare loaded properties before being used by Camel.
      * <p/>
diff --git a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
index 138d223..36d66f8 100644
--- a/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
+++ b/core/camel-base/src/main/java/org/apache/camel/component/properties/PropertiesComponent.java
@@ -513,10 +513,15 @@ public class PropertiesComponent extends ServiceSupport implements org.apache.ca
         if (propertiesSource instanceof CamelContextAware) {
             ((CamelContextAware) propertiesSource).setCamelContext(getCamelContext());
         }
-        sources.add(propertiesSource);
-        if (!this.isNew()) {
-            // if we have already initialized or started then we should also init the source
-            ServiceHelper.initService(propertiesSource);
+        synchronized (lock) {
+            sources.add(propertiesSource);
+            if (!isNew()) {
+                // if we have already initialized or started then we should also init the source
+                ServiceHelper.initService(propertiesSource);
+            }
+            if (isStarted()) {
+                ServiceHelper.startService(propertiesSource);
+            }
         }
     }
 
@@ -528,6 +533,24 @@ public class PropertiesComponent extends ServiceSupport implements org.apache.ca
     protected void doInit() throws Exception {
         super.doInit();
 
+        ObjectHelper.notNull(camelContext, "CamelContext", this);
+
+        if (systemPropertiesMode != SYSTEM_PROPERTIES_MODE_NEVER
+                && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_FALLBACK
+                && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_OVERRIDE) {
+            throw new IllegalArgumentException("Option systemPropertiesMode has invalid value: " + systemPropertiesMode);
+        }
+        if (environmentVariableMode != ENVIRONMENT_VARIABLES_MODE_NEVER
+                && environmentVariableMode != ENVIRONMENT_VARIABLES_MODE_FALLBACK
+                && environmentVariableMode != ENVIRONMENT_VARIABLES_MODE_OVERRIDE) {
+            throw new IllegalArgumentException("Option environmentVariableMode has invalid value: " + environmentVariableMode);
+        }
+
+        // inject the component to the parser
+        if (propertiesParser instanceof DefaultPropertiesParser) {
+            ((DefaultPropertiesParser) propertiesParser).setPropertiesComponent(this);
+        }
+
         if (isAutoDiscoverPropertiesSources()) {
             // discover any 3rd party properties sources
             try {
@@ -553,35 +576,22 @@ public class PropertiesComponent extends ServiceSupport implements org.apache.ca
             }
         }
 
+        sources.sort(OrderedComparator.get());
         ServiceHelper.initService(sources);
     }
 
     @Override
     protected void doStart() throws Exception {
-        ObjectHelper.notNull(camelContext, "CamelContext", this);
-
-        sources.sort(OrderedComparator.get());
         ServiceHelper.startService(sources);
-
-        if (systemPropertiesMode != SYSTEM_PROPERTIES_MODE_NEVER
-                && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_FALLBACK
-                && systemPropertiesMode != SYSTEM_PROPERTIES_MODE_OVERRIDE) {
-            throw new IllegalArgumentException("Option systemPropertiesMode has invalid value: " + systemPropertiesMode);
-        }
-        if (environmentVariableMode != ENVIRONMENT_VARIABLES_MODE_NEVER
-                && environmentVariableMode != ENVIRONMENT_VARIABLES_MODE_FALLBACK
-                && environmentVariableMode != ENVIRONMENT_VARIABLES_MODE_OVERRIDE) {
-            throw new IllegalArgumentException("Option environmentVariableMode has invalid value: " + environmentVariableMode);
-        }
-
-        // inject the component to the parser
-        if (propertiesParser instanceof DefaultPropertiesParser) {
-            ((DefaultPropertiesParser) propertiesParser).setPropertiesComponent(this);
-        }
     }
 
     @Override
     protected void doStop() throws Exception {
+        ServiceHelper.stopService(sources);
+    }
+
+    @Override
+    protected void doShutdown() throws Exception {
         ServiceHelper.stopAndShutdownServices(sources);
     }
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
index ee08b33..7b58856 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/BaseTypeConverterRegistry.java
@@ -272,7 +272,7 @@ public abstract class BaseTypeConverterRegistry extends CoreTypeConverterRegistr
     }
 
     @Override
-    protected void doInit() {
+    protected void doInit() throws Exception {
         if (injector == null && camelContext != null) {
             injector = camelContext.getInjector();
         }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
index 5df13ca..b0456ce 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/CoreTypeConverterRegistry.java
@@ -587,9 +587,6 @@ public class CoreTypeConverterRegistry extends ServiceSupport implements TypeCon
         this.typeConverterExists = typeConverterExists;
     }
 
-    protected void doStart() throws Exception {
-    }
-
     protected void doStop() throws Exception {
         // log utilization statistics when stopping, including mappings
         if (statistics.isStatisticsEnabled()) {
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
index bc8a6a2..e311563 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/DefaultTypeConverter.java
@@ -57,15 +57,10 @@ public class DefaultTypeConverter extends BaseTypeConverterRegistry implements A
     }
 
     @Override
-    protected void doInit() {
-        super.doInit();
-    }
-
-    @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         StopWatch watch = new StopWatch();
 
-        super.doStart();
+        super.doInit();
 
         // core type converters is always loaded which does not use any classpath scanning and therefore is fast
         loadCoreAndFastTypeConverters();
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConvertersPackageScanClassResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConvertersPackageScanClassResolver.java
index 4898a7c..1aa3a12 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConvertersPackageScanClassResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/converter/TypeConvertersPackageScanClassResolver.java
@@ -96,13 +96,4 @@ public class TypeConvertersPackageScanClassResolver extends ServiceSupport imple
         // noop
     }
 
-    @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        // noop
-    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 2980c01..e6cabb6 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -325,7 +325,7 @@ public abstract class AbstractCamelContext extends BaseService
         setRegistry(registry);
     }
 
-    public AbstractCamelContext(boolean init) {
+    public AbstractCamelContext(boolean build) {
         // create a provisional (temporary) endpoint registry at first since end
         // users may access endpoints before CamelContext is started
         // we will later transfer the endpoints to the actual
@@ -337,9 +337,9 @@ public abstract class AbstractCamelContext extends BaseService
 
         setDefaultExtension(HealthCheckRegistry.class, this::createHealthCheckRegistry);
 
-        if (init) {
+        if (build) {
             try {
-                init();
+                build();
             } catch (Exception e) {
                 throw new RuntimeException("Error initializing CamelContext", e);
             }
@@ -506,7 +506,7 @@ public abstract class AbstractCamelContext extends BaseService
     @Override
     public Component getComponent(String name, boolean autoCreateComponents, boolean autoStart) {
         // ensure CamelContext are initialized before we can get a component
-        init();
+        build();
 
         // Check if the named component is already being created, that would mean
         // that the initComponent has triggered a new getComponent
@@ -594,7 +594,7 @@ public abstract class AbstractCamelContext extends BaseService
                 component = getComponentResolver().resolveComponent(name, getCamelContextReference());
                 if (component != null) {
                     component.setCamelContext(getCamelContextReference());
-                    ServiceHelper.initService(component);
+                    component.build();
                     postInitComponent(name, component);
                 }
             } catch (Exception e) {
@@ -778,8 +778,8 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     protected Endpoint doGetEndpoint(String uri, boolean normalized, boolean prototype) {
-        // ensure CamelContext are initialized before we can get an endpoint
-        init();
+        // ensure CamelContext are initialized before we can get a component
+        build();
 
         StringHelper.notEmpty(uri, "uri");
 
@@ -827,6 +827,7 @@ public abstract class AbstractCamelContext extends BaseService
                 }
                 LOG.trace("Endpoint uri: {} is from component with name: {}", uri, scheme);
                 Component component = getComponent(scheme);
+                ServiceHelper.initService(component);
 
                 // Ask the component to resolve the endpoint.
                 if (component != null) {
@@ -1163,7 +1164,7 @@ public abstract class AbstractCamelContext extends BaseService
     @Override
     public void addRoutes(final RoutesBuilder builder) throws Exception {
         try (LifecycleHelper helper = new LifecycleHelper()) {
-            init();
+            build();
             LOG.debug("Adding routes from builder: {}", builder);
             builder.addRoutesToCamelContext(AbstractCamelContext.this);
         }
@@ -1446,12 +1447,13 @@ public abstract class AbstractCamelContext extends BaseService
                         } else {
                             route = setupRoute.get();
                         }
-                        strategy.onServiceAdd(this, service, route);
+                        strategy.onServiceAdd(getCamelContextReference(), service, route);
                     }
                 }
             }
 
             if (!forceStart) {
+                ServiceHelper.initService(service);
                 // now start the service (and defer starting if CamelContext is
                 // starting up itself)
                 deferStartService(object, stopOnShutdown);
@@ -1474,7 +1476,11 @@ public abstract class AbstractCamelContext extends BaseService
                         }
                     }
                 }
-                ServiceHelper.startService(service);
+                if (isStartingOrStarted()) {
+                    ServiceHelper.startService(service);
+                } else {
+                    ServiceHelper.initService(service);
+                }
             }
         }
     }
@@ -2414,24 +2420,19 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
-    public void doInit() throws Exception {
-        // Initialize LRUCacheFactory as eager as possible,
-        // to let it warm up concurrently while Camel is startup up
-        if (initialization != Initialization.Lazy) {
-            LRUCacheFactory.init();
-        }
+    public void init() {
+        super.init();
 
-        // Setup management first since end users may use it to add event
-        // notifiers using the management strategy before the CamelContext has been started
-        setupManagement(null);
-
-        // Call all registered trackers with this context
-        // Note, this may use a partially constructed object
-        CamelContextTracker.notifyContextCreated(this);
-
-        // Setup type converter eager as its highly in use and should not be lazy initialized
-        if (eagerCreateTypeConverter()) {
-            getOrCreateTypeConverter();
+        // was the initialization vetoed?
+        if (vetoed != null) {
+            if (vetoed.isRethrowException()) {
+                throw RuntimeCamelException.wrapRuntimeException(vetoed);
+            } else {
+                LOG.info("CamelContext ({}) vetoed to not initialize due to {}", getName(), vetoed.getMessage());
+                // swallow exception and change state of this camel context to stopped
+                fail(vetoed);
+                return;
+            }
         }
     }
 
@@ -2439,12 +2440,17 @@ public abstract class AbstractCamelContext extends BaseService
     public void start() {
         super.start();
 
+        //
+        // We need to perform the following actions after the {@link #start()} method
+        // is called, so that the state of the {@link CamelContext} is <code>Started<code>.
+        //
+
         // did the start veto?
         if (vetoed != null) {
             if (vetoed.isRethrowException()) {
                 throw RuntimeCamelException.wrapRuntimeException(vetoed);
             } else {
-                LOG.info("CamelContext ({}) vetoed to not start due {}", getName(), vetoed.getMessage());
+                LOG.info("CamelContext ({}) vetoed to not start due to {}", getName(), vetoed.getMessage());
                 // swallow exception and change state of this camel context to stopped
                 stop();
                 return;
@@ -2468,7 +2474,129 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
-    protected synchronized void doStart() throws Exception {
+    public void doBuild() throws Exception {
+        // Initialize LRUCacheFactory as eager as possible,
+        // to let it warm up concurrently while Camel is startup up
+        if (initialization != Initialization.Lazy) {
+            LRUCacheFactory.init();
+        }
+
+        // Setup management first since end users may use it to add event
+        // notifiers using the management strategy before the CamelContext has been started
+        setupManagement(null);
+
+        // Call all registered trackers with this context
+        // Note, this may use a partially constructed object
+        CamelContextTracker.notifyContextCreated(this);
+
+        // Setup type converter eager as its highly in use and should not be lazy initialized
+        if (eagerCreateTypeConverter()) {
+            getOrCreateTypeConverter();
+        }
+
+    }
+
+    @Override
+    public void doInit() throws Exception {
+        // Start the route controller
+        getRouteController();
+        ServiceHelper.initService(this.routeController);
+
+        // optimize - before starting routes lets check if event notifications is possible
+        eventNotificationApplicable = EventHelper.eventsApplicable(this);
+
+        // ensure additional type converters is loaded
+        if (loadTypeConverters && typeConverter instanceof AnnotationScanTypeConverters) {
+            ((AnnotationScanTypeConverters) typeConverter).scanTypeConverters();
+        }
+
+        // custom properties may use property placeholders so resolve those
+        // early on
+        if (globalOptions != null && !globalOptions.isEmpty()) {
+            for (Map.Entry<String, String> entry : globalOptions.entrySet()) {
+                String key = entry.getKey();
+                String value = entry.getValue();
+                if (value != null) {
+                    String replaced = resolvePropertyPlaceholders(value);
+                    if (!value.equals(replaced)) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("Camel property with key {} replaced value from {} -> {}", key, value, replaced);
+                        }
+                        entry.setValue(replaced);
+                    }
+                }
+            }
+        }
+
+        forceLazyInitialization();
+
+        addService(getManagementStrategy(), false);
+        ServiceHelper.initService(lifecycleStrategies);
+        for (LifecycleStrategy strategy : lifecycleStrategies) {
+            try {
+                strategy.onContextInitialized(this);
+            } catch (VetoCamelContextStartException e) {
+                // okay we should not start Camel since it was vetoed
+                LOG.warn("Lifecycle strategy " + strategy + " vetoed initializing CamelContext ({}) due to: {}", getName(), e.getMessage());
+                throw e;
+            } catch (Exception e) {
+                LOG.warn("Lifecycle strategy " + strategy + " failed initializing CamelContext ({}) due to: {}", getName(), e.getMessage());
+                throw e;
+            }
+        }
+
+        // optimize - before starting routes lets check if event notifications is possible
+        eventNotificationApplicable = EventHelper.eventsApplicable(this);
+
+        // start notifiers as services
+        for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
+            if (notifier instanceof Service) {
+                Service service = (Service) notifier;
+                for (LifecycleStrategy strategy : lifecycleStrategies) {
+                    strategy.onServiceAdd(getCamelContextReference(), service, null);
+                }
+            }
+            ServiceHelper.initService(notifier);
+        }
+
+        EventHelper.notifyCamelContextInitializing(this);
+
+        // re-create endpoint registry as the cache size limit may be set after the constructor of this instance was called.
+        // and we needed to create endpoints up-front as it may be accessed before this context is started
+        endpoints = doAddService(createEndpointRegistry(endpoints));
+
+        // optimised to not include runtimeEndpointRegistry unless startServices
+        // is enabled or JMX statistics is in extended mode
+        if (runtimeEndpointRegistry == null && getManagementStrategy() != null && getManagementStrategy().getManagementAgent() != null) {
+            Boolean isEnabled = getManagementStrategy().getManagementAgent().getEndpointRuntimeStatisticsEnabled();
+            boolean isExtended = getManagementStrategy().getManagementAgent().getStatisticsLevel().isExtended();
+            // extended mode is either if we use Extended statistics level or
+            // the option is explicit enabled
+            boolean extended = isExtended || isEnabled != null && isEnabled;
+            if (extended) {
+                runtimeEndpointRegistry = new DefaultRuntimeEndpointRegistry();
+            }
+        }
+        if (runtimeEndpointRegistry != null) {
+            if (runtimeEndpointRegistry instanceof EventNotifier && getManagementStrategy() != null) {
+                getManagementStrategy().addEventNotifier((EventNotifier)runtimeEndpointRegistry);
+            }
+            addService(runtimeEndpointRegistry, true, true);
+        }
+
+        bindDataFormats();
+
+        // start components
+        ServiceHelper.initService(components.values());
+
+        // start the route definitions before the routes is started
+        startRouteDefinitions();
+
+        EventHelper.notifyCamelContextInitialized(this);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
         try {
             doStartContext();
         } catch (Exception e) {
@@ -2480,20 +2608,16 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     protected void doStartContext() throws Exception {
-        startDate = new Date();
-
+        LOG.info("Apache Camel {} (CamelContext: {}) is starting", getVersion(), getName());
         vetoed = null;
+        startDate = new Date();
         stopWatch.restart();
-        LOG.info("Apache Camel {} (CamelContext: {}) is starting", getVersion(), getName());
 
         // Start the route controller
         ServiceHelper.startService(this.routeController);
 
         doNotStartRoutesOnFirstStart = !firstStartDone && !isAutoStartup();
 
-        // optimize - before starting routes lets check if event notifications is possible
-        eventNotificationApplicable = EventHelper.eventsApplicable(this);
-
         // if the context was configured with auto startup = false, and we
         // are already started,
         // then we may need to start the routes on the 2nd start call
@@ -2546,38 +2670,13 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     protected void doStartCamel() throws Exception {
-        // ensure additional type converters is loaded
-        if (loadTypeConverters && typeConverter instanceof AnnotationScanTypeConverters) {
-            ((AnnotationScanTypeConverters) typeConverter).scanTypeConverters();
-        }
-
-        // custom properties may use property placeholders so resolve those
-        // early on
-        if (globalOptions != null && !globalOptions.isEmpty()) {
-            for (Map.Entry<String, String> entry : globalOptions.entrySet()) {
-                String key = entry.getKey();
-                String value = entry.getValue();
-                if (value != null) {
-                    String replaced = resolvePropertyPlaceholders(value);
-                    if (!value.equals(replaced)) {
-                        if (LOG.isDebugEnabled()) {
-                            LOG.debug("Camel property with key {} replaced value from {} -> {}", key, value, replaced);
-                        }
-                        entry.setValue(replaced);
-                    }
-                }
-            }
-        }
-
         if (LOG.isDebugEnabled()) {
             LOG.debug("Using ClassResolver={}, PackageScanClassResolver={}, ApplicationContextClassLoader={}, RouteController={}", getClassResolver(),
                       getPackageScanClassResolver(), getApplicationContextClassLoader(), getRouteController());
         }
-
         if (isStreamCaching()) {
             LOG.info("StreamCaching is enabled on CamelContext: {}", getName());
         }
-
         if (isBacklogTracing()) {
             // tracing is added in the DefaultChannel so we can enable it on the fly
             LOG.info("Backlog Tracing is enabled on CamelContext: {}", getName());
@@ -2586,7 +2685,6 @@ public abstract class AbstractCamelContext extends BaseService
             // tracing is added in the DefaultChannel so we can enable it on the fly
             LOG.info("Tracing is enabled on CamelContext: {}", getName());
         }
-
         if (isUseMDCLogging()) {
             // log if MDC has been enabled
             String pattern = getMDCLoggingKeysPattern();
@@ -2596,7 +2694,6 @@ public abstract class AbstractCamelContext extends BaseService
                 LOG.info("MDC logging is enabled on CamelContext: {}", getName());
             }
         }
-
         if (getDelayer() != null && getDelayer() > 0) {
             LOG.info("Delayer is enabled with: {} ms. on CamelContext: {}", getDelayer(), getName());
         }
@@ -2607,17 +2704,15 @@ public abstract class AbstractCamelContext extends BaseService
 
         // start lifecycle strategies
         ServiceHelper.startService(lifecycleStrategies);
-        Iterator<LifecycleStrategy> it = lifecycleStrategies.iterator();
-        while (it.hasNext()) {
-            LifecycleStrategy strategy = it.next();
+        for (LifecycleStrategy strategy : lifecycleStrategies) {
             try {
                 strategy.onContextStart(this);
             } catch (VetoCamelContextStartException e) {
                 // okay we should not start Camel since it was vetoed
-                LOG.warn("Lifecycle strategy vetoed starting CamelContext ({}) due: {}", getName(), e.getMessage());
+                LOG.warn("Lifecycle strategy " + strategy + " vetoed starting CamelContext ({}) due to: {}", getName(), e.getMessage());
                 throw e;
             } catch (Exception e) {
-                LOG.warn("Lifecycle strategy " + strategy + " failed starting CamelContext ({}) due: {}", getName(), e.getMessage());
+                LOG.warn("Lifecycle strategy " + strategy + " failed starting CamelContext ({}) due to: {}", getName(), e.getMessage());
                 throw e;
             }
         }
@@ -2625,51 +2720,16 @@ public abstract class AbstractCamelContext extends BaseService
         // start notifiers as services
         for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
             if (notifier instanceof Service) {
-                Service service = (Service)notifier;
-                for (LifecycleStrategy strategy : lifecycleStrategies) {
-                    strategy.onServiceAdd(this, service, null);
-                }
                 startService((Service)notifier);
             }
         }
 
-        // must let some bootstrap service be started before we can notify the
-        // starting event
+        // must let some bootstrap service be started before we can notify the starting event
         EventHelper.notifyCamelContextStarting(this);
 
-        forceLazyInitialization();
-
-        // re-create endpoint registry as the cache size limit may be set after the constructor of this instance was called.
-        // and we needed to create endpoints up-front as it may be accessed before this context is started
-        endpoints = doAddService(createEndpointRegistry(endpoints));
-
-        // optimised to not include runtimeEndpointRegistry unless startServices
-        // its enabled or JMX statistics is in extended mode
-        if (runtimeEndpointRegistry == null && getManagementStrategy() != null && getManagementStrategy().getManagementAgent() != null) {
-            Boolean isEnabled = getManagementStrategy().getManagementAgent().getEndpointRuntimeStatisticsEnabled();
-            boolean isExtended = getManagementStrategy().getManagementAgent().getStatisticsLevel().isExtended();
-            // extended mode is either if we use Extended statistics level or
-            // the option is explicit enabled
-            boolean extended = isExtended || isEnabled != null && isEnabled;
-            if (extended) {
-                runtimeEndpointRegistry = new DefaultRuntimeEndpointRegistry();
-            }
-        }
-        if (runtimeEndpointRegistry != null) {
-            if (runtimeEndpointRegistry instanceof EventNotifier && getManagementStrategy() != null) {
-                getManagementStrategy().addEventNotifier((EventNotifier)runtimeEndpointRegistry);
-            }
-            addService(runtimeEndpointRegistry, true, true);
-        }
-
-        bindDataFormats();
-
         // start components
         startServices(components.values());
 
-        // start the route definitions before the routes is started
-        startRouteDefinitions();
-
         if (isUseDataType()) {
             // log if DataType has been enabled
             LOG.info("Message DataType is enabled on CamelContext: {}", getName());
@@ -2731,7 +2791,7 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
-    protected synchronized void doStop() throws Exception {
+    protected void doStop() throws Exception {
         stopWatch.restart();
         LOG.info("Apache Camel {} (CamelContext: {}) is shutting down", getVersion(), getName());
         EventHelper.notifyCamelContextStopping(this);
@@ -2828,8 +2888,10 @@ public abstract class AbstractCamelContext extends BaseService
         EventHelper.notifyCamelContextStopped(this);
 
         // stop the notifier service
-        for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
-            shutdownServices(notifier);
+        if (getManagementStrategy() != null) {
+            for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
+                shutdownServices(notifier);
+            }
         }
 
         // shutdown executor service, reactive executor and management as the last one
@@ -3681,7 +3743,7 @@ public abstract class AbstractCamelContext extends BaseService
     public void disableJMX() {
         if (isNew()) {
             disableJMX = true;
-        } else if (isInit()) {
+        } else if (isInit() || isBuild()) {
             disableJMX = true;
             // we are still in initializing mode, so we can disable JMX, by
             // setting up management again
@@ -4038,7 +4100,7 @@ public abstract class AbstractCamelContext extends BaseService
         if (isStartingOrStarted()) {
             throw new IllegalStateException("Can not set debugger on a started CamelContext");
         }
-        this.debugger = doAddService(debugger);
+        this.debugger = doAddService(debugger, true, false, true);
         // enable debugging if we set a custom debugger
         setDebugging(true);
     }
@@ -4057,7 +4119,7 @@ public abstract class AbstractCamelContext extends BaseService
 
     @Override
     public void setTracer(Tracer tracer) {
-        this.tracer = tracer;
+        this.tracer = doAddService(tracer, true, false, true);
         // enable tracing if we set a custom tracer
         setTracing(true);
     }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
index 3428d2d..261e8e5 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/BaseExecutorServiceManager.java
@@ -421,7 +421,8 @@ public class BaseExecutorServiceManager extends ServiceSupport implements Execut
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
+        super.doInit();
         if (threadNamePattern == null) {
             // set default name pattern which includes the camel context name
             threadNamePattern = "Camel (" + camelContext.getName() + ") thread ##counter# - #name#";
@@ -429,11 +430,6 @@ public class BaseExecutorServiceManager extends ServiceSupport implements Execut
     }
 
     @Override
-    protected void doStop() throws Exception {
-        // noop
-    }
-
-    @Override
     protected void doShutdown() throws Exception {
         // shutdown all remainder executor services by looping and doing this aggressively
         // as by normal all threads pool should have been shutdown using proper lifecycle
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultAsyncProcessorAwaitManager.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultAsyncProcessorAwaitManager.java
index f3c2ad9..21dd10c 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultAsyncProcessorAwaitManager.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultAsyncProcessorAwaitManager.java
@@ -220,11 +220,6 @@ public class DefaultAsyncProcessorAwaitManager extends ServiceSupport implements
     }
 
     @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
     protected void doStop() throws Exception {
         Collection<AwaitThread> threads = browse();
         int count = threads.size();
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
index 69c01b5..3db2234 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultBeanIntrospection.java
@@ -221,7 +221,7 @@ public class DefaultBeanIntrospection extends ServiceSupport implements BeanIntr
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         if (camelContext != null) {
             camelContext.addStartupListener(this);
         }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerCache.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerCache.java
index e77656f..cc90b9b 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerCache.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerCache.java
@@ -228,21 +228,29 @@ public class DefaultConsumerCache extends ServiceSupport implements ConsumerCach
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         if (extendedStatistics) {
             int max = maxCacheSize == 0 ? CamelContextHelper.getMaximumCachePoolSize(camelContext) : maxCacheSize;
             statistics = new DefaultEndpointUtilizationStatistics(max);
         }
-        ServiceHelper.startService(consumers);
+        ServiceHelper.initService(consumers);
     }
 
     @Override
-    protected void doStop() throws Exception {
-        // when stopping we intend to shutdown
-        ServiceHelper.stopAndShutdownServices(statistics, consumers);
+    protected void doStart() throws Exception {
         if (statistics != null) {
             statistics.clear();
         }
+        ServiceHelper.startService(consumers);
     }
 
+    @Override
+    protected void doStop() throws Exception {
+        ServiceHelper.stopService(consumers);
+    }
+
+    @Override
+    protected void doShutdown() throws Exception {
+        ServiceHelper.stopAndShutdownServices(consumers);
+    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerTemplate.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerTemplate.java
index cabf240..96cd50b 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerTemplate.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultConsumerTemplate.java
@@ -272,15 +272,25 @@ public class DefaultConsumerTemplate extends ServiceSupport implements ConsumerT
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         if (consumerCache == null) {
             consumerCache = new DefaultConsumerCache(this, camelContext, maximumCacheSize);
         }
+        ServiceHelper.initService(consumerCache);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
         ServiceHelper.startService(consumerCache);
     }
 
     @Override
     protected void doStop() throws Exception {
+        ServiceHelper.stopService(consumerCache);
+    }
+
+    @Override
+    protected void doShutdown() throws Exception {
         // we should shutdown the services as this is our intention, to not re-use the services anymore
         ServiceHelper.stopAndShutdownService(consumerCache);
         consumerCache = null;
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFluentProducerTemplate.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFluentProducerTemplate.java
index 74dda14..312593a 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFluentProducerTemplate.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultFluentProducerTemplate.java
@@ -337,23 +337,12 @@ public class DefaultFluentProducerTemplate extends ServiceSupport implements Flu
      * @param context the camel context
      */
     public static FluentProducerTemplate on(CamelContext context) {
-        return new DefaultFluentProducerTemplate(context);
+        DefaultFluentProducerTemplate fluent = new DefaultFluentProducerTemplate(context);
+        fluent.start();
+        return fluent;
     }
 
     private ProducerTemplate template() {
-        ObjectHelper.notNull(context, "CamelContext");
-
-        if (template == null) {
-            template = context.createProducerTemplate(maximumCacheSize);
-            if (defaultEndpoint != null) {
-                template.setDefaultEndpoint(defaultEndpoint);
-            }
-            template.setEventNotifierEnabled(eventNotifierEnabled);
-            if (templateCustomizer.get() != null) {
-                templateCustomizer.get().accept(template);
-            }
-        }
-
         return template;
     }
 
@@ -390,10 +379,21 @@ public class DefaultFluentProducerTemplate extends ServiceSupport implements Flu
     }
 
     @Override
-    protected void doStart() throws Exception {
-        if (template == null) {
-            template = template();
+    protected void doInit() throws Exception {
+        ObjectHelper.notNull(context, "CamelContext");
+        template = context.createProducerTemplate(maximumCacheSize);
+        if (defaultEndpoint != null) {
+            template.setDefaultEndpoint(defaultEndpoint);
+        }
+        template.setEventNotifierEnabled(eventNotifierEnabled);
+        if (templateCustomizer.get() != null) {
+            templateCustomizer.get().accept(template);
         }
+        ServiceHelper.initService(template);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
         ServiceHelper.startService(template);
     }
 
@@ -404,7 +404,12 @@ public class DefaultFluentProducerTemplate extends ServiceSupport implements Flu
         this.exchangeSupplier.remove();
         this.processorSupplier.remove();
         this.templateCustomizer.remove();
-
         ServiceHelper.stopService(template);
     }
+
+    @Override
+    protected void doShutdown() throws Exception {
+        ServiceHelper.stopAndShutdownService(template);
+        template = null;
+    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultInflightRepository.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultInflightRepository.java
index 79adbe9..3634ec8 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultInflightRepository.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultInflightRepository.java
@@ -198,10 +198,6 @@ public class DefaultInflightRepository extends ServiceSupport implements Infligh
     }
 
     @Override
-    protected void doStart() throws Exception {
-    }
-
-    @Override
     protected void doStop() throws Exception {
         int count = size();
         if (count > 0) {
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultManagementStrategy.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultManagementStrategy.java
index 43fca10..dad1658 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultManagementStrategy.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultManagementStrategy.java
@@ -103,9 +103,6 @@ public class DefaultManagementStrategy extends ServiceSupport implements Managem
 
     @Override
     public ManagementObjectNameStrategy getManagementObjectNameStrategy() {
-        if (managementObjectNameStrategy == null) {
-            managementObjectNameStrategy = createManagementObjectNameStrategy(null);
-        }
         return managementObjectNameStrategy;
     }
 
@@ -116,9 +113,6 @@ public class DefaultManagementStrategy extends ServiceSupport implements Managem
 
     @Override
     public ManagementObjectStrategy getManagementObjectStrategy() {
-        if (managementObjectStrategy == null) {
-            managementObjectStrategy = createManagementObjectStrategy();
-        }
         return managementObjectStrategy;
     }
 
@@ -186,47 +180,46 @@ public class DefaultManagementStrategy extends ServiceSupport implements Managem
     }
 
     @Override
-    protected void doStart() throws Exception {
-        LOG.info("JMX is disabled");
+    protected void doInit() throws Exception {
+        LOG.info("JMX is enabled");
 
         ObjectHelper.notNull(getCamelContext(), "CamelContext", this);
         if (!getEventNotifiers().isEmpty()) {
             getCamelContext().adapt(ExtendedCamelContext.class).setEventNotificationApplicable(true);
         }
-
-        doStartManagementStrategy();
-    }
-
-    protected void doStartManagementStrategy() throws Exception {
-        ObjectHelper.notNull(camelContext, "CamelContext");
-
         for (EventNotifier notifier : eventNotifiers) {
-
             // inject CamelContext if the service is aware
             if (notifier instanceof CamelContextAware) {
                 CamelContextAware aware = (CamelContextAware) notifier;
                 aware.setCamelContext(camelContext);
             }
+        }
+        ServiceHelper.initService(eventNotifiers, managementAgent);
 
-            ServiceHelper.startService(notifier);
+        if (managementObjectStrategy == null) {
+            managementObjectStrategy = createManagementObjectStrategy();
+        }
+        if (managementObjectStrategy instanceof CamelContextAware) {
+            ((CamelContextAware) managementObjectStrategy).setCamelContext(getCamelContext());
         }
 
-        if (managementAgent != null) {
-            ServiceHelper.startService(managementAgent);
-            // set the naming strategy using the domain name from the agent
-            if (managementObjectNameStrategy == null) {
-                String domain = managementAgent.getMBeanObjectDomainName();
-                managementObjectNameStrategy = createManagementObjectNameStrategy(domain);
-            }
+        if (managementObjectNameStrategy == null) {
+            managementObjectNameStrategy = createManagementObjectNameStrategy();
         }
         if (managementObjectNameStrategy instanceof CamelContextAware) {
             ((CamelContextAware) managementObjectNameStrategy).setCamelContext(getCamelContext());
         }
+        ServiceHelper.initService(managementObjectStrategy, managementObjectNameStrategy);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        ServiceHelper.startService(eventNotifiers, managementAgent, managementObjectStrategy, managementObjectNameStrategy);
     }
 
     @Override
     protected void doStop() throws Exception {
-        ServiceHelper.stopService(managementAgent, eventNotifiers);
+        ServiceHelper.stopService(managementObjectNameStrategy, managementObjectStrategy, managementAgent, eventNotifiers);
     }
 
     protected ManagementObjectNameStrategy createManagementObjectNameStrategy(String domain) {
@@ -237,4 +230,9 @@ public class DefaultManagementStrategy extends ServiceSupport implements Managem
         return null;
     }
 
+    protected ManagementObjectNameStrategy createManagementObjectNameStrategy() {
+        String domain = managementAgent != null ? managementAgent.getMBeanObjectDomainName() : null;
+        return createManagementObjectNameStrategy(domain);
+    }
+
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java
index eac990f..b9adef5 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java
@@ -98,13 +98,4 @@ public class DefaultMessageHistoryFactory extends ServiceSupport implements Mess
         }
     }
 
-    @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        // noop
-    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanClassResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanClassResolver.java
index bbd7c92..6df8d5e 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanClassResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanClassResolver.java
@@ -450,11 +450,6 @@ public class DefaultPackageScanClassResolver extends BasePackageScanResolver imp
     }
 
     @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
     protected void doStop() throws Exception {
         clearCache();
     }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanResourceResolver.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanResourceResolver.java
index f814af6..7c7fef0 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanResourceResolver.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultPackageScanResourceResolver.java
@@ -300,7 +300,7 @@ public class DefaultPackageScanResourceResolver extends BasePackageScanResolver
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         ObjectHelper.notNull(getCamelContext(), "CamelContext", this);
     }
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerCache.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerCache.java
index 1db1029..d8da3c0 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerCache.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerCache.java
@@ -355,22 +355,30 @@ public class DefaultProducerCache extends ServiceSupport implements ProducerCach
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         if (extendedStatistics) {
             int max = maxCacheSize == 0 ? CamelContextHelper.getMaximumCachePoolSize(camelContext) : maxCacheSize;
             statistics = new DefaultEndpointUtilizationStatistics(max);
         }
-
-        ServiceHelper.startService(producers, statistics);
+        ServiceHelper.initService(producers);
     }
 
     @Override
-    protected void doStop() throws Exception {
-        // when stopping we intend to shutdown
-        ServiceHelper.stopAndShutdownServices(statistics, producers);
+    protected void doStart() throws Exception {
         if (statistics != null) {
             statistics.clear();
         }
+        ServiceHelper.startService(producers);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        ServiceHelper.stopService(producers);
+    }
+
+    @Override
+    protected void doShutdown() throws Exception {
+        ServiceHelper.stopAndShutdownServices(producers);
     }
 
     @Override
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerTemplate.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerTemplate.java
index d4bdd1e..02fcbc6 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerTemplate.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultProducerTemplate.java
@@ -777,51 +777,50 @@ public class DefaultProducerTemplate extends ServiceSupport implements ProducerT
         if (!isStarted()) {
             throw new IllegalStateException("ProducerTemplate has not been started");
         }
-
-        if (executor != null) {
-            return executor;
-        }
-
-        // create a default executor which must be synchronized
-        synchronized (this) {
-            if (executor != null) {
-                return executor;
-            }
-            if (!threadedAsyncMode) {
-                executor = new SynchronousExecutorService();
-            } else {
-                executor = camelContext.getExecutorServiceManager().newDefaultThreadPool(this, "ProducerTemplate");
+        if (executor == null) {
+            // create a default executor which must be synchronized
+            synchronized (lock) {
+                if (executor == null) {
+                    if (threadedAsyncMode) {
+                        executor = camelContext.getExecutorServiceManager().newDefaultThreadPool(this, "ProducerTemplate");
+                        ObjectHelper.notNull(executor, "ExecutorService");
+                    } else {
+                        executor = new SynchronousExecutorService();
+                    }
+                }
             }
         }
-
-        ObjectHelper.notNull(executor, "ExecutorService");
         return executor;
     }
 
     @Override
-    protected void doStart() throws Exception {
-        if (producerCache == null) {
-            producerCache = new DefaultProducerCache(this, camelContext, maximumCacheSize);
-            producerCache.setEventNotifierEnabled(isEventNotifierEnabled());
-        }
-
+    protected void doInit() throws Exception {
         // need to lookup default endpoint as it may have been intercepted
         if (defaultEndpoint != null) {
             defaultEndpoint = camelContext.getEndpoint(defaultEndpoint.getEndpointUri());
         }
+        producerCache = new DefaultProducerCache(this, camelContext, maximumCacheSize);
+        producerCache.setEventNotifierEnabled(isEventNotifierEnabled());
+        ServiceHelper.initService(producerCache);
+    }
 
+    @Override
+    protected void doStart() throws Exception {
         ServiceHelper.startService(producerCache);
     }
 
     @Override
     protected void doStop() throws Exception {
         ServiceHelper.stopService(producerCache);
-        producerCache = null;
-
         if (executor != null) {
             camelContext.getExecutorServiceManager().shutdownNow(executor);
             executor = null;
         }
     }
 
+    @Override
+    protected void doShutdown() throws Exception {
+        ServiceHelper.stopAndShutdownService(producerCache);
+        producerCache = null;
+    }
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultReactiveExecutor.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultReactiveExecutor.java
index dbba46e..406e21f 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultReactiveExecutor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultReactiveExecutor.java
@@ -86,11 +86,6 @@ public class DefaultReactiveExecutor extends ServiceSupport implements ReactiveE
     }
 
     @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
     protected void doStop() throws Exception {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Stopping DefaultReactiveExecutor [createdWorkers: {}, runningWorkers: {}, pendingTasks: {}]",
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
index d464456..b5a91ac 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
@@ -212,8 +212,6 @@ public class DefaultRoute extends ServiceSupport implements Route {
 
     @Override
     protected void doShutdown() throws Exception {
-        // and clear start date
-        startDate = null;
         // clear services when shutting down
         services.clear();
     }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
index 11d4eba..b0a3891 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRouteController.java
@@ -53,20 +53,6 @@ public class DefaultRouteController extends ServiceSupport implements RouteContr
     }
 
     // ***************************************************
-    // Life cycle
-    // ***************************************************
-
-    @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        // noop
-    }
-
-    // ***************************************************
     // Route management
     // ***************************************************
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRuntimeEndpointRegistry.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRuntimeEndpointRegistry.java
index 956c4726..0a1b851 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRuntimeEndpointRegistry.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRuntimeEndpointRegistry.java
@@ -186,7 +186,7 @@ public class DefaultRuntimeEndpointRegistry extends EventNotifierSupport impleme
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         ObjectHelper.notNull(camelContext, "camelContext", this);
 
         if (inputs == null) {
@@ -207,6 +207,11 @@ public class DefaultRuntimeEndpointRegistry extends EventNotifierSupport impleme
         } else {
             LOG.info("Runtime endpoint registry is in normal mode gathering information of all incoming and outgoing endpoints (cache limit: {})", limit);
         }
+        ServiceHelper.initService(inputUtilization, outputUtilization);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
         ServiceHelper.startService(inputUtilization, outputUtilization);
     }
 
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializedEvent.java b/core/camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializedEvent.java
new file mode 100644
index 0000000..a277459
--- /dev/null
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializedEvent.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.event;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.CamelEvent;
+
+public class CamelContextInitializedEvent extends AbstractContextEvent implements CamelEvent.CamelContextStartingEvent {
+    private static final long serialVersionUID = -3416082218670845373L;
+
+    public CamelContextInitializedEvent(CamelContext source) {
+        super(source);
+    }
+
+    @Override
+    public String toString() {
+        return "Initialized CamelContext: " + getContext().getName();
+    }
+}
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializingEvent.java b/core/camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializingEvent.java
new file mode 100644
index 0000000..9674817
--- /dev/null
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/event/CamelContextInitializingEvent.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.event;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.spi.CamelEvent;
+
+public class CamelContextInitializingEvent extends AbstractContextEvent implements CamelEvent.CamelContextStartingEvent {
+    private static final long serialVersionUID = 3931186946570864733L;
+
+    public CamelContextInitializingEvent(CamelContext source) {
+        super(source);
+    }
+
+    @Override
+    public String toString() {
+        return "Initializing CamelContext: " + getContext().getName();
+    }
+}
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/event/DefaultEventFactory.java b/core/camel-base/src/main/java/org/apache/camel/impl/event/DefaultEventFactory.java
index 7729788..3b2f22f 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/event/DefaultEventFactory.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/event/DefaultEventFactory.java
@@ -31,6 +31,16 @@ import org.apache.camel.spi.EventFactory;
 public class DefaultEventFactory implements EventFactory {
 
     @Override
+    public CamelEvent createCamelContextInitializingEvent(CamelContext context) {
+        return new CamelContextInitializingEvent(context);
+    }
+
+    @Override
+    public CamelEvent createCamelContextInitializedEvent(CamelContext context) {
+        return new CamelContextInitializedEvent(context);
+    }
+
+    @Override
     public CamelEvent createCamelContextStartingEvent(CamelContext context) {
         return new CamelContextStartingEvent(context);
     }
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/RemovePropertiesProcessor.java b/core/camel-base/src/main/java/org/apache/camel/processor/RemovePropertiesProcessor.java
index 042571a..8dffb58 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/RemovePropertiesProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/RemovePropertiesProcessor.java
@@ -87,13 +87,4 @@ public class RemovePropertiesProcessor extends AsyncProcessorSupport implements
         return excludePattern;
     }
 
-    @Override
-    protected void doStart() throws Exception {
-        // noop
-    }
-
-    @Override
-    protected void doStop() throws Exception {
-        // noop
-    }
 }
\ No newline at end of file
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/interceptor/DefaultDebugger.java b/core/camel-base/src/main/java/org/apache/camel/processor/interceptor/DefaultDebugger.java
index 319dc8e..4fb6cf2 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/interceptor/DefaultDebugger.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/interceptor/DefaultDebugger.java
@@ -331,7 +331,7 @@ public class DefaultDebugger extends ServiceSupport implements Debugger, CamelCo
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext", this);
 
         // must have message history enabled when using this debugger
@@ -340,8 +340,14 @@ public class DefaultDebugger extends ServiceSupport implements Debugger, CamelCo
         }
 
         // register our event notifier
-        ServiceHelper.startService(debugEventNotifier);
         camelContext.getManagementStrategy().addEventNotifier(debugEventNotifier);
+
+        ServiceHelper.initService(debugEventNotifier);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        ServiceHelper.startService(debugEventNotifier);
     }
 
     @Override
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/loadbalancer/LoadBalancerSupport.java b/core/camel-base/src/main/java/org/apache/camel/processor/loadbalancer/LoadBalancerSupport.java
index d098969..590bc46 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/loadbalancer/LoadBalancerSupport.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/loadbalancer/LoadBalancerSupport.java
@@ -112,6 +112,11 @@ public abstract class LoadBalancerSupport extends AsyncProcessorSupport implemen
     }
 
     @Override
+    protected void doInit() throws Exception {
+        ServiceHelper.initService((Object[]) processors.get());
+    }
+
+    @Override
     protected void doStart() throws Exception {
         ServiceHelper.startService((Object[]) processors.get());
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java
index 15a0077..4b15319 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java
@@ -26,6 +26,7 @@ import org.apache.camel.impl.engine.InterceptSendToMockEndpointStrategy;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.support.EndpointHelper;
 import org.apache.camel.support.PatternHelper;
 import org.apache.camel.util.ObjectHelper;
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/NotifyBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/NotifyBuilder.java
index c70a64e..a839dc7 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/NotifyBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/NotifyBuilder.java
@@ -96,7 +96,8 @@ public class NotifyBuilder {
         this.context = context;
         eventNotifier = new ExchangeNotifier();
         try {
-            ServiceHelper.startService(eventNotifier);
+            context.addService(eventNotifier, false);
+            eventNotifier.start();
         } catch (Exception e) {
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
         }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
index 5a0a9f5..21919db 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
@@ -147,12 +147,14 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam
      * Use one of the other constructors to force use an explicit registry.
      */
     public LightweightCamelContext() {
-        delegate = new DefaultCamelContext(false) {
+        DefaultCamelContext d = new DefaultCamelContext(false) {
             @Override
             public CamelContext getCamelContextReference() {
                 return LightweightCamelContext.this;
             }
         };
+        delegate = d;
+        d.build();
     }
 
     /**
@@ -217,6 +219,11 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam
     }
 
     @Override
+    public void build() {
+        delegate.build();
+    }
+
+    @Override
     public void init() {
         delegate.init();
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index 8971d9c..2e616ab 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -267,6 +267,11 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
     }
 
     @Override
+    public void build() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public void init() {
         throw new UnsupportedOperationException();
     }
@@ -288,6 +293,11 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
         for (Route route : routes) {
             route.getConsumer().start();
         }
+        if (LOG.isInfoEnabled()) {
+            long l = System.currentTimeMillis() - startDate.getTime();
+            LOG.info("Apache Camel {} (CamelContext: {}) {} routes started in {}",
+                    getVersion(), getName(), routes.size(), TimeUtils.printDuration(l));
+        }
     }
 
     @Override
diff --git a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 6cfb14f..9752c5b 100644
--- a/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/core/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -410,8 +410,6 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
 
         // init stream caching strategy
         initStreamCachingStrategy();
-
-        getContext().init();
     }
     //CHECKSTYLE:ON
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java b/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
index d641d62..49029e0 100644
--- a/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
+++ b/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
@@ -106,10 +106,18 @@ public abstract class ContextTestSupport extends TestSupport {
             throw new Exception("Context must be a ModelCamelContext");
         }
         assertValidContext(context);
-        context.init();
 
-        // reduce default shutdown timeout to avoid waiting for 300 seconds
-        context.getShutdownStrategy().setTimeout(10);
+        if (isUseRouteBuilder()) {
+            RouteBuilder[] builders = createRouteBuilders();
+            for (RouteBuilder builder : builders) {
+                log.debug("Using created route builder: {}", builder);
+                context.addRoutes(builder);
+            }
+            context.init();
+        } else {
+            log.debug("isUseRouteBuilder() is false");
+        }
+
 
         template = context.createProducerTemplate();
         template.start();
@@ -121,16 +129,11 @@ public abstract class ContextTestSupport extends TestSupport {
         oneExchangeDone = event().whenDone(1).create();
 
         if (isUseRouteBuilder()) {
-            RouteBuilder[] builders = createRouteBuilders();
-            for (RouteBuilder builder : builders) {
-                log.debug("Using created route builder: {}", builder);
-                context.addRoutes(builder);
-            }
             startCamelContext();
-        } else {
-            log.debug("isUseRouteBuilder() is false");
         }
 
+        // reduce default shutdown timeout to avoid waiting for 300 seconds
+        context.getShutdownStrategy().setTimeout(10);
     }
 
     @Override
@@ -202,7 +205,7 @@ public abstract class ContextTestSupport extends TestSupport {
             ctx.setRegistry(createRegistry());
             context = ctx;
         } else {
-            DefaultCamelContext ctx = new DefaultCamelContext(false);
+            DefaultCamelContext ctx = new DefaultCamelContext(true);
             ctx.setRegistry(createRegistry());
             context = ctx;
         }
diff --git a/core/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java b/core/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java
index 35f58f4..24a3e14 100644
--- a/core/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/builder/BuilderWithScopesTest.java
@@ -89,7 +89,7 @@ public class BuilderWithScopesTest extends TestSupport {
         order.clear();
         DefaultCamelContext container = new DefaultCamelContext(false);
         container.disableJMX();
-        container.init();
+        container.build();
 
         container.addRoutes(builder);
         container.start();
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
index 7a34a4c..bdb5fa1 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/MultipleLifecycleStrategyTest.java
@@ -48,9 +48,11 @@ public class MultipleLifecycleStrategyTest extends TestSupport {
         context.removeComponent("log");
         context.stop();
 
-        List<String> expectedEvents = Arrays.asList("onContextStart",
-            "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd",
+        List<String> expectedEvents = Arrays.asList(
+            "onServiceAdd", "onServiceAdd",
             "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd",
+            "onServiceAdd", "onServiceAdd", "onServiceAdd", "onServiceAdd",
+            "onContextStart",
             "onComponentAdd", "onEndpointAdd", "onComponentRemove", "onContextStop");
         
         assertEquals(expectedEvents, dummy1.getEvents());
diff --git a/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierIssueTest.java b/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierIssueTest.java
index 5b6635b..de4d5c6 100644
--- a/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierIssueTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierIssueTest.java
@@ -57,7 +57,6 @@ public class SentExchangeEventNotifierIssueTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierTwoIssueTest.java b/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierTwoIssueTest.java
index 81ccbe1..5f1f1c8 100644
--- a/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierTwoIssueTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/issues/SentExchangeEventNotifierTwoIssueTest.java
@@ -57,7 +57,6 @@ public class SentExchangeEventNotifierTwoIssueTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/EventNotifierExchangeSentExampleTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/EventNotifierExchangeSentExampleTest.java
index 0c79526..0c99012 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/EventNotifierExchangeSentExampleTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/EventNotifierExchangeSentExampleTest.java
@@ -27,7 +27,6 @@ public class EventNotifierExchangeSentExampleTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         DefaultCamelContext context = (DefaultCamelContext)super.createCamelContext();
-        context.init();
 
         // START SNIPPET: e1
         // add event notifier where we can log the times it took to process
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/ProducerTemplateDisableEventNotifierTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/ProducerTemplateDisableEventNotifierTest.java
index c6a9b89..9d53fc2 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/ProducerTemplateDisableEventNotifierTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/ProducerTemplateDisableEventNotifierTest.java
@@ -30,7 +30,6 @@ public class ProducerTemplateDisableEventNotifierTest extends ContextTestSupport
     @Override
     protected CamelContext createCamelContext() throws Exception {
         DefaultCamelContext context = (DefaultCamelContext)super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
index 48948ba..93c07ed 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/SplitterUseOriginalNotPropagateExceptionTest.java
@@ -32,7 +32,6 @@ public class SplitterUseOriginalNotPropagateExceptionTest extends ContextTestSup
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherAsyncUnhandledExceptionTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherAsyncUnhandledExceptionTest.java
index 59160aa..7af0e97 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherAsyncUnhandledExceptionTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherAsyncUnhandledExceptionTest.java
@@ -66,7 +66,6 @@ public class EnricherAsyncUnhandledExceptionTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext camelContext = super.createCamelContext();
-        camelContext.init();
         ShutdownStrategy shutdownStrategy = camelContext.getShutdownStrategy();
         camelContext.addComponent("async", new MyAsyncComponent());
         shutdownStrategy.setTimeout(1000);
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherSendEventTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherSendEventTest.java
index 47fb180..3a77bda 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherSendEventTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/enricher/EnricherSendEventTest.java
@@ -53,7 +53,6 @@ public class EnricherSendEventTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext camelContext = super.createCamelContext();
-        camelContext.init();
         ShutdownStrategy shutdownStrategy = camelContext.getShutdownStrategy();
         camelContext.addComponent("async", new MyAsyncComponent());
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/DynamicRouterEventNotifierTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/DynamicRouterEventNotifierTest.java
index fe5835b..7b49930 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/DynamicRouterEventNotifierTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/DynamicRouterEventNotifierTest.java
@@ -35,7 +35,6 @@ public class DynamicRouterEventNotifierTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RecipientListEventNotifierTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RecipientListEventNotifierTest.java
index 8cbcbac..fe6278d 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RecipientListEventNotifierTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RecipientListEventNotifierTest.java
@@ -32,7 +32,6 @@ public class RecipientListEventNotifierTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RoutingSlipEventNotifierTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RoutingSlipEventNotifierTest.java
index 922c2b4..0fe3d31 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RoutingSlipEventNotifierTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/routingslip/RoutingSlipEventNotifierTest.java
@@ -32,7 +32,6 @@ public class RoutingSlipEventNotifierTest extends ContextTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().addEventNotifier(notifier);
         return context;
     }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index 2493155..1679fcf 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -595,7 +595,7 @@ public abstract class BaseMainSupport extends BaseService {
 
     protected void postProcessCamelContext(CamelContext camelContext) throws Exception {
         // ensure camel is initialized
-        camelContext.init();
+        camelContext.build();
 
         configurePropertiesService(camelContext);
 
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
index 2a165cf..5d2d635 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
@@ -428,20 +428,26 @@ public class DefaultManagementAgent extends ServiceSupport implements Management
     }
 
     @Override
-    protected void doStart() throws Exception {
+    protected void doInit() throws Exception {
         ObjectHelper.notNull(camelContext, "CamelContext");
 
+        finalizeSettings();
+
+        assembler = camelContext.adapt(ExtendedCamelContext.class).getManagementMBeanAssembler();
+        if (assembler == null) {
+            assembler = new DefaultManagementMBeanAssembler(camelContext);
+        }
+        ServiceHelper.initService(assembler);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
         // create mbean server if is has not be injected.
         if (server == null) {
-            finalizeSettings();
             createMBeanServer();
         }
 
         // ensure assembler is started
-        assembler = camelContext.adapt(ExtendedCamelContext.class).getManagementMBeanAssembler();
-        if (assembler == null) {
-            assembler = new DefaultManagementMBeanAssembler(camelContext);
-        }
         ServiceHelper.startService(assembler);
 
         LOG.debug("Starting JMX agent on server: {}", getMBeanServer());
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
index eb9e61c..48a9d0b 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
@@ -125,7 +125,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     // the wrapped processors is for performance counters, which are in use for the created routes
     // when a route is removed, we should remove the associated processors from this map
     private final Map<Processor, KeyValueHolder<NamedNode, InstrumentationProcessor>> wrappedProcessors = new HashMap<>();
-    private final List<PreRegisterService> preServices = new ArrayList<>();
+    private final List<java.util.function.Consumer<JmxManagementLifecycleStrategy>> preServices = new ArrayList<>();
     private final TimerListenerManager loadTimer = new ManagedLoadTimer();
     private final TimerListenerManagerStartupListener loadTimerStartupListener = new TimerListenerManagerStartupListener();
     private volatile CamelContext camelContext;
@@ -145,13 +145,13 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
 
     // used for handing over pre-services between a provisional lifecycycle strategy
     // and then later the actual strategy to be used when using XML
-    List<PreRegisterService> getPreServices() {
+    List<java.util.function.Consumer<JmxManagementLifecycleStrategy>> getPreServices() {
         return preServices;
     }
 
     // used for handing over pre-services between a provisional lifecycycle strategy
     // and then later the actual strategy to be used when using XML
-    void addPreService(PreRegisterService preService) {
+    void addPreService(java.util.function.Consumer<JmxManagementLifecycleStrategy> preService) {
         preServices.add(preService);
     }
 
@@ -216,6 +216,9 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
         // set the name we are going to use
         context.setManagementName(managementName);
 
+        // yes we made it and are initialized
+        initialized = true;
+
         try {
             manageObject(mc);
         } catch (Exception e) {
@@ -224,9 +227,6 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
         }
 
-        // yes we made it and are initialized
-        initialized = true;
-
         if (mc instanceof ManagedCamelContext) {
             camelContextMBean = (ManagedCamelContext) mc;
         }
@@ -293,14 +293,8 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
         }
 
         LOG.debug("Registering {} pre registered services", preServices.size());
-        for (PreRegisterService pre : preServices) {
-            if (pre.getComponent() != null) {
-                onComponentAdd(pre.getName(), pre.getComponent());
-            } else if (pre.getEndpoint() != null) {
-                onEndpointAdd(pre.getEndpoint());
-            } else if (pre.getService() != null) {
-                onServiceAdd(pre.getCamelContext(), pre.getService(), pre.getRoute());
-            }
+        for (java.util.function.Consumer<JmxManagementLifecycleStrategy> pre : preServices) {
+            pre.accept(this);
         }
 
         // we are done so clear the list
@@ -352,9 +346,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
         // always register components as there are only a few of those
         if (!initialized) {
             // pre register so we can register later when we have been initialized
-            PreRegisterService pre = new PreRegisterService();
-            pre.onComponentAdd(name, component);
-            preServices.add(pre);
+            preServices.add(lf -> lf.onComponentAdd(name, component));
             return;
         }
         try {
@@ -390,9 +382,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     public void onEndpointAdd(Endpoint endpoint) {
         if (!initialized) {
             // pre register so we can register later when we have been initialized
-            PreRegisterService pre = new PreRegisterService();
-            pre.onEndpointAdd(endpoint);
-            preServices.add(pre);
+            preServices.add(lf -> lf.onEndpointAdd(endpoint));
             return;
         }
 
@@ -429,12 +419,10 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     }
 
     @Override
-    public void onServiceAdd(CamelContext context, Service service, org.apache.camel.Route route) {
+    public void onServiceAdd(CamelContext context, Service service, Route route) {
         if (!initialized) {
             // pre register so we can register later when we have been initialized
-            PreRegisterService pre = new PreRegisterService();
-            pre.onServiceAdd(context, service, route);
-            preServices.add(pre);
+            preServices.add(lf -> lf.onServiceAdd(camelContext, service, route));
             return;
         }
 
@@ -466,7 +454,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     }
 
     @Override
-    public void onServiceRemove(CamelContext context, Service service, org.apache.camel.Route route) {
+    public void onServiceRemove(CamelContext context, Service service, Route route) {
         // the agent hasn't been started
         if (!initialized) {
             return;
@@ -483,7 +471,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     }
 
     @SuppressWarnings("unchecked")
-    private Object getManagedObjectForService(CamelContext context, Service service, org.apache.camel.Route route) {
+    private Object getManagedObjectForService(CamelContext context, Service service, Route route) {
         // skip channel, UoW and dont double wrap instrumentation
         if (service instanceof Channel || service instanceof UnitOfWork || service instanceof InstrumentationProcessor) {
             return null;
@@ -575,7 +563,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
         return answer;
     }
 
-    private Object getManagedObjectForProcessor(CamelContext context, Processor processor, org.apache.camel.Route route) {
+    private Object getManagedObjectForProcessor(CamelContext context, Processor processor, Route route) {
         // a bit of magic here as the processors we want to manage have already been registered
         // in the wrapped processors map when Camel have instrumented the route on route initialization
         // so the idea is now to only manage the processors from the map
@@ -603,8 +591,8 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     }
 
     @Override
-    public void onRoutesAdd(Collection<org.apache.camel.Route> routes) {
-        for (org.apache.camel.Route route : routes) {
+    public void onRoutesAdd(Collection<Route> routes) {
+        for (Route route : routes) {
 
             // if we are starting CamelContext or either of the two options has been
             // enabled, then enlist the route as a known route
@@ -658,13 +646,13 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     }
 
     @Override
-    public void onRoutesRemove(Collection<org.apache.camel.Route> routes) {
+    public void onRoutesRemove(Collection<Route> routes) {
         // the agent hasn't been started
         if (!initialized) {
             return;
         }
 
-        for (org.apache.camel.Route route : routes) {
+        for (Route route : routes) {
             Object mr = getManagementObjectStrategy().getManagedObjectForRoute(camelContext, route);
 
             // skip unmanaged routes
@@ -690,6 +678,12 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
 
     @Override
     public void onErrorHandlerAdd(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerBuilder) {
+        if (!initialized) {
+            // pre register so we can register later when we have been initialized
+            preServices.add(lf -> lf.onErrorHandlerAdd(route, errorHandler, errorHandlerBuilder));
+            return;
+        }
+
         if (!shouldRegister(errorHandler, null)) {
             // avoid registering if not needed
             return;
@@ -730,6 +724,12 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
     public void onThreadPoolAdd(CamelContext camelContext, ThreadPoolExecutor threadPool, String id,
                                 String sourceId, String routeId, String threadPoolProfileId) {
 
+        if (!initialized) {
+            // pre register so we can register later when we have been initialized
+            preServices.add(lf -> lf.onThreadPoolAdd(camelContext, threadPool, id, sourceId, routeId, threadPoolProfileId));
+            return;
+        }
+
         if (!shouldRegister(threadPool, null)) {
             // avoid registering if not needed
             return;
@@ -778,10 +778,6 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
 
     @Override
     public void onRouteContextCreate(Route route) {
-        if (!initialized) {
-            return;
-        }
-
         // Create a map (ProcessorType -> PerformanceCounter)
         // to be passed to InstrumentationInterceptStrategy.
         Map<NamedNode, PerformanceCounter> registeredCounters = new HashMap<>();
@@ -808,9 +804,9 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
      *
      * @param routes the routes
      */
-    private void removeWrappedProcessorsForRoutes(Collection<org.apache.camel.Route> routes) {
+    private void removeWrappedProcessorsForRoutes(Collection<Route> routes) {
         // loop the routes, and remove the route associated wrapped processors, as they are no longer in use
-        for (org.apache.camel.Route route : routes) {
+        for (Route route : routes) {
             String id = route.getId();
 
             Iterator<KeyValueHolder<NamedNode, InstrumentationProcessor>> it = wrappedProcessors.values().iterator();
@@ -935,7 +931,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
      * @param route   an optional route the mbean is associated with, can be <tt>null</tt>
      * @return <tt>true</tt> to register, <tt>false</tt> to skip registering
      */
-    protected boolean shouldRegister(Object service, org.apache.camel.Route route) {
+    protected boolean shouldRegister(Object service, Route route) {
         // the agent hasn't been started
         if (!initialized) {
             return false;
@@ -950,7 +946,8 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
         }
 
         // always register if we are starting CamelContext
-        if (getCamelContext().getStatus().isStarting()) {
+        if (getCamelContext().getStatus().isStarting()
+                || getCamelContext().getStatus().isInitializing()) {
             return true;
         }
 
@@ -1029,7 +1026,15 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
         private Endpoint endpoint;
         private CamelContext camelContext;
         private Service service;
-        private org.apache.camel.Route route;
+        private Route route;
+        private java.util.function.Consumer<JmxManagementLifecycleStrategy> runnable;
+
+        public PreRegisterService() {
+        }
+
+        public PreRegisterService(java.util.function.Consumer<JmxManagementLifecycleStrategy> runnable) {
+            this.runnable = runnable;
+        }
 
         public void onComponentAdd(String name, Component component) {
             this.name = name;
@@ -1040,7 +1045,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
             this.endpoint = endpoint;
         }
 
-        public void onServiceAdd(CamelContext camelContext, Service service, org.apache.camel.Route route) {
+        public void onServiceAdd(CamelContext camelContext, Service service, Route route) {
             this.camelContext = camelContext;
             this.service = service;
             this.route = route;
@@ -1066,9 +1071,14 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li
             return service;
         }
 
-        public org.apache.camel.Route getRoute() {
+        public Route getRoute() {
             return route;
         }
+
+        public java.util.function.Consumer<JmxManagementLifecycleStrategy> getRunnable() {
+            return runnable;
+        }
+
     }
 
 }
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategy.java b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategy.java
index 5829801..f492a64 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategy.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategy.java
@@ -30,6 +30,9 @@ import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * A JMX capable {@link org.apache.camel.spi.ManagementStrategy} that Camel by default uses if possible.
  * <p/>
@@ -42,6 +45,8 @@ public class JmxManagementStrategy extends DefaultManagementStrategy {
 
     private static final Logger LOG = LoggerFactory.getLogger(JmxManagementStrategy.class);
 
+    private final List<Object> managed = new ArrayList<>();
+
     public JmxManagementStrategy() {
     }
 
@@ -53,6 +58,10 @@ public class JmxManagementStrategy extends DefaultManagementStrategy {
 
     @Override
     public void manageObject(Object managedObject) throws Exception {
+        if (!isStartingOrStarted()) {
+            managed.add(managedObject);
+            return;
+        }
         ObjectName objectName = getManagementObjectNameStrategy().getObjectName(managedObject);
         if (objectName != null) {
             getManagementAgent().register(managedObject, objectName);
@@ -61,6 +70,10 @@ public class JmxManagementStrategy extends DefaultManagementStrategy {
 
     @Override
     public void unmanageObject(Object managedObject) throws Exception {
+        if (!isStartingOrStarted()) {
+            managed.remove(managedObject);
+            return;
+        }
         ObjectName objectName = getManagementObjectNameStrategy().getObjectName(managedObject);
         if (objectName != null) {
             getManagementAgent().unregister(objectName);
@@ -99,14 +112,10 @@ public class JmxManagementStrategy extends DefaultManagementStrategy {
 
     @Override
     protected void doStart() throws Exception {
-        LOG.info("JMX is enabled");
-
-        ObjectHelper.notNull(getCamelContext(), "CamelContext", this);
-        if (!getEventNotifiers().isEmpty()) {
-            getCamelContext().adapt(ExtendedCamelContext.class).setEventNotificationApplicable(true);
+        super.doStart();
+        for (Object o : managed) {
+            manageObject(o);
         }
-
-        doStartManagementStrategy();
     }
 
     @Override
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategyFactory.java b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategyFactory.java
index ef4f9e7..0bddc12 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategyFactory.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementStrategyFactory.java
@@ -54,7 +54,7 @@ public class JmxManagementStrategyFactory implements ManagementStrategyFactory {
             // a bit of ugly code to handover pre registered services that has been add to an eager/provisional JmxManagementLifecycleStrategy
             // which is now re-placed with a new JmxManagementLifecycleStrategy that is based on the end user configured settings
             // and therefore will be in use
-            List<JmxManagementLifecycleStrategy.PreRegisterService> preServices = null;
+            List<java.util.function.Consumer<JmxManagementLifecycleStrategy>> preServices = null;
             JmxManagementLifecycleStrategy jmx = camelContext.getLifecycleStrategies().stream()
                     .filter(s -> s instanceof JmxManagementLifecycleStrategy)
                     .map(JmxManagementLifecycleStrategy.class::cast)
@@ -65,7 +65,7 @@ public class JmxManagementStrategyFactory implements ManagementStrategyFactory {
 
             if (preServices != null &&  !preServices.isEmpty() && lifecycle instanceof JmxManagementLifecycleStrategy) {
                 JmxManagementLifecycleStrategy existing = (JmxManagementLifecycleStrategy) lifecycle;
-                for (JmxManagementLifecycleStrategy.PreRegisterService pre : preServices) {
+                for (java.util.function.Consumer<JmxManagementLifecycleStrategy> pre : preServices) {
                     existing.addPreService(pre);
                 }
             }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/JmxInstrumentationOnlyRegisterProcessorWithCustomIdTest.java b/core/camel-management/src/test/java/org/apache/camel/management/JmxInstrumentationOnlyRegisterProcessorWithCustomIdTest.java
index bb48c72..325eb49 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/JmxInstrumentationOnlyRegisterProcessorWithCustomIdTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/JmxInstrumentationOnlyRegisterProcessorWithCustomIdTest.java
@@ -73,7 +73,6 @@ public class JmxInstrumentationOnlyRegisterProcessorWithCustomIdTest extends Con
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setOnlyRegisterProcessorWithCustomId(true);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextPropertiesTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextPropertiesTest.java
index 13bc1e8..51110d6 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextPropertiesTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextPropertiesTest.java
@@ -30,7 +30,6 @@ public class ManagedCamelContextPropertiesTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         // to force a different management name than the camel id
         context.getManagementNameStrategy().setNamePattern("19-#name#");
         return context;
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
index a1106cf..6830abe 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedCamelContextTest.java
@@ -34,7 +34,6 @@ public class ManagedCamelContextTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         // to force a different management name than the camel id
         context.getManagementNameStrategy().setNamePattern("19-#name#");
         return context;
@@ -42,7 +41,7 @@ public class ManagedCamelContextTest extends ManagementTestSupport {
 
     @Test
     public void testManagedCamelContextClient() throws Exception {
-        // JMX tests dont work well on AIX CI servers (hangs them)
+        // JMX tests don't work well on AIX CI servers (hangs them)
         if (isPlatform("aix")) {
             return;
         }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedDynamicRouterTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedDynamicRouterTest.java
index 3b678c7..a5586a1 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedDynamicRouterTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedDynamicRouterTest.java
@@ -32,7 +32,6 @@ public class ManagedDynamicRouterTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointUtilizationStatisticsTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointUtilizationStatisticsTest.java
index 1ce7489..4665b52 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointUtilizationStatisticsTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedEndpointUtilizationStatisticsTest.java
@@ -29,7 +29,6 @@ public class ManagedEndpointUtilizationStatisticsTest extends ManagementTestSupp
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext camelContext = super.createCamelContext();
-        camelContext.init();
         // turn on runtime statistics in extended mode
         camelContext.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return camelContext;
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedEnricherTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedEnricherTest.java
index e564351..f138804 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedEnricherTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedEnricherTest.java
@@ -32,7 +32,6 @@ public class ManagedEnricherTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternFixedTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternFixedTest.java
index f477a70..1ea5a0c 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternFixedTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternFixedTest.java
@@ -28,7 +28,6 @@ public class ManagedNamePatternFixedTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementNameStrategy().setNamePattern("cool");
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternIncludeHostNameTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternIncludeHostNameTest.java
index e8441a1..d0ab4b6 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternIncludeHostNameTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternIncludeHostNameTest.java
@@ -28,7 +28,7 @@ public class ManagedNamePatternIncludeHostNameTest extends ManagementTestSupport
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
+        context.getManagementStrategy().init();
         DefaultManagementObjectNameStrategy naming = (DefaultManagementObjectNameStrategy)context.getManagementStrategy().getManagementObjectNameStrategy();
         naming.setHostName("localhost");
         context.getManagementStrategy().getManagementAgent().setIncludeHostName(true);
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternTest.java
index 754cc5e..28209ef 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNamePatternTest.java
@@ -28,7 +28,6 @@ public class ManagedNamePatternTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementNameStrategy().setNamePattern("cool-#name#");
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
index e9d545e..3642872 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedNonManagedServiceTest.java
@@ -29,7 +29,7 @@ import org.junit.Test;
 
 public class ManagedNonManagedServiceTest extends ManagementTestSupport {
 
-    private static final int SERVICES = 10;
+    private static final int SERVICES = 11;
 
     @Test
     public void testService() throws Exception {
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedPollEnricherTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedPollEnricherTest.java
index 559f64f..e57cb34 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedPollEnricherTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedPollEnricherTest.java
@@ -32,7 +32,6 @@ public class ManagedPollEnricherTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRecipientListRegisterAlwaysTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRecipientListRegisterAlwaysTest.java
index 168530e..d756ad0 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRecipientListRegisterAlwaysTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRecipientListRegisterAlwaysTest.java
@@ -31,7 +31,6 @@ public class ManagedProducerRecipientListRegisterAlwaysTest extends ManagementTe
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setRegisterAlways(true);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
index dc68cdb..ac22496 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedProducerRouteAddRemoveRegisterAlwaysTest.java
@@ -28,12 +28,11 @@ import org.junit.Test;
 
 public class ManagedProducerRouteAddRemoveRegisterAlwaysTest extends ManagementTestSupport {
 
-    private static final int SERVICES = 10;
+    private static final int SERVICES = 11;
 
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setRegisterAlways(true);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRecipientListTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRecipientListTest.java
index ca86746..2383634 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRecipientListTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRecipientListTest.java
@@ -32,7 +32,6 @@ public class ManagedRecipientListTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
index 702ff39..fff6e2d 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRouteAddRemoveTest.java
@@ -33,7 +33,7 @@ import org.junit.Test;
  */
 public class ManagedRouteAddRemoveTest extends ManagementTestSupport {
     
-    private static final int SERVICES = 10;
+    private static final int SERVICES = 11;
 
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRoutingSlipTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRoutingSlipTest.java
index 7207f76..89ce72f 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedRoutingSlipTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedRoutingSlipTest.java
@@ -32,7 +32,6 @@ public class ManagedRoutingSlipTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedSanitizeTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedSanitizeTest.java
index 397bac2..49be27c 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedSanitizeTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedSanitizeTest.java
@@ -28,7 +28,6 @@ public class ManagedSanitizeTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setMask(true);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedSendDynamicProcessorTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedSendDynamicProcessorTest.java
index 78e8259..06ec234 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedSendDynamicProcessorTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedSendDynamicProcessorTest.java
@@ -32,7 +32,6 @@ public class ManagedSendDynamicProcessorTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedStartupFailedTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedStartupFailedTest.java
index 3e9f655..66da93c 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedStartupFailedTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedStartupFailedTest.java
@@ -77,7 +77,6 @@ public class ManagedStartupFailedTest extends ManagementTestSupport {
         }
 
         MBeanServer server = getMBeanServer();
-        Set<ObjectName> onames = server.queryNames(new ObjectName("org.apache.camel:*"), null);
-        assertEquals(Collections.emptySet(), onames);
+        assertNull(server);
     }
 }
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelOffTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelOffTest.java
index 78136d5..3a6bbae 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelOffTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelOffTest.java
@@ -32,7 +32,6 @@ public class ManagedStatisticsLevelOffTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         // disable it by default
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Off);
         return context;
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelRoutesOnlyTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelRoutesOnlyTest.java
index 6dd018e..32766bc 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelRoutesOnlyTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedStatisticsLevelRoutesOnlyTest.java
@@ -31,7 +31,6 @@ public class ManagedStatisticsLevelRoutesOnlyTest extends ManagementTestSupport
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         // only routes
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.RoutesOnly);
         return context;
diff --git a/core/camel-management/src/test/java/org/apache/camel/management/ManagedWireTapTest.java b/core/camel-management/src/test/java/org/apache/camel/management/ManagedWireTapTest.java
index e71f03e..8e0174b 100644
--- a/core/camel-management/src/test/java/org/apache/camel/management/ManagedWireTapTest.java
+++ b/core/camel-management/src/test/java/org/apache/camel/management/ManagedWireTapTest.java
@@ -32,7 +32,6 @@ public class ManagedWireTapTest extends ManagementTestSupport {
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
-        context.init();
         context.getManagementStrategy().getManagementAgent().setStatisticsLevel(ManagementStatisticsLevel.Extended);
         return context;
     }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ChildServiceSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/ChildServiceSupport.java
index c3bbb30..7fe1aed 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ChildServiceSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ChildServiceSupport.java
@@ -47,7 +47,7 @@ public abstract class ChildServiceSupport extends ServiceSupport {
                 return;
             }
             try {
-                initService(childServices);
+                ServiceHelper.initService(childServices);
             } catch (Exception e) {
                 status = FAILED;
                 LOG.trace("Error while initializing service: " + this, e);
@@ -124,25 +124,24 @@ public abstract class ChildServiceSupport extends ServiceSupport {
 
     protected void addChildService(Object childService) {
         if (childService instanceof Service) {
-            if (childServices == null) {
-                synchronized (lock) {
-                    if (childServices == null) {
-                        childServices = new ArrayList<>();
-                    }
+            synchronized (lock) {
+                if (childServices == null) {
+                    childServices = new ArrayList<>();
                 }
+                childServices.add((Service) childService);
             }
-            childServices.add((Service) childService);
         }
     }
 
     protected boolean removeChildService(Object childService) {
-        return childServices != null && childServices.remove(childService);
-    }
-
-    private void initService(List<Service> services) {
-        if (services != null) {
-            services.forEach(Service::init);
+        if (childService instanceof Service) {
+            synchronized (lock) {
+                if (childServices != null) {
+                    return childServices.remove(childService);
+                }
+            }
         }
+        return false;
     }
 
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java
index 4dd349a..31fc1a4 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/EventHelper.java
@@ -17,6 +17,9 @@
 package org.apache.camel.support;
 
 import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
@@ -69,202 +72,39 @@ public final class EventHelper {
         return true;
     }
 
-    public static boolean notifyCamelContextStarting(CamelContext context) {
-        ManagementStrategy management = context.getManagementStrategy();
-        if (management == null) {
-            return false;
-        }
-
-        EventFactory factory = management.getEventFactory();
-        if (factory == null) {
-            return false;
-        }
-
-        List<EventNotifier> notifiers = management.getEventNotifiers();
-        if (notifiers == null || notifiers.isEmpty()) {
-            return false;
-        }
+    public static boolean notifyCamelContextInitializing(CamelContext context) {
+        return notifyCamelContext(context, EventFactory::createCamelContextInitializingEvent);
+    }
 
-        boolean answer = false;
-        CamelEvent event = null;
-        for (EventNotifier notifier : notifiers) {
-            if (notifier.isDisabled()) {
-                continue;
-            }
-            if (notifier.isIgnoreCamelContextEvents()) {
-                continue;
-            }
+    public static boolean notifyCamelContextInitialized(CamelContext context) {
+        return notifyCamelContext(context, EventFactory::createCamelContextInitializedEvent);
+    }
 
-            if (event == null) {
-                // only create event once
-                event = factory.createCamelContextStartingEvent(context);
-                if (event == null) {
-                    // factory could not create event so exit
-                    return false;
-                }
-            }
-            answer |= doNotifyEvent(notifier, event);
-        }
-        return answer;
+    public static boolean notifyCamelContextStarting(CamelContext context) {
+        return notifyCamelContext(context, EventFactory::createCamelContextStartingEvent);
     }
 
     public static boolean notifyCamelContextStarted(CamelContext context) {
-        ManagementStrategy management = context.getManagementStrategy();
-        if (management == null) {
-            return false;
-        }
-
-        EventFactory factory = management.getEventFactory();
-        if (factory == null) {
-            return false;
-        }
-
-        List<EventNotifier> notifiers = management.getEventNotifiers();
-        if (notifiers == null || notifiers.isEmpty()) {
-            return false;
-        }
-
-        boolean answer = false;
-        CamelEvent event = null;
-        for (EventNotifier notifier : notifiers) {
-            if (notifier.isDisabled()) {
-                continue;
-            }
-            if (notifier.isIgnoreCamelContextEvents()) {
-                continue;
-            }
-
-            if (event == null) {
-                // only create event once
-                event = factory.createCamelContextStartedEvent(context);
-                if (event == null) {
-                    // factory could not create event so exit
-                    return false;
-                }
-            }
-            answer |= doNotifyEvent(notifier, event);
-        }
-        return answer;
+        return notifyCamelContext(context, EventFactory::createCamelContextStartedEvent);
     }
 
     public static boolean notifyCamelContextStartupFailed(CamelContext context, Throwable cause) {
-        ManagementStrategy management = context.getManagementStrategy();
-        if (management == null) {
-            return false;
-        }
-
-        EventFactory factory = management.getEventFactory();
-        if (factory == null) {
-            return false;
-        }
-
-        List<EventNotifier> notifiers = management.getEventNotifiers();
-        if (notifiers == null || notifiers.isEmpty()) {
-            return false;
-        }
-
-        boolean answer = false;
-        CamelEvent event = null;
-        for (EventNotifier notifier : notifiers) {
-            if (notifier.isDisabled()) {
-                continue;
-            }
-            if (notifier.isIgnoreCamelContextEvents()) {
-                continue;
-            }
-
-            if (event == null) {
-                // only create event once
-                event = factory.createCamelContextStartupFailureEvent(context, cause);
-                if (event == null) {
-                    // factory could not create event so exit
-                    return false;
-                }
-            }
-            answer |= doNotifyEvent(notifier, event);
-        }
-        return answer;
+        return notifyCamelContext(context, (ef, ctx) -> ef.createCamelContextStartupFailureEvent(ctx, cause));
     }
 
     public static boolean notifyCamelContextStopping(CamelContext context) {
-        ManagementStrategy management = context.getManagementStrategy();
-        if (management == null) {
-            return false;
-        }
-
-        EventFactory factory = management.getEventFactory();
-        if (factory == null) {
-            return false;
-        }
-
-        List<EventNotifier> notifiers = management.getEventNotifiers();
-        if (notifiers == null || notifiers.isEmpty()) {
-            return false;
-        }
-
-        boolean answer = false;
-        CamelEvent event = null;
-        for (EventNotifier notifier : notifiers) {
-            if (notifier.isDisabled()) {
-                continue;
-            }
-            if (notifier.isIgnoreCamelContextEvents()) {
-                continue;
-            }
-
-            if (event == null) {
-                // only create event once
-                event = factory.createCamelContextStoppingEvent(context);
-                if (event == null) {
-                    // factory could not create event so exit
-                    return false;
-                }
-            }
-            answer |= doNotifyEvent(notifier, event);
-        }
-        return answer;
+        return notifyCamelContext(context, EventFactory::createCamelContextStoppingEvent);
     }
 
     public static boolean notifyCamelContextStopped(CamelContext context) {
-        ManagementStrategy management = context.getManagementStrategy();
-        if (management == null) {
-            return false;
-        }
-
-        EventFactory factory = management.getEventFactory();
-        if (factory == null) {
-            return false;
-        }
-
-        List<EventNotifier> notifiers = management.getEventNotifiers();
-        if (notifiers == null || notifiers.isEmpty()) {
-            return false;
-        }
-
-        boolean answer = false;
-        CamelEvent event = null;
-        for (EventNotifier notifier : notifiers) {
-            if (notifier.isDisabled()) {
-                continue;
-            }
-            if (notifier.isIgnoreCamelContextEvents()) {
-                continue;
-            }
-
-            if (event == null) {
-                // only create event once
-                event = factory.createCamelContextStoppedEvent(context);
-                if (event == null) {
-                    // factory could not create event so exit
-                    return false;
-                }
-            }
-            answer |= doNotifyEvent(notifier, event);
-        }
-        return answer;
+        return notifyCamelContext(context, EventFactory::createCamelContextStoppedEvent);
     }
 
     public static boolean notifyCamelContextStopFailed(CamelContext context, Throwable cause) {
+        return notifyCamelContext(context, (ef, ctx) -> ef.createCamelContextStopFailureEvent(ctx, cause));
+    }
+
+    private static boolean notifyCamelContext(CamelContext context, BiFunction<EventFactory, CamelContext, CamelEvent> eventSupplier) {
         ManagementStrategy management = context.getManagementStrategy();
         if (management == null) {
             return false;
@@ -292,7 +132,7 @@ public final class EventHelper {
 
             if (event == null) {
                 // only create event once
-                event = factory.createCamelContextStopFailureEvent(context, cause);
+                event = eventSupplier.apply(factory, context);
                 if (event == null) {
                     // factory could not create event so exit
                     return false;
diff --git a/docs/components/modules/ROOT/pages/index.adoc b/docs/components/modules/ROOT/pages/index.adoc
index e058017..20180bf 100644
--- a/docs/components/modules/ROOT/pages/index.adoc
+++ b/docs/components/modules/ROOT/pages/index.adoc
@@ -684,6 +684,151 @@ Number of Components: 332 in 265 JAR artifacts (1 deprecated)
 |===
 // components: END
 
+== Data Formats
+
+// dataformats: START
+Number of Data Formats: 45 in 37 JAR artifacts (0 deprecated)
+
+[width="100%",cols="4,1,5",options="header"]
+|===
+| Data Format | Since | Description
+
+| xref:dataformats:any23-dataformat.adoc[Any23] (camel-any23) | 3.0 | Any23 data format is used for parsing data to RDF.
+
+| xref:dataformats:asn1-dataformat.adoc[ASN.1 File] (camel-asn1) | 2.20 | The ASN.1 data format is used for file transfer with telecommunications protocols.
+
+| xref:dataformats:avro-dataformat.adoc[Avro] (camel-avro) | 2.14 | The Avro data format is used for serialization and deserialization of messages using Apache Avro binary dataformat.
+
+| xref:dataformats:barcode-dataformat.adoc[Barcode] (camel-barcode) | 2.14 | The Barcode data format is used for creating barccode images (such as QR-Code)
+
+| xref:dataformats:base64-dataformat.adoc[Base64] (camel-base64) | 2.11 | The Base64 data format is used for base64 encoding and decoding.
+
+| xref:dataformats:beanio-dataformat.adoc[BeanIO] (camel-beanio) | 2.10 | The BeanIO data format is used for working with flat payloads (such as CSV, delimited, or fixed length formats).
+
+| xref:dataformats:bindy-dataformat.adoc[Bindy CSV] (camel-bindy) | 2.0 | The Bindy data format is used for working with flat payloads (such as CSV, delimited, fixed length formats, or FIX messages).
+
+| xref:dataformats:bindy-dataformat.adoc[Bindy Fixed Length] (camel-bindy) | 2.0 | The Bindy data format is used for working with flat payloads (such as CSV, delimited, fixed length formats, or FIX messages).
+
+| xref:dataformats:bindy-dataformat.adoc[Bindy Key Value Pair] (camel-bindy) | 2.0 | The Bindy data format is used for working with flat payloads (such as CSV, delimited, fixed length formats, or FIX messages).
+
+| xref:dataformats:cbor-dataformat.adoc[CBOR] (camel-cbor) | 3.0 | CBOR data format is used for unmarshal a CBOR payload to POJO or to marshal POJO back to CBOR payload.
+
+| xref:dataformats:crypto-dataformat.adoc[Crypto (Java Cryptographic Extension)] (camel-crypto) | 2.3 | Crypto data format is used for encrypting and decrypting of messages using Java Cryptographic Extension.
+
+| xref:dataformats:csv-dataformat.adoc[CSV] (camel-csv) | 1.3 | The CSV data format is used for handling CSV payloads.
+
+| xref:dataformats:fhirJson-dataformat.adoc[FHIR JSon] (camel-fhir) | 2.21 | The FHIR JSon data format is used to marshall/unmarshall to/from FHIR objects to/from JSON.
+
+| xref:dataformats:fhirXml-dataformat.adoc[FHIR XML] (camel-fhir) | 2.21 | The FHIR XML data format is used to marshall/unmarshall from/to FHIR objects to/from XML.
+
+| xref:dataformats:flatpack-dataformat.adoc[Flatpack] (camel-flatpack) | 2.1 | The Flatpack data format is used for working with flat payloads (such as CSV, delimited, or fixed length formats).
+
+| xref:dataformats:grok-dataformat.adoc[Grok] (camel-grok) | 3.0 | The Grok data format is used for unmarshalling unstructured data to objects using Logstash based Grok patterns.
+
+| xref:dataformats:gzipdeflater-dataformat.adoc[GZip Deflater] (camel-zip-deflater) | 2.0 | The GZip data format is a message compression and de-compression format (which works with the popular gzip/gunzip tools).
+
+| xref:dataformats:hl7-dataformat.adoc[HL7] (camel-hl7) | 2.0 | The HL7 data format can be used to marshal or unmarshal HL7 (Health Care) model objects.
+
+| xref:dataformats:ical-dataformat.adoc[iCal] (camel-ical) | 2.12 | The iCal dataformat is used for working with iCalendar messages.
+
+| xref:dataformats:jacksonxml-dataformat.adoc[JacksonXML] (camel-jacksonxml) | 2.16 | JacksonXML data format is used for unmarshal a XML payload to POJO or to marshal POJO back to XML payload.
+
+| xref:dataformats:jaxb-dataformat.adoc[JAXB] (camel-jaxb) | 1.0 | JAXB data format uses the JAXB2 XML marshalling standard to unmarshal an XML payload into Java objects or to marshal Java objects into an XML payload.
+
+| xref:dataformats:json-fastjson-dataformat.adoc[JSon Fastjson] (camel-fastjson) | 2.20 | JSon data format is used for unmarshal a JSon payload to POJO or to marshal POJO back to JSon payload.
+
+| xref:dataformats:json-gson-dataformat.adoc[JSon GSon] (camel-gson) | 2.10 | JSon data format is used for unmarshal a JSon payload to POJO or to marshal POJO back to JSon payload.
+
+| xref:dataformats:json-jackson-dataformat.adoc[JSon Jackson] (camel-jackson) | 2.0 | JSon data format is used for unmarshal a JSon payload to POJO or to marshal POJO back to JSon payload.
+
+| xref:dataformats:json-johnzon-dataformat.adoc[JSon Johnzon] (camel-johnzon) | 2.18 | JSon data format is used for unmarshal a JSon payload to POJO or to marshal POJO back to JSon payload.
+
+| xref:dataformats:json-xstream-dataformat.adoc[JSon XStream] (camel-xstream) | 2.0 | JSon data format is used for unmarshal a JSon payload to POJO or to marshal POJO back to JSon payload.
+
+| xref:dataformats:jsonApi-dataformat.adoc[JSonApi] (camel-jsonapi) | 3.0 | JSonApi data format is used for marshal and unmarshal Json API object.
+
+| xref:dataformats:lzf-dataformat.adoc[LZF Deflate Compression] (camel-lzf) | 2.17 | The LZF data format is a message compression and de-compression format (uses the LZF deflate algorithm).
+
+| xref:dataformats:mime-multipart-dataformat.adoc[MIME Multipart] (camel-mail) | 2.17 | The MIME Multipart data format is used for marshalling Camel messages with attachments into MIME-Multipart message, and vise-versa.
+
+| xref:dataformats:pgp-dataformat.adoc[PGP] (camel-crypto) | 2.9 | PGP data format is used for encrypting and decrypting of messages using Java Cryptographic Extension and PGP.
+
+| xref:dataformats:protobuf-dataformat.adoc[Protobuf] (camel-protobuf) | 2.2 | The Protobuf data format is used for serializing between Java objects and the Google Protobuf protocol.
+
+| xref:dataformats:rss-dataformat.adoc[RSS] (camel-rss) | 2.1 | RSS data format is used for working with RSS sync feed Java Objects and transforming to XML and vice-versa.
+
+| xref:dataformats:soapjaxb-dataformat.adoc[SOAP] (camel-soap) | 2.3 | SOAP is a data format which uses JAXB2 and JAX-WS annotations to marshal and unmarshal SOAP payloads.
+
+| xref:dataformats:syslog-dataformat.adoc[Syslog] (camel-syslog) | 2.6 | The Syslog dataformat is used for working with RFC3164 and RFC5424 messages (logging and monitoring).
+
+| xref:dataformats:tarfile-dataformat.adoc[Tar File] (camel-tarfile) | 2.16 | The Tar File data format is a message compression and de-compression format of tar files.
+
+| xref:dataformats:thrift-dataformat.adoc[Thrift] (camel-thrift) | 2.20 | The Thrift data format is used for serialization and deserialization of messages using Apache Thrift binary dataformat.
+
+| xref:dataformats:tidyMarkup-dataformat.adoc[TidyMarkup] (camel-tagsoup) | 2.0 | TidyMarkup data format is used for parsing HTML and return it as pretty well-formed HTML.
+
+| xref:dataformats:univocity-csv-dataformat.adoc[uniVocity CSV] (camel-univocity-parsers) | 2.15 | The uniVocity CSV data format is used for working with CSV (Comma Separated Values) flat payloads.
+
+| xref:dataformats:univocity-fixed-dataformat.adoc[uniVocity Fixed Length] (camel-univocity-parsers) | 2.15 | The uniVocity Fixed Length data format is used for working with fixed length flat payloads.
+
+| xref:dataformats:univocity-tsv-dataformat.adoc[uniVocity TSV] (camel-univocity-parsers) | 2.15 | The uniVocity TSV data format is used for working with TSV (Tabular Separated Values) flat payloads.
+
+| xref:dataformats:secureXML-dataformat.adoc[XML Security] (camel-xmlsecurity) | 2.0 | The XML Security data format facilitates encryption and decryption of XML payloads.
+
+| xref:dataformats:xstream-dataformat.adoc[XStream] (camel-xstream) | 1.3 | XStream data format is used for unmarshal a XML payload to POJO or to marshal POJO back to XML payload.
+
+| xref:dataformats:yaml-snakeyaml-dataformat.adoc[YAML SnakeYAML] (camel-snakeyaml) | 2.17 | YAML is a data format to marshal and unmarshal Java objects to and from YAML.
+
+| xref:dataformats:zipdeflater-dataformat.adoc[Zip Deflate Compression] (camel-zip-deflater) | 2.12 | Zip Deflate Compression data format is a message compression and de-compression format (not zip files).
+
+| xref:dataformats:zipfile-dataformat.adoc[Zip File] (camel-zipfile) | 2.11 | The Zip File data format is a message compression and de-compression format of zip files.
+|===
+// dataformats: END
+
+== Expression Languages
+
+// languages: START
+Number of Languages: 17 in 11 JAR artifacts (0 deprecated)
+
+[width="100%",cols="4,1,5",options="header"]
+|===
+| Language | Since | Description
+
+| xref:languages:bean-language.adoc[Bean method] (camel-bean) | 1.3 | To use a Java bean (aka method call) in Camel expressions or predicates.
+
+| xref:languages:constant-language.adoc[Constant] (camel-core-languages) | 1.5 | To use a constant value in Camel expressions or predicates. Important: this is a fixed constant value that is only set once during starting up the route, do not use this if you want dynamic values during routing.
+
+| xref:languages:exchangeProperty-language.adoc[ExchangeProperty] (camel-core-languages) | 2.0 | To use a Camel Exchange property in expressions or predicates.
+
+| xref:languages:file-language.adoc[File] (camel-core-languages) | 1.1 | For expressions and predicates using the file/simple language.
+
+| xref:languages:groovy-language.adoc[Groovy] (camel-groovy) | 1.3 | To use Groovy scripts in Camel expressions or predicates.
+
+| xref:languages:header-language.adoc[Header] (camel-core-languages) | 1.5 | To use a Camel Message header in expressions or predicates.
+
+| xref:languages:hl7terser-language.adoc[HL7 Terser] (camel-hl7) | 2.11 | To use HL7 terser scripts in Camel expressions or predicates.
+
+| xref:languages:jsonpath-language.adoc[JsonPath] (camel-jsonpath) | 2.13 | To use JsonPath in Camel expressions or predicates.
+
+| xref:languages:mvel-language.adoc[MVEL] (camel-mvel) | 2.0 | To use MVEL scripts in Camel expressions or predicates.
+
+| xref:languages:ognl-language.adoc[OGNL] (camel-ognl) | 1.1 | To use OGNL scripts in Camel expressions or predicates.
+
+| xref:languages:ref-language.adoc[Ref] (camel-core-languages) | 2.8 | Reference to an existing Camel expression or predicate, which is looked up from the Camel registry.
+
+| xref:languages:simple-language.adoc[Simple] (camel-core-languages) | 1.1 | To use Camels built-in Simple language in Camel expressions or predicates.
+
+| xref:languages:spel-language.adoc[SpEL] (camel-spring) | 2.7 | To use Spring Expression Language (SpEL) in Camel expressions or predicates.
+
+| xref:languages:tokenize-language.adoc[Tokenize] (camel-core-languages) | 2.0 | To use Camel message body or header with a tokenizer in Camel expressions or predicates.
+
+| xref:languages:xtokenize-language.adoc[XML Tokenize] (camel-xml-jaxp) | 2.14 | To use Camel message body or header with a XML tokenizer in Camel expressions or predicates.
+
+| xref:languages:xpath-language.adoc[XPath] (camel-xpath) | 1.1 | To use XPath (XML) in Camel expressions or predicates.
+
+| xref:languages:xquery-language.adoc[XQuery] (camel-saxon) | 1.0 | To use XQuery (XML) in Camel expressions or predicates.
+|===
+// languages: END
 
 == Miscellaneous Components
 


[camel] 02/11: Isolate org.apache.camel.reifier.* packages from model

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit cb507a0441fc3d9eb846e79ceb6baabf2bce67e8
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Tue Mar 17 06:53:36 2020 +0100

    Isolate org.apache.camel.reifier.* packages from model
---
 .../camel/builder/AdviceWithRouteBuilder.java      |  4 +-
 .../camel/builder/ErrorHandlerBuilderRef.java      |  3 ++
 .../org/apache/camel/builder/RouteBuilder.java     | 30 -------------
 .../apache/camel/builder/TransformerBuilder.java   |  4 +-
 .../org/apache/camel/builder/ValidatorBuilder.java |  4 +-
 .../org/apache/camel/impl/DefaultCamelContext.java | 52 ++++++++++++++++++++++
 .../camel/impl/lw/ImmutableCamelContext.java       | 29 ++++++++++++
 .../org/apache/camel/model/ModelCamelContext.java  | 15 +++++++
 .../org/apache/camel/model/RouteDefinition.java    |  3 +-
 .../camel/model/language/ExpressionDefinition.java | 10 +++--
 .../reifier/errorhandler/ErrorHandlerReifier.java  |  3 +-
 .../DefaultManagementObjectNameStrategy.java       |  2 +-
 12 files changed, 114 insertions(+), 45 deletions(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java
index 8c3bed3..15a0077 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/AdviceWithRouteBuilder.java
@@ -26,7 +26,6 @@ import org.apache.camel.impl.engine.InterceptSendToMockEndpointStrategy;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
-import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.support.EndpointHelper;
 import org.apache.camel.support.PatternHelper;
 import org.apache.camel.util.ObjectHelper;
@@ -89,8 +88,7 @@ public abstract class AdviceWithRouteBuilder extends RouteBuilder {
      */
     public static RouteDefinition adviceWith(CamelContext camelContext, Object routeId, ThrowingConsumer<AdviceWithRouteBuilder, Exception> builder) throws Exception {
         RouteDefinition rd = findRouteDefinition(camelContext, routeId);
-
-        return RouteReifier.adviceWith(rd, camelContext, new AdviceWithRouteBuilder() {
+        return camelContext.adapt(ModelCamelContext.class).adviceWith(rd, new AdviceWithRouteBuilder() {
             @Override
             public void configure() throws Exception {
                 builder.accept(this);
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
index 0a7a6bc..b3a6806 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
@@ -21,6 +21,9 @@ package org.apache.camel.builder;
  * reference
  */
 public class ErrorHandlerBuilderRef extends ErrorHandlerBuilderSupport {
+
+    public static final String DEFAULT_ERROR_HANDLER_BUILDER = "CamelDefaultErrorHandlerBuilder";
+
     private final String ref;
     private boolean supportTransacted;
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/RouteBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/RouteBuilder.java
index d12a951..f6e4fce 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/RouteBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/RouteBuilder.java
@@ -27,9 +27,6 @@ import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.Ordered;
 import org.apache.camel.Route;
 import org.apache.camel.RoutesBuilder;
-import org.apache.camel.ValueHolder;
-import org.apache.camel.impl.transformer.TransformerKey;
-import org.apache.camel.impl.validator.ValidatorKey;
 import org.apache.camel.model.FromDefinition;
 import org.apache.camel.model.InterceptDefinition;
 import org.apache.camel.model.InterceptFromDefinition;
@@ -42,15 +39,8 @@ import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.rest.RestConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
-import org.apache.camel.model.transformer.TransformerDefinition;
-import org.apache.camel.model.validator.ValidatorDefinition;
-import org.apache.camel.reifier.transformer.TransformerReifier;
-import org.apache.camel.reifier.validator.ValidatorReifier;
-import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.PropertiesComponent;
 import org.apache.camel.spi.RestConfiguration;
-import org.apache.camel.spi.Transformer;
-import org.apache.camel.spi.Validator;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.function.ThrowingConsumer;
@@ -554,16 +544,6 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         for (TransformerBuilder tdb : transformerBuilders) {
             tdb.configure(camelContext);
         }
-
-        // create and register transformers on transformer registry
-        for (TransformerDefinition def : camelContext.getExtension(Model.class).getTransformers()) {
-            Transformer transformer = TransformerReifier.reifier(camelContext, def).createTransformer();
-            camelContext.getTransformerRegistry().put(createTransformerKey(def), transformer);
-        }
-    }
-
-    private static ValueHolder<String> createTransformerKey(TransformerDefinition def) {
-        return ObjectHelper.isNotEmpty(def.getScheme()) ? new TransformerKey(def.getScheme()) : new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
     }
 
     protected void populateValidators() {
@@ -574,16 +554,6 @@ public abstract class RouteBuilder extends BuilderSupport implements RoutesBuild
         for (ValidatorBuilder vb : validatorBuilders) {
             vb.configure(camelContext);
         }
-
-        // create and register validators on validator registry
-        for (ValidatorDefinition def : camelContext.getExtension(Model.class).getValidators()) {
-            Validator validator = ValidatorReifier.reifier(camelContext, def).createValidator();
-            camelContext.getValidatorRegistry().put(createValidatorKey(def), validator);
-        }
-    }
-
-    private static ValidatorKey createValidatorKey(ValidatorDefinition def) {
-        return new ValidatorKey(new DataType(def.getType()));
     }
 
     public RestsDefinition getRestCollection() {
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/TransformerBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/TransformerBuilder.java
index f309911..d8fe794 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/TransformerBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/TransformerBuilder.java
@@ -18,7 +18,7 @@ package org.apache.camel.builder;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.model.DataFormatDefinition;
-import org.apache.camel.model.Model;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.transformer.CustomTransformerDefinition;
 import org.apache.camel.model.transformer.DataFormatTransformerDefinition;
 import org.apache.camel.model.transformer.EndpointTransformerDefinition;
@@ -188,6 +188,6 @@ public class TransformerBuilder {
         // force init of transformer registry
         camelContext.getTransformerRegistry();
 
-        camelContext.getExtension(Model.class).getTransformers().add(transformer);
+        camelContext.adapt(ModelCamelContext.class).registerTransformer(transformer);
     }
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ValidatorBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ValidatorBuilder.java
index 08d595b..631ba67 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ValidatorBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ValidatorBuilder.java
@@ -19,7 +19,7 @@ package org.apache.camel.builder;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
-import org.apache.camel.model.Model;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.validator.CustomValidatorDefinition;
 import org.apache.camel.model.validator.EndpointValidatorDefinition;
@@ -169,6 +169,6 @@ public class ValidatorBuilder {
         camelContext.getValidatorRegistry();
 
         validator.setType(type);
-        camelContext.getExtension(Model.class).getValidators().add(validator);
+        camelContext.adapt(ModelCamelContext.class).registerValidator(validator);
     }
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 5321734..e4fa1d7 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -25,14 +25,20 @@ import java.util.Map;
 import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
 import org.apache.camel.FailedToStartRouteException;
 import org.apache.camel.Navigate;
+import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
+import org.apache.camel.ValueHolder;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.health.HealthCheckRegistry;
 import org.apache.camel.impl.engine.DefaultRoute;
 import org.apache.camel.impl.engine.RouteService;
 import org.apache.camel.impl.engine.SimpleCamelContext;
+import org.apache.camel.impl.transformer.TransformerKey;
+import org.apache.camel.impl.validator.ValidatorKey;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.HystrixConfigurationDefinition;
 import org.apache.camel.model.Model;
@@ -42,6 +48,7 @@ import org.apache.camel.model.Resilience4jConfigurationDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteDefinitionHelper;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
+import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
@@ -49,12 +56,19 @@ import org.apache.camel.processor.channel.DefaultChannel;
 import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.reifier.dataformat.DataFormatReifier;
 import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
+import org.apache.camel.reifier.language.ExpressionReifier;
+import org.apache.camel.reifier.transformer.TransformerReifier;
+import org.apache.camel.reifier.validator.ValidatorReifier;
 import org.apache.camel.spi.BeanRepository;
 import org.apache.camel.spi.DataFormat;
+import org.apache.camel.spi.DataType;
 import org.apache.camel.spi.ExecutorServiceManager;
 import org.apache.camel.spi.Registry;
+import org.apache.camel.spi.Transformer;
+import org.apache.camel.spi.Validator;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultRegistry;
+import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -404,4 +418,42 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
                 .createErrorHandler(processor);
     }
 
+    @Override
+    public Expression createExpression(ExpressionDefinition definition) {
+        return ExpressionReifier.reifier(this, definition).createExpression();
+    }
+
+    @Override
+    public Predicate createPredicate(ExpressionDefinition definition) {
+        return ExpressionReifier.reifier(this, definition).createPredicate();
+    }
+
+    @Override
+    public RouteDefinition adviceWith(RouteDefinition definition, AdviceWithRouteBuilder builder) throws Exception {
+        return RouteReifier.adviceWith(definition, this, builder);
+    }
+
+    @Override
+    public void registerValidator(ValidatorDefinition def) {
+        model.getValidators().add(def);
+        Validator validator = ValidatorReifier.reifier(this, def).createValidator();
+        getValidatorRegistry().put(createValidatorKey(def), validator);
+    }
+
+    private static ValueHolder<String> createValidatorKey(ValidatorDefinition def) {
+        return new ValidatorKey(new DataType(def.getType()));
+    }
+
+
+    @Override
+    public void registerTransformer(TransformerDefinition def) {
+        model.getTransformers().add(def);
+        Transformer transformer = TransformerReifier.reifier(this, def).createTransformer();
+        getTransformerRegistry().put(createTransformerKey(def), transformer);
+    }
+
+    private static ValueHolder<String> createTransformerKey(TransformerDefinition def) {
+        return ObjectHelper.isNotEmpty(def.getScheme()) ? new TransformerKey(def.getScheme()) : new TransformerKey(new DataType(def.getFromType()), new DataType(def.getToType()));
+    }
+
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
index 2974e2f..62537e4 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
@@ -34,10 +34,12 @@ import org.apache.camel.ConsumerTemplate;
 import org.apache.camel.Endpoint;
 import org.apache.camel.ErrorHandlerFactory;
 import org.apache.camel.Experimental;
+import org.apache.camel.Expression;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.FluentProducerTemplate;
 import org.apache.camel.GlobalEndpointConfiguration;
 import org.apache.camel.NoSuchLanguageException;
+import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.Route;
@@ -48,6 +50,7 @@ import org.apache.camel.ShutdownRunningTask;
 import org.apache.camel.StartupListener;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.ValueHolder;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.model.DataFormatDefinition;
@@ -57,6 +60,7 @@ import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.Resilience4jConfigurationDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
+import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
@@ -1636,6 +1640,31 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
         return getModelCamelContext().getRouteFilter();
     }
 
+    @Override
+    public Expression createExpression(ExpressionDefinition definition) {
+        return getModelCamelContext().createExpression(definition);
+    }
+
+    @Override
+    public Predicate createPredicate(ExpressionDefinition definition) {
+        return getModelCamelContext().createPredicate(definition);
+    }
+
+    @Override
+    public RouteDefinition adviceWith(RouteDefinition definition, AdviceWithRouteBuilder builder) throws Exception {
+        return getModelCamelContext().adviceWith(definition, builder);
+    }
+
+    @Override
+    public void registerValidator(ValidatorDefinition validator) {
+        getModelCamelContext().registerValidator(validator);
+    }
+
+    @Override
+    public void registerTransformer(TransformerDefinition transformer) {
+        getModelCamelContext().registerTransformer(transformer);
+    }
+
     //
     // Immutable
     //
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java
index ea3eafb..4bf7672 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/ModelCamelContext.java
@@ -19,6 +19,12 @@ package org.apache.camel.model;
 import java.util.List;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
+import org.apache.camel.Predicate;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.model.language.ExpressionDefinition;
+import org.apache.camel.model.transformer.TransformerDefinition;
+import org.apache.camel.model.validator.ValidatorDefinition;
 
 /**
  * Model level interface for the {@link CamelContext}
@@ -32,4 +38,13 @@ public interface ModelCamelContext extends CamelContext, Model {
 
     void startRouteDefinitions(List<RouteDefinition> routeDefinitions) throws Exception;
 
+    Expression createExpression(ExpressionDefinition definition);
+
+    Predicate createPredicate(ExpressionDefinition definition);
+
+    RouteDefinition adviceWith(RouteDefinition definition, AdviceWithRouteBuilder builder) throws Exception;
+
+    void registerValidator(ValidatorDefinition validator);
+
+    void registerTransformer(TransformerDefinition transformer);
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/RouteDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/RouteDefinition.java
index e7f194c..8968a34 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -40,7 +40,6 @@ import org.apache.camel.builder.EndpointConsumerBuilder;
 import org.apache.camel.builder.ErrorHandlerBuilderRef;
 import org.apache.camel.model.rest.RestBindingDefinition;
 import org.apache.camel.model.rest.RestDefinition;
-import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.AsEndpointUri;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RoutePolicy;
@@ -938,7 +937,7 @@ public class RouteDefinition extends OutputDefinition<RouteDefinition> implement
         }
 
         // return a reference to the default error handler
-        return new ErrorHandlerBuilderRef(ErrorHandlerReifier.DEFAULT_ERROR_HANDLER_BUILDER);
+        return new ErrorHandlerBuilderRef(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER);
     }
 
     public ErrorHandlerFactory getErrorHandlerFactory() {
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
index 6676439..d2326b7 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
@@ -32,7 +32,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionFactory;
 import org.apache.camel.Predicate;
-import org.apache.camel.reifier.language.ExpressionReifier;
+import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.util.CollectionStringBuffer;
 import org.apache.camel.util.ObjectHelper;
@@ -192,7 +192,11 @@ public class ExpressionDefinition implements Expression, Predicate, ExpressionFa
 
     @Override
     public Expression createExpression(CamelContext camelContext) {
-        return ExpressionReifier.reifier(camelContext, this).createExpression();
+        return camelContext.adapt(ModelCamelContext.class).createExpression(this);
+    }
+
+    public Predicate createPredicate(CamelContext camelContext) {
+        return camelContext.adapt(ModelCamelContext.class).createPredicate(this);
     }
 
     //
@@ -215,7 +219,7 @@ public class ExpressionDefinition implements Expression, Predicate, ExpressionFa
     @Override
     public boolean matches(Exchange exchange) {
         if (predicate == null) {
-            predicate = ExpressionReifier.reifier(exchange.getContext(), this).createPredicate();
+            predicate = createPredicate(exchange.getContext());
         }
         ObjectHelper.notNull(predicate, "predicate");
         return predicate.matches(exchange);
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
index 5a67899..c74447d 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
@@ -52,7 +52,6 @@ import org.apache.camel.util.ObjectHelper;
 
 public abstract class ErrorHandlerReifier<T extends ErrorHandlerBuilderSupport> extends AbstractReifier {
 
-    public static final String DEFAULT_ERROR_HANDLER_BUILDER = "CamelDefaultErrorHandlerBuilder";
     private static final Map<Class<?>, BiFunction<Route, ErrorHandlerFactory, ErrorHandlerReifier<? extends ErrorHandlerFactory>>> ERROR_HANDLERS;
     static {
         Map<Class<?>, BiFunction<Route, ErrorHandlerFactory, ErrorHandlerReifier<? extends ErrorHandlerFactory>>> map = new HashMap<>();
@@ -248,7 +247,7 @@ public abstract class ErrorHandlerReifier<T extends ErrorHandlerBuilderSupport>
      * TransactedErrorHandlerBuilder in camel-spring.
      */
     public static boolean isErrorHandlerFactoryConfigured(String ref) {
-        return !DEFAULT_ERROR_HANDLER_BUILDER.equals(ref);
+        return !ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER.equals(ref);
     }
 
     public void addExceptionPolicy(ErrorHandlerSupport handlerSupport, OnExceptionDefinition exceptionType) {
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectNameStrategy.java b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectNameStrategy.java
index e4e69ee..9c7cb3d 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectNameStrategy.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementObjectNameStrategy.java
@@ -326,7 +326,7 @@ public class DefaultManagementObjectNameStrategy implements ManagementObjectName
             if (builder instanceof ErrorHandlerBuilderRef) {
                 builderRef = (ErrorHandlerBuilderRef) builder;
                 // does it refer to a non default error handler then do a 2nd lookup
-                if (!builderRef.getRef().equals(ErrorHandlerReifier.DEFAULT_ERROR_HANDLER_BUILDER)) {
+                if (!builderRef.getRef().equals(ErrorHandlerBuilderRef.DEFAULT_ERROR_HANDLER_BUILDER)) {
                     refBuilder = ErrorHandlerReifier.lookupErrorHandlerFactory(route, builderRef.getRef(), false);
                     if (refBuilder != null) {
                         ref = builderRef.getRef();


[camel] 08/11: Support lightweight mode in enrichers

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 8a30982f6c5a908292834089b11c493bbf836a77
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Thu Mar 19 08:14:22 2020 +0100

    Support lightweight mode in enrichers
---
 .../java/org/apache/camel/processor/Enricher.java  |   2 +-
 .../org/apache/camel/processor/PollEnricher.java   |  43 ++++--
 .../org/apache/camel/model/ExpressionNode.java     |  20 +--
 .../apache/camel/reifier/PollEnrichReifier.java    |  15 +-
 .../camel/impl/lw/EnricherLightweightTest.java     |  59 ++++++++
 .../camel/impl/lw/PollEnricherLightweightTest.java | 152 +++++++++++++++++++++
 .../org/apache/camel/support/ExchangeHelper.java   |  36 ++++-
 7 files changed, 304 insertions(+), 23 deletions(-)

diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/Enricher.java b/core/camel-base/src/main/java/org/apache/camel/processor/Enricher.java
index 9a5615e..186ff1c 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/Enricher.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/Enricher.java
@@ -360,7 +360,7 @@ public class Enricher extends AsyncProcessorSupport implements IdAware, RouteIdA
         if (recipient != null) {
             if (recipient instanceof NormalizedEndpointUri) {
                 NormalizedEndpointUri nu = (NormalizedEndpointUri) recipient;
-                ExtendedCamelContext ecc = (ExtendedCamelContext) exchange.getContext();
+                ExtendedCamelContext ecc = exchange.getContext().adapt(ExtendedCamelContext.class);
                 return ecc.hasEndpoint(nu);
             } else {
                 String uri = recipient.toString();
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/PollEnricher.java b/core/camel-base/src/main/java/org/apache/camel/processor/PollEnricher.java
index 9483665..659bbf9 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/PollEnricher.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/PollEnricher.java
@@ -69,6 +69,7 @@ public class PollEnricher extends AsyncProcessorSupport implements IdAware, Rout
     private String routeId;
     private AggregationStrategy aggregationStrategy;
     private final Expression expression;
+    private final String destination;
     private long timeout;
     private boolean aggregateOnException;
     private int cacheSize;
@@ -82,6 +83,19 @@ public class PollEnricher extends AsyncProcessorSupport implements IdAware, Rout
      */
     public PollEnricher(Expression expression, long timeout) {
         this.expression = expression;
+        this.destination = null;
+        this.timeout = timeout;
+    }
+
+    /**
+     * Creates a new {@link PollEnricher}.
+     *
+     * @param destination the endpoint to poll from.
+     * @param timeout timeout in millis
+     */
+    public PollEnricher(String destination, long timeout) {
+        this.expression = null;
+        this.destination = destination;
         this.timeout = timeout;
     }
 
@@ -183,6 +197,18 @@ public class PollEnricher extends AsyncProcessorSupport implements IdAware, Rout
         this.ignoreInvalidEndpoint = ignoreInvalidEndpoint;
     }
 
+    @Override
+    protected void doInit() throws Exception {
+        if (destination != null) {
+            Endpoint endpoint = getExistingEndpoint(camelContext, destination);
+            if (endpoint == null) {
+                endpoint = resolveEndpoint(camelContext, destination, cacheSize < 0);
+            }
+        } else if (expression != null) {
+            expression.init(camelContext);
+        }
+    }
+
     /**
      * Enriches the input data (<code>exchange</code>) by first obtaining
      * additional data from an endpoint represented by an endpoint
@@ -213,11 +239,11 @@ public class PollEnricher extends AsyncProcessorSupport implements IdAware, Rout
         Object recipient = null;
         boolean prototype = cacheSize < 0;
         try {
-            recipient = expression.evaluate(exchange, Object.class);
+            recipient = destination != null ? destination : expression.evaluate(exchange, Object.class);
             recipient = prepareRecipient(exchange, recipient);
-            Endpoint existing = getExistingEndpoint(exchange, recipient);
+            Endpoint existing = getExistingEndpoint(camelContext, recipient);
             if (existing == null) {
-                endpoint = resolveEndpoint(exchange, recipient, prototype);
+                endpoint = resolveEndpoint(camelContext, recipient, prototype);
             } else {
                 endpoint = existing;
                 // we have an existing endpoint then its not a prototype scope
@@ -369,25 +395,26 @@ public class PollEnricher extends AsyncProcessorSupport implements IdAware, Rout
         return null;
     }
 
-    protected static Endpoint getExistingEndpoint(Exchange exchange, Object recipient) {
+    protected static Endpoint getExistingEndpoint(CamelContext context, Object recipient) {
         if (recipient instanceof Endpoint) {
             return (Endpoint) recipient;
         }
         if (recipient != null) {
             if (recipient instanceof NormalizedEndpointUri) {
                 NormalizedEndpointUri nu = (NormalizedEndpointUri) recipient;
-                ExtendedCamelContext ecc = (ExtendedCamelContext) exchange.getContext();
+                ExtendedCamelContext ecc = context.adapt(ExtendedCamelContext.class);
                 return ecc.hasEndpoint(nu);
             } else {
                 String uri = recipient.toString();
-                return exchange.getContext().hasEndpoint(uri);
+                return context.hasEndpoint(uri);
             }
         }
         return null;
     }
 
-    protected static Endpoint resolveEndpoint(Exchange exchange, Object recipient, boolean prototype) {
-        return prototype ? ExchangeHelper.resolvePrototypeEndpoint(exchange, recipient) : ExchangeHelper.resolveEndpoint(exchange, recipient);
+    protected static Endpoint resolveEndpoint(CamelContext camelContext, Object recipient, boolean prototype) {
+        return prototype ? ExchangeHelper.resolvePrototypeEndpoint(camelContext, recipient)
+                : ExchangeHelper.resolveEndpoint(camelContext, recipient);
     }
 
     /**
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNode.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNode.java
index 92aec4e..5a0bdf8 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNode.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/ExpressionNode.java
@@ -48,19 +48,15 @@ public abstract class ExpressionNode extends ProcessorDefinition<ExpressionNode>
     }
 
     public ExpressionNode(ExpressionDefinition expression) {
-        this.expression = expression;
+        setExpression(expression);
     }
 
     public ExpressionNode(Expression expression) {
-        if (expression != null) {
-            setExpression(ExpressionNodeHelper.toExpressionDefinition(expression));
-        }
+        setExpression(expression);
     }
 
     public ExpressionNode(Predicate predicate) {
-        if (predicate != null) {
-            setExpression(ExpressionNodeHelper.toExpressionDefinition(predicate));
-        }
+        setExpression(predicate);
     }
 
     public ExpressionDefinition getExpression() {
@@ -68,7 +64,15 @@ public abstract class ExpressionNode extends ProcessorDefinition<ExpressionNode>
     }
 
     public void setExpression(Expression expression) {
-        setExpression(new ExpressionDefinition(expression));
+        if (expression != null) {
+            setExpression(ExpressionNodeHelper.toExpressionDefinition(expression));
+        }
+    }
+
+    private void setExpression(Predicate predicate) {
+        if (predicate != null) {
+            setExpression(ExpressionNodeHelper.toExpressionDefinition(predicate));
+        }
     }
 
     public void setExpression(ExpressionDefinition expression) {
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java
index ec310c4..ea411b5 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/PollEnrichReifier.java
@@ -18,13 +18,16 @@ package org.apache.camel.reifier;
 
 import org.apache.camel.AggregationStrategy;
 import org.apache.camel.CamelContextAware;
+import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.model.PollEnrichDefinition;
 import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.model.language.ConstantExpression;
 import org.apache.camel.processor.PollEnricher;
 import org.apache.camel.processor.aggregate.AggregationStrategyBeanAdapter;
+import org.apache.camel.support.DefaultExchange;
 
 public class PollEnrichReifier extends ProcessorReifier<PollEnrichDefinition> {
 
@@ -38,9 +41,17 @@ public class PollEnrichReifier extends ProcessorReifier<PollEnrichDefinition> {
         // if no timeout then we should block, and there use a negative timeout
         long time = definition.getTimeout() != null ? parseLong(definition.getTimeout()) : -1;
         boolean isIgnoreInvalidEndpoint = parseBoolean(definition.getIgnoreInvalidEndpoint(), false);
-        Expression exp = createExpression(definition.getExpression());
 
-        PollEnricher enricher = new PollEnricher(exp, time);
+        PollEnricher enricher;
+        if (definition.getExpression() instanceof ConstantExpression) {
+            Expression exp = createExpression(definition.getExpression());
+            Exchange ex = new DefaultExchange(camelContext);
+            String dest = exp.evaluate(ex, String.class);
+            enricher = new PollEnricher(dest, time);
+        } else {
+            Expression exp = createExpression(definition.getExpression());
+            enricher = new PollEnricher(exp, time);
+        }
 
         AggregationStrategy strategy = createAggregationStrategy();
         if (strategy == null) {
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/lw/EnricherLightweightTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/lw/EnricherLightweightTest.java
new file mode 100644
index 0000000..b1ca671
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/lw/EnricherLightweightTest.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.lw;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EnricherLightweightTest extends ContextTestSupport {
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        setUseLightweightContext(true);
+        super.setUp();
+    }
+
+    @Test
+    public void testEnrich() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:enriched");
+        mock.expectedBodiesReceived("res-1", "res-2", "res-3");
+
+        template.sendBody("direct:start", 1);
+        template.sendBody("direct:start", 2);
+        template.sendBody("direct:start", 3);
+
+        mock.assertIsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").enrichWith("direct:resource")
+                        .body(Integer.class, String.class, (o, n) -> n + o).to("mock:enriched");
+
+                // set an empty message
+                from("direct:resource").transform().body(b -> "res-");
+            }
+        };
+    }
+}
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/lw/PollEnricherLightweightTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/lw/PollEnricherLightweightTest.java
new file mode 100644
index 0000000..e7142bc
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/lw/PollEnricherLightweightTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.lw;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.processor.enricher.SampleAggregator;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PollEnricherLightweightTest extends ContextTestSupport {
+
+    private static SampleAggregator aggregationStrategy = new SampleAggregator();
+
+    protected MockEndpoint mock;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        setUseLightweightContext(true);
+        super.setUp();
+        mock = getMockEndpoint("mock:mock");
+    }
+
+    // -------------------------------------------------------------
+    // InOnly routes
+    // -------------------------------------------------------------
+
+    @Test
+    public void testPollEnrichInOnly() throws InterruptedException {
+        template.sendBody("seda:foo1", "blah");
+
+        mock.expectedBodiesReceived("test:blah");
+        mock.expectedHeaderReceived(Exchange.TO_ENDPOINT, "seda://foo1");
+
+        template.sendBody("direct:enricher-test-1", "test");
+
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testPollEnrichInOnlyWaitWithTimeout() throws InterruptedException {
+        // this first try there is no data so we timeout
+        mock.expectedBodiesReceived("test:blah");
+        mock.expectedHeaderReceived(Exchange.TO_ENDPOINT, "seda://foo2");
+        template.sendBody("direct:enricher-test-2", "test");
+        // not expected data so we are not happy
+        mock.assertIsNotSatisfied();
+
+        // now send it and try again
+        mock.reset();
+        template.sendBody("seda:foo2", "blah");
+        template.sendBody("direct:enricher-test-2", "test");
+        mock.assertIsSatisfied();
+    }
+
+    @Test
+    public void testPollEnrichInOnlyWaitNoTimeout() throws InterruptedException {
+        // use another thread to send it a bit later
+        Thread t = new Thread(new Runnable() {
+            public void run() {
+                try {
+                    Thread.sleep(250);
+                } catch (InterruptedException e) {
+                    // ignore
+                }
+                template.sendBody("seda:foo3", "blah");
+            }
+        });
+
+        long start = System.currentTimeMillis();
+        mock.expectedBodiesReceived("test:blah");
+        mock.expectedHeaderReceived(Exchange.TO_ENDPOINT, "seda://foo3");
+        t.start();
+        template.sendBody("direct:enricher-test-3", "test");
+        // should take approx 1 sec to complete as the other thread is sending a
+        // bit later and we wait
+        mock.assertIsSatisfied();
+        long delta = System.currentTimeMillis() - start;
+        assertTrue("Should take approx 0.25 sec: was " + delta, delta > 150);
+    }
+
+    // -------------------------------------------------------------
+    // InOut routes
+    // -------------------------------------------------------------
+
+    @Test
+    public void testPollEnrichInOut() throws InterruptedException {
+        template.sendBody("seda:foo4", "blah");
+
+        String result = (String)template.sendBody("direct:enricher-test-4", ExchangePattern.InOut, "test");
+        assertEquals("test:blah", result);
+    }
+
+    @Test
+    public void testPollEnrichInOutPlusHeader() throws InterruptedException {
+        template.sendBody("seda:foo4", "blah");
+
+        Exchange exchange = template.request("direct:enricher-test-4", new Processor() {
+            public void process(Exchange exchange) {
+                exchange.getIn().setHeader("foo", "bar");
+                exchange.getIn().setBody("test");
+            }
+        });
+        assertEquals("bar", exchange.getIn().getHeader("foo"));
+        assertEquals("test:blah", exchange.getIn().getBody());
+        assertEquals("seda://foo4", exchange.getMessage().getHeader(Exchange.TO_ENDPOINT));
+        assertNull(exchange.getException());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            public void configure() {
+                // -------------------------------------------------------------
+                // InOnly routes
+                // -------------------------------------------------------------
+
+                from("direct:enricher-test-1").pollEnrich("seda:foo1", aggregationStrategy).to("mock:mock");
+
+                from("direct:enricher-test-2").pollEnrich("seda:foo2", 1000, aggregationStrategy).to("mock:mock");
+
+                from("direct:enricher-test-3").pollEnrich("seda:foo3", -1, aggregationStrategy).to("mock:mock");
+
+                // -------------------------------------------------------------
+                // InOut routes
+                // -------------------------------------------------------------
+
+                from("direct:enricher-test-4").pollEnrich("seda:foo4", aggregationStrategy);
+            }
+        };
+    }
+
+}
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
index 70d79fa..0bf9076 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java
@@ -89,6 +89,20 @@ public final class ExchangeHelper {
      * @throws NoSuchEndpointException if the endpoint cannot be resolved
      */
     public static Endpoint resolveEndpoint(Exchange exchange, Object value) throws NoSuchEndpointException {
+        return resolveEndpoint(exchange.getContext(), value);
+    }
+
+    /**
+     * Attempts to resolve the endpoint for the given value
+     *
+     * @param context  the camel context
+     * @param value    the value which can be an {@link Endpoint} or an object
+     *                 which provides a String representation of an endpoint via
+     *                 {@link #toString()}
+     * @return the endpoint
+     * @throws NoSuchEndpointException if the endpoint cannot be resolved
+     */
+    public static Endpoint resolveEndpoint(CamelContext context, Object value) throws NoSuchEndpointException {
         if (value == null) {
             throw new NoSuchEndpointException("null");
         }
@@ -97,10 +111,10 @@ public final class ExchangeHelper {
             endpoint = (Endpoint) value;
         } else if (value instanceof NormalizedEndpointUri) {
             NormalizedEndpointUri nu = (NormalizedEndpointUri) value;
-            endpoint = CamelContextHelper.getMandatoryEndpoint(exchange.getContext(), nu);
+            endpoint = CamelContextHelper.getMandatoryEndpoint(context, nu);
         } else {
             String uri = value.toString().trim();
-            endpoint = CamelContextHelper.getMandatoryEndpoint(exchange.getContext(), uri);
+            endpoint = CamelContextHelper.getMandatoryEndpoint(context, uri);
         }
         return endpoint;
     }
@@ -116,6 +130,20 @@ public final class ExchangeHelper {
      * @throws NoSuchEndpointException if the endpoint cannot be resolved
      */
     public static Endpoint resolvePrototypeEndpoint(Exchange exchange, Object value) throws NoSuchEndpointException {
+        return resolvePrototypeEndpoint(exchange.getContext(), value);
+    }
+
+    /**
+     * Attempts to resolve the endpoint (prototype scope) for the given value
+     *
+     * @param context  the camel context
+     * @param value    the value which can be an {@link Endpoint} or an object
+     *                 which provides a String representation of an endpoint via
+     *                 {@link #toString()}
+     * @return the endpoint
+     * @throws NoSuchEndpointException if the endpoint cannot be resolved
+     */
+    public static Endpoint resolvePrototypeEndpoint(CamelContext context, Object value) throws NoSuchEndpointException {
         if (value == null) {
             throw new NoSuchEndpointException("null");
         }
@@ -124,10 +152,10 @@ public final class ExchangeHelper {
             endpoint = (Endpoint) value;
         } else if (value instanceof NormalizedEndpointUri) {
             NormalizedEndpointUri nu = (NormalizedEndpointUri) value;
-            endpoint = CamelContextHelper.getMandatoryPrototypeEndpoint(exchange.getContext(), nu);
+            endpoint = CamelContextHelper.getMandatoryPrototypeEndpoint(context, nu);
         } else {
             String uri = value.toString().trim();
-            endpoint = CamelContextHelper.getMandatoryPrototypeEndpoint(exchange.getContext(), uri);
+            endpoint = CamelContextHelper.getMandatoryPrototypeEndpoint(context, uri);
         }
         return endpoint;
     }


[camel] 07/11: Rename immutable -> lightweight to be more coherent and descriptive

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 73915938ec6bab235d22473d3f74ee8b7d33c542
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 18 18:45:25 2020 +0100

    Rename immutable -> lightweight to be more coherent and descriptive
---
 ...amelContext.java => LightweightCamelContext.java} | 16 ++++++++--------
 ...text.java => LightweightRuntimeCamelContext.java} |  6 +++---
 .../java/org/apache/camel/ContextTestSupport.java    | 20 ++++++++++----------
 ...eContextTest.java => LightweightContextTest.java} |  4 ++--
 .../camel/impl/lw/SplitterLightweightTest.java       |  3 +--
 .../apache/camel/ExtendedCamelContextConfigurer.java |  4 ----
 .../main/MainConfigurationPropertiesConfigurer.java  |  6 ++----
 .../src/main/java/org/apache/camel/main/Main.java    |  4 ++--
 8 files changed, 28 insertions(+), 35 deletions(-)

diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
similarity index 98%
rename from core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
rename to core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
index 36cd754..5a0a9f5 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
@@ -132,11 +132,11 @@ import org.apache.camel.support.DefaultRegistry;
 import org.apache.camel.support.jsse.SSLContextParameters;
 
 @Experimental
-public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamelContext, ModelCamelContext {
+public class LightweightCamelContext implements ExtendedCamelContext, CatalogCamelContext, ModelCamelContext {
 
     protected volatile CamelContext delegate;
 
-    protected ImmutableCamelContext(CamelContext delegate) {
+    protected LightweightCamelContext(CamelContext delegate) {
         this.delegate = delegate;
     }
 
@@ -146,11 +146,11 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
      * <p/>
      * Use one of the other constructors to force use an explicit registry.
      */
-    public ImmutableCamelContext() {
+    public LightweightCamelContext() {
         delegate = new DefaultCamelContext(false) {
             @Override
             public CamelContext getCamelContextReference() {
-                return ImmutableCamelContext.this;
+                return LightweightCamelContext.this;
             }
         };
     }
@@ -163,7 +163,7 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
      *
      * @param repository the bean repository.
      */
-    public ImmutableCamelContext(BeanRepository repository) {
+    public LightweightCamelContext(BeanRepository repository) {
         this(new DefaultRegistry(repository));
     }
 
@@ -172,7 +172,7 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
      *
      * @param registry the registry
      */
-    public ImmutableCamelContext(Registry registry) {
+    public LightweightCamelContext(Registry registry) {
         this();
         setRegistry(registry);
     }
@@ -1652,7 +1652,7 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
     //
 
     public void makeImmutable() {
-        if (delegate instanceof RuntimeImmutableCamelContext) {
+        if (delegate instanceof LightweightRuntimeCamelContext) {
             throw new IllegalStateException();
         }
         delegate.setAutoStartup(false);
@@ -1660,7 +1660,7 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
         for (Route route : delegate.getRoutes()) {
             clearModelReferences(route);
         }
-        delegate = new RuntimeImmutableCamelContext(this, delegate);
+        delegate = new LightweightRuntimeCamelContext(this, delegate);
     }
 
     private void clearModelReferences(Route r) {
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
similarity index 99%
rename from core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
rename to core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index 3de7132..8971d9c 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -136,9 +136,9 @@ import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class RuntimeImmutableCamelContext implements ExtendedCamelContext, CatalogCamelContext {
+public class LightweightRuntimeCamelContext implements ExtendedCamelContext, CatalogCamelContext {
 
-    private static final Logger LOG = LoggerFactory.getLogger(RuntimeImmutableCamelContext.class);
+    private static final Logger LOG = LoggerFactory.getLogger(LightweightRuntimeCamelContext.class);
 
     private final CamelContext reference;
     private final Registry registry;
@@ -180,7 +180,7 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
     private final String version;
     private Date startDate;
 
-    RuntimeImmutableCamelContext(CamelContext reference, CamelContext context) {
+    LightweightRuntimeCamelContext(CamelContext reference, CamelContext context) {
         this.reference = reference;
         registry = context.getRegistry();
         typeConverter = new CoreTypeConverterRegistry(context.getTypeConverterRegistry());
diff --git a/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java b/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
index a5e1560..d641d62 100644
--- a/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
+++ b/core/camel-core/src/test/java/org/apache/camel/ContextTestSupport.java
@@ -24,7 +24,7 @@ import org.apache.camel.builder.NotifyBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.impl.lw.ImmutableCamelContext;
+import org.apache.camel.impl.lw.LightweightCamelContext;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.Registry;
@@ -44,7 +44,7 @@ public abstract class ContextTestSupport extends TestSupport {
     protected volatile ConsumerTemplate consumer;
     protected volatile NotifyBuilder oneExchangeDone;
     private boolean useRouteBuilder = true;
-    private boolean useImmutableContext;
+    private boolean useLightweightContext;
     private Service camelContextService;
 
     /**
@@ -62,12 +62,12 @@ public abstract class ContextTestSupport extends TestSupport {
         this.useRouteBuilder = useRouteBuilder;
     }
 
-    public boolean isUseImmutableContext() {
-        return useImmutableContext;
+    public boolean isUseLightweightContext() {
+        return useLightweightContext;
     }
 
-    public void setUseImmutableContext(boolean useImmutableContext) {
-        this.useImmutableContext = useImmutableContext;
+    public void setUseLightweightContext(boolean useLightweightContext) {
+        this.useLightweightContext = useLightweightContext;
     }
 
     public Service getCamelContextService() {
@@ -180,8 +180,8 @@ public abstract class ContextTestSupport extends TestSupport {
         if (camelContextService != null) {
             camelContextService.start();
         } else {
-            if (context instanceof ImmutableCamelContext) {
-                ImmutableCamelContext ctx = (ImmutableCamelContext) context;
+            if (context instanceof LightweightCamelContext) {
+                LightweightCamelContext ctx = (LightweightCamelContext) context;
                 Boolean autoStartup = ctx.isAutoStartup();
                 ctx.setAutoStartup(false);
                 ctx.start();
@@ -197,8 +197,8 @@ public abstract class ContextTestSupport extends TestSupport {
 
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context;
-        if (useImmutableContext) {
-            ImmutableCamelContext ctx = new ImmutableCamelContext();
+        if (useLightweightContext) {
+            LightweightCamelContext ctx = new LightweightCamelContext();
             ctx.setRegistry(createRegistry());
             context = ctx;
         } else {
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/lw/ImmutableContextTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/lw/LightweightContextTest.java
similarity index 96%
rename from core/camel-core/src/test/java/org/apache/camel/impl/lw/ImmutableContextTest.java
rename to core/camel-core/src/test/java/org/apache/camel/impl/lw/LightweightContextTest.java
index f4b3082..b2110bd 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/lw/ImmutableContextTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/lw/LightweightContextTest.java
@@ -21,12 +21,12 @@ import org.apache.camel.builder.RouteBuilder;
 import org.junit.Before;
 import org.junit.Test;
 
-public class ImmutableContextTest extends ContextTestSupport {
+public class LightweightContextTest extends ContextTestSupport {
 
     @Override
     @Before
     public void setUp() throws Exception {
-        setUseImmutableContext(true);
+        setUseLightweightContext(true);
         super.setUp();
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java
index d458707..466938a 100644
--- a/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/impl/lw/SplitterLightweightTest.java
@@ -35,7 +35,6 @@ import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.processor.MyAggregationStrategy;
 import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class SplitterLightweightTest extends ContextTestSupport {
@@ -43,7 +42,7 @@ public class SplitterLightweightTest extends ContextTestSupport {
     @Override
     @Before
     public void setUp() throws Exception {
-        setUseImmutableContext(true);
+        setUseLightweightContext(true);
         super.setUp();
     }
 
diff --git a/core/camel-main/src/generated/java/org/apache/camel/ExtendedCamelContextConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/ExtendedCamelContextConfigurer.java
index 77383e9..54bd9ff 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/ExtendedCamelContextConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/ExtendedCamelContextConfigurer.java
@@ -15,8 +15,6 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
     public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
         org.apache.camel.ExtendedCamelContext target = (org.apache.camel.ExtendedCamelContext) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
-        case "allowaddingnewroutes":
-        case "AllowAddingNewRoutes": target.setAllowAddingNewRoutes(property(camelContext, boolean.class, value)); return true;
         case "allowuseoriginalmessage":
         case "AllowUseOriginalMessage": target.setAllowUseOriginalMessage(property(camelContext, java.lang.Boolean.class, value)); return true;
         case "applicationcontextclassloader":
@@ -33,8 +31,6 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "CaseInsensitiveHeaders": target.setCaseInsensitiveHeaders(property(camelContext, java.lang.Boolean.class, value)); return true;
         case "classresolver":
         case "ClassResolver": target.setClassResolver(property(camelContext, org.apache.camel.spi.ClassResolver.class, value)); return true;
-        case "clearmodelreferences":
-        case "ClearModelReferences": target.setClearModelReferences(property(camelContext, boolean.class, value)); return true;
         case "componentnameresolver":
         case "ComponentNameResolver": target.setComponentNameResolver(property(camelContext, org.apache.camel.spi.ComponentNameResolver.class, value)); return true;
         case "componentresolver":
diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index 94897c4..bc8ee06 100644
--- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -15,8 +15,6 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
     public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) {
         org.apache.camel.main.MainConfigurationProperties target = (org.apache.camel.main.MainConfigurationProperties) obj;
         switch (ignoreCase ? name.toLowerCase() : name) {
-        case "allowaddingnewroutes":
-        case "AllowAddingNewRoutes": target.setAllowAddingNewRoutes(property(camelContext, boolean.class, value)); return true;
         case "allowuseoriginalmessage":
         case "AllowUseOriginalMessage": target.setAllowUseOriginalMessage(property(camelContext, boolean.class, value)); return true;
         case "autoconfigurationenabled":
@@ -45,8 +43,6 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "BeanIntrospectionLoggingLevel": target.setBeanIntrospectionLoggingLevel(property(camelContext, org.apache.camel.LoggingLevel.class, value)); return true;
         case "caseinsensitiveheaders":
         case "CaseInsensitiveHeaders": target.setCaseInsensitiveHeaders(property(camelContext, boolean.class, value)); return true;
-        case "clearmodelreferences":
-        case "ClearModelReferences": target.setClearModelReferences(property(camelContext, boolean.class, value)); return true;
         case "consumertemplatecachesize":
         case "ConsumerTemplateCacheSize": target.setConsumerTemplateCacheSize(property(camelContext, int.class, value)); return true;
         case "durationhitexitcode":
@@ -83,6 +79,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp
         case "JmxManagementNamePattern": target.setJmxManagementNamePattern(property(camelContext, java.lang.String.class, value)); return true;
         case "jmxmanagementstatisticslevel":
         case "JmxManagementStatisticsLevel": target.setJmxManagementStatisticsLevel(property(camelContext, org.apache.camel.ManagementStatisticsLevel.class, value)); return true;
+        case "lightweight":
+        case "Lightweight": target.setLightweight(property(camelContext, boolean.class, value)); return true;
         case "loadtypeconverters":
         case "LoadTypeConverters": target.setLoadTypeConverters(property(camelContext, boolean.class, value)); return true;
         case "logdebugmaxchars":
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/Main.java b/core/camel-main/src/main/java/org/apache/camel/main/Main.java
index 8721427..c846850 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/Main.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/Main.java
@@ -21,7 +21,7 @@ import java.util.Map;
 import org.apache.camel.CamelContext;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.impl.lw.ImmutableCamelContext;
+import org.apache.camel.impl.lw.LightweightCamelContext;
 import org.apache.camel.spi.Registry;
 
 /**
@@ -144,7 +144,7 @@ public class Main extends MainCommandLineSupport {
     @Override
     protected CamelContext createCamelContext() {
         if (mainConfigurationProperties.isLightweight()) {
-            return new ImmutableCamelContext(registry);
+            return new LightweightCamelContext(registry);
         } else {
             return new DefaultCamelContext(registry);
         }


[camel] 04/11: Add an init method to Expression / Predicate

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 7afcecd94288e88df957f3a4f4d0facb1e747b8f
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Wed Mar 18 10:07:45 2020 +0100

    Add an init method to Expression / Predicate
---
 .../apache/camel/language/bean/BeanExpression.java |   4 +
 .../camel/component/mock/MockExpressionClause.java |  34 +-
 .../camel/component/mock/MockValueBuilder.java     |   6 +
 .../apache/camel/language/xpath/XPathBuilder.java  |   4 +
 .../src/main/java/org/apache/camel/Expression.java |   7 +
 .../src/main/java/org/apache/camel/Predicate.java  |   6 +
 .../apache/camel/processor/FilterProcessor.java    |  11 +-
 .../org/apache/camel/builder/ExpressionClause.java |  34 +-
 .../org/apache/camel/builder/SimpleBuilder.java    |  88 ++++--
 .../camel/model/language/ExpressionDefinition.java |  10 +
 .../apache/camel/reifier/ExpressionReifier.java    |   2 +-
 .../org/apache/camel/reifier/FilterReifier.java    |   2 +-
 .../reifier/language/SimpleExpressionReifier.java  |  37 ++-
 .../apache/camel/processor/TryProcessorTest.java   |   5 +
 .../apache/camel/processor/ValidateSimpleTest.java |   4 +-
 .../apache/camel/support/ExpressionSupport.java    |   5 +
 .../support/ExpressionToPredicateAdapter.java      |   5 +
 .../org/apache/camel/support/ScriptHelper.java     |  10 +
 .../support/builder/BinaryPredicateSupport.java    |   7 +
 .../camel/support/builder/ExpressionBuilder.java   | 342 +++++++++++++++++----
 .../apache/camel/support/builder/ValueBuilder.java |   6 +
 21 files changed, 512 insertions(+), 117 deletions(-)

diff --git a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
index 516c131..3d48bf0 100644
--- a/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
+++ b/components/camel-bean/src/main/java/org/apache/camel/language/bean/BeanExpression.java
@@ -110,6 +110,10 @@ public class BeanExpression implements Expression, Predicate, AfterPropertiesCon
     }
 
     @Override
+    public void init(CamelContext context) {
+    }
+
+    @Override
     public String toString() {
         StringBuilder sb = new StringBuilder("BeanExpression[");
         if (bean != null) {
diff --git a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java
index aa3c77d..ba74616b 100644
--- a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java
+++ b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockExpressionClause.java
@@ -21,6 +21,7 @@ import java.util.function.BiFunction;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionFactory;
@@ -425,23 +426,32 @@ public class MockExpressionClause<T> implements Expression, Predicate {
         return delegate.getExpressionType();
     }
 
+    private volatile Expression expr;
+
     @Override
-    public <T> T evaluate(Exchange exchange, Class<T> type) {
-        if (getExpressionValue() != null) {
-            return getExpressionValue().evaluate(exchange, type);
-        } else {
-            Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
-            return exp.evaluate(exchange, type);
+    public void init(CamelContext context) {
+        if (expr == null) {
+            synchronized (this) {
+                if (expr == null) {
+                    expr = getExpressionValue();
+                    if (expr == null) {
+                        expr = getExpressionType().createExpression(context);
+                    }
+                    expr.init(context);
+                }
+            }
         }
     }
 
     @Override
+    public <T> T evaluate(Exchange exchange, Class<T> type) {
+        init(exchange.getContext());
+        return expr.evaluate(exchange, type);
+    }
+
+    @Override
     public boolean matches(Exchange exchange) {
-        if (getExpressionValue() != null) {
-            return new ExpressionToPredicateAdapter(getExpressionValue()).matches(exchange);
-        } else {
-            Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
-            return new ExpressionToPredicateAdapter(exp).matches(exchange);
-        }
+        init(exchange.getContext());
+        return new ExpressionToPredicateAdapter(expr).matches(exchange);
     }
 }
diff --git a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java
index 551c524..4082a0e 100644
--- a/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java
+++ b/components/camel-mock/src/main/java/org/apache/camel/component/mock/MockValueBuilder.java
@@ -21,6 +21,7 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
@@ -44,6 +45,11 @@ public class MockValueBuilder implements Expression, Predicate {
     }
 
     @Override
+    public void init(CamelContext context) {
+        expression.init(context);
+    }
+
+    @Override
     public <T> T evaluate(Exchange exchange, Class<T> type) {
         return expression.evaluate(exchange, type);
     }
diff --git a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
index 6ff9fef..7adb463 100644
--- a/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
+++ b/components/camel-xpath/src/main/java/org/apache/camel/language/xpath/XPathBuilder.java
@@ -171,6 +171,10 @@ public class XPathBuilder extends ServiceSupport implements CamelContextAware, E
     }
 
     @Override
+    public void init(CamelContext context) {
+    }
+
+    @Override
     public boolean configure(CamelContext camelContext, Object target, String name, Object value, boolean ignoreCase) {
         if (target != this) {
             throw new IllegalStateException("Can only configure our own instance !");
diff --git a/core/camel-api/src/main/java/org/apache/camel/Expression.java b/core/camel-api/src/main/java/org/apache/camel/Expression.java
index 4995d0b..6fc0f64 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Expression.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Expression.java
@@ -30,4 +30,11 @@ public interface Expression {
      * @return the value of the expression
      */
     <T> T evaluate(Exchange exchange, Class<T> type);
+
+    /**
+     * Initialize the expression with the given camel context
+     */
+    default void init(CamelContext context) {
+    }
+
 }
diff --git a/core/camel-api/src/main/java/org/apache/camel/Predicate.java b/core/camel-api/src/main/java/org/apache/camel/Predicate.java
index d6a81c0..2f7f3dc 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Predicate.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Predicate.java
@@ -31,4 +31,10 @@ public interface Predicate {
      */
     boolean matches(Exchange exchange);
 
+    /**
+     * Initialize the predicate with the given camel context
+     */
+    default void init(CamelContext context) {
+    }
+
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java b/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java
index 637cc65..3c472df 100644
--- a/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java
+++ b/core/camel-base/src/main/java/org/apache/camel/processor/FilterProcessor.java
@@ -17,6 +17,7 @@
 package org.apache.camel.processor;
 
 import org.apache.camel.AsyncCallback;
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
@@ -36,17 +37,25 @@ public class FilterProcessor extends DelegateAsyncProcessor implements Traceable
 
     private static final Logger LOG = LoggerFactory.getLogger(FilterProcessor.class);
 
+    private final CamelContext context;
     private String id;
     private String routeId;
     private final Predicate predicate;
     private transient long filtered;
 
-    public FilterProcessor(Predicate predicate, Processor processor) {
+    public FilterProcessor(CamelContext context, Predicate predicate, Processor processor) {
         super(processor);
+        this.context = context;
         this.predicate = predicate;
     }
 
     @Override
+    protected void doInit() throws Exception {
+        super.doInit();
+        predicate.init(context);
+    }
+
+    @Override
     public boolean process(Exchange exchange, AsyncCallback callback) {
         boolean matches = false;
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java
index ff2f968..9dd2f6f 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/ExpressionClause.java
@@ -20,6 +20,7 @@ import java.util.Map;
 import java.util.function.BiFunction;
 import java.util.function.Function;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.ExpressionFactory;
@@ -939,23 +940,32 @@ public class ExpressionClause<T> implements Expression, Predicate {
         return delegate.getExpressionType();
     }
 
+    private volatile Expression expr;
+
     @Override
-    public <T> T evaluate(Exchange exchange, Class<T> type) {
-        if (getExpressionValue() != null) {
-            return getExpressionValue().evaluate(exchange, type);
-        } else {
-            Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
-            return exp.evaluate(exchange, type);
+    public void init(CamelContext context) {
+        if (expr == null) {
+            synchronized (this) {
+                if (expr == null) {
+                    expr = getExpressionValue();
+                    if (expr == null) {
+                        expr = delegate.getExpressionType().createExpression(context);
+                    }
+                    expr.init(context);
+                }
+            }
         }
     }
 
     @Override
+    public <T> T evaluate(Exchange exchange, Class<T> type) {
+        init(exchange.getContext());
+        return expr.evaluate(exchange, type);
+    }
+
+    @Override
     public boolean matches(Exchange exchange) {
-        if (getExpressionValue() != null) {
-            return new ExpressionToPredicateAdapter(getExpressionValue()).matches(exchange);
-        } else {
-            Expression exp = delegate.getExpressionType().createExpression(exchange.getContext());
-            return new ExpressionToPredicateAdapter(exp).matches(exchange);
-        }
+        init(exchange.getContext());
+        return new ExpressionToPredicateAdapter(expr).matches(exchange);
     }
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java b/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
index 894e5e6..d252920 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/builder/SimpleBuilder.java
@@ -103,60 +103,90 @@ public class SimpleBuilder implements Predicate, Expression, ExpressionResultTyp
     }
 
     @Override
-    public boolean matches(Exchange exchange) {
+    public void init(CamelContext context) {
         if (predicate == null) {
-            predicate = createPredicate(exchange);
+            predicate = createPredicate(context);
         }
+        predicate.init(context);
+    }
+
+    @Override
+    public boolean matches(Exchange exchange) {
+        init(exchange.getContext());
         return predicate.matches(exchange);
     }
 
     @Override
     public <T> T evaluate(Exchange exchange, Class<T> type) {
         if (expression == null) {
-            expression = createExpression(exchange);
+            expression = createExpression(exchange.getContext());
         }
         return expression.evaluate(exchange, type);
     }
 
-    private Predicate createPredicate(Exchange exchange) {
+    public Predicate createPredicate(CamelContext context) {
         try {
+            Language simple = context.resolveLanguage("simple");
             // resolve property placeholders
-            String resolve = exchange.getContext().resolvePropertyPlaceholders(text);
-            // and optional it be refer to an external script on the
-            // file/classpath
-            resolve = ScriptHelper.resolveOptionalExternalScript(exchange.getContext(), exchange, resolve);
-            Language simple = exchange.getContext().resolveLanguage("simple");
-            return simple.createPredicate(resolve);
-        } catch (Exception e) {
-            throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
-        }
-    }
-
-    private Expression createExpression(Exchange exchange) {
-        try {
-            // resolve property placeholders
-            String resolve = exchange.getContext().resolvePropertyPlaceholders(text);
-            // and optional it be refer to an external script on the
-            // file/classpath
-            resolve = ScriptHelper.resolveOptionalExternalScript(exchange.getContext(), exchange, resolve);
-            Language simple = exchange.getContext().resolveLanguage("simple");
-            return createSimpleExpression(simple, resolve, resultType);
+            String resolve = context.resolvePropertyPlaceholders(text);
+            // and optional it be refer to an external script on the file/classpath
+            if (ScriptHelper.hasExternalScript(resolve)) {
+                return new Predicate() {
+                    @Override
+                    public boolean matches(Exchange exchange) {
+                        String r = ScriptHelper.resolveOptionalExternalScript(context, exchange, resolve);
+                        return simple.createPredicate(r).matches(exchange);
+                    }
+                    @Override
+                    public String toString() {
+                        return text;
+                    }
+                };
+            } else {
+                Predicate pred = simple.createPredicate(resolve);
+                pred.init(context);
+                return pred;
+            }
         } catch (Exception e) {
-            throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
+            throw CamelExecutionException.wrapCamelExecutionException(null, e);
         }
     }
 
-    private static Expression createSimpleExpression(Language simple, String expression, Class<?> resultType) {
+    public Expression createExpression(CamelContext context) {
         if (resultType == Boolean.class || resultType == boolean.class) {
             // if its a boolean as result then its a predicate
-            Predicate predicate = simple.createPredicate(expression);
+            Predicate predicate = createPredicate(context);
             return PredicateToExpressionAdapter.toExpression(predicate);
-        } else {
-            Expression exp = simple.createExpression(expression);
+        }
+        try {
+            // resolve property placeholders
+            Language simple = context.resolveLanguage("simple");
+            String resolve = context.resolvePropertyPlaceholders(text);
+            Expression exp;
+            // and optional it be refer to an external script on the file/classpath
+            if (ScriptHelper.hasExternalScript(resolve)) {
+                exp = new Expression() {
+                    @Override
+                    public <T> T evaluate(Exchange exchange, Class<T> type) {
+                        String r = ScriptHelper.resolveOptionalExternalScript(context, exchange, resolve);
+                        Expression exp = simple.createExpression(r);
+                        return exp.evaluate(exchange, type);
+                    }
+                    @Override
+                    public String toString() {
+                        return text;
+                    }
+                };
+            } else {
+                exp = simple.createExpression(resolve);
+                exp.init(context);
+            }
             if (resultType != null) {
                 exp = ExpressionBuilder.convertToExpression(exp, resultType);
             }
             return exp;
+        } catch (Exception e) {
+            throw CamelExecutionException.wrapCamelExecutionException(null, e);
         }
     }
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
index d2326b7..0ea00ef 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
@@ -225,4 +225,14 @@ public class ExpressionDefinition implements Expression, Predicate, ExpressionFa
         return predicate.matches(exchange);
     }
 
+    @Override
+    public void init(CamelContext context) {
+        if (expressionValue == null) {
+            expressionValue = createExpression(context);
+        }
+        if (predicate == null) {
+            predicate = createPredicate(context);
+        }
+    }
+
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java
index 77667eb..672a1b6 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/ExpressionReifier.java
@@ -36,7 +36,7 @@ abstract class ExpressionReifier<T extends ExpressionNode> extends ProcessorReif
      */
     protected FilterProcessor createFilterProcessor() throws Exception {
         Processor childProcessor = createOutputsProcessor();
-        return new FilterProcessor(createPredicate(), childProcessor);
+        return new FilterProcessor(camelContext, createPredicate(), childProcessor);
     }
 
     /**
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java
index 4d070ef..239a82b 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/FilterReifier.java
@@ -37,7 +37,7 @@ public class FilterReifier extends ExpressionReifier<FilterDefinition> {
     protected FilterProcessor createFilterProcessor() throws Exception {
         // filter EIP should have child outputs
         Processor childProcessor = this.createChildProcessor(true);
-        return new FilterProcessor(createPredicate(), childProcessor);
+        return new FilterProcessor(camelContext, createPredicate(), childProcessor);
     }
 
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
index c5f238d..0126cee 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/language/SimpleExpressionReifier.java
@@ -20,6 +20,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
 import org.apache.camel.builder.SimpleBuilder;
@@ -34,13 +35,41 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression>
 
     @Override
     public Expression createExpression() {
+        Expression expr = createBuilder().createExpression(camelContext);
+        return new Expression() {
+            @Override
+            public <T> T evaluate(Exchange exchange, Class<T> type) {
+                return expr.evaluate(exchange, type);
+            }
+            @Override
+            public String toString() {
+                return definition.getExpression();
+            }
+        };
+    }
+
+    @Override
+    public Predicate createPredicate() {
+        Predicate pred = createBuilder().createPredicate(camelContext);
+        return new Predicate() {
+            @Override
+            public boolean matches(Exchange exchange) {
+                return pred.matches(exchange);
+            }
+            @Override
+            public String toString() {
+                return definition.getExpression();
+            }
+        };
+    }
+
+    protected SimpleBuilder createBuilder() {
         String exp = parseString(definition.getExpression());
         // should be true by default
         boolean isTrim = parseBoolean(definition.getTrim(), true);
         if (exp != null && isTrim) {
             exp = exp.trim();
         }
-
         SimpleBuilder answer = new SimpleBuilder(exp);
         Map<String, Object> props = new HashMap<>();
         props.put("resultType", or(definition.getResultType(), definition.getResultTypeName()));
@@ -48,10 +77,4 @@ public class SimpleExpressionReifier extends ExpressionReifier<SimpleExpression>
         return answer;
     }
 
-    @Override
-    public Predicate createPredicate() {
-        // SimpleBuilder is also a Predicate
-        return (Predicate) createExpression();
-    }
-
 }
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java
index 5d81d93..e978d7b 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/TryProcessorTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.processor;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.CamelException;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
@@ -95,6 +96,10 @@ public class TryProcessorTest extends ContextTestSupport {
         public boolean matches(Exchange exchange) {
             throw new RuntimeCamelException(new CamelException("Force to fail"));
         }
+
+        @Override
+        public void init(CamelContext context) {
+        }
     }
 
     private class ProcessorHandle implements Processor {
diff --git a/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java b/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java
index b463006..0498090 100644
--- a/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/processor/ValidateSimpleTest.java
@@ -58,8 +58,8 @@ public class ValidateSimpleTest extends ContextTestSupport {
         } catch (CamelExecutionException e) {
             // expected
             assertIsInstanceOf(PredicateValidationException.class, e.getCause());
-            String s = "Validation failed for Predicate[Simple: ${body} contains 'Camel'].";
-            assertTrue(e.getCause().getMessage().startsWith(s));
+            String s = "Validation failed for Predicate[${body} contains 'Camel'].";
+            assertStringContains(e.getCause().getMessage(), s);
         }
 
         assertMockEndpointsSatisfied();
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java
index 322a742..c90810e 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionSupport.java
@@ -16,6 +16,7 @@
  */
 package org.apache.camel.support;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
@@ -27,6 +28,10 @@ import org.apache.camel.util.ObjectHelper;
 public abstract class ExpressionSupport implements Expression, Predicate {
 
     @Override
+    public void init(CamelContext context) {
+    }
+
+    @Override
     public boolean matches(Exchange exchange) {
         Object value = evaluate(exchange, Object.class);
         return ObjectHelper.evaluateValuePredicate(value);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
index 9c8fb6d3..51b4ab5 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ExpressionToPredicateAdapter.java
@@ -58,6 +58,11 @@ public final class ExpressionToPredicateAdapter implements Predicate, CamelConte
     }
 
     @Override
+    public void init(CamelContext context) {
+        expression.init(context);
+    }
+
+    @Override
     public void setCamelContext(CamelContext camelContext) {
         if (expression instanceof CamelContextAware) {
             ((CamelContextAware) expression).setCamelContext(camelContext);
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java
index 0550330..d66d02f 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/ScriptHelper.java
@@ -89,4 +89,14 @@ public final class ScriptHelper {
 
         return expression;
     }
+
+    public static boolean hasExternalScript(String external) {
+        if (external.startsWith("resource:")) {
+            external = external.substring(9);
+            if (ResourceHelper.hasScheme(external) && LanguageSupport.hasSimpleFunction(external)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java
index b7c49ec..65757c5 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/BinaryPredicateSupport.java
@@ -17,6 +17,7 @@
 package org.apache.camel.support.builder;
 
 import org.apache.camel.BinaryPredicate;
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
@@ -40,6 +41,12 @@ public abstract class BinaryPredicateSupport implements BinaryPredicate {
     }
 
     @Override
+    public void init(CamelContext context) {
+        left.init(context);
+        right.init(context);
+    }
+
+    @Override
     public String toString() {
         return left + " " + getOperationText() + " " + right;
     }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
index 71f1d68..d9c0a3a 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
@@ -35,6 +35,7 @@ import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.InvalidPayloadException;
 import org.apache.camel.Message;
 import org.apache.camel.NoSuchLanguageException;
+import org.apache.camel.Predicate;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.RuntimeExchangeException;
 import org.apache.camel.spi.Language;
@@ -65,9 +66,22 @@ public class ExpressionBuilder {
      * @return an expression object which will return the header value
      */
     public static Expression headerExpression(final String headerName) {
+        return headerExpression(simpleExpression(headerName));
+    }
+
+    /**
+     * Returns an expression for the header value with the given name
+     * <p/>
+     * Will fallback and look in properties if not found in headers.
+     *
+     * @param headerName the name of the header the expression will return
+     * @return an expression object which will return the header value
+     */
+    public static Expression headerExpression(final Expression headerName) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String name = simpleExpression(headerName).evaluate(exchange, String.class);
+                String name = headerName.evaluate(exchange, String.class);
                 Object header = exchange.getIn().getHeader(name);
                 if (header == null) {
                     // fall back on a property
@@ -77,6 +91,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                headerName.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "header(" + headerName + ")";
             }
@@ -93,22 +112,7 @@ public class ExpressionBuilder {
      * @return an expression object which will return the header value
      */
     public static <T> Expression headerExpression(final String headerName, final Class<T> type) {
-        return new ExpressionAdapter() {
-            public Object evaluate(Exchange exchange) {
-                String name = simpleExpression(headerName).evaluate(exchange, String.class);
-                T header = exchange.getIn().getHeader(name, type);
-                if (header == null) {
-                    // fall back on a property
-                    header = exchange.getProperty(name, type);
-                }
-                return header;
-            }
-
-            @Override
-            public String toString() {
-                return "headerAs(" + headerName + ", " + type + ")";
-            }
-        };
+        return headerExpression(simpleExpression(headerName), constantExpression(type));
     }
 
     /**
@@ -121,17 +125,30 @@ public class ExpressionBuilder {
      * @return an expression object which will return the header value
      */
     public static Expression headerExpression(final String headerName, final String typeName) {
+        return headerExpression(simpleExpression(headerName), simpleExpression(typeName));
+    }
+
+    /**
+     * Returns an expression for the header value with the given name converted to the given type
+     * <p/>
+     * Will fallback and look in properties if not found in headers.
+     *
+     * @param headerName the name of the header the expression will return
+     * @param typeName the type to convert to as a FQN class name
+     * @return an expression object which will return the header value
+     */
+    public static Expression headerExpression(final Expression headerName, final Expression typeName) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 Class<?> type;
                 try {
-                    String text = simpleExpression(typeName).evaluate(exchange, String.class);
+                    String text = typeName.evaluate(exchange, String.class);
                     type = exchange.getContext().getClassResolver().resolveMandatoryClass(text);
                 } catch (ClassNotFoundException e) {
                     throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
                 }
-
-                String text = simpleExpression(headerName).evaluate(exchange, String.class);
+                String text = headerName.evaluate(exchange, String.class);
                 Object header = exchange.getIn().getHeader(text, type);
                 if (header == null) {
                     // fall back on a property
@@ -141,6 +158,12 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                headerName.init(context);
+                typeName.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "headerAs(" + headerName + ", " + typeName + ")";
             }
@@ -276,13 +299,28 @@ public class ExpressionBuilder {
      * @return an expression object which will return the bean
      */
     public static Expression refExpression(final String ref) {
+        return refExpression(simpleExpression(ref));
+    }
+
+    /**
+     * Returns an expression for lookup a bean in the {@link org.apache.camel.spi.Registry}
+     *
+     * @return an expression object which will return the bean
+     */
+    public static Expression refExpression(final Expression ref) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(ref).evaluate(exchange, String.class);
+                String text = ref.evaluate(exchange, String.class);
                 return exchange.getContext().getRegistry().lookupByName(text);
             }
 
             @Override
+            public void init(CamelContext context) {
+                ref.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "ref(" + ref + ")";
             }
@@ -384,13 +422,29 @@ public class ExpressionBuilder {
      * @return an expression object which will return the property value
      */
     public static Expression exchangePropertyExpression(final String propertyName) {
+        return exchangePropertyExpression(simpleExpression(propertyName));
+    }
+
+    /**
+     * Returns an expression for the property value of exchange with the given name
+     *
+     * @param propertyName the name of the property the expression will return
+     * @return an expression object which will return the property value
+     */
+    public static Expression exchangePropertyExpression(final Expression propertyName) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(propertyName).evaluate(exchange, String.class);
+                String text = propertyName.evaluate(exchange, String.class);
                 return exchange.getProperty(text);
             }
 
             @Override
+            public void init(CamelContext context) {
+                propertyName.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "exchangeProperty(" + propertyName + ")";
             }
@@ -440,13 +494,29 @@ public class ExpressionBuilder {
      * @return an expression object which will return the property value
      */
     public static Expression camelContextPropertyExpression(final String propertyName) {
+        return camelContextPropertyExpression(simpleExpression(propertyName));
+    }
+
+    /**
+     * Returns an expression for the property value of the camel context with the given name
+     *
+     * @param propertyName the name of the property the expression will return
+     * @return an expression object which will return the property value
+     */
+    public static Expression camelContextPropertyExpression(final Expression propertyName) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(propertyName).evaluate(exchange, String.class);
+                String text = propertyName.evaluate(exchange, String.class);
                 return exchange.getContext().getGlobalOption(text);
             }
 
             @Override
+            public void init(CamelContext context) {
+                propertyName.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "camelContextProperty(" + propertyName + ")";
             }
@@ -472,16 +542,37 @@ public class ExpressionBuilder {
      */
     public static Expression systemPropertyExpression(final String propertyName,
                                                       final String defaultValue) {
+        Expression exprName = simpleExpression(propertyName);
+        Expression exprDeflt = simpleExpression(defaultValue);
+        return systemPropertyExpression(exprName, exprDeflt);
+    }
+
+    /**
+     * Returns an expression for a system property value with the given name
+     *
+     * @param exprName the name of the system property the expression will return
+     * @param defaultValue default value to return if no system property exists
+     * @return an expression object which will return the system property value
+     */
+    public static Expression systemPropertyExpression(final Expression exprName,
+                                                      final Expression defaultValue) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(propertyName).evaluate(exchange, String.class);
-                String text2 = simpleExpression(defaultValue).evaluate(exchange, String.class);
+                String text = exprName.evaluate(exchange, String.class);
+                String text2 = defaultValue.evaluate(exchange, String.class);
                 return System.getProperty(text, text2);
             }
 
             @Override
+            public void init(CamelContext context) {
+                exprName.init(context);
+                defaultValue.init(context);
+            }
+
+            @Override
             public String toString() {
-                return "systemProperty(" + propertyName + ")";
+                return "systemProperty(" + exprName + ")";
             }
         };
     }
@@ -505,9 +596,24 @@ public class ExpressionBuilder {
      */
     public static Expression systemEnvironmentExpression(final String propertyName,
                                                          final String defaultValue) {
+        Expression exprName = simpleExpression(propertyName);
+        Expression expDeflt = simpleExpression(defaultValue);
+        return systemEnvironmentExpression(exprName, expDeflt);
+    }
+
+    /**
+     * Returns an expression for a system environment value with the given name
+     *
+     * @param propertyName the name of the system environment the expression will return
+     * @param defaultValue default value to return if no system environment exists
+     * @return an expression object which will return the system environment value
+     */
+    public static Expression systemEnvironmentExpression(final Expression propertyName,
+                                                         final Expression defaultValue) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(propertyName).evaluate(exchange, String.class);
+                String text = propertyName.evaluate(exchange, String.class);
                 String answer = null;
                 if (text != null) {
                     // lookup OS env with upper case key
@@ -521,12 +627,18 @@ public class ExpressionBuilder {
                 }
 
                 if (answer == null) {
-                    answer = simpleExpression(defaultValue).evaluate(exchange, String.class);
+                    answer = defaultValue.evaluate(exchange, String.class);
                 }
                 return answer;
             }
 
             @Override
+            public void init(CamelContext context) {
+                propertyName.init(context);
+                defaultValue.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "systemEnvironment(" + propertyName + ")";
             }
@@ -560,22 +672,36 @@ public class ExpressionBuilder {
      */
     public static Expression languageExpression(final String language, final String expression) {
         return new ExpressionAdapter() {
+            private volatile Expression expr;
+            private volatile Predicate pred;
+
             public Object evaluate(Exchange exchange) {
-                Language lan = exchange.getContext().resolveLanguage(language);
-                if (lan != null) {
-                    return lan.createExpression(expression).evaluate(exchange, Object.class);
-                } else {
-                    throw new NoSuchLanguageException(language);
-                }
+                init(exchange.getContext());
+                return expr.evaluate(exchange, Object.class);
             }
 
             @Override
             public boolean matches(Exchange exchange) {
-                Language lan = exchange.getContext().resolveLanguage(language);
-                if (lan != null) {
-                    return lan.createPredicate(expression).matches(exchange);
-                } else {
-                    throw new NoSuchLanguageException(language);
+                init(exchange.getContext());
+                return pred.matches(exchange);
+            }
+
+            @Override
+            public void init(CamelContext context) {
+                if (expr == null) {
+                    synchronized (this) {
+                        if (expr == null) {
+                            Language lan = context.resolveLanguage(language);
+                            if (lan != null) {
+                                pred = lan.createPredicate(expression);
+                                pred.init(context);
+                                expr = lan.createExpression(expression);
+                                expr.init(context);
+                            } else {
+                                throw new NoSuchLanguageException(language);
+                            }
+                        }
+                    }
                 }
             }
 
@@ -698,11 +824,20 @@ public class ExpressionBuilder {
      * to the given type
      */
     public static Expression bodyExpression(final String name) {
+        return bodyExpression(simpleExpression(name));
+    }
+
+    /**
+     * Returns the expression for the exchanges inbound message body converted
+     * to the given type
+     */
+    public static Expression bodyExpression(final Expression name) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(name).evaluate(exchange, String.class);
                 Class<?> type;
                 try {
+                    String text = name.evaluate(exchange, String.class);
                     type = exchange.getContext().getClassResolver().resolveMandatoryClass(text);
                 } catch (ClassNotFoundException e) {
                     throw CamelExecutionException.wrapCamelExecutionException(exchange, e);
@@ -711,6 +846,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                name.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "bodyAs[" + name + "]";
             }
@@ -722,6 +862,7 @@ public class ExpressionBuilder {
      */
     public static Expression threadNameExpression() {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return Thread.currentThread().getName();
             }
@@ -738,6 +879,7 @@ public class ExpressionBuilder {
      */
     public static Expression hostnameExpression() {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return InetAddressUtil.getLocalHostNameSafe();
             }
@@ -754,6 +896,7 @@ public class ExpressionBuilder {
      */
     public static Expression stepIdExpression() {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return exchange.getProperty(Exchange.STEP_ID);
             }
@@ -785,6 +928,7 @@ public class ExpressionBuilder {
      */
     public static <T> Expression mandatoryBodyExpression(final Class<T> type, final boolean nullBodyAllowed) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 if (nullBodyAllowed) {
                     if (exchange.getIn().getBody() == null) {
@@ -811,6 +955,7 @@ public class ExpressionBuilder {
      */
     public static Expression bodyTypeExpression() {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return exchange.getIn().getBody().getClass();
             }
@@ -827,6 +972,7 @@ public class ExpressionBuilder {
      */
     public static Expression exchangeExpression() {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return exchange;
             }
@@ -843,6 +989,7 @@ public class ExpressionBuilder {
      */
     public static Expression exchangeExpression(final Function<Exchange, Object> function) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return function.apply(exchange);
             }
@@ -873,6 +1020,7 @@ public class ExpressionBuilder {
      */
     public static Expression inMessageExpression() {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return exchange.getIn();
             }
@@ -889,6 +1037,7 @@ public class ExpressionBuilder {
      */
     public static Expression inMessageExpression(final Function<Message, Object> function) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 return function.apply(exchange.getIn());
             }
@@ -905,6 +1054,7 @@ public class ExpressionBuilder {
      */
     public static Expression convertToExpression(final Expression expression, final Class<?> type) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 if (type != null) {
                     return expression.evaluate(exchange, type);
@@ -914,6 +1064,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "" + expression;
             }
@@ -926,6 +1081,7 @@ public class ExpressionBuilder {
      */
     public static Expression convertToExpression(final Expression expression, final Expression type) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 Object result = type.evaluate(exchange, Object.class);
                 if (result != null) {
@@ -936,6 +1092,12 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+                type.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "" + expression;
             }
@@ -948,15 +1110,31 @@ public class ExpressionBuilder {
      */
     public static Expression tokenizeExpression(final Expression expression,
                                                 final String token) {
+        return tokenizeExpression(expression, simpleExpression(token));
+    }
+
+    /**
+     * Returns a tokenize expression which will tokenize the string with the
+     * given token
+     */
+    public static Expression tokenizeExpression(final Expression expression,
+                                                final Expression token) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
-                String text = simpleExpression(token).evaluate(exchange, String.class);
+                String text = token.evaluate(exchange, String.class);
                 Object value = expression.evaluate(exchange, Object.class);
                 Scanner scanner = ExchangeHelper.getScanner(exchange, value, text);
                 return scanner;
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+                token.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "tokenize(" + expression + ", " + token + ")";
             }
@@ -968,6 +1146,7 @@ public class ExpressionBuilder {
      */
     public static Expression skipFirstExpression(final Expression expression) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 Object value = expression.evaluate(exchange, Object.class);
                 Iterator it = exchange.getContext().getTypeConverter().tryConvertTo(Iterator.class, exchange, value);
@@ -981,6 +1160,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "skipFirst(" + expression + ")";
             }
@@ -994,6 +1178,7 @@ public class ExpressionBuilder {
     public static Expression regexTokenizeExpression(final Expression expression,
                                                      final String regexTokenizer) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 Object value = expression.evaluate(exchange, Object.class);
                 Scanner scanner = ExchangeHelper.getScanner(exchange, value, regexTokenizer);
@@ -1001,6 +1186,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "regexTokenize(" + expression + ", " + regexTokenizer + ")";
             }
@@ -1009,6 +1199,7 @@ public class ExpressionBuilder {
 
     public static Expression groupXmlIteratorExpression(final Expression expression, final String group) {
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 // evaluate expression as iterator
                 Iterator<?> it = expression.evaluate(exchange, Iterator.class);
@@ -1025,6 +1216,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "group " + expression + " " + group + " times";
             }
@@ -1052,6 +1248,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "group " + expression + " " + group + " times";
             }
@@ -1073,6 +1274,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "sort(" + expression + " by: " + comparator + ")";
             }
@@ -1096,6 +1302,11 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
             }
@@ -1111,6 +1322,7 @@ public class ExpressionBuilder {
 
         final Pattern pattern = Pattern.compile(regex);
         return new ExpressionAdapter() {
+            @Override
             public Object evaluate(Exchange exchange) {
                 String text = expression.evaluate(exchange, String.class);
                 String replacement = replacementExpression.evaluate(exchange, String.class);
@@ -1121,6 +1333,12 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                expression.init(context);
+                replacementExpression.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "regexReplaceAll(" + expression + ", " + pattern.pattern() + ")";
             }
@@ -1137,6 +1355,12 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                left.init(context);
+                right.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "append(" + left + ", " + right + ")";
             }
@@ -1153,6 +1377,12 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                left.init(context);
+                right.init(context);
+            }
+
+            @Override
             public String toString() {
                 return "prepend(" + left + ", " + right + ")";
             }
@@ -1192,6 +1422,13 @@ public class ExpressionBuilder {
             }
 
             @Override
+            public void init(CamelContext context) {
+                for (Expression expression : expressions) {
+                    expression.init(context);
+                }
+            }
+
+            @Override
             public String toString() {
                 if (description != null) {
                     return description;
@@ -1252,24 +1489,24 @@ public class ExpressionBuilder {
     }
 
     public static Expression simpleExpression(final String expression) {
-        return new ExpressionAdapter() {
-            public Object evaluate(Exchange exchange) {
-                if (LanguageSupport.hasSimpleFunction(expression)) {
+        if (LanguageSupport.hasSimpleFunction(expression)) {
+            return new ExpressionAdapter() {
+                public Object evaluate(Exchange exchange) {
                     // resolve language using context to have a clear separation of packages
                     // must call evaluate to return the nested language evaluate when evaluating
                     // stacked expressions
                     Language language = exchange.getContext().resolveLanguage("simple");
                     return language.createExpression(expression).evaluate(exchange, Object.class);
-                } else {
-                    return expression;
                 }
-            }
 
-            @Override
-            public String toString() {
-                return "simple(" + expression + ")";
-            }
-        };
+                @Override
+                public String toString() {
+                    return "simple(" + expression + ")";
+                }
+            };
+        } else {
+            return constantExpression(expression);
+        }
     }
 
     public static Expression beanExpression(final String expression) {
@@ -1423,4 +1660,5 @@ public class ExpressionBuilder {
             throw new IllegalArgumentException("Failed to set property " + name + " on " + bean + ". Reason: " + e, e);
         }
     }
+
 }
diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java
index 833de82..915a2fa 100644
--- a/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java
+++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/ValueBuilder.java
@@ -20,6 +20,7 @@ import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 
+import org.apache.camel.CamelContext;
 import org.apache.camel.Exchange;
 import org.apache.camel.Expression;
 import org.apache.camel.Predicate;
@@ -36,6 +37,11 @@ public class ValueBuilder implements Expression, Predicate {
     }
 
     @Override
+    public void init(CamelContext context) {
+        expression.init(context);
+    }
+
+    @Override
     public <T> T evaluate(Exchange exchange, Class<T> type) {
         return expression.evaluate(exchange, type);
     }


[camel] 01/11: Move Route.createErrorHandler to ExtendedCamelContext to get rid of the DefaultModelRoute class

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 7616492cd1256c2e363476e088eace65d7765113
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Mon Mar 16 06:59:37 2020 +0100

    Move Route.createErrorHandler to ExtendedCamelContext to get rid of the DefaultModelRoute class
---
 .../org/apache/camel/ExtendedCamelContext.java     |  3 ++
 .../org/apache/camel/impl/engine/DefaultRoute.java |  3 +-
 .../camel/impl/engine/SimpleCamelContext.java      |  6 ++++
 .../org/apache/camel/impl/DefaultCamelContext.java |  8 +++++
 .../org/apache/camel/impl/DefaultModelRoute.java   | 38 ----------------------
 .../camel/impl/lw/ImmutableCamelContext.java       |  5 +++
 .../impl/lw/RuntimeImmutableCamelContext.java      |  6 ++++
 .../org/apache/camel/reifier/RouteReifier.java     |  3 +-
 8 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
index 8b53752..a8ef4ea 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
@@ -584,4 +584,7 @@ public interface ExtendedCamelContext extends CamelContext {
     void addRoute(Route route);
 
     void removeRoute(Route route);
+
+    Processor createErrorHandler(Route route, Processor processor) throws Exception;
+
 }
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
index c280ea1..d464456 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
@@ -31,6 +31,7 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Consumer;
 import org.apache.camel.Endpoint;
 import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.NamedNode;
 import org.apache.camel.Navigate;
 import org.apache.camel.Processor;
@@ -109,7 +110,7 @@ public class DefaultRoute extends ServiceSupport implements Route {
 
     @Override
     public Processor createErrorHandler(Processor processor) throws Exception {
-        throw new UnsupportedOperationException();
+        return camelContext.adapt(ExtendedCamelContext.class).createErrorHandler(this, processor);
     }
 
     @Override
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
index e6cd59f..04f71cd 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/SimpleCamelContext.java
@@ -24,6 +24,7 @@ import org.apache.camel.AsyncProcessor;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Processor;
+import org.apache.camel.Route;
 import org.apache.camel.TypeConverter;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.health.HealthCheckRegistry;
@@ -388,4 +389,9 @@ public class SimpleCamelContext extends AbstractCamelContext {
     protected ExecutorServiceManager createExecutorServiceManager() {
         return new BaseExecutorServiceManager(getCamelContextReference());
     }
+
+    @Override
+    public Processor createErrorHandler(Route route, Processor processor) throws Exception {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index ba3fe6b..5321734 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -48,6 +48,7 @@ import org.apache.camel.model.validator.ValidatorDefinition;
 import org.apache.camel.processor.channel.DefaultChannel;
 import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.reifier.dataformat.DataFormatReifier;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.BeanRepository;
 import org.apache.camel.spi.DataFormat;
 import org.apache.camel.spi.ExecutorServiceManager;
@@ -396,4 +397,11 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
             }
         }
     }
+
+    @Override
+    public Processor createErrorHandler(Route route, Processor processor) throws Exception {
+        return ErrorHandlerReifier.reifier(route, route.getErrorHandlerFactory())
+                .createErrorHandler(processor);
+    }
+
 }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelRoute.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelRoute.java
deleted file mode 100644
index aae9095..0000000
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultModelRoute.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.impl;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Endpoint;
-import org.apache.camel.Processor;
-import org.apache.camel.impl.engine.DefaultRoute;
-import org.apache.camel.model.RouteDefinition;
-import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
-
-public class DefaultModelRoute extends DefaultRoute {
-
-    public DefaultModelRoute(CamelContext camelContext, RouteDefinition definition, String id,
-                             String description, Endpoint endpoint) {
-        super(camelContext, definition, id, description, endpoint);
-    }
-
-    @Override
-    public Processor createErrorHandler(Processor processor) throws Exception {
-        return ErrorHandlerReifier.reifier(this, getErrorHandlerFactory())
-                .createErrorHandler(processor);
-    }
-}
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
index f4da70e..2974e2f 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
@@ -1425,6 +1425,11 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
         getExtendedCamelContext().removeRoute(route);
     }
 
+    @Override
+    public Processor createErrorHandler(Route route, Processor processor) throws Exception {
+        return getExtendedCamelContext().createErrorHandler(route, processor);
+    }
+
     //
     // CatalogCamelContext
     //
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
index 47992fd..b397214 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
@@ -1281,6 +1281,12 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
         throw new UnsupportedOperationException();
     }
 
+    @Override
+    public Processor createErrorHandler(Route route, Processor processor) throws Exception {
+        // TODO: need to revisit this in order to support dynamic endpoints uri
+        throw new UnsupportedOperationException();
+    }
+
     //
     // CatalogCamelContext
     //
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/RouteReifier.java b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/RouteReifier.java
index f670c24..ee32355 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/reifier/RouteReifier.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/reifier/RouteReifier.java
@@ -35,7 +35,6 @@ import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.builder.AdviceWithTask;
 import org.apache.camel.builder.EndpointConsumerBuilder;
 import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.impl.DefaultModelRoute;
 import org.apache.camel.impl.engine.DefaultRoute;
 import org.apache.camel.model.Model;
 import org.apache.camel.model.ProcessorDefinition;
@@ -264,7 +263,7 @@ public class RouteReifier extends ProcessorReifier<RouteDefinition> {
         // create route
         String id = definition.idOrCreate(camelContext.adapt(ExtendedCamelContext.class).getNodeIdFactory());
         String desc = RouteDefinitionHelper.getRouteMessage(definition.toString());
-        DefaultRoute route = new DefaultModelRoute(camelContext, definition, id, desc, endpoint);
+        DefaultRoute route = new DefaultRoute(camelContext, definition, id, desc, endpoint);
 
         // configure error handler
         route.setErrorHandlerFactory(definition.getErrorHandlerFactory());


[camel] 03/11: Move the clearModelReferences / clearReifiers logic into the ImmutableCamelContext and Main.lightweight property

Posted by gn...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 1449f6e815eb6a84f0afab543bd1c8e3f26b9407
Author: Guillaume Nodet <gn...@gmail.com>
AuthorDate: Tue Mar 17 10:48:42 2020 +0100

    Move the clearModelReferences / clearReifiers logic into the ImmutableCamelContext and Main.lightweight property
---
 .../org/apache/camel/ExtendedCamelContext.java     | 36 -----------
 .../camel/impl/engine/AbstractCamelContext.java    | 48 --------------
 .../org/apache/camel/impl/DefaultCamelContext.java | 46 -------------
 .../camel/impl/lw/ImmutableCamelContext.java       | 45 +++++++------
 .../impl/lw/RuntimeImmutableCamelContext.java      | 20 ------
 .../camel-main-configuration-metadata.json         |  3 +-
 .../camel/main/DefaultConfigurationConfigurer.java |  2 -
 .../camel/main/DefaultConfigurationProperties.java | 75 ++++++++--------------
 .../src/main/java/org/apache/camel/main/Main.java  |  7 +-
 9 files changed, 59 insertions(+), 223 deletions(-)

diff --git a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
index a8ef4ea..5e889cb 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
@@ -543,42 +543,6 @@ public interface ExtendedCamelContext extends CamelContext {
      */
     void setConfigurerResolver(ConfigurerResolver configurerResolver);
 
-    /**
-     * Whether it's allowed to add new routes after Camel has been started.
-     * This is enabled by default.
-     * Setting this to false allows Camel to do some internal optimizations to reduce memory footprint.
-     * <p/>
-     * This should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot).
-     * As this affects the entire JVM where Camel JARs are on the classpath.
-     */
-    void setAllowAddingNewRoutes(boolean allowAddingNewRoutes);
-
-    /**
-     * Whether its allowed to add new routes after Camel has been started.
-     * This is enabled by default.
-     * Setting this to false allows Camel to do some internal optimizations to reduce memory footprint.
-     * <p/>
-     * This should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot).
-     * As this affects the entire JVM where Camel JARs are on the classpath.
-     */
-    boolean isAllowAddingNewRoutes();
-
-    /**
-     * Camel context can be configured to remove all references to the model definitions
-     * after it has been started.  It can be used in addition to the {@link #setAllowAddingNewRoutes(boolean)}
-     * method to reduce the footprint.
-     *
-     * @see #isAllowAddingNewRoutes()
-     * @param clearModelReferences
-     */
-    @Experimental
-    void setClearModelReferences(boolean clearModelReferences);
-
-    /**
-     * If references to the model are removed when Camel is started or not.
-     */
-    boolean isClearModelReferences();
-
     RouteController getInternalRouteController();
 
     void addRoute(Route route);
diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 8f3dacb..2980c01 100644
--- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -226,8 +226,6 @@ public abstract class AbstractCamelContext extends BaseService
     private Boolean useBreadcrumb = Boolean.FALSE;
     private Boolean allowUseOriginalMessage = Boolean.FALSE;
     private Boolean caseInsensitiveHeaders = Boolean.TRUE;
-    private boolean allowAddingNewRoutes = true;
-    private boolean clearModelReferences;
     private Long delay;
     private ErrorHandlerFactory errorHandlerFactory;
     private Map<String, String> globalOptions = new HashMap<>();
@@ -1157,10 +1155,6 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     public void addRoute(Route route) {
-        if (isStarted() && !isAllowAddingNewRoutes()) {
-            throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed");
-        }
-
         synchronized (this.routes) {
             this.routes.add(route);
         }
@@ -1168,9 +1162,6 @@ public abstract class AbstractCamelContext extends BaseService
 
     @Override
     public void addRoutes(final RoutesBuilder builder) throws Exception {
-        if (isStarted() && !isAllowAddingNewRoutes()) {
-            throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed");
-        }
         try (LifecycleHelper helper = new LifecycleHelper()) {
             init();
             LOG.debug("Adding routes from builder: {}", builder);
@@ -1938,24 +1929,6 @@ public abstract class AbstractCamelContext extends BaseService
     }
 
     @Override
-    public boolean isAllowAddingNewRoutes() {
-        return allowAddingNewRoutes;
-    }
-
-    @Override
-    public void setAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
-        this.allowAddingNewRoutes = allowAddingNewRoutes;
-    }
-
-    public boolean isClearModelReferences() {
-        return clearModelReferences;
-    }
-
-    public void setClearModelReferences(boolean clearModelReferences) {
-        this.clearModelReferences = clearModelReferences;
-    }
-
-    @Override
     public Registry getRegistry() {
         if (registry == null) {
             synchronized (lock) {
@@ -2551,16 +2524,6 @@ public abstract class AbstractCamelContext extends BaseService
             }
         }
 
-        if (!isAllowAddingNewRoutes()) {
-            LOG.info("Adding new routes after CamelContext has started is not allowed");
-            disallowAddingNewRoutes();
-        }
-
-        if (isClearModelReferences()) {
-            LOG.info("Clearing model references");
-            clearModelReferences();
-        }
-
         if (LOG.isInfoEnabled()) {
             // count how many routes are actually started
             int started = 0;
@@ -2898,17 +2861,6 @@ public abstract class AbstractCamelContext extends BaseService
         CamelContextTracker.notifyContextDestroyed(this);
     }
 
-    /**
-     * Strategy invoked when adding new routes after CamelContext has been started is not allowed.
-     * This is used to do some internal optimizations.
-     */
-    protected void disallowAddingNewRoutes() {
-        ReifierStrategy.clearReifiers();
-    }
-
-    protected void clearModelReferences() {
-    }
-
     public void startRouteDefinitions() throws Exception {
     }
 
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index e4fa1d7..3c93ab0 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -16,9 +16,6 @@
  */
 package org.apache.camel.impl;
 
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -27,14 +24,12 @@ import java.util.function.Function;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
 import org.apache.camel.FailedToStartRouteException;
-import org.apache.camel.Navigate;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
 import org.apache.camel.ValueHolder;
 import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.health.HealthCheckRegistry;
-import org.apache.camel.impl.engine.DefaultRoute;
 import org.apache.camel.impl.engine.RouteService;
 import org.apache.camel.impl.engine.SimpleCamelContext;
 import org.apache.camel.impl.transformer.TransformerKey;
@@ -52,7 +47,6 @@ import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
-import org.apache.camel.processor.channel.DefaultChannel;
 import org.apache.camel.reifier.RouteReifier;
 import org.apache.camel.reifier.dataformat.DataFormatReifier;
 import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
@@ -129,17 +123,11 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
 
     @Override
     public void addRouteDefinitions(Collection<RouteDefinition> routeDefinitions) throws Exception {
-        if (isStarted() && !isAllowAddingNewRoutes()) {
-            throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed");
-        }
         model.addRouteDefinitions(routeDefinitions);
     }
 
     @Override
     public void addRouteDefinition(RouteDefinition routeDefinition) throws Exception {
-        if (isStarted() && !isAllowAddingNewRoutes()) {
-            throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed");
-        }
         model.addRouteDefinition(routeDefinition);
     }
 
@@ -160,9 +148,6 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
 
     @Override
     public void addRestDefinitions(Collection<RestDefinition> restDefinitions, boolean addToRoutes) throws Exception {
-        if (isStarted() && !isAllowAddingNewRoutes()) {
-            throw new IllegalArgumentException("Adding new routes after CamelContext has been started is not allowed");
-        }
         model.addRestDefinitions(restDefinitions, addToRoutes);
     }
 
@@ -382,37 +367,6 @@ public class DefaultCamelContext extends SimpleCamelContext implements ModelCame
     }
 
     @Override
-    protected void clearModelReferences() {
-        model = (Model) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{Model.class }, new InvocationHandler() {
-            @Override
-            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                throw new UnsupportedOperationException("Model invocations are not supported at runtime");
-            }
-        });
-        for (Route route : getRoutes()) {
-            clearModelReferences(route);
-        }
-    }
-
-    private void clearModelReferences(Route r) {
-        if (r instanceof DefaultRoute) {
-            ((DefaultRoute) r).clearModelReferences();
-        }
-        clearModelReferences(r.navigate());
-    }
-
-    private void clearModelReferences(Navigate<Processor> nav) {
-        for (Processor processor : nav.next()) {
-            if (processor instanceof DefaultChannel) {
-                ((DefaultChannel) processor).clearModelReferences();
-            }
-            if (processor instanceof Navigate) {
-                clearModelReferences((Navigate<Processor>) processor);
-            }
-        }
-    }
-
-    @Override
     public Processor createErrorHandler(Route route, Processor processor) throws Exception {
         return ErrorHandlerReifier.reifier(route, route.getErrorHandlerFactory())
                 .createErrorHandler(processor);
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
index 62537e4..36cd754 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/ImmutableCamelContext.java
@@ -38,6 +38,7 @@ import org.apache.camel.Expression;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.FluentProducerTemplate;
 import org.apache.camel.GlobalEndpointConfiguration;
+import org.apache.camel.Navigate;
 import org.apache.camel.NoSuchLanguageException;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
@@ -53,6 +54,7 @@ import org.apache.camel.ValueHolder;
 import org.apache.camel.builder.AdviceWithRouteBuilder;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.engine.DefaultRoute;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.HystrixConfigurationDefinition;
 import org.apache.camel.model.ModelCamelContext;
@@ -64,6 +66,7 @@ import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
 import org.apache.camel.model.validator.ValidatorDefinition;
+import org.apache.camel.processor.channel.DefaultChannel;
 import org.apache.camel.spi.AnnotationBasedProcessorFactory;
 import org.apache.camel.spi.AsyncProcessorAwaitManager;
 import org.apache.camel.spi.BeanIntrospection;
@@ -1394,27 +1397,6 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
     }
 
     @Override
-    public void setAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
-        getExtendedCamelContext().setAllowAddingNewRoutes(allowAddingNewRoutes);
-    }
-
-    @Override
-    public boolean isAllowAddingNewRoutes() {
-        return getExtendedCamelContext().isAllowAddingNewRoutes();
-    }
-
-    @Override
-    @Experimental
-    public void setClearModelReferences(boolean clearModelReferences) {
-        getExtendedCamelContext().setClearModelReferences(clearModelReferences);
-    }
-
-    @Override
-    public boolean isClearModelReferences() {
-        return getExtendedCamelContext().isClearModelReferences();
-    }
-
-    @Override
     public RouteController getInternalRouteController() {
         return getExtendedCamelContext().getInternalRouteController();
     }
@@ -1675,9 +1657,30 @@ public class ImmutableCamelContext implements ExtendedCamelContext, CatalogCamel
         }
         delegate.setAutoStartup(false);
         delegate.start();
+        for (Route route : delegate.getRoutes()) {
+            clearModelReferences(route);
+        }
         delegate = new RuntimeImmutableCamelContext(this, delegate);
     }
 
+    private void clearModelReferences(Route r) {
+        if (r instanceof DefaultRoute) {
+            ((DefaultRoute) r).clearModelReferences();
+        }
+        clearModelReferences(r.navigate());
+    }
+
+    private void clearModelReferences(Navigate<Processor> nav) {
+        for (Processor processor : nav.next()) {
+            if (processor instanceof DefaultChannel) {
+                ((DefaultChannel) processor).clearModelReferences();
+            }
+            if (processor instanceof Navigate) {
+                clearModelReferences((Navigate<Processor>) processor);
+            }
+        }
+    }
+
     public void startImmutable() {
         delegate.start();
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
index b397214..e7ed47d 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/RuntimeImmutableCamelContext.java
@@ -1262,16 +1262,6 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
     }
 
     @Override
-    public boolean isAllowAddingNewRoutes() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public boolean isClearModelReferences() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     public void addRoute(Route route) {
         throw new UnsupportedOperationException();
     }
@@ -1523,16 +1513,6 @@ public class RuntimeImmutableCamelContext implements ExtendedCamelContext, Catal
     }
 
     @Override
-    public void setAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void setClearModelReferences(boolean clearModelReferences) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     public XMLRoutesDefinitionLoader getXMLRoutesDefinitionLoader() {
         throw new UnsupportedOperationException();
     }
diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 7d8987f..0cfdb35 100644
--- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -6,7 +6,6 @@
     { "name": "camel.rest", "description": "camel-rest configurations.", "sourceType": "org.apache.camel.spi.RestConfiguration" }
   ],
   "properties": [
-    { "name": "camel.main.allowAddingNewRoutes", "description": "Whether its allowed to add new routes after Camel has been started. This is enabled by default. Setting this to false allows Camel to do some internal optimizations to reduce memory footprint. This should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot). As this affects the entire JVM where Camel JARs are on the classpath.", "sourceType": "org.apache.came [...]
     { "name": "camel.main.allowUseOriginalMessage", "description": "Sets whether to allow access to the original message from Camel's error handler, or from org.apache.camel.spi.UnitOfWork.getOriginalInMessage(). Turning this off can optimize performance, as defensive copy of the original message is not needed. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.autoConfigurationEnabled", "description": "Whether auto configuration of components, dataformats, languages is enabled or not. When enabled the configuration parameters are loaded from the properties component and optionally from the classpath file META-INF\/services\/org\/apache\/camel\/autowire.properties. You can prefix the parameters in the properties file with: - camel.component.name.option1=value1 - camel.component.name.option2=value2 - camel.dataformat.na [...]
     { "name": "camel.main.autoConfigurationEnvironmentVariablesEnabled", "description": "Whether auto configuration should include OS environment variables as well. When enabled this allows to overrule any configuration using an OS environment variable. For example to set a shutdown timeout of 5 seconds: CAMEL_MAIN_SHUTDOWNTIMEOUT=5. This option is default enabled.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue [...]
@@ -21,7 +20,6 @@
     { "name": "camel.main.beanIntrospectionExtendedStatistics", "description": "Sets whether bean introspection uses extended statistics. The default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.beanIntrospectionLoggingLevel", "description": "Sets the logging level used by bean introspection, logging activity of its usage. The default is TRACE.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] },
     { "name": "camel.main.caseInsensitiveHeaders", "description": "Whether to use case sensitive or insensitive headers. Important: When using case sensitive (this is set to false). Then the map is case sensitive which means headers such as content-type and Content-Type are two different keys which can be a problem for some protocols such as HTTP based, which rely on case insensitive headers. However case sensitive implementations can yield faster performance. Therefore use case sensitiv [...]
-    { "name": "camel.main.clearModelReferences", "description": null, "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.consumerTemplateCacheSize", "description": "Consumer template endpoints cache size.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int", "defaultValue": 1000 },
     { "name": "camel.main.durationHitExitCode", "description": "Sets the exit code for the application if duration was hit", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "integer", "javaType": "int" },
     { "name": "camel.main.durationMaxIdleSeconds", "description": "To specify for how long time in seconds Camel can be idle before automatic terminating the JVM. You can use this to run Camel for a short while.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
@@ -40,6 +38,7 @@
     { "name": "camel.main.jmxEnabled", "description": "Enable JMX in your Camel application.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.jmxManagementNamePattern", "description": "The naming pattern for creating the CamelContext JMX management name. The default pattern is #name#", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "#name#" },
     { "name": "camel.main.jmxManagementStatisticsLevel", "description": "Sets the JMX statistics level The level can be set to Extended to gather additional information The default value is Default.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "object", "javaType": "org.apache.camel.ManagementStatisticsLevel", "defaultValue": "ManagementStatisticsLevel.Default", "enum": [ "Extended", "Default", "RoutesOnly", "Off" ] },
+    { "name": "camel.main.lightweight", "description": "Configure the context to be lightweight. This will trigger some optimizations and memory reduction options. Lightweight context have some limitations. At this moment, dynamic endpoint destinations are not supported.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.loadTypeConverters", "description": "Whether to load custom type converters by scanning classpath. This is used for backwards compatibility with Camel 2.x. Its recommended to migrate to use fast type converter loading by setting Converter(loader = true) on your custom type converter classes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
     { "name": "camel.main.logDebugMaxChars", "description": "Is used to limit the maximum length of the logging Camel message bodies. If the message body is longer than the limit, the log message is clipped. Use -1 to have unlimited length. Use for example 1000 to log at most 1000 characters.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "integer", "javaType": "int" },
     { "name": "camel.main.logExhaustedMessageBody", "description": "Sets whether to log exhausted message body with message history. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean" },
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index a576f72..a76def9 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -153,8 +153,6 @@ public final class DefaultConfigurationConfigurer {
         camelContext.setUseMDCLogging(config.isUseMdcLogging());
         camelContext.setMDCLoggingKeysPattern(config.getMdcLoggingKeysPattern());
         camelContext.setLoadTypeConverters(config.isLoadTypeConverters());
-        ecc.setAllowAddingNewRoutes(config.isAllowAddingNewRoutes());
-        ecc.setClearModelReferences(config.isClearModelReferences());
 
         if (camelContext.getManagementStrategy().getManagementAgent() != null) {
             camelContext.getManagementStrategy().getManagementAgent().setEndpointRuntimeStatisticsEnabled(config.isEndpointRuntimeStatisticsEnabled());
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index cc2b2d5..58777be 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -66,8 +66,6 @@ public abstract class DefaultConfigurationProperties<T> {
     private boolean endpointBasicPropertyBinding;
     private boolean useDataType;
     private boolean useBreadcrumb;
-    private boolean allowAddingNewRoutes = true;
-    private boolean clearModelReferences;
     private ManagementStatisticsLevel jmxManagementStatisticsLevel = ManagementStatisticsLevel.Default;
     private String jmxManagementNamePattern = "#name#";
     private boolean jmxCreateConnector;
@@ -83,6 +81,7 @@ public abstract class DefaultConfigurationProperties<T> {
     private String javaRoutesExcludePattern;
     private String xmlRoutes = "classpath:camel/*.xml";
     private String xmlRests = "classpath:camel-rest/*.xml";
+    private boolean lightweight;
 
     // getter and setters
     // --------------------------------------------------------------
@@ -634,38 +633,6 @@ public abstract class DefaultConfigurationProperties<T> {
         this.useBreadcrumb = useBreadcrumb;
     }
 
-    /**
-     * Whether its allowed to add new routes after Camel has been started.
-     * This is enabled by default.
-     * Setting this to false allows Camel to do some internal optimizations to reduce memory footprint.
-     * <p/>
-     * This should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot).
-     * As this affects the entire JVM where Camel JARs are on the classpath.
-     */
-    public boolean isAllowAddingNewRoutes() {
-        return allowAddingNewRoutes;
-    }
-
-    /**
-     * Whether its allowed to add new routes after Camel has been started.
-     * This is enabled by default.
-     * Setting this to false allows Camel to do some internal optimizations to reduce memory footprint.
-     * <p/>
-     * This should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot).
-     * As this affects the entire JVM where Camel JARs are on the classpath.
-     */
-    public void setAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
-        this.allowAddingNewRoutes = allowAddingNewRoutes;
-    }
-
-    public boolean isClearModelReferences() {
-        return clearModelReferences;
-    }
-
-    public void setClearModelReferences(boolean clearModelReferences) {
-        this.clearModelReferences = clearModelReferences;
-    }
-
     public ManagementStatisticsLevel getJmxManagementStatisticsLevel() {
         return jmxManagementStatisticsLevel;
     }
@@ -924,6 +891,19 @@ public abstract class DefaultConfigurationProperties<T> {
         this.xmlRests = xmlRests;
     }
 
+    public boolean isLightweight() {
+        return lightweight;
+    }
+
+    /**
+     * Configure the context to be lightweight.  This will trigger some optimizations
+     * and memory reduction options.  Lightweight context have some limitations.  At
+     * this moment, dynamic endpoint destinations are not supported.
+     */
+    public void setLightweight(boolean lightweight) {
+        this.lightweight = lightweight;
+    }
+
     // fluent builders
     // --------------------------------------------------------------
 
@@ -1332,19 +1312,6 @@ public abstract class DefaultConfigurationProperties<T> {
     }
 
     /**
-     * Whether its allowed to add new routes after Camel has been started.
-     * This is enabled by default.
-     * Setting this to false allows Camel to do some internal optimizations to reduce memory footprint.
-     * <p/>
-     * This should only be done on a JVM with a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot).
-     * As this affects the entire JVM where Camel JARs are on the classpath.
-     */
-    public T withAllowAddingNewRoutes(boolean allowAddingNewRoutes) {
-        this.allowAddingNewRoutes = allowAddingNewRoutes;
-        return (T) this;
-    }
-
-    /**
      * Set whether breadcrumb is enabled.
      * The default value is false.
      */
@@ -1580,4 +1547,18 @@ public abstract class DefaultConfigurationProperties<T> {
         this.xmlRests = xmlRests;
         return (T) this;
     }
+
+    /*
+     * Configure the context to be lightweight.  This will trigger some optimizations
+     * and memory reduction options.
+     * <p/>
+     * Lightweight context have some limitations.  At the moment, dynamic endpoint
+     * destinations are not supported.  Also, this should only be done on a JVM with
+     * a single Camel application (microservice like camel-main, camel-quarkus, camel-spring-boot).
+     * As this affects the entire JVM where Camel JARs are on the classpath.
+     */
+    public T withLightweight(boolean lightweight) {
+        this.lightweight = lightweight;
+        return (T) this;
+    }
 }
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/Main.java b/core/camel-main/src/main/java/org/apache/camel/main/Main.java
index ac51b86..8721427 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/Main.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/Main.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import org.apache.camel.CamelContext;
 import org.apache.camel.ProducerTemplate;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.lw.ImmutableCamelContext;
 import org.apache.camel.spi.Registry;
 
 /**
@@ -142,7 +143,11 @@ public class Main extends MainCommandLineSupport {
 
     @Override
     protected CamelContext createCamelContext() {
-        return new DefaultCamelContext(registry);
+        if (mainConfigurationProperties.isLightweight()) {
+            return new ImmutableCamelContext(registry);
+        } else {
+            return new DefaultCamelContext(registry);
+        }
     }
 
 }