From 4a140afac6277ae3b2a79dfde3e6f72dea26ea51 Mon Sep 17 00:00:00 2001 From: Richard Peter Date: Mon, 5 May 2014 19:30:20 -0500 Subject: [PATCH] Issue #2726: Autoset route startup order. Change-Id: I1f4165b6eab12207cf6b6d31964e8170ebe1bddc Former-commit-id: b148d11ec9018f4d4ff965b39436152d3501aa96 [formerly b148d11ec9018f4d4ff965b39436152d3501aa96 [formerly 9b9d2b475f4777febf125e4013cba0d971eaf8e8]] Former-commit-id: 4dc91f494fdac3628ad1451ac2f40f947ff69730 Former-commit-id: c6719da76b5f3e42c41392ca54bd2a5013c5d83a --- .../res/spring/text-ingest.xml | 54 +++++++------ .../esb/camel/context/ContextManager.java | 80 +++++++++++++++---- .../res/spring/persist-ingest.xml | 4 + .../res/spring/modelsounding-ingest.xml | 5 +- 4 files changed, 101 insertions(+), 42 deletions(-) diff --git a/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml b/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml index ba7acf67c8..09c6394bcd 100644 --- a/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml +++ b/edexOsgi/com.raytheon.edex.plugin.text/res/spring/text-ingest.xml @@ -86,8 +86,35 @@ --> + + + + text + + + + + + + + + + + + + + + + java.lang.Throwable + + + + + @@ -134,31 +161,6 @@ - - - - text - - - - - - - - - - - - - - - - java.lang.Throwable - - - - - diff --git a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java index 7490a1e673..a7ce7b3bc0 100644 --- a/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java +++ b/edexOsgi/com.raytheon.uf.edex.esb.camel/src/com/raytheon/uf/edex/esb/camel/context/ContextManager.java @@ -20,6 +20,7 @@ package com.raytheon.uf.edex.esb.camel.context; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -38,6 +39,7 @@ import javax.naming.ConfigurationException; import org.apache.camel.CamelContext; import org.apache.camel.Route; import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.model.RouteDefinition; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; @@ -78,6 +80,21 @@ public class ContextManager implements ApplicationContextAware, private static ContextManager instance = new ContextManager(); + /** + * Endpoint types that are internal only. Mainly used at shutdown time to + * designate routes that shouldn't be shutdown immediately. + */ + private static final Set INTERNAL_ENDPOINT_TYPES; + + static { + HashSet set = new HashSet( + ContextDependencyMapping.DEPENDENCY_ENDPOINT_TYPES); + set.add("timer"); + set.add("quartz"); + set.add("direct"); + INTERNAL_ENDPOINT_TYPES = Collections.unmodifiableSet(set); + } + /** * Service used for start up and shut down threading. */ @@ -102,12 +119,6 @@ public class ContextManager implements ApplicationContextAware, */ private ApplicationContext springCtx = null; - /** - * Endpoint types that are internal only. Mainly used at shutdown time to - * designate routes that shouldn't be shutdown immediately. - */ - private final Set internalEndpointTypes = new HashSet(); - /** * Map of context processors that have been registered for a given context. * Used to allow contexts to do custom worn on startup/shutdown. @@ -147,15 +158,19 @@ public class ContextManager implements ApplicationContextAware, } /** - * Private constructor. Sets up internal types for prioritized stopping of - * routes on shutdown. + * Private constructor. */ private ContextManager() { - internalEndpointTypes - .addAll(ContextDependencyMapping.DEPENDENCY_ENDPOINT_TYPES); - internalEndpointTypes.add("timer"); - internalEndpointTypes.add("quartz"); - internalEndpointTypes.add("direct"); + } + + /** + * Returns a set of endpoint types that are considered internal for routing + * purposes. + * + * @return + */ + public Set getInternalEndpointTypes() { + return INTERNAL_ENDPOINT_TYPES; } /** @@ -242,6 +257,31 @@ public class ContextManager implements ApplicationContextAware, List>> callbacks = new LinkedList>>(); for (final CamelContext context : cxtData.getContexts()) { + /* + * Enforce startup order so that internal endpoints start first + * and shutdown last. Each route must have a unique number under + * 1000. Camel documentation doesn't state if numbers can be + * negative or not. Order is reverse of how they are found in + * the file with internal types going first followed by external + * types. + */ + int externalCount = 999; + int internalCount = externalCount - context.getRoutes().size(); + + for (Route route : context.getRoutes()) { + String uri = route.getEndpoint().getEndpointUri(); + Pair typeAndName = ContextData + .getEndpointTypeAndName(uri); + String type = typeAndName.getFirst(); + RouteDefinition def = route.getRouteContext().getRoute(); + + if (INTERNAL_ENDPOINT_TYPES.contains(type)) { + def.setStartupOrder(internalCount--); + } else { + def.setStartupOrder(externalCount--); + } + } + final IContextStateManager stateManager = getStateManager(context); if (stateManager.isContextStartable(context)) { /* @@ -410,7 +450,7 @@ public class ContextManager implements ApplicationContextAware, Pair typeAndName = ContextData .getEndpointTypeAndName(uri); String type = typeAndName.getFirst(); - if (!internalEndpointTypes.contains(type)) { + if (!INTERNAL_ENDPOINT_TYPES.contains(type)) { try { statusHandler.info("Stopping route [" + route.getId() + "]"); @@ -531,7 +571,7 @@ public class ContextManager implements ApplicationContextAware, } /** - * Update all camel beans to have autoStartup to false and handles quart + * Update all camel beans to have autoStartup to false and handles quartz * workaround when JMX is disabled. */ @Override @@ -539,8 +579,18 @@ public class ContextManager implements ApplicationContextAware, ConfigurableListableBeanFactory beanFactory) throws BeansException { for (CamelContext ctx : beanFactory.getBeansOfType(CamelContext.class) .values()) { + /* + * set contexts to not auto start to enforce dependency order + * correctly. + */ ctx.setAutoStartup(false); + /* + * Quartz work around to set management name. + * + * TODO: Remove with camel 2.12.3 upgrade: + * https://issues.apache.org/jira/browse/CAMEL-7132 + */ if ((ctx instanceof DefaultCamelContext) && (ctx.getManagementName() == null)) { ((DefaultCamelContext) ctx).setManagementName(ctx.getName()); diff --git a/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml b/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml index b14c671dbc..6045f19ea7 100644 --- a/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.ingest/res/spring/persist-ingest.xml @@ -51,6 +51,10 @@ + diff --git a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml index 518b24d3c4..f1e08678f6 100644 --- a/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml +++ b/edexOsgi/com.raytheon.uf.edex.plugin.modelsounding/res/spring/modelsounding-ingest.xml @@ -86,7 +86,10 @@ - +