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 2023/08/23 15:00:19 UTC

[camel] 03/03: CAMEL-19785: camel-yaml-dsl - Order of beans should not matter

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

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

commit 00f0c1f0659188b2a26a377fd10261db8fd6207d
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Aug 23 16:51:39 2023 +0200

    CAMEL-19785: camel-yaml-dsl - Order of beans should not matter
---
 .../dsl/yaml/deserializers/BeansDeserializer.java  | 73 +++++++++++++++-------
 1 file changed, 51 insertions(+), 22 deletions(-)

diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
index 4be1c650219..63f4e81fb37 100644
--- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
+++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/BeansDeserializer.java
@@ -23,7 +23,6 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializationContext;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerResolver;
 import org.apache.camel.dsl.yaml.common.YamlDeserializerSupport;
-import org.apache.camel.dsl.yaml.common.YamlSupport;
 import org.apache.camel.model.Model;
 import org.apache.camel.model.app.RegistryBeanDefinition;
 import org.apache.camel.spi.CamelContextCustomizer;
@@ -47,6 +46,7 @@ import org.snakeyaml.engine.v2.nodes.SequenceNode;
 public class BeansDeserializer extends YamlDeserializerSupport implements ConstructNode {
     @Override
     public Object construct(Node node) {
+        final BeansCustomizer answer = new BeansCustomizer();
         final SequenceNode sn = asSequenceNode(node);
         final List<CamelContextCustomizer> customizers = new ArrayList<>();
         final YamlDeserializationContext dc = getDeserializationContext(node);
@@ -65,29 +65,10 @@ public class BeansDeserializer extends YamlDeserializerSupport implements Constr
                 bean.setType("#class:" + bean.getType());
             }
 
-            customizers.add(new CamelContextCustomizer() {
-                @Override
-                public void configure(CamelContext camelContext) {
-                    try {
-                        // to support hot reloading of beans then we need to unbind old existing first
-                        String name = bean.getName();
-                        camelContext.getRegistry().unbind(name);
-                        camelContext.getRegistry().bind(
-                                name,
-                                newInstance(bean, camelContext));
-
-                        // register bean in model
-                        Model model = camelContext.getCamelContextExtension().getContextPlugin(Model.class);
-                        model.addRegistryBean(bean);
-
-                    } catch (Exception e) {
-                        throw new RuntimeException(e);
-                    }
-                }
-            });
+            answer.addBean(bean);
         }
 
-        return YamlSupport.customizer(customizers);
+        return answer;
     }
 
     public Object newInstance(RegistryBeanDefinition bean, CamelContext context) throws Exception {
@@ -100,4 +81,52 @@ public class BeansDeserializer extends YamlDeserializerSupport implements Constr
         return target;
     }
 
+    protected void registerBean(
+            CamelContext camelContext,
+            List<RegistryBeanDefinition> delayedRegistrations,
+            RegistryBeanDefinition def, boolean delayIfFailed) {
+        try {
+            // to support hot reloading of beans then we need to unbind old existing first
+            String name = def.getName();
+            Object bean = newInstance(def, camelContext);
+            camelContext.getRegistry().unbind(name);
+            camelContext.getRegistry().bind(name, bean);
+
+            // register bean in model
+            Model model = camelContext.getCamelContextExtension().getContextPlugin(Model.class);
+            model.addRegistryBean(def);
+
+        } catch (Exception e) {
+            if (delayIfFailed) {
+                delayedRegistrations.add(def);
+            } else {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private class BeansCustomizer implements CamelContextCustomizer {
+
+        private final List<RegistryBeanDefinition> delayedRegistrations = new ArrayList<>();
+        private final List<RegistryBeanDefinition> beans = new ArrayList<>();
+
+        public void addBean(RegistryBeanDefinition bean) {
+            beans.add(bean);
+        }
+
+        @Override
+        public void configure(CamelContext camelContext) {
+            // first-pass of creating beans
+            for (RegistryBeanDefinition bean : beans) {
+                registerBean(camelContext, delayedRegistrations, bean, true);
+            }
+            beans.clear();
+            // second-pass of creating beans should fail if not possible
+            for (RegistryBeanDefinition bean : delayedRegistrations) {
+                registerBean(camelContext, delayedRegistrations, bean, false);
+            }
+            delayedRegistrations.clear();
+        }
+    }
+
 }