use of org.apache.camel.spi.RouteStartupOrder in project camel by apache.
the class DefaultShutdownStrategy method doShutdown.
protected boolean doShutdown(CamelContext context, List<RouteStartupOrder> routes, long timeout, TimeUnit timeUnit, boolean suspendOnly, boolean abortAfterTimeout, boolean forceShutdown) throws Exception {
// timeout must be a positive value
if (timeout <= 0) {
throw new IllegalArgumentException("Timeout must be a positive value");
}
// just return if no routes to shutdown
if (routes.isEmpty()) {
return true;
}
StopWatch watch = new StopWatch();
// at first sort according to route startup order
List<RouteStartupOrder> routesOrdered = new ArrayList<RouteStartupOrder>(routes);
routesOrdered.sort(new Comparator<RouteStartupOrder>() {
public int compare(RouteStartupOrder o1, RouteStartupOrder o2) {
return o1.getStartupOrder() - o2.getStartupOrder();
}
});
if (shutdownRoutesInReverseOrder) {
Collections.reverse(routesOrdered);
}
if (suspendOnly) {
LOG.info("Starting to graceful suspend " + routesOrdered.size() + " routes (timeout " + timeout + " " + timeUnit.toString().toLowerCase(Locale.ENGLISH) + ")");
} else {
LOG.info("Starting to graceful shutdown " + routesOrdered.size() + " routes (timeout " + timeout + " " + timeUnit.toString().toLowerCase(Locale.ENGLISH) + ")");
}
// use another thread to perform the shutdowns so we can support timeout
timeoutOccurred.set(false);
currentShutdownTaskFuture = getExecutorService().submit(new ShutdownTask(context, routesOrdered, timeout, timeUnit, suspendOnly, abortAfterTimeout, timeoutOccurred));
try {
currentShutdownTaskFuture.get(timeout, timeUnit);
} catch (ExecutionException e) {
// unwrap execution exception
throw ObjectHelper.wrapRuntimeCamelException(e.getCause());
} catch (Exception e) {
// either timeout or interrupted exception was thrown so this is okay
// as interrupted would mean cancel was called on the currentShutdownTaskFuture to signal a forced timeout
// we hit a timeout, so set the flag
timeoutOccurred.set(true);
// timeout then cancel the task
currentShutdownTaskFuture.cancel(true);
// signal we are forcing shutdown now, since timeout occurred
this.forceShutdown = forceShutdown;
// if set, stop processing and return false to indicate that the shutdown is aborting
if (!forceShutdown && abortAfterTimeout) {
LOG.warn("Timeout occurred during graceful shutdown. Aborting the shutdown now." + " Notice: some resources may still be running as graceful shutdown did not complete successfully.");
// we attempt to force shutdown so lets log the current inflight exchanges which are affected
logInflightExchanges(context, routes, isLogInflightExchangesOnTimeout());
return false;
} else {
if (forceShutdown || shutdownNowOnTimeout) {
LOG.warn("Timeout occurred during graceful shutdown. Forcing the routes to be shutdown now." + " Notice: some resources may still be running as graceful shutdown did not complete successfully.");
// we attempt to force shutdown so lets log the current inflight exchanges which are affected
logInflightExchanges(context, routes, isLogInflightExchangesOnTimeout());
// force the routes to shutdown now
shutdownRoutesNow(routesOrdered);
// now the route consumers has been shutdown, then prepare route services for shutdown now (forced)
for (RouteStartupOrder order : routes) {
for (Service service : order.getServices()) {
prepareShutdown(service, false, true, true, isSuppressLoggingOnTimeout());
}
}
} else {
LOG.warn("Timeout occurred during graceful shutdown. Will ignore shutting down the remainder routes." + " Notice: some resources may still be running as graceful shutdown did not complete successfully.");
logInflightExchanges(context, routes, isLogInflightExchangesOnTimeout());
}
}
} finally {
currentShutdownTaskFuture = null;
}
// convert to seconds as its easier to read than a big milli seconds number
long seconds = TimeUnit.SECONDS.convert(watch.stop(), TimeUnit.MILLISECONDS);
LOG.info("Graceful shutdown of " + routesOrdered.size() + " routes completed in " + seconds + " seconds");
return true;
}
use of org.apache.camel.spi.RouteStartupOrder in project camel by apache.
the class DefaultCamelContext method shutdownRoute.
public synchronized void shutdownRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
List<RouteStartupOrder> routes = new ArrayList<RouteStartupOrder>(1);
RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
routes.add(order);
getShutdownStrategy().shutdown(this, routes, timeout, timeUnit);
// must stop route service as well (and remove the routes from management)
stopRouteService(routeService, true);
}
}
use of org.apache.camel.spi.RouteStartupOrder in project camel by apache.
the class DefaultCamelContext method doSuspend.
@Override
protected void doSuspend() throws Exception {
EventHelper.notifyCamelContextSuspending(this);
log.info("Apache Camel " + getVersion() + " (CamelContext: " + getName() + ") is suspending");
StopWatch watch = new StopWatch();
// (so when we resume we only resume the routes which actually was suspended)
for (Map.Entry<String, RouteService> entry : getRouteServices().entrySet()) {
if (entry.getValue().getStatus().isStarted()) {
suspendedRouteServices.put(entry.getKey(), entry.getValue());
}
}
// assemble list of startup ordering so routes can be shutdown accordingly
List<RouteStartupOrder> orders = new ArrayList<RouteStartupOrder>();
for (Map.Entry<String, RouteService> entry : suspendedRouteServices.entrySet()) {
Route route = entry.getValue().getRoutes().iterator().next();
Integer order = entry.getValue().getRouteDefinition().getStartupOrder();
if (order == null) {
order = defaultRouteStartupOrder++;
}
orders.add(new DefaultRouteStartupOrder(order, route, entry.getValue()));
}
// suspend routes using the shutdown strategy so it can shutdown in correct order
// routes which doesn't support suspension will be stopped instead
getShutdownStrategy().suspend(this, orders);
// mark the route services as suspended or stopped
for (RouteService service : suspendedRouteServices.values()) {
if (routeSupportsSuspension(service.getId())) {
service.suspend();
} else {
service.stop();
}
}
watch.stop();
if (log.isInfoEnabled()) {
log.info("Apache Camel " + getVersion() + " (CamelContext: " + getName() + ") is suspended in " + TimeUtils.printDuration(watch.taken()));
}
EventHelper.notifyCamelContextSuspended(this);
}
use of org.apache.camel.spi.RouteStartupOrder in project camel by apache.
the class DefaultCamelContext method stopRoute.
public synchronized void stopRoute(String routeId, long timeout, TimeUnit timeUnit) throws Exception {
RouteService routeService = routeServices.get(routeId);
if (routeService != null) {
List<RouteStartupOrder> routes = new ArrayList<RouteStartupOrder>(1);
RouteStartupOrder order = new DefaultRouteStartupOrder(1, routeService.getRoutes().iterator().next(), routeService);
routes.add(order);
getShutdownStrategy().shutdown(this, routes, timeout, timeUnit);
// must stop route service as well
stopRouteService(routeService, false);
}
}
use of org.apache.camel.spi.RouteStartupOrder in project camel by apache.
the class JmsDirectStartupOrderIssueTest method testJmsDirectStartupOrderIssue.
@Test
public void testJmsDirectStartupOrderIssue() throws Exception {
// send messages to queue so there is messages on the queue before we start the route
template.sendBody("activemq:queue:foo", "Hello World");
template.sendBody("activemq:queue:foo", "Hello Camel");
template.sendBody("activemq:queue:foo", "Bye World");
template.sendBody("activemq:queue:foo", "Bye Camel");
context.startRoute("amq");
getMockEndpoint("mock:result").expectedMessageCount(4);
assertMockEndpointsSatisfied();
DefaultCamelContext dcc = (DefaultCamelContext) context;
List<RouteStartupOrder> order = dcc.getRouteStartupOrder();
assertEquals(2, order.size());
assertEquals(1, order.get(0).getStartupOrder());
assertEquals("direct", order.get(0).getRoute().getId());
assertEquals(100, order.get(1).getStartupOrder());
assertEquals("amq", order.get(1).getRoute().getId());
}
Aggregations