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/04/11 16:39:02 UTC

[camel] 01/02: CAMEL-17939: camel-main - Configure camel.beans map style using square brackets

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

commit 802c6d4873562a7cd6dbba76ec077c792ed04a91
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Apr 11 18:33:38 2022 +0200

    CAMEL-17939: camel-main - Configure camel.beans map style using square brackets
---
 .../org/apache/camel/main/BaseMainSupport.java     | 50 +++++++++++--
 .../java/org/apache/camel/main/MainHelper.java     | 26 +++++++
 .../java/org/apache/camel/main/MainBeansTest.java  | 82 ++++++++++++++++++++++
 3 files changed, 151 insertions(+), 7 deletions(-)

diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
index da7da3a4b07..c18caaf037f 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java
@@ -1215,13 +1215,23 @@ public abstract class BaseMainSupport extends BaseService {
 
         // make defensive copy as we mutate the map
         Set<String> keys = new LinkedHashSet(properties.keySet());
-        // find names of beans
-        final Set<String> beans
-                = properties.keySet().stream().map(k -> StringHelper.before(k.toString(), ".", k.toString()))
+        // find names of beans (dot style)
+        final Set<String> beansDot
+                = properties.keySet().stream()
+                        .map(k -> StringHelper.before(k.toString(), ".", k.toString()))
+                        .filter(k -> k.indexOf('[') == -1)
                         .collect(Collectors.toSet());
-        // create beans first
+
+        // find names of beans (map style)
+        final Set<String> beansMap
+                = properties.keySet().stream()
+                        .map(k -> StringHelper.before(k.toString(), "[", k.toString()))
+                        .filter(k -> k.indexOf('.') == -1)
+                        .collect(Collectors.toSet());
+
+        // then create beans first (beans with #class values etc)
         for (String key : keys) {
-            if (key.indexOf('.') == -1) {
+            if (key.indexOf('.') == -1 && key.indexOf('[') == -1) {
                 String name = key;
                 Object value = properties.remove(key);
                 Object bean = PropertyBindingSupport.resolveBean(camelContext, value);
@@ -1238,8 +1248,22 @@ public abstract class BaseMainSupport extends BaseService {
                 camelContext.getRegistry().bind(name, bean);
             }
         }
-        // then set properties per bean
-        for (String name : beans) {
+        // create map beans if none already exists
+        for (String name : beansMap) {
+            if (camelContext.getRegistry().lookupByName(name) == null) {
+                // register bean as a map
+                Map<String, Object> bean = new LinkedHashMap<>();
+                if (logSummary) {
+                    LOG.info("Binding bean: {} (type: {}) to the registry", name, ObjectHelper.classCanonicalName(bean));
+                } else {
+                    LOG.debug("Binding bean: {} (type: {}) to the registry", name, ObjectHelper.classCanonicalName(bean));
+                }
+                camelContext.getRegistry().bind(name, bean);
+            }
+        }
+
+        // then set properties per bean (dot style)
+        for (String name : beansDot) {
             Object bean = camelContext.getRegistry().lookupByName(name);
             if (bean == null) {
                 throw new IllegalArgumentException(
@@ -1250,6 +1274,18 @@ public abstract class BaseMainSupport extends BaseService {
             setPropertiesOnTarget(camelContext, bean, config, optionPrefix + name + ".", failIfNotSet, ignoreCase,
                     autoConfiguredProperties);
         }
+        // then set properties per bean (map style)
+        for (String name : beansMap) {
+            Object bean = camelContext.getRegistry().lookupByName(name);
+            if (bean == null) {
+                throw new IllegalArgumentException(
+                        "Cannot resolve bean with name " + name);
+            }
+            // configure all the properties on the bean at once (to ensure they are configured in right order)
+            OrderedLocationProperties config = MainHelper.extractProperties(properties, name + "[", "]");
+            setPropertiesOnTarget(camelContext, bean, config, optionPrefix + name + ".", failIfNotSet, ignoreCase,
+                    autoConfiguredProperties);
+        }
     }
 
     protected void autoConfigurationPropertiesComponent(
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
index 5b073d993ae..d4eb6aa1bdc 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/MainHelper.java
@@ -514,4 +514,30 @@ public final class MainHelper {
         return rc;
     }
 
+    public static OrderedLocationProperties extractProperties(
+            OrderedLocationProperties properties, String optionPrefix, String optionSuffix) {
+        if (properties == null) {
+            return new OrderedLocationProperties();
+        }
+        OrderedLocationProperties rc = new OrderedLocationProperties();
+
+        Set<Object> toRemove = new HashSet<>();
+        for (var entry : properties.entrySet()) {
+            String key = entry.getKey().toString();
+            String loc = properties.getLocation(key);
+            if (key.startsWith(optionPrefix)) {
+                Object value = properties.get(key);
+                key = key.substring(optionPrefix.length());
+                if (key.endsWith(optionSuffix)) {
+                    key = key.substring(0, key.length() - optionSuffix.length());
+                }
+                rc.put(loc, key, value);
+                toRemove.add(entry.getKey());
+            }
+        }
+        toRemove.forEach(properties::remove);
+
+        return rc;
+    }
+
 }
diff --git a/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java b/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
index 85ced2dfe64..745c4d4a0e2 100644
--- a/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
+++ b/core/camel-main/src/test/java/org/apache/camel/main/MainBeansTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.main;
 
+import java.util.Map;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.builder.RouteBuilder;
 import org.junit.jupiter.api.Test;
@@ -59,6 +61,86 @@ public class MainBeansTest {
         main.stop();
     }
 
+    @Test
+    public void testBindBeansMap() throws Exception {
+        Main main = new Main();
+        main.configure().addRoutesBuilder(new MyRouteBuilder());
+
+        // create by class
+        main.addProperty("camel.beans.foo", "#class:java.util.HashMap");
+        main.addProperty("camel.beans.foo.database", "mydb");
+        main.addProperty("camel.beans.foo.username", "scott");
+        main.addProperty("camel.beans.foo.password", "tiger");
+
+        main.start();
+
+        CamelContext camelContext = main.getCamelContext();
+        assertNotNull(camelContext);
+
+        Map foo = camelContext.getRegistry().lookupByNameAndType("foo", Map.class);
+        assertNotNull(foo);
+
+        assertEquals(3, foo.size());
+        assertEquals("mydb", foo.get("database"));
+        assertEquals("scott", foo.get("username"));
+        assertEquals("tiger", foo.get("password"));
+
+        main.stop();
+    }
+
+    @Test
+    public void testBindBeansMapSquareClass() throws Exception {
+        Main main = new Main();
+        main.configure().addRoutesBuilder(new MyRouteBuilder());
+
+        // create by class
+        main.addProperty("camel.beans.foo", "#class:java.util.HashMap");
+        main.addProperty("camel.beans.foo[database]", "mydb");
+        main.addProperty("camel.beans.foo[username]", "scott");
+        main.addProperty("camel.beans.foo[password]", "tiger");
+
+        main.start();
+
+        CamelContext camelContext = main.getCamelContext();
+        assertNotNull(camelContext);
+
+        Map foo = camelContext.getRegistry().lookupByNameAndType("foo", Map.class);
+        assertNotNull(foo);
+
+        assertEquals(3, foo.size());
+        assertEquals("mydb", foo.get("database"));
+        assertEquals("scott", foo.get("username"));
+        assertEquals("tiger", foo.get("password"));
+
+        main.stop();
+    }
+
+    @Test
+    public void testBindBeansMapSquare() throws Exception {
+        Main main = new Main();
+        main.configure().addRoutesBuilder(new MyRouteBuilder());
+
+        // create by class
+        main.addProperty("camel.beans.foo[database]", "mydb");
+        main.addProperty("camel.beans.foo[username]", "scott");
+        main.addProperty("camel.beans.foo[password]", "tiger");
+
+        main.start();
+
+        CamelContext camelContext = main.getCamelContext();
+        assertNotNull(camelContext);
+
+        Map foo = camelContext.getRegistry().lookupByNameAndType("foo", Map.class);
+        assertNotNull(foo);
+
+        assertEquals(3, foo.size());
+        assertEquals("mydb", foo.get("database"));
+        assertEquals("scott", foo.get("username"));
+        assertEquals("tiger", foo.get("password"));
+
+        main.stop();
+    }
+
     public static class MyRouteBuilder extends RouteBuilder {
         @Override
         public void configure() throws Exception {