This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch rm in repository https://gitbox.apache.org/repos/asf/camel.git
commit 6baee401d80e9eb2668a664a39c4695a064e68ae Author: Claus Ibsen <[email protected]> AuthorDate: Sat Aug 30 15:22:50 2025 +0200 CAMEL-22392: camel-resilience4j - Add micrometer support --- bom/camel-bom/pom.xml | 5 + catalog/camel-allcomponents/pom.xml | 5 + .../main/camel-main-configuration-metadata.json | 1 + .../catalog/models/resilience4jConfiguration.json | 5 +- .../org/apache/camel/catalog/others.properties | 1 + .../catalog/others/resilience4j-micrometer.json | 15 +++ .../apache/camel/catalog/schemas/camel-spring.xsd | 10 ++ .../apache/camel/catalog/schemas/camel-xml-io.xsd | 10 ++ components/camel-resilience4j-micrometer/pom.xml | 69 ++++++++++++++ .../services/org/apache/camel/other.properties | 7 ++ .../apache/camel/resilience4j-micrometer-factory | 2 + .../resources/resilience4j-micrometer.json | 15 +++ .../src/main/docs/resilience4j-micrometer.adoc | 50 ++++++++++ .../DefaultResilience4jMicrometerFactory.java | 106 +++++++++++++++++++++ .../resilience4j/micrometer/MicrometerTest.java | 93 ++++++++++++++++++ .../src/test/resources/log4j2.properties | 28 ++++++ .../resilience4j/ResilienceProcessor.java | 63 +++++++++--- .../component/resilience4j/ResilienceReifier.java | 35 +++++++ components/pom.xml | 5 +- .../camel/spi/Resilience4jMicrometerFactory.java | 34 +++++++ ...ilience4jConfigurationDefinitionConfigurer.java | 7 ++ .../camel/model/resilience4jConfiguration.json | 5 +- .../model/Resilience4jConfigurationCommon.java | 16 ++++ .../model/Resilience4jConfigurationDefinition.java | 9 ++ ...ilience4jConfigurationPropertiesConfigurer.java | 7 ++ .../camel-main-configuration-metadata.json | 1 + core/camel-main/src/main/docs/main.adoc | 3 +- .../org/apache/camel/main/BaseMainSupport.java | 23 +++++ .../main/Resilience4jConfigurationProperties.java | 23 +++++ .../java/org/apache/camel/xml/in/ModelParser.java | 1 + .../java/org/apache/camel/xml/out/ModelWriter.java | 1 + .../org/apache/camel/yaml/out/ModelWriter.java | 1 + .../examples/json/resilience4j-micrometer.json | 1 + docs/components/modules/others/nav.adoc | 1 + .../others/pages/resilience4j-micrometer.adoc | 1 + .../dsl/yaml/deserializers/ModelDeserializers.java | 6 ++ .../generated/resources/schema/camelYamlDsl.json | 6 ++ parent/pom.xml | 5 + 38 files changed, 658 insertions(+), 18 deletions(-) diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml index ea253969858..6ae5cec8f0c 100644 --- a/bom/camel-bom/pom.xml +++ b/bom/camel-bom/pom.xml @@ -1792,6 +1792,11 @@ <artifactId>camel-resilience4j</artifactId> <version>4.15.0-SNAPSHOT</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-resilience4j-micrometer</artifactId> + <version>4.15.0-SNAPSHOT</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-resourceresolver-github</artifactId> diff --git a/catalog/camel-allcomponents/pom.xml b/catalog/camel-allcomponents/pom.xml index 6a4910f05ed..2b09cb90d46 100644 --- a/catalog/camel-allcomponents/pom.xml +++ b/catalog/camel-allcomponents/pom.xml @@ -1591,6 +1591,11 @@ <artifactId>camel-resilience4j</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-resilience4j-micrometer</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-resourceresolver-github</artifactId> diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json index 43cd441ed42..713b469ce9c 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json @@ -247,6 +247,7 @@ { "name": "camel.resilience4j.circuitBreaker", "required": false, "description": "Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreaker instance to lookup and use from the registry. When using this, then any other circuit breaker options are not in use.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "string", "javaType": "java.lang.String", "secret": false }, { "name": "camel.resilience4j.config", "required": false, "description": "Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance to lookup and use from the registry.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "string", "javaType": "java.lang.String", "secret": false }, { "name": "camel.resilience4j.failureRateThreshold", "required": false, "description": "Configures the failure rate threshold in percentage. If the failure rate is equal or greater than the threshold the CircuitBreaker transitions to open and starts short-circuiting calls. The threshold must be greater than 0 and not greater than 100. Default value is 50 percentage.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "number", "javaType": "java.lang.F [...] + { "name": "camel.resilience4j.micrometerEnabled", "required": false, "description": "Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "boolean", "javaType": "java.lang.Boolean", "defaultValue": false, "secret": false }, { "name": "camel.resilience4j.minimumNumberOfCalls", "required": false, "description": "Configures configures the minimum number of calls which are required (per sliding window period) before the CircuitBreaker can calculate the error rate. For example, if minimumNumberOfCalls is 10, then at least 10 calls must be recorded, before the failure rate can be calculated. If only 9 calls have been recorded the CircuitBreaker will not transition to open even if all 9 calls have failed. Defa [...] { "name": "camel.resilience4j.permittedNumberOfCallsInHalfOpenState", "required": false, "description": "Configures the number of permitted calls when the CircuitBreaker is half open. The size must be greater than 0. Default size is 10.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "integer", "javaType": "java.lang.Integer", "defaultValue": 10, "secret": false }, { "name": "camel.resilience4j.slidingWindowSize", "required": false, "description": "Configures the size of the sliding window which is used to record the outcome of calls when the CircuitBreaker is closed. slidingWindowSize configures the size of the sliding window. Sliding window can either be count-based or time-based. If slidingWindowType is COUNT_BASED, the last slidingWindowSize calls are recorded and aggregated. If slidingWindowType is TIME_BASED, the calls of the last sliding [...] diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resilience4jConfiguration.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resilience4jConfiguration.json index 617a8892315..8d3169cf694 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resilience4jConfiguration.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/resilience4jConfiguration.json @@ -33,7 +33,8 @@ "timeoutExecutorService": { "index": 18, "kind": "attribute", "displayName": "Timeout Executor Service", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "References to a custom thread pool to use when timeout is enabled (uses ForkJoinPool#commonPool() by default)" }, "timeoutDuration": { "index": 19, "kind": "attribute", "displayName": "Timeout Duration", "group": "common", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Configures the thread execution timeout. Default value is 1 second." }, "timeoutCancelRunningFuture": { "index": 20, "kind": "attribute", "displayName": "Timeout Cancel Running Future", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Configures whether cancel is called on the running future. Defaults to true." }, - "recordException": { "index": 21, "kind": "element", "displayName": "Record Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list counts as a failure, unless explicitly ignor [...] - "ignoreException": { "index": 22, "kind": "element", "displayName": "Ignore Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are ignored and neither count as a failure nor success. Any exception matching or inheriting from one of the list will not count as a failure nor success, even if t [...] + "micrometerEnabled": { "index": 21, "kind": "attribute", "displayName": "Micrometer Enabled", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath." }, + "recordException": { "index": 22, "kind": "element", "displayName": "Record Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list counts as a failure, unless explicitly ignor [...] + "ignoreException": { "index": 23, "kind": "element", "displayName": "Ignore Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are ignored and neither count as a failure nor success. Any exception matching or inheriting from one of the list will not count as a failure nor success, even if t [...] } } diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties index 8e61de3c759..39b1e80ca2e 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others.properties @@ -46,6 +46,7 @@ reactive-executor-vertx reactor redis resilience4j +resilience4j-micrometer resourceresolver-github rxjava shiro diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/resilience4j-micrometer.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/resilience4j-micrometer.json new file mode 100644 index 00000000000..47b3c9af97f --- /dev/null +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/others/resilience4j-micrometer.json @@ -0,0 +1,15 @@ +{ + "other": { + "kind": "other", + "name": "resilience4j-micrometer", + "title": "Resilience4j Micrometer", + "description": "Micrometer statistics for Resilience4j", + "deprecated": false, + "firstVersion": "4.15.0", + "label": "eip,microservice", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-resilience4j-micrometer", + "version": "4.15.0-SNAPSHOT" + } +} diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd index 7e6a2746d5a..92a2e5f7198 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd @@ -5050,6 +5050,16 @@ Configures the thread execution timeout. Default value is 1 second. Default valu <xs:documentation xml:lang="en"> <![CDATA[ Configures whether cancel is called on the running future. Defaults to true. Default value: true +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="micrometerEnabled" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the +classpath. Default value: false ]]> </xs:documentation> </xs:annotation> diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd index 16fa9d11f17..cb37d6e3b82 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd @@ -3711,6 +3711,16 @@ Configures the thread execution timeout. Default value is 1 second. Default valu <xs:documentation xml:lang="en"> <![CDATA[ Configures whether cancel is called on the running future. Defaults to true. Default value: true +]]> + </xs:documentation> + </xs:annotation> + </xs:attribute> + <xs:attribute name="micrometerEnabled" type="xs:string"> + <xs:annotation> + <xs:documentation xml:lang="en"> +<![CDATA[ +Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the +classpath. Default value: false ]]> </xs:documentation> </xs:annotation> diff --git a/components/camel-resilience4j-micrometer/pom.xml b/components/camel-resilience4j-micrometer/pom.xml new file mode 100644 index 00000000000..829b115d20e --- /dev/null +++ b/components/camel-resilience4j-micrometer/pom.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.camel</groupId> + <artifactId>components</artifactId> + <version>4.15.0-SNAPSHOT</version> + </parent> + + <artifactId>camel-resilience4j-micrometer</artifactId> + <packaging>jar</packaging> + + <name>Camel :: Resilience4j :: Micrometer</name> + <description>Micrometer statistics for Resilience4j</description> + + <properties> + <firstVersion>4.15.0</firstVersion> + <label>eip,microservice</label> + <camel.surefire.parallel>true</camel.surefire.parallel> + </properties> + + <dependencies> + + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-resilience4j</artifactId> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-micrometer</artifactId> + </dependency> + <dependency> + <groupId>io.github.resilience4j</groupId> + <artifactId>resilience4j-micrometer</artifactId> + <version>${resilience4j-version}</version> + </dependency> + + <!-- for testing --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-test-spring-junit5</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-management</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/components/camel-resilience4j-micrometer/src/generated/resources/META-INF/services/org/apache/camel/other.properties b/components/camel-resilience4j-micrometer/src/generated/resources/META-INF/services/org/apache/camel/other.properties new file mode 100644 index 00000000000..248f8e6c9c7 --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/generated/resources/META-INF/services/org/apache/camel/other.properties @@ -0,0 +1,7 @@ +# Generated by camel build tools - do NOT edit this file! +name=resilience4j-micrometer +groupId=org.apache.camel +artifactId=camel-resilience4j-micrometer +version=4.15.0-SNAPSHOT +projectName=Camel :: Resilience4j :: Micrometer +projectDescription=Micrometer statistics for Resilience4j diff --git a/components/camel-resilience4j-micrometer/src/generated/resources/META-INF/services/org/apache/camel/resilience4j-micrometer-factory b/components/camel-resilience4j-micrometer/src/generated/resources/META-INF/services/org/apache/camel/resilience4j-micrometer-factory new file mode 100644 index 00000000000..e622a18899e --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/generated/resources/META-INF/services/org/apache/camel/resilience4j-micrometer-factory @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.component.resilience4j.micrometer.DefaultResilience4jMicrometerFactory diff --git a/components/camel-resilience4j-micrometer/src/generated/resources/resilience4j-micrometer.json b/components/camel-resilience4j-micrometer/src/generated/resources/resilience4j-micrometer.json new file mode 100644 index 00000000000..47b3c9af97f --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/generated/resources/resilience4j-micrometer.json @@ -0,0 +1,15 @@ +{ + "other": { + "kind": "other", + "name": "resilience4j-micrometer", + "title": "Resilience4j Micrometer", + "description": "Micrometer statistics for Resilience4j", + "deprecated": false, + "firstVersion": "4.15.0", + "label": "eip,microservice", + "supportLevel": "Preview", + "groupId": "org.apache.camel", + "artifactId": "camel-resilience4j-micrometer", + "version": "4.15.0-SNAPSHOT" + } +} diff --git a/components/camel-resilience4j-micrometer/src/main/docs/resilience4j-micrometer.adoc b/components/camel-resilience4j-micrometer/src/main/docs/resilience4j-micrometer.adoc new file mode 100644 index 00000000000..bc3cc22d973 --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/main/docs/resilience4j-micrometer.adoc @@ -0,0 +1,50 @@ += Resilience4j Micrometer Component +:doctitle: Resilience4j Micrometer +:shortname: resilience4j-micrometer +:artifactid: camel-resilience4j-micrometer +:description: Micrometer statistics for Resilience4j +:since: 4.15 +:supportlevel: Preview +:tabs-sync-option: +//Manually maintained attributes +:camel-spring-boot-name: resilience4j-micrometer + +*Since Camel {since}* + +This component adds Micrometer statistics for Circuit Breaker EIP with the https://resilience4j.readme.io/[Resilience4j] library. + +For more details, see the xref:eips:circuitBreaker-eip.adoc[Circuit Breaker EIP] documentation. + +Maven users will need to add the following dependency to their `pom.xml` +for this component: + +[source,xml] +---- +<dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-resilience4j-micrometer</artifactId> + <version>x.x.x</version> + <!-- use the same version as your Camel core version --> +</dependency> +---- + +== Configuring Resilience4j Micrometer + +When adding `camel-resilience4j-micrometer` JAR to the classpath, then CircuitBreakers will automatically enable gathering +statistics using Micrometer. + +However, this can explicit be configured via: `application.properties` such as: + +[source,properties] +---- +camel.resilience4j.micrometerEnabled = true +---- + +Or to turn it off: + +[source,properties] +---- +camel.resilience4j.micrometerEnabled = false +---- + +include::spring-boot:partial$starter.adoc[] diff --git a/components/camel-resilience4j-micrometer/src/main/java/org/apache/camel/component/resilience4j/micrometer/DefaultResilience4jMicrometerFactory.java b/components/camel-resilience4j-micrometer/src/main/java/org/apache/camel/component/resilience4j/micrometer/DefaultResilience4jMicrometerFactory.java new file mode 100644 index 00000000000..6e0b138c339 --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/main/java/org/apache/camel/component/resilience4j/micrometer/DefaultResilience4jMicrometerFactory.java @@ -0,0 +1,106 @@ +/* + * 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.resilience4j.micrometer; + +import io.github.resilience4j.bulkhead.BulkheadRegistry; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.micrometer.tagged.TaggedBulkheadMetrics; +import io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics; +import io.github.resilience4j.micrometer.tagged.TaggedTimeLimiterMetrics; +import io.github.resilience4j.timelimiter.TimeLimiterRegistry; +import io.micrometer.core.instrument.MeterRegistry; +import org.apache.camel.CamelContext; +import org.apache.camel.NonManagedService; +import org.apache.camel.component.micrometer.MicrometerConstants; +import org.apache.camel.component.micrometer.MicrometerUtils; +import org.apache.camel.spi.Registry; +import org.apache.camel.spi.Resilience4jMicrometerFactory; +import org.apache.camel.spi.annotations.JdkService; +import org.apache.camel.support.CamelContextHelper; +import org.apache.camel.support.service.ServiceSupport; + +@JdkService(Resilience4jMicrometerFactory.FACTORY) +public class DefaultResilience4jMicrometerFactory extends ServiceSupport + implements Resilience4jMicrometerFactory, NonManagedService { + + private MeterRegistry meterRegistry; + private CamelContext camelContext; + private CircuitBreakerRegistry circuitBreakerRegistry; + private TimeLimiterRegistry timeLimiterRegistry; + private BulkheadRegistry bulkheadRegistry; + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public void setMeterRegistry(Object meterRegistry) { + this.meterRegistry = (MeterRegistry) meterRegistry; + } + + public MeterRegistry getMeterRegistry() { + return meterRegistry; + } + + @Override + protected void doInit() throws Exception { + super.doInit(); + + if (meterRegistry == null) { + Registry camelRegistry = getCamelContext().getRegistry(); + meterRegistry = MicrometerUtils.getOrCreateMeterRegistry(camelRegistry, MicrometerConstants.METRICS_REGISTRY_NAME); + } + circuitBreakerRegistry = CamelContextHelper.findSingleByType(camelContext, CircuitBreakerRegistry.class); + if (circuitBreakerRegistry == null) { + circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults(); + camelContext.getCamelContextExtension().addContextPlugin(CircuitBreakerRegistry.class, circuitBreakerRegistry); + } + timeLimiterRegistry = CamelContextHelper.findSingleByType(camelContext, TimeLimiterRegistry.class); + if (timeLimiterRegistry == null) { + timeLimiterRegistry = TimeLimiterRegistry.ofDefaults(); + camelContext.getCamelContextExtension().addContextPlugin(TimeLimiterRegistry.class, timeLimiterRegistry); + } + bulkheadRegistry = CamelContextHelper.findSingleByType(camelContext, BulkheadRegistry.class); + if (bulkheadRegistry == null) { + bulkheadRegistry = BulkheadRegistry.ofDefaults(); + camelContext.getCamelContextExtension().addContextPlugin(BulkheadRegistry.class, bulkheadRegistry); + } + } + + @Override + protected void doStart() throws Exception { + super.doStart(); + + // bind circuit breakers to micrometer metrics + TaggedCircuitBreakerMetrics + .ofCircuitBreakerRegistry(circuitBreakerRegistry) + .bindTo(meterRegistry); + TaggedTimeLimiterMetrics + .ofTimeLimiterRegistry(timeLimiterRegistry) + .bindTo(meterRegistry); + TaggedBulkheadMetrics + .ofBulkheadRegistry(bulkheadRegistry) + .bindTo(meterRegistry); + } + +} diff --git a/components/camel-resilience4j-micrometer/src/test/java/org/apache/camel/component/resilience4j/micrometer/MicrometerTest.java b/components/camel-resilience4j-micrometer/src/test/java/org/apache/camel/component/resilience4j/micrometer/MicrometerTest.java new file mode 100644 index 00000000000..05441474e76 --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/test/java/org/apache/camel/component/resilience4j/micrometer/MicrometerTest.java @@ -0,0 +1,93 @@ +/* + * 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.resilience4j.micrometer; + +import io.micrometer.core.instrument.MeterRegistry; +import org.apache.camel.CamelContext; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.spi.CircuitBreakerConstants; +import org.apache.camel.test.junit5.CamelTestSupport; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class MicrometerTest extends CamelTestSupport { + + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + // enable micrometer by adding the factory + context.addService(new DefaultResilience4jMicrometerFactory()); + return context; + } + + @Test + public void testResilience() throws Exception { + test("direct:start"); + + DefaultResilience4jMicrometerFactory factory = context.hasService(DefaultResilience4jMicrometerFactory.class); + Assertions.assertNotNull(factory); + + MeterRegistry reg = factory.getMeterRegistry(); + Assertions.assertNotNull(reg); + + Assertions.assertEquals(35, reg.getMeters().size()); + } + + @Test + public void testResilienceWithTimeOut() throws Exception { + test("direct:start.with.timeout.enabled"); + + DefaultResilience4jMicrometerFactory factory = context.hasService(DefaultResilience4jMicrometerFactory.class); + Assertions.assertNotNull(factory); + + MeterRegistry reg = factory.getMeterRegistry(); + Assertions.assertNotNull(reg); + + Assertions.assertEquals(35, reg.getMeters().size()); + } + + private void test(String endPointUri) 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); + getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_STATE, "CLOSED"); + + template.sendBody(endPointUri, "Hello World"); + + MockEndpoint.assertIsSatisfied(context); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + @Override + public void configure() { + 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.with.timeout.enabled").circuitBreaker().resilience4jConfiguration() + .timeoutEnabled(true).timeoutDuration(2000).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-micrometer/src/test/resources/log4j2.properties b/components/camel-resilience4j-micrometer/src/test/resources/log4j2.properties new file mode 100644 index 00000000000..351292feb12 --- /dev/null +++ b/components/camel-resilience4j-micrometer/src/test/resources/log4j2.properties @@ -0,0 +1,28 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- + +appender.file.type = File +appender.file.name = file +appender.file.fileName = target/camel-resilience4j-micrometer-test.log +appender.file.layout.type = PatternLayout +appender.file.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n +appender.out.type = Console +appender.out.name = out +appender.out.layout.type = PatternLayout +appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n +rootLogger.level = INFO +rootLogger.appenderRef.file.ref = file diff --git a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java index 19b36f29ae3..8b8a72b9f54 100644 --- a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java +++ b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java @@ -30,11 +30,14 @@ import java.util.function.Supplier; import io.github.resilience4j.bulkhead.Bulkhead; import io.github.resilience4j.bulkhead.BulkheadConfig; import io.github.resilience4j.bulkhead.BulkheadFullException; +import io.github.resilience4j.bulkhead.BulkheadRegistry; import io.github.resilience4j.circuitbreaker.CallNotPermittedException; import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; import io.github.resilience4j.timelimiter.TimeLimiter; import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import io.github.resilience4j.timelimiter.TimeLimiterRegistry; import io.vavr.control.Try; import org.apache.camel.AsyncCallback; import org.apache.camel.CamelContext; @@ -74,7 +77,11 @@ public class ResilienceProcessor extends BaseProcessorSupport private static final Logger LOG = LoggerFactory.getLogger(ResilienceProcessor.class); - private volatile CircuitBreaker circuitBreaker; + private CircuitBreakerRegistry circuitBreakerRegistry; + private TimeLimiterRegistry timeLimiterRegistry; + private BulkheadRegistry bulkheadRegistry; + private CircuitBreaker circuitBreaker; + private boolean createCircuitBreaker = true; private CamelContext camelContext; private String id; private String routeId; @@ -112,13 +119,6 @@ public class ResilienceProcessor extends BaseProcessorSupport protected void doBuild() throws Exception { ObjectHelper.notNull(camelContext, "CamelContext", this); - if (timeLimiterConfig != null) { - timeLimiter = TimeLimiter.of(id, timeLimiterConfig); - } - if (bulkheadConfig != null) { - bulkhead = Bulkhead.of(id, bulkheadConfig); - } - boolean pooled = camelContext.getCamelContextExtension().getExchangeFactory().isPooled(); if (pooled) { int capacity = camelContext.getCamelContextExtension().getExchangeFactory().getCapacity(); @@ -162,10 +162,15 @@ public class ResilienceProcessor extends BaseProcessorSupport @Override protected void doStart() throws Exception { - if (circuitBreaker == null) { - circuitBreaker = CircuitBreaker.of(id, circuitBreakerConfig); + if (createCircuitBreaker && circuitBreaker == null) { + circuitBreaker = circuitBreakerRegistry.circuitBreaker(id, circuitBreakerConfig); + } + if (timeLimiterConfig != null) { + timeLimiter = timeLimiterRegistry.timeLimiter(id, timeLimiterConfig); + } + if (bulkheadConfig != null) { + bulkhead = bulkheadRegistry.bulkhead(id, bulkheadConfig); } - ServiceHelper.startService(processorExchangeFactory, taskFactory, fallbackTaskFactory, processor); } @@ -176,6 +181,17 @@ public class ResilienceProcessor extends BaseProcessorSupport } ServiceHelper.stopService(processorExchangeFactory, taskFactory, fallbackTaskFactory, processor); + + if (createCircuitBreaker) { + circuitBreakerRegistry.remove(id); + circuitBreaker = null; + } + if (timeLimiter != null) { + timeLimiterRegistry.remove(id); + } + if (bulkhead != null) { + bulkheadRegistry.remove(id); + } } @Override @@ -213,12 +229,37 @@ public class ResilienceProcessor extends BaseProcessorSupport this.routeId = routeId; } + public CircuitBreakerRegistry getCircuitBreakerRegistry() { + return circuitBreakerRegistry; + } + + public void setCircuitBreakerRegistry(CircuitBreakerRegistry circuitBreakerRegistry) { + this.circuitBreakerRegistry = circuitBreakerRegistry; + } + + public TimeLimiterRegistry getTimeLimiterRegistry() { + return timeLimiterRegistry; + } + + public void setTimeLimiterRegistry(TimeLimiterRegistry timeLimiterRegistry) { + this.timeLimiterRegistry = timeLimiterRegistry; + } + + public BulkheadRegistry getBulkheadRegistry() { + return bulkheadRegistry; + } + + public void setBulkheadRegistry(BulkheadRegistry bulkheadRegistry) { + this.bulkheadRegistry = bulkheadRegistry; + } + public CircuitBreaker getCircuitBreaker() { return circuitBreaker; } public void setCircuitBreaker(CircuitBreaker circuitBreaker) { this.circuitBreaker = circuitBreaker; + this.createCircuitBreaker = false; } public boolean isShutdownExecutorService() { 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 594601f72ee..8411a707bfb 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 @@ -26,9 +26,13 @@ import java.util.concurrent.ExecutorService; import java.util.function.Predicate; import io.github.resilience4j.bulkhead.BulkheadConfig; +import io.github.resilience4j.bulkhead.BulkheadRegistry; import io.github.resilience4j.circuitbreaker.CircuitBreaker; import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; import io.github.resilience4j.timelimiter.TimeLimiterConfig; +import io.github.resilience4j.timelimiter.TimeLimiterRegistry; +import org.apache.camel.CamelContext; import org.apache.camel.Processor; import org.apache.camel.Route; import org.apache.camel.model.CircuitBreakerDefinition; @@ -92,9 +96,40 @@ public class ResilienceReifier extends ProcessorReifier<CircuitBreakerDefinition CircuitBreaker cb = mandatoryLookup(parseString(config.getCircuitBreaker()), CircuitBreaker.class); answer.setCircuitBreaker(cb); } + configureResilience4jRegistries(camelContext, answer); return answer; } + private void configureResilience4jRegistries(CamelContext camelContext, ResilienceProcessor processor) { + CircuitBreakerRegistry registry = CamelContextHelper.findSingleByType(camelContext, CircuitBreakerRegistry.class); + if (registry == null) { + registry = camelContext.getCamelContextExtension().getContextPlugin(CircuitBreakerRegistry.class); + } + if (registry == null) { + registry = CircuitBreakerRegistry.ofDefaults(); + camelContext.getCamelContextExtension().addContextPlugin(CircuitBreakerRegistry.class, registry); + } + processor.setCircuitBreakerRegistry(registry); + TimeLimiterRegistry registry2 = CamelContextHelper.findSingleByType(camelContext, TimeLimiterRegistry.class); + if (registry2 == null) { + registry2 = camelContext.getCamelContextExtension().getContextPlugin(TimeLimiterRegistry.class); + } + if (registry2 == null) { + registry2 = TimeLimiterRegistry.ofDefaults(); + camelContext.getCamelContextExtension().addContextPlugin(TimeLimiterRegistry.class, registry2); + } + processor.setTimeLimiterRegistry(registry2); + BulkheadRegistry registry3 = CamelContextHelper.findSingleByType(camelContext, BulkheadRegistry.class); + if (registry3 == null) { + registry3 = camelContext.getCamelContextExtension().getContextPlugin(BulkheadRegistry.class); + } + if (registry3 == null) { + registry3 = BulkheadRegistry.ofDefaults(); + camelContext.getCamelContextExtension().addContextPlugin(BulkheadRegistry.class, registry3); + } + processor.setBulkheadRegistry(registry3); + } + private CircuitBreakerConfig configureCircuitBreaker(Resilience4jConfigurationCommon config) throws ClassNotFoundException { CircuitBreakerConfig.Builder builder = CircuitBreakerConfig.custom(); if (config.getAutomaticTransitionFromOpenToHalfOpenEnabled() != null) { diff --git a/components/pom.xml b/components/pom.xml index 80541a9cba3..3f554e9026c 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -254,8 +254,8 @@ <module>camel-printer</module> <module>camel-protobuf</module> <module>camel-pubnub</module> - <module>camel-pulsar</module> - <module>camel-pqc</module> + <module>camel-pulsar</module> + <module>camel-pqc</module> <module>camel-python</module> <module>camel-quartz</module> <module>camel-quickfix</module> @@ -265,6 +265,7 @@ <module>camel-reactor</module> <module>camel-redis</module> <module>camel-resilience4j</module> + <module>camel-resilience4j-micrometer</module> <module>camel-resourceresolver-github</module> <module>camel-robotframework</module> <module>camel-rocketmq</module> diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/Resilience4jMicrometerFactory.java b/core/camel-api/src/main/java/org/apache/camel/spi/Resilience4jMicrometerFactory.java new file mode 100644 index 00000000000..5896c333dde --- /dev/null +++ b/core/camel-api/src/main/java/org/apache/camel/spi/Resilience4jMicrometerFactory.java @@ -0,0 +1,34 @@ +/* + * 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.spi; + +import org.apache.camel.CamelContextAware; +import org.apache.camel.Service; + +/** + * A factory for using micrometer with resilience4j circuit breakers + */ +public interface Resilience4jMicrometerFactory extends Service, CamelContextAware { + + String FACTORY = "resilience4j-micrometer-factory"; + + /** + * To use a specific io.micrometer.core.instrument.MeterRegistry. + */ + void setMeterRegistry(Object micrometerMeterRegistry); + +} diff --git a/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java b/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java index eadd2454f27..e39a21bcf02 100644 --- a/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java +++ b/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java @@ -31,6 +31,7 @@ public class Resilience4jConfigurationDefinitionConfigurer extends org.apache.ca map.put("FailureRateThreshold", java.lang.String.class); map.put("Id", java.lang.String.class); map.put("IgnoreExceptions", java.util.List.class); + map.put("MicrometerEnabled", java.lang.String.class); map.put("MinimumNumberOfCalls", java.lang.String.class); map.put("PermittedNumberOfCallsInHalfOpenState", java.lang.String.class); map.put("RecordExceptions", java.util.List.class); @@ -68,6 +69,8 @@ public class Resilience4jConfigurationDefinitionConfigurer extends org.apache.ca case "id": target.setId(property(camelContext, java.lang.String.class, value)); return true; case "ignoreexceptions": case "ignoreExceptions": target.setIgnoreExceptions(property(camelContext, java.util.List.class, value)); return true; + case "micrometerenabled": + case "micrometerEnabled": target.setMicrometerEnabled(property(camelContext, java.lang.String.class, value)); return true; case "minimumnumberofcalls": case "minimumNumberOfCalls": target.setMinimumNumberOfCalls(property(camelContext, java.lang.String.class, value)); return true; case "permittednumberofcallsinhalfopenstate": @@ -124,6 +127,8 @@ public class Resilience4jConfigurationDefinitionConfigurer extends org.apache.ca case "id": return java.lang.String.class; case "ignoreexceptions": case "ignoreExceptions": return java.util.List.class; + case "micrometerenabled": + case "micrometerEnabled": return java.lang.String.class; case "minimumnumberofcalls": case "minimumNumberOfCalls": return java.lang.String.class; case "permittednumberofcallsinhalfopenstate": @@ -176,6 +181,8 @@ public class Resilience4jConfigurationDefinitionConfigurer extends org.apache.ca case "id": return target.getId(); case "ignoreexceptions": case "ignoreExceptions": return target.getIgnoreExceptions(); + case "micrometerenabled": + case "micrometerEnabled": return target.getMicrometerEnabled(); case "minimumnumberofcalls": case "minimumNumberOfCalls": return target.getMinimumNumberOfCalls(); case "permittednumberofcallsinhalfopenstate": diff --git a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/resilience4jConfiguration.json b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/resilience4jConfiguration.json index 617a8892315..8d3169cf694 100644 --- a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/resilience4jConfiguration.json +++ b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/resilience4jConfiguration.json @@ -33,7 +33,8 @@ "timeoutExecutorService": { "index": 18, "kind": "attribute", "displayName": "Timeout Executor Service", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "java.util.concurrent.ExecutorService", "deprecated": false, "autowired": false, "secret": false, "description": "References to a custom thread pool to use when timeout is enabled (uses ForkJoinPool#commonPool() by default)" }, "timeoutDuration": { "index": 19, "kind": "attribute", "displayName": "Timeout Duration", "group": "common", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 1000, "description": "Configures the thread execution timeout. Default value is 1 second." }, "timeoutCancelRunningFuture": { "index": 20, "kind": "attribute", "displayName": "Timeout Cancel Running Future", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Configures whether cancel is called on the running future. Defaults to true." }, - "recordException": { "index": 21, "kind": "element", "displayName": "Record Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list counts as a failure, unless explicitly ignor [...] - "ignoreException": { "index": 22, "kind": "element", "displayName": "Ignore Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are ignored and neither count as a failure nor success. Any exception matching or inheriting from one of the list will not count as a failure nor success, even if t [...] + "micrometerEnabled": { "index": 21, "kind": "attribute", "displayName": "Micrometer Enabled", "group": "common", "required": false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath." }, + "recordException": { "index": 22, "kind": "element", "displayName": "Record Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list counts as a failure, unless explicitly ignor [...] + "ignoreException": { "index": 23, "kind": "element", "displayName": "Ignore Exception", "group": "advanced", "label": "advanced", "required": false, "type": "array", "javaType": "java.util.List<java.lang.String>", "deprecated": false, "autowired": false, "secret": false, "description": "Configure a list of exceptions that are ignored and neither count as a failure nor success. Any exception matching or inheriting from one of the list will not count as a failure nor success, even if t [...] } } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java index 81022019b05..8ee79e53136 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java @@ -90,6 +90,9 @@ public class Resilience4jConfigurationCommon extends IdentifiedType { @XmlAttribute @Metadata(label = "advanced", defaultValue = "true", javaType = "java.lang.Boolean") private String timeoutCancelRunningFuture; + @XmlAttribute + @Metadata(defaultValue = "false", javaType = "java.lang.Boolean") + private String micrometerEnabled; @XmlElement(name = "recordException") @Metadata(label = "advanced") private List<String> recordExceptions = new ArrayList<>(); @@ -118,6 +121,7 @@ public class Resilience4jConfigurationCommon extends IdentifiedType { this.bulkheadMaxConcurrentCalls = source.bulkheadMaxConcurrentCalls; this.bulkheadMaxWaitDuration = source.bulkheadMaxWaitDuration; this.timeoutEnabled = source.timeoutEnabled; + this.micrometerEnabled = source.micrometerEnabled; this.timeoutExecutorService = source.timeoutExecutorService; this.timeoutDuration = source.timeoutDuration; this.timeoutCancelRunningFuture = source.timeoutCancelRunningFuture; @@ -403,6 +407,18 @@ public class Resilience4jConfigurationCommon extends IdentifiedType { this.timeoutCancelRunningFuture = timeoutCancelRunningFuture; } + public String getMicrometerEnabled() { + return micrometerEnabled; + } + + /** + * Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR + * to the classpath. + */ + public void setMicrometerEnabled(String micrometerEnabled) { + this.micrometerEnabled = micrometerEnabled; + } + public List<String> getRecordExceptions() { return recordExceptions; } diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java index 1255c5c79ab..4a1c223ec0d 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java @@ -263,6 +263,15 @@ public class Resilience4jConfigurationDefinition extends Resilience4jConfigurati return this; } + /** + * Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR + * to the classpath. + */ + public Resilience4jConfigurationDefinition micrometerEnabled(boolean micrometerEnabled) { + setMicrometerEnabled(Boolean.toString(micrometerEnabled)); + return this; + } + /** * Configure a list of exceptions that are recorded as a failure and thus increase the failure rate. Any exception * matching or inheriting from one of the list counts as a failure, unless explicitly ignored via ignoreExceptions. diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java index 8527c629782..4f6862c7766 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java @@ -29,6 +29,7 @@ public class Resilience4jConfigurationPropertiesConfigurer extends org.apache.ca map.put("CircuitBreaker", java.lang.String.class); map.put("Config", java.lang.String.class); map.put("FailureRateThreshold", java.lang.Float.class); + map.put("MicrometerEnabled", java.lang.Boolean.class); map.put("MinimumNumberOfCalls", java.lang.Integer.class); map.put("PermittedNumberOfCallsInHalfOpenState", java.lang.Integer.class); map.put("SlidingWindowSize", java.lang.Integer.class); @@ -62,6 +63,8 @@ public class Resilience4jConfigurationPropertiesConfigurer extends org.apache.ca case "config": target.setConfig(property(camelContext, java.lang.String.class, value)); return true; case "failureratethreshold": case "failureRateThreshold": target.setFailureRateThreshold(property(camelContext, java.lang.Float.class, value)); return true; + case "micrometerenabled": + case "micrometerEnabled": target.setMicrometerEnabled(property(camelContext, java.lang.Boolean.class, value)); return true; case "minimumnumberofcalls": case "minimumNumberOfCalls": target.setMinimumNumberOfCalls(property(camelContext, java.lang.Integer.class, value)); return true; case "permittednumberofcallsinhalfopenstate": @@ -113,6 +116,8 @@ public class Resilience4jConfigurationPropertiesConfigurer extends org.apache.ca case "config": return java.lang.String.class; case "failureratethreshold": case "failureRateThreshold": return java.lang.Float.class; + case "micrometerenabled": + case "micrometerEnabled": return java.lang.Boolean.class; case "minimumnumberofcalls": case "minimumNumberOfCalls": return java.lang.Integer.class; case "permittednumberofcallsinhalfopenstate": @@ -160,6 +165,8 @@ public class Resilience4jConfigurationPropertiesConfigurer extends org.apache.ca case "config": return target.getConfig(); case "failureratethreshold": case "failureRateThreshold": return target.getFailureRateThreshold(); + case "micrometerenabled": + case "micrometerEnabled": return target.getMicrometerEnabled(); case "minimumnumberofcalls": case "minimumNumberOfCalls": return target.getMinimumNumberOfCalls(); case "permittednumberofcallsinhalfopenstate": diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index 43cd441ed42..713b469ce9c 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -247,6 +247,7 @@ { "name": "camel.resilience4j.circuitBreaker", "required": false, "description": "Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreaker instance to lookup and use from the registry. When using this, then any other circuit breaker options are not in use.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "string", "javaType": "java.lang.String", "secret": false }, { "name": "camel.resilience4j.config", "required": false, "description": "Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance to lookup and use from the registry.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "string", "javaType": "java.lang.String", "secret": false }, { "name": "camel.resilience4j.failureRateThreshold", "required": false, "description": "Configures the failure rate threshold in percentage. If the failure rate is equal or greater than the threshold the CircuitBreaker transitions to open and starts short-circuiting calls. The threshold must be greater than 0 and not greater than 100. Default value is 50 percentage.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "number", "javaType": "java.lang.F [...] + { "name": "camel.resilience4j.micrometerEnabled", "required": false, "description": "Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "boolean", "javaType": "java.lang.Boolean", "defaultValue": false, "secret": false }, { "name": "camel.resilience4j.minimumNumberOfCalls", "required": false, "description": "Configures configures the minimum number of calls which are required (per sliding window period) before the CircuitBreaker can calculate the error rate. For example, if minimumNumberOfCalls is 10, then at least 10 calls must be recorded, before the failure rate can be calculated. If only 9 calls have been recorded the CircuitBreaker will not transition to open even if all 9 calls have failed. Defa [...] { "name": "camel.resilience4j.permittedNumberOfCallsInHalfOpenState", "required": false, "description": "Configures the number of permitted calls when the CircuitBreaker is half open. The size must be greater than 0. Default size is 10.", "sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", "type": "integer", "javaType": "java.lang.Integer", "defaultValue": 10, "secret": false }, { "name": "camel.resilience4j.slidingWindowSize", "required": false, "description": "Configures the size of the sliding window which is used to record the outcome of calls when the CircuitBreaker is closed. slidingWindowSize configures the size of the sliding window. Sliding window can either be count-based or time-based. If slidingWindowType is COUNT_BASED, the last slidingWindowSize calls are recorded and aggregated. If slidingWindowType is TIME_BASED, the calls of the last sliding [...] diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 9046e64a37f..8dac7ccd593 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -607,7 +607,7 @@ The camel.faulttolerance supports 12 options, which are listed below. === Resilience4j EIP Circuit Breaker configurations -The camel.resilience4j supports 20 options, which are listed below. +The camel.resilience4j supports 21 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== @@ -619,6 +619,7 @@ The camel.resilience4j supports 20 options, which are listed below. | *camel.resilience4j.circuit{zwsp}Breaker* | Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreaker instance to lookup and use from the registry. When using this, then any other circuit breaker options are not in use. | | String | *camel.resilience4j.config* | Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance to lookup and use from the registry. | | String | *camel.resilience4j.failureRate{zwsp}Threshold* | Configures the failure rate threshold in percentage. If the failure rate is equal or greater than the threshold the CircuitBreaker transitions to open and starts short-circuiting calls. The threshold must be greater than 0 and not greater than 100. Default value is 50 percentage. | 50 | Float +| *camel.resilience4j.micrometer{zwsp}Enabled* | Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath. | false | Boolean | *camel.resilience4j.minimum{zwsp}NumberOfCalls* | Configures configures the minimum number of calls which are required (per sliding window period) before the CircuitBreaker can calculate the error rate. For example, if minimumNumberOfCalls is 10, then at least 10 calls must be recorded, before the failure rate can be calculated. If only 9 calls have been recorded the CircuitBreaker will not transition to open even if all 9 calls have failed. Default minimumNumberOfCalls is 100 | 100 | Integer | *camel.resilience4j.permitted{zwsp}NumberOfCallsInHalfOpenState* | Configures the number of permitted calls when the CircuitBreaker is half open. The size must be greater than 0. Default size is 10. | 10 | Integer | *camel.resilience4j.sliding{zwsp}WindowSize* | Configures the size of the sliding window which is used to record the outcome of calls when the CircuitBreaker is closed. slidingWindowSize configures the size of the sliding window. Sliding window can either be count-based or time-based. If slidingWindowType is COUNT_BASED, the last slidingWindowSize calls are recorded and aggregated. If slidingWindowType is TIME_BASED, the calls of the last slidingWindowSize seconds are recorded and aggr [...] 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 62d7e776197..972b665f519 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 @@ -60,6 +60,8 @@ import org.apache.camel.health.HealthCheckRegistry; import org.apache.camel.health.HealthCheckRepository; import org.apache.camel.impl.engine.DefaultCompileStrategy; import org.apache.camel.impl.engine.DefaultRoutesLoader; +import org.apache.camel.model.ModelCamelContext; +import org.apache.camel.model.Resilience4jConfigurationDefinition; import org.apache.camel.saga.CamelSagaService; import org.apache.camel.spi.AutowiredLifecycleStrategy; import org.apache.camel.spi.BacklogTracer; @@ -76,6 +78,7 @@ import org.apache.camel.spi.LifecycleStrategy; import org.apache.camel.spi.PackageScanClassResolver; import org.apache.camel.spi.PropertiesComponent; import org.apache.camel.spi.Registry; +import org.apache.camel.spi.Resilience4jMicrometerFactory; import org.apache.camel.spi.RouteTemplateParameterSource; import org.apache.camel.spi.RoutesLoader; import org.apache.camel.spi.StartupCondition; @@ -925,6 +928,8 @@ public abstract class BaseMainSupport extends BaseService { if (standalone) { // detect if camel-debug JAR is on classpath as we need to know this before configuring routes detectCamelDebugJar(camelContext); + // detect micrometer for resilience4j circuit breakers + detectResilience4jMicrometer(camelContext); step = recorder.beginStep(BaseMainSupport.class, "configureRoutes", "Collect Routes"); configureRoutes(camelContext); recorder.endStep(step); @@ -961,6 +966,24 @@ public abstract class BaseMainSupport extends BaseService { } } + protected void detectResilience4jMicrometer(CamelContext camelContext) throws Exception { + // optional discover camel-resilience4j-micrometer + Resilience4jMicrometerFactory mf = camelContext.getCamelContextExtension().getBootstrapFactoryFinder() + .newInstance(Resilience4jMicrometerFactory.FACTORY, Resilience4jMicrometerFactory.class).orElse(null); + if (mf == null) { + ModelCamelContext model = (ModelCamelContext) camelContext; + Resilience4jConfigurationDefinition config = model.getResilience4jConfiguration(null); + boolean micrometer = config != null && CamelContextHelper.parseBoolean(camelContext, config.getMicrometerEnabled()); + if (micrometer) { + throw new IllegalArgumentException( + "Cannot find Resilience4jMicrometerFactory on classpath. Add camel-resilience4j-micrometer to classpath."); + } + } + if (mf != null) { + camelContext.addService(mf); + } + } + protected void autoConfigurationFailFast(CamelContext camelContext, OrderedLocationProperties autoConfiguredProperties) throws Exception { // load properties diff --git a/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java index 460992a07f9..3f67431cbfb 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java @@ -63,6 +63,8 @@ public class Resilience4jConfigurationProperties implements BootstrapCloseable { private Integer timeoutDuration; @Metadata(defaultValue = "true") private Boolean timeoutCancelRunningFuture; + @Metadata(defaultValue = "false") + private Boolean micrometerEnabled; public Resilience4jConfigurationProperties(MainConfigurationProperties parent) { this.parent = parent; @@ -348,6 +350,18 @@ public class Resilience4jConfigurationProperties implements BootstrapCloseable { this.timeoutCancelRunningFuture = timeoutCancelRunningFuture; } + public Boolean getMicrometerEnabled() { + return micrometerEnabled; + } + + /** + * Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR + * to the classpath. + */ + public void setMicrometerEnabled(Boolean micrometerEnabled) { + this.micrometerEnabled = micrometerEnabled; + } + /** * Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreaker instance to lookup and use from the * registry. When using this, then any other circuit breaker options are not in use. @@ -556,4 +570,13 @@ public class Resilience4jConfigurationProperties implements BootstrapCloseable { return this; } + /** + * Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR + * to the classpath. + */ + public Resilience4jConfigurationProperties withMicrometerEnabled(Boolean micrometerEnabled) { + this.micrometerEnabled = micrometerEnabled; + return this; + } + } diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java index 143322315cb..56fc2ae5271 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java @@ -790,6 +790,7 @@ public class ModelParser extends BaseParser { case "circuitBreaker": def.setCircuitBreaker(val); yield true; case "config": def.setConfig(val); yield true; case "failureRateThreshold": def.setFailureRateThreshold(val); yield true; + case "micrometerEnabled": def.setMicrometerEnabled(val); yield true; case "minimumNumberOfCalls": def.setMinimumNumberOfCalls(val); yield true; case "permittedNumberOfCallsInHalfOpenState": def.setPermittedNumberOfCallsInHalfOpenState(val); yield true; case "slidingWindowSize": def.setSlidingWindowSize(val); yield true; diff --git a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java index 9bd654d3b53..023755f7260 100644 --- a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java +++ b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java @@ -1545,6 +1545,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("permittedNumberOfCallsInHalfOpenState", def.getPermittedNumberOfCallsInHalfOpenState(), "10"); doWriteAttribute("throwExceptionWhenHalfOpenOrOpenState", def.getThrowExceptionWhenHalfOpenOrOpenState(), "false"); doWriteAttribute("slowCallRateThreshold", def.getSlowCallRateThreshold(), "100"); + doWriteAttribute("micrometerEnabled", def.getMicrometerEnabled(), "false"); doWriteAttribute("writableStackTraceEnabled", def.getWritableStackTraceEnabled(), "true"); doWriteAttribute("automaticTransitionFromOpenToHalfOpenEnabled", def.getAutomaticTransitionFromOpenToHalfOpenEnabled(), "false"); doWriteAttribute("circuitBreaker", def.getCircuitBreaker(), null); diff --git a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java index 9b1ce4d935c..b1327cecb34 100644 --- a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java +++ b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java @@ -1545,6 +1545,7 @@ public class ModelWriter extends BaseWriter { doWriteAttribute("permittedNumberOfCallsInHalfOpenState", def.getPermittedNumberOfCallsInHalfOpenState(), "10"); doWriteAttribute("throwExceptionWhenHalfOpenOrOpenState", def.getThrowExceptionWhenHalfOpenOrOpenState(), "false"); doWriteAttribute("slowCallRateThreshold", def.getSlowCallRateThreshold(), "100"); + doWriteAttribute("micrometerEnabled", def.getMicrometerEnabled(), "false"); doWriteAttribute("writableStackTraceEnabled", def.getWritableStackTraceEnabled(), "true"); doWriteAttribute("automaticTransitionFromOpenToHalfOpenEnabled", def.getAutomaticTransitionFromOpenToHalfOpenEnabled(), "false"); doWriteAttribute("circuitBreaker", def.getCircuitBreaker(), null); diff --git a/docs/components/modules/others/examples/json/resilience4j-micrometer.json b/docs/components/modules/others/examples/json/resilience4j-micrometer.json new file mode 120000 index 00000000000..69fd982c9d6 --- /dev/null +++ b/docs/components/modules/others/examples/json/resilience4j-micrometer.json @@ -0,0 +1 @@ +../../../../../../components/camel-resilience4j-micrometer/src/generated/resources/resilience4j-micrometer.json \ No newline at end of file diff --git a/docs/components/modules/others/nav.adoc b/docs/components/modules/others/nav.adoc index 33adc3de025..02b181394d9 100644 --- a/docs/components/modules/others/nav.adoc +++ b/docs/components/modules/others/nav.adoc @@ -47,6 +47,7 @@ ** xref:reactor.adoc[Reactor] ** xref:redis.adoc[Redis] ** xref:resilience4j.adoc[Resilience4j] +** xref:resilience4j-micrometer.adoc[Resilience4j Micrometer] ** xref:resourceresolver-github.adoc[Resourceresolver Github] ** xref:rxjava.adoc[RxJava] ** xref:shiro.adoc[Shiro] diff --git a/docs/components/modules/others/pages/resilience4j-micrometer.adoc b/docs/components/modules/others/pages/resilience4j-micrometer.adoc new file mode 120000 index 00000000000..0ff1cc2fadd --- /dev/null +++ b/docs/components/modules/others/pages/resilience4j-micrometer.adoc @@ -0,0 +1 @@ +../../../../../components/camel-resilience4j-micrometer/src/main/docs/resilience4j-micrometer.adoc \ No newline at end of file diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java index 67c71508fd2..b5965ab99bd 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java @@ -14019,6 +14019,7 @@ public final class ModelDeserializers extends YamlDeserializerSupport { @YamlProperty(name = "failureRateThreshold", type = "number", defaultValue = "50", description = "Configures the failure rate threshold in percentage. If the failure rate is equal or greater than the threshold the CircuitBreaker transitions to open and starts short-circuiting calls. The threshold must be greater than 0 and not greater than 100. Default value is 50 percentage.", displayName = "Failure Rate Threshold"), @YamlProperty(name = "id", type = "string", description = "The id of this node", displayName = "Id"), @YamlProperty(name = "ignoreException", type = "array:string", description = "Configure a list of exceptions that are ignored and neither count as a failure nor success. Any exception matching or inheriting from one of the list will not count as a failure nor success, even if the exceptions is part of recordExceptions.", displayName = "Ignore Exception"), + @YamlProperty(name = "micrometerEnabled", type = "boolean", defaultValue = "false", description = "Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath.", displayName = "Micrometer Enabled"), @YamlProperty(name = "minimumNumberOfCalls", type = "number", defaultValue = "100", description = "Configures the minimum number of calls which are required (per sliding window period) before the CircuitBreaker can calculate the error rate. For example, if minimumNumberOfCalls is 10, then at least 10 calls must be recorded, before the failure rate can be calculated. If only 9 calls have been recorded the CircuitBreaker will not transition to open even if all 9 calls h [...] @YamlProperty(name = "permittedNumberOfCallsInHalfOpenState", type = "number", defaultValue = "10", description = "Configures the number of permitted calls when the CircuitBreaker is half open. The size must be greater than 0. Default size is 10.", displayName = "Permitted Number Of Calls In Half Open State"), @YamlProperty(name = "recordException", type = "array:string", description = "Configure a list of exceptions that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list counts as a failure, unless explicitly ignored via ignoreExceptions.", displayName = "Record Exception"), @@ -14095,6 +14096,11 @@ public final class ModelDeserializers extends YamlDeserializerSupport { target.setIgnoreExceptions(val); break; } + case "micrometerEnabled": { + String val = asText(node); + target.setMicrometerEnabled(val); + break; + } case "minimumNumberOfCalls": { String val = asText(node); target.setMinimumNumberOfCalls(val); diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json index 65246663340..9a97600b85e 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json @@ -5218,6 +5218,12 @@ "type" : "string" } }, + "micrometerEnabled" : { + "type" : "boolean", + "title" : "Micrometer Enabled", + "description" : "Whether to enable collecting statistics using Micrometer. This requires adding camel-resilience4j-micrometer JAR to the classpath.", + "default" : "false" + }, "minimumNumberOfCalls" : { "type" : "number", "title" : "Minimum Number Of Calls", diff --git a/parent/pom.xml b/parent/pom.xml index d1f089edfab..ddf386bdf0c 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -2242,6 +2242,11 @@ <artifactId>camel-resilience4j</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-resilience4j-micrometer</artifactId> + <version>${project.version}</version> + </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-resourceresolver-github</artifactId>
