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:49:26 UTC

[camel] branch main 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 main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new dc549b4  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.
dc549b4 is described below

commit dc549b4f6ac06cbe916ce077aafc7baf0188fd15
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 c5cc84e..4f66619 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 358d669..4d0105d 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
@@ -1966,6 +1966,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 fd7d7fc..6a416f31 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":
@@ -224,6 +226,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":
@@ -412,6 +416,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 ac4d26f..537134e 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
@@ -1238,6 +1238,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 ad67ebc..fc3ac5e 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();
@@ -1405,10 +1407,6 @@ public class LightweightRuntimeCamelContext implements ExtendedCamelContext, Cat
         }
     }
 
-    //
-    // CatalogCamelContext
-    //
-
     @Override
     public List<RouteStartupOrder> getRouteStartupOrder() {
         throw new UnsupportedOperationException();
@@ -1416,6 +1414,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 5147364..db7254b 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
@@ -326,8 +326,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();