You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2022/01/15 08:50:16 UTC

[camel] branch camel-3.14.x updated: CAMEL-17492: camel-core - Camel bean post processor should have injected camel context to avoid NPE such as when using spring boot and doing camel endpoint injected dependency injection.

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

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


The following commit(s) were added to refs/heads/camel-3.14.x by this push:
     new 596fdf7  CAMEL-17492: camel-core - Camel bean post processor should have injected camel context to avoid NPE such as when using spring boot and doing camel endpoint injected dependency injection.
596fdf7 is described below

commit 596fdf77f74a09c0049b20d175c28da6130d3ad2
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Jan 15 09:47:45 2022 +0100

    CAMEL-17492: camel-core - Camel bean post processor should have injected camel context to avoid NPE such as when using spring boot and doing camel endpoint injected dependency injection.
---
 .../camel/spring/spi/CamelBeanPostProcessor.java   | 42 ++++++++++++++++------
 .../org/apache/camel/ExtendedCamelContext.java     |  5 +++
 .../camel/impl/engine/AbstractCamelContext.java    |  1 +
 .../impl/engine/DefaultCamelBeanPostProcessor.java | 12 ++++++-
 .../camel/impl/ExtendedCamelContextConfigurer.java |  6 ++++
 .../camel/impl/lw/LightweightCamelContext.java     |  5 +++
 .../impl/lw/LightweightRuntimeCamelContext.java    | 11 +++---
 .../camel/main/DefaultConfigurationConfigurer.java |  3 +-
 8 files changed, 67 insertions(+), 18 deletions(-)

diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
index a8792f4..e365d8d 100644
--- a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
+++ b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Service;
 import org.apache.camel.impl.engine.CamelPostProcessorHelper;
@@ -43,7 +44,8 @@ import org.springframework.core.Ordered;
  * @see DefaultCamelBeanPostProcessor
  */
 public class CamelBeanPostProcessor
-        implements org.apache.camel.spi.CamelBeanPostProcessor, BeanPostProcessor, ApplicationContextAware, Ordered {
+        implements org.apache.camel.spi.CamelBeanPostProcessor, CamelContextAware, BeanPostProcessor, ApplicationContextAware,
+        Ordered {
     private static final Logger LOG = LoggerFactory.getLogger(CamelBeanPostProcessor.class);
 
     private final Set<String> prototypeBeans = new LinkedHashSet<>();
@@ -57,21 +59,34 @@ public class CamelBeanPostProcessor
     private final DefaultCamelBeanPostProcessor delegate = new DefaultCamelBeanPostProcessor() {
         @Override
         public CamelContext getOrLookupCamelContext() {
-            if (camelContext == null) {
+            CamelContext answer = CamelBeanPostProcessor.this.camelContext;
+            if (answer == null) {
                 if (camelId != null) {
                     LOG.trace("Looking up CamelContext by id: {} from Spring ApplicationContext: {}", camelId,
                             applicationContext);
-                    camelContext = applicationContext.getBean(camelId, CamelContext.class);
+                    answer = applicationContext.getBean(camelId, CamelContext.class);
                 } else {
                     // lookup by type and grab the single CamelContext if exists
                     LOG.trace("Looking up CamelContext by type from Spring ApplicationContext: {}", applicationContext);
                     Map<String, CamelContext> contexts = applicationContext.getBeansOfType(CamelContext.class);
                     if (contexts.size() == 1) {
-                        camelContext = contexts.values().iterator().next();
+                        answer = contexts.values().iterator().next();
                     }
                 }
+                if (answer != null) {
+                    // we found a camel context
+                    CamelBeanPostProcessor.this.camelContext = answer;
+                }
+            }
+            return answer;
+        }
+
+        @Override
+        public void setCamelContext(CamelContext camelContext) {
+            super.setCamelContext(camelContext);
+            if (camelPostProcessorHelper != null) {
+                camelPostProcessorHelper.setCamelContext(camelContext);
             }
-            return camelContext;
         }
 
         @Override
@@ -93,15 +108,19 @@ public class CamelBeanPostProcessor
         public CamelPostProcessorHelper getPostProcessorHelper() {
             // lets lazily create the post processor
             if (camelPostProcessorHelper == null) {
-                camelPostProcessorHelper = new CamelPostProcessorHelper() {
+                camelPostProcessorHelper = new CamelPostProcessorHelper(camelContext) {
 
                     @Override
                     public CamelContext getCamelContext() {
-                        // lets lazily lookup the camel context here
-                        // as doing this will cause this context to be started immediately
-                        // breaking the lifecycle ordering of different camel contexts
-                        // so we only want to do this on demand
-                        return delegate.getOrLookupCamelContext();
+                        CamelContext answer = CamelBeanPostProcessor.this.camelContext;
+                        if (answer == null) {
+                            // lets lazily lookup the camel context here
+                            // as doing this will cause this context to be started immediately
+                            // breaking the lifecycle ordering of different camel contexts
+                            // so we only want to do this on demand
+                            answer = delegate.getOrLookupCamelContext();
+                        }
+                        return answer;
                     }
 
                     @Override
@@ -193,6 +212,7 @@ public class CamelBeanPostProcessor
 
     public void setCamelContext(CamelContext camelContext) {
         this.camelContext = camelContext;
+        this.delegate.setCamelContext(camelContext);
     }
 
     public String getCamelId() {
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 26a029b..34f7407 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
@@ -257,6 +257,11 @@ public interface ExtendedCamelContext extends CamelContext {
     CamelBeanPostProcessor getBeanPostProcessor();
 
     /**
+     * Sets a custom bean post processor to use.
+     */
+    void setBeanPostProcessor(CamelBeanPostProcessor beanPostProcessor);
+
+    /**
      * Returns the management mbean assembler
      *
      * @return the mbean assembler
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 1903fc7..f993c2d9 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -1963,6 +1963,7 @@ public abstract class AbstractCamelContext extends BaseService
         return beanPostProcessor;
     }
 
+    @Override
     public void setBeanPostProcessor(CamelBeanPostProcessor beanPostProcessor) {
         this.beanPostProcessor = doAddService(beanPostProcessor);
     }
diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
index e76b8b7..e663b1f 100644
--- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
+++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
@@ -63,7 +63,7 @@ import static org.apache.camel.util.ObjectHelper.isEmpty;
  * Components such as camel-spring or camel-blueprint can leverage this post processor to hook in Camel bean post
  * processing into their bean processing framework.
  */
-public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
+public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor, CamelContextAware {
 
     protected static final Logger LOG = LoggerFactory.getLogger(DefaultCamelBeanPostProcessor.class);
     protected CamelPostProcessorHelper camelPostProcessorHelper;
@@ -78,6 +78,16 @@ public class DefaultCamelBeanPostProcessor implements CamelBeanPostProcessor {
     }
 
     @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
     public void setEnabled(boolean enabled) {
         this.enabled = enabled;
     }
diff --git a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
index 54bc4a1..fe6df2f 100644
--- a/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
+++ b/core/camel-core-engine/src/generated/java/org/apache/camel/impl/ExtendedCamelContextConfigurer.java
@@ -37,6 +37,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "BacklogTracing": target.setBacklogTracing(property(camelContext, java.lang.Boolean.class, value)); return true;
         case "beanintrospection":
         case "BeanIntrospection": target.setBeanIntrospection(property(camelContext, org.apache.camel.spi.BeanIntrospection.class, value)); return true;
+        case "beanpostprocessor":
+        case "BeanPostProcessor": target.setBeanPostProcessor(property(camelContext, org.apache.camel.spi.CamelBeanPostProcessor.class, value)); return true;
         case "bootstrapconfigurerresolver":
         case "BootstrapConfigurerResolver": target.setBootstrapConfigurerResolver(property(camelContext, org.apache.camel.spi.ConfigurerResolver.class, value)); return true;
         case "bootstrapfactoryfinder":
@@ -220,6 +222,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "BacklogTracing": return java.lang.Boolean.class;
         case "beanintrospection":
         case "BeanIntrospection": return org.apache.camel.spi.BeanIntrospection.class;
+        case "beanpostprocessor":
+        case "BeanPostProcessor": return org.apache.camel.spi.CamelBeanPostProcessor.class;
         case "bootstrapconfigurerresolver":
         case "BootstrapConfigurerResolver": return org.apache.camel.spi.ConfigurerResolver.class;
         case "bootstrapfactoryfinder":
@@ -404,6 +408,8 @@ public class ExtendedCamelContextConfigurer extends org.apache.camel.support.com
         case "BacklogTracing": return target.isBacklogTracing();
         case "beanintrospection":
         case "BeanIntrospection": return target.getBeanIntrospection();
+        case "beanpostprocessor":
+        case "BeanPostProcessor": return target.getBeanPostProcessor();
         case "bootstrapconfigurerresolver":
         case "BootstrapConfigurerResolver": return target.getBootstrapConfigurerResolver();
         case "bootstrapfactoryfinder":
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
index 5c1732c..9de9699 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightCamelContext.java
@@ -1214,6 +1214,11 @@ public class LightweightCamelContext implements ExtendedCamelContext, CatalogCam
     }
 
     @Override
+    public void setBeanPostProcessor(CamelBeanPostProcessor beanPostProcessor) {
+        getExtendedCamelContext().setBeanPostProcessor(beanPostProcessor);
+    }
+
+    @Override
     public ManagementMBeanAssembler getManagementMBeanAssembler() {
         return getExtendedCamelContext().getManagementMBeanAssembler();
     }
diff --git a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
index 0c6a135..167bb44 100644
--- a/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
+++ b/core/camel-core-engine/src/main/java/org/apache/camel/impl/lw/LightweightRuntimeCamelContext.java
@@ -173,6 +173,7 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
     private final Map<String, Language> languages;
     private final PropertiesComponent propertiesComponent;
     private final BeanIntrospection beanIntrospection;
+    private final CamelBeanPostProcessor beanPostProcessor;
     private final HeadersMapFactory headersMapFactory;
     private final ExchangeFactory exchangeFactory;
     private final ExchangeFactoryManager exchangeFactoryManager;
@@ -222,6 +223,7 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
         languages = context.getLanguageNames().stream().collect(Collectors.toMap(s -> s, context::resolveLanguage));
         propertiesComponent = context.getPropertiesComponent();
         beanIntrospection = context.adapt(ExtendedCamelContext.class).getBeanIntrospection();
+        beanPostProcessor = context.adapt(ExtendedCamelContext.class).getBeanPostProcessor();
         headersMapFactory = context.adapt(ExtendedCamelContext.class).getHeadersMapFactory();
         exchangeFactory = context.adapt(ExtendedCamelContext.class).getExchangeFactory();
         exchangeFactoryManager = context.adapt(ExtendedCamelContext.class).getExchangeFactoryManager();
@@ -1380,10 +1382,6 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
         }
     }
 
-    //
-    // CatalogCamelContext
-    //
-
     @Override
     public List<RouteStartupOrder> getRouteStartupOrder() {
         throw new UnsupportedOperationException();
@@ -1391,6 +1389,11 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
 
     @Override
     public CamelBeanPostProcessor getBeanPostProcessor() {
+        return beanPostProcessor;
+    }
+
+    @Override
+    public void setBeanPostProcessor(CamelBeanPostProcessor beanPostProcessor) {
         throw new UnsupportedOperationException();
     }
 
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 9361435..a8a24e8 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -314,8 +314,7 @@ public final class DefaultConfigurationConfigurer {
      * Performs additional configuration to lookup beans of Camel types to configure additional configurations on the
      * Camel context.
      * <p/>
-     * Similar code in camel-core-xml module in class org.apache.camel.core.xml.AbstractCamelContextFactoryBean or in
-     * camel-spring-boot module in class org.apache.camel.spring.boot.CamelAutoConfiguration.
+     * Similar code in camel-core-xml module in class org.apache.camel.core.xml.AbstractCamelContextFactoryBean.
      */
     public static void afterConfigure(final CamelContext camelContext) throws Exception {
         final Registry registry = camelContext.getRegistry();