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


The following commit(s) were added to refs/heads/master by this push:
     new 605361d  CAMEL-14860: Avoid reflection in circuit breaker reifiers
605361d is described below

commit 605361dd3842712d2c2bd9f7b9d8d9385cb1c7fa
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu Apr 9 09:17:41 2020 +0200

    CAMEL-14860: Avoid reflection in circuit breaker reifiers
---
 .../hystrix/processor/HystrixReifier.java          |  48 ++++++---
 .../hystrix/processor/HystrixRouteOkTest.java      |  26 +++++
 .../faulttolerance/FaultToleranceReifier.java      |  44 +++++++--
 ...ToleranceRefConfigurationNoReflectionTest.java} |  44 ++++++++-
 .../FaultToleranceRefConfigurationTest.java        | 110 +++++++++++++++++++++
 .../component/resilience4j/ResilienceReifier.java  |  41 ++++++--
 .../resilience4j/ResilienceRouteOkTest.java        |  26 +++++
 7 files changed, 305 insertions(+), 34 deletions(-)

diff --git 
a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixReifier.java
 
b/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixReifier.java
index 3fb59fe..40546bc 100644
--- 
a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixReifier.java
+++ 
b/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixReifier.java
@@ -26,7 +26,6 @@ import com.netflix.hystrix.HystrixCommandKey;
 import com.netflix.hystrix.HystrixCommandProperties;
 import com.netflix.hystrix.HystrixThreadPoolKey;
 import com.netflix.hystrix.HystrixThreadPoolProperties;
-import org.apache.camel.CamelContext;
 import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.Processor;
 import org.apache.camel.Route;
@@ -35,6 +34,8 @@ import org.apache.camel.model.HystrixConfigurationDefinition;
 import org.apache.camel.model.Model;
 import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.PropertyConfigurer;
+import org.apache.camel.spi.PropertyConfigurerGetter;
 import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.function.Suppliers;
 
@@ -211,38 +212,59 @@ public class HystrixReifier extends 
ProcessorReifier<CircuitBreakerDefinition> {
     HystrixConfigurationDefinition buildHystrixConfiguration() throws 
Exception {
         Map<String, Object> properties = new HashMap<>();
 
+        final PropertyConfigurer configurer = 
camelContext.adapt(ExtendedCamelContext.class)
+                
.getConfigurerResolver().resolvePropertyConfigurer(HystrixConfigurationDefinition.class.getSimpleName(),
 camelContext);
+
         // Extract properties from default configuration, the one configured on
         // camel context takes the precedence over those in the registry
-        loadProperties(camelContext, properties, Suppliers.firstNotNull(
+        loadProperties(properties, Suppliers.firstNotNull(
             () -> 
camelContext.getExtension(Model.class).getHystrixConfiguration(null),
-            () -> lookup(HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID, 
HystrixConfigurationDefinition.class))
-        );
+            () -> lookup(HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID, 
HystrixConfigurationDefinition.class)),
+            configurer);
 
         // Extract properties from referenced configuration, the one configured
         // on camel context takes the precedence over those in the registry
         if (definition.getConfigurationRef() != null) {
             final String ref = parseString(definition.getConfigurationRef());
 
-            loadProperties(camelContext, properties, Suppliers.firstNotNull(
+            loadProperties(properties, Suppliers.firstNotNull(
                 () -> 
camelContext.getExtension(Model.class).getHystrixConfiguration(ref),
-                () -> mandatoryLookup(ref, 
HystrixConfigurationDefinition.class))
-            );
+                () -> mandatoryLookup(ref, 
HystrixConfigurationDefinition.class)),
+                configurer);
         }
 
         // Extract properties from local configuration
-        loadProperties(camelContext, properties, 
Optional.ofNullable(definition.getHystrixConfiguration()));
-
-        HystrixConfigurationDefinition config = new 
HystrixConfigurationDefinition();
+        loadProperties(properties, 
Optional.ofNullable(definition.getHystrixConfiguration()), configurer);
 
         // Apply properties to a new configuration
-        PropertyBindingSupport.bindProperties(camelContext, config, 
properties);
+        HystrixConfigurationDefinition config = new 
HystrixConfigurationDefinition();
+        PropertyBindingSupport.build()
+                .withCamelContext(camelContext)
+                .withConfigurer(configurer)
+                .withProperties(properties)
+                .withTarget(config)
+                .bind();
 
         return config;
     }
 
-    private void loadProperties(CamelContext camelContext, Map<String, Object> 
properties, Optional<?> optional) {
+    private void loadProperties(Map<String, Object> properties, Optional<?> 
optional, PropertyConfigurer configurer) {
         BeanIntrospection beanIntrospection = 
camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection();
-        optional.ifPresent(bean -> beanIntrospection.getProperties(bean, 
properties, null, false));
+        optional.ifPresent(bean -> {
+            if (configurer instanceof PropertyConfigurerGetter) {
+                PropertyConfigurerGetter getter = (PropertyConfigurerGetter) 
configurer;
+                Map<String, Object> types = getter.getAllOptions(bean);
+                types.forEach((k, t) -> {
+                    Object value = getter.getOptionValue(bean, k, true);
+                    if (value != null) {
+                        properties.put(k, value);
+                    }
+                });
+            } else {
+                // no configurer found so use bean introspection (reflection)
+                beanIntrospection.getProperties(bean, properties, null, false);
+            }
+        });
     }
 
 }
diff --git 
a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteOkTest.java
 
b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteOkTest.java
index 19a7f88..162677d 100644
--- 
a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteOkTest.java
+++ 
b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteOkTest.java
@@ -16,15 +16,39 @@
  */
 package org.apache.camel.component.hystrix.processor;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.CircuitBreakerConstants;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.junit.Test;
 
 public class HystrixRouteOkTest extends CamelTestSupport {
 
+    private BeanIntrospection bi;
+
+    @Override
+    protected boolean useJmx() {
+        return false;
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        bi = context.adapt(ExtendedCamelContext.class).getBeanIntrospection();
+        bi.setLoggingLevel(LoggingLevel.INFO);
+        bi.resetCounters();
+
+        return context;
+    }
+
     @Test
     public void testHystrix() throws Exception {
+        assertEquals(0, bi.getInvokedCounter());
+
         getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
         
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION,
 true);
         
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK,
 false);
@@ -32,6 +56,8 @@ public class HystrixRouteOkTest extends CamelTestSupport {
         template.sendBody("direct:start", "Hello World");
 
         assertMockEndpointsSatisfied();
+
+        assertEquals(0, bi.getInvokedCounter());
     }
 
     @Override
diff --git 
a/components/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
 
b/components/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
index 8865e96..aa2b268 100644
--- 
a/components/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
+++ 
b/components/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.microprofile.faulttolerance;
 
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.ExecutorService;
@@ -31,6 +32,8 @@ import 
org.apache.camel.model.FaultToleranceConfigurationDefinition;
 import org.apache.camel.model.Model;
 import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.PropertyConfigurer;
+import org.apache.camel.spi.PropertyConfigurerGetter;
 import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.function.Suppliers;
 
@@ -74,7 +77,7 @@ public class FaultToleranceReifier extends 
ProcessorReifier<CircuitBreakerDefini
         target.setSuccessThreshold(parseInt(config.getSuccessThreshold(), 1));
         
target.setRequestVolumeThreshold(parseInt(config.getRequestVolumeThreshold(), 
20));
         if (config.getFailureRatio() != null) {
-            int num = parseInt(config.getFailureRatio(), 50);
+            float num = parseFloat(config.getFailureRatio(), 50);
             if (num < 1 || num > 100) {
                 throw new IllegalArgumentException("FailureRatio must be 
between 1 and 100, was: " + num);
             }
@@ -130,11 +133,15 @@ public class FaultToleranceReifier extends 
ProcessorReifier<CircuitBreakerDefini
     FaultToleranceConfigurationDefinition buildFaultToleranceConfiguration() 
throws Exception {
         Map<String, Object> properties = new HashMap<>();
 
+        final PropertyConfigurer configurer = 
camelContext.adapt(ExtendedCamelContext.class)
+                
.getConfigurerResolver().resolvePropertyConfigurer(FaultToleranceConfigurationDefinition.class.getSimpleName(),
 camelContext);
+
         // Extract properties from default configuration, the one configured on
         // camel context takes the precedence over those in the registry
         loadProperties(properties, Suppliers.firstNotNull(
             () -> 
camelContext.getExtension(Model.class).getFaultToleranceConfiguration(null),
-            () -> 
lookup(FaultToleranceConstants.DEFAULT_FAULT_TOLERANCE_CONFIGURATION_ID, 
FaultToleranceConfigurationDefinition.class)));
+            () -> 
lookup(FaultToleranceConstants.DEFAULT_FAULT_TOLERANCE_CONFIGURATION_ID, 
FaultToleranceConfigurationDefinition.class)),
+            configurer);
 
         // Extract properties from referenced configuration, the one configured
         // on camel context takes the precedence over those in the registry
@@ -143,23 +150,42 @@ public class FaultToleranceReifier extends 
ProcessorReifier<CircuitBreakerDefini
 
             loadProperties(properties, Suppliers.firstNotNull(
                 () -> 
camelContext.getExtension(Model.class).getFaultToleranceConfiguration(ref),
-                () -> mandatoryLookup(ref, 
FaultToleranceConfigurationDefinition.class)));
+                () -> mandatoryLookup(ref, 
FaultToleranceConfigurationDefinition.class)),
+                configurer);
         }
 
         // Extract properties from local configuration
-        loadProperties(properties, 
Optional.ofNullable(definition.getFaultToleranceConfiguration()));
-
-        FaultToleranceConfigurationDefinition config = new 
FaultToleranceConfigurationDefinition();
+        loadProperties(properties, 
Optional.ofNullable(definition.getFaultToleranceConfiguration()), configurer);
 
         // Apply properties to a new configuration
-        PropertyBindingSupport.bindProperties(camelContext, config, 
properties);
+        FaultToleranceConfigurationDefinition config = new 
FaultToleranceConfigurationDefinition();
+        PropertyBindingSupport.build()
+                .withCamelContext(camelContext)
+                .withConfigurer(configurer)
+                .withProperties(properties)
+                .withTarget(config)
+                .bind();
 
         return config;
     }
 
-    private void loadProperties(Map<String, Object> properties, Optional<?> 
optional) {
+    private void loadProperties(Map<String, Object> properties, Optional<?> 
optional, PropertyConfigurer configurer) {
         BeanIntrospection beanIntrospection = 
camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection();
-        optional.ifPresent(bean -> beanIntrospection.getProperties(bean, 
properties, null, false));
+        optional.ifPresent(bean -> {
+            if (configurer instanceof PropertyConfigurerGetter) {
+                PropertyConfigurerGetter getter = (PropertyConfigurerGetter) 
configurer;
+                Map<String, Object> types = getter.getAllOptions(bean);
+                types.forEach((k, t) -> {
+                    Object value = getter.getOptionValue(bean, k, true);
+                    if (value != null) {
+                        properties.put(k, value);
+                    }
+                });
+            } else {
+                // no configurer found so use bean introspection (reflection)
+                beanIntrospection.getProperties(bean, properties, null, false);
+            }
+        });
     }
 
 }
diff --git 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
 
b/components/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceRefConfigurationNoReflectionTest.java
similarity index 51%
copy from 
components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
copy to 
components/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceRefConfigurationNoReflectionTest.java
index b30d832..30d5b28 100644
--- 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
+++ 
b/components/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceRefConfigurationNoReflectionTest.java
@@ -14,17 +14,50 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.component.resilience4j;
+package org.apache.camel.component.microprofile.faulttolerance;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.FaultToleranceConfigurationDefinition;
+import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.CircuitBreakerConstants;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.junit.Test;
 
-public class ResilienceRouteOkTest extends CamelTestSupport {
+public class FaultToleranceRefConfigurationNoReflectionTest extends 
CamelTestSupport {
+
+    private BeanIntrospection bi;
+
+    @Override
+    protected boolean useJmx() {
+        return false;
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        bi = context.adapt(ExtendedCamelContext.class).getBeanIntrospection();
+        bi.setLoggingLevel(LoggingLevel.INFO);
+        bi.resetCounters();
+
+        FaultToleranceConfigurationDefinition config = new 
FaultToleranceConfigurationDefinition();
+        config.setTimeoutPoolSize("5");
+        config.setFailureRatio("25");
+        config.setRequestVolumeThreshold("10");
+        config.setDelay("5000");
+
+        context.getRegistry().bind("myConfig", config);
+
+        return context;
+    }
 
     @Test
-    public void testResilience() throws Exception {
+    public void testFaultTolerance() throws Exception {
+        assertEquals(0, bi.getInvokedCounter());
+
         getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
         
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION,
 true);
         
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK,
 false);
@@ -32,6 +65,8 @@ public class ResilienceRouteOkTest extends CamelTestSupport {
         template.sendBody("direct:start", "Hello World");
 
         assertMockEndpointsSatisfied();
+
+        assertEquals(0, bi.getInvokedCounter());
     }
 
     @Override
@@ -39,7 +74,8 @@ public class ResilienceRouteOkTest extends CamelTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                
from("direct:start").circuitBreaker().to("direct:foo").to("log:foo").onFallback().transform().constant("Fallback
 message").end().to("log:result").to("mock:result");
+                
from("direct:start").circuitBreaker().configuration("myConfig").faultToleranceConfiguration().delay(2000).timeoutEnabled(true).timeoutDuration(5000).end()
+                        
.to("direct:foo").to("log:foo").onFallback().transform().constant("Fallback 
message").end().to("log:result").to("mock:result");
 
                 from("direct:foo").transform().constant("Bye World");
             }
diff --git 
a/components/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceRefConfigurationTest.java
 
b/components/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceRefConfigurationTest.java
new file mode 100644
index 0000000..21c44c9
--- /dev/null
+++ 
b/components/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceRefConfigurationTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.component.microprofile.faulttolerance;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.FaultToleranceConfigurationDefinition;
+import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.CircuitBreakerConstants;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class FaultToleranceRefConfigurationTest extends CamelTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    protected MBeanServer getMBeanServer() {
+        return 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        FaultToleranceConfigurationDefinition config = new 
FaultToleranceConfigurationDefinition();
+        config.setTimeoutPoolSize("5");
+        config.setFailureRatio("25");
+        config.setRequestVolumeThreshold("10");
+        config.setDelay("5000");
+
+        context.getRegistry().bind("myConfig", config);
+
+        return context;
+    }
+
+    @Test
+    public void testFaultTolerance() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
+        
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION,
 true);
+        
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK,
 false);
+
+        template.sendBody("direct:start", "Hello World");
+
+        assertMockEndpointsSatisfied();
+
+        // look inside jmx
+        // get the stats for the route
+        MBeanServer mbeanServer = getMBeanServer();
+
+        // context name
+        String name = context.getManagementName();
+
+        // get the object name for the delayer
+        ObjectName on = ObjectName.getInstance("org.apache.camel:context=" + 
name + ",type=processors,name=\"myFaultTolerance\"");
+
+        // should be on start
+        String routeId = (String)mbeanServer.getAttribute(on, "RouteId");
+        assertEquals("start", routeId);
+
+        Long num = (Long)mbeanServer.getAttribute(on, "Delay");
+        assertEquals("2000", num.toString());
+
+        Boolean bool = (Boolean)mbeanServer.getAttribute(on, "TimeoutEnabled");
+        assertEquals(true, bool.booleanValue());
+
+        num = (Long)mbeanServer.getAttribute(on, "TimeoutDuration");
+        assertEquals("5000", num.toString());
+
+        Float fl = (Float)mbeanServer.getAttribute(on, "FailureRate");
+        assertEquals("0.25", fl.toString());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").routeId("start")
+                        
.circuitBreaker().id("myFaultTolerance").configuration("myConfig").faultToleranceConfiguration().delay(2000).timeoutEnabled(true).timeoutDuration(5000).end()
+                            .to("direct:foo").to("log:foo")
+                        .onFallback().transform().constant("Fallback 
message").end().to("log:result").to("mock:result");
+
+                from("direct:foo").transform().constant("Bye World");
+            }
+        };
+    }
+
+}
diff --git 
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
 
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
index cf18bb9..2ddcc62 100644
--- 
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
+++ 
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
@@ -35,6 +35,8 @@ import org.apache.camel.model.Resilience4jConfigurationCommon;
 import org.apache.camel.model.Resilience4jConfigurationDefinition;
 import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.spi.BeanIntrospection;
+import org.apache.camel.spi.PropertyConfigurer;
+import org.apache.camel.spi.PropertyConfigurerGetter;
 import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.function.Suppliers;
 
@@ -161,11 +163,15 @@ public class ResilienceReifier extends 
ProcessorReifier<CircuitBreakerDefinition
     Resilience4jConfigurationDefinition buildResilience4jConfiguration() 
throws Exception {
         Map<String, Object> properties = new HashMap<>();
 
+        final PropertyConfigurer configurer = 
camelContext.adapt(ExtendedCamelContext.class)
+                
.getConfigurerResolver().resolvePropertyConfigurer(Resilience4jConfigurationDefinition.class.getSimpleName(),
 camelContext);
+
         // Extract properties from default configuration, the one configured on
         // camel context takes the precedence over those in the registry
         loadProperties(properties, Suppliers.firstNotNull(
             () -> 
camelContext.getExtension(Model.class).getResilience4jConfiguration(null),
-            () -> 
lookup(ResilienceConstants.DEFAULT_RESILIENCE_CONFIGURATION_ID, 
Resilience4jConfigurationDefinition.class)));
+            () -> 
lookup(ResilienceConstants.DEFAULT_RESILIENCE_CONFIGURATION_ID, 
Resilience4jConfigurationDefinition.class)),
+            configurer);
 
         // Extract properties from referenced configuration, the one configured
         // on camel context takes the precedence over those in the registry
@@ -174,23 +180,42 @@ public class ResilienceReifier extends 
ProcessorReifier<CircuitBreakerDefinition
 
             loadProperties(properties, Suppliers.firstNotNull(
                 () -> 
camelContext.getExtension(Model.class).getResilience4jConfiguration(ref),
-                () -> mandatoryLookup(ref, 
Resilience4jConfigurationDefinition.class)));
+                () -> mandatoryLookup(ref, 
Resilience4jConfigurationDefinition.class)),
+                configurer);
         }
 
         // Extract properties from local configuration
-        loadProperties(properties, 
Optional.ofNullable(definition.getResilience4jConfiguration()));
-
-        Resilience4jConfigurationDefinition config = new 
Resilience4jConfigurationDefinition();
+        loadProperties(properties, 
Optional.ofNullable(definition.getResilience4jConfiguration()), configurer);
 
         // Apply properties to a new configuration
-        PropertyBindingSupport.bindProperties(camelContext, config, 
properties);
+        Resilience4jConfigurationDefinition config = new 
Resilience4jConfigurationDefinition();
+        PropertyBindingSupport.build()
+                .withCamelContext(camelContext)
+                .withConfigurer(configurer)
+                .withProperties(properties)
+                .withTarget(config)
+                .bind();
 
         return config;
     }
 
-    private void loadProperties(Map<String, Object> properties, Optional<?> 
optional) {
+    private void loadProperties(Map<String, Object> properties, Optional<?> 
optional, PropertyConfigurer configurer) {
         BeanIntrospection beanIntrospection = 
camelContext.adapt(ExtendedCamelContext.class).getBeanIntrospection();
-        optional.ifPresent(bean -> beanIntrospection.getProperties(bean, 
properties, null, false));
+        optional.ifPresent(bean -> {
+            if (configurer instanceof PropertyConfigurerGetter) {
+                PropertyConfigurerGetter getter = (PropertyConfigurerGetter) 
configurer;
+                Map<String, Object> types = getter.getAllOptions(bean);
+                types.forEach((k, t) -> {
+                    Object value = getter.getOptionValue(bean, k, true);
+                    if (value != null) {
+                        properties.put(k, value);
+                    }
+                });
+            } else {
+                // no configurer found so use bean introspection (reflection)
+                beanIntrospection.getProperties(bean, properties, null, false);
+            }
+        });
     }
 
 }
diff --git 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
 
b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
index b30d832..e890e2a 100644
--- 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
+++ 
b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteOkTest.java
@@ -16,15 +16,39 @@
  */
 package org.apache.camel.component.resilience4j;
 
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.LoggingLevel;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.CircuitBreakerConstants;
 import org.apache.camel.test.junit4.CamelTestSupport;
 import org.junit.Test;
 
 public class ResilienceRouteOkTest extends CamelTestSupport {
 
+    private BeanIntrospection bi;
+
+    @Override
+    protected boolean useJmx() {
+        return false;
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+
+        bi = context.adapt(ExtendedCamelContext.class).getBeanIntrospection();
+        bi.setLoggingLevel(LoggingLevel.INFO);
+        bi.resetCounters();
+
+        return context;
+    }
+
     @Test
     public void testResilience() throws Exception {
+        assertEquals(0, bi.getInvokedCounter());
+
         getMockEndpoint("mock:result").expectedBodiesReceived("Bye World");
         
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION,
 true);
         
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK,
 false);
@@ -32,6 +56,8 @@ public class ResilienceRouteOkTest extends CamelTestSupport {
         template.sendBody("direct:start", "Hello World");
 
         assertMockEndpointsSatisfied();
+
+        assertEquals(0, bi.getInvokedCounter());
     }
 
     @Override

Reply via email to