org.apache.camel.impl.engine.InternalServiceManager Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of camel-base-engine Show documentation
Show all versions of camel-base-engine Show documentation
The Base Engine Camel Framework
The newest version!
/*
* 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 InternalRouteStartupManager internalRouteStartupManager;
private final DeferServiceStartupListener deferStartupListener = new DeferServiceStartupListener();
private final List services = new CopyOnWriteArrayList<>();
InternalServiceManager(InternalRouteStartupManager internalRouteStartupManager, List 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 internalRouteStartupManager != null : "the internalRouteStartupManager cannot be null";
assert startupListeners != null : "the startupListeners cannot be null";
this.internalRouteStartupManager = internalRouteStartupManager;
startupListeners.add(deferStartupListener);
}
public T addService(CamelContext camelContext, T object) {
return addService(camelContext, object, true);
}
public T addService(CamelContext camelContext, T object, boolean stopOnShutdown) {
return addService(camelContext, object, stopOnShutdown, true, true);
}
public T addService(
CamelContext camelContext, T object, boolean stopOnShutdown, boolean forceStart, boolean useLifecycleStrategies) {
try {
doAddService(camelContext, object, stopOnShutdown, forceStart, useLifecycleStrategies);
} catch (Exception e) {
throw RuntimeCamelException.wrapRuntimeCamelException(e);
}
return object;
}
public void doAddService(
CamelContext camelContext, 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) {
if (useLifecycleStrategies) {
for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) {
if (service instanceof Endpoint endpoint) {
// use specialized endpoint add
strategy.onEndpointAdd(endpoint);
} else {
Route route;
if (service instanceof RouteAware routeAware) {
route = routeAware.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 (service instanceof IsSingleton singletonService) {
singleton = singletonService.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(camelContext, object, stopOnShutdown, true);
}
}
}
}
}
public void deferStartService(CamelContext camelContext, Object object, boolean stopOnShutdown, boolean startEarly) {
if (object instanceof Service service) {
// 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 (service instanceof IsSingleton singletonService) {
singleton = singletonService.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 Set hasServices(Class type) {
if (services.isEmpty()) {
return Collections.emptySet();
}
Set 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) {
return services.contains(service);
}
return false;
}
public T hasService(Class type) {
if (services.isEmpty()) {
return null;
}
for (Service service : services) {
if (type.isInstance(service)) {
return type.cast(service);
}
}
return null;
}
public void stopConsumers(CamelContext camelContext) {
for (Service service : services) {
if (service instanceof Consumer) {
InternalServiceManager.shutdownServices(camelContext, service);
}
}
}
public void shutdownServices(CamelContext camelContext) {
InternalServiceManager.shutdownServices(camelContext, services);
services.clear();
}
public static void shutdownServices(CamelContext camelContext, Collection> services) {
// reverse stopping by default
shutdownServices(camelContext, services, true);
}
public List getServices() {
return Collections.unmodifiableList(services);
}
public static void shutdownServices(CamelContext camelContext, Collection> services, boolean reverse) {
Collection> list = services;
if (reverse) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy