This is an automated email from the ASF dual-hosted git repository. lburgazzoli pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 3c4ae28338f89346cf19b19ef1f2aa3f8e5de69d Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Thu Aug 20 15:57:08 2020 +0200 lifecycle: add starting/started/stopping/stopped events --- .../org/apache/camel/spi/LifecycleStrategy.java | 47 +++- .../org/apache/camel/spi/OnCamelContextEvent.java | 5 + .../camel/spi/OnCamelContextInitialized.java | 2 +- ...Initialized.java => OnCamelContextStarted.java} | 6 +- ...nitialized.java => OnCamelContextStarting.java} | 6 +- ...Initialized.java => OnCamelContextStopped.java} | 6 +- ...nitialized.java => OnCamelContextStopping.java} | 6 +- .../camel/impl/engine/AbstractCamelContext.java | 280 +++++++++++---------- .../engine/OnCamelContextLifecycleStrategy.java | 52 ++++ .../camel/impl/LifecycleStrategyDiscoveryTest.java | 26 +- .../apache/camel/main/MainLifecycleStrategy.java | 2 +- .../management/JmxManagementLifecycleStrategy.java | 2 +- .../camel/support/LifecycleStrategySupport.java | 273 ++++++++++++++------ 13 files changed, 489 insertions(+), 224 deletions(-) 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 a3e3c0f..a31edec 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 @@ -45,7 +45,7 @@ public interface LifecycleStrategy { } /** - * Notification on initialized a {@link CamelContext}. + * Notification on initialized {@link CamelContext}. * * @param context the camel context * @throws VetoCamelContextStartException can be thrown to veto starting {@link CamelContext}. Any other runtime @@ -58,19 +58,60 @@ public interface LifecycleStrategy { /** * Notification on starting 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. * + * @deprecated use {@link #onContextStarting(CamelContext)}. + */ + @Deprecated + default void onContextStart(CamelContext context) throws VetoCamelContextStartException { + } + + /** + * Notification on starting 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. */ - void onContextStart(CamelContext context) throws VetoCamelContextStartException; + default void onContextStarting(CamelContext context) throws VetoCamelContextStartException { + } + + /** + * Notification on started {@link CamelContext}. + * + * @param context the camel context + */ + default void onContextStarted(CamelContext context) { + } + + /** + * Notification on stopping a {@link CamelContext}. + * + * @param context the camel context + * @deprecated use {@link #onContextStopping(CamelContext)}. + */ + @Deprecated + default void onContextStop(CamelContext context) { + } /** * Notification on stopping a {@link CamelContext}. * * @param context the camel context */ - void onContextStop(CamelContext context); + default void onContextStopping(CamelContext context) { + } + + /** + * Notification on stopped {@link CamelContext}. + * + * @param context the camel context + */ + default void onContextStopped(CamelContext context) { + } /** * Notification on adding an {@link Component}. diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextEvent.java b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextEvent.java index d06da3b..968cfc8 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextEvent.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextEvent.java @@ -21,9 +21,14 @@ import org.apache.camel.CamelContext; /** * Marker interface used to make it easy to discover {@link CamelContext} related event handlers from the registry. * + * @see OnCamelContextInitializing * @see OnCamelContextInitialized * @see OnCamelContextStart + * @see OnCamelContextStarting + * @see OnCamelContextStarted * @see OnCamelContextStop + * @see OnCamelContextStopped + * @see OnCamelContextStopping */ public interface OnCamelContextEvent { } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java index 737bdc0..d491e1d 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java @@ -19,7 +19,7 @@ package org.apache.camel.spi; import org.apache.camel.CamelContext; /** - * Notification on initialized a {@link CamelContext}. + * Notification on an initialized a {@link CamelContext}. */ @FunctionalInterface public interface OnCamelContextInitialized extends OnCamelContextEvent { diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStarted.java similarity index 83% copy from core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java copy to core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStarted.java index 737bdc0..f7f4815 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStarted.java @@ -19,9 +19,9 @@ package org.apache.camel.spi; import org.apache.camel.CamelContext; /** - * Notification on initialized a {@link CamelContext}. + * Notification on a started {@link CamelContext}. */ @FunctionalInterface -public interface OnCamelContextInitialized extends OnCamelContextEvent { - void onContextInitialized(CamelContext context); +public interface OnCamelContextStarted extends OnCamelContextEvent { + void onContextStarted(CamelContext context); } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStarting.java similarity index 83% copy from core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java copy to core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStarting.java index 737bdc0..31899c4 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStarting.java @@ -19,9 +19,9 @@ package org.apache.camel.spi; import org.apache.camel.CamelContext; /** - * Notification on initialized a {@link CamelContext}. + * Notification on starting a {@link CamelContext}. */ @FunctionalInterface -public interface OnCamelContextInitialized extends OnCamelContextEvent { - void onContextInitialized(CamelContext context); +public interface OnCamelContextStarting extends OnCamelContextEvent { + void onContextStarting(CamelContext context); } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStopped.java similarity index 83% copy from core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java copy to core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStopped.java index 737bdc0..de4fb83 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStopped.java @@ -19,9 +19,9 @@ package org.apache.camel.spi; import org.apache.camel.CamelContext; /** - * Notification on initialized a {@link CamelContext}. + * Notification on a stopped {@link CamelContext}. */ @FunctionalInterface -public interface OnCamelContextInitialized extends OnCamelContextEvent { - void onContextInitialized(CamelContext context); +public interface OnCamelContextStopped extends OnCamelContextEvent { + void onContextStopped(CamelContext context); } diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStopping.java similarity index 83% copy from core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java copy to core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStopping.java index 737bdc0..557bf90 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextInitialized.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/OnCamelContextStopping.java @@ -19,9 +19,9 @@ package org.apache.camel.spi; import org.apache.camel.CamelContext; /** - * Notification on initialized a {@link CamelContext}. + * Notification on stopping a {@link CamelContext}. */ @FunctionalInterface -public interface OnCamelContextInitialized extends OnCamelContextEvent { - void onContextInitialized(CamelContext context); +public interface OnCamelContextStopping extends OnCamelContextEvent { + void onContextStopping(CamelContext context); } 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 364fe95..6ccac5b 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 @@ -177,15 +177,6 @@ public abstract class AbstractCamelContext extends BaseService // start auto assigning route ids using numbering 1000 and upwards int defaultRouteStartupOrder = 1000; - public enum Initialization { - Eager, - Default, - Lazy - } - - private VetoCamelContextStartException vetoed; - private String managementName; - private ClassLoader applicationContextClassLoader; private final AtomicInteger endpointKeyCounter = new AtomicInteger(); private final List<EndpointStrategy> endpointStrategies = new ArrayList<>(); private final GlobalEndpointConfiguration globalEndpointConfiguration = new DefaultGlobalEndpointConfiguration(); @@ -194,9 +185,31 @@ public abstract class AbstractCamelContext extends BaseService private final List<Service> servicesToStop = new CopyOnWriteArrayList<>(); private final List<StartupListener> startupListeners = new CopyOnWriteArrayList<>(); private final DeferServiceStartupListener deferStartupListener = new DeferServiceStartupListener(); - private boolean autoCreateComponents = true; private final Map<String, Language> languages = new ConcurrentHashMap<>(); private final List<LifecycleStrategy> lifecycleStrategies = new CopyOnWriteArrayList<>(); + private final ThreadLocal<Boolean> isStartingRoutes = new ThreadLocal<>(); + private final ThreadLocal<Boolean> isSetupRoutes = new ThreadLocal<>(); + private final Map<String, FactoryFinder> factories = new ConcurrentHashMap<>(); + private final Map<String, RouteService> routeServices = new LinkedHashMap<>(); + private final Map<String, RouteService> suspendedRouteServices = new LinkedHashMap<>(); + private final Object lock = new Object(); + private final RouteController internalRouteController = new InternalRouteController(this); + private final InternalRouteStartupManager internalRouteStartupManager = new InternalRouteStartupManager(this); + private final DeferServiceFactory deferServiceFactory = new DefaultDeferServiceFactory(); + private final AnnotationBasedProcessorFactory annotationBasedProcessorFactory + = new DefaultAnnotationBasedProcessorFactory(); + private final List<RouteStartupOrder> routeStartupOrder = new ArrayList<>(); + private final StopWatch stopWatch = new StopWatch(false); + private final ThreadLocal<Set<String>> componentsInCreation = new ThreadLocal<Set<String>>() { + @Override + public Set<String> initialValue() { + return new HashSet<>(); + } + }; + private VetoCamelContextStartException vetoed; + private String managementName; + private ClassLoader applicationContextClassLoader; + private boolean autoCreateComponents = true; private volatile RestConfiguration restConfiguration; private List<InterceptStrategy> interceptStrategies = new ArrayList<>(); private List<RoutePolicyFactory> routePolicyFactories = new ArrayList<>(); @@ -204,8 +217,6 @@ public abstract class AbstractCamelContext extends BaseService // special flags to control the first startup which can are special private volatile boolean firstStartDone; private volatile boolean doNotStartRoutesOnFirstStart; - private final ThreadLocal<Boolean> isStartingRoutes = new ThreadLocal<>(); - private final ThreadLocal<Boolean> isSetupRoutes = new ThreadLocal<>(); private Initialization initialization = Initialization.Default; private Boolean autoStartup = Boolean.TRUE; private Boolean backlogTrace = Boolean.FALSE; @@ -228,11 +239,6 @@ public abstract class AbstractCamelContext extends BaseService private Long delay; private ErrorHandlerFactory errorHandlerFactory; private Map<String, String> globalOptions = new HashMap<>(); - private final Map<String, FactoryFinder> factories = new ConcurrentHashMap<>(); - private final Map<String, RouteService> routeServices = new LinkedHashMap<>(); - private final Map<String, RouteService> suspendedRouteServices = new LinkedHashMap<>(); - - private final Object lock = new Object(); private volatile String version; private volatile PropertiesComponent propertiesComponent; private volatile CamelContextNameStrategy nameStrategy; @@ -275,35 +281,20 @@ public abstract class AbstractCamelContext extends BaseService private volatile UuidGenerator uuidGenerator; private volatile UnitOfWorkFactory unitOfWorkFactory; private volatile RouteController routeController; - private final RouteController internalRouteController = new InternalRouteController(this); - private final InternalRouteStartupManager internalRouteStartupManager = new InternalRouteStartupManager(this); private volatile ScheduledExecutorService errorHandlerExecutorService; private volatile BeanIntrospection beanIntrospection; private volatile Tracer tracer; private volatile boolean eventNotificationApplicable; - private final DeferServiceFactory deferServiceFactory = new DefaultDeferServiceFactory(); - private final AnnotationBasedProcessorFactory annotationBasedProcessorFactory - = new DefaultAnnotationBasedProcessorFactory(); - private volatile TransformerRegistry<TransformerKey> transformerRegistry; private volatile ValidatorRegistry<ValidatorKey> validatorRegistry; private EndpointRegistry<EndpointKey> endpoints; private RuntimeEndpointRegistry runtimeEndpointRegistry; - - private final List<RouteStartupOrder> routeStartupOrder = new ArrayList<>(); private ShutdownRoute shutdownRoute = ShutdownRoute.Default; private ShutdownRunningTask shutdownRunningTask = ShutdownRunningTask.CompleteCurrentTaskOnly; private Debugger debugger; - private final StopWatch stopWatch = new StopWatch(false); private Date startDate; private SSLContextParameters sslContextParameters; - private final ThreadLocal<Set<String>> componentsInCreation = new ThreadLocal<Set<String>>() { - @Override - public Set<String> initialValue() { - return new HashSet<>(); - } - }; private Map<Class<?>, Object> extensions = new ConcurrentHashMap<>(); /** @@ -347,6 +338,25 @@ public abstract class AbstractCamelContext extends BaseService } } + protected static <T> T lookup(CamelContext context, String ref, Class<T> type) { + try { + return context.getRegistry().lookupByNameAndType(ref, type); + } catch (Exception e) { + // need to ignore not same type and return it as null + return null; + } + } + + /** + * Reset context counter to a preset value. Mostly used for tests to ensure a predictable getName() + * + * @param value new value for the context counter + */ + public static void setContextCounter(int value) { + DefaultCamelContextNameStrategy.setCounter(value); + DefaultManagementNameStrategy.setCounter(value); + } + public void close() throws IOException { try { stop(); @@ -637,6 +647,9 @@ public abstract class AbstractCamelContext extends BaseService return answer; } + // Endpoint Management Methods + // ----------------------------------------------------------------------- + @Override public Component removeComponent(String componentName) { Component oldComponent = components.remove(componentName); @@ -653,9 +666,6 @@ public abstract class AbstractCamelContext extends BaseService return oldComponent; } - // Endpoint Management Methods - // ----------------------------------------------------------------------- - @Override public EndpointRegistry<EndpointKey> getEndpointRegistry() { return endpoints; @@ -1074,17 +1084,12 @@ public abstract class AbstractCamelContext extends BaseService } } - @Override - public GlobalEndpointConfiguration getGlobalEndpointConfiguration() { - return globalEndpointConfiguration; - } - // Route Management Methods // ----------------------------------------------------------------------- @Override - public void setRouteController(RouteController routeController) { - this.routeController = doAddService(routeController); + public GlobalEndpointConfiguration getGlobalEndpointConfiguration() { + return globalEndpointConfiguration; } @Override @@ -1100,6 +1105,11 @@ public abstract class AbstractCamelContext extends BaseService } @Override + public void setRouteController(RouteController routeController) { + this.routeController = doAddService(routeController); + } + + @Override public List<RouteStartupOrder> getRouteStartupOrder() { return routeStartupOrder; } @@ -1692,6 +1702,9 @@ public abstract class AbstractCamelContext extends BaseService return null; } + // Helper methods + // ----------------------------------------------------------------------- + public String getEipParameterJsonSchema(String eipName) throws IOException { // the eip json schema may be in some of the sub-packages so look until // we find it @@ -1712,9 +1725,6 @@ public abstract class AbstractCamelContext extends BaseService return null; } - // Helper methods - // ----------------------------------------------------------------------- - @Override public Language resolveLanguage(String language) { Language answer; @@ -1753,6 +1763,9 @@ public abstract class AbstractCamelContext extends BaseService return answer; } + // Properties + // ----------------------------------------------------------------------- + @Override public String resolvePropertyPlaceholders(String text) { if (text != null && text.contains(PropertiesComponent.PREFIX_TOKEN)) { @@ -1778,14 +1791,15 @@ public abstract class AbstractCamelContext extends BaseService return text; } - // Properties - // ----------------------------------------------------------------------- - @Override public TypeConverter getTypeConverter() { return typeConverter; } + public void setTypeConverter(TypeConverter typeConverter) { + this.typeConverter = doAddService(typeConverter); + } + protected TypeConverter getOrCreateTypeConverter() { if (typeConverter == null) { synchronized (lock) { @@ -1797,10 +1811,6 @@ public abstract class AbstractCamelContext extends BaseService return typeConverter; } - public void setTypeConverter(TypeConverter typeConverter) { - this.typeConverter = doAddService(typeConverter); - } - @Override public TypeConverterRegistry getTypeConverterRegistry() { if (typeConverterRegistry == null) { @@ -1962,6 +1972,14 @@ public abstract class AbstractCamelContext extends BaseService } @Override + public void setRegistry(Registry registry) { + if (registry instanceof CamelContextAware) { + ((CamelContextAware) registry).setCamelContext(getCamelContextReference()); + } + this.registry = registry; + } + + @Override public <T> T getRegistry(Class<T> type) { Registry reg = getRegistry(); @@ -1972,14 +1990,6 @@ public abstract class AbstractCamelContext extends BaseService } @Override - public void setRegistry(Registry registry) { - if (registry instanceof CamelContextAware) { - ((CamelContextAware) registry).setCamelContext(getCamelContextReference()); - } - this.registry = registry; - } - - @Override public List<LifecycleStrategy> getLifecycleStrategies() { return lifecycleStrategies; } @@ -2220,15 +2230,15 @@ public abstract class AbstractCamelContext extends BaseService return errorHandlerExecutorService; } + public void setErrorHandlerExecutorService(ScheduledExecutorService errorHandlerExecutorService) { + this.errorHandlerExecutorService = errorHandlerExecutorService; + } + protected ScheduledExecutorService createErrorHandlerExecutorService() { return getExecutorServiceManager().newDefaultScheduledThreadPool("ErrorHandlerRedeliveryThreadPool", "ErrorHandlerRedeliveryTask"); } - public void setErrorHandlerExecutorService(ScheduledExecutorService errorHandlerExecutorService) { - this.errorHandlerExecutorService = errorHandlerExecutorService; - } - @Override public UnitOfWorkFactory getUnitOfWorkFactory() { if (unitOfWorkFactory == null) { @@ -2391,6 +2401,9 @@ public abstract class AbstractCamelContext extends BaseService EventHelper.notifyCamelContextSuspended(this); } + // Implementation methods + // ----------------------------------------------------------------------- + @Override protected void doResume() throws Exception { try { @@ -2428,9 +2441,6 @@ public abstract class AbstractCamelContext extends BaseService } } - // Implementation methods - // ----------------------------------------------------------------------- - @Override protected AutoCloseable doLifecycleChange() { return new LifecycleHelper(); @@ -2474,6 +2484,17 @@ public abstract class AbstractCamelContext extends BaseService } } + for (LifecycleStrategy strategy : lifecycleStrategies) { + try { + strategy.onContextStarted(this); + } catch (Throwable e) { + LOG.warn("Lifecycle strategy {} failed on CamelContext ({}) due to: {}. This exception will be ignored", + strategy, + getName(), + e.getMessage()); + } + } + // okay the routes has been started so emit event that CamelContext // has started (here at the end) EventHelper.notifyCamelContextStarted(this); @@ -2489,6 +2510,23 @@ public abstract class AbstractCamelContext extends BaseService } @Override + public void stop() { + for (LifecycleStrategy strategy : lifecycleStrategies) { + try { + strategy.onContextStopping(this); + strategy.onContextStop(this); + } catch (Throwable e) { + LOG.warn("Lifecycle strategy {} failed on CamelContext ({}) due to: {}. This exception will be ignored", + strategy, + getName(), + e.getMessage()); + } + } + + super.stop(); + } + + @Override public void doBuild() throws Exception { // Initialize LRUCacheFactory as eager as possible, // to let it warm up concurrently while Camel is startup up @@ -2772,6 +2810,7 @@ public abstract class AbstractCamelContext extends BaseService ServiceHelper.startService(lifecycleStrategies); for (LifecycleStrategy strategy : lifecycleStrategies) { try { + strategy.onContextStarting(this); strategy.onContextStart(this); } catch (VetoCamelContextStartException e) { // okay we should not start Camel since it was vetoed @@ -2876,7 +2915,6 @@ public abstract class AbstractCamelContext extends BaseService if (invokedCounter > 0) { LOG.debug("BeanIntrospection invoked {} times during starting Camel", invokedCounter); } - // starting will continue in the start method } @@ -2884,6 +2922,7 @@ public abstract class AbstractCamelContext extends BaseService protected void doStop() throws Exception { stopWatch.restart(); LOG.info("Apache Camel {} ({}) is shutting down", getVersion(), getName()); + EventHelper.notifyCamelContextStopping(this); EventHelper.notifyCamelContextRoutesStopping(this); @@ -2962,18 +3001,18 @@ public abstract class AbstractCamelContext extends BaseService shutdownServices(languages.values()); languages.clear(); + // shutdown services as late as possible (except type converters as they may be needed during the remainder of the stopping) + shutdownServices(servicesToStop); + servicesToStop.clear(); + try { for (LifecycleStrategy strategy : lifecycleStrategies) { - strategy.onContextStop(this); + strategy.onContextStopped(this); } } catch (Throwable e) { LOG.warn("Error occurred while stopping lifecycle strategies. This exception will be ignored.", e); } - // shutdown services as late as possible (except type converters as they may be needed during the remainder of the stopping) - shutdownServices(servicesToStop); - servicesToStop.clear(); - // must notify that we are stopped before stopping the management strategy EventHelper.notifyCamelContextStopped(this); @@ -3724,15 +3763,6 @@ public abstract class AbstractCamelContext extends BaseService return answer; } - protected static <T> T lookup(CamelContext context, String ref, Class<T> type) { - try { - return context.getRegistry().lookupByNameAndType(ref, type); - } catch (Exception e) { - // need to ignore not same type and return it as null - return null; - } - } - @Override public ShutdownStrategy getShutdownStrategy() { if (shutdownStrategy == null) { @@ -4009,13 +4039,13 @@ public abstract class AbstractCamelContext extends BaseService } @Override - public void setSSLContextParameters(SSLContextParameters sslContextParameters) { - this.sslContextParameters = sslContextParameters; + public SSLContextParameters getSSLContextParameters() { + return this.sslContextParameters; } @Override - public SSLContextParameters getSSLContextParameters() { - return this.sslContextParameters; + public void setSSLContextParameters(SSLContextParameters sslContextParameters) { + this.sslContextParameters = sslContextParameters; } @Override @@ -4155,52 +4185,11 @@ public abstract class AbstractCamelContext extends BaseService return routeServices; } - /** - * Reset context counter to a preset value. Mostly used for tests to ensure a predictable getName() - * - * @param value new value for the context counter - */ - public static void setContextCounter(int value) { - DefaultCamelContextNameStrategy.setCounter(value); - DefaultManagementNameStrategy.setCounter(value); - } - @Override public String toString() { return "CamelContext(" + getName() + ")"; } - class LifecycleHelper implements AutoCloseable { - final Map<String, String> originalContextMap; - final ClassLoader tccl; - - LifecycleHelper() { - // Using the ApplicationClassLoader as the default for TCCL - tccl = Thread.currentThread().getContextClassLoader(); - if (applicationContextClassLoader != null) { - Thread.currentThread().setContextClassLoader(applicationContextClassLoader); - } - if (isUseMDCLogging()) { - originalContextMap = MDC.getCopyOfContextMap(); - MDC.put(MDC_CAMEL_CONTEXT_ID, getName()); - } else { - originalContextMap = null; - } - } - - @Override - public void close() { - if (isUseMDCLogging()) { - if (originalContextMap != null) { - MDC.setContextMap(originalContextMap); - } else { - MDC.clear(); - } - } - Thread.currentThread().setContextClassLoader(tccl); - } - } - protected abstract HealthCheckRegistry createHealthCheckRegistry(); protected abstract ReactiveExecutor createReactiveExecutor(); @@ -4307,4 +4296,41 @@ public abstract class AbstractCamelContext extends BaseService public RouteController getInternalRouteController() { return internalRouteController; } + + public enum Initialization { + Eager, + Default, + Lazy + } + + class LifecycleHelper implements AutoCloseable { + final Map<String, String> originalContextMap; + final ClassLoader tccl; + + LifecycleHelper() { + // Using the ApplicationClassLoader as the default for TCCL + tccl = Thread.currentThread().getContextClassLoader(); + if (applicationContextClassLoader != null) { + Thread.currentThread().setContextClassLoader(applicationContextClassLoader); + } + if (isUseMDCLogging()) { + originalContextMap = MDC.getCopyOfContextMap(); + MDC.put(MDC_CAMEL_CONTEXT_ID, getName()); + } else { + originalContextMap = null; + } + } + + @Override + public void close() { + if (isUseMDCLogging()) { + if (originalContextMap != null) { + MDC.setContextMap(originalContextMap); + } else { + MDC.clear(); + } + } + Thread.currentThread().setContextClassLoader(tccl); + } + } } diff --git a/core/camel-base/src/main/java/org/apache/camel/impl/engine/OnCamelContextLifecycleStrategy.java b/core/camel-base/src/main/java/org/apache/camel/impl/engine/OnCamelContextLifecycleStrategy.java index 9449aac..de6a728 100644 --- a/core/camel-base/src/main/java/org/apache/camel/impl/engine/OnCamelContextLifecycleStrategy.java +++ b/core/camel-base/src/main/java/org/apache/camel/impl/engine/OnCamelContextLifecycleStrategy.java @@ -23,7 +23,11 @@ import org.apache.camel.spi.LifecycleStrategy; import org.apache.camel.spi.OnCamelContextInitialized; import org.apache.camel.spi.OnCamelContextInitializing; import org.apache.camel.spi.OnCamelContextStart; +import org.apache.camel.spi.OnCamelContextStarted; +import org.apache.camel.spi.OnCamelContextStarting; import org.apache.camel.spi.OnCamelContextStop; +import org.apache.camel.spi.OnCamelContextStopped; +import org.apache.camel.spi.OnCamelContextStopping; import org.apache.camel.support.LifecycleStrategySupport; /** @@ -69,6 +73,30 @@ class OnCamelContextLifecycleStrategy extends LifecycleStrategySupport { } @Override + public void onContextStarting(CamelContext context) throws VetoCamelContextStartException { + for (OnCamelContextStarting handler : context.getRegistry().findByType(OnCamelContextStarting.class)) { + // RoutesBuilder should register them-self to the camel context + // to avoid invoking them multiple times if routes are discovered + // from the registry (i.e. camel-main) + if (!(handler instanceof RoutesBuilder)) { + handler.onContextStarting(context); + } + } + } + + @Override + public void onContextStarted(CamelContext context) { + for (OnCamelContextStarted handler : context.getRegistry().findByType(OnCamelContextStarted.class)) { + // RoutesBuilder should register them-self to the camel context + // to avoid invoking them multiple times if routes are discovered + // from the registry (i.e. camel-main) + if (!(handler instanceof RoutesBuilder)) { + handler.onContextStarted(context); + } + } + } + + @Override public void onContextStop(CamelContext context) { for (OnCamelContextStop handler : context.getRegistry().findByType(OnCamelContextStop.class)) { // RoutesBuilder should register them-self to the camel context @@ -80,4 +108,28 @@ class OnCamelContextLifecycleStrategy extends LifecycleStrategySupport { } } + @Override + public void onContextStopping(CamelContext context) { + for (OnCamelContextStopping handler : context.getRegistry().findByType(OnCamelContextStopping.class)) { + // RoutesBuilder should register them-self to the camel context + // to avoid invoking them multiple times if routes are discovered + // from the registry (i.e. camel-main) + if (!(handler instanceof RoutesBuilder)) { + handler.onContextStopping(context); + } + } + } + + @Override + public void onContextStopped(CamelContext context) { + for (OnCamelContextStopped handler : context.getRegistry().findByType(OnCamelContextStopped.class)) { + // RoutesBuilder should register them-self to the camel context + // to avoid invoking them multiple times if routes are discovered + // from the registry (i.e. camel-main) + if (!(handler instanceof RoutesBuilder)) { + handler.onContextStopped(context); + } + } + } + } diff --git a/core/camel-core/src/test/java/org/apache/camel/impl/LifecycleStrategyDiscoveryTest.java b/core/camel-core/src/test/java/org/apache/camel/impl/LifecycleStrategyDiscoveryTest.java index 7347808..81d2941 100644 --- a/core/camel-core/src/test/java/org/apache/camel/impl/LifecycleStrategyDiscoveryTest.java +++ b/core/camel-core/src/test/java/org/apache/camel/impl/LifecycleStrategyDiscoveryTest.java @@ -29,6 +29,12 @@ import org.junit.jupiter.api.Test; import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextInitialized; import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextInitializing; +import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextStart; +import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextStarted; +import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextStarting; +import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextStop; +import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextStopped; +import static org.apache.camel.support.LifecycleStrategySupport.onCamelContextStopping; import static org.junit.jupiter.api.Assertions.assertEquals; public class LifecycleStrategyDiscoveryTest extends TestSupport { @@ -37,7 +43,11 @@ public class LifecycleStrategyDiscoveryTest extends TestSupport { final AtomicInteger onInitializing = new AtomicInteger(); final AtomicInteger onInitialized = new AtomicInteger(); final AtomicInteger onStart = new AtomicInteger(); + final AtomicInteger onStarting = new AtomicInteger(); + final AtomicInteger onStarted = new AtomicInteger(); final AtomicInteger onStop = new AtomicInteger(); + final AtomicInteger onStopping = new AtomicInteger(); + final AtomicInteger onStopped = new AtomicInteger(); final AtomicInteger onInitializingRoute = new AtomicInteger(); final AtomicInteger onInitializedRoute = new AtomicInteger(); final AtomicInteger onStartRoute = new AtomicInteger(); @@ -46,12 +56,18 @@ public class LifecycleStrategyDiscoveryTest extends TestSupport { CamelContext context = new DefaultCamelContext(); context.getRegistry().bind("myOnInitializing", onCamelContextInitializing(c -> onInitializing.incrementAndGet())); context.getRegistry().bind("myOnInitialized", onCamelContextInitialized(c -> onInitialized.incrementAndGet())); - context.getRegistry().bind("myOnStart", onCamelContextInitialized(c -> onStart.incrementAndGet())); - context.getRegistry().bind("myOnStop", onCamelContextInitialized(c -> onStop.incrementAndGet())); + context.getRegistry().bind("myOnStart", onCamelContextStart(c -> onStart.incrementAndGet())); + context.getRegistry().bind("myOnStarting", onCamelContextStarting(c -> onStarting.incrementAndGet())); + context.getRegistry().bind("myOnStarted", onCamelContextStarted(c -> onStarted.incrementAndGet())); + context.getRegistry().bind("myOnStop", onCamelContextStop(c -> onStop.incrementAndGet())); + context.getRegistry().bind("myOnStopping", onCamelContextStopping(c -> onStopping.incrementAndGet())); + context.getRegistry().bind("myOnStopped", onCamelContextStopped(c -> onStopped.incrementAndGet())); try { - class MyBuilder extends RouteBuilder + class MyBuilder + extends RouteBuilder implements OnCamelContextInitializing, OnCamelContextInitialized, OnCamelContextStart, OnCamelContextStop { + @Override public void configure() throws Exception { } @@ -86,7 +102,11 @@ public class LifecycleStrategyDiscoveryTest extends TestSupport { assertEquals(1, onInitializing.get()); assertEquals(1, onInitialized.get()); assertEquals(1, onStart.get()); + assertEquals(1, onStarting.get()); + assertEquals(1, onStarted.get()); assertEquals(1, onStop.get()); + assertEquals(1, onStopping.get()); + assertEquals(1, onStopped.get()); assertEquals(1, onInitializingRoute.get()); assertEquals(1, onInitializedRoute.get()); assertEquals(1, onStartRoute.get()); diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainLifecycleStrategy.java b/core/camel-main/src/main/java/org/apache/camel/main/MainLifecycleStrategy.java index f723d35..080aaea 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/MainLifecycleStrategy.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/MainLifecycleStrategy.java @@ -34,7 +34,7 @@ public class MainLifecycleStrategy extends LifecycleStrategySupport { } @Override - public void onContextStop(CamelContext context) { + public void onContextStopping(CamelContext context) { LOG.info("CamelContext: {} has been shutdown, triggering shutdown of the JVM.", context.getName()); // trigger stopping the Main 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 1318fd4..fc70cba 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 @@ -167,7 +167,7 @@ public class JmxManagementLifecycleStrategy extends ServiceSupport implements Li } @Override - public void onContextStart(CamelContext context) throws VetoCamelContextStartException { + public void onContextStarting(CamelContext context) throws VetoCamelContextStartException { Object mc = getManagementObjectStrategy().getManagedObjectForCamelContext(context); String name = context.getName(); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java b/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java index 37627bd..4e8d7ba 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/LifecycleStrategySupport.java @@ -33,93 +33,33 @@ import org.apache.camel.spi.OnCamelContextEvent; import org.apache.camel.spi.OnCamelContextInitialized; import org.apache.camel.spi.OnCamelContextInitializing; import org.apache.camel.spi.OnCamelContextStart; +import org.apache.camel.spi.OnCamelContextStarted; +import org.apache.camel.spi.OnCamelContextStarting; import org.apache.camel.spi.OnCamelContextStop; +import org.apache.camel.spi.OnCamelContextStopped; +import org.apache.camel.spi.OnCamelContextStopping; /** * A useful base class for {@link LifecycleStrategy} implementations. */ public abstract class LifecycleStrategySupport implements LifecycleStrategy { - @Override - public void onContextStart(CamelContext context) throws VetoCamelContextStartException { - // noop - } - - @Override - public void onContextStop(CamelContext context) { - // noop - } - - @Override - public void onComponentAdd(String name, Component component) { - // noop - } - - @Override - public void onComponentRemove(String name, Component component) { - // noop - } - - @Override - public void onEndpointAdd(Endpoint endpoint) { - // noop - } - - @Override - public void onEndpointRemove(Endpoint endpoint) { - // noop - } - - @Override - public void onServiceAdd(CamelContext context, Service service, org.apache.camel.Route route) { - // noop - } - - @Override - public void onServiceRemove(CamelContext context, Service service, org.apache.camel.Route route) { - // noop - } - - @Override - public void onRoutesAdd(Collection<org.apache.camel.Route> routes) { - // noop - } - - @Override - public void onRoutesRemove(Collection<org.apache.camel.Route> routes) { - // noop - } - - @Override - public void onRouteContextCreate(Route route) { - // noop - } - - @Override - public void onErrorHandlerAdd(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerBuilder) { - // noop - } - - @Override - public void onErrorHandlerRemove(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerBuilder) { - // noop - } - - @Override - public void onThreadPoolAdd( - CamelContext camelContext, ThreadPoolExecutor threadPool, String id, - String sourceId, String routeId, String threadPoolProfileId) { - // noop - } - - @Override - public void onThreadPoolRemove(CamelContext camelContext, ThreadPoolExecutor threadPool) { - // noop - } + // ******************************* + // + // Helpers (adapters) + // + // ******************************** public static LifecycleStrategy adapt(OnCamelContextEvent handler) { return new LifecycleStrategySupport() { @Override + public void onContextInitializing(CamelContext context) throws VetoCamelContextStartException { + if (handler instanceof OnCamelContextInitializing) { + ((OnCamelContextInitializing) handler).onContextInitializing(context); + } + } + + @Override public void onContextInitialized(CamelContext context) throws VetoCamelContextStartException { if (handler instanceof OnCamelContextInitialized) { ((OnCamelContextInitialized) handler).onContextInitialized(context); @@ -134,11 +74,39 @@ public abstract class LifecycleStrategySupport implements LifecycleStrategy { } @Override + public void onContextStarting(CamelContext context) throws VetoCamelContextStartException { + if (handler instanceof OnCamelContextStarting) { + ((OnCamelContextStarting) handler).onContextStarting(context); + } + } + + @Override + public void onContextStarted(CamelContext context) { + if (handler instanceof OnCamelContextStarted) { + ((OnCamelContextStarted) handler).onContextStarted(context); + } + } + + @Override public void onContextStop(CamelContext context) { if (handler instanceof OnCamelContextStop) { ((OnCamelContextStop) handler).onContextStop(context); } } + + @Override + public void onContextStopping(CamelContext context) { + if (handler instanceof OnCamelContextStopping) { + ((OnCamelContextStopping) handler).onContextStopping(context); + } + } + + @Override + public void onContextStopped(CamelContext context) { + if (handler instanceof OnCamelContextStopped) { + ((OnCamelContextStopped) handler).onContextStopped(context); + } + } }; } @@ -160,6 +128,7 @@ public abstract class LifecycleStrategySupport implements LifecycleStrategy { }; } + @Deprecated public static LifecycleStrategy adapt(OnCamelContextStart handler) { return new LifecycleStrategySupport() { @Override @@ -169,6 +138,25 @@ public abstract class LifecycleStrategySupport implements LifecycleStrategy { }; } + public static LifecycleStrategy adapt(OnCamelContextStarting handler) { + return new LifecycleStrategySupport() { + @Override + public void onContextStarting(CamelContext context) throws VetoCamelContextStartException { + handler.onContextStarting(context); + } + }; + } + + public static LifecycleStrategy adapt(OnCamelContextStarted handler) { + return new LifecycleStrategySupport() { + @Override + public void onContextStarted(CamelContext context) { + handler.onContextStarted(context); + } + }; + } + + @Deprecated public static LifecycleStrategy adapt(OnCamelContextStop handler) { return new LifecycleStrategySupport() { @Override @@ -178,6 +166,30 @@ public abstract class LifecycleStrategySupport implements LifecycleStrategy { }; } + public static LifecycleStrategy adapt(OnCamelContextStopping handler) { + return new LifecycleStrategySupport() { + @Override + public void onContextStopping(CamelContext context) { + handler.onContextStopping(context); + } + }; + } + + public static LifecycleStrategy adapt(OnCamelContextStopped handler) { + return new LifecycleStrategySupport() { + @Override + public void onContextStopped(CamelContext context) { + handler.onContextStopped(context); + } + }; + } + + // ******************************* + // + // Helpers (functional) + // + // ******************************** + public static OnCamelContextInitializing onCamelContextInitializing(Consumer<CamelContext> consumer) { return consumer::accept; } @@ -186,11 +198,120 @@ public abstract class LifecycleStrategySupport implements LifecycleStrategy { return consumer::accept; } + @Deprecated public static OnCamelContextStart onCamelContextStart(Consumer<CamelContext> consumer) { return consumer::accept; } + public static OnCamelContextStarting onCamelContextStarting(Consumer<CamelContext> consumer) { + return consumer::accept; + } + + public static OnCamelContextStarted onCamelContextStarted(Consumer<CamelContext> consumer) { + return consumer::accept; + } + + @Deprecated public static OnCamelContextStop onCamelContextStop(Consumer<CamelContext> consumer) { return consumer::accept; } + + public static OnCamelContextStopping onCamelContextStopping(Consumer<CamelContext> consumer) { + return consumer::accept; + } + + public static OnCamelContextStopped onCamelContextStopped(Consumer<CamelContext> consumer) { + return consumer::accept; + } + + // ******************************* + // + // Helpers + // + // ******************************** + + /** + * @deprecated see {@link LifecycleStrategy#onContextStart(CamelContext)} + */ + @Deprecated + @Override + public void onContextStart(CamelContext context) throws VetoCamelContextStartException { + // noop + } + + /** + * @deprecated see {@link LifecycleStrategy#onContextStop(CamelContext)} + */ + @Deprecated + @Override + public void onContextStop(CamelContext context) { + // noop + } + + @Override + public void onComponentAdd(String name, Component component) { + // noop + } + + @Override + public void onComponentRemove(String name, Component component) { + // noop + } + + @Override + public void onEndpointAdd(Endpoint endpoint) { + // noop + } + + @Override + public void onEndpointRemove(Endpoint endpoint) { + // noop + } + + @Override + public void onServiceAdd(CamelContext context, Service service, org.apache.camel.Route route) { + // noop + } + + @Override + public void onServiceRemove(CamelContext context, Service service, org.apache.camel.Route route) { + // noop + } + + @Override + public void onRoutesAdd(Collection<org.apache.camel.Route> routes) { + // noop + } + + @Override + public void onRoutesRemove(Collection<org.apache.camel.Route> routes) { + // noop + } + + @Override + public void onRouteContextCreate(Route route) { + // noop + } + + @Override + public void onErrorHandlerAdd(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerBuilder) { + // noop + } + + @Override + public void onErrorHandlerRemove(Route route, Processor errorHandler, ErrorHandlerFactory errorHandlerBuilder) { + // noop + } + + @Override + public void onThreadPoolAdd( + CamelContext camelContext, ThreadPoolExecutor threadPool, String id, + String sourceId, String routeId, String threadPoolProfileId) { + // noop + } + + @Override + public void onThreadPoolRemove(CamelContext camelContext, ThreadPoolExecutor threadPool) { + // noop + } }