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