This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit f08a4e6d5b08f7edce3ccf28335787acfd63907c
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Jun 6 11:52:01 2019 +0200

    CAMEL-12868: Detect if camel on spring-boot shutdown very quickly because 
there is no main controller or starter-web dependency to keep the JVM alive.
---
 .../camel/spring/boot/CamelAutoConfiguration.java  | 32 ++++++------
 .../camel/spring/boot/SpringBootCamelContext.java  | 57 ++++++++++++++++++++++
 .../org/apache/camel/ExtendedCamelContext.java     | 21 ++++++++
 .../camel/impl/engine/AbstractCamelContext.java    |  8 +--
 4 files changed, 93 insertions(+), 25 deletions(-)

diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
index 9ee72ae..070bc68 100644
--- 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/CamelAutoConfiguration.java
@@ -39,7 +39,6 @@ import org.apache.camel.component.properties.PropertiesParser;
 import org.apache.camel.health.HealthCheckRegistry;
 import org.apache.camel.health.HealthCheckRepository;
 import org.apache.camel.health.HealthCheckService;
-import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.impl.FileWatcherReloadStrategy;
 import org.apache.camel.model.Model;
 import org.apache.camel.processor.interceptor.BacklogTracer;
@@ -66,7 +65,6 @@ import org.apache.camel.spi.ThreadPoolProfile;
 import org.apache.camel.spi.UnitOfWorkFactory;
 import org.apache.camel.spi.UuidGenerator;
 import org.apache.camel.spring.CamelBeanPostProcessor;
-import org.apache.camel.spring.SpringCamelContext;
 import org.apache.camel.spring.spi.ApplicationContextBeanRepository;
 import org.apache.camel.spring.spi.XmlCamelContextConfigurer;
 import org.apache.camel.support.DefaultRegistry;
@@ -115,7 +113,7 @@ public class CamelAutoConfiguration {
     @ConditionalOnMissingBean(CamelContext.class)
     CamelContext camelContext(ApplicationContext applicationContext,
                               CamelConfigurationProperties config) throws 
Exception {
-        CamelContext camelContext = new SpringCamelContext(applicationContext);
+        CamelContext camelContext = new 
SpringBootCamelContext(applicationContext);
         return doConfigureCamelContext(applicationContext, camelContext, 
config);
     }
 
@@ -125,20 +123,18 @@ public class CamelAutoConfiguration {
 
         camelContext.init();
 
-        if (camelContext instanceof DefaultCamelContext) {
-            final DefaultCamelContext defaultContext = (DefaultCamelContext) 
camelContext;
-            final Map<String, BeanRepository> repositories = 
applicationContext.getBeansOfType(BeanRepository.class);
-
-            if (!repositories.isEmpty()) {
-                List<BeanRepository> reps = new ArrayList<>();
-                // include default bean repository as well
-                reps.add(new 
ApplicationContextBeanRepository(applicationContext));
-                // and then any custom
-                reps.addAll(repositories.values());
-                // sort by ordered
-                OrderComparator.sort(reps);
-                defaultContext.setRegistry(new DefaultRegistry(reps));
-            }
+        final Map<String, BeanRepository> repositories = 
applicationContext.getBeansOfType(BeanRepository.class);
+
+        if (!repositories.isEmpty()) {
+            List<BeanRepository> reps = new ArrayList<>();
+            // include default bean repository as well
+            reps.add(new ApplicationContextBeanRepository(applicationContext));
+            // and then any custom
+            reps.addAll(repositories.values());
+            // sort by ordered
+            OrderComparator.sort(reps);
+            // and plugin as new registry
+            camelContext.adapt(ExtendedCamelContext.class).setRegistry(new 
DefaultRegistry(reps));
         }
 
         if (ObjectHelper.isNotEmpty(config.getFileConfigurations())) {
@@ -158,7 +154,7 @@ public class CamelAutoConfiguration {
         }
 
         if (config.getName() != null) {
-            ((SpringCamelContext) camelContext).setName(config.getName());
+            
camelContext.adapt(ExtendedCamelContext.class).setName(config.getName());
         }
 
         if (config.getShutdownTimeout() > 0) {
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SpringBootCamelContext.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SpringBootCamelContext.java
new file mode 100644
index 0000000..bbcd395
--- /dev/null
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/SpringBootCamelContext.java
@@ -0,0 +1,57 @@
+/*
+ * 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.spring.boot;
+
+import org.apache.camel.spring.SpringCamelContext;
+import org.apache.camel.util.StopWatch;
+import org.springframework.context.ApplicationContext;
+
+/**
+ * The {@link org.apache.camel.CamelContext} created by Spring Boot.
+ */
+public class SpringBootCamelContext extends SpringCamelContext {
+
+    private final StopWatch stopWatch = new StopWatch();
+
+    public SpringBootCamelContext(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        stopWatch.restart();
+        super.doStart();
+    }
+
+    @Override
+    protected synchronized void doStop() throws Exception {
+        // if we are stopping very quickly then its likely because the user 
may not have either spring-boot-web
+        // or enabled Camel's main controller, so lets log a WARN about this.
+        long taken = stopWatch.taken();
+        if (taken < 1200) { // give it a bit of slack
+            String cp = System.getProperty("java.class.path");
+            boolean starterWeb = cp != null && 
cp.contains("spring-boot-starter-web");
+            boolean junit = cp != null && cp.contains("junit-");
+            if (!junit && !starterWeb) {
+                log.warn("CamelContext has only been running for less than a 
second. If you intend to run Camel for a longer time "
+                        + "then you can set the property 
camel.springboot.main-run-controller=true in application.properties"
+                        + " or add spring-boot-starter-web JAR to the 
classpath.");
+            }
+        }
+        super.doStop();
+    }
+}
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java 
b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
index 1304268..450b98a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExtendedCamelContext.java
@@ -41,6 +41,7 @@ import org.apache.camel.spi.ModelJAXBContextFactory;
 import org.apache.camel.spi.NodeIdFactory;
 import org.apache.camel.spi.PackageScanClassResolver;
 import org.apache.camel.spi.ProcessorFactory;
+import org.apache.camel.spi.Registry;
 import org.apache.camel.spi.RouteStartupOrder;
 import org.apache.camel.spi.UnitOfWorkFactory;
 
@@ -51,6 +52,26 @@ import org.apache.camel.spi.UnitOfWorkFactory;
 public interface ExtendedCamelContext extends CamelContext {
 
     /**
+     * Sets the name (id) of the this context.
+     * <p/>
+     * This operation is mostly only used by different Camel runtimes such as 
camel-spring, camel-cdi, camel-spring-boot etc.
+     * Important: Setting the name should only be set before CamelContext is 
started.
+     *
+     * @param name the name
+     */
+    void setName(String name);
+
+    /**
+     * Sets the registry Camel should use for looking up beans by name or type.
+     * <p/>
+     * This operation is mostly only used by different Camel runtimes such as 
camel-spring, camel-cdi, camel-spring-boot etc.
+     * Important: Setting the registry should only be set before CamelContext 
is started.
+     *
+     * @param registry the registry such as DefaultRegistry or
+     */
+    void setRegistry(Registry registry);
+
+    /**
      * Method to signal to {@link CamelContext} that the process to initialize 
setup routes is in progress.
      *
      * @param done <tt>false</tt> to start the process, call again with 
<tt>true</tt> to signal its done.
diff --git 
a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
 
b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index dd71ffd..adc276d 100644
--- 
a/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ 
b/core/camel-base/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -376,14 +376,8 @@ public abstract class AbstractCamelContext extends 
ServiceSupport implements Ext
         return getNameStrategy().getName();
     }
 
-    /**
-     * Sets the name of the this context.
-     *
-     * @param name the name
-     */
     public void setName(String name) {
-        // use an explicit name strategy since an explicit name was provided to
-        // be used
+        // use an explicit name strategy since an explicit name was provided 
to be used
         setNameStrategy(new ExplicitCamelContextNameStrategy(name));
     }
 

Reply via email to