You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by or...@apache.org on 2023/03/24 11:56:03 UTC
[camel] branch main updated: CAMEL-15105: decouple handling of internal services
This is an automated email from the ASF dual-hosted git repository.
orpiske pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 7d455ef7aec CAMEL-15105: decouple handling of internal services
7d455ef7aec is described below
commit 7d455ef7aec2391e6c00549c3ca6e4e2eb4963fa
Author: Otavio Rodolfo Piske <an...@gmail.com>
AuthorDate: Fri Mar 24 10:53:36 2023 +0100
CAMEL-15105: decouple handling of internal services
Implement a handler for managing the internal services and their lifecycle.
---
.../camel/impl/engine/AbstractCamelContext.java | 220 ++++------------
.../impl/engine/DefaultCamelContextExtension.java | 65 ++---
.../camel/impl/engine/InternalServiceHelper.java | 142 -----------
.../camel/impl/engine/InternalServiceManager.java | 278 +++++++++++++++++++++
4 files changed, 366 insertions(+), 339 deletions(-)
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 9d3c13ffff2..d93243898b8 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -47,14 +47,12 @@ import org.apache.camel.CamelContext;
import org.apache.camel.CamelContextAware;
import org.apache.camel.CatalogCamelContext;
import org.apache.camel.Component;
-import org.apache.camel.Consumer;
import org.apache.camel.ConsumerTemplate;
import org.apache.camel.Endpoint;
import org.apache.camel.ExtendedCamelContext;
import org.apache.camel.FailedToStartComponentException;
import org.apache.camel.FluentProducerTemplate;
import org.apache.camel.GlobalEndpointConfiguration;
-import org.apache.camel.IsSingleton;
import org.apache.camel.LoggingLevel;
import org.apache.camel.NoSuchEndpointException;
import org.apache.camel.Processor;
@@ -201,8 +199,9 @@ public abstract class AbstractCamelContext extends BaseService
private static final Logger LOG = LoggerFactory.getLogger(AbstractCamelContext.class);
+ protected final InternalServiceManager internalServiceManager;
+
// start auto assigning route ids using numbering 1000 and upwards
- final List<Service> servicesToStop = new CopyOnWriteArrayList<>();
final List<BootstrapCloseable> bootstraps = new CopyOnWriteArrayList<>();
final Map<String, FactoryFinder> bootstrapFactories = new ConcurrentHashMap<>();
volatile FactoryFinder bootstrapFactoryFinder;
@@ -264,7 +263,6 @@ public abstract class AbstractCamelContext extends BaseService
private final Map<String, Component> components = new ConcurrentHashMap<>();
private final Set<Route> routes = new LinkedHashSet<>();
private final List<StartupListener> startupListeners = new CopyOnWriteArrayList<>();
- private final DeferServiceStartupListener deferStartupListener = new DeferServiceStartupListener();
private final Map<String, Language> languages = new ConcurrentHashMap<>();
private final Map<String, DataFormat> dataformats = new ConcurrentHashMap<>();
private final List<LifecycleStrategy> lifecycleStrategies = new CopyOnWriteArrayList<>();
@@ -375,9 +373,6 @@ public abstract class AbstractCamelContext extends BaseService
// DefaultEndpointRegistry later, but we do this to startup Camel faster.
this.endpoints = new ProvisionalEndpointRegistry();
- // add the defer service startup listener
- this.startupListeners.add(deferStartupListener);
-
// add a default LifecycleStrategy that discover strategies on the registry and invoke them
this.lifecycleStrategies.add(new OnCamelContextLifecycleStrategy());
@@ -398,6 +393,8 @@ public abstract class AbstractCamelContext extends BaseService
}
});
+ this.internalServiceManager = new InternalServiceManager(this, internalRouteStartupManager, startupListeners);
+
if (build) {
try {
build();
@@ -475,7 +472,7 @@ public abstract class AbstractCamelContext extends BaseService
public <T> void setExtension(Class<T> type, T module) {
if (module != null) {
try {
- extensions.put(type, doAddService(module));
+ extensions.put(type, internalServiceManager.addService(module));
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
@@ -507,7 +504,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setNameStrategy(CamelContextNameStrategy nameStrategy) {
- this.nameStrategy = doAddService(nameStrategy);
+ this.nameStrategy = internalServiceManager.addService(nameStrategy);
}
@Override
@@ -524,7 +521,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setManagementNameStrategy(ManagementNameStrategy managementNameStrategy) {
- this.managementNameStrategy = doAddService(managementNameStrategy);
+ this.managementNameStrategy = internalServiceManager.addService(managementNameStrategy);
}
@Override
@@ -1003,7 +1000,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setRouteController(RouteController routeController) {
- this.routeController = doAddService(routeController);
+ this.routeController = internalServiceManager.addService(routeController);
}
@Override
@@ -1402,31 +1399,12 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void addService(Object object, boolean stopOnShutdown, boolean forceStart) throws Exception {
- InternalServiceHelper.internalAddService(object, stopOnShutdown, forceStart, true, this,
- internalRouteStartupManager, servicesToStop, deferStartupListener);
+ internalServiceManager.doAddService(object, stopOnShutdown, forceStart, true);
}
@Override
public void addPrototypeService(Object object) throws Exception {
- doAddService(object, false, true, false);
- }
-
- protected <T> T doAddService(T object) {
- return doAddService(object, true);
- }
-
- protected <T> T doAddService(T object, boolean stopOnShutdown) {
- return doAddService(object, stopOnShutdown, true, true);
- }
-
- protected <T> T doAddService(T object, boolean stopOnShutdown, boolean forceStart, boolean useLifecycleStrategies) {
- try {
- InternalServiceHelper.internalAddService(object, stopOnShutdown, forceStart, useLifecycleStrategies, this,
- internalRouteStartupManager, servicesToStop, deferStartupListener);
- } catch (Exception e) {
- throw RuntimeCamelException.wrapRuntimeCamelException(e);
- }
- return object;
+ internalServiceManager.addService(object, false, true, false);
}
@Override
@@ -1440,81 +1418,30 @@ public abstract class AbstractCamelContext extends BaseService
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onServiceRemove(this, service, null);
}
- return servicesToStop.remove(service);
+
+ return internalServiceManager.removeService(service);
}
return false;
}
@Override
public boolean hasService(Object object) {
- if (servicesToStop.isEmpty()) {
- return false;
- }
- if (object instanceof Service) {
- Service service = (Service) object;
- return servicesToStop.contains(service);
- }
- return false;
+ return internalServiceManager.hasService(object);
}
@Override
public <T> T hasService(Class<T> type) {
- if (servicesToStop.isEmpty()) {
- return null;
- }
- for (Service service : servicesToStop) {
- if (type.isInstance(service)) {
- return type.cast(service);
- }
- }
- return null;
+ return internalServiceManager.hasService(type);
}
@Override
- @SuppressWarnings("unchecked")
public <T> Set<T> hasServices(Class<T> type) {
- if (servicesToStop.isEmpty()) {
- return Collections.emptySet();
- }
- Set<T> set = new HashSet<>();
- for (Service service : servicesToStop) {
- if (type.isInstance(service)) {
- set.add((T) service);
- }
- }
- return set;
+ return internalServiceManager.hasServices(type);
}
@Override
public void deferStartService(Object object, boolean stopOnShutdown) throws Exception {
- deferStartService(object, stopOnShutdown, false);
- }
-
- public void deferStartService(Object object, boolean stopOnShutdown, boolean startEarly) throws Exception {
- if (object instanceof Service) {
- Service service = (Service) object;
-
- // only add to services to close if its a singleton
- // otherwise we could for example end up with a lot of prototype
- // scope endpoints
- boolean singleton = true; // assume singleton by default
- if (object instanceof IsSingleton) {
- singleton = ((IsSingleton) service).isSingleton();
- }
- // do not add endpoints as they have their own list
- if (singleton && !(service instanceof Endpoint)) {
- // only add to list of services to stop if its not already there
- if (stopOnShutdown && !hasService(service)) {
- servicesToStop.add(service);
- }
- }
- // are we already started?
- if (isStarted()) {
- ServiceHelper.startService(service);
- } else {
- deferStartupListener.addService(service, startEarly);
- }
- }
+ internalServiceManager.deferStartService(object, stopOnShutdown, false);
}
protected List<StartupListener> getStartupListeners() {
@@ -1712,7 +1639,7 @@ public abstract class AbstractCamelContext extends BaseService
}
public void setTypeConverter(TypeConverter typeConverter) {
- this.typeConverter = doAddService(typeConverter);
+ this.typeConverter = internalServiceManager.addService(typeConverter);
}
protected TypeConverter getOrCreateTypeConverter() {
@@ -1740,7 +1667,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setTypeConverterRegistry(TypeConverterRegistry typeConverterRegistry) {
- this.typeConverterRegistry = doAddService(typeConverterRegistry);
+ this.typeConverterRegistry = internalServiceManager.addService(typeConverterRegistry);
// some registries are also a type converter implementation
if (typeConverterRegistry instanceof TypeConverter) {
this.typeConverter = (TypeConverter) typeConverterRegistry;
@@ -1761,7 +1688,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setInjector(Injector injector) {
- this.injector = doAddService(injector);
+ this.injector = internalServiceManager.addService(injector);
}
@Override
@@ -1778,11 +1705,11 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setPropertiesComponent(PropertiesComponent propertiesComponent) {
- this.propertiesComponent = doAddService(propertiesComponent);
+ this.propertiesComponent = internalServiceManager.addService(propertiesComponent);
}
public void setManagementMBeanAssembler(ManagementMBeanAssembler managementMBeanAssembler) {
- this.managementMBeanAssembler = doAddService(managementMBeanAssembler, false);
+ this.managementMBeanAssembler = internalServiceManager.addService(managementMBeanAssembler, false);
}
public void setAutoCreateComponents(boolean autoCreateComponents) {
@@ -2018,7 +1945,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setRuntimeEndpointRegistry(RuntimeEndpointRegistry runtimeEndpointRegistry) {
- this.runtimeEndpointRegistry = doAddService(runtimeEndpointRegistry);
+ this.runtimeEndpointRegistry = internalServiceManager.addService(runtimeEndpointRegistry);
}
@Override
@@ -2480,7 +2407,7 @@ public abstract class AbstractCamelContext extends BaseService
// 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));
+ endpoints = internalServiceManager.addService(createEndpointRegistry(endpoints));
// optimised to not include runtimeEndpointRegistry unless startServices
// is enabled or JMX statistics is in extended mode
@@ -3024,7 +2951,7 @@ public abstract class AbstractCamelContext extends BaseService
// shutdown await manager to trigger interrupt of blocked threads to
// attempt to free these threads graceful
- shutdownServices(asyncProcessorAwaitManager);
+ InternalServiceManager.shutdownServices(this, asyncProcessorAwaitManager);
// we need also to include routes which failed to start to ensure all resources get stopped when stopping Camel
for (RouteService routeService : routeServices.values()) {
@@ -3042,7 +2969,7 @@ public abstract class AbstractCamelContext extends BaseService
RouteService routeService = order.getRouteService();
list.add(routeService);
}
- shutdownServices(list, false);
+ InternalServiceManager.shutdownServices(this, list, false);
if (startupSummaryLevel != StartupSummaryLevel.Oneline
&& startupSummaryLevel != StartupSummaryLevel.Off) {
@@ -3062,11 +2989,7 @@ public abstract class AbstractCamelContext extends BaseService
// consumer (eg @Consumer)
// which we need to stop after the routes, as a POJO consumer is
// essentially a route also
- for (Service service : servicesToStop) {
- if (service instanceof Consumer) {
- shutdownServices(service);
- }
- }
+ internalServiceManager.stopConsumers();
// the stop order is important
@@ -3080,18 +3003,17 @@ public abstract class AbstractCamelContext extends BaseService
// shutdown debugger
ServiceHelper.stopAndShutdownService(getDebugger());
- shutdownServices(endpoints.values());
+ InternalServiceManager.shutdownServices(this, endpoints.values());
endpoints.clear();
- shutdownServices(components.values());
+ InternalServiceManager.shutdownServices(this, components.values());
components.clear();
- shutdownServices(languages.values());
+ InternalServiceManager.shutdownServices(this, 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();
+ internalServiceManager.shutdownServices();
try {
for (LifecycleStrategy strategy : lifecycleStrategies) {
@@ -3107,20 +3029,20 @@ public abstract class AbstractCamelContext extends BaseService
// stop the notifier service
if (getManagementStrategy() != null) {
for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
- shutdownServices(notifier);
+ InternalServiceManager.shutdownServices(this, notifier);
}
}
// shutdown management and lifecycle after all other services
- shutdownServices(managementStrategy);
- shutdownServices(managementMBeanAssembler);
- shutdownServices(lifecycleStrategies);
+ InternalServiceManager.shutdownServices(this, managementStrategy);
+ InternalServiceManager.shutdownServices(this, managementMBeanAssembler);
+ InternalServiceManager.shutdownServices(this, lifecycleStrategies);
// do not clear lifecycleStrategies as we can start Camel again and get
// the route back as before
// shutdown executor service, reactive executor last
- shutdownServices(executorServiceManager);
- shutdownServices(reactiveExecutor);
+ InternalServiceManager.shutdownServices(this, executorServiceManager);
+ InternalServiceManager.shutdownServices(this, reactiveExecutor);
// shutdown type converter and registry as late as possible
ServiceHelper.stopService(typeConverter);
@@ -3235,42 +3157,6 @@ public abstract class AbstractCamelContext extends BaseService
return false;
}
- private void shutdownServices(Object service) {
- // do not rethrow exception as we want to keep shutting down in case of
- // problems
-
- // allow us to do custom work before delegating to service helper
- try {
- if (service instanceof Service) {
- ServiceHelper.stopAndShutdownService(service);
- } else if (service instanceof Collection) {
- ServiceHelper.stopAndShutdownServices((Collection<?>) service);
- }
- } catch (Throwable e) {
- LOG.warn("Error occurred while shutting down service: " + service + ". This exception will be ignored.", e);
- // fire event
- EventHelper.notifyServiceStopFailure(this, service, e);
- }
- }
-
- private void shutdownServices(Collection<?> services) {
- // reverse stopping by default
- shutdownServices(services, true);
- }
-
- private void shutdownServices(Collection<?> services, boolean reverse) {
- Collection<?> list = services;
- if (reverse) {
- List<Object> reverseList = new ArrayList<>(services);
- Collections.reverse(reverseList);
- list = reverseList;
- }
-
- for (Object service : list) {
- shutdownServices(service);
- }
- }
-
void startService(Service service) throws Exception {
// and register startup aware so they can be notified when
// camel context has been started
@@ -3562,7 +3448,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setClassResolver(ClassResolver classResolver) {
- this.classResolver = doAddService(classResolver);
+ this.classResolver = internalServiceManager.addService(classResolver);
}
@Override
@@ -3639,7 +3525,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setInflightRepository(InflightRepository repository) {
- this.inflightRepository = doAddService(repository);
+ this.inflightRepository = internalServiceManager.addService(repository);
}
@Override
@@ -3846,7 +3732,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setShutdownStrategy(ShutdownStrategy shutdownStrategy) {
- this.shutdownStrategy = doAddService(shutdownStrategy);
+ this.shutdownStrategy = internalServiceManager.addService(shutdownStrategy);
}
@Override
@@ -3915,7 +3801,7 @@ public abstract class AbstractCamelContext extends BaseService
public void setExecutorServiceManager(ExecutorServiceManager executorServiceManager) {
// special for executorServiceManager as want to stop it manually so
// false in stopOnShutdown
- this.executorServiceManager = doAddService(executorServiceManager, false);
+ this.executorServiceManager = internalServiceManager.addService(executorServiceManager, false);
}
@Override
@@ -3932,7 +3818,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setMessageHistoryFactory(MessageHistoryFactory messageHistoryFactory) {
- this.messageHistoryFactory = doAddService(messageHistoryFactory);
+ this.messageHistoryFactory = internalServiceManager.addService(messageHistoryFactory);
// enable message history if we set a custom factory
setMessageHistory(true);
}
@@ -3949,7 +3835,7 @@ public abstract class AbstractCamelContext extends BaseService
if (isStartingOrStarted()) {
throw new IllegalStateException("Cannot set debugger on a started CamelContext");
}
- this.debugger = doAddService(debugger, true, false, true);
+ this.debugger = internalServiceManager.addService(debugger, true, false, true);
}
@Override
@@ -3970,7 +3856,7 @@ public abstract class AbstractCamelContext extends BaseService
if (!isTracingStandby() && isStartingOrStarted()) {
throw new IllegalStateException("Cannot set tracer on a started CamelContext");
}
- this.tracer = doAddService(tracer, true, false, true);
+ this.tracer = internalServiceManager.addService(tracer, true, false, true);
}
@Override
@@ -4007,7 +3893,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setUuidGenerator(UuidGenerator uuidGenerator) {
- this.uuidGenerator = doAddService(uuidGenerator);
+ this.uuidGenerator = internalServiceManager.addService(uuidGenerator);
}
@Override
@@ -4024,7 +3910,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setStreamCachingStrategy(StreamCachingStrategy streamCachingStrategy) {
- this.streamCachingStrategy = doAddService(streamCachingStrategy, true, false, true);
+ this.streamCachingStrategy = internalServiceManager.addService(streamCachingStrategy, true, false, true);
}
@Override
@@ -4041,7 +3927,7 @@ public abstract class AbstractCamelContext extends BaseService
@Override
public void setRestRegistry(RestRegistry restRegistry) {
- this.restRegistry = doAddService(restRegistry);
+ this.restRegistry = internalServiceManager.addService(restRegistry);
}
protected RestRegistry createRestRegistry() {
@@ -4061,7 +3947,7 @@ public abstract class AbstractCamelContext extends BaseService
}
public void setRestRegistryFactory(RestRegistryFactory restRegistryFactory) {
- this.restRegistryFactory = doAddService(restRegistryFactory);
+ this.restRegistryFactory = internalServiceManager.addService(restRegistryFactory);
}
@Override
@@ -4100,7 +3986,7 @@ public abstract class AbstractCamelContext extends BaseService
}
public void setTransformerRegistry(TransformerRegistry transformerRegistry) {
- this.transformerRegistry = doAddService(transformerRegistry);
+ this.transformerRegistry = internalServiceManager.addService(transformerRegistry);
}
@Override
@@ -4121,7 +4007,7 @@ public abstract class AbstractCamelContext extends BaseService
}
public void setValidatorRegistry(ValidatorRegistry validatorRegistry) {
- this.validatorRegistry = doAddService(validatorRegistry);
+ this.validatorRegistry = internalServiceManager.addService(validatorRegistry);
}
@Override
@@ -4145,11 +4031,11 @@ public abstract class AbstractCamelContext extends BaseService
}
public void setBeanProxyFactory(BeanProxyFactory beanProxyFactory) {
- this.beanProxyFactory = doAddService(beanProxyFactory);
+ this.beanProxyFactory = internalServiceManager.addService(beanProxyFactory);
}
public void setBeanProcessorFactory(BeanProcessorFactory beanProcessorFactory) {
- this.beanProcessorFactory = doAddService(beanProcessorFactory);
+ this.beanProcessorFactory = internalServiceManager.addService(beanProcessorFactory);
}
public boolean isLogJvmUptime() {
@@ -4533,4 +4419,8 @@ public abstract class AbstractCamelContext extends BaseService
List<RouteStartupOrder> getRouteStartupOrder() {
return routeStartupOrder;
}
+
+ InternalServiceManager getInternalServiceManager() {
+ return internalServiceManager;
+ }
}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
index f7e988cf761..736b8d39dff 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelContextExtension.java
@@ -18,7 +18,6 @@
package org.apache.camel.impl.engine;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -219,7 +218,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public List<Service> getServices() {
- return Collections.unmodifiableList(camelContext.servicesToStop);
+ return camelContext.getInternalServiceManager().getServices();
}
@Override
@@ -261,7 +260,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setBeanPostProcessor(CamelBeanPostProcessor beanPostProcessor) {
- camelContext.beanPostProcessor = camelContext.doAddService(beanPostProcessor);
+ camelContext.beanPostProcessor = camelContext.getInternalServiceManager().addService(beanPostProcessor);
}
@Override
@@ -299,7 +298,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setComponentResolver(ComponentResolver componentResolver) {
- camelContext.componentResolver = camelContext.doAddService(componentResolver);
+ camelContext.componentResolver = camelContext.getInternalServiceManager().addService(componentResolver);
}
public ComponentNameResolver getComponentNameResolver() {
@@ -314,7 +313,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setComponentNameResolver(ComponentNameResolver componentNameResolver) {
- camelContext.componentNameResolver = camelContext.doAddService(componentNameResolver);
+ camelContext.componentNameResolver = camelContext.getInternalServiceManager().addService(componentNameResolver);
}
public LanguageResolver getLanguageResolver() {
@@ -329,7 +328,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setLanguageResolver(LanguageResolver languageResolver) {
- camelContext.languageResolver = camelContext.doAddService(languageResolver);
+ camelContext.languageResolver = camelContext.getInternalServiceManager().addService(languageResolver);
}
public ConfigurerResolver getConfigurerResolver() {
@@ -344,7 +343,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setConfigurerResolver(ConfigurerResolver configurerResolver) {
- camelContext.configurerResolver = camelContext.doAddService(configurerResolver);
+ camelContext.configurerResolver = camelContext.getInternalServiceManager().addService(configurerResolver);
}
public UriFactoryResolver getUriFactoryResolver() {
@@ -359,7 +358,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setUriFactoryResolver(UriFactoryResolver uriFactoryResolver) {
- camelContext.uriFactoryResolver = camelContext.doAddService(uriFactoryResolver);
+ camelContext.uriFactoryResolver = camelContext.getInternalServiceManager().addService(uriFactoryResolver);
}
@Override
@@ -454,7 +453,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setUnitOfWorkFactory(UnitOfWorkFactory unitOfWorkFactory) {
- camelContext.unitOfWorkFactory = camelContext.doAddService(unitOfWorkFactory);
+ camelContext.unitOfWorkFactory = camelContext.getInternalServiceManager().addService(unitOfWorkFactory);
}
@Override
@@ -528,7 +527,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setFactoryFinderResolver(FactoryFinderResolver factoryFinderResolver) {
- camelContext.factoryFinderResolver = camelContext.doAddService(factoryFinderResolver);
+ camelContext.factoryFinderResolver = camelContext.getInternalServiceManager().addService(factoryFinderResolver);
}
@Override
@@ -550,7 +549,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setPackageScanClassResolver(PackageScanClassResolver packageScanClassResolver) {
- camelContext.packageScanClassResolver = camelContext.doAddService(packageScanClassResolver);
+ camelContext.packageScanClassResolver = camelContext.getInternalServiceManager().addService(packageScanClassResolver);
}
@Override
@@ -567,7 +566,8 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setPackageScanResourceResolver(PackageScanResourceResolver packageScanResourceResolver) {
- camelContext.packageScanResourceResolver = camelContext.doAddService(packageScanResourceResolver);
+ camelContext.packageScanResourceResolver
+ = camelContext.getInternalServiceManager().addService(packageScanResourceResolver);
}
@Override
@@ -584,7 +584,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setModelJAXBContextFactory(final ModelJAXBContextFactory modelJAXBContextFactory) {
- camelContext.modelJAXBContextFactory = camelContext.doAddService(modelJAXBContextFactory);
+ camelContext.modelJAXBContextFactory = camelContext.getInternalServiceManager().addService(modelJAXBContextFactory);
}
@Override
@@ -601,7 +601,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setNodeIdFactory(NodeIdFactory idFactory) {
- camelContext.nodeIdFactory = camelContext.doAddService(idFactory);
+ camelContext.nodeIdFactory = camelContext.getInternalServiceManager().addService(idFactory);
}
@Override
@@ -618,7 +618,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setModelineFactory(ModelineFactory modelineFactory) {
- camelContext.modelineFactory = camelContext.doAddService(modelineFactory);
+ camelContext.modelineFactory = camelContext.getInternalServiceManager().addService(modelineFactory);
}
@Override
@@ -635,7 +635,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setPeriodTaskResolver(PeriodTaskResolver periodTaskResolver) {
- camelContext.periodTaskResolver = camelContext.doAddService(periodTaskResolver);
+ camelContext.periodTaskResolver = camelContext.getInternalServiceManager().addService(periodTaskResolver);
}
public PeriodTaskScheduler getPeriodTaskScheduler() {
@@ -650,7 +650,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setPeriodTaskScheduler(PeriodTaskScheduler periodTaskScheduler) {
- camelContext.periodTaskScheduler = camelContext.doAddService(periodTaskScheduler);
+ camelContext.periodTaskScheduler = camelContext.getInternalServiceManager().addService(periodTaskScheduler);
}
@Override
@@ -717,7 +717,8 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setAsyncProcessorAwaitManager(AsyncProcessorAwaitManager asyncProcessorAwaitManager) {
- camelContext.asyncProcessorAwaitManager = camelContext.doAddService(asyncProcessorAwaitManager);
+ camelContext.asyncProcessorAwaitManager
+ = camelContext.getInternalServiceManager().addService(asyncProcessorAwaitManager);
}
@Override
@@ -734,7 +735,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setBeanIntrospection(BeanIntrospection beanIntrospection) {
- camelContext.beanIntrospection = camelContext.doAddService(beanIntrospection);
+ camelContext.beanIntrospection = camelContext.getInternalServiceManager().addService(beanIntrospection);
}
@Override
@@ -761,7 +762,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setDataFormatResolver(DataFormatResolver dataFormatResolver) {
- camelContext.dataFormatResolver = camelContext.doAddService(dataFormatResolver);
+ camelContext.dataFormatResolver = camelContext.getInternalServiceManager().addService(dataFormatResolver);
}
@Override
@@ -778,7 +779,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setHealthCheckResolver(HealthCheckResolver healthCheckResolver) {
- camelContext.healthCheckResolver = camelContext.doAddService(healthCheckResolver);
+ camelContext.healthCheckResolver = camelContext.getInternalServiceManager().addService(healthCheckResolver);
}
public DevConsoleResolver getDevConsoleResolver() {
@@ -793,7 +794,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setDevConsoleResolver(DevConsoleResolver devConsoleResolver) {
- camelContext.devConsoleResolver = camelContext.doAddService(devConsoleResolver);
+ camelContext.devConsoleResolver = camelContext.getInternalServiceManager().addService(devConsoleResolver);
}
@Override
@@ -820,7 +821,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setProcessorFactory(ProcessorFactory processorFactory) {
- camelContext.processorFactory = camelContext.doAddService(processorFactory);
+ camelContext.processorFactory = camelContext.getInternalServiceManager().addService(processorFactory);
}
@Override
@@ -837,7 +838,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setInternalProcessorFactory(InternalProcessorFactory internalProcessorFactory) {
- camelContext.internalProcessorFactory = camelContext.doAddService(internalProcessorFactory);
+ camelContext.internalProcessorFactory = camelContext.getInternalServiceManager().addService(internalProcessorFactory);
}
@Override
@@ -854,7 +855,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setInterceptEndpointFactory(InterceptEndpointFactory interceptEndpointFactory) {
- camelContext.interceptEndpointFactory = camelContext.doAddService(interceptEndpointFactory);
+ camelContext.interceptEndpointFactory = camelContext.getInternalServiceManager().addService(interceptEndpointFactory);
}
@Override
@@ -881,7 +882,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setHeadersMapFactory(HeadersMapFactory headersMapFactory) {
- camelContext.headersMapFactory = camelContext.doAddService(headersMapFactory);
+ camelContext.headersMapFactory = camelContext.getInternalServiceManager().addService(headersMapFactory);
}
@Override
@@ -898,7 +899,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setRoutesLoader(RoutesLoader routesLoader) {
- camelContext.routesLoader = camelContext.doAddService(routesLoader);
+ camelContext.routesLoader = camelContext.getInternalServiceManager().addService(routesLoader);
}
@Override
@@ -915,7 +916,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
- camelContext.resourceLoader = camelContext.doAddService(resourceLoader);
+ camelContext.resourceLoader = camelContext.getInternalServiceManager().addService(resourceLoader);
}
public ModelToXMLDumper getModelToXMLDumper() {
@@ -930,7 +931,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
}
public void setModelToXMLDumper(ModelToXMLDumper modelToXMLDumper) {
- camelContext.modelToXMLDumper = camelContext.doAddService(modelToXMLDumper);
+ camelContext.modelToXMLDumper = camelContext.getInternalServiceManager().addService(modelToXMLDumper);
}
public RestBindingJaxbDataFormatFactory getRestBindingJaxbDataFormatFactory() {
@@ -962,7 +963,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setRuntimeCamelCatalog(RuntimeCamelCatalog runtimeCamelCatalog) {
- camelContext.runtimeCamelCatalog = camelContext.doAddService(runtimeCamelCatalog);
+ camelContext.runtimeCamelCatalog = camelContext.getInternalServiceManager().addService(runtimeCamelCatalog);
}
@Override
@@ -998,7 +999,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
@Override
public void setExchangeFactoryManager(ExchangeFactoryManager exchangeFactoryManager) {
- camelContext.exchangeFactoryManager = camelContext.doAddService(exchangeFactoryManager);
+ camelContext.exchangeFactoryManager = camelContext.getInternalServiceManager().addService(exchangeFactoryManager);
}
@Override
@@ -1036,7 +1037,7 @@ class DefaultCamelContextExtension implements ExtendedCamelContext {
public void setReactiveExecutor(ReactiveExecutor reactiveExecutor) {
// special for executorServiceManager as want to stop it manually so
// false in stopOnShutdown
- camelContext.reactiveExecutor = camelContext.doAddService(reactiveExecutor, false);
+ camelContext.reactiveExecutor = camelContext.getInternalServiceManager().addService(reactiveExecutor, false);
}
@Override
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalServiceHelper.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalServiceHelper.java
deleted file mode 100644
index 9bc9c96c435..00000000000
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalServiceHelper.java
+++ /dev/null
@@ -1,142 +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.engine;
-
-import java.util.List;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.CamelContextAware;
-import org.apache.camel.Endpoint;
-import org.apache.camel.IsSingleton;
-import org.apache.camel.Route;
-import org.apache.camel.RouteAware;
-import org.apache.camel.Service;
-import org.apache.camel.TypeConverter;
-import org.apache.camel.spi.LifecycleStrategy;
-import org.apache.camel.spi.TypeConverterRegistry;
-import org.apache.camel.support.service.BaseService;
-import org.apache.camel.support.service.ServiceHelper;
-
-final class InternalServiceHelper {
-
- private InternalServiceHelper() {
-
- }
-
- public static void internalAddService(
- Object object, boolean stopOnShutdown,
- boolean forceStart, boolean useLifecycleStrategies, CamelContext camelContext,
- InternalRouteStartupManager internalRouteStartupManager,
- List<Service> servicesToStop, DeferServiceStartupListener deferStartupListener)
- throws Exception {
-
- if (object == null) {
- return;
- }
-
- // inject CamelContext
- CamelContextAware.trySetCamelContext(object, camelContext);
-
- if (object instanceof Service) {
- Service service = (Service) object;
-
- if (useLifecycleStrategies) {
- for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) {
- if (service instanceof Endpoint) {
- // use specialized endpoint add
- strategy.onEndpointAdd((Endpoint) service);
- } else {
- Route route;
- if (service instanceof RouteAware) {
- route = ((RouteAware) service).getRoute();
- } else {
- // if the service is added while creating a new route then grab the route from the startup manager
- route = internalRouteStartupManager.getSetupRoute();
- }
- strategy.onServiceAdd(camelContext, service, route);
- }
- }
- }
-
- if (!forceStart) {
- ServiceHelper.initService(service);
- // now start the service (and defer starting if CamelContext is
- // starting up itself)
- camelContext.deferStartService(object, stopOnShutdown);
- } else {
- // only add to services to close if its a singleton
- // otherwise we could for example end up with a lot of prototype
- // scope endpoints
- boolean singleton = true; // assume singleton by default
- if (object instanceof IsSingleton) {
- singleton = ((IsSingleton) service).isSingleton();
- }
- // do not add endpoints as they have their own list
- if (singleton && !(service instanceof Endpoint)) {
- // only add to list of services to stop if its not already there
- if (stopOnShutdown && !camelContext.hasService(service)) {
- // special for type converter / type converter registry which is stopped manual later
- boolean tc = service instanceof TypeConverter || service instanceof TypeConverterRegistry;
- if (!tc) {
- servicesToStop.add(service);
- }
- }
- }
-
- if (camelContext instanceof BaseService baseService) {
- if (baseService.isStartingOrStarted()) {
- ServiceHelper.startService(service);
- } else {
- ServiceHelper.initService(service);
- deferStartService(object, stopOnShutdown, true, camelContext, servicesToStop, deferStartupListener);
- }
- }
- }
- }
- }
-
- private static void deferStartService(
- Object object, boolean stopOnShutdown, boolean startEarly, CamelContext camelContext,
- List<Service> servicesToStop, DeferServiceStartupListener deferStartupListener)
- throws Exception {
- if (object instanceof Service) {
- Service service = (Service) object;
-
- // only add to services to close if its a singleton
- // otherwise we could for example end up with a lot of prototype
- // scope endpoints
- boolean singleton = true; // assume singleton by default
- if (object instanceof IsSingleton) {
- singleton = ((IsSingleton) service).isSingleton();
- }
- // do not add endpoints as they have their own list
- if (singleton && !(service instanceof Endpoint)) {
- // only add to list of services to stop if its not already there
- if (stopOnShutdown && !camelContext.hasService(service)) {
- servicesToStop.add(service);
- }
- }
- // are we already started?
- if (camelContext.isStarted()) {
- ServiceHelper.startService(service);
- } else {
- deferStartupListener.addService(service, startEarly);
- }
- }
- }
-}
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalServiceManager.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalServiceManager.java
new file mode 100644
index 00000000000..e2502da0e2f
--- /dev/null
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/InternalServiceManager.java
@@ -0,0 +1,278 @@
+/*
+ * 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.engine;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.Consumer;
+import org.apache.camel.Endpoint;
+import org.apache.camel.IsSingleton;
+import org.apache.camel.Route;
+import org.apache.camel.RouteAware;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.Service;
+import org.apache.camel.StartupListener;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.LifecycleStrategy;
+import org.apache.camel.spi.TypeConverterRegistry;
+import org.apache.camel.support.EventHelper;
+import org.apache.camel.support.service.BaseService;
+import org.apache.camel.support.service.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+final class InternalServiceManager {
+ private static final Logger LOG = LoggerFactory.getLogger(InternalServiceManager.class);
+
+ private final CamelContext camelContext;
+ private final InternalRouteStartupManager internalRouteStartupManager;
+
+ private final DeferServiceStartupListener deferStartupListener = new DeferServiceStartupListener();
+ private final List<Service> services = new CopyOnWriteArrayList<>();
+
+ InternalServiceManager(CamelContext camelContext, InternalRouteStartupManager internalRouteStartupManager,
+ List<StartupListener> startupListeners) {
+ /*
+ Note: this is an internal API and not meant to be public, so it uses assertion for lightweight nullability
+ checking for extremely unlikely scenarios that should be found during development time.
+ */
+ assert camelContext != null : "the Camel context cannot be null";
+ assert internalRouteStartupManager != null : "the internalRouteStartupManager cannot be null";
+ assert startupListeners != null : "the startupListeners cannot be null";
+
+ this.camelContext = camelContext;
+ this.internalRouteStartupManager = internalRouteStartupManager;
+
+ startupListeners.add(deferStartupListener);
+ }
+
+ public <T> T addService(T object) {
+ return addService(object, true);
+ }
+
+ public <T> T addService(T object, boolean stopOnShutdown) {
+ return addService(object, stopOnShutdown, true, true);
+ }
+
+ public <T> T addService(T object, boolean stopOnShutdown, boolean forceStart, boolean useLifecycleStrategies) {
+ try {
+ doAddService(object, stopOnShutdown, forceStart, useLifecycleStrategies);
+ } catch (Exception e) {
+ throw RuntimeCamelException.wrapRuntimeCamelException(e);
+ }
+ return object;
+ }
+
+ public void doAddService(Object object, boolean stopOnShutdown, boolean forceStart, boolean useLifecycleStrategies)
+ throws Exception {
+
+ if (object == null) {
+ return;
+ }
+
+ // inject CamelContext
+ CamelContextAware.trySetCamelContext(object, camelContext);
+
+ if (object instanceof Service) {
+ Service service = (Service) object;
+
+ if (useLifecycleStrategies) {
+ for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) {
+ if (service instanceof Endpoint) {
+ // use specialized endpoint add
+ strategy.onEndpointAdd((Endpoint) service);
+ } else {
+ Route route;
+ if (service instanceof RouteAware) {
+ route = ((RouteAware) service).getRoute();
+ } else {
+ // if the service is added while creating a new route then grab the route from the startup manager
+ route = internalRouteStartupManager.getSetupRoute();
+ }
+ strategy.onServiceAdd(camelContext, service, route);
+ }
+ }
+ }
+
+ if (!forceStart) {
+ ServiceHelper.initService(service);
+ // now start the service (and defer starting if CamelContext is
+ // starting up itself)
+ camelContext.deferStartService(object, stopOnShutdown);
+ } else {
+ // only add to services to close if its a singleton
+ // otherwise we could for example end up with a lot of prototype
+ // scope endpoints
+ boolean singleton = true; // assume singleton by default
+ if (object instanceof IsSingleton) {
+ singleton = ((IsSingleton) service).isSingleton();
+ }
+ // do not add endpoints as they have their own list
+ if (singleton && !(service instanceof Endpoint)) {
+ // only add to list of services to stop if its not already there
+ if (stopOnShutdown && !camelContext.hasService(service)) {
+ // special for type converter / type converter registry which is stopped manual later
+ boolean tc = service instanceof TypeConverter || service instanceof TypeConverterRegistry;
+ if (!tc) {
+ services.add(service);
+ }
+ }
+ }
+
+ if (camelContext instanceof BaseService baseService) {
+ if (baseService.isStartingOrStarted()) {
+ ServiceHelper.startService(service);
+ } else {
+ ServiceHelper.initService(service);
+ deferStartService(object, stopOnShutdown, true);
+ }
+ }
+ }
+ }
+ }
+
+ public void deferStartService(Object object, boolean stopOnShutdown, boolean startEarly) {
+ if (object instanceof Service) {
+ Service service = (Service) object;
+
+ // only add to services to close if its a singleton
+ // otherwise we could for example end up with a lot of prototype
+ // scope endpoints
+ boolean singleton = true; // assume singleton by default
+ if (object instanceof IsSingleton) {
+ singleton = ((IsSingleton) service).isSingleton();
+ }
+ // do not add endpoints as they have their own list
+ if (singleton && !(service instanceof Endpoint)) {
+ // only add to list of services to stop if its not already there
+ if (stopOnShutdown && !camelContext.hasService(service)) {
+ services.add(service);
+ }
+ }
+ // are we already started?
+ if (camelContext.isStarted()) {
+ ServiceHelper.startService(service);
+ } else {
+ deferStartupListener.addService(service, startEarly);
+ }
+ }
+ }
+
+ public boolean removeService(Service service) {
+ return services.remove(service);
+ }
+
+ @SuppressWarnings("unchecked")
+ public <T> Set<T> hasServices(Class<T> type) {
+ if (services.isEmpty()) {
+ return Collections.emptySet();
+ }
+
+ Set<T> set = new HashSet<>();
+ for (Service service : services) {
+ if (type.isInstance(service)) {
+ set.add((T) service);
+ }
+ }
+ return set;
+ }
+
+ public boolean hasService(Object object) {
+ if (services.isEmpty()) {
+ return false;
+ }
+ if (object instanceof Service) {
+ Service service = (Service) object;
+ return services.contains(service);
+ }
+ return false;
+ }
+
+ public <T> T hasService(Class<T> type) {
+ if (services.isEmpty()) {
+ return null;
+ }
+ for (Service service : services) {
+ if (type.isInstance(service)) {
+ return type.cast(service);
+ }
+ }
+ return null;
+ }
+
+ public void stopConsumers() {
+ for (Service service : services) {
+ if (service instanceof Consumer) {
+ InternalServiceManager.shutdownServices(camelContext, service);
+ }
+ }
+ }
+
+ public void shutdownServices() {
+ InternalServiceManager.shutdownServices(camelContext, services);
+ services.clear();
+ }
+
+ public static void shutdownServices(CamelContext camelContext, Collection<?> services) {
+ // reverse stopping by default
+ shutdownServices(camelContext, services, true);
+ }
+
+ public List<Service> getServices() {
+ return Collections.unmodifiableList(services);
+ }
+
+ public static void shutdownServices(CamelContext camelContext, Collection<?> services, boolean reverse) {
+ Collection<?> list = services;
+ if (reverse) {
+ List<Object> reverseList = new ArrayList<>(services);
+ Collections.reverse(reverseList);
+ list = reverseList;
+ }
+
+ for (Object service : list) {
+ shutdownServices(camelContext, service);
+ }
+ }
+
+ public static void shutdownServices(CamelContext camelContext, Object service) {
+ // do not rethrow exception as we want to keep shutting down in case of
+ // problems
+
+ // allow us to do custom work before delegating to service helper
+ try {
+ if (service instanceof Service) {
+ ServiceHelper.stopAndShutdownService(service);
+ } else if (service instanceof Collection) {
+ ServiceHelper.stopAndShutdownServices((Collection<?>) service);
+ }
+ } catch (Exception e) {
+ LOG.warn("Error occurred while shutting down service: {}. This exception will be ignored.", service, e);
+ // fire event
+ EventHelper.notifyServiceStopFailure(camelContext, service, e);
+ }
+ }
+}