use of org.apache.camel.spi.LifecycleStrategy in project camel by apache.
the class DefaultCamelContext method doStop.
protected synchronized void doStop() throws Exception {
stopWatch.restart();
log.info("Apache Camel " + getVersion() + " (CamelContext: " + getName() + ") is shutting down");
EventHelper.notifyCamelContextStopping(this);
// stop route inputs in the same order as they was started so we stop the very first inputs first
try {
// force shutting down routes as they may otherwise cause shutdown to hang
shutdownStrategy.shutdownForced(this, getRouteStartupOrder());
} catch (Throwable e) {
log.warn("Error occurred while shutting down routes. This exception will be ignored.", e);
}
// shutdown await manager to trigger interrupt of blocked threads to attempt to free these threads graceful
shutdownServices(asyncProcessorAwaitManager);
shutdownServices(getRouteStartupOrder().stream().sorted(Comparator.comparing(RouteStartupOrder::getStartupOrder).reversed()).map(DefaultRouteStartupOrder.class::cast).map(DefaultRouteStartupOrder::getRouteService).collect(Collectors.toList()), false);
// do not clear route services or startup listeners as we can start Camel again and get the route back as before
getRouteStartupOrder().clear();
// but clear any suspend routes
suspendedRouteServices.clear();
// 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);
}
}
// shutdown default error handler thread pool
if (errorHandlerExecutorService != null) {
// force shutting down the thread pool
getExecutorServiceManager().shutdownNow(errorHandlerExecutorService);
errorHandlerExecutorService = null;
}
// shutdown debugger
ServiceHelper.stopAndShutdownService(getDebugger());
shutdownServices(endpoints.values());
endpoints.clear();
shutdownServices(components.values());
components.clear();
shutdownServices(languages.values());
languages.clear();
try {
for (LifecycleStrategy strategy : lifecycleStrategies) {
strategy.onContextStop(this);
}
} catch (Throwable e) {
log.warn("Error occurred while stopping lifecycle strategies. This exception will be ignored.", e);
}
// shutdown services as late as possible
shutdownServices(servicesToStop);
servicesToStop.clear();
// must notify that we are stopped before stopping the management strategy
EventHelper.notifyCamelContextStopped(this);
// stop the notifier service
for (EventNotifier notifier : getManagementStrategy().getEventNotifiers()) {
shutdownServices(notifier);
}
// shutdown executor service and management as the last one
shutdownServices(executorServiceManager);
shutdownServices(managementStrategy);
shutdownServices(managementMBeanAssembler);
shutdownServices(lifecycleStrategies);
// do not clear lifecycleStrategies as we can start Camel again and get the route back as before
// stop the lazy created so they can be re-created on restart
forceStopLazyInitialization();
// stop to clear introspection cache
IntrospectionSupport.stop();
stopWatch.stop();
if (log.isInfoEnabled()) {
log.info("Apache Camel " + getVersion() + " (CamelContext: " + getName() + ") uptime {}", getUptime());
log.info("Apache Camel " + getVersion() + " (CamelContext: " + getName() + ") is shutdown in " + TimeUtils.printDuration(stopWatch.taken()));
}
// and clear start date
startDate = null;
// [TODO] Remove in 3.0
Container.Instance.unmanage(this);
}
use of org.apache.camel.spi.LifecycleStrategy in project camel by apache.
the class DefaultExecutorServiceManager method doShutdown.
private boolean doShutdown(ExecutorService executorService, long shutdownAwaitTermination, boolean failSafe) {
if (executorService == null) {
return false;
}
boolean warned = false;
// we ought to shutdown much faster)
if (!executorService.isShutdown()) {
StopWatch watch = new StopWatch();
LOG.trace("Shutdown of ExecutorService: {} with await termination: {} millis", executorService, shutdownAwaitTermination);
executorService.shutdown();
if (shutdownAwaitTermination > 0) {
try {
if (!awaitTermination(executorService, shutdownAwaitTermination)) {
warned = true;
LOG.warn("Forcing shutdown of ExecutorService: {} due first await termination elapsed.", executorService);
executorService.shutdownNow();
// we are now shutting down aggressively, so wait to see if we can completely shutdown or not
if (!awaitTermination(executorService, shutdownAwaitTermination)) {
LOG.warn("Cannot completely force shutdown of ExecutorService: {} due second await termination elapsed.", executorService);
}
}
} catch (InterruptedException e) {
warned = true;
LOG.warn("Forcing shutdown of ExecutorService: {} due interrupted.", executorService);
// we were interrupted during shutdown, so force shutdown
executorService.shutdownNow();
}
}
// if we logged at WARN level, then report at INFO level when we are complete so the end user can see this in the log
if (warned) {
LOG.info("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.", executorService, executorService.isShutdown(), executorService.isTerminated(), TimeUtils.printDuration(watch.taken()));
} else if (LOG.isDebugEnabled()) {
LOG.debug("Shutdown of ExecutorService: {} is shutdown: {} and terminated: {} took: {}.", executorService, executorService.isShutdown(), executorService.isTerminated(), TimeUtils.printDuration(watch.taken()));
}
}
// let lifecycle strategy be notified as well which can let it be managed in JMX as well
ThreadPoolExecutor threadPool = null;
if (executorService instanceof ThreadPoolExecutor) {
threadPool = (ThreadPoolExecutor) executorService;
} else if (executorService instanceof SizedScheduledExecutorService) {
threadPool = ((SizedScheduledExecutorService) executorService).getScheduledThreadPoolExecutor();
}
if (threadPool != null) {
for (LifecycleStrategy lifecycle : camelContext.getLifecycleStrategies()) {
lifecycle.onThreadPoolRemove(camelContext, threadPool);
}
}
// remove reference as its shutdown (do not remove if fail-safe)
if (!failSafe) {
executorServices.remove(executorService);
}
return warned;
}
use of org.apache.camel.spi.LifecycleStrategy in project camel by apache.
the class DefaultExecutorServiceManager method onThreadPoolCreated.
/**
* Invoked when a new thread pool is created.
* This implementation will invoke the {@link LifecycleStrategy#onThreadPoolAdd(org.apache.camel.CamelContext,
* java.util.concurrent.ThreadPoolExecutor, String, String, String, String) LifecycleStrategy.onThreadPoolAdd} method,
* which for example will enlist the thread pool in JMX management.
*
* @param executorService the thread pool
* @param source the source to use the thread pool
* @param threadPoolProfileId profile id, if the thread pool was created from a thread pool profile
*/
private void onThreadPoolCreated(ExecutorService executorService, Object source, String threadPoolProfileId) {
// add to internal list of thread pools
executorServices.add(executorService);
String id;
String sourceId = null;
String routeId = null;
// extract id from source
if (source instanceof NamedNode) {
id = ((OptionalIdentifiedDefinition<?>) source).idOrCreate(this.camelContext.getNodeIdFactory());
// and let source be the short name of the pattern
sourceId = ((NamedNode) source).getShortName();
} else if (source instanceof String) {
id = (String) source;
} else if (source != null) {
if (source instanceof StaticService) {
// the source is static service so its name would be unique
id = source.getClass().getSimpleName();
} else {
// fallback and use the simple class name with hashcode for the id so its unique for this given source
id = source.getClass().getSimpleName() + "(" + ObjectHelper.getIdentityHashCode(source) + ")";
}
} else {
// no source, so fallback and use the simple class name from thread pool and its hashcode identity so its unique
id = executorService.getClass().getSimpleName() + "(" + ObjectHelper.getIdentityHashCode(executorService) + ")";
}
// id is mandatory
ObjectHelper.notEmpty(id, "id for thread pool " + executorService);
// extract route id if possible
if (source instanceof ProcessorDefinition) {
RouteDefinition route = ProcessorDefinitionHelper.getRoute((ProcessorDefinition<?>) source);
if (route != null) {
routeId = route.idOrCreate(this.camelContext.getNodeIdFactory());
}
}
// let lifecycle strategy be notified as well which can let it be managed in JMX as well
ThreadPoolExecutor threadPool = null;
if (executorService instanceof ThreadPoolExecutor) {
threadPool = (ThreadPoolExecutor) executorService;
} else if (executorService instanceof SizedScheduledExecutorService) {
threadPool = ((SizedScheduledExecutorService) executorService).getScheduledThreadPoolExecutor();
}
if (threadPool != null) {
for (LifecycleStrategy lifecycle : camelContext.getLifecycleStrategies()) {
lifecycle.onThreadPoolAdd(camelContext, threadPool, id, sourceId, routeId, threadPoolProfileId);
}
}
// now call strategy to allow custom logic
onNewExecutorService(executorService);
}
use of org.apache.camel.spi.LifecycleStrategy in project camel by apache.
the class RouteDefinition method addRoutes.
// Implementation methods
// -------------------------------------------------------------------------
protected RouteContext addRoutes(CamelContext camelContext, Collection<Route> routes, FromDefinition fromType) throws Exception {
RouteContext routeContext = new DefaultRouteContext(camelContext, this, fromType, routes);
// configure tracing
if (trace != null) {
Boolean isTrace = CamelContextHelper.parseBoolean(camelContext, getTrace());
if (isTrace != null) {
routeContext.setTracing(isTrace);
if (isTrace) {
log.debug("Tracing is enabled on route: {}", getId());
// tracing is added in the DefaultChannel so we can enable it on the fly
}
}
}
// configure message history
if (messageHistory != null) {
Boolean isMessageHistory = CamelContextHelper.parseBoolean(camelContext, getMessageHistory());
if (isMessageHistory != null) {
routeContext.setMessageHistory(isMessageHistory);
if (isMessageHistory) {
log.debug("Message history is enabled on route: {}", getId());
}
}
}
// configure stream caching
if (streamCache != null) {
Boolean isStreamCache = CamelContextHelper.parseBoolean(camelContext, getStreamCache());
if (isStreamCache != null) {
routeContext.setStreamCaching(isStreamCache);
if (isStreamCache) {
log.debug("StreamCaching is enabled on route: {}", getId());
}
}
}
// configure handle fault
if (handleFault != null) {
Boolean isHandleFault = CamelContextHelper.parseBoolean(camelContext, getHandleFault());
if (isHandleFault != null) {
routeContext.setHandleFault(isHandleFault);
if (isHandleFault) {
log.debug("HandleFault is enabled on route: {}", getId());
// only add a new handle fault if not already a global configured on camel context
if (HandleFault.getHandleFault(camelContext) == null) {
addInterceptStrategy(new HandleFault());
}
}
}
}
// configure delayer
if (delayer != null) {
Long delayer = CamelContextHelper.parseLong(camelContext, getDelayer());
if (delayer != null) {
routeContext.setDelayer(delayer);
if (delayer > 0) {
log.debug("Delayer is enabled with: {} ms. on route: {}", delayer, getId());
} else {
log.debug("Delayer is disabled on route: {}", getId());
}
}
}
// configure route policy
if (routePolicies != null && !routePolicies.isEmpty()) {
for (RoutePolicy policy : routePolicies) {
log.debug("RoutePolicy is enabled: {} on route: {}", policy, getId());
routeContext.getRoutePolicyList().add(policy);
}
}
if (routePolicyRef != null) {
StringTokenizer policyTokens = new StringTokenizer(routePolicyRef, ",");
while (policyTokens.hasMoreTokens()) {
String ref = policyTokens.nextToken().trim();
RoutePolicy policy = CamelContextHelper.mandatoryLookup(camelContext, ref, RoutePolicy.class);
log.debug("RoutePolicy is enabled: {} on route: {}", policy, getId());
routeContext.getRoutePolicyList().add(policy);
}
}
if (camelContext.getRoutePolicyFactories() != null) {
for (RoutePolicyFactory factory : camelContext.getRoutePolicyFactories()) {
RoutePolicy policy = factory.createRoutePolicy(camelContext, getId(), this);
if (policy != null) {
log.debug("RoutePolicy is enabled: {} on route: {}", policy, getId());
routeContext.getRoutePolicyList().add(policy);
}
}
}
// configure auto startup
Boolean isAutoStartup = CamelContextHelper.parseBoolean(camelContext, getAutoStartup());
if (isAutoStartup != null) {
log.debug("Using AutoStartup {} on route: {}", isAutoStartup, getId());
routeContext.setAutoStartup(isAutoStartup);
}
// configure shutdown
if (shutdownRoute != null) {
log.debug("Using ShutdownRoute {} on route: {}", getShutdownRoute(), getId());
routeContext.setShutdownRoute(getShutdownRoute());
}
if (shutdownRunningTask != null) {
log.debug("Using ShutdownRunningTask {} on route: {}", getShutdownRunningTask(), getId());
routeContext.setShutdownRunningTask(getShutdownRunningTask());
}
// should inherit the intercept strategies we have defined
routeContext.setInterceptStrategies(this.getInterceptStrategies());
// force endpoint resolution
routeContext.getEndpoint();
for (LifecycleStrategy strategy : camelContext.getLifecycleStrategies()) {
strategy.onRouteContextCreate(routeContext);
}
// validate route has output processors
if (!ProcessorDefinitionHelper.hasOutputs(outputs, true)) {
RouteDefinition route = routeContext.getRoute();
String at = fromType.toString();
Exception cause = new IllegalArgumentException("Route " + route.getId() + " has no output processors." + " You need to add outputs to the route such as to(\"log:foo\").");
throw new FailedToCreateRouteException(route.getId(), route.toString(), at, cause);
}
List<ProcessorDefinition<?>> list = new ArrayList<ProcessorDefinition<?>>(outputs);
for (ProcessorDefinition<?> output : list) {
try {
output.addRoutes(routeContext, routes);
} catch (Exception e) {
RouteDefinition route = routeContext.getRoute();
throw new FailedToCreateRouteException(route.getId(), route.toString(), output.toString(), e);
}
}
routeContext.commit();
return routeContext;
}
use of org.apache.camel.spi.LifecycleStrategy in project camel by apache.
the class ProcessorDefinition method wrapInErrorHandler.
/**
* Wraps the given output in an error handler
*
* @param routeContext the route context
* @param output the output
* @return the output wrapped with the error handler
* @throws Exception can be thrown if failed to create error handler builder
*/
protected Processor wrapInErrorHandler(RouteContext routeContext, Processor output) throws Exception {
ErrorHandlerFactory builder = routeContext.getRoute().getErrorHandlerBuilder();
// create error handler
Processor errorHandler = builder.createErrorHandler(routeContext, output);
// invoke lifecycles so we can manage this error handler builder
for (LifecycleStrategy strategy : routeContext.getCamelContext().getLifecycleStrategies()) {
strategy.onErrorHandlerAdd(routeContext, errorHandler, builder);
}
return errorHandler;
}
Aggregations